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