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