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