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