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