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