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