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