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