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