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