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