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