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