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