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