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