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