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