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