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