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