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