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