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