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