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