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