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