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