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