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