pandora: defconfig: update
[pandora-kernel.git] / drivers / message / fusion / mptbase.c
1 /*
2  *  linux/drivers/message/fusion/mptbase.c
3  *      This is the Fusion MPT base driver which supports multiple
4  *      (SCSI + LAN) specialized protocol drivers.
5  *      For use with LSI PCI chip/adapter(s)
6  *      running LSI Fusion MPT (Message Passing Technology) firmware.
7  *
8  *  Copyright (c) 1999-2008 LSI Corporation
9  *  (mailto:DL-MPTFusionLinux@lsi.com)
10  *
11  */
12 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
13 /*
14     This program is free software; you can redistribute it and/or modify
15     it under the terms of the GNU General Public License as published by
16     the Free Software Foundation; version 2 of the License.
17
18     This program is distributed in the hope that it will be useful,
19     but WITHOUT ANY WARRANTY; without even the implied warranty of
20     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21     GNU General Public License for more details.
22
23     NO WARRANTY
24     THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
25     CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
26     LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
27     MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
28     solely responsible for determining the appropriateness of using and
29     distributing the Program and assumes all risks associated with its
30     exercise of rights under this Agreement, including but not limited to
31     the risks and costs of program errors, damage to or loss of data,
32     programs or equipment, and unavailability or interruption of operations.
33
34     DISCLAIMER OF LIABILITY
35     NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
36     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37     DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
38     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
39     TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
40     USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
41     HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
42
43     You should have received a copy of the GNU General Public License
44     along with this program; if not, write to the Free Software
45     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
46 */
47 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
48
49 #include <linux/kernel.h>
50 #include <linux/module.h>
51 #include <linux/errno.h>
52 #include <linux/init.h>
53 #include <linux/seq_file.h>
54 #include <linux/slab.h>
55 #include <linux/types.h>
56 #include <linux/pci.h>
57 #include <linux/kdev_t.h>
58 #include <linux/blkdev.h>
59 #include <linux/delay.h>
60 #include <linux/interrupt.h>            /* needed for in_interrupt() proto */
61 #include <linux/dma-mapping.h>
62 #include <asm/io.h>
63 #ifdef CONFIG_MTRR
64 #include <asm/mtrr.h>
65 #endif
66 #include <linux/kthread.h>
67 #include <scsi/scsi_host.h>
68
69 #include "mptbase.h"
70 #include "lsi/mpi_log_fc.h"
71
72 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
73 #define my_NAME         "Fusion MPT base driver"
74 #define my_VERSION      MPT_LINUX_VERSION_COMMON
75 #define MYNAM           "mptbase"
76
77 MODULE_AUTHOR(MODULEAUTHOR);
78 MODULE_DESCRIPTION(my_NAME);
79 MODULE_LICENSE("GPL");
80 MODULE_VERSION(my_VERSION);
81
82 /*
83  *  cmd line parameters
84  */
85
86 static int mpt_msi_enable_spi;
87 module_param(mpt_msi_enable_spi, int, 0);
88 MODULE_PARM_DESC(mpt_msi_enable_spi,
89                  " Enable MSI Support for SPI controllers (default=0)");
90
91 static int mpt_msi_enable_fc;
92 module_param(mpt_msi_enable_fc, int, 0);
93 MODULE_PARM_DESC(mpt_msi_enable_fc,
94                  " Enable MSI Support for FC controllers (default=0)");
95
96 static int mpt_msi_enable_sas;
97 module_param(mpt_msi_enable_sas, int, 0);
98 MODULE_PARM_DESC(mpt_msi_enable_sas,
99                  " Enable MSI Support for SAS controllers (default=0)");
100
101 static int mpt_channel_mapping;
102 module_param(mpt_channel_mapping, int, 0);
103 MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
104
105 static int mpt_debug_level;
106 static int mpt_set_debug_level(const char *val, struct kernel_param *kp);
107 module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int,
108                   &mpt_debug_level, 0600);
109 MODULE_PARM_DESC(mpt_debug_level,
110                  " debug level - refer to mptdebug.h - (default=0)");
111
112 int mpt_fwfault_debug;
113 EXPORT_SYMBOL(mpt_fwfault_debug);
114 module_param(mpt_fwfault_debug, int, 0600);
115 MODULE_PARM_DESC(mpt_fwfault_debug,
116                  "Enable detection of Firmware fault and halt Firmware on fault - (default=0)");
117
118 static char     MptCallbacksName[MPT_MAX_PROTOCOL_DRIVERS][50];
119
120 #ifdef MFCNT
121 static int mfcounter = 0;
122 #define PRINT_MF_COUNT 20000
123 #endif
124
125 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
126 /*
127  *  Public data...
128  */
129
130 #define WHOINIT_UNKNOWN         0xAA
131
132 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
133 /*
134  *  Private data...
135  */
136                                         /* Adapter link list */
137 LIST_HEAD(ioc_list);
138                                         /* Callback lookup table */
139 static MPT_CALLBACK              MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
140                                         /* Protocol driver class lookup table */
141 static int                       MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
142                                         /* Event handler lookup table */
143 static MPT_EVHANDLER             MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
144                                         /* Reset handler lookup table */
145 static MPT_RESETHANDLER          MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
146 static struct mpt_pci_driver    *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
147
148 #ifdef CONFIG_PROC_FS
149 static struct proc_dir_entry    *mpt_proc_root_dir;
150 #endif
151
152 /*
153  *  Driver Callback Index's
154  */
155 static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS;
156 static u8 last_drv_idx;
157
158 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
159 /*
160  *  Forward protos...
161  */
162 static irqreturn_t mpt_interrupt(int irq, void *bus_id);
163 static int      mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
164                 MPT_FRAME_HDR *reply);
165 static int      mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
166                         u32 *req, int replyBytes, u16 *u16reply, int maxwait,
167                         int sleepFlag);
168 static int      mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
169 static void     mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
170 static void     mpt_adapter_disable(MPT_ADAPTER *ioc);
171 static void     mpt_adapter_dispose(MPT_ADAPTER *ioc);
172
173 static void     MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
174 static int      MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
175 static int      GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
176 static int      GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
177 static int      SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
178 static int      SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
179 static int      mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
180 static int      mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
181 static int      mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
182 static int      KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
183 static int      SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
184 static int      PrimeIocFifos(MPT_ADAPTER *ioc);
185 static int      WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
186 static int      WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
187 static int      WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
188 static int      GetLanConfigPages(MPT_ADAPTER *ioc);
189 static int      GetIoUnitPage2(MPT_ADAPTER *ioc);
190 int             mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
191 static int      mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
192 static int      mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
193 static void     mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
194 static void     mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
195 static void     mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
196 static int      SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch,
197         int sleepFlag);
198 static int      SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
199 static int      mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
200 static int      mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
201
202 #ifdef CONFIG_PROC_FS
203 static const struct file_operations mpt_summary_proc_fops;
204 static const struct file_operations mpt_version_proc_fops;
205 static const struct file_operations mpt_iocinfo_proc_fops;
206 #endif
207 static void     mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
208
209 static int      ProcessEventNotification(MPT_ADAPTER *ioc,
210                 EventNotificationReply_t *evReply, int *evHandlers);
211 static void     mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
212 static void     mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
213 static void     mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
214 static void     mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info , u8 cb_idx);
215 static int      mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
216 static void     mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
217
218 /* module entry point */
219 static int  __init    fusion_init  (void);
220 static void __exit    fusion_exit  (void);
221
222 #define CHIPREG_READ32(addr)            readl_relaxed(addr)
223 #define CHIPREG_READ32_dmasync(addr)    readl(addr)
224 #define CHIPREG_WRITE32(addr,val)       writel(val, addr)
225 #define CHIPREG_PIO_WRITE32(addr,val)   outl(val, (unsigned long)addr)
226 #define CHIPREG_PIO_READ32(addr)        inl((unsigned long)addr)
227
228 static void
229 pci_disable_io_access(struct pci_dev *pdev)
230 {
231         u16 command_reg;
232
233         pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
234         command_reg &= ~1;
235         pci_write_config_word(pdev, PCI_COMMAND, command_reg);
236 }
237
238 static void
239 pci_enable_io_access(struct pci_dev *pdev)
240 {
241         u16 command_reg;
242
243         pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
244         command_reg |= 1;
245         pci_write_config_word(pdev, PCI_COMMAND, command_reg);
246 }
247
248 static int mpt_set_debug_level(const char *val, struct kernel_param *kp)
249 {
250         int ret = param_set_int(val, kp);
251         MPT_ADAPTER *ioc;
252
253         if (ret)
254                 return ret;
255
256         list_for_each_entry(ioc, &ioc_list, list)
257                 ioc->debug_level = mpt_debug_level;
258         return 0;
259 }
260
261 /**
262  *      mpt_get_cb_idx - obtain cb_idx for registered driver
263  *      @dclass: class driver enum
264  *
265  *      Returns cb_idx, or zero means it wasn't found
266  **/
267 static u8
268 mpt_get_cb_idx(MPT_DRIVER_CLASS dclass)
269 {
270         u8 cb_idx;
271
272         for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--)
273                 if (MptDriverClass[cb_idx] == dclass)
274                         return cb_idx;
275         return 0;
276 }
277
278 /**
279  * mpt_is_discovery_complete - determine if discovery has completed
280  * @ioc: per adatper instance
281  *
282  * Returns 1 when discovery completed, else zero.
283  */
284 static int
285 mpt_is_discovery_complete(MPT_ADAPTER *ioc)
286 {
287         ConfigExtendedPageHeader_t hdr;
288         CONFIGPARMS cfg;
289         SasIOUnitPage0_t *buffer;
290         dma_addr_t dma_handle;
291         int rc = 0;
292
293         memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
294         memset(&cfg, 0, sizeof(CONFIGPARMS));
295         hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
296         hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
297         hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
298         cfg.cfghdr.ehdr = &hdr;
299         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
300
301         if ((mpt_config(ioc, &cfg)))
302                 goto out;
303         if (!hdr.ExtPageLength)
304                 goto out;
305
306         buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
307             &dma_handle);
308         if (!buffer)
309                 goto out;
310
311         cfg.physAddr = dma_handle;
312         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
313
314         if ((mpt_config(ioc, &cfg)))
315                 goto out_free_consistent;
316
317         if (!(buffer->PhyData[0].PortFlags &
318             MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS))
319                 rc = 1;
320
321  out_free_consistent:
322         pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
323             buffer, dma_handle);
324  out:
325         return rc;
326 }
327
328
329 /**
330  *  mpt_remove_dead_ioc_func - kthread context to remove dead ioc
331  * @arg: input argument, used to derive ioc
332  *
333  * Return 0 if controller is removed from pci subsystem.
334  * Return -1 for other case.
335  */
336 static int mpt_remove_dead_ioc_func(void *arg)
337 {
338         MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
339         struct pci_dev *pdev;
340
341         if ((ioc == NULL))
342                 return -1;
343
344         pdev = ioc->pcidev;
345         if ((pdev == NULL))
346                 return -1;
347
348         pci_remove_bus_device(pdev);
349         return 0;
350 }
351
352
353
354 /**
355  *      mpt_fault_reset_work - work performed on workq after ioc fault
356  *      @work: input argument, used to derive ioc
357  *
358 **/
359 static void
360 mpt_fault_reset_work(struct work_struct *work)
361 {
362         MPT_ADAPTER     *ioc =
363             container_of(work, MPT_ADAPTER, fault_reset_work.work);
364         u32              ioc_raw_state;
365         int              rc;
366         unsigned long    flags;
367         MPT_SCSI_HOST   *hd;
368         struct task_struct *p;
369
370         if (ioc->ioc_reset_in_progress || !ioc->active)
371                 goto out;
372
373
374         ioc_raw_state = mpt_GetIocState(ioc, 0);
375         if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_MASK) {
376                 printk(MYIOC_s_INFO_FMT "%s: IOC is non-operational !!!!\n",
377                     ioc->name, __func__);
378
379                 /*
380                  * Call mptscsih_flush_pending_cmds callback so that we
381                  * flush all pending commands back to OS.
382                  * This call is required to aovid deadlock at block layer.
383                  * Dead IOC will fail to do diag reset,and this call is safe
384                  * since dead ioc will never return any command back from HW.
385                  */
386                 hd = shost_priv(ioc->sh);
387                 ioc->schedule_dead_ioc_flush_running_cmds(hd);
388
389                 /*Remove the Dead Host */
390                 p = kthread_run(mpt_remove_dead_ioc_func, ioc,
391                                 "mpt_dead_ioc_%d", ioc->id);
392                 if (IS_ERR(p))  {
393                         printk(MYIOC_s_ERR_FMT
394                                 "%s: Running mpt_dead_ioc thread failed !\n",
395                                 ioc->name, __func__);
396                 } else {
397                         printk(MYIOC_s_WARN_FMT
398                                 "%s: Running mpt_dead_ioc thread success !\n",
399                                 ioc->name, __func__);
400                 }
401                 return; /* don't rearm timer */
402         }
403
404         if ((ioc_raw_state & MPI_IOC_STATE_MASK)
405                         == MPI_IOC_STATE_FAULT) {
406                 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n",
407                        ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
408                 printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
409                        ioc->name, __func__);
410                 rc = mpt_HardResetHandler(ioc, CAN_SLEEP);
411                 printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name,
412                        __func__, (rc == 0) ? "success" : "failed");
413                 ioc_raw_state = mpt_GetIocState(ioc, 0);
414                 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT)
415                         printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after "
416                             "reset (%04xh)\n", ioc->name, ioc_raw_state &
417                             MPI_DOORBELL_DATA_MASK);
418         } else if (ioc->bus_type == SAS && ioc->sas_discovery_quiesce_io) {
419                 if ((mpt_is_discovery_complete(ioc))) {
420                         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "clearing "
421                             "discovery_quiesce_io flag\n", ioc->name));
422                         ioc->sas_discovery_quiesce_io = 0;
423                 }
424         }
425
426  out:
427         /*
428          * Take turns polling alternate controller
429          */
430         if (ioc->alt_ioc)
431                 ioc = ioc->alt_ioc;
432
433         /* rearm the timer */
434         spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
435         if (ioc->reset_work_q)
436                 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
437                         msecs_to_jiffies(MPT_POLLING_INTERVAL));
438         spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
439 }
440
441
442 /*
443  *  Process turbo (context) reply...
444  */
445 static void
446 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
447 {
448         MPT_FRAME_HDR *mf = NULL;
449         MPT_FRAME_HDR *mr = NULL;
450         u16 req_idx = 0;
451         u8 cb_idx;
452
453         dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n",
454                                 ioc->name, pa));
455
456         switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
457         case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
458                 req_idx = pa & 0x0000FFFF;
459                 cb_idx = (pa & 0x00FF0000) >> 16;
460                 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
461                 break;
462         case MPI_CONTEXT_REPLY_TYPE_LAN:
463                 cb_idx = mpt_get_cb_idx(MPTLAN_DRIVER);
464                 /*
465                  *  Blind set of mf to NULL here was fatal
466                  *  after lan_reply says "freeme"
467                  *  Fix sort of combined with an optimization here;
468                  *  added explicit check for case where lan_reply
469                  *  was just returning 1 and doing nothing else.
470                  *  For this case skip the callback, but set up
471                  *  proper mf value first here:-)
472                  */
473                 if ((pa & 0x58000000) == 0x58000000) {
474                         req_idx = pa & 0x0000FFFF;
475                         mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
476                         mpt_free_msg_frame(ioc, mf);
477                         mb();
478                         return;
479                         break;
480                 }
481                 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
482                 break;
483         case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
484                 cb_idx = mpt_get_cb_idx(MPTSTM_DRIVER);
485                 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
486                 break;
487         default:
488                 cb_idx = 0;
489                 BUG();
490         }
491
492         /*  Check for (valid) IO callback!  */
493         if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
494                 MptCallbacks[cb_idx] == NULL) {
495                 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
496                                 __func__, ioc->name, cb_idx);
497                 goto out;
498         }
499
500         if (MptCallbacks[cb_idx](ioc, mf, mr))
501                 mpt_free_msg_frame(ioc, mf);
502  out:
503         mb();
504 }
505
506 static void
507 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
508 {
509         MPT_FRAME_HDR   *mf;
510         MPT_FRAME_HDR   *mr;
511         u16              req_idx;
512         u8               cb_idx;
513         int              freeme;
514
515         u32 reply_dma_low;
516         u16 ioc_stat;
517
518         /* non-TURBO reply!  Hmmm, something may be up...
519          *  Newest turbo reply mechanism; get address
520          *  via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
521          */
522
523         /* Map DMA address of reply header to cpu address.
524          * pa is 32 bits - but the dma address may be 32 or 64 bits
525          * get offset based only only the low addresses
526          */
527
528         reply_dma_low = (pa <<= 1);
529         mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
530                          (reply_dma_low - ioc->reply_frames_low_dma));
531
532         req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
533         cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
534         mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
535
536         dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
537                         ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
538         DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr);
539
540          /*  Check/log IOC log info
541          */
542         ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
543         if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
544                 u32      log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
545                 if (ioc->bus_type == FC)
546                         mpt_fc_log_info(ioc, log_info);
547                 else if (ioc->bus_type == SPI)
548                         mpt_spi_log_info(ioc, log_info);
549                 else if (ioc->bus_type == SAS)
550                         mpt_sas_log_info(ioc, log_info, cb_idx);
551         }
552
553         if (ioc_stat & MPI_IOCSTATUS_MASK)
554                 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
555
556         /*  Check for (valid) IO callback!  */
557         if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
558                 MptCallbacks[cb_idx] == NULL) {
559                 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
560                                 __func__, ioc->name, cb_idx);
561                 freeme = 0;
562                 goto out;
563         }
564
565         freeme = MptCallbacks[cb_idx](ioc, mf, mr);
566
567  out:
568         /*  Flush (non-TURBO) reply with a WRITE!  */
569         CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
570
571         if (freeme)
572                 mpt_free_msg_frame(ioc, mf);
573         mb();
574 }
575
576 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
577 /**
578  *      mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
579  *      @irq: irq number (not used)
580  *      @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
581  *
582  *      This routine is registered via the request_irq() kernel API call,
583  *      and handles all interrupts generated from a specific MPT adapter
584  *      (also referred to as a IO Controller or IOC).
585  *      This routine must clear the interrupt from the adapter and does
586  *      so by reading the reply FIFO.  Multiple replies may be processed
587  *      per single call to this routine.
588  *
589  *      This routine handles register-level access of the adapter but
590  *      dispatches (calls) a protocol-specific callback routine to handle
591  *      the protocol-specific details of the MPT request completion.
592  */
593 static irqreturn_t
594 mpt_interrupt(int irq, void *bus_id)
595 {
596         MPT_ADAPTER *ioc = bus_id;
597         u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
598
599         if (pa == 0xFFFFFFFF)
600                 return IRQ_NONE;
601
602         /*
603          *  Drain the reply FIFO!
604          */
605         do {
606                 if (pa & MPI_ADDRESS_REPLY_A_BIT)
607                         mpt_reply(ioc, pa);
608                 else
609                         mpt_turbo_reply(ioc, pa);
610                 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
611         } while (pa != 0xFFFFFFFF);
612
613         return IRQ_HANDLED;
614 }
615
616 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
617 /**
618  *      mptbase_reply - MPT base driver's callback routine
619  *      @ioc: Pointer to MPT_ADAPTER structure
620  *      @req: Pointer to original MPT request frame
621  *      @reply: Pointer to MPT reply frame (NULL if TurboReply)
622  *
623  *      MPT base driver's callback routine; all base driver
624  *      "internal" request/reply processing is routed here.
625  *      Currently used for EventNotification and EventAck handling.
626  *
627  *      Returns 1 indicating original alloc'd request frame ptr
628  *      should be freed, or 0 if it shouldn't.
629  */
630 static int
631 mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
632 {
633         EventNotificationReply_t *pEventReply;
634         u8 event;
635         int evHandlers;
636         int freereq = 1;
637
638         switch (reply->u.hdr.Function) {
639         case MPI_FUNCTION_EVENT_NOTIFICATION:
640                 pEventReply = (EventNotificationReply_t *)reply;
641                 evHandlers = 0;
642                 ProcessEventNotification(ioc, pEventReply, &evHandlers);
643                 event = le32_to_cpu(pEventReply->Event) & 0xFF;
644                 if (pEventReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
645                         freereq = 0;
646                 if (event != MPI_EVENT_EVENT_CHANGE)
647                         break;
648         case MPI_FUNCTION_CONFIG:
649         case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
650                 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
651                 if (reply) {
652                         ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
653                         memcpy(ioc->mptbase_cmds.reply, reply,
654                             min(MPT_DEFAULT_FRAME_SIZE,
655                                 4 * reply->u.reply.MsgLength));
656                 }
657                 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
658                         ioc->mptbase_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
659                         complete(&ioc->mptbase_cmds.done);
660                 } else
661                         freereq = 0;
662                 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_FREE_MF)
663                         freereq = 1;
664                 break;
665         case MPI_FUNCTION_EVENT_ACK:
666                 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
667                     "EventAck reply received\n", ioc->name));
668                 break;
669         default:
670                 printk(MYIOC_s_ERR_FMT
671                     "Unexpected msg function (=%02Xh) reply received!\n",
672                     ioc->name, reply->u.hdr.Function);
673                 break;
674         }
675
676         /*
677          *      Conditionally tell caller to free the original
678          *      EventNotification/EventAck/unexpected request frame!
679          */
680         return freereq;
681 }
682
683 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
684 /**
685  *      mpt_register - Register protocol-specific main callback handler.
686  *      @cbfunc: callback function pointer
687  *      @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
688  *      @func_name: call function's name
689  *
690  *      This routine is called by a protocol-specific driver (SCSI host,
691  *      LAN, SCSI target) to register its reply callback routine.  Each
692  *      protocol-specific driver must do this before it will be able to
693  *      use any IOC resources, such as obtaining request frames.
694  *
695  *      NOTES: The SCSI protocol driver currently calls this routine thrice
696  *      in order to register separate callbacks; one for "normal" SCSI IO;
697  *      one for MptScsiTaskMgmt requests; one for Scan/DV requests.
698  *
699  *      Returns u8 valued "handle" in the range (and S.O.D. order)
700  *      {N,...,7,6,5,...,1} if successful.
701  *      A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
702  *      considered an error by the caller.
703  */
704 u8
705 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass, char *func_name)
706 {
707         u8 cb_idx;
708         last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS;
709
710         /*
711          *  Search for empty callback slot in this order: {N,...,7,6,5,...,1}
712          *  (slot/handle 0 is reserved!)
713          */
714         for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
715                 if (MptCallbacks[cb_idx] == NULL) {
716                         MptCallbacks[cb_idx] = cbfunc;
717                         MptDriverClass[cb_idx] = dclass;
718                         MptEvHandlers[cb_idx] = NULL;
719                         last_drv_idx = cb_idx;
720                         memcpy(MptCallbacksName[cb_idx], func_name,
721                             strlen(func_name) > 50 ? 50 : strlen(func_name));
722                         break;
723                 }
724         }
725
726         return last_drv_idx;
727 }
728
729 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
730 /**
731  *      mpt_deregister - Deregister a protocol drivers resources.
732  *      @cb_idx: previously registered callback handle
733  *
734  *      Each protocol-specific driver should call this routine when its
735  *      module is unloaded.
736  */
737 void
738 mpt_deregister(u8 cb_idx)
739 {
740         if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
741                 MptCallbacks[cb_idx] = NULL;
742                 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
743                 MptEvHandlers[cb_idx] = NULL;
744
745                 last_drv_idx++;
746         }
747 }
748
749 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
750 /**
751  *      mpt_event_register - Register protocol-specific event callback handler.
752  *      @cb_idx: previously registered (via mpt_register) callback handle
753  *      @ev_cbfunc: callback function
754  *
755  *      This routine can be called by one or more protocol-specific drivers
756  *      if/when they choose to be notified of MPT events.
757  *
758  *      Returns 0 for success.
759  */
760 int
761 mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc)
762 {
763         if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
764                 return -1;
765
766         MptEvHandlers[cb_idx] = ev_cbfunc;
767         return 0;
768 }
769
770 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
771 /**
772  *      mpt_event_deregister - Deregister protocol-specific event callback handler
773  *      @cb_idx: previously registered callback handle
774  *
775  *      Each protocol-specific driver should call this routine
776  *      when it does not (or can no longer) handle events,
777  *      or when its module is unloaded.
778  */
779 void
780 mpt_event_deregister(u8 cb_idx)
781 {
782         if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
783                 return;
784
785         MptEvHandlers[cb_idx] = NULL;
786 }
787
788 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
789 /**
790  *      mpt_reset_register - Register protocol-specific IOC reset handler.
791  *      @cb_idx: previously registered (via mpt_register) callback handle
792  *      @reset_func: reset function
793  *
794  *      This routine can be called by one or more protocol-specific drivers
795  *      if/when they choose to be notified of IOC resets.
796  *
797  *      Returns 0 for success.
798  */
799 int
800 mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func)
801 {
802         if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
803                 return -1;
804
805         MptResetHandlers[cb_idx] = reset_func;
806         return 0;
807 }
808
809 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
810 /**
811  *      mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
812  *      @cb_idx: previously registered callback handle
813  *
814  *      Each protocol-specific driver should call this routine
815  *      when it does not (or can no longer) handle IOC reset handling,
816  *      or when its module is unloaded.
817  */
818 void
819 mpt_reset_deregister(u8 cb_idx)
820 {
821         if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
822                 return;
823
824         MptResetHandlers[cb_idx] = NULL;
825 }
826
827 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
828 /**
829  *      mpt_device_driver_register - Register device driver hooks
830  *      @dd_cbfunc: driver callbacks struct
831  *      @cb_idx: MPT protocol driver index
832  */
833 int
834 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
835 {
836         MPT_ADAPTER     *ioc;
837         const struct pci_device_id *id;
838
839         if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
840                 return -EINVAL;
841
842         MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
843
844         /* call per pci device probe entry point */
845         list_for_each_entry(ioc, &ioc_list, list) {
846                 id = ioc->pcidev->driver ?
847                     ioc->pcidev->driver->id_table : NULL;
848                 if (dd_cbfunc->probe)
849                         dd_cbfunc->probe(ioc->pcidev, id);
850          }
851
852         return 0;
853 }
854
855 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
856 /**
857  *      mpt_device_driver_deregister - DeRegister device driver hooks
858  *      @cb_idx: MPT protocol driver index
859  */
860 void
861 mpt_device_driver_deregister(u8 cb_idx)
862 {
863         struct mpt_pci_driver *dd_cbfunc;
864         MPT_ADAPTER     *ioc;
865
866         if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
867                 return;
868
869         dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
870
871         list_for_each_entry(ioc, &ioc_list, list) {
872                 if (dd_cbfunc->remove)
873                         dd_cbfunc->remove(ioc->pcidev);
874         }
875
876         MptDeviceDriverHandlers[cb_idx] = NULL;
877 }
878
879
880 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
881 /**
882  *      mpt_get_msg_frame - Obtain an MPT request frame from the pool
883  *      @cb_idx: Handle of registered MPT protocol driver
884  *      @ioc: Pointer to MPT adapter structure
885  *
886  *      Obtain an MPT request frame from the pool (of 1024) that are
887  *      allocated per MPT adapter.
888  *
889  *      Returns pointer to a MPT request frame or %NULL if none are available
890  *      or IOC is not active.
891  */
892 MPT_FRAME_HDR*
893 mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc)
894 {
895         MPT_FRAME_HDR *mf;
896         unsigned long flags;
897         u16      req_idx;       /* Request index */
898
899         /* validate handle and ioc identifier */
900
901 #ifdef MFCNT
902         if (!ioc->active)
903                 printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame "
904                     "returning NULL!\n", ioc->name);
905 #endif
906
907         /* If interrupts are not attached, do not return a request frame */
908         if (!ioc->active)
909                 return NULL;
910
911         spin_lock_irqsave(&ioc->FreeQlock, flags);
912         if (!list_empty(&ioc->FreeQ)) {
913                 int req_offset;
914
915                 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
916                                 u.frame.linkage.list);
917                 list_del(&mf->u.frame.linkage.list);
918                 mf->u.frame.linkage.arg1 = 0;
919                 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;  /* byte */
920                 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
921                                                                 /* u16! */
922                 req_idx = req_offset / ioc->req_sz;
923                 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
924                 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
925                 /* Default, will be changed if necessary in SG generation */
926                 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame;
927 #ifdef MFCNT
928                 ioc->mfcnt++;
929 #endif
930         }
931         else
932                 mf = NULL;
933         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
934
935 #ifdef MFCNT
936         if (mf == NULL)
937                 printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! "
938                     "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt,
939                     ioc->req_depth);
940         mfcounter++;
941         if (mfcounter == PRINT_MF_COUNT)
942                 printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name,
943                     ioc->mfcnt, ioc->req_depth);
944 #endif
945
946         dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n",
947             ioc->name, cb_idx, ioc->id, mf));
948         return mf;
949 }
950
951 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
952 /**
953  *      mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
954  *      @cb_idx: Handle of registered MPT protocol driver
955  *      @ioc: Pointer to MPT adapter structure
956  *      @mf: Pointer to MPT request frame
957  *
958  *      This routine posts an MPT request frame to the request post FIFO of a
959  *      specific MPT adapter.
960  */
961 void
962 mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
963 {
964         u32 mf_dma_addr;
965         int req_offset;
966         u16      req_idx;       /* Request index */
967
968         /* ensure values are reset properly! */
969         mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;          /* byte */
970         req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
971                                                                 /* u16! */
972         req_idx = req_offset / ioc->req_sz;
973         mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
974         mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
975
976         DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
977
978         mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
979         dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d "
980             "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx,
981             ioc->RequestNB[req_idx]));
982         CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
983 }
984
985 /**
986  *      mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
987  *      @cb_idx: Handle of registered MPT protocol driver
988  *      @ioc: Pointer to MPT adapter structure
989  *      @mf: Pointer to MPT request frame
990  *
991  *      Send a protocol-specific MPT request frame to an IOC using
992  *      hi-priority request queue.
993  *
994  *      This routine posts an MPT request frame to the request post FIFO of a
995  *      specific MPT adapter.
996  **/
997 void
998 mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
999 {
1000         u32 mf_dma_addr;
1001         int req_offset;
1002         u16      req_idx;       /* Request index */
1003
1004         /* ensure values are reset properly! */
1005         mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
1006         req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
1007         req_idx = req_offset / ioc->req_sz;
1008         mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
1009         mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
1010
1011         DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
1012
1013         mf_dma_addr = (ioc->req_frames_low_dma + req_offset);
1014         dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n",
1015                 ioc->name, mf_dma_addr, req_idx));
1016         CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr);
1017 }
1018
1019 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1020 /**
1021  *      mpt_free_msg_frame - Place MPT request frame back on FreeQ.
1022  *      @ioc: Pointer to MPT adapter structure
1023  *      @mf: Pointer to MPT request frame
1024  *
1025  *      This routine places a MPT request frame back on the MPT adapter's
1026  *      FreeQ.
1027  */
1028 void
1029 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
1030 {
1031         unsigned long flags;
1032
1033         /*  Put Request back on FreeQ!  */
1034         spin_lock_irqsave(&ioc->FreeQlock, flags);
1035         if (cpu_to_le32(mf->u.frame.linkage.arg1) == 0xdeadbeaf)
1036                 goto out;
1037         /* signature to know if this mf is freed */
1038         mf->u.frame.linkage.arg1 = cpu_to_le32(0xdeadbeaf);
1039         list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
1040 #ifdef MFCNT
1041         ioc->mfcnt--;
1042 #endif
1043  out:
1044         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1045 }
1046
1047 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1048 /**
1049  *      mpt_add_sge - Place a simple 32 bit SGE at address pAddr.
1050  *      @pAddr: virtual address for SGE
1051  *      @flagslength: SGE flags and data transfer length
1052  *      @dma_addr: Physical address
1053  *
1054  *      This routine places a MPT request frame back on the MPT adapter's
1055  *      FreeQ.
1056  */
1057 static void
1058 mpt_add_sge(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1059 {
1060         SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
1061         pSge->FlagsLength = cpu_to_le32(flagslength);
1062         pSge->Address = cpu_to_le32(dma_addr);
1063 }
1064
1065 /**
1066  *      mpt_add_sge_64bit - Place a simple 64 bit SGE at address pAddr.
1067  *      @pAddr: virtual address for SGE
1068  *      @flagslength: SGE flags and data transfer length
1069  *      @dma_addr: Physical address
1070  *
1071  *      This routine places a MPT request frame back on the MPT adapter's
1072  *      FreeQ.
1073  **/
1074 static void
1075 mpt_add_sge_64bit(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1076 {
1077         SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1078         pSge->Address.Low = cpu_to_le32
1079                         (lower_32_bits(dma_addr));
1080         pSge->Address.High = cpu_to_le32
1081                         (upper_32_bits(dma_addr));
1082         pSge->FlagsLength = cpu_to_le32
1083                         ((flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1084 }
1085
1086 /**
1087  *      mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address pAddr (1078 workaround).
1088  *      @pAddr: virtual address for SGE
1089  *      @flagslength: SGE flags and data transfer length
1090  *      @dma_addr: Physical address
1091  *
1092  *      This routine places a MPT request frame back on the MPT adapter's
1093  *      FreeQ.
1094  **/
1095 static void
1096 mpt_add_sge_64bit_1078(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1097 {
1098         SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1099         u32 tmp;
1100
1101         pSge->Address.Low = cpu_to_le32
1102                         (lower_32_bits(dma_addr));
1103         tmp = (u32)(upper_32_bits(dma_addr));
1104
1105         /*
1106          * 1078 errata workaround for the 36GB limitation
1107          */
1108         if ((((u64)dma_addr + MPI_SGE_LENGTH(flagslength)) >> 32)  == 9) {
1109                 flagslength |=
1110                     MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS);
1111                 tmp |= (1<<31);
1112                 if (mpt_debug_level & MPT_DEBUG_36GB_MEM)
1113                         printk(KERN_DEBUG "1078 P0M2 addressing for "
1114                             "addr = 0x%llx len = %d\n",
1115                             (unsigned long long)dma_addr,
1116                             MPI_SGE_LENGTH(flagslength));
1117         }
1118
1119         pSge->Address.High = cpu_to_le32(tmp);
1120         pSge->FlagsLength = cpu_to_le32(
1121                 (flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1122 }
1123
1124 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1125 /**
1126  *      mpt_add_chain - Place a 32 bit chain SGE at address pAddr.
1127  *      @pAddr: virtual address for SGE
1128  *      @next: nextChainOffset value (u32's)
1129  *      @length: length of next SGL segment
1130  *      @dma_addr: Physical address
1131  *
1132  */
1133 static void
1134 mpt_add_chain(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1135 {
1136                 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
1137                 pChain->Length = cpu_to_le16(length);
1138                 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
1139                 pChain->NextChainOffset = next;
1140                 pChain->Address = cpu_to_le32(dma_addr);
1141 }
1142
1143 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1144 /**
1145  *      mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr.
1146  *      @pAddr: virtual address for SGE
1147  *      @next: nextChainOffset value (u32's)
1148  *      @length: length of next SGL segment
1149  *      @dma_addr: Physical address
1150  *
1151  */
1152 static void
1153 mpt_add_chain_64bit(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1154 {
1155                 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
1156                 u32 tmp = dma_addr & 0xFFFFFFFF;
1157
1158                 pChain->Length = cpu_to_le16(length);
1159                 pChain->Flags = (MPI_SGE_FLAGS_CHAIN_ELEMENT |
1160                                  MPI_SGE_FLAGS_64_BIT_ADDRESSING);
1161
1162                 pChain->NextChainOffset = next;
1163
1164                 pChain->Address.Low = cpu_to_le32(tmp);
1165                 tmp = (u32)(upper_32_bits(dma_addr));
1166                 pChain->Address.High = cpu_to_le32(tmp);
1167 }
1168
1169 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1170 /**
1171  *      mpt_send_handshake_request - Send MPT request via doorbell handshake method.
1172  *      @cb_idx: Handle of registered MPT protocol driver
1173  *      @ioc: Pointer to MPT adapter structure
1174  *      @reqBytes: Size of the request in bytes
1175  *      @req: Pointer to MPT request frame
1176  *      @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1177  *
1178  *      This routine is used exclusively to send MptScsiTaskMgmt
1179  *      requests since they are required to be sent via doorbell handshake.
1180  *
1181  *      NOTE: It is the callers responsibility to byte-swap fields in the
1182  *      request which are greater than 1 byte in size.
1183  *
1184  *      Returns 0 for success, non-zero for failure.
1185  */
1186 int
1187 mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
1188 {
1189         int     r = 0;
1190         u8      *req_as_bytes;
1191         int      ii;
1192
1193         /* State is known to be good upon entering
1194          * this function so issue the bus reset
1195          * request.
1196          */
1197
1198         /*
1199          * Emulate what mpt_put_msg_frame() does /wrt to sanity
1200          * setting cb_idx/req_idx.  But ONLY if this request
1201          * is in proper (pre-alloc'd) request buffer range...
1202          */
1203         ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
1204         if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
1205                 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
1206                 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
1207                 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
1208         }
1209
1210         /* Make sure there are no doorbells */
1211         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1212
1213         CHIPREG_WRITE32(&ioc->chip->Doorbell,
1214                         ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1215                          ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1216
1217         /* Wait for IOC doorbell int */
1218         if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1219                 return ii;
1220         }
1221
1222         /* Read doorbell and check for active bit */
1223         if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1224                 return -5;
1225
1226         dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n",
1227                 ioc->name, ii));
1228
1229         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1230
1231         if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1232                 return -2;
1233         }
1234
1235         /* Send request via doorbell handshake */
1236         req_as_bytes = (u8 *) req;
1237         for (ii = 0; ii < reqBytes/4; ii++) {
1238                 u32 word;
1239
1240                 word = ((req_as_bytes[(ii*4) + 0] <<  0) |
1241                         (req_as_bytes[(ii*4) + 1] <<  8) |
1242                         (req_as_bytes[(ii*4) + 2] << 16) |
1243                         (req_as_bytes[(ii*4) + 3] << 24));
1244                 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1245                 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1246                         r = -3;
1247                         break;
1248                 }
1249         }
1250
1251         if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1252                 r = 0;
1253         else
1254                 r = -4;
1255
1256         /* Make sure there are no doorbells */
1257         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1258
1259         return r;
1260 }
1261
1262 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1263 /**
1264  * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1265  * @ioc: Pointer to MPT adapter structure
1266  * @access_control_value: define bits below
1267  * @sleepFlag: Specifies whether the process can sleep
1268  *
1269  * Provides mechanism for the host driver to control the IOC's
1270  * Host Page Buffer access.
1271  *
1272  * Access Control Value - bits[15:12]
1273  * 0h Reserved
1274  * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1275  * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1276  * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1277  *
1278  * Returns 0 for success, non-zero for failure.
1279  */
1280
1281 static int
1282 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1283 {
1284         int      r = 0;
1285
1286         /* return if in use */
1287         if (CHIPREG_READ32(&ioc->chip->Doorbell)
1288             & MPI_DOORBELL_ACTIVE)
1289             return -1;
1290
1291         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1292
1293         CHIPREG_WRITE32(&ioc->chip->Doorbell,
1294                 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1295                  <<MPI_DOORBELL_FUNCTION_SHIFT) |
1296                  (access_control_value<<12)));
1297
1298         /* Wait for IOC to clear Doorbell Status bit */
1299         if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1300                 return -2;
1301         }else
1302                 return 0;
1303 }
1304
1305 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1306 /**
1307  *      mpt_host_page_alloc - allocate system memory for the fw
1308  *      @ioc: Pointer to pointer to IOC adapter
1309  *      @ioc_init: Pointer to ioc init config page
1310  *
1311  *      If we already allocated memory in past, then resend the same pointer.
1312  *      Returns 0 for success, non-zero for failure.
1313  */
1314 static int
1315 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1316 {
1317         char    *psge;
1318         int     flags_length;
1319         u32     host_page_buffer_sz=0;
1320
1321         if(!ioc->HostPageBuffer) {
1322
1323                 host_page_buffer_sz =
1324                     le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1325
1326                 if(!host_page_buffer_sz)
1327                         return 0; /* fw doesn't need any host buffers */
1328
1329                 /* spin till we get enough memory */
1330                 while(host_page_buffer_sz > 0) {
1331
1332                         if((ioc->HostPageBuffer = pci_alloc_consistent(
1333                             ioc->pcidev,
1334                             host_page_buffer_sz,
1335                             &ioc->HostPageBuffer_dma)) != NULL) {
1336
1337                                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1338                                     "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1339                                     ioc->name, ioc->HostPageBuffer,
1340                                     (u32)ioc->HostPageBuffer_dma,
1341                                     host_page_buffer_sz));
1342                                 ioc->alloc_total += host_page_buffer_sz;
1343                                 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1344                                 break;
1345                         }
1346
1347                         host_page_buffer_sz -= (4*1024);
1348                 }
1349         }
1350
1351         if(!ioc->HostPageBuffer) {
1352                 printk(MYIOC_s_ERR_FMT
1353                     "Failed to alloc memory for host_page_buffer!\n",
1354                     ioc->name);
1355                 return -999;
1356         }
1357
1358         psge = (char *)&ioc_init->HostPageBufferSGE;
1359         flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1360             MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1361             MPI_SGE_FLAGS_HOST_TO_IOC |
1362             MPI_SGE_FLAGS_END_OF_BUFFER;
1363         flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1364         flags_length |= ioc->HostPageBuffer_sz;
1365         ioc->add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1366         ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1367
1368 return 0;
1369 }
1370
1371 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1372 /**
1373  *      mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1374  *      @iocid: IOC unique identifier (integer)
1375  *      @iocpp: Pointer to pointer to IOC adapter
1376  *
1377  *      Given a unique IOC identifier, set pointer to the associated MPT
1378  *      adapter structure.
1379  *
1380  *      Returns iocid and sets iocpp if iocid is found.
1381  *      Returns -1 if iocid is not found.
1382  */
1383 int
1384 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1385 {
1386         MPT_ADAPTER *ioc;
1387
1388         list_for_each_entry(ioc,&ioc_list,list) {
1389                 if (ioc->id == iocid) {
1390                         *iocpp =ioc;
1391                         return iocid;
1392                 }
1393         }
1394
1395         *iocpp = NULL;
1396         return -1;
1397 }
1398
1399 /**
1400  *      mpt_get_product_name - returns product string
1401  *      @vendor: pci vendor id
1402  *      @device: pci device id
1403  *      @revision: pci revision id
1404  *      @prod_name: string returned
1405  *
1406  *      Returns product string displayed when driver loads,
1407  *      in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1408  *
1409  **/
1410 static void
1411 mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
1412 {
1413         char *product_str = NULL;
1414
1415         if (vendor == PCI_VENDOR_ID_BROCADE) {
1416                 switch (device)
1417                 {
1418                 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1419                         switch (revision)
1420                         {
1421                         case 0x00:
1422                                 product_str = "BRE040 A0";
1423                                 break;
1424                         case 0x01:
1425                                 product_str = "BRE040 A1";
1426                                 break;
1427                         default:
1428                                 product_str = "BRE040";
1429                                 break;
1430                         }
1431                         break;
1432                 }
1433                 goto out;
1434         }
1435
1436         switch (device)
1437         {
1438         case MPI_MANUFACTPAGE_DEVICEID_FC909:
1439                 product_str = "LSIFC909 B1";
1440                 break;
1441         case MPI_MANUFACTPAGE_DEVICEID_FC919:
1442                 product_str = "LSIFC919 B0";
1443                 break;
1444         case MPI_MANUFACTPAGE_DEVICEID_FC929:
1445                 product_str = "LSIFC929 B0";
1446                 break;
1447         case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1448                 if (revision < 0x80)
1449                         product_str = "LSIFC919X A0";
1450                 else
1451                         product_str = "LSIFC919XL A1";
1452                 break;
1453         case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1454                 if (revision < 0x80)
1455                         product_str = "LSIFC929X A0";
1456                 else
1457                         product_str = "LSIFC929XL A1";
1458                 break;
1459         case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1460                 product_str = "LSIFC939X A1";
1461                 break;
1462         case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1463                 product_str = "LSIFC949X A1";
1464                 break;
1465         case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1466                 switch (revision)
1467                 {
1468                 case 0x00:
1469                         product_str = "LSIFC949E A0";
1470                         break;
1471                 case 0x01:
1472                         product_str = "LSIFC949E A1";
1473                         break;
1474                 default:
1475                         product_str = "LSIFC949E";
1476                         break;
1477                 }
1478                 break;
1479         case MPI_MANUFACTPAGE_DEVID_53C1030:
1480                 switch (revision)
1481                 {
1482                 case 0x00:
1483                         product_str = "LSI53C1030 A0";
1484                         break;
1485                 case 0x01:
1486                         product_str = "LSI53C1030 B0";
1487                         break;
1488                 case 0x03:
1489                         product_str = "LSI53C1030 B1";
1490                         break;
1491                 case 0x07:
1492                         product_str = "LSI53C1030 B2";
1493                         break;
1494                 case 0x08:
1495                         product_str = "LSI53C1030 C0";
1496                         break;
1497                 case 0x80:
1498                         product_str = "LSI53C1030T A0";
1499                         break;
1500                 case 0x83:
1501                         product_str = "LSI53C1030T A2";
1502                         break;
1503                 case 0x87:
1504                         product_str = "LSI53C1030T A3";
1505                         break;
1506                 case 0xc1:
1507                         product_str = "LSI53C1020A A1";
1508                         break;
1509                 default:
1510                         product_str = "LSI53C1030";
1511                         break;
1512                 }
1513                 break;
1514         case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1515                 switch (revision)
1516                 {
1517                 case 0x03:
1518                         product_str = "LSI53C1035 A2";
1519                         break;
1520                 case 0x04:
1521                         product_str = "LSI53C1035 B0";
1522                         break;
1523                 default:
1524                         product_str = "LSI53C1035";
1525                         break;
1526                 }
1527                 break;
1528         case MPI_MANUFACTPAGE_DEVID_SAS1064:
1529                 switch (revision)
1530                 {
1531                 case 0x00:
1532                         product_str = "LSISAS1064 A1";
1533                         break;
1534                 case 0x01:
1535                         product_str = "LSISAS1064 A2";
1536                         break;
1537                 case 0x02:
1538                         product_str = "LSISAS1064 A3";
1539                         break;
1540                 case 0x03:
1541                         product_str = "LSISAS1064 A4";
1542                         break;
1543                 default:
1544                         product_str = "LSISAS1064";
1545                         break;
1546                 }
1547                 break;
1548         case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1549                 switch (revision)
1550                 {
1551                 case 0x00:
1552                         product_str = "LSISAS1064E A0";
1553                         break;
1554                 case 0x01:
1555                         product_str = "LSISAS1064E B0";
1556                         break;
1557                 case 0x02:
1558                         product_str = "LSISAS1064E B1";
1559                         break;
1560                 case 0x04:
1561                         product_str = "LSISAS1064E B2";
1562                         break;
1563                 case 0x08:
1564                         product_str = "LSISAS1064E B3";
1565                         break;
1566                 default:
1567                         product_str = "LSISAS1064E";
1568                         break;
1569                 }
1570                 break;
1571         case MPI_MANUFACTPAGE_DEVID_SAS1068:
1572                 switch (revision)
1573                 {
1574                 case 0x00:
1575                         product_str = "LSISAS1068 A0";
1576                         break;
1577                 case 0x01:
1578                         product_str = "LSISAS1068 B0";
1579                         break;
1580                 case 0x02:
1581                         product_str = "LSISAS1068 B1";
1582                         break;
1583                 default:
1584                         product_str = "LSISAS1068";
1585                         break;
1586                 }
1587                 break;
1588         case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1589                 switch (revision)
1590                 {
1591                 case 0x00:
1592                         product_str = "LSISAS1068E A0";
1593                         break;
1594                 case 0x01:
1595                         product_str = "LSISAS1068E B0";
1596                         break;
1597                 case 0x02:
1598                         product_str = "LSISAS1068E B1";
1599                         break;
1600                 case 0x04:
1601                         product_str = "LSISAS1068E B2";
1602                         break;
1603                 case 0x08:
1604                         product_str = "LSISAS1068E B3";
1605                         break;
1606                 default:
1607                         product_str = "LSISAS1068E";
1608                         break;
1609                 }
1610                 break;
1611         case MPI_MANUFACTPAGE_DEVID_SAS1078:
1612                 switch (revision)
1613                 {
1614                 case 0x00:
1615                         product_str = "LSISAS1078 A0";
1616                         break;
1617                 case 0x01:
1618                         product_str = "LSISAS1078 B0";
1619                         break;
1620                 case 0x02:
1621                         product_str = "LSISAS1078 C0";
1622                         break;
1623                 case 0x03:
1624                         product_str = "LSISAS1078 C1";
1625                         break;
1626                 case 0x04:
1627                         product_str = "LSISAS1078 C2";
1628                         break;
1629                 default:
1630                         product_str = "LSISAS1078";
1631                         break;
1632                 }
1633                 break;
1634         }
1635
1636  out:
1637         if (product_str)
1638                 sprintf(prod_name, "%s", product_str);
1639 }
1640
1641 /**
1642  *      mpt_mapresources - map in memory mapped io
1643  *      @ioc: Pointer to pointer to IOC adapter
1644  *
1645  **/
1646 static int
1647 mpt_mapresources(MPT_ADAPTER *ioc)
1648 {
1649         u8              __iomem *mem;
1650         int              ii;
1651         resource_size_t  mem_phys;
1652         unsigned long    port;
1653         u32              msize;
1654         u32              psize;
1655         u8               revision;
1656         int              r = -ENODEV;
1657         struct pci_dev *pdev;
1658
1659         pdev = ioc->pcidev;
1660         ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
1661         if (pci_enable_device_mem(pdev)) {
1662                 printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
1663                     "failed\n", ioc->name);
1664                 return r;
1665         }
1666         if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
1667                 printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
1668                     "MEM failed\n", ioc->name);
1669                 return r;
1670         }
1671
1672         pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1673
1674         if (sizeof(dma_addr_t) > 4) {
1675                 const uint64_t required_mask = dma_get_required_mask
1676                     (&pdev->dev);
1677                 if (required_mask > DMA_BIT_MASK(32)
1678                         && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1679                         && !pci_set_consistent_dma_mask(pdev,
1680                                                  DMA_BIT_MASK(64))) {
1681                         ioc->dma_mask = DMA_BIT_MASK(64);
1682                         dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1683                                 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1684                                 ioc->name));
1685                 } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1686                         && !pci_set_consistent_dma_mask(pdev,
1687                                                 DMA_BIT_MASK(32))) {
1688                         ioc->dma_mask = DMA_BIT_MASK(32);
1689                         dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1690                                 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1691                                 ioc->name));
1692                 } else {
1693                         printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1694                             ioc->name, pci_name(pdev));
1695                         pci_release_selected_regions(pdev, ioc->bars);
1696                         return r;
1697                 }
1698         } else {
1699                 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1700                         && !pci_set_consistent_dma_mask(pdev,
1701                                                 DMA_BIT_MASK(32))) {
1702                         ioc->dma_mask = DMA_BIT_MASK(32);
1703                         dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1704                                 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1705                                 ioc->name));
1706                 } else {
1707                         printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1708                             ioc->name, pci_name(pdev));
1709                         pci_release_selected_regions(pdev, ioc->bars);
1710                         return r;
1711                 }
1712         }
1713
1714         mem_phys = msize = 0;
1715         port = psize = 0;
1716         for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1717                 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1718                         if (psize)
1719                                 continue;
1720                         /* Get I/O space! */
1721                         port = pci_resource_start(pdev, ii);
1722                         psize = pci_resource_len(pdev, ii);
1723                 } else {
1724                         if (msize)
1725                                 continue;
1726                         /* Get memmap */
1727                         mem_phys = pci_resource_start(pdev, ii);
1728                         msize = pci_resource_len(pdev, ii);
1729                 }
1730         }
1731         ioc->mem_size = msize;
1732
1733         mem = NULL;
1734         /* Get logical ptr for PciMem0 space */
1735         /*mem = ioremap(mem_phys, msize);*/
1736         mem = ioremap(mem_phys, msize);
1737         if (mem == NULL) {
1738                 printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
1739                         " memory!\n", ioc->name);
1740                 pci_release_selected_regions(pdev, ioc->bars);
1741                 return -EINVAL;
1742         }
1743         ioc->memmap = mem;
1744         dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %llx\n",
1745             ioc->name, mem, (unsigned long long)mem_phys));
1746
1747         ioc->mem_phys = mem_phys;
1748         ioc->chip = (SYSIF_REGS __iomem *)mem;
1749
1750         /* Save Port IO values in case we need to do downloadboot */
1751         ioc->pio_mem_phys = port;
1752         ioc->pio_chip = (SYSIF_REGS __iomem *)port;
1753
1754         return 0;
1755 }
1756
1757 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1758 /**
1759  *      mpt_attach - Install a PCI intelligent MPT adapter.
1760  *      @pdev: Pointer to pci_dev structure
1761  *      @id: PCI device ID information
1762  *
1763  *      This routine performs all the steps necessary to bring the IOC of
1764  *      a MPT adapter to a OPERATIONAL state.  This includes registering
1765  *      memory regions, registering the interrupt, and allocating request
1766  *      and reply memory pools.
1767  *
1768  *      This routine also pre-fetches the LAN MAC address of a Fibre Channel
1769  *      MPT adapter.
1770  *
1771  *      Returns 0 for success, non-zero for failure.
1772  *
1773  *      TODO: Add support for polled controllers
1774  */
1775 int
1776 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1777 {
1778         MPT_ADAPTER     *ioc;
1779         u8               cb_idx;
1780         int              r = -ENODEV;
1781         u8               revision;
1782         u8               pcixcmd;
1783         static int       mpt_ids = 0;
1784 #ifdef CONFIG_PROC_FS
1785         struct proc_dir_entry *dent;
1786 #endif
1787
1788         ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1789         if (ioc == NULL) {
1790                 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1791                 return -ENOMEM;
1792         }
1793
1794         ioc->id = mpt_ids++;
1795         sprintf(ioc->name, "ioc%d", ioc->id);
1796         dinitprintk(ioc, printk(KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1797
1798         /*
1799          * set initial debug level
1800          * (refer to mptdebug.h)
1801          *
1802          */
1803         ioc->debug_level = mpt_debug_level;
1804         if (mpt_debug_level)
1805                 printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level);
1806
1807         dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
1808
1809         ioc->pcidev = pdev;
1810         if (mpt_mapresources(ioc)) {
1811                 kfree(ioc);
1812                 return r;
1813         }
1814
1815         /*
1816          * Setting up proper handlers for scatter gather handling
1817          */
1818         if (ioc->dma_mask == DMA_BIT_MASK(64)) {
1819                 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
1820                         ioc->add_sge = &mpt_add_sge_64bit_1078;
1821                 else
1822                         ioc->add_sge = &mpt_add_sge_64bit;
1823                 ioc->add_chain = &mpt_add_chain_64bit;
1824                 ioc->sg_addr_size = 8;
1825         } else {
1826                 ioc->add_sge = &mpt_add_sge;
1827                 ioc->add_chain = &mpt_add_chain;
1828                 ioc->sg_addr_size = 4;
1829         }
1830         ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
1831
1832         ioc->alloc_total = sizeof(MPT_ADAPTER);
1833         ioc->req_sz = MPT_DEFAULT_FRAME_SIZE;           /* avoid div by zero! */
1834         ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1835
1836
1837         spin_lock_init(&ioc->taskmgmt_lock);
1838         mutex_init(&ioc->internal_cmds.mutex);
1839         init_completion(&ioc->internal_cmds.done);
1840         mutex_init(&ioc->mptbase_cmds.mutex);
1841         init_completion(&ioc->mptbase_cmds.done);
1842         mutex_init(&ioc->taskmgmt_cmds.mutex);
1843         init_completion(&ioc->taskmgmt_cmds.done);
1844
1845         /* Initialize the event logging.
1846          */
1847         ioc->eventTypes = 0;    /* None */
1848         ioc->eventContext = 0;
1849         ioc->eventLogSize = 0;
1850         ioc->events = NULL;
1851
1852 #ifdef MFCNT
1853         ioc->mfcnt = 0;
1854 #endif
1855
1856         ioc->sh = NULL;
1857         ioc->cached_fw = NULL;
1858
1859         /* Initialize SCSI Config Data structure
1860          */
1861         memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1862
1863         /* Initialize the fc rport list head.
1864          */
1865         INIT_LIST_HEAD(&ioc->fc_rports);
1866
1867         /* Find lookup slot. */
1868         INIT_LIST_HEAD(&ioc->list);
1869
1870
1871         /* Initialize workqueue */
1872         INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
1873
1874         snprintf(ioc->reset_work_q_name, MPT_KOBJ_NAME_LEN,
1875                  "mpt_poll_%d", ioc->id);
1876         ioc->reset_work_q =
1877                 create_singlethread_workqueue(ioc->reset_work_q_name);
1878         if (!ioc->reset_work_q) {
1879                 printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
1880                     ioc->name);
1881                 pci_release_selected_regions(pdev, ioc->bars);
1882                 kfree(ioc);
1883                 return -ENOMEM;
1884         }
1885
1886         dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
1887             ioc->name, &ioc->facts, &ioc->pfacts[0]));
1888
1889         pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1890         mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1891
1892         switch (pdev->device)
1893         {
1894         case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1895         case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1896                 ioc->errata_flag_1064 = 1;
1897         case MPI_MANUFACTPAGE_DEVICEID_FC909:
1898         case MPI_MANUFACTPAGE_DEVICEID_FC929:
1899         case MPI_MANUFACTPAGE_DEVICEID_FC919:
1900         case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1901                 ioc->bus_type = FC;
1902                 break;
1903
1904         case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1905                 if (revision < XL_929) {
1906                         /* 929X Chip Fix. Set Split transactions level
1907                         * for PCIX. Set MOST bits to zero.
1908                         */
1909                         pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1910                         pcixcmd &= 0x8F;
1911                         pci_write_config_byte(pdev, 0x6a, pcixcmd);
1912                 } else {
1913                         /* 929XL Chip Fix. Set MMRBC to 0x08.
1914                         */
1915                         pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1916                         pcixcmd |= 0x08;
1917                         pci_write_config_byte(pdev, 0x6a, pcixcmd);
1918                 }
1919                 ioc->bus_type = FC;
1920                 break;
1921
1922         case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1923                 /* 919X Chip Fix. Set Split transactions level
1924                  * for PCIX. Set MOST bits to zero.
1925                  */
1926                 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1927                 pcixcmd &= 0x8F;
1928                 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1929                 ioc->bus_type = FC;
1930                 break;
1931
1932         case MPI_MANUFACTPAGE_DEVID_53C1030:
1933                 /* 1030 Chip Fix. Disable Split transactions
1934                  * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1935                  */
1936                 if (revision < C0_1030) {
1937                         pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1938                         pcixcmd &= 0x8F;
1939                         pci_write_config_byte(pdev, 0x6a, pcixcmd);
1940                 }
1941
1942         case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1943                 ioc->bus_type = SPI;
1944                 break;
1945
1946         case MPI_MANUFACTPAGE_DEVID_SAS1064:
1947         case MPI_MANUFACTPAGE_DEVID_SAS1068:
1948                 ioc->errata_flag_1064 = 1;
1949                 ioc->bus_type = SAS;
1950                 break;
1951
1952         case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1953         case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1954         case MPI_MANUFACTPAGE_DEVID_SAS1078:
1955                 ioc->bus_type = SAS;
1956                 break;
1957         }
1958
1959
1960         switch (ioc->bus_type) {
1961
1962         case SAS:
1963                 ioc->msi_enable = mpt_msi_enable_sas;
1964                 break;
1965
1966         case SPI:
1967                 ioc->msi_enable = mpt_msi_enable_spi;
1968                 break;
1969
1970         case FC:
1971                 ioc->msi_enable = mpt_msi_enable_fc;
1972                 break;
1973
1974         default:
1975                 ioc->msi_enable = 0;
1976                 break;
1977         }
1978
1979         ioc->fw_events_off = 1;
1980
1981         if (ioc->errata_flag_1064)
1982                 pci_disable_io_access(pdev);
1983
1984         spin_lock_init(&ioc->FreeQlock);
1985
1986         /* Disable all! */
1987         CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1988         ioc->active = 0;
1989         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1990
1991         /* Set IOC ptr in the pcidev's driver data. */
1992         pci_set_drvdata(ioc->pcidev, ioc);
1993
1994         /* Set lookup ptr. */
1995         list_add_tail(&ioc->list, &ioc_list);
1996
1997         /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1998          */
1999         mpt_detect_bound_ports(ioc, pdev);
2000
2001         INIT_LIST_HEAD(&ioc->fw_event_list);
2002         spin_lock_init(&ioc->fw_event_lock);
2003         snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN, "mpt/%d", ioc->id);
2004         ioc->fw_event_q = create_singlethread_workqueue(ioc->fw_event_q_name);
2005
2006         if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2007             CAN_SLEEP)) != 0){
2008                 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
2009                     ioc->name, r);
2010
2011                 list_del(&ioc->list);
2012                 if (ioc->alt_ioc)
2013                         ioc->alt_ioc->alt_ioc = NULL;
2014                 iounmap(ioc->memmap);
2015                 if (r != -5)
2016                         pci_release_selected_regions(pdev, ioc->bars);
2017
2018                 destroy_workqueue(ioc->reset_work_q);
2019                 ioc->reset_work_q = NULL;
2020
2021                 kfree(ioc);
2022                 pci_set_drvdata(pdev, NULL);
2023                 return r;
2024         }
2025
2026         /* call per device driver probe entry point */
2027         for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2028                 if(MptDeviceDriverHandlers[cb_idx] &&
2029                   MptDeviceDriverHandlers[cb_idx]->probe) {
2030                         MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
2031                 }
2032         }
2033
2034 #ifdef CONFIG_PROC_FS
2035         /*
2036          *  Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
2037          */
2038         dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
2039         if (dent) {
2040                 proc_create_data("info", S_IRUGO, dent, &mpt_iocinfo_proc_fops, ioc);
2041                 proc_create_data("summary", S_IRUGO, dent, &mpt_summary_proc_fops, ioc);
2042         }
2043 #endif
2044
2045         if (!ioc->alt_ioc)
2046                 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
2047                         msecs_to_jiffies(MPT_POLLING_INTERVAL));
2048
2049         return 0;
2050 }
2051
2052 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2053 /**
2054  *      mpt_detach - Remove a PCI intelligent MPT adapter.
2055  *      @pdev: Pointer to pci_dev structure
2056  */
2057
2058 void
2059 mpt_detach(struct pci_dev *pdev)
2060 {
2061         MPT_ADAPTER     *ioc = pci_get_drvdata(pdev);
2062         char pname[32];
2063         u8 cb_idx;
2064         unsigned long flags;
2065         struct workqueue_struct *wq;
2066
2067         /*
2068          * Stop polling ioc for fault condition
2069          */
2070         spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2071         wq = ioc->reset_work_q;
2072         ioc->reset_work_q = NULL;
2073         spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2074         cancel_delayed_work(&ioc->fault_reset_work);
2075         destroy_workqueue(wq);
2076
2077         spin_lock_irqsave(&ioc->fw_event_lock, flags);
2078         wq = ioc->fw_event_q;
2079         ioc->fw_event_q = NULL;
2080         spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2081         destroy_workqueue(wq);
2082
2083         sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
2084         remove_proc_entry(pname, NULL);
2085         sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
2086         remove_proc_entry(pname, NULL);
2087         sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
2088         remove_proc_entry(pname, NULL);
2089
2090         /* call per device driver remove entry point */
2091         for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2092                 if(MptDeviceDriverHandlers[cb_idx] &&
2093                   MptDeviceDriverHandlers[cb_idx]->remove) {
2094                         MptDeviceDriverHandlers[cb_idx]->remove(pdev);
2095                 }
2096         }
2097
2098         /* Disable interrupts! */
2099         CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2100
2101         ioc->active = 0;
2102         synchronize_irq(pdev->irq);
2103
2104         /* Clear any lingering interrupt */
2105         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2106
2107         CHIPREG_READ32(&ioc->chip->IntStatus);
2108
2109         mpt_adapter_dispose(ioc);
2110
2111 }
2112
2113 /**************************************************************************
2114  * Power Management
2115  */
2116 #ifdef CONFIG_PM
2117 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2118 /**
2119  *      mpt_suspend - Fusion MPT base driver suspend routine.
2120  *      @pdev: Pointer to pci_dev structure
2121  *      @state: new state to enter
2122  */
2123 int
2124 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
2125 {
2126         u32 device_state;
2127         MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2128
2129         device_state = pci_choose_state(pdev, state);
2130         printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
2131             "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2132             device_state);
2133
2134         /* put ioc into READY_STATE */
2135         if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
2136                 printk(MYIOC_s_ERR_FMT
2137                 "pci-suspend:  IOC msg unit reset failed!\n", ioc->name);
2138         }
2139
2140         /* disable interrupts */
2141         CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2142         ioc->active = 0;
2143
2144         /* Clear any lingering interrupt */
2145         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2146
2147         free_irq(ioc->pci_irq, ioc);
2148         if (ioc->msi_enable)
2149                 pci_disable_msi(ioc->pcidev);
2150         ioc->pci_irq = -1;
2151         pci_save_state(pdev);
2152         pci_disable_device(pdev);
2153         pci_release_selected_regions(pdev, ioc->bars);
2154         pci_set_power_state(pdev, device_state);
2155         return 0;
2156 }
2157
2158 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2159 /**
2160  *      mpt_resume - Fusion MPT base driver resume routine.
2161  *      @pdev: Pointer to pci_dev structure
2162  */
2163 int
2164 mpt_resume(struct pci_dev *pdev)
2165 {
2166         MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2167         u32 device_state = pdev->current_state;
2168         int recovery_state;
2169         int err;
2170
2171         printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
2172             "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2173             device_state);
2174
2175         pci_set_power_state(pdev, PCI_D0);
2176         pci_enable_wake(pdev, PCI_D0, 0);
2177         pci_restore_state(pdev);
2178         ioc->pcidev = pdev;
2179         err = mpt_mapresources(ioc);
2180         if (err)
2181                 return err;
2182
2183         if (ioc->dma_mask == DMA_BIT_MASK(64)) {
2184                 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
2185                         ioc->add_sge = &mpt_add_sge_64bit_1078;
2186                 else
2187                         ioc->add_sge = &mpt_add_sge_64bit;
2188                 ioc->add_chain = &mpt_add_chain_64bit;
2189                 ioc->sg_addr_size = 8;
2190         } else {
2191
2192                 ioc->add_sge = &mpt_add_sge;
2193                 ioc->add_chain = &mpt_add_chain;
2194                 ioc->sg_addr_size = 4;
2195         }
2196         ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
2197
2198         printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2199             ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
2200             CHIPREG_READ32(&ioc->chip->Doorbell));
2201
2202         /*
2203          * Errata workaround for SAS pci express:
2204          * Upon returning to the D0 state, the contents of the doorbell will be
2205          * stale data, and this will incorrectly signal to the host driver that
2206          * the firmware is ready to process mpt commands.   The workaround is
2207          * to issue a diagnostic reset.
2208          */
2209         if (ioc->bus_type == SAS && (pdev->device ==
2210             MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
2211             MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
2212                 if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
2213                         printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
2214                             ioc->name);
2215                         goto out;
2216                 }
2217         }
2218
2219         /* bring ioc to operational state */
2220         printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
2221         recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2222                                                  CAN_SLEEP);
2223         if (recovery_state != 0)
2224                 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
2225                     "error:[%x]\n", ioc->name, recovery_state);
2226         else
2227                 printk(MYIOC_s_INFO_FMT
2228                     "pci-resume: success\n", ioc->name);
2229  out:
2230         return 0;
2231
2232 }
2233 #endif
2234
2235 static int
2236 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
2237 {
2238         if ((MptDriverClass[index] == MPTSPI_DRIVER &&
2239              ioc->bus_type != SPI) ||
2240             (MptDriverClass[index] == MPTFC_DRIVER &&
2241              ioc->bus_type != FC) ||
2242             (MptDriverClass[index] == MPTSAS_DRIVER &&
2243              ioc->bus_type != SAS))
2244                 /* make sure we only call the relevant reset handler
2245                  * for the bus */
2246                 return 0;
2247         return (MptResetHandlers[index])(ioc, reset_phase);
2248 }
2249
2250 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2251 /**
2252  *      mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2253  *      @ioc: Pointer to MPT adapter structure
2254  *      @reason: Event word / reason
2255  *      @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2256  *
2257  *      This routine performs all the steps necessary to bring the IOC
2258  *      to a OPERATIONAL state.
2259  *
2260  *      This routine also pre-fetches the LAN MAC address of a Fibre Channel
2261  *      MPT adapter.
2262  *
2263  *      Returns:
2264  *               0 for success
2265  *              -1 if failed to get board READY
2266  *              -2 if READY but IOCFacts Failed
2267  *              -3 if READY but PrimeIOCFifos Failed
2268  *              -4 if READY but IOCInit Failed
2269  *              -5 if failed to enable_device and/or request_selected_regions
2270  *              -6 if failed to upload firmware
2271  */
2272 static int
2273 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2274 {
2275         int      hard_reset_done = 0;
2276         int      alt_ioc_ready = 0;
2277         int      hard;
2278         int      rc=0;
2279         int      ii;
2280         int      ret = 0;
2281         int      reset_alt_ioc_active = 0;
2282         int      irq_allocated = 0;
2283         u8      *a;
2284
2285         printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
2286             reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
2287
2288         /* Disable reply interrupts (also blocks FreeQ) */
2289         CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2290         ioc->active = 0;
2291
2292         if (ioc->alt_ioc) {
2293                 if (ioc->alt_ioc->active ||
2294                     reason == MPT_HOSTEVENT_IOC_RECOVER) {
2295                         reset_alt_ioc_active = 1;
2296                         /* Disable alt-IOC's reply interrupts
2297                          *  (and FreeQ) for a bit
2298                          **/
2299                         CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2300                                 0xFFFFFFFF);
2301                         ioc->alt_ioc->active = 0;
2302                 }
2303         }
2304
2305         hard = 1;
2306         if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
2307                 hard = 0;
2308
2309         if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
2310                 if (hard_reset_done == -4) {
2311                         printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
2312                             ioc->name);
2313
2314                         if (reset_alt_ioc_active && ioc->alt_ioc) {
2315                                 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2316                                 dprintk(ioc, printk(MYIOC_s_INFO_FMT
2317                                     "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
2318                                 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2319                                 ioc->alt_ioc->active = 1;
2320                         }
2321
2322                 } else {
2323                         printk(MYIOC_s_WARN_FMT
2324                             "NOT READY WARNING!\n", ioc->name);
2325                 }
2326                 ret = -1;
2327                 goto out;
2328         }
2329
2330         /* hard_reset_done = 0 if a soft reset was performed
2331          * and 1 if a hard reset was performed.
2332          */
2333         if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
2334                 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
2335                         alt_ioc_ready = 1;
2336                 else
2337                         printk(MYIOC_s_WARN_FMT
2338                             ": alt-ioc Not ready WARNING!\n",
2339                             ioc->alt_ioc->name);
2340         }
2341
2342         for (ii=0; ii<5; ii++) {
2343                 /* Get IOC facts! Allow 5 retries */
2344                 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
2345                         break;
2346         }
2347
2348
2349         if (ii == 5) {
2350                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2351                     "Retry IocFacts failed rc=%x\n", ioc->name, rc));
2352                 ret = -2;
2353         } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2354                 MptDisplayIocCapabilities(ioc);
2355         }
2356
2357         if (alt_ioc_ready) {
2358                 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
2359                         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2360                             "Initial Alt IocFacts failed rc=%x\n",
2361                             ioc->name, rc));
2362                         /* Retry - alt IOC was initialized once
2363                          */
2364                         rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
2365                 }
2366                 if (rc) {
2367                         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2368                             "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
2369                         alt_ioc_ready = 0;
2370                         reset_alt_ioc_active = 0;
2371                 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2372                         MptDisplayIocCapabilities(ioc->alt_ioc);
2373                 }
2374         }
2375
2376         if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) &&
2377             (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) {
2378                 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2379                 ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
2380                     IORESOURCE_IO);
2381                 if (pci_enable_device(ioc->pcidev))
2382                         return -5;
2383                 if (pci_request_selected_regions(ioc->pcidev, ioc->bars,
2384                         "mpt"))
2385                         return -5;
2386         }
2387
2388         /*
2389          * Device is reset now. It must have de-asserted the interrupt line
2390          * (if it was asserted) and it should be safe to register for the
2391          * interrupt now.
2392          */
2393         if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2394                 ioc->pci_irq = -1;
2395                 if (ioc->pcidev->irq) {
2396                         if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
2397                                 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
2398                                     ioc->name);
2399                         else
2400                                 ioc->msi_enable = 0;
2401                         rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
2402                             IRQF_SHARED, ioc->name, ioc);
2403                         if (rc < 0) {
2404                                 printk(MYIOC_s_ERR_FMT "Unable to allocate "
2405                                     "interrupt %d!\n",
2406                                     ioc->name, ioc->pcidev->irq);
2407                                 if (ioc->msi_enable)
2408                                         pci_disable_msi(ioc->pcidev);
2409                                 ret = -EBUSY;
2410                                 goto out;
2411                         }
2412                         irq_allocated = 1;
2413                         ioc->pci_irq = ioc->pcidev->irq;
2414                         pci_set_master(ioc->pcidev);            /* ?? */
2415                         pci_set_drvdata(ioc->pcidev, ioc);
2416                         dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2417                             "installed at interrupt %d\n", ioc->name,
2418                             ioc->pcidev->irq));
2419                 }
2420         }
2421
2422         /* Prime reply & request queues!
2423          * (mucho alloc's) Must be done prior to
2424          * init as upper addresses are needed for init.
2425          * If fails, continue with alt-ioc processing
2426          */
2427         dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "PrimeIocFifos\n",
2428             ioc->name));
2429         if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2430                 ret = -3;
2431
2432         /* May need to check/upload firmware & data here!
2433          * If fails, continue with alt-ioc processing
2434          */
2435         dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "SendIocInit\n",
2436             ioc->name));
2437         if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2438                 ret = -4;
2439 // NEW!
2440         if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2441                 printk(MYIOC_s_WARN_FMT
2442                     ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n",
2443                     ioc->alt_ioc->name, rc);
2444                 alt_ioc_ready = 0;
2445                 reset_alt_ioc_active = 0;
2446         }
2447
2448         if (alt_ioc_ready) {
2449                 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2450                         alt_ioc_ready = 0;
2451                         reset_alt_ioc_active = 0;
2452                         printk(MYIOC_s_WARN_FMT
2453                                 ": alt-ioc: (%d) init failure WARNING!\n",
2454                                         ioc->alt_ioc->name, rc);
2455                 }
2456         }
2457
2458         if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2459                 if (ioc->upload_fw) {
2460                         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2461                             "firmware upload required!\n", ioc->name));
2462
2463                         /* Controller is not operational, cannot do upload
2464                          */
2465                         if (ret == 0) {
2466                                 rc = mpt_do_upload(ioc, sleepFlag);
2467                                 if (rc == 0) {
2468                                         if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2469                                                 /*
2470                                                  * Maintain only one pointer to FW memory
2471                                                  * so there will not be two attempt to
2472                                                  * downloadboot onboard dual function
2473                                                  * chips (mpt_adapter_disable,
2474                                                  * mpt_diag_reset)
2475                                                  */
2476                                                 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2477                                                     "mpt_upload:  alt_%s has cached_fw=%p \n",
2478                                                     ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2479                                                 ioc->cached_fw = NULL;
2480                                         }
2481                                 } else {
2482                                         printk(MYIOC_s_WARN_FMT
2483                                             "firmware upload failure!\n", ioc->name);
2484                                         ret = -6;
2485                                 }
2486                         }
2487                 }
2488         }
2489
2490         /*  Enable MPT base driver management of EventNotification
2491          *  and EventAck handling.
2492          */
2493         if ((ret == 0) && (!ioc->facts.EventState)) {
2494                 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2495                         "SendEventNotification\n",
2496                     ioc->name));
2497                 ret = SendEventNotification(ioc, 1, sleepFlag); /* 1=Enable */
2498         }
2499
2500         if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2501                 rc = SendEventNotification(ioc->alt_ioc, 1, sleepFlag);
2502
2503         if (ret == 0) {
2504                 /* Enable! (reply interrupt) */
2505                 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2506                 ioc->active = 1;
2507         }
2508         if (rc == 0) {  /* alt ioc */
2509                 if (reset_alt_ioc_active && ioc->alt_ioc) {
2510                         /* (re)Enable alt-IOC! (reply interrupt) */
2511                         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "alt-ioc"
2512                                 "reply irq re-enabled\n",
2513                                 ioc->alt_ioc->name));
2514                         CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2515                                 MPI_HIM_DIM);
2516                         ioc->alt_ioc->active = 1;
2517                 }
2518         }
2519
2520
2521         /*      Add additional "reason" check before call to GetLanConfigPages
2522          *      (combined with GetIoUnitPage2 call).  This prevents a somewhat
2523          *      recursive scenario; GetLanConfigPages times out, timer expired
2524          *      routine calls HardResetHandler, which calls into here again,
2525          *      and we try GetLanConfigPages again...
2526          */
2527         if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2528
2529                 /*
2530                  * Initialize link list for inactive raid volumes.
2531                  */
2532                 mutex_init(&ioc->raid_data.inactive_list_mutex);
2533                 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2534
2535                 switch (ioc->bus_type) {
2536
2537                 case SAS:
2538                         /* clear persistency table */
2539                         if(ioc->facts.IOCExceptions &
2540                             MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2541                                 ret = mptbase_sas_persist_operation(ioc,
2542                                     MPI_SAS_OP_CLEAR_NOT_PRESENT);
2543                                 if(ret != 0)
2544                                         goto out;
2545                         }
2546
2547                         /* Find IM volumes
2548                          */
2549                         mpt_findImVolumes(ioc);
2550
2551                         /* Check, and possibly reset, the coalescing value
2552                          */
2553                         mpt_read_ioc_pg_1(ioc);
2554
2555                         break;
2556
2557                 case FC:
2558                         if ((ioc->pfacts[0].ProtocolFlags &
2559                                 MPI_PORTFACTS_PROTOCOL_LAN) &&
2560                             (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2561                                 /*
2562                                  *  Pre-fetch the ports LAN MAC address!
2563                                  *  (LANPage1_t stuff)
2564                                  */
2565                                 (void) GetLanConfigPages(ioc);
2566                                 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2567                                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2568                                         "LanAddr = %02X:%02X:%02X"
2569                                         ":%02X:%02X:%02X\n",
2570                                         ioc->name, a[5], a[4],
2571                                         a[3], a[2], a[1], a[0]));
2572                         }
2573                         break;
2574
2575                 case SPI:
2576                         /* Get NVRAM and adapter maximums from SPP 0 and 2
2577                          */
2578                         mpt_GetScsiPortSettings(ioc, 0);
2579
2580                         /* Get version and length of SDP 1
2581                          */
2582                         mpt_readScsiDevicePageHeaders(ioc, 0);
2583
2584                         /* Find IM volumes
2585                          */
2586                         if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2587                                 mpt_findImVolumes(ioc);
2588
2589                         /* Check, and possibly reset, the coalescing value
2590                          */
2591                         mpt_read_ioc_pg_1(ioc);
2592
2593                         mpt_read_ioc_pg_4(ioc);
2594
2595                         break;
2596                 }
2597
2598                 GetIoUnitPage2(ioc);
2599                 mpt_get_manufacturing_pg_0(ioc);
2600         }
2601
2602  out:
2603         if ((ret != 0) && irq_allocated) {
2604                 free_irq(ioc->pci_irq, ioc);
2605                 if (ioc->msi_enable)
2606                         pci_disable_msi(ioc->pcidev);
2607         }
2608         return ret;
2609 }
2610
2611 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2612 /**
2613  *      mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2614  *      @ioc: Pointer to MPT adapter structure
2615  *      @pdev: Pointer to (struct pci_dev) structure
2616  *
2617  *      Search for PCI bus/dev_function which matches
2618  *      PCI bus/dev_function (+/-1) for newly discovered 929,
2619  *      929X, 1030 or 1035.
2620  *
2621  *      If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2622  *      using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2623  */
2624 static void
2625 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2626 {
2627         struct pci_dev *peer=NULL;
2628         unsigned int slot = PCI_SLOT(pdev->devfn);
2629         unsigned int func = PCI_FUNC(pdev->devfn);
2630         MPT_ADAPTER *ioc_srch;
2631
2632         dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2633             " searching for devfn match on %x or %x\n",
2634             ioc->name, pci_name(pdev), pdev->bus->number,
2635             pdev->devfn, func-1, func+1));
2636
2637         peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2638         if (!peer) {
2639                 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2640                 if (!peer)
2641                         return;
2642         }
2643
2644         list_for_each_entry(ioc_srch, &ioc_list, list) {
2645                 struct pci_dev *_pcidev = ioc_srch->pcidev;
2646                 if (_pcidev == peer) {
2647                         /* Paranoia checks */
2648                         if (ioc->alt_ioc != NULL) {
2649                                 printk(MYIOC_s_WARN_FMT
2650                                     "Oops, already bound (%s <==> %s)!\n",
2651                                     ioc->name, ioc->name, ioc->alt_ioc->name);
2652                                 break;
2653                         } else if (ioc_srch->alt_ioc != NULL) {
2654                                 printk(MYIOC_s_WARN_FMT
2655                                     "Oops, already bound (%s <==> %s)!\n",
2656                                     ioc_srch->name, ioc_srch->name,
2657                                     ioc_srch->alt_ioc->name);
2658                                 break;
2659                         }
2660                         dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2661                                 "FOUND! binding %s <==> %s\n",
2662                                 ioc->name, ioc->name, ioc_srch->name));
2663                         ioc_srch->alt_ioc = ioc;
2664                         ioc->alt_ioc = ioc_srch;
2665                 }
2666         }
2667         pci_dev_put(peer);
2668 }
2669
2670 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2671 /**
2672  *      mpt_adapter_disable - Disable misbehaving MPT adapter.
2673  *      @ioc: Pointer to MPT adapter structure
2674  */
2675 static void
2676 mpt_adapter_disable(MPT_ADAPTER *ioc)
2677 {
2678         int sz;
2679         int ret;
2680
2681         if (ioc->cached_fw != NULL) {
2682                 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2683                         "%s: Pushing FW onto adapter\n", __func__, ioc->name));
2684                 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2685                     ioc->cached_fw, CAN_SLEEP)) < 0) {
2686                         printk(MYIOC_s_WARN_FMT
2687                             ": firmware downloadboot failure (%d)!\n",
2688                             ioc->name, ret);
2689                 }
2690         }
2691
2692         /*
2693          * Put the controller into ready state (if its not already)
2694          */
2695         if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY) {
2696                 if (!SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET,
2697                     CAN_SLEEP)) {
2698                         if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY)
2699                                 printk(MYIOC_s_ERR_FMT "%s:  IOC msg unit "
2700                                     "reset failed to put ioc in ready state!\n",
2701                                     ioc->name, __func__);
2702                 } else
2703                         printk(MYIOC_s_ERR_FMT "%s:  IOC msg unit reset "
2704                             "failed!\n", ioc->name, __func__);
2705         }
2706
2707
2708         /* Disable adapter interrupts! */
2709         synchronize_irq(ioc->pcidev->irq);
2710         CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2711         ioc->active = 0;
2712
2713         /* Clear any lingering interrupt */
2714         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2715         CHIPREG_READ32(&ioc->chip->IntStatus);
2716
2717         if (ioc->alloc != NULL) {
2718                 sz = ioc->alloc_sz;
2719                 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free  @ %p, sz=%d bytes\n",
2720                     ioc->name, ioc->alloc, ioc->alloc_sz));
2721                 pci_free_consistent(ioc->pcidev, sz,
2722                                 ioc->alloc, ioc->alloc_dma);
2723                 ioc->reply_frames = NULL;
2724                 ioc->req_frames = NULL;
2725                 ioc->alloc = NULL;
2726                 ioc->alloc_total -= sz;
2727         }
2728
2729         if (ioc->sense_buf_pool != NULL) {
2730                 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2731                 pci_free_consistent(ioc->pcidev, sz,
2732                                 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2733                 ioc->sense_buf_pool = NULL;
2734                 ioc->alloc_total -= sz;
2735         }
2736
2737         if (ioc->events != NULL){
2738                 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2739                 kfree(ioc->events);
2740                 ioc->events = NULL;
2741                 ioc->alloc_total -= sz;
2742         }
2743
2744         mpt_free_fw_memory(ioc);
2745
2746         kfree(ioc->spi_data.nvram);
2747         mpt_inactive_raid_list_free(ioc);
2748         kfree(ioc->raid_data.pIocPg2);
2749         kfree(ioc->raid_data.pIocPg3);
2750         ioc->spi_data.nvram = NULL;
2751         ioc->raid_data.pIocPg3 = NULL;
2752
2753         if (ioc->spi_data.pIocPg4 != NULL) {
2754                 sz = ioc->spi_data.IocPg4Sz;
2755                 pci_free_consistent(ioc->pcidev, sz,
2756                         ioc->spi_data.pIocPg4,
2757                         ioc->spi_data.IocPg4_dma);
2758                 ioc->spi_data.pIocPg4 = NULL;
2759                 ioc->alloc_total -= sz;
2760         }
2761
2762         if (ioc->ReqToChain != NULL) {
2763                 kfree(ioc->ReqToChain);
2764                 kfree(ioc->RequestNB);
2765                 ioc->ReqToChain = NULL;
2766         }
2767
2768         kfree(ioc->ChainToChain);
2769         ioc->ChainToChain = NULL;
2770
2771         if (ioc->HostPageBuffer != NULL) {
2772                 if((ret = mpt_host_page_access_control(ioc,
2773                     MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2774                         printk(MYIOC_s_ERR_FMT
2775                            ": %s: host page buffers free failed (%d)!\n",
2776                             ioc->name, __func__, ret);
2777                 }
2778                 dexitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2779                         "HostPageBuffer free  @ %p, sz=%d bytes\n",
2780                         ioc->name, ioc->HostPageBuffer,
2781                         ioc->HostPageBuffer_sz));
2782                 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2783                     ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2784                 ioc->HostPageBuffer = NULL;
2785                 ioc->HostPageBuffer_sz = 0;
2786                 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2787         }
2788
2789         pci_set_drvdata(ioc->pcidev, NULL);
2790 }
2791 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2792 /**
2793  *      mpt_adapter_dispose - Free all resources associated with an MPT adapter
2794  *      @ioc: Pointer to MPT adapter structure
2795  *
2796  *      This routine unregisters h/w resources and frees all alloc'd memory
2797  *      associated with a MPT adapter structure.
2798  */
2799 static void
2800 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2801 {
2802         int sz_first, sz_last;
2803
2804         if (ioc == NULL)
2805                 return;
2806
2807         sz_first = ioc->alloc_total;
2808
2809         mpt_adapter_disable(ioc);
2810
2811         if (ioc->pci_irq != -1) {
2812                 free_irq(ioc->pci_irq, ioc);
2813                 if (ioc->msi_enable)
2814                         pci_disable_msi(ioc->pcidev);
2815                 ioc->pci_irq = -1;
2816         }
2817
2818         if (ioc->memmap != NULL) {
2819                 iounmap(ioc->memmap);
2820                 ioc->memmap = NULL;
2821         }
2822
2823         pci_disable_device(ioc->pcidev);
2824         pci_release_selected_regions(ioc->pcidev, ioc->bars);
2825
2826 #if defined(CONFIG_MTRR) && 0
2827         if (ioc->mtrr_reg > 0) {
2828                 mtrr_del(ioc->mtrr_reg, 0, 0);
2829                 dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name));
2830         }
2831 #endif
2832
2833         /*  Zap the adapter lookup ptr!  */
2834         list_del(&ioc->list);
2835
2836         sz_last = ioc->alloc_total;
2837         dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2838             ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2839
2840         if (ioc->alt_ioc)
2841                 ioc->alt_ioc->alt_ioc = NULL;
2842
2843         kfree(ioc);
2844 }
2845
2846 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2847 /**
2848  *      MptDisplayIocCapabilities - Disply IOC's capabilities.
2849  *      @ioc: Pointer to MPT adapter structure
2850  */
2851 static void
2852 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2853 {
2854         int i = 0;
2855
2856         printk(KERN_INFO "%s: ", ioc->name);
2857         if (ioc->prod_name)
2858                 printk("%s: ", ioc->prod_name);
2859         printk("Capabilities={");
2860
2861         if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2862                 printk("Initiator");
2863                 i++;
2864         }
2865
2866         if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2867                 printk("%sTarget", i ? "," : "");
2868                 i++;
2869         }
2870
2871         if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2872                 printk("%sLAN", i ? "," : "");
2873                 i++;
2874         }
2875
2876 #if 0
2877         /*
2878          *  This would probably evoke more questions than it's worth
2879          */
2880         if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2881                 printk("%sLogBusAddr", i ? "," : "");
2882                 i++;
2883         }
2884 #endif
2885
2886         printk("}\n");
2887 }
2888
2889 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2890 /**
2891  *      MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2892  *      @ioc: Pointer to MPT_ADAPTER structure
2893  *      @force: Force hard KickStart of IOC
2894  *      @sleepFlag: Specifies whether the process can sleep
2895  *
2896  *      Returns:
2897  *               1 - DIAG reset and READY
2898  *               0 - READY initially OR soft reset and READY
2899  *              -1 - Any failure on KickStart
2900  *              -2 - Msg Unit Reset Failed
2901  *              -3 - IO Unit Reset Failed
2902  *              -4 - IOC owned by a PEER
2903  */
2904 static int
2905 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2906 {
2907         u32      ioc_state;
2908         int      statefault = 0;
2909         int      cntdn;
2910         int      hard_reset_done = 0;
2911         int      r;
2912         int      ii;
2913         int      whoinit;
2914
2915         /* Get current [raw] IOC state  */
2916         ioc_state = mpt_GetIocState(ioc, 0);
2917         dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2918
2919         /*
2920          *      Check to see if IOC got left/stuck in doorbell handshake
2921          *      grip of death.  If so, hard reset the IOC.
2922          */
2923         if (ioc_state & MPI_DOORBELL_ACTIVE) {
2924                 statefault = 1;
2925                 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2926                                 ioc->name);
2927         }
2928
2929         /* Is it already READY? */
2930         if (!statefault &&
2931             ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)) {
2932                 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2933                     "IOC is in READY state\n", ioc->name));
2934                 return 0;
2935         }
2936
2937         /*
2938          *      Check to see if IOC is in FAULT state.
2939          */
2940         if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2941                 statefault = 2;
2942                 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2943                     ioc->name);
2944                 printk(MYIOC_s_WARN_FMT "           FAULT code = %04xh\n",
2945                     ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2946         }
2947
2948         /*
2949          *      Hmmm...  Did it get left operational?
2950          */
2951         if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2952                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2953                                 ioc->name));
2954
2955                 /* Check WhoInit.
2956                  * If PCI Peer, exit.
2957                  * Else, if no fault conditions are present, issue a MessageUnitReset
2958                  * Else, fall through to KickStart case
2959                  */
2960                 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2961                 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2962                         "whoinit 0x%x statefault %d force %d\n",
2963                         ioc->name, whoinit, statefault, force));
2964                 if (whoinit == MPI_WHOINIT_PCI_PEER)
2965                         return -4;
2966                 else {
2967                         if ((statefault == 0 ) && (force == 0)) {
2968                                 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2969                                         return 0;
2970                         }
2971                         statefault = 3;
2972                 }
2973         }
2974
2975         hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2976         if (hard_reset_done < 0)
2977                 return -1;
2978
2979         /*
2980          *  Loop here waiting for IOC to come READY.
2981          */
2982         ii = 0;
2983         cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5;     /* 5 seconds */
2984
2985         while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2986                 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2987                         /*
2988                          *  BIOS or previous driver load left IOC in OP state.
2989                          *  Reset messaging FIFOs.
2990                          */
2991                         if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2992                                 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2993                                 return -2;
2994                         }
2995                 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2996                         /*
2997                          *  Something is wrong.  Try to get IOC back
2998                          *  to a known state.
2999                          */
3000                         if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
3001                                 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
3002                                 return -3;
3003                         }
3004                 }
3005
3006                 ii++; cntdn--;
3007                 if (!cntdn) {
3008                         printk(MYIOC_s_ERR_FMT
3009                                 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
3010                                 ioc->name, ioc_state, (int)((ii+5)/HZ));
3011                         return -ETIME;
3012                 }
3013
3014                 if (sleepFlag == CAN_SLEEP) {
3015                         msleep(1);
3016                 } else {
3017                         mdelay (1);     /* 1 msec delay */
3018                 }
3019
3020         }
3021
3022         if (statefault < 3) {
3023                 printk(MYIOC_s_INFO_FMT "Recovered from %s\n", ioc->name,
3024                         statefault == 1 ? "stuck handshake" : "IOC FAULT");
3025         }
3026
3027         return hard_reset_done;
3028 }
3029
3030 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3031 /**
3032  *      mpt_GetIocState - Get the current state of a MPT adapter.
3033  *      @ioc: Pointer to MPT_ADAPTER structure
3034  *      @cooked: Request raw or cooked IOC state
3035  *
3036  *      Returns all IOC Doorbell register bits if cooked==0, else just the
3037  *      Doorbell bits in MPI_IOC_STATE_MASK.
3038  */
3039 u32
3040 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
3041 {
3042         u32 s, sc;
3043
3044         /*  Get!  */
3045         s = CHIPREG_READ32(&ioc->chip->Doorbell);
3046         sc = s & MPI_IOC_STATE_MASK;
3047
3048         /*  Save!  */
3049         ioc->last_state = sc;
3050
3051         return cooked ? sc : s;
3052 }
3053
3054 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3055 /**
3056  *      GetIocFacts - Send IOCFacts request to MPT adapter.
3057  *      @ioc: Pointer to MPT_ADAPTER structure
3058  *      @sleepFlag: Specifies whether the process can sleep
3059  *      @reason: If recovery, only update facts.
3060  *
3061  *      Returns 0 for success, non-zero for failure.
3062  */
3063 static int
3064 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
3065 {
3066         IOCFacts_t               get_facts;
3067         IOCFactsReply_t         *facts;
3068         int                      r;
3069         int                      req_sz;
3070         int                      reply_sz;
3071         int                      sz;
3072         u32                      status, vv;
3073         u8                       shiftFactor=1;
3074
3075         /* IOC *must* NOT be in RESET state! */
3076         if (ioc->last_state == MPI_IOC_STATE_RESET) {
3077                 printk(KERN_ERR MYNAM
3078                     ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
3079                     ioc->name, ioc->last_state);
3080                 return -44;
3081         }
3082
3083         facts = &ioc->facts;
3084
3085         /* Destination (reply area)... */
3086         reply_sz = sizeof(*facts);
3087         memset(facts, 0, reply_sz);
3088
3089         /* Request area (get_facts on the stack right now!) */
3090         req_sz = sizeof(get_facts);
3091         memset(&get_facts, 0, req_sz);
3092
3093         get_facts.Function = MPI_FUNCTION_IOC_FACTS;
3094         /* Assert: All other get_facts fields are zero! */
3095
3096         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3097             "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
3098             ioc->name, req_sz, reply_sz));
3099
3100         /* No non-zero fields in the get_facts request are greater than
3101          * 1 byte in size, so we can just fire it off as is.
3102          */
3103         r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
3104                         reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
3105         if (r != 0)
3106                 return r;
3107
3108         /*
3109          * Now byte swap (GRRR) the necessary fields before any further
3110          * inspection of reply contents.
3111          *
3112          * But need to do some sanity checks on MsgLength (byte) field
3113          * to make sure we don't zero IOC's req_sz!
3114          */
3115         /* Did we get a valid reply? */
3116         if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
3117                 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3118                         /*
3119                          * If not been here, done that, save off first WhoInit value
3120                          */
3121                         if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
3122                                 ioc->FirstWhoInit = facts->WhoInit;
3123                 }
3124
3125                 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
3126                 facts->MsgContext = le32_to_cpu(facts->MsgContext);
3127                 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
3128                 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
3129                 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
3130                 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
3131                 /* CHECKME! IOCStatus, IOCLogInfo */
3132
3133                 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
3134                 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
3135
3136                 /*
3137                  * FC f/w version changed between 1.1 and 1.2
3138                  *      Old: u16{Major(4),Minor(4),SubMinor(8)}
3139                  *      New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
3140                  */
3141                 if (facts->MsgVersion < MPI_VERSION_01_02) {
3142                         /*
3143                          *      Handle old FC f/w style, convert to new...
3144                          */
3145                         u16      oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
3146                         facts->FWVersion.Word =
3147                                         ((oldv<<12) & 0xFF000000) |
3148                                         ((oldv<<8)  & 0x000FFF00);
3149                 } else
3150                         facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
3151
3152                 facts->ProductID = le16_to_cpu(facts->ProductID);
3153
3154                 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
3155                     > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
3156                         ioc->ir_firmware = 1;
3157
3158                 facts->CurrentHostMfaHighAddr =
3159                                 le32_to_cpu(facts->CurrentHostMfaHighAddr);
3160                 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
3161                 facts->CurrentSenseBufferHighAddr =
3162                                 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
3163                 facts->CurReplyFrameSize =
3164                                 le16_to_cpu(facts->CurReplyFrameSize);
3165                 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
3166
3167                 /*
3168                  * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
3169                  * Older MPI-1.00.xx struct had 13 dwords, and enlarged
3170                  * to 14 in MPI-1.01.0x.
3171                  */
3172                 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
3173                     facts->MsgVersion > MPI_VERSION_01_00) {
3174                         facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
3175                 }
3176
3177                 sz = facts->FWImageSize;
3178                 if ( sz & 0x01 )
3179                         sz += 1;
3180                 if ( sz & 0x02 )
3181                         sz += 2;
3182                 facts->FWImageSize = sz;
3183
3184                 if (!facts->RequestFrameSize) {
3185                         /*  Something is wrong!  */
3186                         printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
3187                                         ioc->name);
3188                         return -55;
3189                 }
3190
3191                 r = sz = facts->BlockSize;
3192                 vv = ((63 / (sz * 4)) + 1) & 0x03;
3193                 ioc->NB_for_64_byte_frame = vv;
3194                 while ( sz )
3195                 {
3196                         shiftFactor++;
3197                         sz = sz >> 1;
3198                 }
3199                 ioc->NBShiftFactor  = shiftFactor;
3200                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3201                     "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
3202                     ioc->name, vv, shiftFactor, r));
3203
3204                 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3205                         /*
3206                          * Set values for this IOC's request & reply frame sizes,
3207                          * and request & reply queue depths...
3208                          */
3209                         ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
3210                         ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
3211                         ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
3212                         ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
3213
3214                         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
3215                                 ioc->name, ioc->reply_sz, ioc->reply_depth));
3216                         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz  =%3d, req_depth  =%4d\n",
3217                                 ioc->name, ioc->req_sz, ioc->req_depth));
3218
3219                         /* Get port facts! */
3220                         if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
3221                                 return r;
3222                 }
3223         } else {
3224                 printk(MYIOC_s_ERR_FMT
3225                      "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
3226                      ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
3227                      RequestFrameSize)/sizeof(u32)));
3228                 return -66;
3229         }
3230
3231         return 0;
3232 }
3233
3234 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3235 /**
3236  *      GetPortFacts - Send PortFacts request to MPT adapter.
3237  *      @ioc: Pointer to MPT_ADAPTER structure
3238  *      @portnum: Port number
3239  *      @sleepFlag: Specifies whether the process can sleep
3240  *
3241  *      Returns 0 for success, non-zero for failure.
3242  */
3243 static int
3244 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3245 {
3246         PortFacts_t              get_pfacts;
3247         PortFactsReply_t        *pfacts;
3248         int                      ii;
3249         int                      req_sz;
3250         int                      reply_sz;
3251         int                      max_id;
3252
3253         /* IOC *must* NOT be in RESET state! */
3254         if (ioc->last_state == MPI_IOC_STATE_RESET) {
3255                 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
3256                     ioc->name, ioc->last_state );
3257                 return -4;
3258         }
3259
3260         pfacts = &ioc->pfacts[portnum];
3261
3262         /* Destination (reply area)...  */
3263         reply_sz = sizeof(*pfacts);
3264         memset(pfacts, 0, reply_sz);
3265
3266         /* Request area (get_pfacts on the stack right now!) */
3267         req_sz = sizeof(get_pfacts);
3268         memset(&get_pfacts, 0, req_sz);
3269
3270         get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
3271         get_pfacts.PortNumber = portnum;
3272         /* Assert: All other get_pfacts fields are zero! */
3273
3274         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
3275                         ioc->name, portnum));
3276
3277         /* No non-zero fields in the get_pfacts request are greater than
3278          * 1 byte in size, so we can just fire it off as is.
3279          */
3280         ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
3281                                 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
3282         if (ii != 0)
3283                 return ii;
3284
3285         /* Did we get a valid reply? */
3286
3287         /* Now byte swap the necessary fields in the response. */
3288         pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
3289         pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
3290         pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
3291         pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
3292         pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
3293         pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
3294         pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
3295         pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
3296         pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
3297
3298         max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
3299             pfacts->MaxDevices;
3300         ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
3301         ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
3302
3303         /*
3304          * Place all the devices on channels
3305          *
3306          * (for debuging)
3307          */
3308         if (mpt_channel_mapping) {
3309                 ioc->devices_per_bus = 1;
3310                 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
3311         }
3312
3313         return 0;
3314 }
3315
3316 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3317 /**
3318  *      SendIocInit - Send IOCInit request to MPT adapter.
3319  *      @ioc: Pointer to MPT_ADAPTER structure
3320  *      @sleepFlag: Specifies whether the process can sleep
3321  *
3322  *      Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3323  *
3324  *      Returns 0 for success, non-zero for failure.
3325  */
3326 static int
3327 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
3328 {
3329         IOCInit_t                ioc_init;
3330         MPIDefaultReply_t        init_reply;
3331         u32                      state;
3332         int                      r;
3333         int                      count;
3334         int                      cntdn;
3335
3336         memset(&ioc_init, 0, sizeof(ioc_init));
3337         memset(&init_reply, 0, sizeof(init_reply));
3338
3339         ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
3340         ioc_init.Function = MPI_FUNCTION_IOC_INIT;
3341
3342         /* If we are in a recovery mode and we uploaded the FW image,
3343          * then this pointer is not NULL. Skip the upload a second time.
3344          * Set this flag if cached_fw set for either IOC.
3345          */
3346         if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
3347                 ioc->upload_fw = 1;
3348         else
3349                 ioc->upload_fw = 0;
3350         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
3351                    ioc->name, ioc->upload_fw, ioc->facts.Flags));
3352
3353         ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
3354         ioc_init.MaxBuses = (U8)ioc->number_of_buses;
3355
3356         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
3357                    ioc->name, ioc->facts.MsgVersion));
3358         if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
3359                 // set MsgVersion and HeaderVersion host driver was built with
3360                 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
3361                 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
3362
3363                 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
3364                         ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
3365                 } else if(mpt_host_page_alloc(ioc, &ioc_init))
3366                         return -99;
3367         }
3368         ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz);   /* in BYTES */
3369
3370         if (ioc->sg_addr_size == sizeof(u64)) {
3371                 /* Save the upper 32-bits of the request
3372                  * (reply) and sense buffers.
3373                  */
3374                 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
3375                 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
3376         } else {
3377                 /* Force 32-bit addressing */
3378                 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
3379                 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
3380         }
3381
3382         ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
3383         ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
3384         ioc->facts.MaxDevices = ioc_init.MaxDevices;
3385         ioc->facts.MaxBuses = ioc_init.MaxBuses;
3386
3387         dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
3388                         ioc->name, &ioc_init));
3389
3390         r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
3391                                 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
3392         if (r != 0) {
3393                 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
3394                 return r;
3395         }
3396
3397         /* No need to byte swap the multibyte fields in the reply
3398          * since we don't even look at its contents.
3399          */
3400
3401         dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
3402                         ioc->name, &ioc_init));
3403
3404         if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
3405                 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
3406                 return r;
3407         }
3408
3409         /* YIKES!  SUPER IMPORTANT!!!
3410          *  Poll IocState until _OPERATIONAL while IOC is doing
3411          *  LoopInit and TargetDiscovery!
3412          */
3413         count = 0;
3414         cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60;    /* 60 seconds */
3415         state = mpt_GetIocState(ioc, 1);
3416         while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
3417                 if (sleepFlag == CAN_SLEEP) {
3418                         msleep(1);
3419                 } else {
3420                         mdelay(1);
3421                 }
3422
3423                 if (!cntdn) {
3424                         printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
3425                                         ioc->name, (int)((count+5)/HZ));
3426                         return -9;
3427                 }
3428
3429                 state = mpt_GetIocState(ioc, 1);
3430                 count++;
3431         }
3432         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
3433                         ioc->name, count));
3434
3435         ioc->aen_event_read_flag=0;
3436         return r;
3437 }
3438
3439 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3440 /**
3441  *      SendPortEnable - Send PortEnable request to MPT adapter port.
3442  *      @ioc: Pointer to MPT_ADAPTER structure
3443  *      @portnum: Port number to enable
3444  *      @sleepFlag: Specifies whether the process can sleep
3445  *
3446  *      Send PortEnable to bring IOC to OPERATIONAL state.
3447  *
3448  *      Returns 0 for success, non-zero for failure.
3449  */
3450 static int
3451 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3452 {
3453         PortEnable_t             port_enable;
3454         MPIDefaultReply_t        reply_buf;
3455         int      rc;
3456         int      req_sz;
3457         int      reply_sz;
3458
3459         /*  Destination...  */
3460         reply_sz = sizeof(MPIDefaultReply_t);
3461         memset(&reply_buf, 0, reply_sz);
3462
3463         req_sz = sizeof(PortEnable_t);
3464         memset(&port_enable, 0, req_sz);
3465
3466         port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3467         port_enable.PortNumber = portnum;
3468 /*      port_enable.ChainOffset = 0;            */
3469 /*      port_enable.MsgFlags = 0;               */
3470 /*      port_enable.MsgContext = 0;             */
3471
3472         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3473                         ioc->name, portnum, &port_enable));
3474
3475         /* RAID FW may take a long time to enable
3476          */
3477         if (ioc->ir_firmware || ioc->bus_type == SAS) {
3478                 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3479                 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3480                 300 /*seconds*/, sleepFlag);
3481         } else {
3482                 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3483                 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3484                 30 /*seconds*/, sleepFlag);
3485         }
3486         return rc;
3487 }
3488
3489 /**
3490  *      mpt_alloc_fw_memory - allocate firmware memory
3491  *      @ioc: Pointer to MPT_ADAPTER structure
3492  *      @size: total FW bytes
3493  *
3494  *      If memory has already been allocated, the same (cached) value
3495  *      is returned.
3496  *
3497  *      Return 0 if successful, or non-zero for failure
3498  **/
3499 int
3500 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3501 {
3502         int rc;
3503
3504         if (ioc->cached_fw) {
3505                 rc = 0;  /* use already allocated memory */
3506                 goto out;
3507         }
3508         else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3509                 ioc->cached_fw = ioc->alt_ioc->cached_fw;  /* use alt_ioc's memory */
3510                 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3511                 rc = 0;
3512                 goto out;
3513         }
3514         ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3515         if (!ioc->cached_fw) {
3516                 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3517                     ioc->name);
3518                 rc = -1;
3519         } else {
3520                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image  @ %p[%p], sz=%d[%x] bytes\n",
3521                     ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3522                 ioc->alloc_total += size;
3523                 rc = 0;
3524         }
3525  out:
3526         return rc;
3527 }
3528
3529 /**
3530  *      mpt_free_fw_memory - free firmware memory
3531  *      @ioc: Pointer to MPT_ADAPTER structure
3532  *
3533  *      If alt_img is NULL, delete from ioc structure.
3534  *      Else, delete a secondary image in same format.
3535  **/
3536 void
3537 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3538 {
3539         int sz;
3540
3541         if (!ioc->cached_fw)
3542                 return;
3543
3544         sz = ioc->facts.FWImageSize;
3545         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image  @ %p[%p], sz=%d[%x] bytes\n",
3546                  ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3547         pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3548         ioc->alloc_total -= sz;
3549         ioc->cached_fw = NULL;
3550 }
3551
3552 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3553 /**
3554  *      mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3555  *      @ioc: Pointer to MPT_ADAPTER structure
3556  *      @sleepFlag: Specifies whether the process can sleep
3557  *
3558  *      Returns 0 for success, >0 for handshake failure
3559  *              <0 for fw upload failure.
3560  *
3561  *      Remark: If bound IOC and a successful FWUpload was performed
3562  *      on the bound IOC, the second image is discarded
3563  *      and memory is free'd. Both channels must upload to prevent
3564  *      IOC from running in degraded mode.
3565  */
3566 static int
3567 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3568 {
3569         u8                       reply[sizeof(FWUploadReply_t)];
3570         FWUpload_t              *prequest;
3571         FWUploadReply_t         *preply;
3572         FWUploadTCSGE_t         *ptcsge;
3573         u32                      flagsLength;
3574         int                      ii, sz, reply_sz;
3575         int                      cmdStatus;
3576         int                     request_size;
3577         /* If the image size is 0, we are done.
3578          */
3579         if ((sz = ioc->facts.FWImageSize) == 0)
3580                 return 0;
3581
3582         if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3583                 return -ENOMEM;
3584
3585         dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image  @ %p[%p], sz=%d[%x] bytes\n",
3586             ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3587
3588         prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3589             kzalloc(ioc->req_sz, GFP_KERNEL);
3590         if (!prequest) {
3591                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3592                     "while allocating memory \n", ioc->name));
3593                 mpt_free_fw_memory(ioc);
3594                 return -ENOMEM;
3595         }
3596
3597         preply = (FWUploadReply_t *)&reply;
3598
3599         reply_sz = sizeof(reply);
3600         memset(preply, 0, reply_sz);
3601
3602         prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3603         prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3604
3605         ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3606         ptcsge->DetailsLength = 12;
3607         ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3608         ptcsge->ImageSize = cpu_to_le32(sz);
3609         ptcsge++;
3610
3611         flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3612         ioc->add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3613         request_size = offsetof(FWUpload_t, SGL) + sizeof(FWUploadTCSGE_t) +
3614             ioc->SGE_size;
3615         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending FW Upload "
3616             " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc->name, prequest,
3617             ioc->facts.FWImageSize, request_size));
3618         DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3619
3620         ii = mpt_handshake_req_reply_wait(ioc, request_size, (u32 *)prequest,
3621             reply_sz, (u16 *)preply, 65 /*seconds*/, sleepFlag);
3622
3623         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Upload completed "
3624             "rc=%x \n", ioc->name, ii));
3625
3626         cmdStatus = -EFAULT;
3627         if (ii == 0) {
3628                 /* Handshake transfer was complete and successful.
3629                  * Check the Reply Frame.
3630                  */
3631                 int status;
3632                 status = le16_to_cpu(preply->IOCStatus) &
3633                                 MPI_IOCSTATUS_MASK;
3634                 if (status == MPI_IOCSTATUS_SUCCESS &&
3635                     ioc->facts.FWImageSize ==
3636                     le32_to_cpu(preply->ActualImageSize))
3637                                 cmdStatus = 0;
3638         }
3639         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3640                         ioc->name, cmdStatus));
3641
3642
3643         if (cmdStatus) {
3644                 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed, "
3645                     "freeing image \n", ioc->name));
3646                 mpt_free_fw_memory(ioc);
3647         }
3648         kfree(prequest);
3649
3650         return cmdStatus;
3651 }
3652
3653 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3654 /**
3655  *      mpt_downloadboot - DownloadBoot code
3656  *      @ioc: Pointer to MPT_ADAPTER structure
3657  *      @pFwHeader: Pointer to firmware header info
3658  *      @sleepFlag: Specifies whether the process can sleep
3659  *
3660  *      FwDownloadBoot requires Programmed IO access.
3661  *
3662  *      Returns 0 for success
3663  *              -1 FW Image size is 0
3664  *              -2 No valid cached_fw Pointer
3665  *              <0 for fw upload failure.
3666  */
3667 static int
3668 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3669 {
3670         MpiExtImageHeader_t     *pExtImage;
3671         u32                      fwSize;
3672         u32                      diag0val;
3673         int                      count;
3674         u32                     *ptrFw;
3675         u32                      diagRwData;
3676         u32                      nextImage;
3677         u32                      load_addr;
3678         u32                      ioc_state=0;
3679
3680         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3681                                 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3682
3683         CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3684         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3685         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3686         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3687         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3688         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3689
3690         CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3691
3692         /* wait 1 msec */
3693         if (sleepFlag == CAN_SLEEP) {
3694                 msleep(1);
3695         } else {
3696                 mdelay (1);
3697         }
3698
3699         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3700         CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3701
3702         for (count = 0; count < 30; count ++) {
3703                 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3704                 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3705                         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3706                                 ioc->name, count));
3707                         break;
3708                 }
3709                 /* wait .1 sec */
3710                 if (sleepFlag == CAN_SLEEP) {
3711                         msleep (100);
3712                 } else {
3713                         mdelay (100);
3714                 }
3715         }
3716
3717         if ( count == 30 ) {
3718                 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3719                 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3720                 ioc->name, diag0val));
3721                 return -3;
3722         }
3723
3724         CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3725         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3726         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3727         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3728         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3729         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3730
3731         /* Set the DiagRwEn and Disable ARM bits */
3732         CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3733
3734         fwSize = (pFwHeader->ImageSize + 3)/4;
3735         ptrFw = (u32 *) pFwHeader;
3736
3737         /* Write the LoadStartAddress to the DiagRw Address Register
3738          * using Programmed IO
3739          */
3740         if (ioc->errata_flag_1064)
3741                 pci_enable_io_access(ioc->pcidev);
3742
3743         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3744         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3745                 ioc->name, pFwHeader->LoadStartAddress));
3746
3747         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3748                                 ioc->name, fwSize*4, ptrFw));
3749         while (fwSize--) {
3750                 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3751         }
3752
3753         nextImage = pFwHeader->NextImageHeaderOffset;
3754         while (nextImage) {
3755                 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3756
3757                 load_addr = pExtImage->LoadStartAddress;
3758
3759                 fwSize = (pExtImage->ImageSize + 3) >> 2;
3760                 ptrFw = (u32 *)pExtImage;
3761
3762                 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3763                                                 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3764                 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3765
3766                 while (fwSize--) {
3767                         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3768                 }
3769                 nextImage = pExtImage->NextImageHeaderOffset;
3770         }
3771
3772         /* Write the IopResetVectorRegAddr */
3773         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name,  pFwHeader->IopResetRegAddr));
3774         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3775
3776         /* Write the IopResetVectorValue */
3777         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3778         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3779
3780         /* Clear the internal flash bad bit - autoincrementing register,
3781          * so must do two writes.
3782          */
3783         if (ioc->bus_type == SPI) {
3784                 /*
3785                  * 1030 and 1035 H/W errata, workaround to access
3786                  * the ClearFlashBadSignatureBit
3787                  */
3788                 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3789                 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3790                 diagRwData |= 0x40000000;
3791                 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3792                 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3793
3794         } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3795                 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3796                 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3797                     MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3798
3799                 /* wait 1 msec */
3800                 if (sleepFlag == CAN_SLEEP) {
3801                         msleep (1);
3802                 } else {
3803                         mdelay (1);
3804                 }
3805         }
3806
3807         if (ioc->errata_flag_1064)
3808                 pci_disable_io_access(ioc->pcidev);
3809
3810         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3811         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3812                 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3813                 ioc->name, diag0val));
3814         diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3815         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3816                 ioc->name, diag0val));
3817         CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3818
3819         /* Write 0xFF to reset the sequencer */
3820         CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3821
3822         if (ioc->bus_type == SAS) {
3823                 ioc_state = mpt_GetIocState(ioc, 0);
3824                 if ( (GetIocFacts(ioc, sleepFlag,
3825                                 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3826                         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3827                                         ioc->name, ioc_state));
3828                         return -EFAULT;
3829                 }
3830         }
3831
3832         for (count=0; count<HZ*20; count++) {
3833                 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3834                         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3835                                 "downloadboot successful! (count=%d) IocState=%x\n",
3836                                 ioc->name, count, ioc_state));
3837                         if (ioc->bus_type == SAS) {
3838                                 return 0;
3839                         }
3840                         if ((SendIocInit(ioc, sleepFlag)) != 0) {
3841                                 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3842                                         "downloadboot: SendIocInit failed\n",
3843                                         ioc->name));
3844                                 return -EFAULT;
3845                         }
3846                         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3847                                         "downloadboot: SendIocInit successful\n",
3848                                         ioc->name));
3849                         return 0;
3850                 }
3851                 if (sleepFlag == CAN_SLEEP) {
3852                         msleep (10);
3853                 } else {
3854                         mdelay (10);
3855                 }
3856         }
3857         ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3858                 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3859         return -EFAULT;
3860 }
3861
3862 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3863 /**
3864  *      KickStart - Perform hard reset of MPT adapter.
3865  *      @ioc: Pointer to MPT_ADAPTER structure
3866  *      @force: Force hard reset
3867  *      @sleepFlag: Specifies whether the process can sleep
3868  *
3869  *      This routine places MPT adapter in diagnostic mode via the
3870  *      WriteSequence register, and then performs a hard reset of adapter
3871  *      via the Diagnostic register.
3872  *
3873  *      Inputs:   sleepflag - CAN_SLEEP (non-interrupt thread)
3874  *                      or NO_SLEEP (interrupt thread, use mdelay)
3875  *                force - 1 if doorbell active, board fault state
3876  *                              board operational, IOC_RECOVERY or
3877  *                              IOC_BRINGUP and there is an alt_ioc.
3878  *                        0 else
3879  *
3880  *      Returns:
3881  *               1 - hard reset, READY
3882  *               0 - no reset due to History bit, READY
3883  *              -1 - no reset due to History bit but not READY
3884  *                   OR reset but failed to come READY
3885  *              -2 - no reset, could not enter DIAG mode
3886  *              -3 - reset but bad FW bit
3887  */
3888 static int
3889 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3890 {
3891         int hard_reset_done = 0;
3892         u32 ioc_state=0;
3893         int cnt,cntdn;
3894
3895         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3896         if (ioc->bus_type == SPI) {
3897                 /* Always issue a Msg Unit Reset first. This will clear some
3898                  * SCSI bus hang conditions.
3899                  */
3900                 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3901
3902                 if (sleepFlag == CAN_SLEEP) {
3903                         msleep (1000);
3904                 } else {
3905                         mdelay (1000);
3906                 }
3907         }
3908
3909         hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3910         if (hard_reset_done < 0)
3911                 return hard_reset_done;
3912
3913         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3914                 ioc->name));
3915
3916         cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2;     /* 2 seconds */
3917         for (cnt=0; cnt<cntdn; cnt++) {
3918                 ioc_state = mpt_GetIocState(ioc, 1);
3919                 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3920                         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3921                                         ioc->name, cnt));
3922                         return hard_reset_done;
3923                 }
3924                 if (sleepFlag == CAN_SLEEP) {
3925                         msleep (10);
3926                 } else {
3927                         mdelay (10);
3928                 }
3929         }
3930
3931         dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3932                 ioc->name, mpt_GetIocState(ioc, 0)));
3933         return -1;
3934 }
3935
3936 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3937 /**
3938  *      mpt_diag_reset - Perform hard reset of the adapter.
3939  *      @ioc: Pointer to MPT_ADAPTER structure
3940  *      @ignore: Set if to honor and clear to ignore
3941  *              the reset history bit
3942  *      @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3943  *              else set to NO_SLEEP (use mdelay instead)
3944  *
3945  *      This routine places the adapter in diagnostic mode via the
3946  *      WriteSequence register and then performs a hard reset of adapter
3947  *      via the Diagnostic register. Adapter should be in ready state
3948  *      upon successful completion.
3949  *
3950  *      Returns:  1  hard reset successful
3951  *                0  no reset performed because reset history bit set
3952  *               -2  enabling diagnostic mode failed
3953  *               -3  diagnostic reset failed
3954  */
3955 static int
3956 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3957 {
3958         u32 diag0val;
3959         u32 doorbell;
3960         int hard_reset_done = 0;
3961         int count = 0;
3962         u32 diag1val = 0;
3963         MpiFwHeader_t *cached_fw;       /* Pointer to FW */
3964         u8       cb_idx;
3965
3966         /* Clear any existing interrupts */
3967         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3968
3969         if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3970
3971                 if (!ignore)
3972                         return 0;
3973
3974                 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3975                         "address=%p\n",  ioc->name, __func__,
3976                         &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3977                 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3978                 if (sleepFlag == CAN_SLEEP)
3979                         msleep(1);
3980                 else
3981                         mdelay(1);
3982
3983                 /*
3984                  * Call each currently registered protocol IOC reset handler
3985                  * with pre-reset indication.
3986                  * NOTE: If we're doing _IOC_BRINGUP, there can be no
3987                  * MptResetHandlers[] registered yet.
3988                  */
3989                 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3990                         if (MptResetHandlers[cb_idx])
3991                                 (*(MptResetHandlers[cb_idx]))(ioc,
3992                                                 MPT_IOC_PRE_RESET);
3993                 }
3994
3995                 for (count = 0; count < 60; count ++) {
3996                         doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3997                         doorbell &= MPI_IOC_STATE_MASK;
3998
3999                         drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4000                                 "looking for READY STATE: doorbell=%x"
4001                                 " count=%d\n",
4002                                 ioc->name, doorbell, count));
4003
4004                         if (doorbell == MPI_IOC_STATE_READY) {
4005                                 return 1;
4006                         }
4007
4008                         /* wait 1 sec */
4009                         if (sleepFlag == CAN_SLEEP)
4010                                 msleep(1000);
4011                         else
4012                                 mdelay(1000);
4013                 }
4014                 return -1;
4015         }
4016
4017         /* Use "Diagnostic reset" method! (only thing available!) */
4018         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4019
4020         if (ioc->debug_level & MPT_DEBUG) {
4021                 if (ioc->alt_ioc)
4022                         diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4023                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
4024                         ioc->name, diag0val, diag1val));
4025         }
4026
4027         /* Do the reset if we are told to ignore the reset history
4028          * or if the reset history is 0
4029          */
4030         if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
4031                 while ((diag0val & MPI_DIAG_DRWE) == 0) {
4032                         /* Write magic sequence to WriteSequence register
4033                          * Loop until in diagnostic mode
4034                          */
4035                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
4036                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
4037                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
4038                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
4039                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
4040                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
4041
4042                         /* wait 100 msec */
4043                         if (sleepFlag == CAN_SLEEP) {
4044                                 msleep (100);
4045                         } else {
4046                                 mdelay (100);
4047                         }
4048
4049                         count++;
4050                         if (count > 20) {
4051                                 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4052                                                 ioc->name, diag0val);
4053                                 return -2;
4054
4055                         }
4056
4057                         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4058
4059                         dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
4060                                         ioc->name, diag0val));
4061                 }
4062
4063                 if (ioc->debug_level & MPT_DEBUG) {
4064                         if (ioc->alt_ioc)
4065                                 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4066                         dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
4067                                 ioc->name, diag0val, diag1val));
4068                 }
4069                 /*
4070                  * Disable the ARM (Bug fix)
4071                  *
4072                  */
4073                 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
4074                 mdelay(1);
4075
4076                 /*
4077                  * Now hit the reset bit in the Diagnostic register
4078                  * (THE BIG HAMMER!) (Clears DRWE bit).
4079                  */
4080                 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
4081                 hard_reset_done = 1;
4082                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
4083                                 ioc->name));
4084
4085                 /*
4086                  * Call each currently registered protocol IOC reset handler
4087                  * with pre-reset indication.
4088                  * NOTE: If we're doing _IOC_BRINGUP, there can be no
4089                  * MptResetHandlers[] registered yet.
4090                  */
4091                 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
4092                         if (MptResetHandlers[cb_idx]) {
4093                                 mpt_signal_reset(cb_idx,
4094                                         ioc, MPT_IOC_PRE_RESET);
4095                                 if (ioc->alt_ioc) {
4096                                         mpt_signal_reset(cb_idx,
4097                                         ioc->alt_ioc, MPT_IOC_PRE_RESET);
4098                                 }
4099                         }
4100                 }
4101
4102                 if (ioc->cached_fw)
4103                         cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
4104                 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
4105                         cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
4106                 else
4107                         cached_fw = NULL;
4108                 if (cached_fw) {
4109                         /* If the DownloadBoot operation fails, the
4110                          * IOC will be left unusable. This is a fatal error
4111                          * case.  _diag_reset will return < 0
4112                          */
4113                         for (count = 0; count < 30; count ++) {
4114                                 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4115                                 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
4116                                         break;
4117                                 }
4118
4119                                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
4120                                         ioc->name, diag0val, count));
4121                                 /* wait 1 sec */
4122                                 if (sleepFlag == CAN_SLEEP) {
4123                                         msleep (1000);
4124                                 } else {
4125                                         mdelay (1000);
4126                                 }
4127                         }
4128                         if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
4129                                 printk(MYIOC_s_WARN_FMT
4130                                         "firmware downloadboot failure (%d)!\n", ioc->name, count);
4131                         }
4132
4133                 } else {
4134                         /* Wait for FW to reload and for board
4135                          * to go to the READY state.
4136                          * Maximum wait is 60 seconds.
4137                          * If fail, no error will check again
4138                          * with calling program.
4139                          */
4140                         for (count = 0; count < 60; count ++) {
4141                                 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
4142                                 doorbell &= MPI_IOC_STATE_MASK;
4143
4144                                 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4145                                     "looking for READY STATE: doorbell=%x"
4146                                     " count=%d\n", ioc->name, doorbell, count));
4147
4148                                 if (doorbell == MPI_IOC_STATE_READY) {
4149                                         break;
4150                                 }
4151
4152                                 /* wait 1 sec */
4153                                 if (sleepFlag == CAN_SLEEP) {
4154                                         msleep (1000);
4155                                 } else {
4156                                         mdelay (1000);
4157                                 }
4158                         }
4159
4160                         if (doorbell != MPI_IOC_STATE_READY)
4161                                 printk(MYIOC_s_ERR_FMT "Failed to come READY "
4162                                     "after reset! IocState=%x", ioc->name,
4163                                     doorbell);
4164                 }
4165         }
4166
4167         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4168         if (ioc->debug_level & MPT_DEBUG) {
4169                 if (ioc->alt_ioc)
4170                         diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4171                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
4172                         ioc->name, diag0val, diag1val));
4173         }
4174
4175         /* Clear RESET_HISTORY bit!  Place board in the
4176          * diagnostic mode to update the diag register.
4177          */
4178         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4179         count = 0;
4180         while ((diag0val & MPI_DIAG_DRWE) == 0) {
4181                 /* Write magic sequence to WriteSequence register
4182                  * Loop until in diagnostic mode
4183                  */
4184                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
4185                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
4186                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
4187                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
4188                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
4189                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
4190
4191                 /* wait 100 msec */
4192                 if (sleepFlag == CAN_SLEEP) {
4193                         msleep (100);
4194                 } else {
4195                         mdelay (100);
4196                 }
4197
4198                 count++;
4199                 if (count > 20) {
4200                         printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4201                                         ioc->name, diag0val);
4202                         break;
4203                 }
4204                 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4205         }
4206         diag0val &= ~MPI_DIAG_RESET_HISTORY;
4207         CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
4208         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4209         if (diag0val & MPI_DIAG_RESET_HISTORY) {
4210                 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
4211                                 ioc->name);
4212         }
4213
4214         /* Disable Diagnostic Mode
4215          */
4216         CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
4217
4218         /* Check FW reload status flags.
4219          */
4220         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4221         if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
4222                 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
4223                                 ioc->name, diag0val);
4224                 return -3;
4225         }
4226
4227         if (ioc->debug_level & MPT_DEBUG) {
4228                 if (ioc->alt_ioc)
4229                         diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4230                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
4231                         ioc->name, diag0val, diag1val));
4232         }
4233
4234         /*
4235          * Reset flag that says we've enabled event notification
4236          */
4237         ioc->facts.EventState = 0;
4238
4239         if (ioc->alt_ioc)
4240                 ioc->alt_ioc->facts.EventState = 0;
4241
4242         return hard_reset_done;
4243 }
4244
4245 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4246 /**
4247  *      SendIocReset - Send IOCReset request to MPT adapter.
4248  *      @ioc: Pointer to MPT_ADAPTER structure
4249  *      @reset_type: reset type, expected values are
4250  *      %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
4251  *      @sleepFlag: Specifies whether the process can sleep
4252  *
4253  *      Send IOCReset request to the MPT adapter.
4254  *
4255  *      Returns 0 for success, non-zero for failure.
4256  */
4257 static int
4258 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
4259 {
4260         int r;
4261         u32 state;
4262         int cntdn, count;
4263
4264         drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
4265                         ioc->name, reset_type));
4266         CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
4267         if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4268                 return r;
4269
4270         /* FW ACK'd request, wait for READY state
4271          */
4272         count = 0;
4273         cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15;    /* 15 seconds */
4274
4275         while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
4276                 cntdn--;
4277                 count++;
4278                 if (!cntdn) {
4279                         if (sleepFlag != CAN_SLEEP)
4280                                 count *= 10;
4281
4282                         printk(MYIOC_s_ERR_FMT
4283                             "Wait IOC_READY state (0x%x) timeout(%d)!\n",
4284                             ioc->name, state, (int)((count+5)/HZ));
4285                         return -ETIME;
4286                 }
4287
4288                 if (sleepFlag == CAN_SLEEP) {
4289                         msleep(1);
4290                 } else {
4291                         mdelay (1);     /* 1 msec delay */
4292                 }
4293         }
4294
4295         /* TODO!
4296          *  Cleanup all event stuff for this IOC; re-issue EventNotification
4297          *  request if needed.
4298          */
4299         if (ioc->facts.Function)
4300                 ioc->facts.EventState = 0;
4301
4302         return 0;
4303 }
4304
4305 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4306 /**
4307  *      initChainBuffers - Allocate memory for and initialize chain buffers
4308  *      @ioc: Pointer to MPT_ADAPTER structure
4309  *
4310  *      Allocates memory for and initializes chain buffers,
4311  *      chain buffer control arrays and spinlock.
4312  */
4313 static int
4314 initChainBuffers(MPT_ADAPTER *ioc)
4315 {
4316         u8              *mem;
4317         int             sz, ii, num_chain;
4318         int             scale, num_sge, numSGE;
4319
4320         /* ReqToChain size must equal the req_depth
4321          * index = req_idx
4322          */
4323         if (ioc->ReqToChain == NULL) {
4324                 sz = ioc->req_depth * sizeof(int);
4325                 mem = kmalloc(sz, GFP_ATOMIC);
4326                 if (mem == NULL)
4327                         return -1;
4328
4329                 ioc->ReqToChain = (int *) mem;
4330                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc  @ %p, sz=%d bytes\n",
4331                                 ioc->name, mem, sz));
4332                 mem = kmalloc(sz, GFP_ATOMIC);
4333                 if (mem == NULL)
4334                         return -1;
4335
4336                 ioc->RequestNB = (int *) mem;
4337                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc  @ %p, sz=%d bytes\n",
4338                                 ioc->name, mem, sz));
4339         }
4340         for (ii = 0; ii < ioc->req_depth; ii++) {
4341                 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
4342         }
4343
4344         /* ChainToChain size must equal the total number
4345          * of chain buffers to be allocated.
4346          * index = chain_idx
4347          *
4348          * Calculate the number of chain buffers needed(plus 1) per I/O
4349          * then multiply the maximum number of simultaneous cmds
4350          *
4351          * num_sge = num sge in request frame + last chain buffer
4352          * scale = num sge per chain buffer if no chain element
4353          */
4354         scale = ioc->req_sz / ioc->SGE_size;
4355         if (ioc->sg_addr_size == sizeof(u64))
4356                 num_sge =  scale + (ioc->req_sz - 60) / ioc->SGE_size;
4357         else
4358                 num_sge =  1 + scale + (ioc->req_sz - 64) / ioc->SGE_size;
4359
4360         if (ioc->sg_addr_size == sizeof(u64)) {
4361                 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
4362                         (ioc->req_sz - 60) / ioc->SGE_size;
4363         } else {
4364                 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) +
4365                     scale + (ioc->req_sz - 64) / ioc->SGE_size;
4366         }
4367         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
4368                 ioc->name, num_sge, numSGE));
4369
4370         if (ioc->bus_type == FC) {
4371                 if (numSGE > MPT_SCSI_FC_SG_DEPTH)
4372                         numSGE = MPT_SCSI_FC_SG_DEPTH;
4373         } else {
4374                 if (numSGE > MPT_SCSI_SG_DEPTH)
4375                         numSGE = MPT_SCSI_SG_DEPTH;
4376         }
4377
4378         num_chain = 1;
4379         while (numSGE - num_sge > 0) {
4380                 num_chain++;
4381                 num_sge += (scale - 1);
4382         }
4383         num_chain++;
4384
4385         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
4386                 ioc->name, numSGE, num_sge, num_chain));
4387
4388         if (ioc->bus_type == SPI)
4389                 num_chain *= MPT_SCSI_CAN_QUEUE;
4390         else if (ioc->bus_type == SAS)
4391                 num_chain *= MPT_SAS_CAN_QUEUE;
4392         else
4393                 num_chain *= MPT_FC_CAN_QUEUE;
4394
4395         ioc->num_chain = num_chain;
4396
4397         sz = num_chain * sizeof(int);
4398         if (ioc->ChainToChain == NULL) {
4399                 mem = kmalloc(sz, GFP_ATOMIC);
4400                 if (mem == NULL)
4401                         return -1;
4402
4403                 ioc->ChainToChain = (int *) mem;
4404                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
4405                                 ioc->name, mem, sz));
4406         } else {
4407                 mem = (u8 *) ioc->ChainToChain;
4408         }
4409         memset(mem, 0xFF, sz);
4410         return num_chain;
4411 }
4412
4413 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4414 /**
4415  *      PrimeIocFifos - Initialize IOC request and reply FIFOs.
4416  *      @ioc: Pointer to MPT_ADAPTER structure
4417  *
4418  *      This routine allocates memory for the MPT reply and request frame
4419  *      pools (if necessary), and primes the IOC reply FIFO with
4420  *      reply frames.
4421  *
4422  *      Returns 0 for success, non-zero for failure.
4423  */
4424 static int
4425 PrimeIocFifos(MPT_ADAPTER *ioc)
4426 {
4427         MPT_FRAME_HDR *mf;
4428         unsigned long flags;
4429         dma_addr_t alloc_dma;
4430         u8 *mem;
4431         int i, reply_sz, sz, total_size, num_chain;
4432         u64     dma_mask;
4433
4434         dma_mask = 0;
4435
4436         /*  Prime reply FIFO...  */
4437
4438         if (ioc->reply_frames == NULL) {
4439                 if ( (num_chain = initChainBuffers(ioc)) < 0)
4440                         return -1;
4441                 /*
4442                  * 1078 errata workaround for the 36GB limitation
4443                  */
4444                 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078 &&
4445                     ioc->dma_mask > DMA_BIT_MASK(35)) {
4446                         if (!pci_set_dma_mask(ioc->pcidev, DMA_BIT_MASK(32))
4447                             && !pci_set_consistent_dma_mask(ioc->pcidev,
4448                             DMA_BIT_MASK(32))) {
4449                                 dma_mask = DMA_BIT_MASK(35);
4450                                 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4451                                     "setting 35 bit addressing for "
4452                                     "Request/Reply/Chain and Sense Buffers\n",
4453                                     ioc->name));
4454                         } else {
4455                                 /*Reseting DMA mask to 64 bit*/
4456                                 pci_set_dma_mask(ioc->pcidev,
4457                                         DMA_BIT_MASK(64));
4458                                 pci_set_consistent_dma_mask(ioc->pcidev,
4459                                         DMA_BIT_MASK(64));
4460
4461                                 printk(MYIOC_s_ERR_FMT
4462                                     "failed setting 35 bit addressing for "
4463                                     "Request/Reply/Chain and Sense Buffers\n",
4464                                     ioc->name);
4465                                 return -1;
4466                         }
4467                 }
4468
4469                 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
4470                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4471                                 ioc->name, ioc->reply_sz, ioc->reply_depth));
4472                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
4473                                 ioc->name, reply_sz, reply_sz));
4474
4475                 sz = (ioc->req_sz * ioc->req_depth);
4476                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4477                                 ioc->name, ioc->req_sz, ioc->req_depth));
4478                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
4479                                 ioc->name, sz, sz));
4480                 total_size += sz;
4481
4482                 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
4483                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4484                                 ioc->name, ioc->req_sz, num_chain));
4485                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4486                                 ioc->name, sz, sz, num_chain));
4487
4488                 total_size += sz;
4489                 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
4490                 if (mem == NULL) {
4491                         printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
4492                                 ioc->name);
4493                         goto out_fail;
4494                 }
4495
4496                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4497                                 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
4498
4499                 memset(mem, 0, total_size);
4500                 ioc->alloc_total += total_size;
4501                 ioc->alloc = mem;
4502                 ioc->alloc_dma = alloc_dma;
4503                 ioc->alloc_sz = total_size;
4504                 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4505                 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4506
4507                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4508                         ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4509
4510                 alloc_dma += reply_sz;
4511                 mem += reply_sz;
4512
4513                 /*  Request FIFO - WE manage this!  */
4514
4515                 ioc->req_frames = (MPT_FRAME_HDR *) mem;
4516                 ioc->req_frames_dma = alloc_dma;
4517
4518                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4519                                 ioc->name, mem, (void *)(ulong)alloc_dma));
4520
4521                 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4522
4523 #if defined(CONFIG_MTRR) && 0
4524                 /*
4525                  *  Enable Write Combining MTRR for IOC's memory region.
4526                  *  (at least as much as we can; "size and base must be
4527                  *  multiples of 4 kiB"
4528                  */
4529                 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
4530                                          sz,
4531                                          MTRR_TYPE_WRCOMB, 1);
4532                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
4533                                 ioc->name, ioc->req_frames_dma, sz));
4534 #endif
4535
4536                 for (i = 0; i < ioc->req_depth; i++) {
4537                         alloc_dma += ioc->req_sz;
4538                         mem += ioc->req_sz;
4539                 }
4540
4541                 ioc->ChainBuffer = mem;
4542                 ioc->ChainBufferDMA = alloc_dma;
4543
4544                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4545                         ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4546
4547                 /* Initialize the free chain Q.
4548                 */
4549
4550                 INIT_LIST_HEAD(&ioc->FreeChainQ);
4551
4552                 /* Post the chain buffers to the FreeChainQ.
4553                 */
4554                 mem = (u8 *)ioc->ChainBuffer;
4555                 for (i=0; i < num_chain; i++) {
4556                         mf = (MPT_FRAME_HDR *) mem;
4557                         list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4558                         mem += ioc->req_sz;
4559                 }
4560
4561                 /* Initialize Request frames linked list
4562                  */
4563                 alloc_dma = ioc->req_frames_dma;
4564                 mem = (u8 *) ioc->req_frames;
4565
4566                 spin_lock_irqsave(&ioc->FreeQlock, flags);
4567                 INIT_LIST_HEAD(&ioc->FreeQ);
4568                 for (i = 0; i < ioc->req_depth; i++) {
4569                         mf = (MPT_FRAME_HDR *) mem;
4570
4571                         /*  Queue REQUESTs *internally*!  */
4572                         list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4573
4574                         mem += ioc->req_sz;
4575                 }
4576                 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4577
4578                 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4579                 ioc->sense_buf_pool =
4580                         pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4581                 if (ioc->sense_buf_pool == NULL) {
4582                         printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4583                                 ioc->name);
4584                         goto out_fail;
4585                 }
4586
4587                 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4588                 ioc->alloc_total += sz;
4589                 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4590                         ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4591
4592         }
4593
4594         /* Post Reply frames to FIFO
4595          */
4596         alloc_dma = ioc->alloc_dma;
4597         dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4598                 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4599
4600         for (i = 0; i < ioc->reply_depth; i++) {
4601                 /*  Write each address to the IOC!  */
4602                 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4603                 alloc_dma += ioc->reply_sz;
4604         }
4605
4606         if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
4607             ioc->dma_mask) && !pci_set_consistent_dma_mask(ioc->pcidev,
4608             ioc->dma_mask))
4609                 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4610                     "restoring 64 bit addressing\n", ioc->name));
4611
4612         return 0;
4613
4614 out_fail:
4615
4616         if (ioc->alloc != NULL) {
4617                 sz = ioc->alloc_sz;
4618                 pci_free_consistent(ioc->pcidev,
4619                                 sz,
4620                                 ioc->alloc, ioc->alloc_dma);
4621                 ioc->reply_frames = NULL;
4622                 ioc->req_frames = NULL;
4623                 ioc->alloc_total -= sz;
4624         }
4625         if (ioc->sense_buf_pool != NULL) {
4626                 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4627                 pci_free_consistent(ioc->pcidev,
4628                                 sz,
4629                                 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4630                 ioc->sense_buf_pool = NULL;
4631         }
4632
4633         if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
4634             DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc->pcidev,
4635             DMA_BIT_MASK(64)))
4636                 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4637                     "restoring 64 bit addressing\n", ioc->name));
4638
4639         return -1;
4640 }
4641
4642 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4643 /**
4644  *      mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4645  *      from IOC via doorbell handshake method.
4646  *      @ioc: Pointer to MPT_ADAPTER structure
4647  *      @reqBytes: Size of the request in bytes
4648  *      @req: Pointer to MPT request frame
4649  *      @replyBytes: Expected size of the reply in bytes
4650  *      @u16reply: Pointer to area where reply should be written
4651  *      @maxwait: Max wait time for a reply (in seconds)
4652  *      @sleepFlag: Specifies whether the process can sleep
4653  *
4654  *      NOTES: It is the callers responsibility to byte-swap fields in the
4655  *      request which are greater than 1 byte in size.  It is also the
4656  *      callers responsibility to byte-swap response fields which are
4657  *      greater than 1 byte in size.
4658  *
4659  *      Returns 0 for success, non-zero for failure.
4660  */
4661 static int
4662 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4663                 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4664 {
4665         MPIDefaultReply_t *mptReply;
4666         int failcnt = 0;
4667         int t;
4668
4669         /*
4670          * Get ready to cache a handshake reply
4671          */
4672         ioc->hs_reply_idx = 0;
4673         mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4674         mptReply->MsgLength = 0;
4675
4676         /*
4677          * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4678          * then tell IOC that we want to handshake a request of N words.
4679          * (WRITE u32val to Doorbell reg).
4680          */
4681         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4682         CHIPREG_WRITE32(&ioc->chip->Doorbell,
4683                         ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4684                          ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4685
4686         /*
4687          * Wait for IOC's doorbell handshake int
4688          */
4689         if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4690                 failcnt++;
4691
4692         dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4693                         ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4694
4695         /* Read doorbell and check for active bit */
4696         if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4697                         return -1;
4698
4699         /*
4700          * Clear doorbell int (WRITE 0 to IntStatus reg),
4701          * then wait for IOC to ACKnowledge that it's ready for
4702          * our handshake request.
4703          */
4704         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4705         if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4706                 failcnt++;
4707
4708         if (!failcnt) {
4709                 int      ii;
4710                 u8      *req_as_bytes = (u8 *) req;
4711
4712                 /*
4713                  * Stuff request words via doorbell handshake,
4714                  * with ACK from IOC for each.
4715                  */
4716                 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4717                         u32 word = ((req_as_bytes[(ii*4) + 0] <<  0) |
4718                                     (req_as_bytes[(ii*4) + 1] <<  8) |
4719                                     (req_as_bytes[(ii*4) + 2] << 16) |
4720                                     (req_as_bytes[(ii*4) + 3] << 24));
4721
4722                         CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4723                         if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4724                                 failcnt++;
4725                 }
4726
4727                 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4728                 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4729
4730                 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4731                                 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4732
4733                 /*
4734                  * Wait for completion of doorbell handshake reply from the IOC
4735                  */
4736                 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4737                         failcnt++;
4738
4739                 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4740                                 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4741
4742                 /*
4743                  * Copy out the cached reply...
4744                  */
4745                 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4746                         u16reply[ii] = ioc->hs_reply[ii];
4747         } else {
4748                 return -99;
4749         }
4750
4751         return -failcnt;
4752 }
4753
4754 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4755 /**
4756  *      WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4757  *      @ioc: Pointer to MPT_ADAPTER structure
4758  *      @howlong: How long to wait (in seconds)
4759  *      @sleepFlag: Specifies whether the process can sleep
4760  *
4761  *      This routine waits (up to ~2 seconds max) for IOC doorbell
4762  *      handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4763  *      bit in its IntStatus register being clear.
4764  *
4765  *      Returns a negative value on failure, else wait loop count.
4766  */
4767 static int
4768 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4769 {
4770         int cntdn;
4771         int count = 0;
4772         u32 intstat=0;
4773
4774         cntdn = 1000 * howlong;
4775
4776         if (sleepFlag == CAN_SLEEP) {
4777                 while (--cntdn) {
4778                         msleep (1);
4779                         intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4780                         if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4781                                 break;
4782                         count++;
4783                 }
4784         } else {
4785                 while (--cntdn) {
4786                         udelay (1000);
4787                         intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4788                         if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4789                                 break;
4790                         count++;
4791                 }
4792         }
4793
4794         if (cntdn) {
4795                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4796                                 ioc->name, count));
4797                 return count;
4798         }
4799
4800         printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4801                         ioc->name, count, intstat);
4802         return -1;
4803 }
4804
4805 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4806 /**
4807  *      WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4808  *      @ioc: Pointer to MPT_ADAPTER structure
4809  *      @howlong: How long to wait (in seconds)
4810  *      @sleepFlag: Specifies whether the process can sleep
4811  *
4812  *      This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4813  *      (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4814  *
4815  *      Returns a negative value on failure, else wait loop count.
4816  */
4817 static int
4818 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4819 {
4820         int cntdn;
4821         int count = 0;
4822         u32 intstat=0;
4823
4824         cntdn = 1000 * howlong;
4825         if (sleepFlag == CAN_SLEEP) {
4826                 while (--cntdn) {
4827                         intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4828                         if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4829                                 break;
4830                         msleep(1);
4831                         count++;
4832                 }
4833         } else {
4834                 while (--cntdn) {
4835                         intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4836                         if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4837                                 break;
4838                         udelay (1000);
4839                         count++;
4840                 }
4841         }
4842
4843         if (cntdn) {
4844                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4845                                 ioc->name, count, howlong));
4846                 return count;
4847         }
4848
4849         printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4850                         ioc->name, count, intstat);
4851         return -1;
4852 }
4853
4854 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4855 /**
4856  *      WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4857  *      @ioc: Pointer to MPT_ADAPTER structure
4858  *      @howlong: How long to wait (in seconds)
4859  *      @sleepFlag: Specifies whether the process can sleep
4860  *
4861  *      This routine polls the IOC for a handshake reply, 16 bits at a time.
4862  *      Reply is cached to IOC private area large enough to hold a maximum
4863  *      of 128 bytes of reply data.
4864  *
4865  *      Returns a negative value on failure, else size of reply in WORDS.
4866  */
4867 static int
4868 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4869 {
4870         int u16cnt = 0;
4871         int failcnt = 0;
4872         int t;
4873         u16 *hs_reply = ioc->hs_reply;
4874         volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4875         u16 hword;
4876
4877         hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4878
4879         /*
4880          * Get first two u16's so we can look at IOC's intended reply MsgLength
4881          */
4882         u16cnt=0;
4883         if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4884                 failcnt++;
4885         } else {
4886                 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4887                 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4888                 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4889                         failcnt++;
4890                 else {
4891                         hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4892                         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4893                 }
4894         }
4895
4896         dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4897                         ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4898                         failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4899
4900         /*
4901          * If no error (and IOC said MsgLength is > 0), piece together
4902          * reply 16 bits at a time.
4903          */
4904         for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4905                 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4906                         failcnt++;
4907                 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4908                 /* don't overflow our IOC hs_reply[] buffer! */
4909                 if (u16cnt < ARRAY_SIZE(ioc->hs_reply))
4910                         hs_reply[u16cnt] = hword;
4911                 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4912         }
4913
4914         if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4915                 failcnt++;
4916         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4917
4918         if (failcnt) {
4919                 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4920                                 ioc->name);
4921                 return -failcnt;
4922         }
4923 #if 0
4924         else if (u16cnt != (2 * mptReply->MsgLength)) {
4925                 return -101;
4926         }
4927         else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4928                 return -102;
4929         }
4930 #endif
4931
4932         dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4933         DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4934
4935         dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4936                         ioc->name, t, u16cnt/2));
4937         return u16cnt/2;
4938 }
4939
4940 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4941 /**
4942  *      GetLanConfigPages - Fetch LANConfig pages.
4943  *      @ioc: Pointer to MPT_ADAPTER structure
4944  *
4945  *      Return: 0 for success
4946  *      -ENOMEM if no memory available
4947  *              -EPERM if not allowed due to ISR context
4948  *              -EAGAIN if no msg frames currently available
4949  *              -EFAULT for non-successful reply or no reply (timeout)
4950  */
4951 static int
4952 GetLanConfigPages(MPT_ADAPTER *ioc)
4953 {
4954         ConfigPageHeader_t       hdr;
4955         CONFIGPARMS              cfg;
4956         LANPage0_t              *ppage0_alloc;
4957         dma_addr_t               page0_dma;
4958         LANPage1_t              *ppage1_alloc;
4959         dma_addr_t               page1_dma;
4960         int                      rc = 0;
4961         int                      data_sz;
4962         int                      copy_sz;
4963
4964         /* Get LAN Page 0 header */
4965         hdr.PageVersion = 0;
4966         hdr.PageLength = 0;
4967         hdr.PageNumber = 0;
4968         hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4969         cfg.cfghdr.hdr = &hdr;
4970         cfg.physAddr = -1;
4971         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4972         cfg.dir = 0;
4973         cfg.pageAddr = 0;
4974         cfg.timeout = 0;
4975
4976         if ((rc = mpt_config(ioc, &cfg)) != 0)
4977                 return rc;
4978
4979         if (hdr.PageLength > 0) {
4980                 data_sz = hdr.PageLength * 4;
4981                 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4982                 rc = -ENOMEM;
4983                 if (ppage0_alloc) {
4984                         memset((u8 *)ppage0_alloc, 0, data_sz);
4985                         cfg.physAddr = page0_dma;
4986                         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4987
4988                         if ((rc = mpt_config(ioc, &cfg)) == 0) {
4989                                 /* save the data */
4990                                 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4991                                 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4992
4993                         }
4994
4995                         pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4996
4997                         /* FIXME!
4998                          *      Normalize endianness of structure data,
4999                          *      by byte-swapping all > 1 byte fields!
5000                          */
5001
5002                 }
5003
5004                 if (rc)
5005                         return rc;
5006         }
5007
5008         /* Get LAN Page 1 header */
5009         hdr.PageVersion = 0;
5010         hdr.PageLength = 0;
5011         hdr.PageNumber = 1;
5012         hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
5013         cfg.cfghdr.hdr = &hdr;
5014         cfg.physAddr = -1;
5015         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5016         cfg.dir = 0;
5017         cfg.pageAddr = 0;
5018
5019         if ((rc = mpt_config(ioc, &cfg)) != 0)
5020                 return rc;
5021
5022         if (hdr.PageLength == 0)
5023                 return 0;
5024
5025         data_sz = hdr.PageLength * 4;
5026         rc = -ENOMEM;
5027         ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
5028         if (ppage1_alloc) {
5029                 memset((u8 *)ppage1_alloc, 0, data_sz);
5030                 cfg.physAddr = page1_dma;
5031                 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5032
5033                 if ((rc = mpt_config(ioc, &cfg)) == 0) {
5034                         /* save the data */
5035                         copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
5036                         memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
5037                 }
5038
5039                 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
5040
5041                 /* FIXME!
5042                  *      Normalize endianness of structure data,
5043                  *      by byte-swapping all > 1 byte fields!
5044                  */
5045
5046         }
5047
5048         return rc;
5049 }
5050
5051 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5052 /**
5053  *      mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
5054  *      @ioc: Pointer to MPT_ADAPTER structure
5055  *      @persist_opcode: see below
5056  *
5057  *      MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
5058  *              devices not currently present.
5059  *      MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
5060  *
5061  *      NOTE: Don't use not this function during interrupt time.
5062  *
5063  *      Returns 0 for success, non-zero error
5064  */
5065
5066 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5067 int
5068 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
5069 {
5070         SasIoUnitControlRequest_t       *sasIoUnitCntrReq;
5071         SasIoUnitControlReply_t         *sasIoUnitCntrReply;
5072         MPT_FRAME_HDR                   *mf = NULL;
5073         MPIHeader_t                     *mpi_hdr;
5074         int                             ret = 0;
5075         unsigned long                   timeleft;
5076
5077         mutex_lock(&ioc->mptbase_cmds.mutex);
5078
5079         /* init the internal cmd struct */
5080         memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
5081         INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
5082
5083         /* insure garbage is not sent to fw */
5084         switch(persist_opcode) {
5085
5086         case MPI_SAS_OP_CLEAR_NOT_PRESENT:
5087         case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
5088                 break;
5089
5090         default:
5091                 ret = -1;
5092                 goto out;
5093         }
5094
5095         printk(KERN_DEBUG  "%s: persist_opcode=%x\n",
5096                 __func__, persist_opcode);
5097
5098         /* Get a MF for this command.
5099          */
5100         if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5101                 printk(KERN_DEBUG "%s: no msg frames!\n", __func__);
5102                 ret = -1;
5103                 goto out;
5104         }
5105
5106         mpi_hdr = (MPIHeader_t *) mf;
5107         sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
5108         memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
5109         sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
5110         sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
5111         sasIoUnitCntrReq->Operation = persist_opcode;
5112
5113         mpt_put_msg_frame(mpt_base_index, ioc, mf);
5114         timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done, 10*HZ);
5115         if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
5116                 ret = -ETIME;
5117                 printk(KERN_DEBUG "%s: failed\n", __func__);
5118                 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
5119                         goto out;
5120                 if (!timeleft) {
5121                         printk(MYIOC_s_WARN_FMT
5122                                "Issuing Reset from %s!!, doorbell=0x%08x\n",
5123                                ioc->name, __func__, mpt_GetIocState(ioc, 0));
5124                         mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
5125                         mpt_free_msg_frame(ioc, mf);
5126                 }
5127                 goto out;
5128         }
5129
5130         if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
5131                 ret = -1;
5132                 goto out;
5133         }
5134
5135         sasIoUnitCntrReply =
5136             (SasIoUnitControlReply_t *)ioc->mptbase_cmds.reply;
5137         if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
5138                 printk(KERN_DEBUG "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
5139                     __func__, sasIoUnitCntrReply->IOCStatus,
5140                     sasIoUnitCntrReply->IOCLogInfo);
5141                 printk(KERN_DEBUG "%s: failed\n", __func__);
5142                 ret = -1;
5143         } else
5144                 printk(KERN_DEBUG "%s: success\n", __func__);
5145  out:
5146
5147         CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
5148         mutex_unlock(&ioc->mptbase_cmds.mutex);
5149         return ret;
5150 }
5151
5152 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5153
5154 static void
5155 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
5156     MpiEventDataRaid_t * pRaidEventData)
5157 {
5158         int     volume;
5159         int     reason;
5160         int     disk;
5161         int     status;
5162         int     flags;
5163         int     state;
5164
5165         volume  = pRaidEventData->VolumeID;
5166         reason  = pRaidEventData->ReasonCode;
5167         disk    = pRaidEventData->PhysDiskNum;
5168         status  = le32_to_cpu(pRaidEventData->SettingsStatus);
5169         flags   = (status >> 0) & 0xff;
5170         state   = (status >> 8) & 0xff;
5171
5172         if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
5173                 return;
5174         }
5175
5176         if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
5177              reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
5178             (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
5179                 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
5180                         ioc->name, disk, volume);
5181         } else {
5182                 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
5183                         ioc->name, volume);
5184         }
5185
5186         switch(reason) {
5187         case MPI_EVENT_RAID_RC_VOLUME_CREATED:
5188                 printk(MYIOC_s_INFO_FMT "  volume has been created\n",
5189                         ioc->name);
5190                 break;
5191
5192         case MPI_EVENT_RAID_RC_VOLUME_DELETED:
5193
5194                 printk(MYIOC_s_INFO_FMT "  volume has been deleted\n",
5195                         ioc->name);
5196                 break;
5197
5198         case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
5199                 printk(MYIOC_s_INFO_FMT "  volume settings have been changed\n",
5200                         ioc->name);
5201                 break;
5202
5203         case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
5204                 printk(MYIOC_s_INFO_FMT "  volume is now %s%s%s%s\n",
5205                         ioc->name,
5206                         state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
5207                          ? "optimal"
5208                          : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
5209                           ? "degraded"
5210                           : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
5211                            ? "failed"
5212                            : "state unknown",
5213                         flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
5214                          ? ", enabled" : "",
5215                         flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
5216                          ? ", quiesced" : "",
5217                         flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
5218                          ? ", resync in progress" : "" );
5219                 break;
5220
5221         case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
5222                 printk(MYIOC_s_INFO_FMT "  volume membership of PhysDisk %d has changed\n",
5223                         ioc->name, disk);
5224                 break;
5225
5226         case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
5227                 printk(MYIOC_s_INFO_FMT "  PhysDisk has been created\n",
5228                         ioc->name);
5229                 break;
5230
5231         case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
5232                 printk(MYIOC_s_INFO_FMT "  PhysDisk has been deleted\n",
5233                         ioc->name);
5234                 break;
5235
5236         case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
5237                 printk(MYIOC_s_INFO_FMT "  PhysDisk settings have been changed\n",
5238                         ioc->name);
5239                 break;
5240
5241         case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
5242                 printk(MYIOC_s_INFO_FMT "  PhysDisk is now %s%s%s\n",
5243                         ioc->name,
5244                         state == MPI_PHYSDISK0_STATUS_ONLINE
5245                          ? "online"
5246                          : state == MPI_PHYSDISK0_STATUS_MISSING
5247                           ? "missing"
5248                           : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
5249                            ? "not compatible"
5250                            : state == MPI_PHYSDISK0_STATUS_FAILED
5251                             ? "failed"
5252                             : state == MPI_PHYSDISK0_STATUS_INITIALIZING
5253                              ? "initializing"
5254                              : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
5255                               ? "offline requested"
5256                               : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
5257                                ? "failed requested"
5258                                : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
5259                                 ? "offline"
5260                                 : "state unknown",
5261                         flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
5262                          ? ", out of sync" : "",
5263                         flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
5264                          ? ", quiesced" : "" );
5265                 break;
5266
5267         case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
5268                 printk(MYIOC_s_INFO_FMT "  Domain Validation needed for PhysDisk %d\n",
5269                         ioc->name, disk);
5270                 break;
5271
5272         case MPI_EVENT_RAID_RC_SMART_DATA:
5273                 printk(MYIOC_s_INFO_FMT "  SMART data received, ASC/ASCQ = %02xh/%02xh\n",
5274                         ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
5275                 break;
5276
5277         case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
5278                 printk(MYIOC_s_INFO_FMT "  replacement of PhysDisk %d has started\n",
5279                         ioc->name, disk);
5280                 break;
5281         }
5282 }
5283
5284 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5285 /**
5286  *      GetIoUnitPage2 - Retrieve BIOS version and boot order information.
5287  *      @ioc: Pointer to MPT_ADAPTER structure
5288  *
5289  *      Returns: 0 for success
5290  *      -ENOMEM if no memory available
5291  *              -EPERM if not allowed due to ISR context
5292  *              -EAGAIN if no msg frames currently available
5293  *              -EFAULT for non-successful reply or no reply (timeout)
5294  */
5295 static int
5296 GetIoUnitPage2(MPT_ADAPTER *ioc)
5297 {
5298         ConfigPageHeader_t       hdr;
5299         CONFIGPARMS              cfg;
5300         IOUnitPage2_t           *ppage_alloc;
5301         dma_addr_t               page_dma;
5302         int                      data_sz;
5303         int                      rc;
5304
5305         /* Get the page header */
5306         hdr.PageVersion = 0;
5307         hdr.PageLength = 0;
5308         hdr.PageNumber = 2;
5309         hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
5310         cfg.cfghdr.hdr = &hdr;
5311         cfg.physAddr = -1;
5312         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5313         cfg.dir = 0;
5314         cfg.pageAddr = 0;
5315         cfg.timeout = 0;
5316
5317         if ((rc = mpt_config(ioc, &cfg)) != 0)
5318                 return rc;
5319
5320         if (hdr.PageLength == 0)
5321                 return 0;
5322
5323         /* Read the config page */
5324         data_sz = hdr.PageLength * 4;
5325         rc = -ENOMEM;
5326         ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
5327         if (ppage_alloc) {
5328                 memset((u8 *)ppage_alloc, 0, data_sz);
5329                 cfg.physAddr = page_dma;
5330                 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5331
5332                 /* If Good, save data */
5333                 if ((rc = mpt_config(ioc, &cfg)) == 0)
5334                         ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
5335
5336                 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
5337         }
5338
5339         return rc;
5340 }
5341
5342 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5343 /**
5344  *      mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
5345  *      @ioc: Pointer to a Adapter Strucutre
5346  *      @portnum: IOC port number
5347  *
5348  *      Return: -EFAULT if read of config page header fails
5349  *                      or if no nvram
5350  *      If read of SCSI Port Page 0 fails,
5351  *              NVRAM = MPT_HOST_NVRAM_INVALID  (0xFFFFFFFF)
5352  *              Adapter settings: async, narrow
5353  *              Return 1
5354  *      If read of SCSI Port Page 2 fails,
5355  *              Adapter settings valid
5356  *              NVRAM = MPT_HOST_NVRAM_INVALID  (0xFFFFFFFF)
5357  *              Return 1
5358  *      Else
5359  *              Both valid
5360  *              Return 0
5361  *      CHECK - what type of locking mechanisms should be used????
5362  */
5363 static int
5364 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
5365 {
5366         u8                      *pbuf;
5367         dma_addr_t               buf_dma;
5368         CONFIGPARMS              cfg;
5369         ConfigPageHeader_t       header;
5370         int                      ii;
5371         int                      data, rc = 0;
5372
5373         /* Allocate memory
5374          */
5375         if (!ioc->spi_data.nvram) {
5376                 int      sz;
5377                 u8      *mem;
5378                 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
5379                 mem = kmalloc(sz, GFP_ATOMIC);
5380                 if (mem == NULL)
5381                         return -EFAULT;
5382
5383                 ioc->spi_data.nvram = (int *) mem;
5384
5385                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
5386                         ioc->name, ioc->spi_data.nvram, sz));
5387         }
5388
5389         /* Invalidate NVRAM information
5390          */
5391         for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5392                 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
5393         }
5394
5395         /* Read SPP0 header, allocate memory, then read page.
5396          */
5397         header.PageVersion = 0;
5398         header.PageLength = 0;
5399         header.PageNumber = 0;
5400         header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5401         cfg.cfghdr.hdr = &header;
5402         cfg.physAddr = -1;
5403         cfg.pageAddr = portnum;
5404         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5405         cfg.dir = 0;
5406         cfg.timeout = 0;        /* use default */
5407         if (mpt_config(ioc, &cfg) != 0)
5408                  return -EFAULT;
5409
5410         if (header.PageLength > 0) {
5411                 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5412                 if (pbuf) {
5413                         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5414                         cfg.physAddr = buf_dma;
5415                         if (mpt_config(ioc, &cfg) != 0) {
5416                                 ioc->spi_data.maxBusWidth = MPT_NARROW;
5417                                 ioc->spi_data.maxSyncOffset = 0;
5418                                 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5419                                 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
5420                                 rc = 1;
5421                                 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5422                                         "Unable to read PortPage0 minSyncFactor=%x\n",
5423                                         ioc->name, ioc->spi_data.minSyncFactor));
5424                         } else {
5425                                 /* Save the Port Page 0 data
5426                                  */
5427                                 SCSIPortPage0_t  *pPP0 = (SCSIPortPage0_t  *) pbuf;
5428                                 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
5429                                 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
5430
5431                                 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
5432                                         ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
5433                                         ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5434                                                 "noQas due to Capabilities=%x\n",
5435                                                 ioc->name, pPP0->Capabilities));
5436                                 }
5437                                 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
5438                                 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
5439                                 if (data) {
5440                                         ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
5441                                         data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
5442                                         ioc->spi_data.minSyncFactor = (u8) (data >> 8);
5443                                         ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5444                                                 "PortPage0 minSyncFactor=%x\n",
5445                                                 ioc->name, ioc->spi_data.minSyncFactor));
5446                                 } else {
5447                                         ioc->spi_data.maxSyncOffset = 0;
5448                                         ioc->spi_data.minSyncFactor = MPT_ASYNC;
5449                                 }
5450
5451                                 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
5452
5453                                 /* Update the minSyncFactor based on bus type.
5454                                  */
5455                                 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
5456                                         (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE))  {
5457
5458                                         if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
5459                                                 ioc->spi_data.minSyncFactor = MPT_ULTRA;
5460                                                 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5461                                                         "HVD or SE detected, minSyncFactor=%x\n",
5462                                                         ioc->name, ioc->spi_data.minSyncFactor));
5463                                         }
5464                                 }
5465                         }
5466                         if (pbuf) {
5467                                 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5468                         }
5469                 }
5470         }
5471
5472         /* SCSI Port Page 2 - Read the header then the page.
5473          */
5474         header.PageVersion = 0;
5475         header.PageLength = 0;
5476         header.PageNumber = 2;
5477         header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5478         cfg.cfghdr.hdr = &header;
5479         cfg.physAddr = -1;
5480         cfg.pageAddr = portnum;
5481         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5482         cfg.dir = 0;
5483         if (mpt_config(ioc, &cfg) != 0)
5484                 return -EFAULT;
5485
5486         if (header.PageLength > 0) {
5487                 /* Allocate memory and read SCSI Port Page 2
5488                  */
5489                 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5490                 if (pbuf) {
5491                         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
5492                         cfg.physAddr = buf_dma;
5493                         if (mpt_config(ioc, &cfg) != 0) {
5494                                 /* Nvram data is left with INVALID mark
5495                                  */
5496                                 rc = 1;
5497                         } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
5498
5499                                 /* This is an ATTO adapter, read Page2 accordingly
5500                                 */
5501                                 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t  *) pbuf;
5502                                 ATTODeviceInfo_t *pdevice = NULL;
5503                                 u16 ATTOFlags;
5504
5505                                 /* Save the Port Page 2 data
5506                                  * (reformat into a 32bit quantity)
5507                                  */
5508                                 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5509                                   pdevice = &pPP2->DeviceSettings[ii];
5510                                   ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
5511                                   data = 0;
5512
5513                                   /* Translate ATTO device flags to LSI format
5514                                    */
5515                                   if (ATTOFlags & ATTOFLAG_DISC)
5516                                     data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
5517                                   if (ATTOFlags & ATTOFLAG_ID_ENB)
5518                                     data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
5519                                   if (ATTOFlags & ATTOFLAG_LUN_ENB)
5520                                     data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
5521                                   if (ATTOFlags & ATTOFLAG_TAGGED)
5522                                     data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
5523                                   if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
5524                                     data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
5525
5526                                   data = (data << 16) | (pdevice->Period << 8) | 10;
5527                                   ioc->spi_data.nvram[ii] = data;
5528                                 }
5529                         } else {
5530                                 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t  *) pbuf;
5531                                 MpiDeviceInfo_t *pdevice = NULL;
5532
5533                                 /*
5534                                  * Save "Set to Avoid SCSI Bus Resets" flag
5535                                  */
5536                                 ioc->spi_data.bus_reset =
5537                                     (le32_to_cpu(pPP2->PortFlags) &
5538                                 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
5539                                     0 : 1 ;
5540
5541                                 /* Save the Port Page 2 data
5542                                  * (reformat into a 32bit quantity)
5543                                  */
5544                                 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
5545                                 ioc->spi_data.PortFlags = data;
5546                                 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5547                                         pdevice = &pPP2->DeviceSettings[ii];
5548                                         data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
5549                                                 (pdevice->SyncFactor << 8) | pdevice->Timeout;
5550                                         ioc->spi_data.nvram[ii] = data;
5551                                 }
5552                         }
5553
5554                         pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5555                 }
5556         }
5557
5558         /* Update Adapter limits with those from NVRAM
5559          * Comment: Don't need to do this. Target performance
5560          * parameters will never exceed the adapters limits.
5561          */
5562
5563         return rc;
5564 }
5565
5566 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5567 /**
5568  *      mpt_readScsiDevicePageHeaders - save version and length of SDP1
5569  *      @ioc: Pointer to a Adapter Strucutre
5570  *      @portnum: IOC port number
5571  *
5572  *      Return: -EFAULT if read of config page header fails
5573  *              or 0 if success.
5574  */
5575 static int
5576 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5577 {
5578         CONFIGPARMS              cfg;
5579         ConfigPageHeader_t       header;
5580
5581         /* Read the SCSI Device Page 1 header
5582          */
5583         header.PageVersion = 0;
5584         header.PageLength = 0;
5585         header.PageNumber = 1;
5586         header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5587         cfg.cfghdr.hdr = &header;
5588         cfg.physAddr = -1;
5589         cfg.pageAddr = portnum;
5590         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5591         cfg.dir = 0;
5592         cfg.timeout = 0;
5593         if (mpt_config(ioc, &cfg) != 0)
5594                  return -EFAULT;
5595
5596         ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5597         ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5598
5599         header.PageVersion = 0;
5600         header.PageLength = 0;
5601         header.PageNumber = 0;
5602         header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5603         if (mpt_config(ioc, &cfg) != 0)
5604                  return -EFAULT;
5605
5606         ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5607         ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5608
5609         dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5610                         ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5611
5612         dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5613                         ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5614         return 0;
5615 }
5616
5617 /**
5618  * mpt_inactive_raid_list_free - This clears this link list.
5619  * @ioc : pointer to per adapter structure
5620  **/
5621 static void
5622 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5623 {
5624         struct inactive_raid_component_info *component_info, *pNext;
5625
5626         if (list_empty(&ioc->raid_data.inactive_list))
5627                 return;
5628
5629         mutex_lock(&ioc->raid_data.inactive_list_mutex);
5630         list_for_each_entry_safe(component_info, pNext,
5631             &ioc->raid_data.inactive_list, list) {
5632                 list_del(&component_info->list);
5633                 kfree(component_info);
5634         }
5635         mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5636 }
5637
5638 /**
5639  * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5640  *
5641  * @ioc : pointer to per adapter structure
5642  * @channel : volume channel
5643  * @id : volume target id
5644  **/
5645 static void
5646 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5647 {
5648         CONFIGPARMS                     cfg;
5649         ConfigPageHeader_t              hdr;
5650         dma_addr_t                      dma_handle;
5651         pRaidVolumePage0_t              buffer = NULL;
5652         int                             i;
5653         RaidPhysDiskPage0_t             phys_disk;
5654         struct inactive_raid_component_info *component_info;
5655         int                             handle_inactive_volumes;
5656
5657         memset(&cfg, 0 , sizeof(CONFIGPARMS));
5658         memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5659         hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5660         cfg.pageAddr = (channel << 8) + id;
5661         cfg.cfghdr.hdr = &hdr;
5662         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5663
5664         if (mpt_config(ioc, &cfg) != 0)
5665                 goto out;
5666
5667         if (!hdr.PageLength)
5668                 goto out;
5669
5670         buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5671             &dma_handle);
5672
5673         if (!buffer)
5674                 goto out;
5675
5676         cfg.physAddr = dma_handle;
5677         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5678
5679         if (mpt_config(ioc, &cfg) != 0)
5680                 goto out;
5681
5682         if (!buffer->NumPhysDisks)
5683                 goto out;
5684
5685         handle_inactive_volumes =
5686            (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5687            (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5688             buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5689             buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5690
5691         if (!handle_inactive_volumes)
5692                 goto out;
5693
5694         mutex_lock(&ioc->raid_data.inactive_list_mutex);
5695         for (i = 0; i < buffer->NumPhysDisks; i++) {
5696                 if(mpt_raid_phys_disk_pg0(ioc,
5697                     buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5698                         continue;
5699
5700                 if ((component_info = kmalloc(sizeof (*component_info),
5701                  GFP_KERNEL)) == NULL)
5702                         continue;
5703
5704                 component_info->volumeID = id;
5705                 component_info->volumeBus = channel;
5706                 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5707                 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5708                 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5709                 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5710
5711                 list_add_tail(&component_info->list,
5712                     &ioc->raid_data.inactive_list);
5713         }
5714         mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5715
5716  out:
5717         if (buffer)
5718                 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5719                     dma_handle);
5720 }
5721
5722 /**
5723  *      mpt_raid_phys_disk_pg0 - returns phys disk page zero
5724  *      @ioc: Pointer to a Adapter Structure
5725  *      @phys_disk_num: io unit unique phys disk num generated by the ioc
5726  *      @phys_disk: requested payload data returned
5727  *
5728  *      Return:
5729  *      0 on success
5730  *      -EFAULT if read of config page header fails or data pointer not NULL
5731  *      -ENOMEM if pci_alloc failed
5732  **/
5733 int
5734 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num,
5735                         RaidPhysDiskPage0_t *phys_disk)
5736 {
5737         CONFIGPARMS                     cfg;
5738         ConfigPageHeader_t              hdr;
5739         dma_addr_t                      dma_handle;
5740         pRaidPhysDiskPage0_t            buffer = NULL;
5741         int                             rc;
5742
5743         memset(&cfg, 0 , sizeof(CONFIGPARMS));
5744         memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5745         memset(phys_disk, 0, sizeof(RaidPhysDiskPage0_t));
5746
5747         hdr.PageVersion = MPI_RAIDPHYSDISKPAGE0_PAGEVERSION;
5748         hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5749         cfg.cfghdr.hdr = &hdr;
5750         cfg.physAddr = -1;
5751         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5752
5753         if (mpt_config(ioc, &cfg) != 0) {
5754                 rc = -EFAULT;
5755                 goto out;
5756         }
5757
5758         if (!hdr.PageLength) {
5759                 rc = -EFAULT;
5760                 goto out;
5761         }
5762
5763         buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5764             &dma_handle);
5765
5766         if (!buffer) {
5767                 rc = -ENOMEM;
5768                 goto out;
5769         }
5770
5771         cfg.physAddr = dma_handle;
5772         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5773         cfg.pageAddr = phys_disk_num;
5774
5775         if (mpt_config(ioc, &cfg) != 0) {
5776                 rc = -EFAULT;
5777                 goto out;
5778         }
5779
5780         rc = 0;
5781         memcpy(phys_disk, buffer, sizeof(*buffer));
5782         phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5783
5784  out:
5785
5786         if (buffer)
5787                 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5788                     dma_handle);
5789
5790         return rc;
5791 }
5792
5793 /**
5794  *      mpt_raid_phys_disk_get_num_paths - returns number paths associated to this phys_num
5795  *      @ioc: Pointer to a Adapter Structure
5796  *      @phys_disk_num: io unit unique phys disk num generated by the ioc
5797  *
5798  *      Return:
5799  *      returns number paths
5800  **/
5801 int
5802 mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER *ioc, u8 phys_disk_num)
5803 {
5804         CONFIGPARMS                     cfg;
5805         ConfigPageHeader_t              hdr;
5806         dma_addr_t                      dma_handle;
5807         pRaidPhysDiskPage1_t            buffer = NULL;
5808         int                             rc;
5809
5810         memset(&cfg, 0 , sizeof(CONFIGPARMS));
5811         memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5812
5813         hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5814         hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5815         hdr.PageNumber = 1;
5816         cfg.cfghdr.hdr = &hdr;
5817         cfg.physAddr = -1;
5818         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5819
5820         if (mpt_config(ioc, &cfg) != 0) {
5821                 rc = 0;
5822                 goto out;
5823         }
5824
5825         if (!hdr.PageLength) {
5826                 rc = 0;
5827                 goto out;
5828         }
5829
5830         buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5831             &dma_handle);
5832
5833         if (!buffer) {
5834                 rc = 0;
5835                 goto out;
5836         }
5837
5838         cfg.physAddr = dma_handle;
5839         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5840         cfg.pageAddr = phys_disk_num;
5841
5842         if (mpt_config(ioc, &cfg) != 0) {
5843                 rc = 0;
5844                 goto out;
5845         }
5846
5847         rc = buffer->NumPhysDiskPaths;
5848  out:
5849
5850         if (buffer)
5851                 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5852                     dma_handle);
5853
5854         return rc;
5855 }
5856 EXPORT_SYMBOL(mpt_raid_phys_disk_get_num_paths);
5857
5858 /**
5859  *      mpt_raid_phys_disk_pg1 - returns phys disk page 1
5860  *      @ioc: Pointer to a Adapter Structure
5861  *      @phys_disk_num: io unit unique phys disk num generated by the ioc
5862  *      @phys_disk: requested payload data returned
5863  *
5864  *      Return:
5865  *      0 on success
5866  *      -EFAULT if read of config page header fails or data pointer not NULL
5867  *      -ENOMEM if pci_alloc failed
5868  **/
5869 int
5870 mpt_raid_phys_disk_pg1(MPT_ADAPTER *ioc, u8 phys_disk_num,
5871                 RaidPhysDiskPage1_t *phys_disk)
5872 {
5873         CONFIGPARMS                     cfg;
5874         ConfigPageHeader_t              hdr;
5875         dma_addr_t                      dma_handle;
5876         pRaidPhysDiskPage1_t            buffer = NULL;
5877         int                             rc;
5878         int                             i;
5879         __le64                          sas_address;
5880
5881         memset(&cfg, 0 , sizeof(CONFIGPARMS));
5882         memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5883         rc = 0;
5884
5885         hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5886         hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5887         hdr.PageNumber = 1;
5888         cfg.cfghdr.hdr = &hdr;
5889         cfg.physAddr = -1;
5890         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5891
5892         if (mpt_config(ioc, &cfg) != 0) {
5893                 rc = -EFAULT;
5894                 goto out;
5895         }
5896
5897         if (!hdr.PageLength) {
5898                 rc = -EFAULT;
5899                 goto out;
5900         }
5901
5902         buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5903             &dma_handle);
5904
5905         if (!buffer) {
5906                 rc = -ENOMEM;
5907                 goto out;
5908         }
5909
5910         cfg.physAddr = dma_handle;
5911         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5912         cfg.pageAddr = phys_disk_num;
5913
5914         if (mpt_config(ioc, &cfg) != 0) {
5915                 rc = -EFAULT;
5916                 goto out;
5917         }
5918
5919         phys_disk->NumPhysDiskPaths = buffer->NumPhysDiskPaths;
5920         phys_disk->PhysDiskNum = phys_disk_num;
5921         for (i = 0; i < phys_disk->NumPhysDiskPaths; i++) {
5922                 phys_disk->Path[i].PhysDiskID = buffer->Path[i].PhysDiskID;
5923                 phys_disk->Path[i].PhysDiskBus = buffer->Path[i].PhysDiskBus;
5924                 phys_disk->Path[i].OwnerIdentifier =
5925                                 buffer->Path[i].OwnerIdentifier;
5926                 phys_disk->Path[i].Flags = le16_to_cpu(buffer->Path[i].Flags);
5927                 memcpy(&sas_address, &buffer->Path[i].WWID, sizeof(__le64));
5928                 sas_address = le64_to_cpu(sas_address);
5929                 memcpy(&phys_disk->Path[i].WWID, &sas_address, sizeof(__le64));
5930                 memcpy(&sas_address,
5931                                 &buffer->Path[i].OwnerWWID, sizeof(__le64));
5932                 sas_address = le64_to_cpu(sas_address);
5933                 memcpy(&phys_disk->Path[i].OwnerWWID,
5934                                 &sas_address, sizeof(__le64));
5935         }
5936
5937  out:
5938
5939         if (buffer)
5940                 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5941                     dma_handle);
5942
5943         return rc;
5944 }
5945 EXPORT_SYMBOL(mpt_raid_phys_disk_pg1);
5946
5947
5948 /**
5949  *      mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5950  *      @ioc: Pointer to a Adapter Strucutre
5951  *
5952  *      Return:
5953  *      0 on success
5954  *      -EFAULT if read of config page header fails or data pointer not NULL
5955  *      -ENOMEM if pci_alloc failed
5956  **/
5957 int
5958 mpt_findImVolumes(MPT_ADAPTER *ioc)
5959 {
5960         IOCPage2_t              *pIoc2;
5961         u8                      *mem;
5962         dma_addr_t               ioc2_dma;
5963         CONFIGPARMS              cfg;
5964         ConfigPageHeader_t       header;
5965         int                      rc = 0;
5966         int                      iocpage2sz;
5967         int                      i;
5968
5969         if (!ioc->ir_firmware)
5970                 return 0;
5971
5972         /* Free the old page
5973          */
5974         kfree(ioc->raid_data.pIocPg2);
5975         ioc->raid_data.pIocPg2 = NULL;
5976         mpt_inactive_raid_list_free(ioc);
5977
5978         /* Read IOCP2 header then the page.
5979          */
5980         header.PageVersion = 0;
5981         header.PageLength = 0;
5982         header.PageNumber = 2;
5983         header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5984         cfg.cfghdr.hdr = &header;
5985         cfg.physAddr = -1;
5986         cfg.pageAddr = 0;
5987         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5988         cfg.dir = 0;
5989         cfg.timeout = 0;
5990         if (mpt_config(ioc, &cfg) != 0)
5991                  return -EFAULT;
5992
5993         if (header.PageLength == 0)
5994                 return -EFAULT;
5995
5996         iocpage2sz = header.PageLength * 4;
5997         pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5998         if (!pIoc2)
5999                 return -ENOMEM;
6000
6001         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6002         cfg.physAddr = ioc2_dma;
6003         if (mpt_config(ioc, &cfg) != 0)
6004                 goto out;
6005
6006         mem = kmalloc(iocpage2sz, GFP_KERNEL);
6007         if (!mem) {
6008                 rc = -ENOMEM;
6009                 goto out;
6010         }
6011
6012         memcpy(mem, (u8 *)pIoc2, iocpage2sz);
6013         ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
6014
6015         mpt_read_ioc_pg_3(ioc);
6016
6017         for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
6018                 mpt_inactive_raid_volumes(ioc,
6019                     pIoc2->RaidVolume[i].VolumeBus,
6020                     pIoc2->RaidVolume[i].VolumeID);
6021
6022  out:
6023         pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
6024
6025         return rc;
6026 }
6027
6028 static int
6029 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
6030 {
6031         IOCPage3_t              *pIoc3;
6032         u8                      *mem;
6033         CONFIGPARMS              cfg;
6034         ConfigPageHeader_t       header;
6035         dma_addr_t               ioc3_dma;
6036         int                      iocpage3sz = 0;
6037
6038         /* Free the old page
6039          */
6040         kfree(ioc->raid_data.pIocPg3);
6041         ioc->raid_data.pIocPg3 = NULL;
6042
6043         /* There is at least one physical disk.
6044          * Read and save IOC Page 3
6045          */
6046         header.PageVersion = 0;
6047         header.PageLength = 0;
6048         header.PageNumber = 3;
6049         header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6050         cfg.cfghdr.hdr = &header;
6051         cfg.physAddr = -1;
6052         cfg.pageAddr = 0;
6053         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6054         cfg.dir = 0;
6055         cfg.timeout = 0;
6056         if (mpt_config(ioc, &cfg) != 0)
6057                 return 0;
6058
6059         if (header.PageLength == 0)
6060                 return 0;
6061
6062         /* Read Header good, alloc memory
6063          */
6064         iocpage3sz = header.PageLength * 4;
6065         pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
6066         if (!pIoc3)
6067                 return 0;
6068
6069         /* Read the Page and save the data
6070          * into malloc'd memory.
6071          */
6072         cfg.physAddr = ioc3_dma;
6073         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6074         if (mpt_config(ioc, &cfg) == 0) {
6075                 mem = kmalloc(iocpage3sz, GFP_KERNEL);
6076                 if (mem) {
6077                         memcpy(mem, (u8 *)pIoc3, iocpage3sz);
6078                         ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
6079                 }
6080         }
6081
6082         pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
6083
6084         return 0;
6085 }
6086
6087 static void
6088 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
6089 {
6090         IOCPage4_t              *pIoc4;
6091         CONFIGPARMS              cfg;
6092         ConfigPageHeader_t       header;
6093         dma_addr_t               ioc4_dma;
6094         int                      iocpage4sz;
6095
6096         /* Read and save IOC Page 4
6097          */
6098         header.PageVersion = 0;
6099         header.PageLength = 0;
6100         header.PageNumber = 4;
6101         header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6102         cfg.cfghdr.hdr = &header;
6103         cfg.physAddr = -1;
6104         cfg.pageAddr = 0;
6105         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6106         cfg.dir = 0;
6107         cfg.timeout = 0;
6108         if (mpt_config(ioc, &cfg) != 0)
6109                 return;
6110
6111         if (header.PageLength == 0)
6112                 return;
6113
6114         if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
6115                 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
6116                 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
6117                 if (!pIoc4)
6118                         return;
6119                 ioc->alloc_total += iocpage4sz;
6120         } else {
6121                 ioc4_dma = ioc->spi_data.IocPg4_dma;
6122                 iocpage4sz = ioc->spi_data.IocPg4Sz;
6123         }
6124
6125         /* Read the Page into dma memory.
6126          */
6127         cfg.physAddr = ioc4_dma;
6128         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6129         if (mpt_config(ioc, &cfg) == 0) {
6130                 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
6131                 ioc->spi_data.IocPg4_dma = ioc4_dma;
6132                 ioc->spi_data.IocPg4Sz = iocpage4sz;
6133         } else {
6134                 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
6135                 ioc->spi_data.pIocPg4 = NULL;
6136                 ioc->alloc_total -= iocpage4sz;
6137         }
6138 }
6139
6140 static void
6141 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
6142 {
6143         IOCPage1_t              *pIoc1;
6144         CONFIGPARMS              cfg;
6145         ConfigPageHeader_t       header;
6146         dma_addr_t               ioc1_dma;
6147         int                      iocpage1sz = 0;
6148         u32                      tmp;
6149
6150         /* Check the Coalescing Timeout in IOC Page 1
6151          */
6152         header.PageVersion = 0;
6153         header.PageLength = 0;
6154         header.PageNumber = 1;
6155         header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6156         cfg.cfghdr.hdr = &header;
6157         cfg.physAddr = -1;
6158         cfg.pageAddr = 0;
6159         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6160         cfg.dir = 0;
6161         cfg.timeout = 0;
6162         if (mpt_config(ioc, &cfg) != 0)
6163                 return;
6164
6165         if (header.PageLength == 0)
6166                 return;
6167
6168         /* Read Header good, alloc memory
6169          */
6170         iocpage1sz = header.PageLength * 4;
6171         pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
6172         if (!pIoc1)
6173                 return;
6174
6175         /* Read the Page and check coalescing timeout
6176          */
6177         cfg.physAddr = ioc1_dma;
6178         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6179         if (mpt_config(ioc, &cfg) == 0) {
6180
6181                 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
6182                 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
6183                         tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
6184
6185                         dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
6186                                         ioc->name, tmp));
6187
6188                         if (tmp > MPT_COALESCING_TIMEOUT) {
6189                                 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
6190
6191                                 /* Write NVRAM and current
6192                                  */
6193                                 cfg.dir = 1;
6194                                 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
6195                                 if (mpt_config(ioc, &cfg) == 0) {
6196                                         dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
6197                                                         ioc->name, MPT_COALESCING_TIMEOUT));
6198
6199                                         cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
6200                                         if (mpt_config(ioc, &cfg) == 0) {
6201                                                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6202                                                                 "Reset NVRAM Coalescing Timeout to = %d\n",
6203                                                                 ioc->name, MPT_COALESCING_TIMEOUT));
6204                                         } else {
6205                                                 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6206                                                                 "Reset NVRAM Coalescing Timeout Failed\n",
6207                                                                 ioc->name));
6208                                         }
6209
6210                                 } else {
6211                                         dprintk(ioc, printk(MYIOC_s_WARN_FMT
6212                                                 "Reset of Current Coalescing Timeout Failed!\n",
6213                                                 ioc->name));
6214                                 }
6215                         }
6216
6217                 } else {
6218                         dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
6219                 }
6220         }
6221
6222         pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
6223
6224         return;
6225 }
6226
6227 static void
6228 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
6229 {
6230         CONFIGPARMS             cfg;
6231         ConfigPageHeader_t      hdr;
6232         dma_addr_t              buf_dma;
6233         ManufacturingPage0_t    *pbuf = NULL;
6234
6235         memset(&cfg, 0 , sizeof(CONFIGPARMS));
6236         memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
6237
6238         hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
6239         cfg.cfghdr.hdr = &hdr;
6240         cfg.physAddr = -1;
6241         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6242         cfg.timeout = 10;
6243
6244         if (mpt_config(ioc, &cfg) != 0)
6245                 goto out;
6246
6247         if (!cfg.cfghdr.hdr->PageLength)
6248                 goto out;
6249
6250         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6251         pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
6252         if (!pbuf)
6253                 goto out;
6254
6255         cfg.physAddr = buf_dma;
6256
6257         if (mpt_config(ioc, &cfg) != 0)
6258                 goto out;
6259
6260         memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
6261         memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
6262         memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
6263
6264         out:
6265
6266         if (pbuf)
6267                 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
6268 }
6269
6270 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6271 /**
6272  *      SendEventNotification - Send EventNotification (on or off) request to adapter
6273  *      @ioc: Pointer to MPT_ADAPTER structure
6274  *      @EvSwitch: Event switch flags
6275  *      @sleepFlag: Specifies whether the process can sleep
6276  */
6277 static int
6278 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch, int sleepFlag)
6279 {
6280         EventNotification_t     evn;
6281         MPIDefaultReply_t       reply_buf;
6282
6283         memset(&evn, 0, sizeof(EventNotification_t));
6284         memset(&reply_buf, 0, sizeof(MPIDefaultReply_t));
6285
6286         evn.Function = MPI_FUNCTION_EVENT_NOTIFICATION;
6287         evn.Switch = EvSwitch;
6288         evn.MsgContext = cpu_to_le32(mpt_base_index << 16);
6289
6290         devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6291             "Sending EventNotification (%d) request %p\n",
6292             ioc->name, EvSwitch, &evn));
6293
6294         return mpt_handshake_req_reply_wait(ioc, sizeof(EventNotification_t),
6295             (u32 *)&evn, sizeof(MPIDefaultReply_t), (u16 *)&reply_buf, 30,
6296             sleepFlag);
6297 }
6298
6299 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6300 /**
6301  *      SendEventAck - Send EventAck request to MPT adapter.
6302  *      @ioc: Pointer to MPT_ADAPTER structure
6303  *      @evnp: Pointer to original EventNotification request
6304  */
6305 static int
6306 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
6307 {
6308         EventAck_t      *pAck;
6309
6310         if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6311                 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
6312                     ioc->name, __func__));
6313                 return -1;
6314         }
6315
6316         devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
6317
6318         pAck->Function     = MPI_FUNCTION_EVENT_ACK;
6319         pAck->ChainOffset  = 0;
6320         pAck->Reserved[0]  = pAck->Reserved[1] = 0;
6321         pAck->MsgFlags     = 0;
6322         pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
6323         pAck->Event        = evnp->Event;
6324         pAck->EventContext = evnp->EventContext;
6325
6326         mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
6327
6328         return 0;
6329 }
6330
6331 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6332 /**
6333  *      mpt_config - Generic function to issue config message
6334  *      @ioc:   Pointer to an adapter structure
6335  *      @pCfg:  Pointer to a configuration structure. Struct contains
6336  *              action, page address, direction, physical address
6337  *              and pointer to a configuration page header
6338  *              Page header is updated.
6339  *
6340  *      Returns 0 for success
6341  *      -EPERM if not allowed due to ISR context
6342  *      -EAGAIN if no msg frames currently available
6343  *      -EFAULT for non-successful reply or no reply (timeout)
6344  */
6345 int
6346 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
6347 {
6348         Config_t        *pReq;
6349         ConfigReply_t   *pReply;
6350         ConfigExtendedPageHeader_t  *pExtHdr = NULL;
6351         MPT_FRAME_HDR   *mf;
6352         int              ii;
6353         int              flagsLength;
6354         long             timeout;
6355         int              ret;
6356         u8               page_type = 0, extend_page;
6357         unsigned long    timeleft;
6358         unsigned long    flags;
6359     int          in_isr;
6360         u8               issue_hard_reset = 0;
6361         u8               retry_count = 0;
6362
6363         /*      Prevent calling wait_event() (below), if caller happens
6364          *      to be in ISR context, because that is fatal!
6365          */
6366         in_isr = in_interrupt();
6367         if (in_isr) {
6368                 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
6369                                 ioc->name));
6370                 return -EPERM;
6371     }
6372
6373         /* don't send a config page during diag reset */
6374         spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6375         if (ioc->ioc_reset_in_progress) {
6376                 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6377                     "%s: busy with host reset\n", ioc->name, __func__));
6378                 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6379                 return -EBUSY;
6380         }
6381         spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6382
6383         /* don't send if no chance of success */
6384         if (!ioc->active ||
6385             mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_OPERATIONAL) {
6386                 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6387                     "%s: ioc not operational, %d, %xh\n",
6388                     ioc->name, __func__, ioc->active,
6389                     mpt_GetIocState(ioc, 0)));
6390                 return -EFAULT;
6391         }
6392
6393  retry_config:
6394         mutex_lock(&ioc->mptbase_cmds.mutex);
6395         /* init the internal cmd struct */
6396         memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
6397         INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
6398
6399         /* Get and Populate a free Frame
6400          */
6401         if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6402                 dcprintk(ioc, printk(MYIOC_s_WARN_FMT
6403                 "mpt_config: no msg frames!\n", ioc->name));
6404                 ret = -EAGAIN;
6405                 goto out;
6406         }
6407
6408         pReq = (Config_t *)mf;
6409         pReq->Action = pCfg->action;
6410         pReq->Reserved = 0;
6411         pReq->ChainOffset = 0;
6412         pReq->Function = MPI_FUNCTION_CONFIG;
6413
6414         /* Assume page type is not extended and clear "reserved" fields. */
6415         pReq->ExtPageLength = 0;
6416         pReq->ExtPageType = 0;
6417         pReq->MsgFlags = 0;
6418
6419         for (ii=0; ii < 8; ii++)
6420                 pReq->Reserved2[ii] = 0;
6421
6422         pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
6423         pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
6424         pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
6425         pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
6426
6427         if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
6428                 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
6429                 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
6430                 pReq->ExtPageType = pExtHdr->ExtPageType;
6431                 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
6432
6433                 /* Page Length must be treated as a reserved field for the
6434                  * extended header.
6435                  */
6436                 pReq->Header.PageLength = 0;
6437         }
6438
6439         pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
6440
6441         /* Add a SGE to the config request.
6442          */
6443         if (pCfg->dir)
6444                 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
6445         else
6446                 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
6447
6448         if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) ==
6449             MPI_CONFIG_PAGETYPE_EXTENDED) {
6450                 flagsLength |= pExtHdr->ExtPageLength * 4;
6451                 page_type = pReq->ExtPageType;
6452                 extend_page = 1;
6453         } else {
6454                 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
6455                 page_type = pReq->Header.PageType;
6456                 extend_page = 0;
6457         }
6458
6459         dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6460             "Sending Config request type 0x%x, page 0x%x and action %d\n",
6461             ioc->name, page_type, pReq->Header.PageNumber, pReq->Action));
6462
6463         ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
6464         timeout = (pCfg->timeout < 15) ? HZ*15 : HZ*pCfg->timeout;
6465         mpt_put_msg_frame(mpt_base_index, ioc, mf);
6466         timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done,
6467                 timeout);
6468         if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
6469                 ret = -ETIME;
6470                 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6471                     "Failed Sending Config request type 0x%x, page 0x%x,"
6472                     " action %d, status %xh, time left %ld\n\n",
6473                         ioc->name, page_type, pReq->Header.PageNumber,
6474                         pReq->Action, ioc->mptbase_cmds.status, timeleft));
6475                 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
6476                         goto out;
6477                 if (!timeleft) {
6478                         spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6479                         if (ioc->ioc_reset_in_progress) {
6480                                 spin_unlock_irqrestore(&ioc->taskmgmt_lock,
6481                                         flags);
6482                                 printk(MYIOC_s_INFO_FMT "%s: host reset in"
6483                                         " progress mpt_config timed out.!!\n",
6484                                         __func__, ioc->name);
6485                                 return -EFAULT;
6486                         }
6487                         spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6488                         issue_hard_reset = 1;
6489                 }
6490                 goto out;
6491         }
6492
6493         if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
6494                 ret = -1;
6495                 goto out;
6496         }
6497         pReply = (ConfigReply_t *)ioc->mptbase_cmds.reply;
6498         ret = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
6499         if (ret == MPI_IOCSTATUS_SUCCESS) {
6500                 if (extend_page) {
6501                         pCfg->cfghdr.ehdr->ExtPageLength =
6502                             le16_to_cpu(pReply->ExtPageLength);
6503                         pCfg->cfghdr.ehdr->ExtPageType =
6504                             pReply->ExtPageType;
6505                 }
6506                 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
6507                 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
6508                 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
6509                 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
6510
6511         }
6512
6513         if (retry_count)
6514                 printk(MYIOC_s_INFO_FMT "Retry completed "
6515                     "ret=0x%x timeleft=%ld\n",
6516                     ioc->name, ret, timeleft);
6517
6518         dcprintk(ioc, printk(KERN_DEBUG "IOCStatus=%04xh, IOCLogInfo=%08xh\n",
6519              ret, le32_to_cpu(pReply->IOCLogInfo)));
6520
6521 out:
6522
6523         CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
6524         mutex_unlock(&ioc->mptbase_cmds.mutex);
6525         if (issue_hard_reset) {
6526                 issue_hard_reset = 0;
6527                 printk(MYIOC_s_WARN_FMT
6528                        "Issuing Reset from %s!!, doorbell=0x%08x\n",
6529                        ioc->name, __func__, mpt_GetIocState(ioc, 0));
6530                 if (retry_count == 0) {
6531                         if (mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP) != 0)
6532                                 retry_count++;
6533                 } else
6534                         mpt_HardResetHandler(ioc, CAN_SLEEP);
6535
6536                 mpt_free_msg_frame(ioc, mf);
6537                 /* attempt one retry for a timed out command */
6538                 if (retry_count < 2) {
6539                         printk(MYIOC_s_INFO_FMT
6540                             "Attempting Retry Config request"
6541                             " type 0x%x, page 0x%x,"
6542                             " action %d\n", ioc->name, page_type,
6543                             pCfg->cfghdr.hdr->PageNumber, pCfg->action);
6544                         retry_count++;
6545                         goto retry_config;
6546                 }
6547         }
6548         return ret;
6549
6550 }
6551
6552 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6553 /**
6554  *      mpt_ioc_reset - Base cleanup for hard reset
6555  *      @ioc: Pointer to the adapter structure
6556  *      @reset_phase: Indicates pre- or post-reset functionality
6557  *
6558  *      Remark: Frees resources with internally generated commands.
6559  */
6560 static int
6561 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
6562 {
6563         switch (reset_phase) {
6564         case MPT_IOC_SETUP_RESET:
6565                 ioc->taskmgmt_quiesce_io = 1;
6566                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6567                     "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
6568                 break;
6569         case MPT_IOC_PRE_RESET:
6570                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6571                     "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
6572                 break;
6573         case MPT_IOC_POST_RESET:
6574                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6575                     "%s: MPT_IOC_POST_RESET\n",  ioc->name, __func__));
6576 /* wake up mptbase_cmds */
6577                 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
6578                         ioc->mptbase_cmds.status |=
6579                             MPT_MGMT_STATUS_DID_IOCRESET;
6580                         complete(&ioc->mptbase_cmds.done);
6581                 }
6582 /* wake up taskmgmt_cmds */
6583                 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
6584                         ioc->taskmgmt_cmds.status |=
6585                                 MPT_MGMT_STATUS_DID_IOCRESET;
6586                         complete(&ioc->taskmgmt_cmds.done);
6587                 }
6588                 break;
6589         default:
6590                 break;
6591         }
6592
6593         return 1;               /* currently means nothing really */
6594 }
6595
6596
6597 #ifdef CONFIG_PROC_FS           /* { */
6598 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6599 /*
6600  *      procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6601  */
6602 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6603 /**
6604  *      procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6605  *
6606  *      Returns 0 for success, non-zero for failure.
6607  */
6608 static int
6609 procmpt_create(void)
6610 {
6611         mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
6612         if (mpt_proc_root_dir == NULL)
6613                 return -ENOTDIR;
6614
6615         proc_create("summary", S_IRUGO, mpt_proc_root_dir, &mpt_summary_proc_fops);
6616         proc_create("version", S_IRUGO, mpt_proc_root_dir, &mpt_version_proc_fops);
6617         return 0;
6618 }
6619
6620 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6621 /**
6622  *      procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6623  *
6624  *      Returns 0 for success, non-zero for failure.
6625  */
6626 static void
6627 procmpt_destroy(void)
6628 {
6629         remove_proc_entry("version", mpt_proc_root_dir);
6630         remove_proc_entry("summary", mpt_proc_root_dir);
6631         remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
6632 }
6633
6634 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6635 /*
6636  *      Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6637  */
6638 static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan);
6639
6640 static int mpt_summary_proc_show(struct seq_file *m, void *v)
6641 {
6642         MPT_ADAPTER *ioc = m->private;
6643
6644         if (ioc) {
6645                 seq_mpt_print_ioc_summary(ioc, m, 1);
6646         } else {
6647                 list_for_each_entry(ioc, &ioc_list, list) {
6648                         seq_mpt_print_ioc_summary(ioc, m, 1);
6649                 }
6650         }
6651
6652         return 0;
6653 }
6654
6655 static int mpt_summary_proc_open(struct inode *inode, struct file *file)
6656 {
6657         return single_open(file, mpt_summary_proc_show, PDE(inode)->data);
6658 }
6659
6660 static const struct file_operations mpt_summary_proc_fops = {
6661         .owner          = THIS_MODULE,
6662         .open           = mpt_summary_proc_open,
6663         .read           = seq_read,
6664         .llseek         = seq_lseek,
6665         .release        = single_release,
6666 };
6667
6668 static int mpt_version_proc_show(struct seq_file *m, void *v)
6669 {
6670         u8       cb_idx;
6671         int      scsi, fc, sas, lan, ctl, targ, dmp;
6672         char    *drvname;
6673
6674         seq_printf(m, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
6675         seq_printf(m, "  Fusion MPT base driver\n");
6676
6677         scsi = fc = sas = lan = ctl = targ = dmp = 0;
6678         for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6679                 drvname = NULL;
6680                 if (MptCallbacks[cb_idx]) {
6681                         switch (MptDriverClass[cb_idx]) {
6682                         case MPTSPI_DRIVER:
6683                                 if (!scsi++) drvname = "SPI host";
6684                                 break;
6685                         case MPTFC_DRIVER:
6686                                 if (!fc++) drvname = "FC host";
6687                                 break;
6688                         case MPTSAS_DRIVER:
6689                                 if (!sas++) drvname = "SAS host";
6690                                 break;
6691                         case MPTLAN_DRIVER:
6692                                 if (!lan++) drvname = "LAN";
6693                                 break;
6694                         case MPTSTM_DRIVER:
6695                                 if (!targ++) drvname = "SCSI target";
6696                                 break;
6697                         case MPTCTL_DRIVER:
6698                                 if (!ctl++) drvname = "ioctl";
6699                                 break;
6700                         }
6701
6702                         if (drvname)
6703                                 seq_printf(m, "  Fusion MPT %s driver\n", drvname);
6704                 }
6705         }
6706
6707         return 0;
6708 }
6709
6710 static int mpt_version_proc_open(struct inode *inode, struct file *file)
6711 {
6712         return single_open(file, mpt_version_proc_show, NULL);
6713 }
6714
6715 static const struct file_operations mpt_version_proc_fops = {
6716         .owner          = THIS_MODULE,
6717         .open           = mpt_version_proc_open,
6718         .read           = seq_read,
6719         .llseek         = seq_lseek,
6720         .release        = single_release,
6721 };
6722
6723 static int mpt_iocinfo_proc_show(struct seq_file *m, void *v)
6724 {
6725         MPT_ADAPTER     *ioc = m->private;
6726         char             expVer[32];
6727         int              sz;
6728         int              p;
6729
6730         mpt_get_fw_exp_ver(expVer, ioc);
6731
6732         seq_printf(m, "%s:", ioc->name);
6733         if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6734                 seq_printf(m, "  (f/w download boot flag set)");
6735 //      if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6736 //              seq_printf(m, "  CONFIG_CHECKSUM_FAIL!");
6737
6738         seq_printf(m, "\n  ProductID = 0x%04x (%s)\n",
6739                         ioc->facts.ProductID,
6740                         ioc->prod_name);
6741         seq_printf(m, "  FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6742         if (ioc->facts.FWImageSize)
6743                 seq_printf(m, " (fw_size=%d)", ioc->facts.FWImageSize);
6744         seq_printf(m, "\n  MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6745         seq_printf(m, "  FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6746         seq_printf(m, "  EventState = 0x%02x\n", ioc->facts.EventState);
6747
6748         seq_printf(m, "  CurrentHostMfaHighAddr = 0x%08x\n",
6749                         ioc->facts.CurrentHostMfaHighAddr);
6750         seq_printf(m, "  CurrentSenseBufferHighAddr = 0x%08x\n",
6751                         ioc->facts.CurrentSenseBufferHighAddr);
6752
6753         seq_printf(m, "  MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6754         seq_printf(m, "  MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6755
6756         seq_printf(m, "  RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6757                                         (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6758         /*
6759          *  Rounding UP to nearest 4-kB boundary here...
6760          */
6761         sz = (ioc->req_sz * ioc->req_depth) + 128;
6762         sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6763         seq_printf(m, "    {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6764                                         ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6765         seq_printf(m, "    {MaxReqSz=%d}   {MaxReqDepth=%d}\n",
6766                                         4*ioc->facts.RequestFrameSize,
6767                                         ioc->facts.GlobalCredits);
6768
6769         seq_printf(m, "  Frames   @ 0x%p (Dma @ 0x%p)\n",
6770                                         (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6771         sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6772         seq_printf(m, "    {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6773                                         ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6774         seq_printf(m, "    {MaxRepSz=%d}   {MaxRepDepth=%d}\n",
6775                                         ioc->facts.CurReplyFrameSize,
6776                                         ioc->facts.ReplyQueueDepth);
6777
6778         seq_printf(m, "  MaxDevices = %d\n",
6779                         (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6780         seq_printf(m, "  MaxBuses = %d\n", ioc->facts.MaxBuses);
6781
6782         /* per-port info */
6783         for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6784                 seq_printf(m, "  PortNumber = %d (of %d)\n",
6785                                 p+1,
6786                                 ioc->facts.NumberOfPorts);
6787                 if (ioc->bus_type == FC) {
6788                         if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6789                                 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6790                                 seq_printf(m, "    LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6791                                                 a[5], a[4], a[3], a[2], a[1], a[0]);
6792                         }
6793                         seq_printf(m, "    WWN = %08X%08X:%08X%08X\n",
6794                                         ioc->fc_port_page0[p].WWNN.High,
6795                                         ioc->fc_port_page0[p].WWNN.Low,
6796                                         ioc->fc_port_page0[p].WWPN.High,
6797                                         ioc->fc_port_page0[p].WWPN.Low);
6798                 }
6799         }
6800
6801         return 0;
6802 }
6803
6804 static int mpt_iocinfo_proc_open(struct inode *inode, struct file *file)
6805 {
6806         return single_open(file, mpt_iocinfo_proc_show, PDE(inode)->data);
6807 }
6808
6809 static const struct file_operations mpt_iocinfo_proc_fops = {
6810         .owner          = THIS_MODULE,
6811         .open           = mpt_iocinfo_proc_open,
6812         .read           = seq_read,
6813         .llseek         = seq_lseek,
6814         .release        = single_release,
6815 };
6816 #endif          /* CONFIG_PROC_FS } */
6817
6818 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6819 static void
6820 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6821 {
6822         buf[0] ='\0';
6823         if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6824                 sprintf(buf, " (Exp %02d%02d)",
6825                         (ioc->facts.FWVersion.Word >> 16) & 0x00FF,     /* Month */
6826                         (ioc->facts.FWVersion.Word >> 8) & 0x1F);       /* Day */
6827
6828                 /* insider hack! */
6829                 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6830                         strcat(buf, " [MDBG]");
6831         }
6832 }
6833
6834 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6835 /**
6836  *      mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6837  *      @ioc: Pointer to MPT_ADAPTER structure
6838  *      @buffer: Pointer to buffer where IOC summary info should be written
6839  *      @size: Pointer to number of bytes we wrote (set by this routine)
6840  *      @len: Offset at which to start writing in buffer
6841  *      @showlan: Display LAN stuff?
6842  *
6843  *      This routine writes (english readable) ASCII text, which represents
6844  *      a summary of IOC information, to a buffer.
6845  */
6846 void
6847 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6848 {
6849         char expVer[32];
6850         int y;
6851
6852         mpt_get_fw_exp_ver(expVer, ioc);
6853
6854         /*
6855          *  Shorter summary of attached ioc's...
6856          */
6857         y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6858                         ioc->name,
6859                         ioc->prod_name,
6860                         MPT_FW_REV_MAGIC_ID_STRING,     /* "FwRev=" or somesuch */
6861                         ioc->facts.FWVersion.Word,
6862                         expVer,
6863                         ioc->facts.NumberOfPorts,
6864                         ioc->req_depth);
6865
6866         if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6867                 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6868                 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6869                         a[5], a[4], a[3], a[2], a[1], a[0]);
6870         }
6871
6872         y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6873
6874         if (!ioc->active)
6875                 y += sprintf(buffer+len+y, " (disabled)");
6876
6877         y += sprintf(buffer+len+y, "\n");
6878
6879         *size = y;
6880 }
6881
6882 static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan)
6883 {
6884         char expVer[32];
6885
6886         mpt_get_fw_exp_ver(expVer, ioc);
6887
6888         /*
6889          *  Shorter summary of attached ioc's...
6890          */
6891         seq_printf(m, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6892                         ioc->name,
6893                         ioc->prod_name,
6894                         MPT_FW_REV_MAGIC_ID_STRING,     /* "FwRev=" or somesuch */
6895                         ioc->facts.FWVersion.Word,
6896                         expVer,
6897                         ioc->facts.NumberOfPorts,
6898                         ioc->req_depth);
6899
6900         if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6901                 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6902                 seq_printf(m, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6903                         a[5], a[4], a[3], a[2], a[1], a[0]);
6904         }
6905
6906         seq_printf(m, ", IRQ=%d", ioc->pci_irq);
6907
6908         if (!ioc->active)
6909                 seq_printf(m, " (disabled)");
6910
6911         seq_putc(m, '\n');
6912 }
6913
6914 /**
6915  *      mpt_set_taskmgmt_in_progress_flag - set flags associated with task management
6916  *      @ioc: Pointer to MPT_ADAPTER structure
6917  *
6918  *      Returns 0 for SUCCESS or -1 if FAILED.
6919  *
6920  *      If -1 is return, then it was not possible to set the flags
6921  **/
6922 int
6923 mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6924 {
6925         unsigned long    flags;
6926         int              retval;
6927
6928         spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6929         if (ioc->ioc_reset_in_progress || ioc->taskmgmt_in_progress ||
6930             (ioc->alt_ioc && ioc->alt_ioc->taskmgmt_in_progress)) {
6931                 retval = -1;
6932                 goto out;
6933         }
6934         retval = 0;
6935         ioc->taskmgmt_in_progress = 1;
6936         ioc->taskmgmt_quiesce_io = 1;
6937         if (ioc->alt_ioc) {
6938                 ioc->alt_ioc->taskmgmt_in_progress = 1;
6939                 ioc->alt_ioc->taskmgmt_quiesce_io = 1;
6940         }
6941  out:
6942         spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6943         return retval;
6944 }
6945 EXPORT_SYMBOL(mpt_set_taskmgmt_in_progress_flag);
6946
6947 /**
6948  *      mpt_clear_taskmgmt_in_progress_flag - clear flags associated with task management
6949  *      @ioc: Pointer to MPT_ADAPTER structure
6950  *
6951  **/
6952 void
6953 mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6954 {
6955         unsigned long    flags;
6956
6957         spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6958         ioc->taskmgmt_in_progress = 0;
6959         ioc->taskmgmt_quiesce_io = 0;
6960         if (ioc->alt_ioc) {
6961                 ioc->alt_ioc->taskmgmt_in_progress = 0;
6962                 ioc->alt_ioc->taskmgmt_quiesce_io = 0;
6963         }
6964         spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6965 }
6966 EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag);
6967
6968
6969 /**
6970  *      mpt_halt_firmware - Halts the firmware if it is operational and panic
6971  *      the kernel
6972  *      @ioc: Pointer to MPT_ADAPTER structure
6973  *
6974  **/
6975 void
6976 mpt_halt_firmware(MPT_ADAPTER *ioc)
6977 {
6978         u32      ioc_raw_state;
6979
6980         ioc_raw_state = mpt_GetIocState(ioc, 0);
6981
6982         if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
6983                 printk(MYIOC_s_ERR_FMT "IOC is in FAULT state (%04xh)!!!\n",
6984                         ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6985                 panic("%s: IOC Fault (%04xh)!!!\n", ioc->name,
6986                         ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6987         } else {
6988                 CHIPREG_WRITE32(&ioc->chip->Doorbell, 0xC0FFEE00);
6989                 panic("%s: Firmware is halted due to command timeout\n",
6990                         ioc->name);
6991         }
6992 }
6993 EXPORT_SYMBOL(mpt_halt_firmware);
6994
6995 /**
6996  *      mpt_SoftResetHandler - Issues a less expensive reset
6997  *      @ioc: Pointer to MPT_ADAPTER structure
6998  *      @sleepFlag: Indicates if sleep or schedule must be called.
6999  *
7000  *      Returns 0 for SUCCESS or -1 if FAILED.
7001  *
7002  *      Message Unit Reset - instructs the IOC to reset the Reply Post and
7003  *      Free FIFO's. All the Message Frames on Reply Free FIFO are discarded.
7004  *      All posted buffers are freed, and event notification is turned off.
7005  *      IOC doesn't reply to any outstanding request. This will transfer IOC
7006  *      to READY state.
7007  **/
7008 int
7009 mpt_SoftResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
7010 {
7011         int              rc;
7012         int              ii;
7013         u8               cb_idx;
7014         unsigned long    flags;
7015         u32              ioc_state;
7016         unsigned long    time_count;
7017
7018         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SoftResetHandler Entered!\n",
7019                 ioc->name));
7020
7021         ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
7022
7023         if (mpt_fwfault_debug)
7024                 mpt_halt_firmware(ioc);
7025
7026         if (ioc_state == MPI_IOC_STATE_FAULT ||
7027             ioc_state == MPI_IOC_STATE_RESET) {
7028                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7029                     "skipping, either in FAULT or RESET state!\n", ioc->name));
7030                 return -1;
7031         }
7032
7033         if (ioc->bus_type == FC) {
7034                 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7035                     "skipping, because the bus type is FC!\n", ioc->name));
7036                 return -1;
7037         }
7038
7039         spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7040         if (ioc->ioc_reset_in_progress) {
7041                 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7042                 return -1;
7043         }
7044         ioc->ioc_reset_in_progress = 1;
7045         spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7046
7047         rc = -1;
7048
7049         for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7050                 if (MptResetHandlers[cb_idx])
7051                         mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
7052         }
7053
7054         spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7055         if (ioc->taskmgmt_in_progress) {
7056                 ioc->ioc_reset_in_progress = 0;
7057                 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7058                 return -1;
7059         }
7060         spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7061         /* Disable reply interrupts (also blocks FreeQ) */
7062         CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
7063         ioc->active = 0;
7064         time_count = jiffies;
7065
7066         rc = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
7067
7068         for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7069                 if (MptResetHandlers[cb_idx])
7070                         mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
7071         }
7072
7073         if (rc)
7074                 goto out;
7075
7076         ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
7077         if (ioc_state != MPI_IOC_STATE_READY)
7078                 goto out;
7079
7080         for (ii = 0; ii < 5; ii++) {
7081                 /* Get IOC facts! Allow 5 retries */
7082                 rc = GetIocFacts(ioc, sleepFlag,
7083                         MPT_HOSTEVENT_IOC_RECOVER);
7084                 if (rc == 0)
7085                         break;
7086                 if (sleepFlag == CAN_SLEEP)
7087                         msleep(100);
7088                 else
7089                         mdelay(100);
7090         }
7091         if (ii == 5)
7092                 goto out;
7093
7094         rc = PrimeIocFifos(ioc);
7095         if (rc != 0)
7096                 goto out;
7097
7098         rc = SendIocInit(ioc, sleepFlag);
7099         if (rc != 0)
7100                 goto out;
7101
7102         rc = SendEventNotification(ioc, 1, sleepFlag);
7103         if (rc != 0)
7104                 goto out;
7105
7106         if (ioc->hard_resets < -1)
7107                 ioc->hard_resets++;
7108
7109         /*
7110          * At this point, we know soft reset succeeded.
7111          */
7112
7113         ioc->active = 1;
7114         CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
7115
7116  out:
7117         spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7118         ioc->ioc_reset_in_progress = 0;
7119         ioc->taskmgmt_quiesce_io = 0;
7120         ioc->taskmgmt_in_progress = 0;
7121         spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7122
7123         if (ioc->active) {      /* otherwise, hard reset coming */
7124                 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7125                         if (MptResetHandlers[cb_idx])
7126                                 mpt_signal_reset(cb_idx, ioc,
7127                                         MPT_IOC_POST_RESET);
7128                 }
7129         }
7130
7131         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7132                 "SoftResetHandler: completed (%d seconds): %s\n",
7133                 ioc->name, jiffies_to_msecs(jiffies - time_count)/1000,
7134                 ((rc == 0) ? "SUCCESS" : "FAILED")));
7135
7136         return rc;
7137 }
7138
7139 /**
7140  *      mpt_Soft_Hard_ResetHandler - Try less expensive reset
7141  *      @ioc: Pointer to MPT_ADAPTER structure
7142  *      @sleepFlag: Indicates if sleep or schedule must be called.
7143  *
7144  *      Returns 0 for SUCCESS or -1 if FAILED.
7145  *      Try for softreset first, only if it fails go for expensive
7146  *      HardReset.
7147  **/
7148 int
7149 mpt_Soft_Hard_ResetHandler(MPT_ADAPTER *ioc, int sleepFlag) {
7150         int ret = -1;
7151
7152         ret = mpt_SoftResetHandler(ioc, sleepFlag);
7153         if (ret == 0)
7154                 return ret;
7155         ret = mpt_HardResetHandler(ioc, sleepFlag);
7156         return ret;
7157 }
7158 EXPORT_SYMBOL(mpt_Soft_Hard_ResetHandler);
7159
7160 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7161 /*
7162  *      Reset Handling
7163  */
7164 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7165 /**
7166  *      mpt_HardResetHandler - Generic reset handler
7167  *      @ioc: Pointer to MPT_ADAPTER structure
7168  *      @sleepFlag: Indicates if sleep or schedule must be called.
7169  *
7170  *      Issues SCSI Task Management call based on input arg values.
7171  *      If TaskMgmt fails, returns associated SCSI request.
7172  *
7173  *      Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
7174  *      or a non-interrupt thread.  In the former, must not call schedule().
7175  *
7176  *      Note: A return of -1 is a FATAL error case, as it means a
7177  *      FW reload/initialization failed.
7178  *
7179  *      Returns 0 for SUCCESS or -1 if FAILED.
7180  */
7181 int
7182 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
7183 {
7184         int      rc;
7185         u8       cb_idx;
7186         unsigned long    flags;
7187         unsigned long    time_count;
7188
7189         dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
7190 #ifdef MFCNT
7191         printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
7192         printk("MF count 0x%x !\n", ioc->mfcnt);
7193 #endif
7194         if (mpt_fwfault_debug)
7195                 mpt_halt_firmware(ioc);
7196
7197         /* Reset the adapter. Prevent more than 1 call to
7198          * mpt_do_ioc_recovery at any instant in time.
7199          */
7200         spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7201         if (ioc->ioc_reset_in_progress) {
7202                 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7203                 ioc->wait_on_reset_completion = 1;
7204                 do {
7205                         ssleep(1);
7206                 } while (ioc->ioc_reset_in_progress == 1);
7207                 ioc->wait_on_reset_completion = 0;
7208                 return ioc->reset_status;
7209         }
7210         if (ioc->wait_on_reset_completion) {
7211                 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7212                 rc = 0;
7213                 time_count = jiffies;
7214                 goto exit;
7215         }
7216         ioc->ioc_reset_in_progress = 1;
7217         if (ioc->alt_ioc)
7218                 ioc->alt_ioc->ioc_reset_in_progress = 1;
7219         spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7220
7221
7222         /* The SCSI driver needs to adjust timeouts on all current
7223          * commands prior to the diagnostic reset being issued.
7224          * Prevents timeouts occurring during a diagnostic reset...very bad.
7225          * For all other protocol drivers, this is a no-op.
7226          */
7227         for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7228                 if (MptResetHandlers[cb_idx]) {
7229                         mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
7230                         if (ioc->alt_ioc)
7231                                 mpt_signal_reset(cb_idx, ioc->alt_ioc,
7232                                         MPT_IOC_SETUP_RESET);
7233                 }
7234         }
7235
7236         time_count = jiffies;
7237         rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag);
7238         if (rc != 0) {
7239                 printk(KERN_WARNING MYNAM
7240                        ": WARNING - (%d) Cannot recover %s, doorbell=0x%08x\n",
7241                        rc, ioc->name, mpt_GetIocState(ioc, 0));
7242         } else {
7243                 if (ioc->hard_resets < -1)
7244                         ioc->hard_resets++;
7245         }
7246
7247         spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7248         ioc->ioc_reset_in_progress = 0;
7249         ioc->taskmgmt_quiesce_io = 0;
7250         ioc->taskmgmt_in_progress = 0;
7251         ioc->reset_status = rc;
7252         if (ioc->alt_ioc) {
7253                 ioc->alt_ioc->ioc_reset_in_progress = 0;
7254                 ioc->alt_ioc->taskmgmt_quiesce_io = 0;
7255                 ioc->alt_ioc->taskmgmt_in_progress = 0;
7256         }
7257         spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7258
7259         for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7260                 if (MptResetHandlers[cb_idx]) {
7261                         mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
7262                         if (ioc->alt_ioc)
7263                                 mpt_signal_reset(cb_idx,
7264                                         ioc->alt_ioc, MPT_IOC_POST_RESET);
7265                 }
7266         }
7267 exit:
7268         dtmprintk(ioc,
7269             printk(MYIOC_s_DEBUG_FMT
7270                 "HardResetHandler: completed (%d seconds): %s\n", ioc->name,
7271                 jiffies_to_msecs(jiffies - time_count)/1000, ((rc == 0) ?
7272                 "SUCCESS" : "FAILED")));
7273
7274         return rc;
7275 }
7276
7277 #ifdef CONFIG_FUSION_LOGGING
7278 static void
7279 mpt_display_event_info(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply)
7280 {
7281         char *ds = NULL;
7282         u32 evData0;
7283         int ii;
7284         u8 event;
7285         char *evStr = ioc->evStr;
7286
7287         event = le32_to_cpu(pEventReply->Event) & 0xFF;
7288         evData0 = le32_to_cpu(pEventReply->Data[0]);
7289
7290         switch(event) {
7291         case MPI_EVENT_NONE:
7292                 ds = "None";
7293                 break;
7294         case MPI_EVENT_LOG_DATA:
7295                 ds = "Log Data";
7296                 break;
7297         case MPI_EVENT_STATE_CHANGE:
7298                 ds = "State Change";
7299                 break;
7300         case MPI_EVENT_UNIT_ATTENTION:
7301                 ds = "Unit Attention";
7302                 break;
7303         case MPI_EVENT_IOC_BUS_RESET:
7304                 ds = "IOC Bus Reset";
7305                 break;
7306         case MPI_EVENT_EXT_BUS_RESET:
7307                 ds = "External Bus Reset";
7308                 break;
7309         case MPI_EVENT_RESCAN:
7310                 ds = "Bus Rescan Event";
7311                 break;
7312         case MPI_EVENT_LINK_STATUS_CHANGE:
7313                 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
7314                         ds = "Link Status(FAILURE) Change";
7315                 else
7316                         ds = "Link Status(ACTIVE) Change";
7317                 break;
7318         case MPI_EVENT_LOOP_STATE_CHANGE:
7319                 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
7320                         ds = "Loop State(LIP) Change";
7321                 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
7322                         ds = "Loop State(LPE) Change";
7323                 else
7324                         ds = "Loop State(LPB) Change";
7325                 break;
7326         case MPI_EVENT_LOGOUT:
7327                 ds = "Logout";
7328                 break;
7329         case MPI_EVENT_EVENT_CHANGE:
7330                 if (evData0)
7331                         ds = "Events ON";
7332                 else
7333                         ds = "Events OFF";
7334                 break;
7335         case MPI_EVENT_INTEGRATED_RAID:
7336         {
7337                 u8 ReasonCode = (u8)(evData0 >> 16);
7338                 switch (ReasonCode) {
7339                 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
7340                         ds = "Integrated Raid: Volume Created";
7341                         break;
7342                 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
7343                         ds = "Integrated Raid: Volume Deleted";
7344                         break;
7345                 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
7346                         ds = "Integrated Raid: Volume Settings Changed";
7347                         break;
7348                 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
7349                         ds = "Integrated Raid: Volume Status Changed";
7350                         break;
7351                 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
7352                         ds = "Integrated Raid: Volume Physdisk Changed";
7353                         break;
7354                 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
7355                         ds = "Integrated Raid: Physdisk Created";
7356                         break;
7357                 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
7358                         ds = "Integrated Raid: Physdisk Deleted";
7359                         break;
7360                 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
7361                         ds = "Integrated Raid: Physdisk Settings Changed";
7362                         break;
7363                 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
7364                         ds = "Integrated Raid: Physdisk Status Changed";
7365                         break;
7366                 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
7367                         ds = "Integrated Raid: Domain Validation Needed";
7368                         break;
7369                 case MPI_EVENT_RAID_RC_SMART_DATA :
7370                         ds = "Integrated Raid; Smart Data";
7371                         break;
7372                 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
7373                         ds = "Integrated Raid: Replace Action Started";
7374                         break;
7375                 default:
7376                         ds = "Integrated Raid";
7377                 break;
7378                 }
7379                 break;
7380         }
7381         case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
7382                 ds = "SCSI Device Status Change";
7383                 break;
7384         case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
7385         {
7386                 u8 id = (u8)(evData0);
7387                 u8 channel = (u8)(evData0 >> 8);
7388                 u8 ReasonCode = (u8)(evData0 >> 16);
7389                 switch (ReasonCode) {
7390                 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
7391                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7392                             "SAS Device Status Change: Added: "
7393                             "id=%d channel=%d", id, channel);
7394                         break;
7395                 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
7396                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7397                             "SAS Device Status Change: Deleted: "
7398                             "id=%d channel=%d", id, channel);
7399                         break;
7400                 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
7401                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7402                             "SAS Device Status Change: SMART Data: "
7403                             "id=%d channel=%d", id, channel);
7404                         break;
7405                 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
7406                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7407                             "SAS Device Status Change: No Persistancy: "
7408                             "id=%d channel=%d", id, channel);
7409                         break;
7410                 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
7411                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7412                             "SAS Device Status Change: Unsupported Device "
7413                             "Discovered : id=%d channel=%d", id, channel);
7414                         break;
7415                 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
7416                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7417                             "SAS Device Status Change: Internal Device "
7418                             "Reset : id=%d channel=%d", id, channel);
7419                         break;
7420                 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
7421                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7422                             "SAS Device Status Change: Internal Task "
7423                             "Abort : id=%d channel=%d", id, channel);
7424                         break;
7425                 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
7426                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7427                             "SAS Device Status Change: Internal Abort "
7428                             "Task Set : id=%d channel=%d", id, channel);
7429                         break;
7430                 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
7431                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7432                             "SAS Device Status Change: Internal Clear "
7433                             "Task Set : id=%d channel=%d", id, channel);
7434                         break;
7435                 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
7436                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7437                             "SAS Device Status Change: Internal Query "
7438                             "Task : id=%d channel=%d", id, channel);
7439                         break;
7440                 default:
7441                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7442                             "SAS Device Status Change: Unknown: "
7443                             "id=%d channel=%d", id, channel);
7444                         break;
7445                 }
7446                 break;
7447         }
7448         case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
7449                 ds = "Bus Timer Expired";
7450                 break;
7451         case MPI_EVENT_QUEUE_FULL:
7452         {
7453                 u16 curr_depth = (u16)(evData0 >> 16);
7454                 u8 channel = (u8)(evData0 >> 8);
7455                 u8 id = (u8)(evData0);
7456
7457                 snprintf(evStr, EVENT_DESCR_STR_SZ,
7458                    "Queue Full: channel=%d id=%d depth=%d",
7459                    channel, id, curr_depth);
7460                 break;
7461         }
7462         case MPI_EVENT_SAS_SES:
7463                 ds = "SAS SES Event";
7464                 break;
7465         case MPI_EVENT_PERSISTENT_TABLE_FULL:
7466                 ds = "Persistent Table Full";
7467                 break;
7468         case MPI_EVENT_SAS_PHY_LINK_STATUS:
7469         {
7470                 u8 LinkRates = (u8)(evData0 >> 8);
7471                 u8 PhyNumber = (u8)(evData0);
7472                 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
7473                         MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
7474                 switch (LinkRates) {
7475                 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
7476                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7477                            "SAS PHY Link Status: Phy=%d:"
7478                            " Rate Unknown",PhyNumber);
7479                         break;
7480                 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
7481                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7482                            "SAS PHY Link Status: Phy=%d:"
7483                            " Phy Disabled",PhyNumber);
7484                         break;
7485                 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
7486                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7487                            "SAS PHY Link Status: Phy=%d:"
7488                            " Failed Speed Nego",PhyNumber);
7489                         break;
7490                 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
7491                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7492                            "SAS PHY Link Status: Phy=%d:"
7493                            " Sata OOB Completed",PhyNumber);
7494                         break;
7495                 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
7496                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7497                            "SAS PHY Link Status: Phy=%d:"
7498                            " Rate 1.5 Gbps",PhyNumber);
7499                         break;
7500                 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
7501                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7502                            "SAS PHY Link Status: Phy=%d:"
7503                            " Rate 3.0 Gbps", PhyNumber);
7504                         break;
7505                 case MPI_EVENT_SAS_PLS_LR_RATE_6_0:
7506                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7507                            "SAS PHY Link Status: Phy=%d:"
7508                            " Rate 6.0 Gbps", PhyNumber);
7509                         break;
7510                 default:
7511                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7512                            "SAS PHY Link Status: Phy=%d", PhyNumber);
7513                         break;
7514                 }
7515                 break;
7516         }
7517         case MPI_EVENT_SAS_DISCOVERY_ERROR:
7518                 ds = "SAS Discovery Error";
7519                 break;
7520         case MPI_EVENT_IR_RESYNC_UPDATE:
7521         {
7522                 u8 resync_complete = (u8)(evData0 >> 16);
7523                 snprintf(evStr, EVENT_DESCR_STR_SZ,
7524                     "IR Resync Update: Complete = %d:",resync_complete);
7525                 break;
7526         }
7527         case MPI_EVENT_IR2:
7528         {
7529                 u8 id = (u8)(evData0);
7530                 u8 channel = (u8)(evData0 >> 8);
7531                 u8 phys_num = (u8)(evData0 >> 24);
7532                 u8 ReasonCode = (u8)(evData0 >> 16);
7533
7534                 switch (ReasonCode) {
7535                 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
7536                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7537                             "IR2: LD State Changed: "
7538                             "id=%d channel=%d phys_num=%d",
7539                             id, channel, phys_num);
7540                         break;
7541                 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
7542                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7543                             "IR2: PD State Changed "
7544                             "id=%d channel=%d phys_num=%d",
7545                             id, channel, phys_num);
7546                         break;
7547                 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
7548                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7549                             "IR2: Bad Block Table Full: "
7550                             "id=%d channel=%d phys_num=%d",
7551                             id, channel, phys_num);
7552                         break;
7553                 case MPI_EVENT_IR2_RC_PD_INSERTED:
7554                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7555                             "IR2: PD Inserted: "
7556                             "id=%d channel=%d phys_num=%d",
7557                             id, channel, phys_num);
7558                         break;
7559                 case MPI_EVENT_IR2_RC_PD_REMOVED:
7560                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7561                             "IR2: PD Removed: "
7562                             "id=%d channel=%d phys_num=%d",
7563                             id, channel, phys_num);
7564                         break;
7565                 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
7566                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7567                             "IR2: Foreign CFG Detected: "
7568                             "id=%d channel=%d phys_num=%d",
7569                             id, channel, phys_num);
7570                         break;
7571                 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
7572                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7573                             "IR2: Rebuild Medium Error: "
7574                             "id=%d channel=%d phys_num=%d",
7575                             id, channel, phys_num);
7576                         break;
7577                 case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
7578                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7579                             "IR2: Dual Port Added: "
7580                             "id=%d channel=%d phys_num=%d",
7581                             id, channel, phys_num);
7582                         break;
7583                 case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
7584                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7585                             "IR2: Dual Port Removed: "
7586                             "id=%d channel=%d phys_num=%d",
7587                             id, channel, phys_num);
7588                         break;
7589                 default:
7590                         ds = "IR2";
7591                 break;
7592                 }
7593                 break;
7594         }
7595         case MPI_EVENT_SAS_DISCOVERY:
7596         {
7597                 if (evData0)
7598                         ds = "SAS Discovery: Start";
7599                 else
7600                         ds = "SAS Discovery: Stop";
7601                 break;
7602         }
7603         case MPI_EVENT_LOG_ENTRY_ADDED:
7604                 ds = "SAS Log Entry Added";
7605                 break;
7606
7607         case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
7608         {
7609                 u8 phy_num = (u8)(evData0);
7610                 u8 port_num = (u8)(evData0 >> 8);
7611                 u8 port_width = (u8)(evData0 >> 16);
7612                 u8 primative = (u8)(evData0 >> 24);
7613                 snprintf(evStr, EVENT_DESCR_STR_SZ,
7614                     "SAS Broadcase Primative: phy=%d port=%d "
7615                     "width=%d primative=0x%02x",
7616                     phy_num, port_num, port_width, primative);
7617                 break;
7618         }
7619
7620         case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
7621         {
7622                 u8 reason = (u8)(evData0);
7623
7624                 switch (reason) {
7625                 case MPI_EVENT_SAS_INIT_RC_ADDED:
7626                         ds = "SAS Initiator Status Change: Added";
7627                         break;
7628                 case MPI_EVENT_SAS_INIT_RC_REMOVED:
7629                         ds = "SAS Initiator Status Change: Deleted";
7630                         break;
7631                 default:
7632                         ds = "SAS Initiator Status Change";
7633                         break;
7634                 }
7635                 break;
7636         }
7637
7638         case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
7639         {
7640                 u8 max_init = (u8)(evData0);
7641                 u8 current_init = (u8)(evData0 >> 8);
7642
7643                 snprintf(evStr, EVENT_DESCR_STR_SZ,
7644                     "SAS Initiator Device Table Overflow: max initiators=%02d "
7645                     "current initators=%02d",
7646                     max_init, current_init);
7647                 break;
7648         }
7649         case MPI_EVENT_SAS_SMP_ERROR:
7650         {
7651                 u8 status = (u8)(evData0);
7652                 u8 port_num = (u8)(evData0 >> 8);
7653                 u8 result = (u8)(evData0 >> 16);
7654
7655                 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
7656                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7657                             "SAS SMP Error: port=%d result=0x%02x",
7658                             port_num, result);
7659                 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
7660                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7661                             "SAS SMP Error: port=%d : CRC Error",
7662                             port_num);
7663                 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
7664                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7665                             "SAS SMP Error: port=%d : Timeout",
7666                             port_num);
7667                 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
7668                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7669                             "SAS SMP Error: port=%d : No Destination",
7670                             port_num);
7671                 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
7672                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7673                             "SAS SMP Error: port=%d : Bad Destination",
7674                             port_num);
7675                 else
7676                         snprintf(evStr, EVENT_DESCR_STR_SZ,
7677                             "SAS SMP Error: port=%d : status=0x%02x",
7678                             port_num, status);
7679                 break;
7680         }
7681
7682         case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
7683         {
7684                 u8 reason = (u8)(evData0);
7685
7686                 switch (reason) {
7687                 case MPI_EVENT_SAS_EXP_RC_ADDED:
7688                         ds = "Expander Status Change: Added";
7689                         break;
7690                 case MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING:
7691                         ds = "Expander Status Change: Deleted";
7692                         break;
7693                 default:
7694                         ds = "Expander Status Change";
7695                         break;
7696                 }
7697                 break;
7698         }
7699
7700         /*
7701          *  MPT base "custom" events may be added here...
7702          */
7703         default:
7704                 ds = "Unknown";
7705                 break;
7706         }
7707         if (ds)
7708                 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
7709
7710
7711         devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7712             "MPT event:(%02Xh) : %s\n",
7713             ioc->name, event, evStr));
7714
7715         devtverboseprintk(ioc, printk(KERN_DEBUG MYNAM
7716             ": Event data:\n"));
7717         for (ii = 0; ii < le16_to_cpu(pEventReply->EventDataLength); ii++)
7718                 devtverboseprintk(ioc, printk(" %08x",
7719                     le32_to_cpu(pEventReply->Data[ii])));
7720         devtverboseprintk(ioc, printk(KERN_DEBUG "\n"));
7721 }
7722 #endif
7723 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7724 /**
7725  *      ProcessEventNotification - Route EventNotificationReply to all event handlers
7726  *      @ioc: Pointer to MPT_ADAPTER structure
7727  *      @pEventReply: Pointer to EventNotification reply frame
7728  *      @evHandlers: Pointer to integer, number of event handlers
7729  *
7730  *      Routes a received EventNotificationReply to all currently registered
7731  *      event handlers.
7732  *      Returns sum of event handlers return values.
7733  */
7734 static int
7735 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
7736 {
7737         u16 evDataLen;
7738         u32 evData0 = 0;
7739         int ii;
7740         u8 cb_idx;
7741         int r = 0;
7742         int handlers = 0;
7743         u8 event;
7744
7745         /*
7746          *  Do platform normalization of values
7747          */
7748         event = le32_to_cpu(pEventReply->Event) & 0xFF;
7749         evDataLen = le16_to_cpu(pEventReply->EventDataLength);
7750         if (evDataLen) {
7751                 evData0 = le32_to_cpu(pEventReply->Data[0]);
7752         }
7753
7754 #ifdef CONFIG_FUSION_LOGGING
7755         if (evDataLen)
7756                 mpt_display_event_info(ioc, pEventReply);
7757 #endif
7758
7759         /*
7760          *  Do general / base driver event processing
7761          */
7762         switch(event) {
7763         case MPI_EVENT_EVENT_CHANGE:            /* 0A */
7764                 if (evDataLen) {
7765                         u8 evState = evData0 & 0xFF;
7766
7767                         /* CHECKME! What if evState unexpectedly says OFF (0)? */
7768
7769                         /* Update EventState field in cached IocFacts */
7770                         if (ioc->facts.Function) {
7771                                 ioc->facts.EventState = evState;
7772                         }
7773                 }
7774                 break;
7775         case MPI_EVENT_INTEGRATED_RAID:
7776                 mptbase_raid_process_event_data(ioc,
7777                     (MpiEventDataRaid_t *)pEventReply->Data);
7778                 break;
7779         default:
7780                 break;
7781         }
7782
7783         /*
7784          * Should this event be logged? Events are written sequentially.
7785          * When buffer is full, start again at the top.
7786          */
7787         if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
7788                 int idx;
7789
7790                 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
7791
7792                 ioc->events[idx].event = event;
7793                 ioc->events[idx].eventContext = ioc->eventContext;
7794
7795                 for (ii = 0; ii < 2; ii++) {
7796                         if (ii < evDataLen)
7797                                 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
7798                         else
7799                                 ioc->events[idx].data[ii] =  0;
7800                 }
7801
7802                 ioc->eventContext++;
7803         }
7804
7805
7806         /*
7807          *  Call each currently registered protocol event handler.
7808          */
7809         for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7810                 if (MptEvHandlers[cb_idx]) {
7811                         devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7812                             "Routing Event to event handler #%d\n",
7813                             ioc->name, cb_idx));
7814                         r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
7815                         handlers++;
7816                 }
7817         }
7818         /* FIXME?  Examine results here? */
7819
7820         /*
7821          *  If needed, send (a single) EventAck.
7822          */
7823         if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
7824                 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7825                         "EventAck required\n",ioc->name));
7826                 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
7827                         devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
7828                                         ioc->name, ii));
7829                 }
7830         }
7831
7832         *evHandlers = handlers;
7833         return r;
7834 }
7835
7836 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7837 /**
7838  *      mpt_fc_log_info - Log information returned from Fibre Channel IOC.
7839  *      @ioc: Pointer to MPT_ADAPTER structure
7840  *      @log_info: U32 LogInfo reply word from the IOC
7841  *
7842  *      Refer to lsi/mpi_log_fc.h.
7843  */
7844 static void
7845 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
7846 {
7847         char *desc = "unknown";
7848
7849         switch (log_info & 0xFF000000) {
7850         case MPI_IOCLOGINFO_FC_INIT_BASE:
7851                 desc = "FCP Initiator";
7852                 break;
7853         case MPI_IOCLOGINFO_FC_TARGET_BASE:
7854                 desc = "FCP Target";
7855                 break;
7856         case MPI_IOCLOGINFO_FC_LAN_BASE:
7857                 desc = "LAN";
7858                 break;
7859         case MPI_IOCLOGINFO_FC_MSG_BASE:
7860                 desc = "MPI Message Layer";
7861                 break;
7862         case MPI_IOCLOGINFO_FC_LINK_BASE:
7863                 desc = "FC Link";
7864                 break;
7865         case MPI_IOCLOGINFO_FC_CTX_BASE:
7866                 desc = "Context Manager";
7867                 break;
7868         case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
7869                 desc = "Invalid Field Offset";
7870                 break;
7871         case MPI_IOCLOGINFO_FC_STATE_CHANGE:
7872                 desc = "State Change Info";
7873                 break;
7874         }
7875
7876         printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
7877                         ioc->name, log_info, desc, (log_info & 0xFFFFFF));
7878 }
7879
7880 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7881 /**
7882  *      mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
7883  *      @ioc: Pointer to MPT_ADAPTER structure
7884  *      @log_info: U32 LogInfo word from the IOC
7885  *
7886  *      Refer to lsi/sp_log.h.
7887  */
7888 static void
7889 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
7890 {
7891         u32 info = log_info & 0x00FF0000;
7892         char *desc = "unknown";
7893
7894         switch (info) {
7895         case 0x00010000:
7896                 desc = "bug! MID not found";
7897                 break;
7898
7899         case 0x00020000:
7900                 desc = "Parity Error";
7901                 break;
7902
7903         case 0x00030000:
7904                 desc = "ASYNC Outbound Overrun";
7905                 break;
7906
7907         case 0x00040000:
7908                 desc = "SYNC Offset Error";
7909                 break;
7910
7911         case 0x00050000:
7912                 desc = "BM Change";
7913                 break;
7914
7915         case 0x00060000:
7916                 desc = "Msg In Overflow";
7917                 break;
7918
7919         case 0x00070000:
7920                 desc = "DMA Error";
7921                 break;
7922
7923         case 0x00080000:
7924                 desc = "Outbound DMA Overrun";
7925                 break;
7926
7927         case 0x00090000:
7928                 desc = "Task Management";
7929                 break;
7930
7931         case 0x000A0000:
7932                 desc = "Device Problem";
7933                 break;
7934
7935         case 0x000B0000:
7936                 desc = "Invalid Phase Change";
7937                 break;
7938
7939         case 0x000C0000:
7940                 desc = "Untagged Table Size";
7941                 break;
7942
7943         }
7944
7945         printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
7946 }
7947
7948 /* strings for sas loginfo */
7949         static char *originator_str[] = {
7950                 "IOP",                                          /* 00h */
7951                 "PL",                                           /* 01h */
7952                 "IR"                                            /* 02h */
7953         };
7954         static char *iop_code_str[] = {
7955                 NULL,                                           /* 00h */
7956                 "Invalid SAS Address",                          /* 01h */
7957                 NULL,                                           /* 02h */
7958                 "Invalid Page",                                 /* 03h */
7959                 "Diag Message Error",                           /* 04h */
7960                 "Task Terminated",                              /* 05h */
7961                 "Enclosure Management",                         /* 06h */
7962                 "Target Mode"                                   /* 07h */
7963         };
7964         static char *pl_code_str[] = {
7965                 NULL,                                           /* 00h */
7966                 "Open Failure",                                 /* 01h */
7967                 "Invalid Scatter Gather List",                  /* 02h */
7968                 "Wrong Relative Offset or Frame Length",        /* 03h */
7969                 "Frame Transfer Error",                         /* 04h */
7970                 "Transmit Frame Connected Low",                 /* 05h */
7971                 "SATA Non-NCQ RW Error Bit Set",                /* 06h */
7972                 "SATA Read Log Receive Data Error",             /* 07h */
7973                 "SATA NCQ Fail All Commands After Error",       /* 08h */
7974                 "SATA Error in Receive Set Device Bit FIS",     /* 09h */
7975                 "Receive Frame Invalid Message",                /* 0Ah */
7976                 "Receive Context Message Valid Error",          /* 0Bh */
7977                 "Receive Frame Current Frame Error",            /* 0Ch */
7978                 "SATA Link Down",                               /* 0Dh */
7979                 "Discovery SATA Init W IOS",                    /* 0Eh */
7980                 "Config Invalid Page",                          /* 0Fh */
7981                 "Discovery SATA Init Timeout",                  /* 10h */
7982                 "Reset",                                        /* 11h */
7983                 "Abort",                                        /* 12h */
7984                 "IO Not Yet Executed",                          /* 13h */
7985                 "IO Executed",                                  /* 14h */
7986                 "Persistent Reservation Out Not Affiliation "
7987                     "Owner",                                    /* 15h */
7988                 "Open Transmit DMA Abort",                      /* 16h */
7989                 "IO Device Missing Delay Retry",                /* 17h */
7990                 "IO Cancelled Due to Receive Error",            /* 18h */
7991                 NULL,                                           /* 19h */
7992                 NULL,                                           /* 1Ah */
7993                 NULL,                                           /* 1Bh */
7994                 NULL,                                           /* 1Ch */
7995                 NULL,                                           /* 1Dh */
7996                 NULL,                                           /* 1Eh */
7997                 NULL,                                           /* 1Fh */
7998                 "Enclosure Management"                          /* 20h */
7999         };
8000         static char *ir_code_str[] = {
8001                 "Raid Action Error",                            /* 00h */
8002                 NULL,                                           /* 00h */
8003                 NULL,                                           /* 01h */
8004                 NULL,                                           /* 02h */
8005                 NULL,                                           /* 03h */
8006                 NULL,                                           /* 04h */
8007                 NULL,                                           /* 05h */
8008                 NULL,                                           /* 06h */
8009                 NULL                                            /* 07h */
8010         };
8011         static char *raid_sub_code_str[] = {
8012                 NULL,                                           /* 00h */
8013                 "Volume Creation Failed: Data Passed too "
8014                     "Large",                                    /* 01h */
8015                 "Volume Creation Failed: Duplicate Volumes "
8016                     "Attempted",                                /* 02h */
8017                 "Volume Creation Failed: Max Number "
8018                     "Supported Volumes Exceeded",               /* 03h */
8019                 "Volume Creation Failed: DMA Error",            /* 04h */
8020                 "Volume Creation Failed: Invalid Volume Type",  /* 05h */
8021                 "Volume Creation Failed: Error Reading "
8022                     "MFG Page 4",                               /* 06h */
8023                 "Volume Creation Failed: Creating Internal "
8024                     "Structures",                               /* 07h */
8025                 NULL,                                           /* 08h */
8026                 NULL,                                           /* 09h */
8027                 NULL,                                           /* 0Ah */
8028                 NULL,                                           /* 0Bh */
8029                 NULL,                                           /* 0Ch */
8030                 NULL,                                           /* 0Dh */
8031                 NULL,                                           /* 0Eh */
8032                 NULL,                                           /* 0Fh */
8033                 "Activation failed: Already Active Volume",     /* 10h */
8034                 "Activation failed: Unsupported Volume Type",   /* 11h */
8035                 "Activation failed: Too Many Active Volumes",   /* 12h */
8036                 "Activation failed: Volume ID in Use",          /* 13h */
8037                 "Activation failed: Reported Failure",          /* 14h */
8038                 "Activation failed: Importing a Volume",        /* 15h */
8039                 NULL,                                           /* 16h */
8040                 NULL,                                           /* 17h */
8041                 NULL,                                           /* 18h */
8042                 NULL,                                           /* 19h */
8043                 NULL,                                           /* 1Ah */
8044                 NULL,                                           /* 1Bh */
8045                 NULL,                                           /* 1Ch */
8046                 NULL,                                           /* 1Dh */
8047                 NULL,                                           /* 1Eh */
8048                 NULL,                                           /* 1Fh */
8049                 "Phys Disk failed: Too Many Phys Disks",        /* 20h */
8050                 "Phys Disk failed: Data Passed too Large",      /* 21h */
8051                 "Phys Disk failed: DMA Error",                  /* 22h */
8052                 "Phys Disk failed: Invalid <channel:id>",       /* 23h */
8053                 "Phys Disk failed: Creating Phys Disk Config "
8054                     "Page",                                     /* 24h */
8055                 NULL,                                           /* 25h */
8056                 NULL,                                           /* 26h */
8057                 NULL,                                           /* 27h */
8058                 NULL,                                           /* 28h */
8059                 NULL,                                           /* 29h */
8060                 NULL,                                           /* 2Ah */
8061                 NULL,                                           /* 2Bh */
8062                 NULL,                                           /* 2Ch */
8063                 NULL,                                           /* 2Dh */
8064                 NULL,                                           /* 2Eh */
8065                 NULL,                                           /* 2Fh */
8066                 "Compatibility Error: IR Disabled",             /* 30h */
8067                 "Compatibility Error: Inquiry Command Failed",  /* 31h */
8068                 "Compatibility Error: Device not Direct Access "
8069                     "Device ",                                  /* 32h */
8070                 "Compatibility Error: Removable Device Found",  /* 33h */
8071                 "Compatibility Error: Device SCSI Version not "
8072                     "2 or Higher",                              /* 34h */
8073                 "Compatibility Error: SATA Device, 48 BIT LBA "
8074                     "not Supported",                            /* 35h */
8075                 "Compatibility Error: Device doesn't have "
8076                     "512 Byte Block Sizes",                     /* 36h */
8077                 "Compatibility Error: Volume Type Check Failed", /* 37h */
8078                 "Compatibility Error: Volume Type is "
8079                     "Unsupported by FW",                        /* 38h */
8080                 "Compatibility Error: Disk Drive too Small for "
8081                     "use in Volume",                            /* 39h */
8082                 "Compatibility Error: Phys Disk for Create "
8083                     "Volume not Found",                         /* 3Ah */
8084                 "Compatibility Error: Too Many or too Few "
8085                     "Disks for Volume Type",                    /* 3Bh */
8086                 "Compatibility Error: Disk stripe Sizes "
8087                     "Must be 64KB",                             /* 3Ch */
8088                 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
8089         };
8090
8091 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8092 /**
8093  *      mpt_sas_log_info - Log information returned from SAS IOC.
8094  *      @ioc: Pointer to MPT_ADAPTER structure
8095  *      @log_info: U32 LogInfo reply word from the IOC
8096  *      @cb_idx: callback function's handle
8097  *
8098  *      Refer to lsi/mpi_log_sas.h.
8099  **/
8100 static void
8101 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info, u8 cb_idx)
8102 {
8103 union loginfo_type {
8104         u32     loginfo;
8105         struct {
8106                 u32     subcode:16;
8107                 u32     code:8;
8108                 u32     originator:4;
8109                 u32     bus_type:4;
8110         }dw;
8111 };
8112         union loginfo_type sas_loginfo;
8113         char *originator_desc = NULL;
8114         char *code_desc = NULL;
8115         char *sub_code_desc = NULL;
8116
8117         sas_loginfo.loginfo = log_info;
8118         if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
8119             (sas_loginfo.dw.originator < ARRAY_SIZE(originator_str)))
8120                 return;
8121
8122         originator_desc = originator_str[sas_loginfo.dw.originator];
8123
8124         switch (sas_loginfo.dw.originator) {
8125
8126                 case 0:  /* IOP */
8127                         if (sas_loginfo.dw.code <
8128                             ARRAY_SIZE(iop_code_str))
8129                                 code_desc = iop_code_str[sas_loginfo.dw.code];
8130                         break;
8131                 case 1:  /* PL */
8132                         if (sas_loginfo.dw.code <
8133                             ARRAY_SIZE(pl_code_str))
8134                                 code_desc = pl_code_str[sas_loginfo.dw.code];
8135                         break;
8136                 case 2:  /* IR */
8137                         if (sas_loginfo.dw.code >=
8138                             ARRAY_SIZE(ir_code_str))
8139                                 break;
8140                         code_desc = ir_code_str[sas_loginfo.dw.code];
8141                         if (sas_loginfo.dw.subcode >=
8142                             ARRAY_SIZE(raid_sub_code_str))
8143                                 break;
8144                         if (sas_loginfo.dw.code == 0)
8145                                 sub_code_desc =
8146                                     raid_sub_code_str[sas_loginfo.dw.subcode];
8147                         break;
8148                 default:
8149                         return;
8150         }
8151
8152         if (sub_code_desc != NULL)
8153                 printk(MYIOC_s_INFO_FMT
8154                         "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8155                         " SubCode={%s} cb_idx %s\n",
8156                         ioc->name, log_info, originator_desc, code_desc,
8157                         sub_code_desc, MptCallbacksName[cb_idx]);
8158         else if (code_desc != NULL)
8159                 printk(MYIOC_s_INFO_FMT
8160                         "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8161                         " SubCode(0x%04x) cb_idx %s\n",
8162                         ioc->name, log_info, originator_desc, code_desc,
8163                         sas_loginfo.dw.subcode, MptCallbacksName[cb_idx]);
8164         else
8165                 printk(MYIOC_s_INFO_FMT
8166                         "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
8167                         " SubCode(0x%04x) cb_idx %s\n",
8168                         ioc->name, log_info, originator_desc,
8169                         sas_loginfo.dw.code, sas_loginfo.dw.subcode,
8170                         MptCallbacksName[cb_idx]);
8171 }
8172
8173 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8174 /**
8175  *      mpt_iocstatus_info_config - IOCSTATUS information for config pages
8176  *      @ioc: Pointer to MPT_ADAPTER structure
8177  *      @ioc_status: U32 IOCStatus word from IOC
8178  *      @mf: Pointer to MPT request frame
8179  *
8180  *      Refer to lsi/mpi.h.
8181  **/
8182 static void
8183 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
8184 {
8185         Config_t *pReq = (Config_t *)mf;
8186         char extend_desc[EVENT_DESCR_STR_SZ];
8187         char *desc = NULL;
8188         u32 form;
8189         u8 page_type;
8190
8191         if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
8192                 page_type = pReq->ExtPageType;
8193         else
8194                 page_type = pReq->Header.PageType;
8195
8196         /*
8197          * ignore invalid page messages for GET_NEXT_HANDLE
8198          */
8199         form = le32_to_cpu(pReq->PageAddress);
8200         if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
8201                 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
8202                     page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
8203                     page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
8204                         if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
8205                                 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
8206                                 return;
8207                 }
8208                 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
8209                         if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
8210                                 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
8211                                 return;
8212         }
8213
8214         snprintf(extend_desc, EVENT_DESCR_STR_SZ,
8215             "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
8216             page_type, pReq->Header.PageNumber, pReq->Action, form);
8217
8218         switch (ioc_status) {
8219
8220         case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
8221                 desc = "Config Page Invalid Action";
8222                 break;
8223
8224         case MPI_IOCSTATUS_CONFIG_INVALID_TYPE:   /* 0x0021 */
8225                 desc = "Config Page Invalid Type";
8226                 break;
8227
8228         case MPI_IOCSTATUS_CONFIG_INVALID_PAGE:   /* 0x0022 */
8229                 desc = "Config Page Invalid Page";
8230                 break;
8231
8232         case MPI_IOCSTATUS_CONFIG_INVALID_DATA:   /* 0x0023 */
8233                 desc = "Config Page Invalid Data";
8234                 break;
8235
8236         case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS:    /* 0x0024 */
8237                 desc = "Config Page No Defaults";
8238                 break;
8239
8240         case MPI_IOCSTATUS_CONFIG_CANT_COMMIT:    /* 0x0025 */
8241                 desc = "Config Page Can't Commit";
8242                 break;
8243         }
8244
8245         if (!desc)
8246                 return;
8247
8248         dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
8249             ioc->name, ioc_status, desc, extend_desc));
8250 }
8251
8252 /**
8253  *      mpt_iocstatus_info - IOCSTATUS information returned from IOC.
8254  *      @ioc: Pointer to MPT_ADAPTER structure
8255  *      @ioc_status: U32 IOCStatus word from IOC
8256  *      @mf: Pointer to MPT request frame
8257  *
8258  *      Refer to lsi/mpi.h.
8259  **/
8260 static void
8261 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
8262 {
8263         u32 status = ioc_status & MPI_IOCSTATUS_MASK;
8264         char *desc = NULL;
8265
8266         switch (status) {
8267
8268 /****************************************************************************/
8269 /*  Common IOCStatus values for all replies                                 */
8270 /****************************************************************************/
8271
8272         case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
8273                 desc = "Invalid Function";
8274                 break;
8275
8276         case MPI_IOCSTATUS_BUSY: /* 0x0002 */
8277                 desc = "Busy";
8278                 break;
8279
8280         case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
8281                 desc = "Invalid SGL";
8282                 break;
8283
8284         case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
8285                 desc = "Internal Error";
8286                 break;
8287
8288         case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
8289                 desc = "Reserved";
8290                 break;
8291
8292         case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
8293                 desc = "Insufficient Resources";
8294                 break;
8295
8296         case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
8297                 desc = "Invalid Field";
8298                 break;
8299
8300         case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
8301                 desc = "Invalid State";
8302                 break;
8303
8304 /****************************************************************************/
8305 /*  Config IOCStatus values                                                 */
8306 /****************************************************************************/
8307
8308         case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
8309         case MPI_IOCSTATUS_CONFIG_INVALID_TYPE:   /* 0x0021 */
8310         case MPI_IOCSTATUS_CONFIG_INVALID_PAGE:   /* 0x0022 */
8311         case MPI_IOCSTATUS_CONFIG_INVALID_DATA:   /* 0x0023 */
8312         case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS:    /* 0x0024 */
8313         case MPI_IOCSTATUS_CONFIG_CANT_COMMIT:    /* 0x0025 */
8314                 mpt_iocstatus_info_config(ioc, status, mf);
8315                 break;
8316
8317 /****************************************************************************/
8318 /*  SCSIIO Reply (SPI, FCP, SAS) initiator values                           */
8319 /*                                                                          */
8320 /*  Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
8321 /*                                                                          */
8322 /****************************************************************************/
8323
8324         case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
8325         case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
8326         case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
8327         case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
8328         case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
8329         case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
8330         case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
8331         case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
8332         case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
8333         case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
8334         case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
8335         case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
8336         case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
8337                 break;
8338
8339 /****************************************************************************/
8340 /*  SCSI Target values                                                      */
8341 /****************************************************************************/
8342
8343         case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
8344                 desc = "Target: Priority IO";
8345                 break;
8346
8347         case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
8348                 desc = "Target: Invalid Port";
8349                 break;
8350
8351         case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
8352                 desc = "Target Invalid IO Index:";
8353                 break;
8354
8355         case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
8356                 desc = "Target: Aborted";
8357                 break;
8358
8359         case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
8360                 desc = "Target: No Conn Retryable";
8361                 break;
8362
8363         case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
8364                 desc = "Target: No Connection";
8365                 break;
8366
8367         case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
8368                 desc = "Target: Transfer Count Mismatch";
8369                 break;
8370
8371         case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
8372                 desc = "Target: STS Data not Sent";
8373                 break;
8374
8375         case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
8376                 desc = "Target: Data Offset Error";
8377                 break;
8378
8379         case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
8380                 desc = "Target: Too Much Write Data";
8381                 break;
8382
8383         case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
8384                 desc = "Target: IU Too Short";
8385                 break;
8386
8387         case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
8388                 desc = "Target: ACK NAK Timeout";
8389                 break;
8390
8391         case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
8392                 desc = "Target: Nak Received";
8393                 break;
8394
8395 /****************************************************************************/
8396 /*  Fibre Channel Direct Access values                                      */
8397 /****************************************************************************/
8398
8399         case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
8400                 desc = "FC: Aborted";
8401                 break;
8402
8403         case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
8404                 desc = "FC: RX ID Invalid";
8405                 break;
8406
8407         case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
8408                 desc = "FC: DID Invalid";
8409                 break;
8410
8411         case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
8412                 desc = "FC: Node Logged Out";
8413                 break;
8414
8415         case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
8416                 desc = "FC: Exchange Canceled";
8417                 break;
8418
8419 /****************************************************************************/
8420 /*  LAN values                                                              */
8421 /****************************************************************************/
8422
8423         case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
8424                 desc = "LAN: Device not Found";
8425                 break;
8426
8427         case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
8428                 desc = "LAN: Device Failure";
8429                 break;
8430
8431         case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
8432                 desc = "LAN: Transmit Error";
8433                 break;
8434
8435         case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
8436                 desc = "LAN: Transmit Aborted";
8437                 break;
8438
8439         case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
8440                 desc = "LAN: Receive Error";
8441                 break;
8442
8443         case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
8444                 desc = "LAN: Receive Aborted";
8445                 break;
8446
8447         case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
8448                 desc = "LAN: Partial Packet";
8449                 break;
8450
8451         case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
8452                 desc = "LAN: Canceled";
8453                 break;
8454
8455 /****************************************************************************/
8456 /*  Serial Attached SCSI values                                             */
8457 /****************************************************************************/
8458
8459         case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
8460                 desc = "SAS: SMP Request Failed";
8461                 break;
8462
8463         case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
8464                 desc = "SAS: SMP Data Overrun";
8465                 break;
8466
8467         default:
8468                 desc = "Others";
8469                 break;
8470         }
8471
8472         if (!desc)
8473                 return;
8474
8475         dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
8476             ioc->name, status, desc));
8477 }
8478
8479 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8480 EXPORT_SYMBOL(mpt_attach);
8481 EXPORT_SYMBOL(mpt_detach);
8482 #ifdef CONFIG_PM
8483 EXPORT_SYMBOL(mpt_resume);
8484 EXPORT_SYMBOL(mpt_suspend);
8485 #endif
8486 EXPORT_SYMBOL(ioc_list);
8487 EXPORT_SYMBOL(mpt_register);
8488 EXPORT_SYMBOL(mpt_deregister);
8489 EXPORT_SYMBOL(mpt_event_register);
8490 EXPORT_SYMBOL(mpt_event_deregister);
8491 EXPORT_SYMBOL(mpt_reset_register);
8492 EXPORT_SYMBOL(mpt_reset_deregister);
8493 EXPORT_SYMBOL(mpt_device_driver_register);
8494 EXPORT_SYMBOL(mpt_device_driver_deregister);
8495 EXPORT_SYMBOL(mpt_get_msg_frame);
8496 EXPORT_SYMBOL(mpt_put_msg_frame);
8497 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
8498 EXPORT_SYMBOL(mpt_free_msg_frame);
8499 EXPORT_SYMBOL(mpt_send_handshake_request);
8500 EXPORT_SYMBOL(mpt_verify_adapter);
8501 EXPORT_SYMBOL(mpt_GetIocState);
8502 EXPORT_SYMBOL(mpt_print_ioc_summary);
8503 EXPORT_SYMBOL(mpt_HardResetHandler);
8504 EXPORT_SYMBOL(mpt_config);
8505 EXPORT_SYMBOL(mpt_findImVolumes);
8506 EXPORT_SYMBOL(mpt_alloc_fw_memory);
8507 EXPORT_SYMBOL(mpt_free_fw_memory);
8508 EXPORT_SYMBOL(mptbase_sas_persist_operation);
8509 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
8510
8511 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8512 /**
8513  *      fusion_init - Fusion MPT base driver initialization routine.
8514  *
8515  *      Returns 0 for success, non-zero for failure.
8516  */
8517 static int __init
8518 fusion_init(void)
8519 {
8520         u8 cb_idx;
8521
8522         show_mptmod_ver(my_NAME, my_VERSION);
8523         printk(KERN_INFO COPYRIGHT "\n");
8524
8525         for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
8526                 MptCallbacks[cb_idx] = NULL;
8527                 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
8528                 MptEvHandlers[cb_idx] = NULL;
8529                 MptResetHandlers[cb_idx] = NULL;
8530         }
8531
8532         /*  Register ourselves (mptbase) in order to facilitate
8533          *  EventNotification handling.
8534          */
8535         mpt_base_index = mpt_register(mptbase_reply, MPTBASE_DRIVER,
8536             "mptbase_reply");
8537
8538         /* Register for hard reset handling callbacks.
8539          */
8540         mpt_reset_register(mpt_base_index, mpt_ioc_reset);
8541
8542 #ifdef CONFIG_PROC_FS
8543         (void) procmpt_create();
8544 #endif
8545         return 0;
8546 }
8547
8548 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8549 /**
8550  *      fusion_exit - Perform driver unload cleanup.
8551  *
8552  *      This routine frees all resources associated with each MPT adapter
8553  *      and removes all %MPT_PROCFS_MPTBASEDIR entries.
8554  */
8555 static void __exit
8556 fusion_exit(void)
8557 {
8558
8559         mpt_reset_deregister(mpt_base_index);
8560
8561 #ifdef CONFIG_PROC_FS
8562         procmpt_destroy();
8563 #endif
8564 }
8565
8566 module_init(fusion_init);
8567 module_exit(fusion_exit);