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