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