[SCSI] mptfusion: fix panic loading driver statically compiled
[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 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
190 /*
191  *      mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
192  *      @irq: irq number (not used)
193  *      @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
194  *      @r: pt_regs pointer (not used)
195  *
196  *      This routine is registered via the request_irq() kernel API call,
197  *      and handles all interrupts generated from a specific MPT adapter
198  *      (also referred to as a IO Controller or IOC).
199  *      This routine must clear the interrupt from the adapter and does
200  *      so by reading the reply FIFO.  Multiple replies may be processed
201  *      per single call to this routine; up to MPT_MAX_REPLIES_PER_ISR
202  *      which is currently set to 32 in mptbase.h.
203  *
204  *      This routine handles register-level access of the adapter but
205  *      dispatches (calls) a protocol-specific callback routine to handle
206  *      the protocol-specific details of the MPT request completion.
207  */
208 static irqreturn_t
209 mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
210 {
211         MPT_ADAPTER     *ioc;
212         MPT_FRAME_HDR   *mf;
213         MPT_FRAME_HDR   *mr;
214         u32              pa;
215         int              req_idx;
216         int              cb_idx;
217         int              type;
218         int              freeme;
219
220         ioc = (MPT_ADAPTER *)bus_id;
221
222         /*
223          *  Drain the reply FIFO!
224          *
225          * NOTES: I've seen up to 10 replies processed in this loop, so far...
226          * Update: I've seen up to 9182 replies processed in this loop! ??
227          * Update: Limit ourselves to processing max of N replies
228          *      (bottom of loop).
229          */
230         while (1) {
231
232                 if ((pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo)) == 0xFFFFFFFF)
233                         return IRQ_HANDLED;
234
235                 cb_idx = 0;
236                 freeme = 0;
237
238                 /*
239                  *  Check for non-TURBO reply!
240                  */
241                 if (pa & MPI_ADDRESS_REPLY_A_BIT) {
242                         u32 reply_dma_low;
243                         u16 ioc_stat;
244
245                         /* non-TURBO reply!  Hmmm, something may be up...
246                          *  Newest turbo reply mechanism; get address
247                          *  via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
248                          */
249
250                         /* Map DMA address of reply header to cpu address.
251                          * pa is 32 bits - but the dma address may be 32 or 64 bits
252                          * get offset based only only the low addresses
253                          */
254                         reply_dma_low = (pa = (pa << 1));
255                         mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
256                                          (reply_dma_low - ioc->reply_frames_low_dma));
257
258                         req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
259                         cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
260                         mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
261
262                         dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x\n",
263                                         ioc->name, mr, req_idx));
264                         DBG_DUMP_REPLY_FRAME(mr)
265
266                         /*  Check/log IOC log info
267                          */
268                         ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
269                         if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
270                                 u32      log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
271                                 if (ioc->bus_type == FC)
272                                         mpt_fc_log_info(ioc, log_info);
273                                 else if (ioc->bus_type == SCSI)
274                                         mpt_sp_log_info(ioc, log_info);
275                         }
276                         if (ioc_stat & MPI_IOCSTATUS_MASK) {
277                                 if (ioc->bus_type == SCSI)
278                                         mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
279                         }
280                 } else {
281                         /*
282                          *  Process turbo (context) reply...
283                          */
284                         dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n", ioc->name, pa));
285                         type = (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT);
286                         if (type == MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET) {
287                                 cb_idx = mpt_stm_index;
288                                 mf = NULL;
289                                 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
290                         } else if (type == MPI_CONTEXT_REPLY_TYPE_LAN) {
291                                 cb_idx = mpt_lan_index;
292                                  /*  Blind set of mf to NULL here was fatal
293                                  *  after lan_reply says "freeme"
294                                  *  Fix sort of combined with an optimization here;
295                                  *  added explicit check for case where lan_reply
296                                  *  was just returning 1 and doing nothing else.
297                                  *  For this case skip the callback, but set up
298                                  *  proper mf value first here:-)
299                                  */
300                                 if ((pa & 0x58000000) == 0x58000000) {
301                                         req_idx = pa & 0x0000FFFF;
302                                         mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
303                                         freeme = 1;
304                                         /*
305                                          *  IMPORTANT!  Invalidate the callback!
306                                          */
307                                         cb_idx = 0;
308                                 } else {
309                                         mf = NULL;
310                                 }
311                                 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
312                         } else {
313                                 req_idx = pa & 0x0000FFFF;
314                                 cb_idx = (pa & 0x00FF0000) >> 16;
315                                 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
316                                 mr = NULL;
317                         }
318                         pa = 0;                                 /* No reply flush! */
319                 }
320
321 #ifdef MPT_DEBUG_IRQ
322                 if (ioc->bus_type == SCSI) {
323                         /* Verify mf, mr are reasonable.
324                          */
325                         if ((mf) && ((mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))
326                                 || (mf < ioc->req_frames)) ) {
327                                 printk(MYIOC_s_WARN_FMT
328                                         "mpt_interrupt: Invalid mf (%p) req_idx (%d)!\n", ioc->name, (void *)mf, req_idx);
329                                 cb_idx = 0;
330                                 pa = 0;
331                                 freeme = 0;
332                         }
333                         if ((pa) && (mr) && ((mr >= MPT_INDEX_2_RFPTR(ioc, ioc->req_depth))
334                                 || (mr < ioc->reply_frames)) ) {
335                                 printk(MYIOC_s_WARN_FMT
336                                         "mpt_interrupt: Invalid rf (%p)!\n", ioc->name, (void *)mr);
337                                 cb_idx = 0;
338                                 pa = 0;
339                                 freeme = 0;
340                         }
341                         if (cb_idx > (MPT_MAX_PROTOCOL_DRIVERS-1)) {
342                                 printk(MYIOC_s_WARN_FMT
343                                         "mpt_interrupt: Invalid cb_idx (%d)!\n", ioc->name, cb_idx);
344                                 cb_idx = 0;
345                                 pa = 0;
346                                 freeme = 0;
347                         }
348                 }
349 #endif
350
351                 /*  Check for (valid) IO callback!  */
352                 if (cb_idx) {
353                         /*  Do the callback!  */
354                         freeme = (*(MptCallbacks[cb_idx]))(ioc, mf, mr);
355                 }
356
357                 if (pa) {
358                         /*  Flush (non-TURBO) reply with a WRITE!  */
359                         CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
360                 }
361
362                 if (freeme) {
363                         /*  Put Request back on FreeQ!  */
364                         mpt_free_msg_frame(ioc, mf);
365                 }
366
367                 mb();
368         }       /* drain reply FIFO */
369
370         return IRQ_HANDLED;
371 }
372
373 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
374 /*
375  *      mpt_base_reply - MPT base driver's callback routine; all base driver
376  *      "internal" request/reply processing is routed here.
377  *      Currently used for EventNotification and EventAck handling.
378  *      @ioc: Pointer to MPT_ADAPTER structure
379  *      @mf: Pointer to original MPT request frame
380  *      @reply: Pointer to MPT reply frame (NULL if TurboReply)
381  *
382         *       Returns 1 indicating original alloc'd request frame ptr
383  *      should be freed, or 0 if it shouldn't.
384  */
385 static int
386 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
387 {
388         int freereq = 1;
389         u8 func;
390
391         dprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name));
392
393         if ((mf == NULL) ||
394             (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
395                 printk(MYIOC_s_ERR_FMT "NULL or BAD request frame ptr! (=%p)\n",
396                                 ioc->name, (void *)mf);
397                 return 1;
398         }
399
400         if (reply == NULL) {
401                 dprintk((MYIOC_s_ERR_FMT "Unexpected NULL Event (turbo?) reply!\n",
402                                 ioc->name));
403                 return 1;
404         }
405
406         if (!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
407                 dmfprintk((KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf));
408                 DBG_DUMP_REQUEST_FRAME_HDR(mf)
409         }
410
411         func = reply->u.hdr.Function;
412         dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n",
413                         ioc->name, func));
414
415         if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
416                 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
417                 int evHandlers = 0;
418                 int results;
419
420                 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
421                 if (results != evHandlers) {
422                         /* CHECKME! Any special handling needed here? */
423                         devtprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
424                                         ioc->name, evHandlers, results));
425                 }
426
427                 /*
428                  *      Hmmm...  It seems that EventNotificationReply is an exception
429                  *      to the rule of one reply per request.
430                  */
431                 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
432                         freereq = 0;
433
434 #ifdef CONFIG_PROC_FS
435 //              LogEvent(ioc, pEvReply);
436 #endif
437
438         } else if (func == MPI_FUNCTION_EVENT_ACK) {
439                 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
440                                 ioc->name));
441         } else if (func == MPI_FUNCTION_CONFIG ||
442                    func == MPI_FUNCTION_TOOLBOX) {
443                 CONFIGPARMS *pCfg;
444                 unsigned long flags;
445
446                 dcprintk((MYIOC_s_INFO_FMT "config_complete (mf=%p,mr=%p)\n",
447                                 ioc->name, mf, reply));
448
449                 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
450
451                 if (pCfg) {
452                         /* disable timer and remove from linked list */
453                         del_timer(&pCfg->timer);
454
455                         spin_lock_irqsave(&ioc->FreeQlock, flags);
456                         list_del(&pCfg->linkage);
457                         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
458
459                         /*
460                          *      If IOC Status is SUCCESS, save the header
461                          *      and set the status code to GOOD.
462                          */
463                         pCfg->status = MPT_CONFIG_ERROR;
464                         if (reply) {
465                                 ConfigReply_t   *pReply = (ConfigReply_t *)reply;
466                                 u16              status;
467
468                                 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
469                                 dcprintk((KERN_NOTICE "  IOCStatus=%04xh, IOCLogInfo=%08xh\n",
470                                      status, le32_to_cpu(pReply->IOCLogInfo)));
471
472                                 pCfg->status = status;
473                                 if (status == MPI_IOCSTATUS_SUCCESS) {
474                                         pCfg->hdr->PageVersion = pReply->Header.PageVersion;
475                                         pCfg->hdr->PageLength = pReply->Header.PageLength;
476                                         pCfg->hdr->PageNumber = pReply->Header.PageNumber;
477                                         pCfg->hdr->PageType = pReply->Header.PageType;
478                                 }
479                         }
480
481                         /*
482                          *      Wake up the original calling thread
483                          */
484                         pCfg->wait_done = 1;
485                         wake_up(&mpt_waitq);
486                 }
487         } else {
488                 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
489                                 ioc->name, func);
490         }
491
492         /*
493          *      Conditionally tell caller to free the original
494          *      EventNotification/EventAck/unexpected request frame!
495          */
496         return freereq;
497 }
498
499 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
500 /**
501  *      mpt_register - Register protocol-specific main callback handler.
502  *      @cbfunc: callback function pointer
503  *      @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
504  *
505  *      This routine is called by a protocol-specific driver (SCSI host,
506  *      LAN, SCSI target) to register it's reply callback routine.  Each
507  *      protocol-specific driver must do this before it will be able to
508  *      use any IOC resources, such as obtaining request frames.
509  *
510  *      NOTES: The SCSI protocol driver currently calls this routine thrice
511  *      in order to register separate callbacks; one for "normal" SCSI IO;
512  *      one for MptScsiTaskMgmt requests; one for Scan/DV requests.
513  *
514  *      Returns a positive integer valued "handle" in the
515  *      range (and S.O.D. order) {N,...,7,6,5,...,1} if successful.
516  *      Any non-positive return value (including zero!) should be considered
517  *      an error by the caller.
518  */
519 int
520 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
521 {
522         int i;
523
524         last_drv_idx = -1;
525
526         /*
527          *  Search for empty callback slot in this order: {N,...,7,6,5,...,1}
528          *  (slot/handle 0 is reserved!)
529          */
530         for (i = MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
531                 if (MptCallbacks[i] == NULL) {
532                         MptCallbacks[i] = cbfunc;
533                         MptDriverClass[i] = dclass;
534                         MptEvHandlers[i] = NULL;
535                         last_drv_idx = i;
536                         break;
537                 }
538         }
539
540         return last_drv_idx;
541 }
542
543 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
544 /**
545  *      mpt_deregister - Deregister a protocol drivers resources.
546  *      @cb_idx: previously registered callback handle
547  *
548  *      Each protocol-specific driver should call this routine when it's
549  *      module is unloaded.
550  */
551 void
552 mpt_deregister(int cb_idx)
553 {
554         if ((cb_idx >= 0) && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
555                 MptCallbacks[cb_idx] = NULL;
556                 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
557                 MptEvHandlers[cb_idx] = NULL;
558
559                 last_drv_idx++;
560         }
561 }
562
563 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
564 /**
565  *      mpt_event_register - Register protocol-specific event callback
566  *      handler.
567  *      @cb_idx: previously registered (via mpt_register) callback handle
568  *      @ev_cbfunc: callback function
569  *
570  *      This routine can be called by one or more protocol-specific drivers
571  *      if/when they choose to be notified of MPT events.
572  *
573  *      Returns 0 for success.
574  */
575 int
576 mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc)
577 {
578         if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
579                 return -1;
580
581         MptEvHandlers[cb_idx] = ev_cbfunc;
582         return 0;
583 }
584
585 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
586 /**
587  *      mpt_event_deregister - Deregister protocol-specific event callback
588  *      handler.
589  *      @cb_idx: previously registered callback handle
590  *
591  *      Each protocol-specific driver should call this routine
592  *      when it does not (or can no longer) handle events,
593  *      or when it's module is unloaded.
594  */
595 void
596 mpt_event_deregister(int cb_idx)
597 {
598         if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
599                 return;
600
601         MptEvHandlers[cb_idx] = NULL;
602 }
603
604 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
605 /**
606  *      mpt_reset_register - Register protocol-specific IOC reset handler.
607  *      @cb_idx: previously registered (via mpt_register) callback handle
608  *      @reset_func: reset function
609  *
610  *      This routine can be called by one or more protocol-specific drivers
611  *      if/when they choose to be notified of IOC resets.
612  *
613  *      Returns 0 for success.
614  */
615 int
616 mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func)
617 {
618         if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
619                 return -1;
620
621         MptResetHandlers[cb_idx] = reset_func;
622         return 0;
623 }
624
625 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
626 /**
627  *      mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
628  *      @cb_idx: previously registered callback handle
629  *
630  *      Each protocol-specific driver should call this routine
631  *      when it does not (or can no longer) handle IOC reset handling,
632  *      or when it's module is unloaded.
633  */
634 void
635 mpt_reset_deregister(int cb_idx)
636 {
637         if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
638                 return;
639
640         MptResetHandlers[cb_idx] = NULL;
641 }
642
643 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
644 /**
645  *      mpt_device_driver_register - Register device driver hooks
646  */
647 int
648 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
649 {
650         MPT_ADAPTER     *ioc;
651
652         if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) {
653                 return -EINVAL;
654         }
655
656         MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
657
658         /* call per pci device probe entry point */
659         list_for_each_entry(ioc, &ioc_list, list) {
660                 if(dd_cbfunc->probe) {
661                         dd_cbfunc->probe(ioc->pcidev,
662                           ioc->pcidev->driver->id_table);
663                 }
664          }
665
666         return 0;
667 }
668
669 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
670 /**
671  *      mpt_device_driver_deregister - DeRegister device driver hooks
672  */
673 void
674 mpt_device_driver_deregister(int cb_idx)
675 {
676         struct mpt_pci_driver *dd_cbfunc;
677         MPT_ADAPTER     *ioc;
678
679         if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
680                 return;
681
682         dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
683
684         list_for_each_entry(ioc, &ioc_list, list) {
685                 if (dd_cbfunc->remove)
686                         dd_cbfunc->remove(ioc->pcidev);
687         }
688         
689         MptDeviceDriverHandlers[cb_idx] = NULL;
690 }
691
692
693 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
694 /**
695  *      mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
696  *      allocated per MPT adapter.
697  *      @handle: Handle of registered MPT protocol driver
698  *      @ioc: Pointer to MPT adapter structure
699  *
700  *      Returns pointer to a MPT request frame or %NULL if none are available
701  *      or IOC is not active.
702  */
703 MPT_FRAME_HDR*
704 mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc)
705 {
706         MPT_FRAME_HDR *mf;
707         unsigned long flags;
708         u16      req_idx;       /* Request index */
709
710         /* validate handle and ioc identifier */
711
712 #ifdef MFCNT
713         if (!ioc->active)
714                 printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n");
715 #endif
716
717         /* If interrupts are not attached, do not return a request frame */
718         if (!ioc->active)
719                 return NULL;
720
721         spin_lock_irqsave(&ioc->FreeQlock, flags);
722         if (!list_empty(&ioc->FreeQ)) {
723                 int req_offset;
724
725                 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
726                                 u.frame.linkage.list);
727                 list_del(&mf->u.frame.linkage.list);
728                 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;  /* byte */
729                 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
730                                                                 /* u16! */
731                 req_idx = req_offset / ioc->req_sz;
732                 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
733                 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
734                 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; /* Default, will be changed if necessary in SG generation */
735 #ifdef MFCNT
736                 ioc->mfcnt++;
737 #endif
738         }
739         else
740                 mf = NULL;
741         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
742
743 #ifdef MFCNT
744         if (mf == NULL)
745                 printk(KERN_WARNING "IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", ioc->mfcnt, ioc->req_depth);
746         mfcounter++;
747         if (mfcounter == PRINT_MF_COUNT)
748                 printk(KERN_INFO "MF Count 0x%x Max 0x%x \n", ioc->mfcnt, ioc->req_depth);
749 #endif
750
751         dmfprintk((KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",
752                         ioc->name, handle, ioc->id, mf));
753         return mf;
754 }
755
756 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
757 /**
758  *      mpt_put_msg_frame - Send a protocol specific MPT request frame
759  *      to a IOC.
760  *      @handle: Handle of registered MPT protocol driver
761  *      @ioc: Pointer to MPT adapter structure
762  *      @mf: Pointer to MPT request frame
763  *
764  *      This routine posts a MPT request frame to the request post FIFO of a
765  *      specific MPT adapter.
766  */
767 void
768 mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
769 {
770         u32 mf_dma_addr;
771         int req_offset;
772         u16      req_idx;       /* Request index */
773
774         /* ensure values are reset properly! */
775         mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;          /* byte */
776         req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
777                                                                 /* u16! */
778         req_idx = req_offset / ioc->req_sz;
779         mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
780         mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
781
782 #ifdef MPT_DEBUG_MSG_FRAME
783         {
784                 u32     *m = mf->u.frame.hwhdr.__hdr;
785                 int      ii, n;
786
787                 printk(KERN_INFO MYNAM ": %s: About to Put msg frame @ %p:\n" KERN_INFO " ",
788                                 ioc->name, m);
789                 n = ioc->req_sz/4 - 1;
790                 while (m[n] == 0)
791                         n--;
792                 for (ii=0; ii<=n; ii++) {
793                         if (ii && ((ii%8)==0))
794                                 printk("\n" KERN_INFO " ");
795                         printk(" %08x", le32_to_cpu(m[ii]));
796                 }
797                 printk("\n");
798         }
799 #endif
800
801         mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];  
802         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]));
803         CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
804 }
805
806 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
807 /**
808  *      mpt_free_msg_frame - Place MPT request frame back on FreeQ.
809  *      @handle: Handle of registered MPT protocol driver
810  *      @ioc: Pointer to MPT adapter structure
811  *      @mf: Pointer to MPT request frame
812  *
813  *      This routine places a MPT request frame back on the MPT adapter's
814  *      FreeQ.
815  */
816 void
817 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
818 {
819         unsigned long flags;
820
821         /*  Put Request back on FreeQ!  */
822         spin_lock_irqsave(&ioc->FreeQlock, flags);
823         list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
824 #ifdef MFCNT
825         ioc->mfcnt--;
826 #endif
827         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
828 }
829
830 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
831 /**
832  *      mpt_add_sge - Place a simple SGE at address pAddr.
833  *      @pAddr: virtual address for SGE
834  *      @flagslength: SGE flags and data transfer length
835  *      @dma_addr: Physical address
836  *
837  *      This routine places a MPT request frame back on the MPT adapter's
838  *      FreeQ.
839  */
840 void
841 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
842 {
843         if (sizeof(dma_addr_t) == sizeof(u64)) {
844                 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
845                 u32 tmp = dma_addr & 0xFFFFFFFF;
846
847                 pSge->FlagsLength = cpu_to_le32(flagslength);
848                 pSge->Address.Low = cpu_to_le32(tmp);
849                 tmp = (u32) ((u64)dma_addr >> 32);
850                 pSge->Address.High = cpu_to_le32(tmp);
851
852         } else {
853                 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
854                 pSge->FlagsLength = cpu_to_le32(flagslength);
855                 pSge->Address = cpu_to_le32(dma_addr);
856         }
857 }
858
859 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
860 /**
861  *      mpt_send_handshake_request - Send MPT request via doorbell
862  *      handshake method.
863  *      @handle: Handle of registered MPT protocol driver
864  *      @ioc: Pointer to MPT adapter structure
865  *      @reqBytes: Size of the request in bytes
866  *      @req: Pointer to MPT request frame
867  *      @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
868  *
869  *      This routine is used exclusively to send MptScsiTaskMgmt
870  *      requests since they are required to be sent via doorbell handshake.
871  *
872  *      NOTE: It is the callers responsibility to byte-swap fields in the
873  *      request which are greater than 1 byte in size.
874  *
875  *      Returns 0 for success, non-zero for failure.
876  */
877 int
878 mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
879 {
880         int              r = 0;
881         u8      *req_as_bytes;
882         int      ii;
883
884         /* State is known to be good upon entering
885          * this function so issue the bus reset
886          * request.
887          */
888
889         /*
890          * Emulate what mpt_put_msg_frame() does /wrt to sanity
891          * setting cb_idx/req_idx.  But ONLY if this request
892          * is in proper (pre-alloc'd) request buffer range...
893          */
894         ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
895         if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
896                 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
897                 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
898                 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
899         }
900
901         /* Make sure there are no doorbells */
902         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
903         
904         CHIPREG_WRITE32(&ioc->chip->Doorbell,
905                         ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
906                          ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
907
908         /* Wait for IOC doorbell int */
909         if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
910                 return ii;
911         }
912
913         /* Read doorbell and check for active bit */
914         if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
915                 return -5;
916
917         dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
918                         ioc->name, ii));
919
920         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
921
922         if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
923                 return -2;
924         }
925                 
926         /* Send request via doorbell handshake */
927         req_as_bytes = (u8 *) req;
928         for (ii = 0; ii < reqBytes/4; ii++) {
929                 u32 word;
930
931                 word = ((req_as_bytes[(ii*4) + 0] <<  0) |
932                         (req_as_bytes[(ii*4) + 1] <<  8) |
933                         (req_as_bytes[(ii*4) + 2] << 16) |
934                         (req_as_bytes[(ii*4) + 3] << 24));
935                 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
936                 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
937                         r = -3;
938                         break;
939                 }
940         }
941
942         if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
943                 r = 0;
944         else
945                 r = -4;
946
947         /* Make sure there are no doorbells */
948         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
949         
950         return r;
951 }
952
953 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
954 /**
955  *      mpt_verify_adapter - Given a unique IOC identifier, set pointer to
956  *      the associated MPT adapter structure.
957  *      @iocid: IOC unique identifier (integer)
958  *      @iocpp: Pointer to pointer to IOC adapter
959  *
960  *      Returns iocid and sets iocpp.
961  */
962 int
963 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
964 {
965         MPT_ADAPTER *ioc;
966
967         list_for_each_entry(ioc,&ioc_list,list) {
968                 if (ioc->id == iocid) {
969                         *iocpp =ioc;
970                         return iocid;
971                 } 
972         }
973         
974         *iocpp = NULL;
975         return -1;
976 }
977
978 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
979 /*
980  *      mpt_attach - Install a PCI intelligent MPT adapter.
981  *      @pdev: Pointer to pci_dev structure
982  *
983  *      This routine performs all the steps necessary to bring the IOC of
984  *      a MPT adapter to a OPERATIONAL state.  This includes registering
985  *      memory regions, registering the interrupt, and allocating request
986  *      and reply memory pools.
987  *
988  *      This routine also pre-fetches the LAN MAC address of a Fibre Channel
989  *      MPT adapter.
990  *
991  *      Returns 0 for success, non-zero for failure.
992  *
993  *      TODO: Add support for polled controllers
994  */
995 int
996 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
997 {
998         MPT_ADAPTER     *ioc;
999         u8              __iomem *mem;
1000         unsigned long    mem_phys;
1001         unsigned long    port;
1002         u32              msize;
1003         u32              psize;
1004         int              ii;
1005         int              r = -ENODEV;
1006         u8               revision;
1007         u8               pcixcmd;
1008         static int       mpt_ids = 0;
1009 #ifdef CONFIG_PROC_FS
1010         struct proc_dir_entry *dent, *ent;
1011 #endif
1012
1013         if (pci_enable_device(pdev))
1014                 return r;
1015         
1016         dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1017         
1018         if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1019                 dprintk((KERN_INFO MYNAM
1020                         ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1021         } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1022                 printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1023                 return r;
1024         }
1025
1026         if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
1027                 dprintk((KERN_INFO MYNAM
1028                         ": Using 64 bit consistent mask\n"));
1029         else
1030                 dprintk((KERN_INFO MYNAM
1031                         ": Not using 64 bit consistent mask\n"));
1032
1033         ioc = kmalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1034         if (ioc == NULL) {
1035                 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1036                 return -ENOMEM;
1037         }
1038         memset(ioc, 0, sizeof(MPT_ADAPTER));
1039         ioc->alloc_total = sizeof(MPT_ADAPTER);
1040         ioc->req_sz = MPT_DEFAULT_FRAME_SIZE;           /* avoid div by zero! */
1041         ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1042         
1043         ioc->pcidev = pdev;
1044         ioc->diagPending = 0;
1045         spin_lock_init(&ioc->diagLock);
1046
1047         /* Initialize the event logging.
1048          */
1049         ioc->eventTypes = 0;    /* None */
1050         ioc->eventContext = 0;
1051         ioc->eventLogSize = 0;
1052         ioc->events = NULL;
1053
1054 #ifdef MFCNT
1055         ioc->mfcnt = 0;
1056 #endif
1057
1058         ioc->cached_fw = NULL;
1059
1060         /* Initilize SCSI Config Data structure
1061          */
1062         memset(&ioc->spi_data, 0, sizeof(ScsiCfgData));
1063
1064         /* Initialize the running configQ head.
1065          */
1066         INIT_LIST_HEAD(&ioc->configQ);
1067
1068         /* Find lookup slot. */
1069         INIT_LIST_HEAD(&ioc->list);
1070         ioc->id = mpt_ids++;
1071         
1072         mem_phys = msize = 0;
1073         port = psize = 0;
1074         for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1075                 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1076                         /* Get I/O space! */
1077                         port = pci_resource_start(pdev, ii);
1078                         psize = pci_resource_len(pdev,ii);
1079                 } else {
1080                         /* Get memmap */
1081                         mem_phys = pci_resource_start(pdev, ii);
1082                         msize = pci_resource_len(pdev,ii);
1083                         break;
1084                 }
1085         }
1086         ioc->mem_size = msize;
1087
1088         if (ii == DEVICE_COUNT_RESOURCE) {
1089                 printk(KERN_ERR MYNAM ": ERROR - MPT adapter has no memory regions defined!\n");
1090                 kfree(ioc);
1091                 return -EINVAL;
1092         }
1093
1094         dinitprintk((KERN_INFO MYNAM ": MPT adapter @ %lx, msize=%dd bytes\n", mem_phys, msize));
1095         dinitprintk((KERN_INFO MYNAM ": (port i/o @ %lx, psize=%dd bytes)\n", port, psize));
1096
1097         mem = NULL;
1098         /* Get logical ptr for PciMem0 space */
1099         /*mem = ioremap(mem_phys, msize);*/
1100         mem = ioremap(mem_phys, 0x100);
1101         if (mem == NULL) {
1102                 printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1103                 kfree(ioc);
1104                 return -EINVAL;
1105         }
1106         ioc->memmap = mem;
1107         dinitprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1108
1109         dinitprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1110                         &ioc->facts, &ioc->pfacts[0]));
1111
1112         ioc->mem_phys = mem_phys;
1113         ioc->chip = (SYSIF_REGS __iomem *)mem;
1114
1115         /* Save Port IO values in case we need to do downloadboot */
1116         {
1117                 u8 *pmem = (u8*)port;
1118                 ioc->pio_mem_phys = port;
1119                 ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1120         }
1121
1122         if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC909) {
1123                 ioc->prod_name = "LSIFC909";
1124                 ioc->bus_type = FC;
1125         }
1126         if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
1127                 ioc->prod_name = "LSIFC929";
1128                 ioc->bus_type = FC;
1129         }
1130         else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) {
1131                 ioc->prod_name = "LSIFC919";
1132                 ioc->bus_type = FC;
1133         }
1134         else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) {
1135                 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1136                 ioc->bus_type = FC;
1137                 if (revision < XL_929) {
1138                         ioc->prod_name = "LSIFC929X";
1139                         /* 929X Chip Fix. Set Split transactions level
1140                         * for PCIX. Set MOST bits to zero.
1141                         */
1142                         pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1143                         pcixcmd &= 0x8F;
1144                         pci_write_config_byte(pdev, 0x6a, pcixcmd);
1145                 } else {
1146                         ioc->prod_name = "LSIFC929XL";
1147                         /* 929XL Chip Fix. Set MMRBC to 0x08.
1148                         */
1149                         pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1150                         pcixcmd |= 0x08;
1151                         pci_write_config_byte(pdev, 0x6a, pcixcmd);
1152                 }
1153         }
1154         else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) {
1155                 ioc->prod_name = "LSIFC919X";
1156                 ioc->bus_type = FC;
1157                 /* 919X Chip Fix. Set Split transactions level
1158                  * for PCIX. Set MOST bits to zero.
1159                  */
1160                 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1161                 pcixcmd &= 0x8F;
1162                 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1163         }
1164         else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
1165                 ioc->prod_name = "LSI53C1030";
1166                 ioc->bus_type = SCSI;
1167                 /* 1030 Chip Fix. Disable Split transactions
1168                  * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1169                  */
1170                 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1171                 if (revision < C0_1030) {
1172                         pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1173                         pcixcmd &= 0x8F;
1174                         pci_write_config_byte(pdev, 0x6a, pcixcmd);
1175                 }
1176         }
1177         else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
1178                 ioc->prod_name = "LSI53C1035";
1179                 ioc->bus_type = SCSI;
1180         }
1181
1182         sprintf(ioc->name, "ioc%d", ioc->id);
1183
1184         spin_lock_init(&ioc->FreeQlock);
1185
1186         /* Disable all! */
1187         CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1188         ioc->active = 0;
1189         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1190
1191         /* Set lookup ptr. */
1192         list_add_tail(&ioc->list, &ioc_list);
1193
1194         ioc->pci_irq = -1;
1195         if (pdev->irq) {
1196                 r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc);
1197
1198                 if (r < 0) {
1199 #ifndef __sparc__
1200                         printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %d!\n",
1201                                         ioc->name, pdev->irq);
1202 #else
1203                         printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %s!\n",
1204                                         ioc->name, __irq_itoa(pdev->irq));
1205 #endif
1206                         list_del(&ioc->list);
1207                         iounmap(mem);
1208                         kfree(ioc);
1209                         return -EBUSY;
1210                 }
1211
1212                 ioc->pci_irq = pdev->irq;
1213
1214                 pci_set_master(pdev);                   /* ?? */
1215                 pci_set_drvdata(pdev, ioc);
1216
1217 #ifndef __sparc__
1218                 dprintk((KERN_INFO MYNAM ": %s installed at interrupt %d\n", ioc->name, pdev->irq));
1219 #else
1220                 dprintk((KERN_INFO MYNAM ": %s installed at interrupt %s\n", ioc->name, __irq_itoa(pdev->irq)));
1221 #endif
1222         }
1223
1224         /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1225          */
1226         mpt_detect_bound_ports(ioc, pdev);
1227
1228         if ((r = mpt_do_ioc_recovery(ioc,
1229           MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0) {
1230                 printk(KERN_WARNING MYNAM
1231                   ": WARNING - %s did not initialize properly! (%d)\n",
1232                   ioc->name, r);
1233
1234                 list_del(&ioc->list);
1235                 free_irq(ioc->pci_irq, ioc);
1236                 iounmap(mem);
1237                 kfree(ioc);
1238                 pci_set_drvdata(pdev, NULL);
1239                 return r;
1240         }
1241
1242         /* call per device driver probe entry point */
1243         for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1244                 if(MptDeviceDriverHandlers[ii] &&
1245                   MptDeviceDriverHandlers[ii]->probe) {
1246                         MptDeviceDriverHandlers[ii]->probe(pdev,id);
1247                 }
1248         }
1249
1250 #ifdef CONFIG_PROC_FS
1251         /*
1252          *  Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1253          */
1254         dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1255         if (dent) {
1256                 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1257                 if (ent) {
1258                         ent->read_proc = procmpt_iocinfo_read;
1259                         ent->data = ioc;
1260                 }
1261                 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1262                 if (ent) {
1263                         ent->read_proc = procmpt_summary_read;
1264                         ent->data = ioc;
1265                 }
1266         }
1267 #endif
1268
1269         return 0;
1270 }
1271
1272 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1273 /*
1274  *      mpt_detach - Remove a PCI intelligent MPT adapter.
1275  *      @pdev: Pointer to pci_dev structure
1276  *
1277  */
1278
1279 void
1280 mpt_detach(struct pci_dev *pdev)
1281 {
1282         MPT_ADAPTER     *ioc = pci_get_drvdata(pdev);
1283         char pname[32];
1284         int ii;
1285
1286         sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1287         remove_proc_entry(pname, NULL);
1288         sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1289         remove_proc_entry(pname, NULL);
1290         sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1291         remove_proc_entry(pname, NULL);
1292         
1293         /* call per device driver remove entry point */
1294         for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1295                 if(MptDeviceDriverHandlers[ii] &&
1296                   MptDeviceDriverHandlers[ii]->remove) {
1297                         MptDeviceDriverHandlers[ii]->remove(pdev);
1298                 }
1299         }
1300         
1301         /* Disable interrupts! */
1302         CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1303
1304         ioc->active = 0;
1305         synchronize_irq(pdev->irq);
1306
1307         /* Clear any lingering interrupt */
1308         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1309
1310         CHIPREG_READ32(&ioc->chip->IntStatus);
1311
1312         mpt_adapter_dispose(ioc);
1313
1314         pci_set_drvdata(pdev, NULL);
1315 }
1316
1317 /**************************************************************************
1318  * Power Management
1319  */
1320 #ifdef CONFIG_PM
1321 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1322 /*
1323  *      mpt_suspend - Fusion MPT base driver suspend routine.
1324  *
1325  *
1326  */
1327 int
1328 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1329 {
1330         u32 device_state;
1331         MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1332
1333         switch(state)
1334         {
1335                 case 1: /* S1 */
1336                         device_state=1; /* D1 */;
1337                         break;
1338                 case 3: /* S3 */
1339                 case 4: /* S4 */
1340                         device_state=3; /* D3 */;
1341                         break;
1342                 default:
1343                         return -EAGAIN /*FIXME*/;
1344                         break;
1345         }
1346
1347         printk(MYIOC_s_INFO_FMT
1348         "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1349                 ioc->name, pdev, pci_name(pdev), device_state);
1350
1351         pci_save_state(pdev);
1352
1353         /* put ioc into READY_STATE */
1354         if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1355                 printk(MYIOC_s_ERR_FMT
1356                 "pci-suspend:  IOC msg unit reset failed!\n", ioc->name);
1357         }
1358
1359         /* disable interrupts */
1360         CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1361         ioc->active = 0;
1362
1363         /* Clear any lingering interrupt */
1364         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1365
1366         pci_disable_device(pdev);
1367         pci_set_power_state(pdev, device_state);
1368
1369         return 0;
1370 }
1371
1372 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1373 /*
1374  *      mpt_resume - Fusion MPT base driver resume routine.
1375  *
1376  *
1377  */
1378 int
1379 mpt_resume(struct pci_dev *pdev)
1380 {
1381         MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1382         u32 device_state = pdev->current_state;
1383         int recovery_state;
1384         int ii;
1385         
1386         printk(MYIOC_s_INFO_FMT
1387         "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1388                 ioc->name, pdev, pci_name(pdev), device_state);
1389
1390         pci_set_power_state(pdev, 0);
1391         pci_restore_state(pdev);
1392         pci_enable_device(pdev);
1393
1394         /* enable interrupts */
1395         CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
1396         ioc->active = 1;
1397
1398         /* F/W not running */
1399         if(!CHIPREG_READ32(&ioc->chip->Doorbell)) {
1400                 /* enable domain validation flags */
1401                 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
1402                         ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_NEED_DV;
1403                 }
1404         }
1405
1406         printk(MYIOC_s_INFO_FMT
1407                 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1408                 ioc->name,
1409                 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1410                 CHIPREG_READ32(&ioc->chip->Doorbell));
1411
1412         /* bring ioc to operational state */
1413         if ((recovery_state = mpt_do_ioc_recovery(ioc,
1414             MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1415                 printk(MYIOC_s_INFO_FMT
1416                         "pci-resume: Cannot recover, error:[%x]\n",
1417                         ioc->name, recovery_state);
1418         } else {
1419                 printk(MYIOC_s_INFO_FMT
1420                         "pci-resume: success\n", ioc->name);
1421         }
1422
1423         return 0;
1424 }
1425 #endif
1426
1427 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1428 /*
1429  *      mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1430  *      @ioc: Pointer to MPT adapter structure
1431  *      @reason: Event word / reason
1432  *      @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1433  *
1434  *      This routine performs all the steps necessary to bring the IOC
1435  *      to a OPERATIONAL state.
1436  *
1437  *      This routine also pre-fetches the LAN MAC address of a Fibre Channel
1438  *      MPT adapter.
1439  *
1440  *      Returns:
1441  *               0 for success
1442  *              -1 if failed to get board READY
1443  *              -2 if READY but IOCFacts Failed
1444  *              -3 if READY but PrimeIOCFifos Failed
1445  *              -4 if READY but IOCInit Failed
1446  */
1447 static int
1448 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1449 {
1450         int      hard_reset_done = 0;
1451         int      alt_ioc_ready = 0;
1452         int      hard;
1453         int      rc=0;
1454         int      ii;
1455         int      handlers;
1456         int      ret = 0;
1457         int      reset_alt_ioc_active = 0;
1458
1459         printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1460                         ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1461
1462         /* Disable reply interrupts (also blocks FreeQ) */
1463         CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1464         ioc->active = 0;
1465
1466         if (ioc->alt_ioc) {
1467                 if (ioc->alt_ioc->active)
1468                         reset_alt_ioc_active = 1;
1469
1470                 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1471                 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1472                 ioc->alt_ioc->active = 0;
1473         }
1474
1475         hard = 1;
1476         if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1477                 hard = 0;
1478
1479         if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1480                 if (hard_reset_done == -4) {
1481                         printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1482                                         ioc->name);
1483
1484                         if (reset_alt_ioc_active && ioc->alt_ioc) {
1485                                 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1486                                 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1487                                                 ioc->alt_ioc->name));
1488                                 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
1489                                 ioc->alt_ioc->active = 1;
1490                         }
1491
1492                 } else {
1493                         printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1494                                         ioc->name);
1495                 }
1496                 return -1;
1497         }
1498
1499         /* hard_reset_done = 0 if a soft reset was performed
1500          * and 1 if a hard reset was performed.
1501          */
1502         if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1503                 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1504                         alt_ioc_ready = 1;
1505                 else
1506                         printk(KERN_WARNING MYNAM
1507                                         ": alt-%s: Not ready WARNING!\n",
1508                                         ioc->alt_ioc->name);
1509         }
1510
1511         for (ii=0; ii<5; ii++) {
1512                 /* Get IOC facts! Allow 5 retries */
1513                 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1514                         break;
1515         }
1516         
1517
1518         if (ii == 5) {
1519                 dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1520                 ret = -2;
1521         } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1522                 MptDisplayIocCapabilities(ioc);
1523         }
1524         
1525         if (alt_ioc_ready) {
1526                 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1527                         dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1528                         /* Retry - alt IOC was initialized once
1529                          */
1530                         rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1531                 }
1532                 if (rc) {
1533                         dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1534                         alt_ioc_ready = 0;
1535                         reset_alt_ioc_active = 0;
1536                 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1537                         MptDisplayIocCapabilities(ioc->alt_ioc);
1538                 }
1539         }
1540
1541         /* Prime reply & request queues!
1542          * (mucho alloc's) Must be done prior to
1543          * init as upper addresses are needed for init.
1544          * If fails, continue with alt-ioc processing
1545          */
1546         if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
1547                 ret = -3;
1548
1549         /* May need to check/upload firmware & data here!
1550          * If fails, continue with alt-ioc processing
1551          */
1552         if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
1553                 ret = -4;
1554 // NEW!
1555         if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
1556                 printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1557                                 ioc->alt_ioc->name, rc);
1558                 alt_ioc_ready = 0;
1559                 reset_alt_ioc_active = 0;
1560         }
1561
1562         if (alt_ioc_ready) {
1563                 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
1564                         alt_ioc_ready = 0;
1565                         reset_alt_ioc_active = 0;
1566                         printk(KERN_WARNING MYNAM
1567                                 ": alt-%s: (%d) init failure WARNING!\n",
1568                                         ioc->alt_ioc->name, rc);
1569                 }
1570         }
1571
1572         if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
1573                 if (ioc->upload_fw) {
1574                         ddlprintk((MYIOC_s_INFO_FMT
1575                                 "firmware upload required!\n", ioc->name));
1576
1577                         /* Controller is not operational, cannot do upload
1578                          */
1579                         if (ret == 0) {
1580                                 rc = mpt_do_upload(ioc, sleepFlag);
1581                                 if (rc != 0)
1582                                         printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
1583                         }
1584                 }
1585         }
1586
1587         if (ret == 0) {
1588                 /* Enable! (reply interrupt) */
1589                 CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
1590                 ioc->active = 1;
1591         }
1592
1593         if (reset_alt_ioc_active && ioc->alt_ioc) {
1594                 /* (re)Enable alt-IOC! (reply interrupt) */
1595                 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1596                                 ioc->alt_ioc->name));
1597                 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
1598                 ioc->alt_ioc->active = 1;
1599         }
1600
1601         /*  Enable MPT base driver management of EventNotification
1602          *  and EventAck handling.
1603          */
1604         if ((ret == 0) && (!ioc->facts.EventState))
1605                 (void) SendEventNotification(ioc, 1);   /* 1=Enable EventNotification */
1606
1607         if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
1608                 (void) SendEventNotification(ioc->alt_ioc, 1);  /* 1=Enable EventNotification */
1609
1610         /*      Add additional "reason" check before call to GetLanConfigPages
1611          *      (combined with GetIoUnitPage2 call).  This prevents a somewhat
1612          *      recursive scenario; GetLanConfigPages times out, timer expired
1613          *      routine calls HardResetHandler, which calls into here again,
1614          *      and we try GetLanConfigPages again...
1615          */
1616         if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1617                 if (ioc->bus_type == FC) {
1618                         /*
1619                          *  Pre-fetch FC port WWN and stuff...
1620                          *  (FCPortPage0_t stuff)
1621                          */
1622                         for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1623                                 (void) GetFcPortPage0(ioc, ii);
1624                         }
1625
1626                         if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
1627                             (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
1628                                 /*
1629                                  *  Pre-fetch the ports LAN MAC address!
1630                                  *  (LANPage1_t stuff)
1631                                  */
1632                                 (void) GetLanConfigPages(ioc);
1633 #ifdef MPT_DEBUG
1634                                 {
1635                                         u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
1636                                         dprintk((MYIOC_s_INFO_FMT "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
1637                                                         ioc->name, a[5], a[4], a[3], a[2], a[1], a[0] ));
1638                                 }
1639 #endif
1640                         }
1641                 } else {
1642                         /* Get NVRAM and adapter maximums from SPP 0 and 2
1643                          */
1644                         mpt_GetScsiPortSettings(ioc, 0);
1645
1646                         /* Get version and length of SDP 1
1647                          */
1648                         mpt_readScsiDevicePageHeaders(ioc, 0);
1649
1650                         /* Find IM volumes
1651                          */
1652                         if (ioc->facts.MsgVersion >= 0x0102)
1653                                 mpt_findImVolumes(ioc);
1654
1655                         /* Check, and possibly reset, the coalescing value
1656                          */
1657                         mpt_read_ioc_pg_1(ioc);
1658
1659                         mpt_read_ioc_pg_4(ioc);
1660                 }
1661
1662                 GetIoUnitPage2(ioc);
1663         }
1664
1665         /*
1666          * Call each currently registered protocol IOC reset handler
1667          * with post-reset indication.
1668          * NOTE: If we're doing _IOC_BRINGUP, there can be no
1669          * MptResetHandlers[] registered yet.
1670          */
1671         if (hard_reset_done) {
1672                 rc = handlers = 0;
1673                 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
1674                         if ((ret == 0) && MptResetHandlers[ii]) {
1675                                 dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
1676                                                 ioc->name, ii));
1677                                 rc += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET);
1678                                 handlers++;
1679                         }
1680
1681                         if (alt_ioc_ready && MptResetHandlers[ii]) {
1682                                 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
1683                                                 ioc->name, ioc->alt_ioc->name, ii));
1684                                 rc += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
1685                                 handlers++;
1686                         }
1687                 }
1688                 /* FIXME?  Examine results here? */
1689         }
1690
1691         return ret;
1692 }
1693
1694 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1695 /*
1696  *      mpt_detect_bound_ports - Search for PCI bus/dev_function
1697  *      which matches PCI bus/dev_function (+/-1) for newly discovered 929,
1698  *      929X, 1030 or 1035.
1699  *      @ioc: Pointer to MPT adapter structure
1700  *      @pdev: Pointer to (struct pci_dev) structure
1701  *
1702  *      If match on PCI dev_function +/-1 is found, bind the two MPT adapters
1703  *      using alt_ioc pointer fields in their %MPT_ADAPTER structures.
1704  */
1705 static void
1706 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
1707 {
1708         struct pci_dev *peer=NULL;
1709         unsigned int slot = PCI_SLOT(pdev->devfn);
1710         unsigned int func = PCI_FUNC(pdev->devfn);
1711         MPT_ADAPTER *ioc_srch;
1712
1713         dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x,"
1714             " searching for devfn match on %x or %x\n",
1715                 ioc->name, pci_name(pdev), pdev->devfn,
1716                 func-1, func+1));
1717
1718         peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
1719         if (!peer) {
1720                 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
1721                 if (!peer)
1722                         return;
1723         }
1724
1725         list_for_each_entry(ioc_srch, &ioc_list, list) {
1726                 struct pci_dev *_pcidev = ioc_srch->pcidev;
1727                 if (_pcidev == peer) {
1728                         /* Paranoia checks */
1729                         if (ioc->alt_ioc != NULL) {
1730                                 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1731                                         ioc->name, ioc->alt_ioc->name);
1732                                 break;
1733                         } else if (ioc_srch->alt_ioc != NULL) {
1734                                 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1735                                         ioc_srch->name, ioc_srch->alt_ioc->name);
1736                                 break;
1737                         }
1738                         dprintk((KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
1739                                 ioc->name, ioc_srch->name));
1740                         ioc_srch->alt_ioc = ioc;
1741                         ioc->alt_ioc = ioc_srch;
1742                 }
1743         }
1744         pci_dev_put(peer);
1745 }
1746
1747 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1748 /*
1749  *      mpt_adapter_disable - Disable misbehaving MPT adapter.
1750  *      @this: Pointer to MPT adapter structure
1751  */
1752 static void
1753 mpt_adapter_disable(MPT_ADAPTER *ioc)
1754 {
1755         int sz;
1756         int ret;
1757
1758         if (ioc->cached_fw != NULL) {
1759                 ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
1760                 if ((ret = mpt_downloadboot(ioc, NO_SLEEP)) < 0) {
1761                         printk(KERN_WARNING MYNAM
1762                                 ": firmware downloadboot failure (%d)!\n", ret);
1763                 }
1764         }
1765
1766         /* Disable adapter interrupts! */
1767         CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1768         ioc->active = 0;
1769         /* Clear any lingering interrupt */
1770         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1771
1772         if (ioc->alloc != NULL) {
1773                 sz = ioc->alloc_sz;
1774                 dexitprintk((KERN_INFO MYNAM ": %s.free  @ %p, sz=%d bytes\n",
1775                         ioc->name, ioc->alloc, ioc->alloc_sz));
1776                 pci_free_consistent(ioc->pcidev, sz,
1777                                 ioc->alloc, ioc->alloc_dma);
1778                 ioc->reply_frames = NULL;
1779                 ioc->req_frames = NULL;
1780                 ioc->alloc = NULL;
1781                 ioc->alloc_total -= sz;
1782         }
1783
1784         if (ioc->sense_buf_pool != NULL) {
1785                 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
1786                 pci_free_consistent(ioc->pcidev, sz,
1787                                 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
1788                 ioc->sense_buf_pool = NULL;
1789                 ioc->alloc_total -= sz;
1790         }
1791
1792         if (ioc->events != NULL){
1793                 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
1794                 kfree(ioc->events);
1795                 ioc->events = NULL;
1796                 ioc->alloc_total -= sz;
1797         }
1798
1799         if (ioc->cached_fw != NULL) {
1800                 sz = ioc->facts.FWImageSize;
1801                 pci_free_consistent(ioc->pcidev, sz,
1802                         ioc->cached_fw, ioc->cached_fw_dma);
1803                 ioc->cached_fw = NULL;
1804                 ioc->alloc_total -= sz;
1805         }
1806
1807         if (ioc->spi_data.nvram != NULL) {
1808                 kfree(ioc->spi_data.nvram);
1809                 ioc->spi_data.nvram = NULL;
1810         }
1811
1812         if (ioc->spi_data.pIocPg3 != NULL) {
1813                 kfree(ioc->spi_data.pIocPg3);
1814                 ioc->spi_data.pIocPg3 = NULL;
1815         }
1816
1817         if (ioc->spi_data.pIocPg4 != NULL) {
1818                 sz = ioc->spi_data.IocPg4Sz;
1819                 pci_free_consistent(ioc->pcidev, sz, 
1820                         ioc->spi_data.pIocPg4,
1821                         ioc->spi_data.IocPg4_dma);
1822                 ioc->spi_data.pIocPg4 = NULL;
1823                 ioc->alloc_total -= sz;
1824         }
1825
1826         if (ioc->ReqToChain != NULL) {
1827                 kfree(ioc->ReqToChain);
1828                 kfree(ioc->RequestNB);
1829                 ioc->ReqToChain = NULL;
1830         }
1831
1832         if (ioc->ChainToChain != NULL) {
1833                 kfree(ioc->ChainToChain);
1834                 ioc->ChainToChain = NULL;
1835         }
1836 }
1837
1838 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1839 /*
1840  *      mpt_adapter_dispose - Free all resources associated with a MPT
1841  *      adapter.
1842  *      @ioc: Pointer to MPT adapter structure
1843  *
1844  *      This routine unregisters h/w resources and frees all alloc'd memory
1845  *      associated with a MPT adapter structure.
1846  */
1847 static void
1848 mpt_adapter_dispose(MPT_ADAPTER *ioc)
1849 {
1850         if (ioc != NULL) {
1851                 int sz_first, sz_last;
1852
1853                 sz_first = ioc->alloc_total;
1854
1855                 mpt_adapter_disable(ioc);
1856
1857                 if (ioc->pci_irq != -1) {
1858                         free_irq(ioc->pci_irq, ioc);
1859                         ioc->pci_irq = -1;
1860                 }
1861
1862                 if (ioc->memmap != NULL)
1863                         iounmap(ioc->memmap);
1864
1865 #if defined(CONFIG_MTRR) && 0
1866                 if (ioc->mtrr_reg > 0) {
1867                         mtrr_del(ioc->mtrr_reg, 0, 0);
1868                         dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
1869                 }
1870 #endif
1871
1872                 /*  Zap the adapter lookup ptr!  */
1873                 list_del(&ioc->list);
1874
1875                 sz_last = ioc->alloc_total;
1876                 dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
1877                                 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
1878                 kfree(ioc);
1879         }
1880 }
1881
1882 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1883 /*
1884  *      MptDisplayIocCapabilities - Disply IOC's capacilities.
1885  *      @ioc: Pointer to MPT adapter structure
1886  */
1887 static void
1888 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
1889 {
1890         int i = 0;
1891
1892         printk(KERN_INFO "%s: ", ioc->name);
1893         if (ioc->prod_name && strlen(ioc->prod_name) > 3)
1894                 printk("%s: ", ioc->prod_name+3);
1895         printk("Capabilities={");
1896
1897         if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
1898                 printk("Initiator");
1899                 i++;
1900         }
1901
1902         if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
1903                 printk("%sTarget", i ? "," : "");
1904                 i++;
1905         }
1906
1907         if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
1908                 printk("%sLAN", i ? "," : "");
1909                 i++;
1910         }
1911
1912 #if 0
1913         /*
1914          *  This would probably evoke more questions than it's worth
1915          */
1916         if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
1917                 printk("%sLogBusAddr", i ? "," : "");
1918                 i++;
1919         }
1920 #endif
1921
1922         printk("}\n");
1923 }
1924
1925 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1926 /*
1927  *      MakeIocReady - Get IOC to a READY state, using KickStart if needed.
1928  *      @ioc: Pointer to MPT_ADAPTER structure
1929  *      @force: Force hard KickStart of IOC
1930  *      @sleepFlag: Specifies whether the process can sleep
1931  *
1932  *      Returns:
1933  *               1 - DIAG reset and READY
1934  *               0 - READY initially OR soft reset and READY
1935  *              -1 - Any failure on KickStart
1936  *              -2 - Msg Unit Reset Failed
1937  *              -3 - IO Unit Reset Failed
1938  *              -4 - IOC owned by a PEER
1939  */
1940 static int
1941 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
1942 {
1943         u32      ioc_state;
1944         int      statefault = 0;
1945         int      cntdn;
1946         int      hard_reset_done = 0;
1947         int      r;
1948         int      ii;
1949         int      whoinit;
1950
1951         /* Get current [raw] IOC state  */
1952         ioc_state = mpt_GetIocState(ioc, 0);
1953         dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
1954
1955         /*
1956          *      Check to see if IOC got left/stuck in doorbell handshake
1957          *      grip of death.  If so, hard reset the IOC.
1958          */
1959         if (ioc_state & MPI_DOORBELL_ACTIVE) {
1960                 statefault = 1;
1961                 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
1962                                 ioc->name);
1963         }
1964
1965         /* Is it already READY? */
1966         if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY) 
1967                 return 0;
1968
1969         /*
1970          *      Check to see if IOC is in FAULT state.
1971          */
1972         if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
1973                 statefault = 2;
1974                 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
1975                                 ioc->name);
1976                 printk(KERN_WARNING "           FAULT code = %04xh\n",
1977                                 ioc_state & MPI_DOORBELL_DATA_MASK);
1978         }
1979
1980         /*
1981          *      Hmmm...  Did it get left operational?
1982          */
1983         if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
1984                 dinitprintk((MYIOC_s_WARN_FMT "IOC operational unexpected\n",
1985                                 ioc->name));
1986
1987                 /* Check WhoInit.
1988                  * If PCI Peer, exit.
1989                  * Else, if no fault conditions are present, issue a MessageUnitReset
1990                  * Else, fall through to KickStart case
1991                  */
1992                 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
1993                 dprintk((KERN_WARNING MYNAM
1994                         ": whoinit 0x%x\n statefault %d force %d\n",
1995                         whoinit, statefault, force));
1996                 if (whoinit == MPI_WHOINIT_PCI_PEER)
1997                         return -4;
1998                 else {
1999                         if ((statefault == 0 ) && (force == 0)) {
2000                                 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2001                                         return 0;
2002                         }
2003                         statefault = 3;
2004                 }
2005         }
2006
2007         hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2008         if (hard_reset_done < 0)
2009                 return -1;
2010
2011         /*
2012          *  Loop here waiting for IOC to come READY.
2013          */
2014         ii = 0;
2015         cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15;    /* 15 seconds */
2016
2017         while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2018                 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2019                         /*
2020                          *  BIOS or previous driver load left IOC in OP state.
2021                          *  Reset messaging FIFOs.
2022                          */
2023                         if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2024                                 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2025                                 return -2;
2026                         }
2027                 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2028                         /*
2029                          *  Something is wrong.  Try to get IOC back
2030                          *  to a known state.
2031                          */
2032                         if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2033                                 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2034                                 return -3;
2035                         }
2036                 }
2037
2038                 ii++; cntdn--;
2039                 if (!cntdn) {
2040                         printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2041                                         ioc->name, (int)((ii+5)/HZ));
2042                         return -ETIME;
2043                 }
2044
2045                 if (sleepFlag == CAN_SLEEP) {
2046                         msleep_interruptible(1);
2047                 } else {
2048                         mdelay (1);     /* 1 msec delay */
2049                 }
2050
2051         }
2052
2053         if (statefault < 3) {
2054                 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2055                                 ioc->name,
2056                                 statefault==1 ? "stuck handshake" : "IOC FAULT");
2057         }
2058
2059         return hard_reset_done;
2060 }
2061
2062 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2063 /*
2064  *      mpt_GetIocState - Get the current state of a MPT adapter.
2065  *      @ioc: Pointer to MPT_ADAPTER structure
2066  *      @cooked: Request raw or cooked IOC state
2067  *
2068  *      Returns all IOC Doorbell register bits if cooked==0, else just the
2069  *      Doorbell bits in MPI_IOC_STATE_MASK.
2070  */
2071 u32
2072 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2073 {
2074         u32 s, sc;
2075
2076         /*  Get!  */
2077         s = CHIPREG_READ32(&ioc->chip->Doorbell);
2078 //      dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2079         sc = s & MPI_IOC_STATE_MASK;
2080
2081         /*  Save!  */
2082         ioc->last_state = sc;
2083
2084         return cooked ? sc : s;
2085 }
2086
2087 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2088 /*
2089  *      GetIocFacts - Send IOCFacts request to MPT adapter.
2090  *      @ioc: Pointer to MPT_ADAPTER structure
2091  *      @sleepFlag: Specifies whether the process can sleep
2092  *      @reason: If recovery, only update facts.
2093  *
2094  *      Returns 0 for success, non-zero for failure.
2095  */
2096 static int
2097 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2098 {
2099         IOCFacts_t               get_facts;
2100         IOCFactsReply_t         *facts;
2101         int                      r;
2102         int                      req_sz;
2103         int                      reply_sz;
2104         int                      sz;
2105         u32                      status, vv;
2106         u8                       shiftFactor=1;
2107
2108         /* IOC *must* NOT be in RESET state! */
2109         if (ioc->last_state == MPI_IOC_STATE_RESET) {
2110                 printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2111                                 ioc->name,
2112                                 ioc->last_state );
2113                 return -44;
2114         }
2115
2116         facts = &ioc->facts;
2117
2118         /* Destination (reply area)... */
2119         reply_sz = sizeof(*facts);
2120         memset(facts, 0, reply_sz);
2121
2122         /* Request area (get_facts on the stack right now!) */
2123         req_sz = sizeof(get_facts);
2124         memset(&get_facts, 0, req_sz);
2125
2126         get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2127         /* Assert: All other get_facts fields are zero! */
2128
2129         dinitprintk((MYIOC_s_INFO_FMT 
2130             "Sending get IocFacts request req_sz=%d reply_sz=%d\n", 
2131             ioc->name, req_sz, reply_sz));
2132
2133         /* No non-zero fields in the get_facts request are greater than
2134          * 1 byte in size, so we can just fire it off as is.
2135          */
2136         r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2137                         reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2138         if (r != 0)
2139                 return r;
2140
2141         /*
2142          * Now byte swap (GRRR) the necessary fields before any further
2143          * inspection of reply contents.
2144          *
2145          * But need to do some sanity checks on MsgLength (byte) field
2146          * to make sure we don't zero IOC's req_sz!
2147          */
2148         /* Did we get a valid reply? */
2149         if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2150                 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2151                         /*
2152                          * If not been here, done that, save off first WhoInit value
2153                          */
2154                         if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2155                                 ioc->FirstWhoInit = facts->WhoInit;
2156                 }
2157
2158                 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2159                 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2160                 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2161                 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2162                 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2163                 status = facts->IOCStatus & MPI_IOCSTATUS_MASK;
2164                 /* CHECKME! IOCStatus, IOCLogInfo */
2165
2166                 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2167                 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2168
2169                 /*
2170                  * FC f/w version changed between 1.1 and 1.2
2171                  *      Old: u16{Major(4),Minor(4),SubMinor(8)}
2172                  *      New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2173                  */
2174                 if (facts->MsgVersion < 0x0102) {
2175                         /*
2176                          *      Handle old FC f/w style, convert to new...
2177                          */
2178                         u16      oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2179                         facts->FWVersion.Word =
2180                                         ((oldv<<12) & 0xFF000000) |
2181                                         ((oldv<<8)  & 0x000FFF00);
2182                 } else
2183                         facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2184
2185                 facts->ProductID = le16_to_cpu(facts->ProductID);
2186                 facts->CurrentHostMfaHighAddr =
2187                                 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2188                 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2189                 facts->CurrentSenseBufferHighAddr =
2190                                 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2191                 facts->CurReplyFrameSize =
2192                                 le16_to_cpu(facts->CurReplyFrameSize);
2193
2194                 /*
2195                  * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2196                  * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2197                  * to 14 in MPI-1.01.0x.
2198                  */
2199                 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2200                     facts->MsgVersion > 0x0100) {
2201                         facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2202                 }
2203
2204                 sz = facts->FWImageSize;
2205                 if ( sz & 0x01 )
2206                         sz += 1;
2207                 if ( sz & 0x02 )
2208                         sz += 2;
2209                 facts->FWImageSize = sz;
2210                 
2211                 if (!facts->RequestFrameSize) {
2212                         /*  Something is wrong!  */
2213                         printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2214                                         ioc->name);
2215                         return -55;
2216                 }
2217
2218                 r = sz = facts->BlockSize;
2219                 vv = ((63 / (sz * 4)) + 1) & 0x03;
2220                 ioc->NB_for_64_byte_frame = vv;
2221                 while ( sz )
2222                 {
2223                         shiftFactor++;
2224                         sz = sz >> 1;
2225                 }
2226                 ioc->NBShiftFactor  = shiftFactor;
2227                 dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2228                                         ioc->name, vv, shiftFactor, r));
2229     
2230                 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2231                         /*
2232                          * Set values for this IOC's request & reply frame sizes,
2233                          * and request & reply queue depths...
2234                          */
2235                         ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2236                         ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2237                         ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2238                         ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2239
2240                         dinitprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
2241                                 ioc->name, ioc->reply_sz, ioc->reply_depth));
2242                         dinitprintk((MYIOC_s_INFO_FMT "req_sz  =%3d, req_depth  =%4d\n",
2243                                 ioc->name, ioc->req_sz, ioc->req_depth));
2244
2245                         /* Get port facts! */
2246                         if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2247                                 return r;
2248                 }
2249         } else {
2250                 printk(MYIOC_s_ERR_FMT 
2251                      "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2252                      ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2253                      RequestFrameSize)/sizeof(u32)));
2254                 return -66;
2255         }
2256
2257         return 0;
2258 }
2259
2260 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2261 /*
2262  *      GetPortFacts - Send PortFacts request to MPT adapter.
2263  *      @ioc: Pointer to MPT_ADAPTER structure
2264  *      @portnum: Port number
2265  *      @sleepFlag: Specifies whether the process can sleep
2266  *
2267  *      Returns 0 for success, non-zero for failure.
2268  */
2269 static int
2270 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2271 {
2272         PortFacts_t              get_pfacts;
2273         PortFactsReply_t        *pfacts;
2274         int                      ii;
2275         int                      req_sz;
2276         int                      reply_sz;
2277
2278         /* IOC *must* NOT be in RESET state! */
2279         if (ioc->last_state == MPI_IOC_STATE_RESET) {
2280                 printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2281                                 ioc->name,
2282                                 ioc->last_state );
2283                 return -4;
2284         }
2285
2286         pfacts = &ioc->pfacts[portnum];
2287
2288         /* Destination (reply area)...  */
2289         reply_sz = sizeof(*pfacts);
2290         memset(pfacts, 0, reply_sz);
2291
2292         /* Request area (get_pfacts on the stack right now!) */
2293         req_sz = sizeof(get_pfacts);
2294         memset(&get_pfacts, 0, req_sz);
2295
2296         get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2297         get_pfacts.PortNumber = portnum;
2298         /* Assert: All other get_pfacts fields are zero! */
2299
2300         dinitprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
2301                         ioc->name, portnum));
2302
2303         /* No non-zero fields in the get_pfacts request are greater than
2304          * 1 byte in size, so we can just fire it off as is.
2305          */
2306         ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2307                                 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2308         if (ii != 0)
2309                 return ii;
2310
2311         /* Did we get a valid reply? */
2312
2313         /* Now byte swap the necessary fields in the response. */
2314         pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2315         pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2316         pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2317         pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2318         pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2319         pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2320         pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2321         pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2322         pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2323
2324         return 0;
2325 }
2326
2327 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2328 /*
2329  *      SendIocInit - Send IOCInit request to MPT adapter.
2330  *      @ioc: Pointer to MPT_ADAPTER structure
2331  *      @sleepFlag: Specifies whether the process can sleep
2332  *
2333  *      Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2334  *
2335  *      Returns 0 for success, non-zero for failure.
2336  */
2337 static int
2338 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2339 {
2340         IOCInit_t                ioc_init;
2341         MPIDefaultReply_t        init_reply;
2342         u32                      state;
2343         int                      r;
2344         int                      count;
2345         int                      cntdn;
2346
2347         memset(&ioc_init, 0, sizeof(ioc_init));
2348         memset(&init_reply, 0, sizeof(init_reply));
2349
2350         ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2351         ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2352
2353         /* If we are in a recovery mode and we uploaded the FW image,
2354          * then this pointer is not NULL. Skip the upload a second time.
2355          * Set this flag if cached_fw set for either IOC.
2356          */
2357         if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2358                 ioc->upload_fw = 1;
2359         else
2360                 ioc->upload_fw = 0;
2361         ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
2362                    ioc->name, ioc->upload_fw, ioc->facts.Flags));
2363
2364         if (ioc->bus_type == FC)
2365                 ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
2366         else
2367                 ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
2368         
2369         ioc_init.MaxBuses = MPT_MAX_BUS;
2370
2371         ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz);   /* in BYTES */
2372
2373         if (sizeof(dma_addr_t) == sizeof(u64)) {
2374                 /* Save the upper 32-bits of the request
2375                  * (reply) and sense buffers.
2376                  */
2377                 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2378                 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2379         } else {
2380                 /* Force 32-bit addressing */
2381                 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2382                 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2383         }
2384                 
2385         ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2386         ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2387
2388         dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
2389                         ioc->name, &ioc_init));
2390
2391         r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2392                                 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2393         if (r != 0)
2394                 return r;
2395
2396         /* No need to byte swap the multibyte fields in the reply
2397          * since we don't even look at it's contents.
2398          */
2399
2400         dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
2401                         ioc->name, &ioc_init));
2402         
2403         if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0)
2404                 return r;
2405
2406         /* YIKES!  SUPER IMPORTANT!!!
2407          *  Poll IocState until _OPERATIONAL while IOC is doing
2408          *  LoopInit and TargetDiscovery!
2409          */
2410         count = 0;
2411         cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60;    /* 60 seconds */
2412         state = mpt_GetIocState(ioc, 1);
2413         while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2414                 if (sleepFlag == CAN_SLEEP) {
2415                         msleep_interruptible(1);
2416                 } else {
2417                         mdelay(1);
2418                 }
2419
2420                 if (!cntdn) {
2421                         printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2422                                         ioc->name, (int)((count+5)/HZ));
2423                         return -9;
2424                 }
2425
2426                 state = mpt_GetIocState(ioc, 1);
2427                 count++;
2428         }
2429         dhsprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2430                         ioc->name, count));
2431
2432         return r;
2433 }
2434
2435 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2436 /*
2437  *      SendPortEnable - Send PortEnable request to MPT adapter port.
2438  *      @ioc: Pointer to MPT_ADAPTER structure
2439  *      @portnum: Port number to enable
2440  *      @sleepFlag: Specifies whether the process can sleep
2441  *
2442  *      Send PortEnable to bring IOC to OPERATIONAL state.
2443  *
2444  *      Returns 0 for success, non-zero for failure.
2445  */
2446 static int
2447 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2448 {
2449         PortEnable_t             port_enable;
2450         MPIDefaultReply_t        reply_buf;
2451         int      ii;
2452         int      req_sz;
2453         int      reply_sz;
2454
2455         /*  Destination...  */
2456         reply_sz = sizeof(MPIDefaultReply_t);
2457         memset(&reply_buf, 0, reply_sz);
2458
2459         req_sz = sizeof(PortEnable_t);
2460         memset(&port_enable, 0, req_sz);
2461
2462         port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2463         port_enable.PortNumber = portnum;
2464 /*      port_enable.ChainOffset = 0;            */
2465 /*      port_enable.MsgFlags = 0;               */
2466 /*      port_enable.MsgContext = 0;             */
2467
2468         dinitprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
2469                         ioc->name, portnum, &port_enable));
2470
2471         /* RAID FW may take a long time to enable
2472          */
2473         if (ioc->bus_type == FC) {
2474                 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2475                                 reply_sz, (u16*)&reply_buf, 65 /*seconds*/, sleepFlag);
2476         } else {
2477                 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2478                                 reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag);
2479         }
2480
2481         if (ii != 0)
2482                 return ii;
2483
2484         /* We do not even look at the reply, so we need not
2485          * swap the multi-byte fields.
2486          */
2487
2488         return 0;
2489 }
2490
2491 /*
2492  *      ioc: Pointer to MPT_ADAPTER structure
2493  *      size - total FW bytes
2494  */
2495 void
2496 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
2497 {
2498         if (ioc->cached_fw)
2499                 return;  /* use already allocated memory */
2500         if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2501                 ioc->cached_fw = ioc->alt_ioc->cached_fw;  /* use alt_ioc's memory */
2502                 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
2503         } else {
2504                 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
2505                         ioc->alloc_total += size;
2506         }
2507 }
2508 /*
2509  * If alt_img is NULL, delete from ioc structure.
2510  * Else, delete a secondary image in same format.
2511  */
2512 void
2513 mpt_free_fw_memory(MPT_ADAPTER *ioc)
2514 {
2515         int sz;
2516
2517         sz = ioc->facts.FWImageSize;
2518         dinitprintk((KERN_WARNING MYNAM "free_fw_memory: FW Image  @ %p[%p], sz=%d[%x] bytes\n",
2519                  ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2520         pci_free_consistent(ioc->pcidev, sz,
2521                         ioc->cached_fw, ioc->cached_fw_dma);
2522         ioc->cached_fw = NULL;
2523
2524         return;
2525 }
2526
2527
2528 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2529 /*
2530  *      mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
2531  *      @ioc: Pointer to MPT_ADAPTER structure
2532  *      @sleepFlag: Specifies whether the process can sleep
2533  *
2534  *      Returns 0 for success, >0 for handshake failure
2535  *              <0 for fw upload failure.
2536  *
2537  *      Remark: If bound IOC and a successful FWUpload was performed
2538  *      on the bound IOC, the second image is discarded
2539  *      and memory is free'd. Both channels must upload to prevent
2540  *      IOC from running in degraded mode.
2541  */
2542 static int
2543 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2544 {
2545         u8                       request[ioc->req_sz];
2546         u8                       reply[sizeof(FWUploadReply_t)];
2547         FWUpload_t              *prequest;
2548         FWUploadReply_t         *preply;
2549         FWUploadTCSGE_t         *ptcsge;
2550         int                      sgeoffset;
2551         u32                      flagsLength;
2552         int                      ii, sz, reply_sz;
2553         int                      cmdStatus;
2554
2555         /* If the image size is 0, we are done.
2556          */
2557         if ((sz = ioc->facts.FWImageSize) == 0)
2558                 return 0;
2559
2560         mpt_alloc_fw_memory(ioc, sz);
2561
2562         dinitprintk((KERN_WARNING MYNAM ": FW Image  @ %p[%p], sz=%d[%x] bytes\n",
2563                  ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2564         
2565         if (ioc->cached_fw == NULL) {
2566                 /* Major Failure.
2567                  */
2568                 return -ENOMEM;
2569         }
2570
2571         prequest = (FWUpload_t *)&request;
2572         preply = (FWUploadReply_t *)&reply;
2573
2574         /*  Destination...  */
2575         memset(prequest, 0, ioc->req_sz);
2576
2577         reply_sz = sizeof(reply);
2578         memset(preply, 0, reply_sz);
2579
2580         prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
2581         prequest->Function = MPI_FUNCTION_FW_UPLOAD;
2582
2583         ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
2584         ptcsge->DetailsLength = 12;
2585         ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
2586         ptcsge->ImageSize = cpu_to_le32(sz);
2587
2588         sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
2589
2590         flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
2591         mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
2592
2593         sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
2594         dinitprintk((KERN_WARNING MYNAM "Sending FW Upload (req @ %p) sgeoffset=%d \n",
2595                         prequest, sgeoffset));
2596         DBG_DUMP_FW_REQUEST_FRAME(prequest)
2597
2598         ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
2599                                 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
2600
2601         dinitprintk((KERN_WARNING MYNAM "FW Upload completed rc=%x \n", ii));
2602
2603         cmdStatus = -EFAULT;
2604         if (ii == 0) {
2605                 /* Handshake transfer was complete and successful.
2606                  * Check the Reply Frame.
2607                  */
2608                 int status, transfer_sz;
2609                 status = le16_to_cpu(preply->IOCStatus);
2610                 if (status == MPI_IOCSTATUS_SUCCESS) {
2611                         transfer_sz = le32_to_cpu(preply->ActualImageSize);
2612                         if (transfer_sz == sz)
2613                                 cmdStatus = 0;
2614                 }
2615         }
2616         dinitprintk((MYIOC_s_INFO_FMT ": do_upload status %d \n",
2617                         ioc->name, cmdStatus));
2618
2619         
2620         if (cmdStatus) {
2621
2622                 ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
2623                         ioc->name));
2624                 mpt_free_fw_memory(ioc);
2625         }
2626
2627         return cmdStatus;
2628 }
2629
2630 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2631 /*
2632  *      mpt_downloadboot - DownloadBoot code
2633  *      @ioc: Pointer to MPT_ADAPTER structure
2634  *      @flag: Specify which part of IOC memory is to be uploaded.
2635  *      @sleepFlag: Specifies whether the process can sleep
2636  *
2637  *      FwDownloadBoot requires Programmed IO access.
2638  *
2639  *      Returns 0 for success
2640  *              -1 FW Image size is 0
2641  *              -2 No valid cached_fw Pointer
2642  *              <0 for fw upload failure.
2643  */
2644 static int
2645 mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
2646 {
2647         MpiFwHeader_t           *pFwHeader;
2648         MpiExtImageHeader_t     *pExtImage;
2649         u32                      fwSize;
2650         u32                      diag0val;
2651         int                      count;
2652         u32                     *ptrFw;
2653         u32                      diagRwData;
2654         u32                      nextImage;
2655         u32                      load_addr;
2656         u32                      ioc_state=0;
2657
2658         ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x, ioc FW Ptr %p\n",
2659                                 ioc->name, ioc->facts.FWImageSize, ioc->cached_fw));
2660
2661         if ( ioc->facts.FWImageSize == 0 )
2662                 return -1;
2663
2664         if (ioc->cached_fw == NULL)
2665                 return -2;
2666
2667         /* prevent a second downloadboot and memory free with alt_ioc */
2668         if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
2669                 ioc->alt_ioc->cached_fw = NULL;
2670         
2671         CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2672         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2673         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2674         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2675         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2676         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2677
2678         CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
2679
2680         /* wait 1 msec */
2681         if (sleepFlag == CAN_SLEEP) {
2682                 msleep_interruptible(1);
2683         } else {
2684                 mdelay (1);
2685         }
2686
2687         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2688         CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2689
2690         for (count = 0; count < 30; count ++) {
2691                 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2692                 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
2693                         ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
2694                                 ioc->name, count));
2695                         break;
2696                 }
2697                 /* wait 1 sec */
2698                 if (sleepFlag == CAN_SLEEP) {
2699                         msleep_interruptible (1000);
2700                 } else {
2701                         mdelay (1000);
2702                 }
2703         }
2704
2705         if ( count == 30 ) {
2706                 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! Unable to RESET_ADAPTER diag0val=%x\n",
2707                 ioc->name, diag0val));
2708                 return -3;
2709         }
2710
2711         CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2712         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2713         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2714         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2715         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2716         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2717
2718         /* Set the DiagRwEn and Disable ARM bits */
2719         CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
2720
2721         pFwHeader = (MpiFwHeader_t *) ioc->cached_fw;
2722         fwSize = (pFwHeader->ImageSize + 3)/4;
2723         ptrFw = (u32 *) pFwHeader;
2724
2725         /* Write the LoadStartAddress to the DiagRw Address Register
2726          * using Programmed IO
2727          */
2728         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
2729         ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
2730                 ioc->name, pFwHeader->LoadStartAddress));
2731
2732         ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n",
2733                                 ioc->name, fwSize*4, ptrFw));
2734         while (fwSize--) {
2735                 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2736         }
2737
2738         nextImage = pFwHeader->NextImageHeaderOffset;
2739         while (nextImage) {
2740                 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
2741
2742                 load_addr = pExtImage->LoadStartAddress;
2743
2744                 fwSize = (pExtImage->ImageSize + 3) >> 2;
2745                 ptrFw = (u32 *)pExtImage;
2746
2747                 ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x bytes @ %p load_addr=%x\n",
2748                                                 ioc->name, fwSize*4, ptrFw, load_addr));
2749                 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
2750
2751                 while (fwSize--) {
2752                         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2753                 }
2754                 nextImage = pExtImage->NextImageHeaderOffset;
2755         }
2756
2757         /* Write the IopResetVectorRegAddr */
2758         ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name,      pFwHeader->IopResetRegAddr));
2759         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
2760
2761         /* Write the IopResetVectorValue */
2762         ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
2763         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
2764
2765         /* Clear the internal flash bad bit - autoincrementing register,
2766          * so must do two writes.
2767          */
2768         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
2769         diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
2770         diagRwData |= 0x4000000;
2771         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
2772         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
2773
2774         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2775         ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, turning off PREVENT_IOC_BOOT, DISABLE_ARM\n",
2776                 ioc->name, diag0val));
2777         diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM);
2778         ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
2779                 ioc->name, diag0val));
2780         CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
2781
2782         /* Write 0xFF to reset the sequencer */
2783         CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2784
2785         for (count=0; count<HZ*20; count++) {
2786                 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
2787                         ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
2788                                         ioc->name, count, ioc_state));
2789                         if ((SendIocInit(ioc, sleepFlag)) != 0) {
2790                                 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
2791                                         ioc->name));
2792                                 return -EFAULT;
2793                         }
2794                         ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit successful\n",
2795                                         ioc->name));
2796                         return 0;
2797                 }
2798                 if (sleepFlag == CAN_SLEEP) {
2799                         msleep_interruptible (10);
2800                 } else {
2801                         mdelay (10);
2802                 }
2803         }
2804         ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! IocState=%x\n",
2805                 ioc->name, ioc_state));
2806         return -EFAULT;
2807 }
2808
2809 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2810 /*
2811  *      KickStart - Perform hard reset of MPT adapter.
2812  *      @ioc: Pointer to MPT_ADAPTER structure
2813  *      @force: Force hard reset
2814  *      @sleepFlag: Specifies whether the process can sleep
2815  *
2816  *      This routine places MPT adapter in diagnostic mode via the
2817  *      WriteSequence register, and then performs a hard reset of adapter
2818  *      via the Diagnostic register.
2819  *
2820  *      Inputs:   sleepflag - CAN_SLEEP (non-interrupt thread)
2821  *                      or NO_SLEEP (interrupt thread, use mdelay)
2822  *                force - 1 if doorbell active, board fault state
2823  *                              board operational, IOC_RECOVERY or
2824  *                              IOC_BRINGUP and there is an alt_ioc.
2825  *                        0 else
2826  *
2827  *      Returns:
2828  *               1 - hard reset, READY  
2829  *               0 - no reset due to History bit, READY 
2830  *              -1 - no reset due to History bit but not READY  
2831  *                   OR reset but failed to come READY
2832  *              -2 - no reset, could not enter DIAG mode
2833  *              -3 - reset but bad FW bit
2834  */
2835 static int
2836 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
2837 {
2838         int hard_reset_done = 0;
2839         u32 ioc_state=0;
2840         int cnt,cntdn;
2841
2842         dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
2843         if (ioc->bus_type == SCSI) {
2844                 /* Always issue a Msg Unit Reset first. This will clear some
2845                  * SCSI bus hang conditions.
2846                  */
2847                 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
2848
2849                 if (sleepFlag == CAN_SLEEP) {
2850                         msleep_interruptible (1000);
2851                 } else {
2852                         mdelay (1000);
2853                 }
2854         }
2855
2856         hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
2857         if (hard_reset_done < 0)
2858                 return hard_reset_done;
2859
2860         dinitprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
2861                         ioc->name));
2862
2863         cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2;     /* 2 seconds */
2864         for (cnt=0; cnt<cntdn; cnt++) {
2865                 ioc_state = mpt_GetIocState(ioc, 1);
2866                 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
2867                         dinitprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
2868                                         ioc->name, cnt));
2869                         return hard_reset_done;
2870                 }
2871                 if (sleepFlag == CAN_SLEEP) {
2872                         msleep_interruptible (10);
2873                 } else {
2874                         mdelay (10);
2875                 }
2876         }
2877
2878         printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
2879                         ioc->name, ioc_state);
2880         return -1;
2881 }
2882
2883 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2884 /*
2885  *      mpt_diag_reset - Perform hard reset of the adapter.
2886  *      @ioc: Pointer to MPT_ADAPTER structure
2887  *      @ignore: Set if to honor and clear to ignore
2888  *              the reset history bit
2889  *      @sleepflag: CAN_SLEEP if called in a non-interrupt thread,
2890  *              else set to NO_SLEEP (use mdelay instead)
2891  *
2892  *      This routine places the adapter in diagnostic mode via the
2893  *      WriteSequence register and then performs a hard reset of adapter
2894  *      via the Diagnostic register. Adapter should be in ready state
2895  *      upon successful completion.
2896  *
2897  *      Returns:  1  hard reset successful
2898  *                0  no reset performed because reset history bit set
2899  *               -2  enabling diagnostic mode failed
2900  *               -3  diagnostic reset failed
2901  */
2902 static int
2903 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
2904 {
2905         u32 diag0val;
2906         u32 doorbell;
2907         int hard_reset_done = 0;
2908         int count = 0;
2909 #ifdef MPT_DEBUG
2910         u32 diag1val = 0;
2911 #endif
2912
2913         /* Clear any existing interrupts */
2914         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2915
2916         /* Use "Diagnostic reset" method! (only thing available!) */
2917         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2918
2919 #ifdef MPT_DEBUG
2920         if (ioc->alt_ioc)
2921                 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
2922         dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
2923                         ioc->name, diag0val, diag1val));
2924 #endif
2925
2926         /* Do the reset if we are told to ignore the reset history
2927          * or if the reset history is 0
2928          */
2929         if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
2930                 while ((diag0val & MPI_DIAG_DRWE) == 0) {
2931                         /* Write magic sequence to WriteSequence register
2932                          * Loop until in diagnostic mode
2933                          */
2934                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2935                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2936                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2937                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2938                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2939                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2940
2941                         /* wait 100 msec */
2942                         if (sleepFlag == CAN_SLEEP) {
2943                                 msleep_interruptible (100);
2944                         } else {
2945                                 mdelay (100);
2946                         }
2947
2948                         count++;
2949                         if (count > 20) {
2950                                 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
2951                                                 ioc->name, diag0val);
2952                                 return -2;
2953
2954                         }
2955
2956                         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2957
2958                         dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
2959                                         ioc->name, diag0val));
2960                 }
2961
2962 #ifdef MPT_DEBUG
2963                 if (ioc->alt_ioc)
2964                         diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
2965                 dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
2966                                 ioc->name, diag0val, diag1val));
2967 #endif
2968                 /*
2969                  * Disable the ARM (Bug fix)
2970                  *
2971                  */
2972                 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
2973                 mdelay (1);
2974
2975                 /*
2976                  * Now hit the reset bit in the Diagnostic register
2977                  * (THE BIG HAMMER!) (Clears DRWE bit).
2978                  */
2979                 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2980                 hard_reset_done = 1;
2981                 dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
2982                                 ioc->name));
2983
2984                 /*
2985                  * Call each currently registered protocol IOC reset handler
2986                  * with pre-reset indication.
2987                  * NOTE: If we're doing _IOC_BRINGUP, there can be no
2988                  * MptResetHandlers[] registered yet.
2989                  */
2990                 {
2991                         int      ii;
2992                         int      r = 0;
2993
2994                         for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
2995                                 if (MptResetHandlers[ii]) {
2996                                         dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
2997                                                         ioc->name, ii));
2998                                         r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_PRE_RESET);
2999                                         if (ioc->alt_ioc) {
3000                                                 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3001                                                                 ioc->name, ioc->alt_ioc->name, ii));
3002                                                 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_PRE_RESET);
3003                                         }
3004                                 }
3005                         }
3006                         /* FIXME?  Examine results here? */
3007                 }
3008
3009                 if (ioc->cached_fw) {
3010                         /* If the DownloadBoot operation fails, the
3011                          * IOC will be left unusable. This is a fatal error
3012                          * case.  _diag_reset will return < 0
3013                          */
3014                         for (count = 0; count < 30; count ++) {
3015                                 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3016                                 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3017                                         break;
3018                                 }
3019
3020                                 /* wait 1 sec */
3021                                 if (sleepFlag == CAN_SLEEP) {
3022                                         ssleep(1);
3023                                 } else {
3024                                         mdelay (1000);
3025                                 }
3026                         }
3027                         if ((count = mpt_downloadboot(ioc, sleepFlag)) < 0) {
3028                                 printk(KERN_WARNING MYNAM
3029                                         ": firmware downloadboot failure (%d)!\n", count);
3030                         }
3031
3032                 } else {
3033                         /* Wait for FW to reload and for board
3034                          * to go to the READY state.
3035                          * Maximum wait is 60 seconds.
3036                          * If fail, no error will check again
3037                          * with calling program.
3038                          */
3039                         for (count = 0; count < 60; count ++) {
3040                                 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3041                                 doorbell &= MPI_IOC_STATE_MASK;
3042
3043                                 if (doorbell == MPI_IOC_STATE_READY) {
3044                                         break;
3045                                 }
3046
3047                                 /* wait 1 sec */
3048                                 if (sleepFlag == CAN_SLEEP) {
3049                                         msleep_interruptible (1000);
3050                                 } else {
3051                                         mdelay (1000);
3052                                 }
3053                         }
3054                 }
3055         }
3056
3057         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3058 #ifdef MPT_DEBUG
3059         if (ioc->alt_ioc)
3060                 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3061         dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3062                 ioc->name, diag0val, diag1val));
3063 #endif
3064
3065         /* Clear RESET_HISTORY bit!  Place board in the
3066          * diagnostic mode to update the diag register.
3067          */
3068         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3069         count = 0;
3070         while ((diag0val & MPI_DIAG_DRWE) == 0) {
3071                 /* Write magic sequence to WriteSequence register
3072                  * Loop until in diagnostic mode
3073                  */
3074                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3075                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3076                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3077                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3078                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3079                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3080
3081                 /* wait 100 msec */
3082                 if (sleepFlag == CAN_SLEEP) {
3083                         msleep_interruptible (100);
3084                 } else {
3085                         mdelay (100);
3086                 }
3087
3088                 count++;
3089                 if (count > 20) {
3090                         printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3091                                         ioc->name, diag0val);
3092                         break;
3093                 }
3094                 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3095         }
3096         diag0val &= ~MPI_DIAG_RESET_HISTORY;
3097         CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3098         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3099         if (diag0val & MPI_DIAG_RESET_HISTORY) {
3100                 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3101                                 ioc->name);
3102         }
3103
3104         /* Disable Diagnostic Mode
3105          */
3106         CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3107
3108         /* Check FW reload status flags.
3109          */
3110         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3111         if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3112                 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3113                                 ioc->name, diag0val);
3114                 return -3;
3115         }
3116
3117 #ifdef MPT_DEBUG
3118         if (ioc->alt_ioc)
3119                 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3120         dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3121                         ioc->name, diag0val, diag1val));
3122 #endif
3123
3124         /*
3125          * Reset flag that says we've enabled event notification
3126          */
3127         ioc->facts.EventState = 0;
3128
3129         if (ioc->alt_ioc)
3130                 ioc->alt_ioc->facts.EventState = 0;
3131
3132         return hard_reset_done;
3133 }
3134
3135 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3136 /*
3137  *      SendIocReset - Send IOCReset request to MPT adapter.
3138  *      @ioc: Pointer to MPT_ADAPTER structure
3139  *      @reset_type: reset type, expected values are
3140  *      %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3141  *
3142  *      Send IOCReset request to the MPT adapter.
3143  *
3144  *      Returns 0 for success, non-zero for failure.
3145  */
3146 static int
3147 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3148 {
3149         int r;
3150         u32 state;
3151         int cntdn, count;
3152
3153         drsprintk((KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
3154                         ioc->name, reset_type));
3155         CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3156         if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3157                 return r;
3158
3159         /* FW ACK'd request, wait for READY state
3160          */
3161         count = 0;
3162         cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15;    /* 15 seconds */
3163
3164         while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3165                 cntdn--;
3166                 count++;
3167                 if (!cntdn) {
3168                         if (sleepFlag != CAN_SLEEP)
3169                                 count *= 10;
3170
3171                         printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3172                                         ioc->name, (int)((count+5)/HZ));
3173                         return -ETIME;
3174                 }
3175
3176                 if (sleepFlag == CAN_SLEEP) {
3177                         msleep_interruptible(1);
3178                 } else {
3179                         mdelay (1);     /* 1 msec delay */
3180                 }
3181         }
3182
3183         /* TODO!
3184          *  Cleanup all event stuff for this IOC; re-issue EventNotification
3185          *  request if needed.
3186          */
3187         if (ioc->facts.Function)
3188                 ioc->facts.EventState = 0;
3189
3190         return 0;
3191 }
3192
3193 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3194 /*
3195  *      initChainBuffers - Allocate memory for and initialize
3196  *      chain buffers, chain buffer control arrays and spinlock.
3197  *      @hd: Pointer to MPT_SCSI_HOST structure
3198  *      @init: If set, initialize the spin lock.
3199  */
3200 static int
3201 initChainBuffers(MPT_ADAPTER *ioc)
3202 {
3203         u8              *mem;
3204         int             sz, ii, num_chain;
3205         int             scale, num_sge, numSGE;
3206
3207         /* ReqToChain size must equal the req_depth
3208          * index = req_idx
3209          */
3210         if (ioc->ReqToChain == NULL) {
3211                 sz = ioc->req_depth * sizeof(int);
3212                 mem = kmalloc(sz, GFP_ATOMIC);
3213                 if (mem == NULL)
3214                         return -1;
3215
3216                 ioc->ReqToChain = (int *) mem;
3217                 dinitprintk((KERN_INFO MYNAM ": %s ReqToChain alloc  @ %p, sz=%d bytes\n",
3218                                 ioc->name, mem, sz));
3219                 mem = kmalloc(sz, GFP_ATOMIC);
3220                 if (mem == NULL)
3221                         return -1;
3222
3223                 ioc->RequestNB = (int *) mem;
3224                 dinitprintk((KERN_INFO MYNAM ": %s RequestNB alloc  @ %p, sz=%d bytes\n",
3225                                 ioc->name, mem, sz));
3226         }
3227         for (ii = 0; ii < ioc->req_depth; ii++) {
3228                 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3229         }
3230
3231         /* ChainToChain size must equal the total number
3232          * of chain buffers to be allocated.
3233          * index = chain_idx
3234          *
3235          * Calculate the number of chain buffers needed(plus 1) per I/O
3236          * then multiply the the maximum number of simultaneous cmds
3237          *
3238          * num_sge = num sge in request frame + last chain buffer
3239          * scale = num sge per chain buffer if no chain element
3240          */
3241         scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3242         if (sizeof(dma_addr_t) == sizeof(u64))
3243                 num_sge =  scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3244         else
3245                 num_sge =  1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3246
3247         if (sizeof(dma_addr_t) == sizeof(u64)) {
3248                 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3249                         (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3250         } else {
3251                 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3252                         (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3253         }
3254         dinitprintk((KERN_INFO MYNAM ": %s num_sge=%d numSGE=%d\n",
3255                 ioc->name, num_sge, numSGE));
3256
3257         if ( numSGE > MPT_SCSI_SG_DEPTH )
3258                 numSGE = MPT_SCSI_SG_DEPTH;
3259
3260         num_chain = 1;
3261         while (numSGE - num_sge > 0) {
3262                 num_chain++;
3263                 num_sge += (scale - 1);
3264         }
3265         num_chain++;
3266
3267         dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
3268                 ioc->name, numSGE, num_sge, num_chain));
3269
3270         if (ioc->bus_type == SCSI)
3271                 num_chain *= MPT_SCSI_CAN_QUEUE;
3272         else
3273                 num_chain *= MPT_FC_CAN_QUEUE;
3274
3275         ioc->num_chain = num_chain;
3276
3277         sz = num_chain * sizeof(int);
3278         if (ioc->ChainToChain == NULL) {
3279                 mem = kmalloc(sz, GFP_ATOMIC);
3280                 if (mem == NULL)
3281                         return -1;
3282
3283                 ioc->ChainToChain = (int *) mem;
3284                 dinitprintk((KERN_INFO MYNAM ": %s ChainToChain alloc @ %p, sz=%d bytes\n",
3285                                 ioc->name, mem, sz));
3286         } else {
3287                 mem = (u8 *) ioc->ChainToChain;
3288         }
3289         memset(mem, 0xFF, sz);
3290         return num_chain;
3291 }
3292
3293 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3294 /*
3295  *      PrimeIocFifos - Initialize IOC request and reply FIFOs.
3296  *      @ioc: Pointer to MPT_ADAPTER structure
3297  *
3298  *      This routine allocates memory for the MPT reply and request frame
3299  *      pools (if necessary), and primes the IOC reply FIFO with
3300  *      reply frames.
3301  *
3302  *      Returns 0 for success, non-zero for failure.
3303  */
3304 static int
3305 PrimeIocFifos(MPT_ADAPTER *ioc)
3306 {
3307         MPT_FRAME_HDR *mf;
3308         unsigned long flags;
3309         dma_addr_t alloc_dma;
3310         u8 *mem;
3311         int i, reply_sz, sz, total_size, num_chain;
3312
3313         /*  Prime reply FIFO...  */
3314
3315         if (ioc->reply_frames == NULL) {
3316                 if ( (num_chain = initChainBuffers(ioc)) < 0)
3317                         return -1;
3318
3319                 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3320                 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3321                                 ioc->name, ioc->reply_sz, ioc->reply_depth));
3322                 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d[%x] bytes\n",
3323                                 ioc->name, reply_sz, reply_sz));
3324
3325                 sz = (ioc->req_sz * ioc->req_depth);
3326                 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3327                                 ioc->name, ioc->req_sz, ioc->req_depth));
3328                 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d[%x] bytes\n",
3329                                 ioc->name, sz, sz));
3330                 total_size += sz;
3331
3332                 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3333                 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3334                                 ioc->name, ioc->req_sz, num_chain));
3335                 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3336                                 ioc->name, sz, sz, num_chain));
3337
3338                 total_size += sz;
3339                 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3340                 if (mem == NULL) {
3341                         printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3342                                 ioc->name);
3343                         goto out_fail;
3344                 }
3345
3346                 dinitprintk((KERN_INFO MYNAM ": %s.Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3347                                 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3348
3349                 memset(mem, 0, total_size);
3350                 ioc->alloc_total += total_size;
3351                 ioc->alloc = mem;
3352                 ioc->alloc_dma = alloc_dma;
3353                 ioc->alloc_sz = total_size;
3354                 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3355                 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3356
3357                 alloc_dma += reply_sz;
3358                 mem += reply_sz;
3359
3360                 /*  Request FIFO - WE manage this!  */
3361
3362                 ioc->req_frames = (MPT_FRAME_HDR *) mem;
3363                 ioc->req_frames_dma = alloc_dma;
3364
3365                 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffers @ %p[%p]\n",
3366                                 ioc->name, mem, (void *)(ulong)alloc_dma));
3367
3368                 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3369
3370 #if defined(CONFIG_MTRR) && 0
3371                 /*
3372                  *  Enable Write Combining MTRR for IOC's memory region.
3373                  *  (at least as much as we can; "size and base must be
3374                  *  multiples of 4 kiB"
3375                  */
3376                 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
3377                                          sz,
3378                                          MTRR_TYPE_WRCOMB, 1);
3379                 dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
3380                                 ioc->name, ioc->req_frames_dma, sz));
3381 #endif
3382
3383                 for (i = 0; i < ioc->req_depth; i++) {
3384                         alloc_dma += ioc->req_sz;
3385                         mem += ioc->req_sz;
3386                 }
3387
3388                 ioc->ChainBuffer = mem;
3389                 ioc->ChainBufferDMA = alloc_dma;
3390
3391                 dinitprintk((KERN_INFO MYNAM " :%s.ChainBuffers @ %p(%p)\n",
3392                         ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
3393
3394                 /* Initialize the free chain Q.
3395                 */
3396
3397                 INIT_LIST_HEAD(&ioc->FreeChainQ);
3398
3399                 /* Post the chain buffers to the FreeChainQ.
3400                 */
3401                 mem = (u8 *)ioc->ChainBuffer;
3402                 for (i=0; i < num_chain; i++) {
3403                         mf = (MPT_FRAME_HDR *) mem;
3404                         list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
3405                         mem += ioc->req_sz;
3406                 }
3407
3408                 /* Initialize Request frames linked list
3409                  */
3410                 alloc_dma = ioc->req_frames_dma;
3411                 mem = (u8 *) ioc->req_frames;
3412
3413                 spin_lock_irqsave(&ioc->FreeQlock, flags);
3414                 INIT_LIST_HEAD(&ioc->FreeQ);
3415                 for (i = 0; i < ioc->req_depth; i++) {
3416                         mf = (MPT_FRAME_HDR *) mem;
3417
3418                         /*  Queue REQUESTs *internally*!  */
3419                         list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
3420
3421                         mem += ioc->req_sz;
3422                 }
3423                 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3424
3425                 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3426                 ioc->sense_buf_pool =
3427                         pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3428                 if (ioc->sense_buf_pool == NULL) {
3429                         printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
3430                                 ioc->name);
3431                         goto out_fail;
3432                 }
3433
3434                 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
3435                 ioc->alloc_total += sz;
3436                 dinitprintk((KERN_INFO MYNAM ": %s.SenseBuffers @ %p[%p]\n",
3437                         ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
3438
3439         }
3440
3441         /* Post Reply frames to FIFO
3442          */
3443         alloc_dma = ioc->alloc_dma;
3444         dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffers @ %p[%p]\n",
3445                 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3446
3447         for (i = 0; i < ioc->reply_depth; i++) {
3448                 /*  Write each address to the IOC!  */
3449                 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
3450                 alloc_dma += ioc->reply_sz;
3451         }
3452
3453         return 0;
3454
3455 out_fail:
3456         if (ioc->alloc != NULL) {
3457                 sz = ioc->alloc_sz;
3458                 pci_free_consistent(ioc->pcidev,
3459                                 sz,
3460                                 ioc->alloc, ioc->alloc_dma);
3461                 ioc->reply_frames = NULL;
3462                 ioc->req_frames = NULL;
3463                 ioc->alloc_total -= sz;
3464         }
3465         if (ioc->sense_buf_pool != NULL) {
3466                 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3467                 pci_free_consistent(ioc->pcidev,
3468                                 sz,
3469                                 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
3470                 ioc->sense_buf_pool = NULL;
3471         }
3472         return -1;
3473 }
3474
3475 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3476 /**
3477  *      mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3478  *      from IOC via doorbell handshake method.
3479  *      @ioc: Pointer to MPT_ADAPTER structure
3480  *      @reqBytes: Size of the request in bytes
3481  *      @req: Pointer to MPT request frame
3482  *      @replyBytes: Expected size of the reply in bytes
3483  *      @u16reply: Pointer to area where reply should be written
3484  *      @maxwait: Max wait time for a reply (in seconds)
3485  *      @sleepFlag: Specifies whether the process can sleep
3486  *
3487  *      NOTES: It is the callers responsibility to byte-swap fields in the
3488  *      request which are greater than 1 byte in size.  It is also the
3489  *      callers responsibility to byte-swap response fields which are
3490  *      greater than 1 byte in size.
3491  *
3492  *      Returns 0 for success, non-zero for failure.
3493  */
3494 static int
3495 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
3496                                 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
3497 {
3498         MPIDefaultReply_t *mptReply;
3499         int failcnt = 0;
3500         int t;
3501
3502         /*
3503          * Get ready to cache a handshake reply
3504          */
3505         ioc->hs_reply_idx = 0;
3506         mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3507         mptReply->MsgLength = 0;
3508
3509         /*
3510          * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
3511          * then tell IOC that we want to handshake a request of N words.
3512          * (WRITE u32val to Doorbell reg).
3513          */
3514         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3515         CHIPREG_WRITE32(&ioc->chip->Doorbell,
3516                         ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
3517                          ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
3518
3519         /*
3520          * Wait for IOC's doorbell handshake int
3521          */
3522         if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3523                 failcnt++;
3524
3525         dhsprintk((MYIOC_s_INFO_FMT "HandShake