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