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