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