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