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