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