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