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