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