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