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