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