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