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