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