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