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