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