[SCSI] fusion - Adding pci recog support for Fibre 949X and 939X chips
[linux-2.6.git] / 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         if (ioc->spi_data.nvram != NULL) {
1841                 kfree(ioc->spi_data.nvram);
1842                 ioc->spi_data.nvram = NULL;
1843         }
1844
1845         if (ioc->spi_data.pIocPg3 != NULL) {
1846                 kfree(ioc->spi_data.pIocPg3);
1847                 ioc->spi_data.pIocPg3 = NULL;
1848         }
1849
1850         if (ioc->spi_data.pIocPg4 != NULL) {
1851                 sz = ioc->spi_data.IocPg4Sz;
1852                 pci_free_consistent(ioc->pcidev, sz, 
1853                         ioc->spi_data.pIocPg4,
1854                         ioc->spi_data.IocPg4_dma);
1855                 ioc->spi_data.pIocPg4 = NULL;
1856                 ioc->alloc_total -= sz;
1857         }
1858
1859         if (ioc->ReqToChain != NULL) {
1860                 kfree(ioc->ReqToChain);
1861                 kfree(ioc->RequestNB);
1862                 ioc->ReqToChain = NULL;
1863         }
1864
1865         if (ioc->ChainToChain != NULL) {
1866                 kfree(ioc->ChainToChain);
1867                 ioc->ChainToChain = NULL;
1868         }
1869 }
1870
1871 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1872 /*
1873  *      mpt_adapter_dispose - Free all resources associated with a MPT
1874  *      adapter.
1875  *      @ioc: Pointer to MPT adapter structure
1876  *
1877  *      This routine unregisters h/w resources and frees all alloc'd memory
1878  *      associated with a MPT adapter structure.
1879  */
1880 static void
1881 mpt_adapter_dispose(MPT_ADAPTER *ioc)
1882 {
1883         if (ioc != NULL) {
1884                 int sz_first, sz_last;
1885
1886                 sz_first = ioc->alloc_total;
1887
1888                 mpt_adapter_disable(ioc);
1889
1890                 if (ioc->pci_irq != -1) {
1891                         free_irq(ioc->pci_irq, ioc);
1892                         ioc->pci_irq = -1;
1893                 }
1894
1895                 if (ioc->memmap != NULL)
1896                         iounmap(ioc->memmap);
1897
1898 #if defined(CONFIG_MTRR) && 0
1899                 if (ioc->mtrr_reg > 0) {
1900                         mtrr_del(ioc->mtrr_reg, 0, 0);
1901                         dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
1902                 }
1903 #endif
1904
1905                 /*  Zap the adapter lookup ptr!  */
1906                 list_del(&ioc->list);
1907
1908                 sz_last = ioc->alloc_total;
1909                 dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
1910                                 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
1911                 kfree(ioc);
1912         }
1913 }
1914
1915 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1916 /*
1917  *      MptDisplayIocCapabilities - Disply IOC's capacilities.
1918  *      @ioc: Pointer to MPT adapter structure
1919  */
1920 static void
1921 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
1922 {
1923         int i = 0;
1924
1925         printk(KERN_INFO "%s: ", ioc->name);
1926         if (ioc->prod_name && strlen(ioc->prod_name) > 3)
1927                 printk("%s: ", ioc->prod_name+3);
1928         printk("Capabilities={");
1929
1930         if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
1931                 printk("Initiator");
1932                 i++;
1933         }
1934
1935         if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
1936                 printk("%sTarget", i ? "," : "");
1937                 i++;
1938         }
1939
1940         if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
1941                 printk("%sLAN", i ? "," : "");
1942                 i++;
1943         }
1944
1945 #if 0
1946         /*
1947          *  This would probably evoke more questions than it's worth
1948          */
1949         if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
1950                 printk("%sLogBusAddr", i ? "," : "");
1951                 i++;
1952         }
1953 #endif
1954
1955         printk("}\n");
1956 }
1957
1958 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1959 /*
1960  *      MakeIocReady - Get IOC to a READY state, using KickStart if needed.
1961  *      @ioc: Pointer to MPT_ADAPTER structure
1962  *      @force: Force hard KickStart of IOC
1963  *      @sleepFlag: Specifies whether the process can sleep
1964  *
1965  *      Returns:
1966  *               1 - DIAG reset and READY
1967  *               0 - READY initially OR soft reset and READY
1968  *              -1 - Any failure on KickStart
1969  *              -2 - Msg Unit Reset Failed
1970  *              -3 - IO Unit Reset Failed
1971  *              -4 - IOC owned by a PEER
1972  */
1973 static int
1974 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
1975 {
1976         u32      ioc_state;
1977         int      statefault = 0;
1978         int      cntdn;
1979         int      hard_reset_done = 0;
1980         int      r;
1981         int      ii;
1982         int      whoinit;
1983
1984         /* Get current [raw] IOC state  */
1985         ioc_state = mpt_GetIocState(ioc, 0);
1986         dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
1987
1988         /*
1989          *      Check to see if IOC got left/stuck in doorbell handshake
1990          *      grip of death.  If so, hard reset the IOC.
1991          */
1992         if (ioc_state & MPI_DOORBELL_ACTIVE) {
1993                 statefault = 1;
1994                 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
1995                                 ioc->name);
1996         }
1997
1998         /* Is it already READY? */
1999         if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY) 
2000                 return 0;
2001
2002         /*
2003          *      Check to see if IOC is in FAULT state.
2004          */
2005         if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2006                 statefault = 2;
2007                 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2008                                 ioc->name);
2009                 printk(KERN_WARNING "           FAULT code = %04xh\n",
2010                                 ioc_state & MPI_DOORBELL_DATA_MASK);
2011         }
2012
2013         /*
2014          *      Hmmm...  Did it get left operational?
2015          */
2016         if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2017                 dinitprintk((MYIOC_s_WARN_FMT "IOC operational unexpected\n",
2018                                 ioc->name));
2019
2020                 /* Check WhoInit.
2021                  * If PCI Peer, exit.
2022                  * Else, if no fault conditions are present, issue a MessageUnitReset
2023                  * Else, fall through to KickStart case
2024                  */
2025                 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2026                 dprintk((KERN_WARNING MYNAM
2027                         ": whoinit 0x%x\n statefault %d force %d\n",
2028                         whoinit, statefault, force));
2029                 if (whoinit == MPI_WHOINIT_PCI_PEER)
2030                         return -4;
2031                 else {
2032                         if ((statefault == 0 ) && (force == 0)) {
2033                                 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2034                                         return 0;
2035                         }
2036                         statefault = 3;
2037                 }
2038         }
2039
2040         hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2041         if (hard_reset_done < 0)
2042                 return -1;
2043
2044         /*
2045          *  Loop here waiting for IOC to come READY.
2046          */
2047         ii = 0;
2048         cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15;    /* 15 seconds */
2049
2050         while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2051                 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2052                         /*
2053                          *  BIOS or previous driver load left IOC in OP state.
2054                          *  Reset messaging FIFOs.
2055                          */
2056                         if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2057                                 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2058                                 return -2;
2059                         }
2060                 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2061                         /*
2062                          *  Something is wrong.  Try to get IOC back
2063                          *  to a known state.
2064                          */
2065                         if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2066                                 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2067                                 return -3;
2068                         }
2069                 }
2070
2071                 ii++; cntdn--;
2072                 if (!cntdn) {
2073                         printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2074                                         ioc->name, (int)((ii+5)/HZ));
2075                         return -ETIME;
2076                 }
2077
2078                 if (sleepFlag == CAN_SLEEP) {
2079                         msleep_interruptible(1);
2080                 } else {
2081                         mdelay (1);     /* 1 msec delay */
2082                 }
2083
2084         }
2085
2086         if (statefault < 3) {
2087                 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2088                                 ioc->name,
2089                                 statefault==1 ? "stuck handshake" : "IOC FAULT");
2090         }
2091
2092         return hard_reset_done;
2093 }
2094
2095 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2096 /*
2097  *      mpt_GetIocState - Get the current state of a MPT adapter.
2098  *      @ioc: Pointer to MPT_ADAPTER structure
2099  *      @cooked: Request raw or cooked IOC state
2100  *
2101  *      Returns all IOC Doorbell register bits if cooked==0, else just the
2102  *      Doorbell bits in MPI_IOC_STATE_MASK.
2103  */
2104 u32
2105 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2106 {
2107         u32 s, sc;
2108
2109         /*  Get!  */
2110         s = CHIPREG_READ32(&ioc->chip->Doorbell);
2111 //      dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2112         sc = s & MPI_IOC_STATE_MASK;
2113
2114         /*  Save!  */
2115         ioc->last_state = sc;
2116
2117         return cooked ? sc : s;
2118 }
2119
2120 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2121 /*
2122  *      GetIocFacts - Send IOCFacts request to MPT adapter.
2123  *      @ioc: Pointer to MPT_ADAPTER structure
2124  *      @sleepFlag: Specifies whether the process can sleep
2125  *      @reason: If recovery, only update facts.
2126  *
2127  *      Returns 0 for success, non-zero for failure.
2128  */
2129 static int
2130 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2131 {
2132         IOCFacts_t               get_facts;
2133         IOCFactsReply_t         *facts;
2134         int                      r;
2135         int                      req_sz;
2136         int                      reply_sz;
2137         int                      sz;
2138         u32                      status, vv;
2139         u8                       shiftFactor=1;
2140
2141         /* IOC *must* NOT be in RESET state! */
2142         if (ioc->last_state == MPI_IOC_STATE_RESET) {
2143                 printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2144                                 ioc->name,
2145                                 ioc->last_state );
2146                 return -44;
2147         }
2148
2149         facts = &ioc->facts;
2150
2151         /* Destination (reply area)... */
2152         reply_sz = sizeof(*facts);
2153         memset(facts, 0, reply_sz);
2154
2155         /* Request area (get_facts on the stack right now!) */
2156         req_sz = sizeof(get_facts);
2157         memset(&get_facts, 0, req_sz);
2158
2159         get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2160         /* Assert: All other get_facts fields are zero! */
2161
2162         dinitprintk((MYIOC_s_INFO_FMT 
2163             "Sending get IocFacts request req_sz=%d reply_sz=%d\n", 
2164             ioc->name, req_sz, reply_sz));
2165
2166         /* No non-zero fields in the get_facts request are greater than
2167          * 1 byte in size, so we can just fire it off as is.
2168          */
2169         r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2170                         reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2171         if (r != 0)
2172                 return r;
2173
2174         /*
2175          * Now byte swap (GRRR) the necessary fields before any further
2176          * inspection of reply contents.
2177          *
2178          * But need to do some sanity checks on MsgLength (byte) field
2179          * to make sure we don't zero IOC's req_sz!
2180          */
2181         /* Did we get a valid reply? */
2182         if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2183                 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2184                         /*
2185                          * If not been here, done that, save off first WhoInit value
2186                          */
2187                         if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2188                                 ioc->FirstWhoInit = facts->WhoInit;
2189                 }
2190
2191                 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2192                 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2193                 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2194                 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2195                 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2196                 status = facts->IOCStatus & MPI_IOCSTATUS_MASK;
2197                 /* CHECKME! IOCStatus, IOCLogInfo */
2198
2199                 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2200                 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2201
2202                 /*
2203                  * FC f/w version changed between 1.1 and 1.2
2204                  *      Old: u16{Major(4),Minor(4),SubMinor(8)}
2205                  *      New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2206                  */
2207                 if (facts->MsgVersion < 0x0102) {
2208                         /*
2209                          *      Handle old FC f/w style, convert to new...
2210                          */
2211                         u16      oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2212                         facts->FWVersion.Word =
2213                                         ((oldv<<12) & 0xFF000000) |
2214                                         ((oldv<<8)  & 0x000FFF00);
2215                 } else
2216                         facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2217
2218                 facts->ProductID = le16_to_cpu(facts->ProductID);
2219                 facts->CurrentHostMfaHighAddr =
2220                                 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2221                 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2222                 facts->CurrentSenseBufferHighAddr =
2223                                 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2224                 facts->CurReplyFrameSize =
2225                                 le16_to_cpu(facts->CurReplyFrameSize);
2226
2227                 /*
2228                  * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2229                  * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2230                  * to 14 in MPI-1.01.0x.
2231                  */
2232                 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2233                     facts->MsgVersion > 0x0100) {
2234                         facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2235                 }
2236
2237                 sz = facts->FWImageSize;
2238                 if ( sz & 0x01 )
2239                         sz += 1;
2240                 if ( sz & 0x02 )
2241                         sz += 2;
2242                 facts->FWImageSize = sz;
2243                 
2244                 if (!facts->RequestFrameSize) {
2245                         /*  Something is wrong!  */
2246                         printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2247                                         ioc->name);
2248                         return -55;
2249                 }
2250
2251                 r = sz = facts->BlockSize;
2252                 vv = ((63 / (sz * 4)) + 1) & 0x03;
2253                 ioc->NB_for_64_byte_frame = vv;
2254                 while ( sz )
2255                 {
2256                         shiftFactor++;
2257                         sz = sz >> 1;
2258                 }
2259                 ioc->NBShiftFactor  = shiftFactor;
2260                 dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2261                                         ioc->name, vv, shiftFactor, r));
2262     
2263                 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2264                         /*
2265                          * Set values for this IOC's request & reply frame sizes,
2266                          * and request & reply queue depths...
2267                          */
2268                         ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2269                         ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2270                         ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2271                         ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2272
2273                         dinitprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
2274                                 ioc->name, ioc->reply_sz, ioc->reply_depth));
2275                         dinitprintk((MYIOC_s_INFO_FMT "req_sz  =%3d, req_depth  =%4d\n",
2276                                 ioc->name, ioc->req_sz, ioc->req_depth));
2277
2278                         /* Get port facts! */
2279                         if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2280                                 return r;
2281                 }
2282         } else {
2283                 printk(MYIOC_s_ERR_FMT 
2284                      "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2285                      ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2286                      RequestFrameSize)/sizeof(u32)));
2287                 return -66;
2288         }
2289
2290         return 0;
2291 }
2292
2293 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2294 /*
2295  *      GetPortFacts - Send PortFacts request to MPT adapter.
2296  *      @ioc: Pointer to MPT_ADAPTER structure
2297  *      @portnum: Port number
2298  *      @sleepFlag: Specifies whether the process can sleep
2299  *
2300  *      Returns 0 for success, non-zero for failure.
2301  */
2302 static int
2303 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2304 {
2305         PortFacts_t              get_pfacts;
2306         PortFactsReply_t        *pfacts;
2307         int                      ii;
2308         int                      req_sz;
2309         int                      reply_sz;
2310
2311         /* IOC *must* NOT be in RESET state! */
2312         if (ioc->last_state == MPI_IOC_STATE_RESET) {
2313                 printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2314                                 ioc->name,
2315                                 ioc->last_state );
2316                 return -4;
2317         }
2318
2319         pfacts = &ioc->pfacts[portnum];
2320
2321         /* Destination (reply area)...  */
2322         reply_sz = sizeof(*pfacts);
2323         memset(pfacts, 0, reply_sz);
2324
2325         /* Request area (get_pfacts on the stack right now!) */
2326         req_sz = sizeof(get_pfacts);
2327         memset(&get_pfacts, 0, req_sz);
2328
2329         get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2330         get_pfacts.PortNumber = portnum;
2331         /* Assert: All other get_pfacts fields are zero! */
2332
2333         dinitprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
2334                         ioc->name, portnum));
2335
2336         /* No non-zero fields in the get_pfacts request are greater than
2337          * 1 byte in size, so we can just fire it off as is.
2338          */
2339         ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2340                                 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2341         if (ii != 0)
2342                 return ii;
2343
2344         /* Did we get a valid reply? */
2345
2346         /* Now byte swap the necessary fields in the response. */
2347         pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2348         pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2349         pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2350         pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2351         pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2352         pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2353         pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2354         pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2355         pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2356
2357         return 0;
2358 }
2359
2360 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2361 /*
2362  *      SendIocInit - Send IOCInit request to MPT adapter.
2363  *      @ioc: Pointer to MPT_ADAPTER structure
2364  *      @sleepFlag: Specifies whether the process can sleep
2365  *
2366  *      Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2367  *
2368  *      Returns 0 for success, non-zero for failure.
2369  */
2370 static int
2371 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2372 {
2373         IOCInit_t                ioc_init;
2374         MPIDefaultReply_t        init_reply;
2375         u32                      state;
2376         int                      r;
2377         int                      count;
2378         int                      cntdn;
2379
2380         memset(&ioc_init, 0, sizeof(ioc_init));
2381         memset(&init_reply, 0, sizeof(init_reply));
2382
2383         ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2384         ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2385
2386         /* If we are in a recovery mode and we uploaded the FW image,
2387          * then this pointer is not NULL. Skip the upload a second time.
2388          * Set this flag if cached_fw set for either IOC.
2389          */
2390         if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2391                 ioc->upload_fw = 1;
2392         else
2393                 ioc->upload_fw = 0;
2394         ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
2395                    ioc->name, ioc->upload_fw, ioc->facts.Flags));
2396
2397         if (ioc->bus_type == FC)
2398                 ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
2399         else
2400                 ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
2401         
2402         ioc_init.MaxBuses = MPT_MAX_BUS;
2403
2404         ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz);   /* in BYTES */
2405
2406         if (sizeof(dma_addr_t) == sizeof(u64)) {
2407                 /* Save the upper 32-bits of the request
2408                  * (reply) and sense buffers.
2409                  */
2410                 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2411                 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2412         } else {
2413                 /* Force 32-bit addressing */
2414                 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2415                 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2416         }
2417                 
2418         ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2419         ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2420
2421         dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
2422                         ioc->name, &ioc_init));
2423
2424         r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2425                                 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2426         if (r != 0)
2427                 return r;
2428
2429         /* No need to byte swap the multibyte fields in the reply
2430          * since we don't even look at it's contents.
2431          */
2432
2433         dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
2434                         ioc->name, &ioc_init));
2435         
2436         if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0)
2437                 return r;
2438
2439         /* YIKES!  SUPER IMPORTANT!!!
2440          *  Poll IocState until _OPERATIONAL while IOC is doing
2441          *  LoopInit and TargetDiscovery!
2442          */
2443         count = 0;
2444         cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60;    /* 60 seconds */
2445         state = mpt_GetIocState(ioc, 1);
2446         while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2447                 if (sleepFlag == CAN_SLEEP) {
2448                         msleep_interruptible(1);
2449                 } else {
2450                         mdelay(1);
2451                 }
2452
2453                 if (!cntdn) {
2454                         printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2455                                         ioc->name, (int)((count+5)/HZ));
2456                         return -9;
2457                 }
2458
2459                 state = mpt_GetIocState(ioc, 1);
2460                 count++;
2461         }
2462         dhsprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2463                         ioc->name, count));
2464
2465         return r;
2466 }
2467
2468 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2469 /*
2470  *      SendPortEnable - Send PortEnable request to MPT adapter port.
2471  *      @ioc: Pointer to MPT_ADAPTER structure
2472  *      @portnum: Port number to enable
2473  *      @sleepFlag: Specifies whether the process can sleep
2474  *
2475  *      Send PortEnable to bring IOC to OPERATIONAL state.
2476  *
2477  *      Returns 0 for success, non-zero for failure.
2478  */
2479 static int
2480 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2481 {
2482         PortEnable_t             port_enable;
2483         MPIDefaultReply_t        reply_buf;
2484         int      ii;
2485         int      req_sz;
2486         int      reply_sz;
2487
2488         /*  Destination...  */
2489         reply_sz = sizeof(MPIDefaultReply_t);
2490         memset(&reply_buf, 0, reply_sz);
2491
2492         req_sz = sizeof(PortEnable_t);
2493         memset(&port_enable, 0, req_sz);
2494
2495         port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2496         port_enable.PortNumber = portnum;
2497 /*      port_enable.ChainOffset = 0;            */
2498 /*      port_enable.MsgFlags = 0;               */
2499 /*      port_enable.MsgContext = 0;             */
2500
2501         dinitprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
2502                         ioc->name, portnum, &port_enable));
2503
2504         /* RAID FW may take a long time to enable
2505          */
2506         if (ioc->bus_type == FC) {
2507                 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2508                                 reply_sz, (u16*)&reply_buf, 65 /*seconds*/, sleepFlag);
2509         } else {
2510                 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2511                                 reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag);
2512         }
2513
2514         if (ii != 0)
2515                 return ii;
2516
2517         /* We do not even look at the reply, so we need not
2518          * swap the multi-byte fields.
2519          */
2520
2521         return 0;
2522 }
2523
2524 /*
2525  *      ioc: Pointer to MPT_ADAPTER structure
2526  *      size - total FW bytes
2527  */
2528 void
2529 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
2530 {
2531         if (ioc->cached_fw)
2532                 return;  /* use already allocated memory */
2533         if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2534                 ioc->cached_fw = ioc->alt_ioc->cached_fw;  /* use alt_ioc's memory */
2535                 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
2536         } else {
2537                 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
2538                         ioc->alloc_total += size;
2539         }
2540 }
2541 /*
2542  * If alt_img is NULL, delete from ioc structure.
2543  * Else, delete a secondary image in same format.
2544  */
2545 void
2546 mpt_free_fw_memory(MPT_ADAPTER *ioc)
2547 {
2548         int sz;
2549
2550         sz = ioc->facts.FWImageSize;
2551         dinitprintk((KERN_WARNING MYNAM "free_fw_memory: FW Image  @ %p[%p], sz=%d[%x] bytes\n",
2552                  ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2553         pci_free_consistent(ioc->pcidev, sz,
2554                         ioc->cached_fw, ioc->cached_fw_dma);
2555         ioc->cached_fw = NULL;
2556
2557         return;
2558 }
2559
2560
2561 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2562 /*
2563  *      mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
2564  *      @ioc: Pointer to MPT_ADAPTER structure
2565  *      @sleepFlag: Specifies whether the process can sleep
2566  *
2567  *      Returns 0 for success, >0 for handshake failure
2568  *              <0 for fw upload failure.
2569  *
2570  *      Remark: If bound IOC and a successful FWUpload was performed
2571  *      on the bound IOC, the second image is discarded
2572  *      and memory is free'd. Both channels must upload to prevent
2573  *      IOC from running in degraded mode.
2574  */
2575 static int
2576 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2577 {
2578         u8                       request[ioc->req_sz];
2579         u8                       reply[sizeof(FWUploadReply_t)];
2580         FWUpload_t              *prequest;
2581         FWUploadReply_t         *preply;
2582         FWUploadTCSGE_t         *ptcsge;
2583         int                      sgeoffset;
2584         u32                      flagsLength;
2585         int                      ii, sz, reply_sz;
2586         int                      cmdStatus;
2587
2588         /* If the image size is 0, we are done.
2589          */
2590         if ((sz = ioc->facts.FWImageSize) == 0)
2591                 return 0;
2592
2593         mpt_alloc_fw_memory(ioc, sz);
2594
2595         dinitprintk((KERN_WARNING MYNAM ": FW Image  @ %p[%p], sz=%d[%x] bytes\n",
2596                  ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2597         
2598         if (ioc->cached_fw == NULL) {
2599                 /* Major Failure.
2600                  */
2601                 return -ENOMEM;
2602         }
2603
2604         prequest = (FWUpload_t *)&request;
2605         preply = (FWUploadReply_t *)&reply;
2606
2607         /*  Destination...  */
2608         memset(prequest, 0, ioc->req_sz);
2609
2610         reply_sz = sizeof(reply);
2611         memset(preply, 0, reply_sz);
2612
2613         prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
2614         prequest->Function = MPI_FUNCTION_FW_UPLOAD;
2615
2616         ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
2617         ptcsge->DetailsLength = 12;
2618         ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
2619         ptcsge->ImageSize = cpu_to_le32(sz);
2620
2621         sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
2622
2623         flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
2624         mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
2625
2626         sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
2627         dinitprintk((KERN_WARNING MYNAM "Sending FW Upload (req @ %p) sgeoffset=%d \n",
2628                         prequest, sgeoffset));
2629         DBG_DUMP_FW_REQUEST_FRAME(prequest)
2630
2631         ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
2632                                 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
2633
2634         dinitprintk((KERN_WARNING MYNAM "FW Upload completed rc=%x \n", ii));
2635
2636         cmdStatus = -EFAULT;
2637         if (ii == 0) {
2638                 /* Handshake transfer was complete and successful.
2639                  * Check the Reply Frame.
2640                  */
2641                 int status, transfer_sz;
2642                 status = le16_to_cpu(preply->IOCStatus);
2643                 if (status == MPI_IOCSTATUS_SUCCESS) {
2644                         transfer_sz = le32_to_cpu(preply->ActualImageSize);
2645                         if (transfer_sz == sz)
2646                                 cmdStatus = 0;
2647                 }
2648         }
2649         dinitprintk((MYIOC_s_INFO_FMT ": do_upload status %d \n",
2650                         ioc->name, cmdStatus));
2651
2652         
2653         if (cmdStatus) {
2654
2655                 ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
2656                         ioc->name));
2657                 mpt_free_fw_memory(ioc);
2658         }
2659
2660         return cmdStatus;
2661 }
2662
2663 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2664 /*
2665  *      mpt_downloadboot - DownloadBoot code
2666  *      @ioc: Pointer to MPT_ADAPTER structure
2667  *      @flag: Specify which part of IOC memory is to be uploaded.
2668  *      @sleepFlag: Specifies whether the process can sleep
2669  *
2670  *      FwDownloadBoot requires Programmed IO access.
2671  *
2672  *      Returns 0 for success
2673  *              -1 FW Image size is 0
2674  *              -2 No valid cached_fw Pointer
2675  *              <0 for fw upload failure.
2676  */
2677 static int
2678 mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
2679 {
2680         MpiFwHeader_t           *pFwHeader;
2681         MpiExtImageHeader_t     *pExtImage;
2682         u32                      fwSize;
2683         u32                      diag0val;
2684         int                      count;
2685         u32                     *ptrFw;
2686         u32                      diagRwData;
2687         u32                      nextImage;
2688         u32                      load_addr;
2689         u32                      ioc_state=0;
2690
2691         ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x, ioc FW Ptr %p\n",
2692                                 ioc->name, ioc->facts.FWImageSize, ioc->cached_fw));
2693
2694         if ( ioc->facts.FWImageSize == 0 )
2695                 return -1;
2696
2697         if (ioc->cached_fw == NULL)
2698                 return -2;
2699
2700         /* prevent a second downloadboot and memory free with alt_ioc */
2701         if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
2702                 ioc->alt_ioc->cached_fw = NULL;
2703
2704         CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2705         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2706         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2707         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2708         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2709         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2710
2711         CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
2712
2713         /* wait 1 msec */
2714         if (sleepFlag == CAN_SLEEP) {
2715                 msleep_interruptible(1);
2716         } else {
2717                 mdelay (1);
2718         }
2719
2720         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2721         CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2722
2723         for (count = 0; count < 30; count ++) {
2724                 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2725                 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
2726                         ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
2727                                 ioc->name, count));
2728                         break;
2729                 }
2730                 /* wait 1 sec */
2731                 if (sleepFlag == CAN_SLEEP) {
2732                         msleep_interruptible (1000);
2733                 } else {
2734                         mdelay (1000);
2735                 }
2736         }
2737
2738         if ( count == 30 ) {
2739                 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! Unable to RESET_ADAPTER diag0val=%x\n",
2740                 ioc->name, diag0val));
2741                 return -3;
2742         }
2743
2744         CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2745         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2746         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2747         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2748         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2749         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2750
2751         /* Set the DiagRwEn and Disable ARM bits */
2752         CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
2753
2754         pFwHeader = (MpiFwHeader_t *) ioc->cached_fw;
2755         fwSize = (pFwHeader->ImageSize + 3)/4;
2756         ptrFw = (u32 *) pFwHeader;
2757
2758         /* Write the LoadStartAddress to the DiagRw Address Register
2759          * using Programmed IO
2760          */
2761         if (ioc->errata_flag_1064)
2762                 pci_enable_io_access(ioc->pcidev);
2763
2764         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
2765         ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
2766                 ioc->name, pFwHeader->LoadStartAddress));
2767
2768         ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n",
2769                                 ioc->name, fwSize*4, ptrFw));
2770         while (fwSize--) {
2771                 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2772         }
2773
2774         nextImage = pFwHeader->NextImageHeaderOffset;
2775         while (nextImage) {
2776                 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
2777
2778                 load_addr = pExtImage->LoadStartAddress;
2779
2780                 fwSize = (pExtImage->ImageSize + 3) >> 2;
2781                 ptrFw = (u32 *)pExtImage;
2782
2783                 ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x bytes @ %p load_addr=%x\n",
2784                                                 ioc->name, fwSize*4, ptrFw, load_addr));
2785                 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
2786
2787                 while (fwSize--) {
2788                         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2789                 }
2790                 nextImage = pExtImage->NextImageHeaderOffset;
2791         }
2792
2793         /* Write the IopResetVectorRegAddr */
2794         ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name,      pFwHeader->IopResetRegAddr));
2795         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
2796
2797         /* Write the IopResetVectorValue */
2798         ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
2799         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
2800
2801         /* Clear the internal flash bad bit - autoincrementing register,
2802          * so must do two writes.
2803          */
2804         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
2805         diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
2806         diagRwData |= 0x4000000;
2807         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
2808         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
2809
2810         if (ioc->errata_flag_1064)
2811                 pci_disable_io_access(ioc->pcidev);
2812
2813         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2814         ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, turning off PREVENT_IOC_BOOT, DISABLE_ARM\n",
2815                 ioc->name, diag0val));
2816         diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM);
2817         ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
2818                 ioc->name, diag0val));
2819         CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
2820
2821         /* Write 0xFF to reset the sequencer */
2822         CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2823
2824         for (count=0; count<HZ*20; count++) {
2825                 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
2826                         ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
2827                                         ioc->name, count, ioc_state));
2828                         if ((SendIocInit(ioc, sleepFlag)) != 0) {
2829                                 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
2830                                         ioc->name));
2831                                 return -EFAULT;
2832                         }
2833                         ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit successful\n",
2834                                         ioc->name));
2835                         return 0;
2836                 }
2837                 if (sleepFlag == CAN_SLEEP) {
2838                         msleep_interruptible (10);
2839                 } else {
2840                         mdelay (10);
2841                 }
2842         }
2843         ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! IocState=%x\n",
2844                 ioc->name, ioc_state));
2845         return -EFAULT;
2846 }
2847
2848 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2849 /*
2850  *      KickStart - Perform hard reset of MPT adapter.
2851  *      @ioc: Pointer to MPT_ADAPTER structure
2852  *      @force: Force hard reset
2853  *      @sleepFlag: Specifies whether the process can sleep
2854  *
2855  *      This routine places MPT adapter in diagnostic mode via the
2856  *      WriteSequence register, and then performs a hard reset of adapter
2857  *      via the Diagnostic register.
2858  *
2859  *      Inputs:   sleepflag - CAN_SLEEP (non-interrupt thread)
2860  *                      or NO_SLEEP (interrupt thread, use mdelay)
2861  *                force - 1 if doorbell active, board fault state
2862  *                              board operational, IOC_RECOVERY or
2863  *                              IOC_BRINGUP and there is an alt_ioc.
2864  *                        0 else
2865  *
2866  *      Returns:
2867  *               1 - hard reset, READY  
2868  *               0 - no reset due to History bit, READY 
2869  *              -1 - no reset due to History bit but not READY  
2870  *                   OR reset but failed to come READY
2871  *              -2 - no reset, could not enter DIAG mode
2872  *              -3 - reset but bad FW bit
2873  */
2874 static int
2875 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
2876 {
2877         int hard_reset_done = 0;
2878         u32 ioc_state=0;
2879         int cnt,cntdn;
2880
2881         dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
2882         if (ioc->bus_type == SCSI) {
2883                 /* Always issue a Msg Unit Reset first. This will clear some
2884                  * SCSI bus hang conditions.
2885                  */
2886                 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
2887
2888                 if (sleepFlag == CAN_SLEEP) {
2889                         msleep_interruptible (1000);
2890                 } else {
2891                         mdelay (1000);
2892                 }
2893         }
2894
2895         hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
2896         if (hard_reset_done < 0)
2897                 return hard_reset_done;
2898
2899         dinitprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
2900                         ioc->name));
2901
2902         cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2;     /* 2 seconds */
2903         for (cnt=0; cnt<cntdn; cnt++) {
2904                 ioc_state = mpt_GetIocState(ioc, 1);
2905                 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
2906                         dinitprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
2907                                         ioc->name, cnt));
2908                         return hard_reset_done;
2909                 }
2910                 if (sleepFlag == CAN_SLEEP) {
2911                         msleep_interruptible (10);
2912                 } else {
2913                         mdelay (10);
2914                 }
2915         }
2916
2917         printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
2918                         ioc->name, ioc_state);
2919         return -1;
2920 }
2921
2922 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2923 /*
2924  *      mpt_diag_reset - Perform hard reset of the adapter.
2925  *      @ioc: Pointer to MPT_ADAPTER structure
2926  *      @ignore: Set if to honor and clear to ignore
2927  *              the reset history bit
2928  *      @sleepflag: CAN_SLEEP if called in a non-interrupt thread,
2929  *              else set to NO_SLEEP (use mdelay instead)
2930  *
2931  *      This routine places the adapter in diagnostic mode via the
2932  *      WriteSequence register and then performs a hard reset of adapter
2933  *      via the Diagnostic register. Adapter should be in ready state
2934  *      upon successful completion.
2935  *
2936  *      Returns:  1  hard reset successful
2937  *                0  no reset performed because reset history bit set
2938  *               -2  enabling diagnostic mode failed
2939  *               -3  diagnostic reset failed
2940  */
2941 static int
2942 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
2943 {
2944         u32 diag0val;
2945         u32 doorbell;
2946         int hard_reset_done = 0;
2947         int count = 0;
2948 #ifdef MPT_DEBUG
2949         u32 diag1val = 0;
2950 #endif
2951
2952         /* Clear any existing interrupts */
2953         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2954
2955         /* Use "Diagnostic reset" method! (only thing available!) */
2956         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2957
2958 #ifdef MPT_DEBUG
2959         if (ioc->alt_ioc)
2960                 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
2961         dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
2962                         ioc->name, diag0val, diag1val));
2963 #endif
2964
2965         /* Do the reset if we are told to ignore the reset history
2966          * or if the reset history is 0
2967          */
2968         if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
2969                 while ((diag0val & MPI_DIAG_DRWE) == 0) {
2970                         /* Write magic sequence to WriteSequence register
2971                          * Loop until in diagnostic mode
2972                          */
2973                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2974                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2975                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2976                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2977                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2978                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2979
2980                         /* wait 100 msec */
2981                         if (sleepFlag == CAN_SLEEP) {
2982                                 msleep_interruptible (100);
2983                         } else {
2984                                 mdelay (100);
2985                         }
2986
2987                         count++;
2988                         if (count > 20) {
2989                                 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
2990                                                 ioc->name, diag0val);
2991                                 return -2;
2992
2993                         }
2994
2995                         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2996
2997                         dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
2998                                         ioc->name, diag0val));
2999                 }
3000
3001 #ifdef MPT_DEBUG
3002                 if (ioc->alt_ioc)
3003                         diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3004                 dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3005                                 ioc->name, diag0val, diag1val));
3006 #endif
3007                 /*
3008                  * Disable the ARM (Bug fix)
3009                  *
3010                  */
3011                 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3012                 mdelay (1);
3013
3014                 /*
3015                  * Now hit the reset bit in the Diagnostic register
3016                  * (THE BIG HAMMER!) (Clears DRWE bit).
3017                  */
3018                 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3019                 hard_reset_done = 1;
3020                 dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
3021                                 ioc->name));
3022
3023                 /*
3024                  * Call each currently registered protocol IOC reset handler
3025                  * with pre-reset indication.
3026                  * NOTE: If we're doing _IOC_BRINGUP, there can be no
3027                  * MptResetHandlers[] registered yet.
3028                  */
3029                 {
3030                         int      ii;
3031                         int      r = 0;
3032
3033                         for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
3034                                 if (MptResetHandlers[ii]) {
3035                                         dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
3036                                                         ioc->name, ii));
3037                                         r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_PRE_RESET);
3038                                         if (ioc->alt_ioc) {
3039                                                 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3040                                                                 ioc->name, ioc->alt_ioc->name, ii));
3041                                                 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_PRE_RESET);
3042                                         }
3043                                 }
3044                         }
3045                         /* FIXME?  Examine results here? */
3046                 }
3047
3048                 if (ioc->cached_fw) {
3049                         /* If the DownloadBoot operation fails, the
3050                          * IOC will be left unusable. This is a fatal error
3051                          * case.  _diag_reset will return < 0
3052                          */
3053                         for (count = 0; count < 30; count ++) {
3054                                 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3055                                 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3056                                         break;
3057                                 }
3058
3059                                 /* wait 1 sec */
3060                                 if (sleepFlag == CAN_SLEEP) {
3061                                         ssleep(1);
3062                                 } else {
3063                                         mdelay (1000);
3064                                 }
3065                         }
3066                         if ((count = mpt_downloadboot(ioc, sleepFlag)) < 0) {
3067                                 printk(KERN_WARNING MYNAM
3068                                         ": firmware downloadboot failure (%d)!\n", count);
3069                         }
3070
3071                 } else {
3072                         /* Wait for FW to reload and for board
3073                          * to go to the READY state.
3074                          * Maximum wait is 60 seconds.
3075                          * If fail, no error will check again
3076                          * with calling program.
3077                          */
3078                         for (count = 0; count < 60; count ++) {
3079                                 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3080                                 doorbell &= MPI_IOC_STATE_MASK;
3081
3082                                 if (doorbell == MPI_IOC_STATE_READY) {
3083                                         break;
3084                                 }
3085
3086                                 /* wait 1 sec */
3087                                 if (sleepFlag == CAN_SLEEP) {
3088                                         msleep_interruptible (1000);
3089                                 } else {
3090                                         mdelay (1000);
3091                                 }
3092                         }
3093                 }
3094         }
3095
3096         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3097 #ifdef MPT_DEBUG
3098         if (ioc->alt_ioc)
3099                 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3100         dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3101                 ioc->name, diag0val, diag1val));
3102 #endif
3103
3104         /* Clear RESET_HISTORY bit!  Place board in the
3105          * diagnostic mode to update the diag register.
3106          */
3107         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3108         count = 0;
3109         while ((diag0val & MPI_DIAG_DRWE) == 0) {
3110                 /* Write magic sequence to WriteSequence register
3111                  * Loop until in diagnostic mode
3112                  */
3113                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3114                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3115                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3116                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3117                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3118                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3119
3120                 /* wait 100 msec */
3121                 if (sleepFlag == CAN_SLEEP) {
3122                         msleep_interruptible (100);
3123                 } else {
3124                         mdelay (100);
3125                 }
3126
3127                 count++;
3128                 if (count > 20) {
3129                         printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3130                                         ioc->name, diag0val);
3131                         break;
3132                 }
3133                 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3134         }
3135         diag0val &= ~MPI_DIAG_RESET_HISTORY;
3136         CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3137         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3138         if (diag0val & MPI_DIAG_RESET_HISTORY) {
3139                 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3140                                 ioc->name);
3141         }
3142
3143         /* Disable Diagnostic Mode
3144          */
3145         CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3146
3147         /* Check FW reload status flags.
3148          */
3149         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3150         if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3151                 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3152                                 ioc->name, diag0val);
3153                 return -3;
3154         }
3155
3156 #ifdef MPT_DEBUG
3157         if (ioc->alt_ioc)
3158                 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3159         dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3160                         ioc->name, diag0val, diag1val));
3161 #endif
3162
3163         /*
3164          * Reset flag that says we've enabled event notification
3165          */
3166         ioc->facts.EventState = 0;
3167
3168         if (ioc->alt_ioc)
3169                 ioc->alt_ioc->facts.EventState = 0;
3170
3171         return hard_reset_done;
3172 }
3173
3174 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3175 /*
3176  *      SendIocReset - Send IOCReset request to MPT adapter.
3177  *      @ioc: Pointer to MPT_ADAPTER structure
3178  *      @reset_type: reset type, expected values are
3179  *      %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3180  *
3181  *      Send IOCReset request to the MPT adapter.
3182  *
3183  *      Returns 0 for success, non-zero for failure.
3184  */
3185 static int
3186 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3187 {
3188         int r;
3189         u32 state;
3190         int cntdn, count;
3191
3192         drsprintk((KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
3193                         ioc->name, reset_type));
3194         CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3195         if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3196                 return r;
3197
3198         /* FW ACK'd request, wait for READY state
3199          */
3200         count = 0;
3201         cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15;    /* 15 seconds */
3202
3203         while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3204                 cntdn--;
3205                 count++;
3206                 if (!cntdn) {
3207                         if (sleepFlag != CAN_SLEEP)
3208                                 count *= 10;
3209
3210                         printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3211                                         ioc->name, (int)((count+5)/HZ));
3212                         return -ETIME;
3213                 }
3214
3215                 if (sleepFlag == CAN_SLEEP) {
3216                         msleep_interruptible(1);
3217                 } else {
3218                         mdelay (1);     /* 1 msec delay */
3219                 }
3220         }
3221
3222         /* TODO!
3223          *  Cleanup all event stuff for this IOC; re-issue EventNotification
3224          *  request if needed.
3225          */
3226         if (ioc->facts.Function)
3227                 ioc->facts.EventState = 0;
3228
3229         return 0;
3230 }
3231
3232 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3233 /*
3234  *      initChainBuffers - Allocate memory for and initialize
3235  *      chain buffers, chain buffer control arrays and spinlock.
3236  *      @hd: Pointer to MPT_SCSI_HOST structure
3237  *      @init: If set, initialize the spin lock.
3238  */
3239 static int
3240 initChainBuffers(MPT_ADAPTER *ioc)
3241 {
3242         u8              *mem;
3243         int             sz, ii, num_chain;
3244         int             scale, num_sge, numSGE;
3245
3246         /* ReqToChain size must equal the req_depth
3247          * index = req_idx
3248          */
3249         if (ioc->ReqToChain == NULL) {
3250                 sz = ioc->req_depth * sizeof(int);
3251                 mem = kmalloc(sz, GFP_ATOMIC);
3252                 if (mem == NULL)
3253                         return -1;
3254
3255                 ioc->ReqToChain = (int *) mem;
3256                 dinitprintk((KERN_INFO MYNAM ": %s ReqToChain alloc  @ %p, sz=%d bytes\n",
3257                                 ioc->name, mem, sz));
3258                 mem = kmalloc(sz, GFP_ATOMIC);
3259                 if (mem == NULL)
3260                         return -1;
3261
3262                 ioc->RequestNB = (int *) mem;
3263                 dinitprintk((KERN_INFO MYNAM ": %s RequestNB alloc  @ %p, sz=%d bytes\n",
3264                                 ioc->name, mem, sz));
3265         }
3266         for (ii = 0; ii < ioc->req_depth; ii++) {
3267                 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3268         }
3269
3270         /* ChainToChain size must equal the total number
3271          * of chain buffers to be allocated.
3272          * index = chain_idx
3273          *
3274          * Calculate the number of chain buffers needed(plus 1) per I/O
3275          * then multiply the the maximum number of simultaneous cmds
3276          *
3277          * num_sge = num sge in request frame + last chain buffer
3278          * scale = num sge per chain buffer if no chain element
3279          */
3280         scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3281         if (sizeof(dma_addr_t) == sizeof(u64))
3282                 num_sge =  scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3283         else
3284                 num_sge =  1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3285
3286         if (sizeof(dma_addr_t) == sizeof(u64)) {
3287                 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3288                         (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3289         } else {
3290                 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3291                         (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3292         }
3293         dinitprintk((KERN_INFO MYNAM ": %s num_sge=%d numSGE=%d\n",
3294                 ioc->name, num_sge, numSGE));
3295
3296         if ( numSGE > MPT_SCSI_SG_DEPTH )
3297                 numSGE = MPT_SCSI_SG_DEPTH;
3298
3299         num_chain = 1;
3300         while (numSGE - num_sge > 0) {
3301                 num_chain++;
3302                 num_sge += (scale - 1);
3303         }
3304         num_chain++;
3305
3306         dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
3307                 ioc->name, numSGE, num_sge, num_chain));
3308
3309         if (ioc->bus_type == SCSI)
3310                 num_chain *= MPT_SCSI_CAN_QUEUE;
3311         else
3312                 num_chain *= MPT_FC_CAN_QUEUE;
3313
3314         ioc->num_chain = num_chain;
3315
3316         sz = num_chain * sizeof(int);
3317         if (ioc->ChainToChain == NULL) {
3318                 mem = kmalloc(sz, GFP_ATOMIC);
3319                 if (mem == NULL)
3320                         return -1;
3321
3322                 ioc->ChainToChain = (int *) mem;
3323                 dinitprintk((KERN_INFO MYNAM ": %s ChainToChain alloc @ %p, sz=%d bytes\n",
3324                                 ioc->name, mem, sz));
3325         } else {
3326                 mem = (u8 *) ioc->ChainToChain;
3327         }
3328         memset(mem, 0xFF, sz);
3329         return num_chain;
3330 }
3331
3332 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3333 /*
3334  *      PrimeIocFifos - Initialize IOC request and reply FIFOs.
3335  *      @ioc: Pointer to MPT_ADAPTER structure
3336  *
3337  *      This routine allocates memory for the MPT reply and request frame
3338  *      pools (if necessary), and primes the IOC reply FIFO with
3339  *      reply frames.
3340  *
3341  *      Returns 0 for success, non-zero for failure.
3342  */
3343 static int
3344 PrimeIocFifos(MPT_ADAPTER *ioc)
3345 {
3346         MPT_FRAME_HDR *mf;
3347         unsigned long flags;
3348         dma_addr_t alloc_dma;
3349         u8 *mem;
3350         int i, reply_sz, sz, total_size, num_chain;
3351
3352         /*  Prime reply FIFO...  */
3353
3354         if (ioc->reply_frames == NULL) {
3355                 if ( (num_chain = initChainBuffers(ioc)) < 0)
3356                         return -1;
3357
3358                 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3359                 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3360                                 ioc->name, ioc->reply_sz, ioc->reply_depth));
3361                 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d[%x] bytes\n",
3362                                 ioc->name, reply_sz, reply_sz));
3363
3364                 sz = (ioc->req_sz * ioc->req_depth);
3365                 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3366                                 ioc->name, ioc->req_sz, ioc->req_depth));
3367                 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d[%x] bytes\n",
3368                                 ioc->name, sz, sz));
3369                 total_size += sz;
3370
3371                 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3372                 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3373                                 ioc->name, ioc->req_sz, num_chain));
3374                 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3375                                 ioc->name, sz, sz, num_chain));
3376
3377                 total_size += sz;
3378                 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3379                 if (mem == NULL) {
3380                         printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3381                                 ioc->name);
3382                         goto out_fail;
3383                 }
3384
3385                 dinitprintk((KERN_INFO MYNAM ": %s.Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3386                                 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3387
3388                 memset(mem, 0, total_size);
3389                 ioc->alloc_total += total_size;
3390                 ioc->alloc = mem;
3391                 ioc->alloc_dma = alloc_dma;
3392                 ioc->alloc_sz = total_size;
3393                 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3394                 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3395
3396                 alloc_dma += reply_sz;
3397                 mem += reply_sz;
3398
3399                 /*  Request FIFO - WE manage this!  */
3400
3401                 ioc->req_frames = (MPT_FRAME_HDR *) mem;
3402                 ioc->req_frames_dma = alloc_dma;
3403
3404                 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffers @ %p[%p]\n",
3405                                 ioc->name, mem, (void *)(ulong)alloc_dma));
3406
3407                 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3408
3409 #if defined(CONFIG_MTRR) && 0
3410                 /*
3411                  *  Enable Write Combining MTRR for IOC's memory region.
3412                  *  (at least as much as we can; "size and base must be
3413                  *  multiples of 4 kiB"
3414                  */
3415                 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
3416                                          sz,
3417                                          MTRR_TYPE_WRCOMB, 1);
3418                 dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
3419                                 ioc->name, ioc->req_frames_dma, sz));
3420 #endif
3421
3422                 for (i = 0; i < ioc->req_depth; i++) {
3423                         alloc_dma += ioc->req_sz;
3424                         mem += ioc->req_sz;
3425                 }
3426
3427                 ioc->ChainBuffer = mem;
3428                 ioc->ChainBufferDMA = alloc_dma;
3429
3430                 dinitprintk((KERN_INFO MYNAM " :%s.ChainBuffers @ %p(%p)\n",
3431                         ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
3432
3433                 /* Initialize the free chain Q.
3434                 */
3435
3436                 INIT_LIST_HEAD(&ioc->FreeChainQ);
3437
3438                 /* Post the chain buffers to the FreeChainQ.
3439                 */
3440                 mem = (u8 *)ioc->ChainBuffer;
3441                 for (i=0; i < num_chain; i++) {
3442                         mf = (MPT_FRAME_HDR *) mem;
3443                         list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
3444                         mem += ioc->req_sz;
3445                 }
3446
3447                 /* Initialize Request frames linked list
3448                  */
3449                 alloc_dma = ioc->req_frames_dma;
3450                 mem = (u8 *) ioc->req_frames;
3451
3452                 spin_lock_irqsave(&ioc->FreeQlock, flags);
3453                 INIT_LIST_HEAD(&ioc->FreeQ);
3454                 for (i = 0; i < ioc->req_depth; i++) {
3455                         mf = (MPT_FRAME_HDR *) mem;
3456
3457                         /*  Queue REQUESTs *internally*!  */
3458                         list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
3459
3460                         mem += ioc->req_sz;
3461                 }
3462                 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3463
3464                 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3465                 ioc->sense_buf_pool =
3466                         pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3467                 if (ioc->sense_buf_pool == NULL) {
3468                         printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
3469                                 ioc->name);
3470                         goto out_fail;
3471                 }
3472
3473                 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
3474                 ioc->alloc_total += sz;
3475                 dinitprintk((KERN_INFO MYNAM ": %s.SenseBuffers @ %p[%p]\n",
3476                         ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
3477
3478         }
3479
3480         /* Post Reply frames to FIFO
3481          */
3482         alloc_dma = ioc->alloc_dma;
3483         dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffers @ %p[%p]\n",
3484                 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3485
3486         for (i = 0; i < ioc->reply_depth; i++) {
3487                 /*  Write each address to the IOC!  */
3488                 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
3489                 alloc_dma += ioc->reply_sz;
3490         }
3491
3492         return 0;
3493
3494 out_fail:
3495         if (ioc->alloc != NULL) {
3496                 sz = ioc->alloc_sz;
3497                 pci_free_consistent(ioc->pcidev,
3498                                 sz,
3499                                 ioc->alloc, ioc->alloc_dma);
3500                 ioc->reply_frames = NULL;
3501                 ioc->req_frames = NULL;
3502                 ioc->alloc_total -= sz;
3503         }
3504         if (ioc->sense_buf_pool != NULL) {
3505                 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3506                 pci_free_consistent(ioc->pcidev,
3507                                 sz,
3508                                 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
3509                 ioc->sense_buf_pool = NULL;
3510         }
3511         return -1;
3512 }
3513
3514 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3515 /**
3516  *      mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3517  *      from IOC via doorbell handshake method.
3518  *      @ioc: Pointer to MPT_ADAPTER structure
3519  *      @reqBytes: Size of the request in bytes
3520  *      @req: Pointer to MPT request frame
3521  *      @replyBytes: Expected size of the reply in bytes
3522  *      @u16reply: Pointer to area where reply should be written
3523  *      @maxwait: Max wait time for a reply (in seconds)
3524  *      @sleepFlag: Specifies whether the process can sleep
3525  *
3526  *      NOTES: It is the callers responsibility to byte-swap fields in the
3527  *      request which are greater than 1 byte in size.  It is also the
3528  *  &nb