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