af340674e1dd3d20705be40460e4c060fa976387
[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,
1058                                     ioc->HostPageBuffer,
1059                                     ioc->HostPageBuffer_dma,
1060                                     host_page_buffer_sz));
1061                                 ioc->alloc_total += host_page_buffer_sz;
1062                                 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1063                                 break;
1064                         }
1065
1066                         host_page_buffer_sz -= (4*1024);
1067                 }
1068         }
1069
1070         if(!ioc->HostPageBuffer) {
1071                 printk(MYIOC_s_ERR_FMT
1072                     "Failed to alloc memory for host_page_buffer!\n",
1073                     ioc->name);
1074                 return -999;
1075         }
1076
1077         psge = (char *)&ioc_init->HostPageBufferSGE;
1078         flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1079             MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1080             MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1081             MPI_SGE_FLAGS_HOST_TO_IOC |
1082             MPI_SGE_FLAGS_END_OF_BUFFER;
1083         if (sizeof(dma_addr_t) == sizeof(u64)) {
1084             flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1085         }
1086         flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1087         flags_length |= ioc->HostPageBuffer_sz;
1088         mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1089         ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1090
1091 return 0;
1092 }
1093
1094 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1095 /**
1096  *      mpt_verify_adapter - Given a unique IOC identifier, set pointer to
1097  *      the associated MPT adapter structure.
1098  *      @iocid: IOC unique identifier (integer)
1099  *      @iocpp: Pointer to pointer to IOC adapter
1100  *
1101  *      Returns iocid and sets iocpp.
1102  */
1103 int
1104 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1105 {
1106         MPT_ADAPTER *ioc;
1107
1108         list_for_each_entry(ioc,&ioc_list,list) {
1109                 if (ioc->id == iocid) {
1110                         *iocpp =ioc;
1111                         return iocid;
1112                 }
1113         }
1114
1115         *iocpp = NULL;
1116         return -1;
1117 }
1118
1119 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1120 /*
1121  *      mpt_attach - Install a PCI intelligent MPT adapter.
1122  *      @pdev: Pointer to pci_dev structure
1123  *
1124  *      This routine performs all the steps necessary to bring the IOC of
1125  *      a MPT adapter to a OPERATIONAL state.  This includes registering
1126  *      memory regions, registering the interrupt, and allocating request
1127  *      and reply memory pools.
1128  *
1129  *      This routine also pre-fetches the LAN MAC address of a Fibre Channel
1130  *      MPT adapter.
1131  *
1132  *      Returns 0 for success, non-zero for failure.
1133  *
1134  *      TODO: Add support for polled controllers
1135  */
1136 int
1137 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1138 {
1139         MPT_ADAPTER     *ioc;
1140         u8              __iomem *mem;
1141         unsigned long    mem_phys;
1142         unsigned long    port;
1143         u32              msize;
1144         u32              psize;
1145         int              ii;
1146         int              r = -ENODEV;
1147         u8               revision;
1148         u8               pcixcmd;
1149         static int       mpt_ids = 0;
1150 #ifdef CONFIG_PROC_FS
1151         struct proc_dir_entry *dent, *ent;
1152 #endif
1153
1154         if (pci_enable_device(pdev))
1155                 return r;
1156
1157         dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1158
1159         if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1160                 dprintk((KERN_INFO MYNAM
1161                         ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1162         } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1163                 printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1164                 return r;
1165         }
1166
1167         if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
1168                 dprintk((KERN_INFO MYNAM
1169                         ": Using 64 bit consistent mask\n"));
1170         else
1171                 dprintk((KERN_INFO MYNAM
1172                         ": Not using 64 bit consistent mask\n"));
1173
1174         ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1175         if (ioc == NULL) {
1176                 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1177                 return -ENOMEM;
1178         }
1179         ioc->alloc_total = sizeof(MPT_ADAPTER);
1180         ioc->req_sz = MPT_DEFAULT_FRAME_SIZE;           /* avoid div by zero! */
1181         ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1182
1183         ioc->pcidev = pdev;
1184         ioc->diagPending = 0;
1185         spin_lock_init(&ioc->diagLock);
1186         spin_lock_init(&ioc->initializing_hba_lock);
1187
1188         /* Initialize the event logging.
1189          */
1190         ioc->eventTypes = 0;    /* None */
1191         ioc->eventContext = 0;
1192         ioc->eventLogSize = 0;
1193         ioc->events = NULL;
1194
1195 #ifdef MFCNT
1196         ioc->mfcnt = 0;
1197 #endif
1198
1199         ioc->cached_fw = NULL;
1200
1201         /* Initilize SCSI Config Data structure
1202          */
1203         memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1204
1205         /* Initialize the running configQ head.
1206          */
1207         INIT_LIST_HEAD(&ioc->configQ);
1208
1209         /* Initialize the fc rport list head.
1210          */
1211         INIT_LIST_HEAD(&ioc->fc_rports);
1212
1213         /* Find lookup slot. */
1214         INIT_LIST_HEAD(&ioc->list);
1215         ioc->id = mpt_ids++;
1216
1217         mem_phys = msize = 0;
1218         port = psize = 0;
1219         for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1220                 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1221                         if (psize)
1222                                 continue;
1223                         /* Get I/O space! */
1224                         port = pci_resource_start(pdev, ii);
1225                         psize = pci_resource_len(pdev,ii);
1226                 } else {
1227                         if (msize)
1228                                 continue;
1229                         /* Get memmap */
1230                         mem_phys = pci_resource_start(pdev, ii);
1231                         msize = pci_resource_len(pdev,ii);
1232                 }
1233         }
1234         ioc->mem_size = msize;
1235
1236         mem = NULL;
1237         /* Get logical ptr for PciMem0 space */
1238         /*mem = ioremap(mem_phys, msize);*/
1239         mem = ioremap(mem_phys, msize);
1240         if (mem == NULL) {
1241                 printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1242                 kfree(ioc);
1243                 return -EINVAL;
1244         }
1245         ioc->memmap = mem;
1246         dinitprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1247
1248         dinitprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1249                         &ioc->facts, &ioc->pfacts[0]));
1250
1251         ioc->mem_phys = mem_phys;
1252         ioc->chip = (SYSIF_REGS __iomem *)mem;
1253
1254         /* Save Port IO values in case we need to do downloadboot */
1255         {
1256                 u8 *pmem = (u8*)port;
1257                 ioc->pio_mem_phys = port;
1258                 ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1259         }
1260
1261         if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC909) {
1262                 ioc->prod_name = "LSIFC909";
1263                 ioc->bus_type = FC;
1264         }
1265         else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
1266                 ioc->prod_name = "LSIFC929";
1267                 ioc->bus_type = FC;
1268         }
1269         else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) {
1270                 ioc->prod_name = "LSIFC919";
1271                 ioc->bus_type = FC;
1272         }
1273         else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) {
1274                 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1275                 ioc->bus_type = FC;
1276                 if (revision < XL_929) {
1277                         ioc->prod_name = "LSIFC929X";
1278                         /* 929X Chip Fix. Set Split transactions level
1279                         * for PCIX. Set MOST bits to zero.
1280                         */
1281                         pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1282                         pcixcmd &= 0x8F;
1283                         pci_write_config_byte(pdev, 0x6a, pcixcmd);
1284                 } else {
1285                         ioc->prod_name = "LSIFC929XL";
1286                         /* 929XL Chip Fix. Set MMRBC to 0x08.
1287                         */
1288                         pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1289                         pcixcmd |= 0x08;
1290                         pci_write_config_byte(pdev, 0x6a, pcixcmd);
1291                 }
1292         }
1293         else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) {
1294                 ioc->prod_name = "LSIFC919X";
1295                 ioc->bus_type = FC;
1296                 /* 919X Chip Fix. Set Split transactions level
1297                  * for PCIX. Set MOST bits to zero.
1298                  */
1299                 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1300                 pcixcmd &= 0x8F;
1301                 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1302         }
1303         else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC939X) {
1304                 ioc->prod_name = "LSIFC939X";
1305                 ioc->bus_type = FC;
1306                 ioc->errata_flag_1064 = 1;
1307         }
1308         else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949X) {
1309                 ioc->prod_name = "LSIFC949X";
1310                 ioc->bus_type = FC;
1311                 ioc->errata_flag_1064 = 1;
1312         }
1313         else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949E) {
1314                 ioc->prod_name = "LSIFC949E";
1315                 ioc->bus_type = FC;
1316         }
1317         else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
1318                 ioc->prod_name = "LSI53C1030";
1319                 ioc->bus_type = SPI;
1320                 /* 1030 Chip Fix. Disable Split transactions
1321                  * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1322                  */
1323                 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1324                 if (revision < C0_1030) {
1325                         pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1326                         pcixcmd &= 0x8F;
1327                         pci_write_config_byte(pdev, 0x6a, pcixcmd);
1328                 }
1329         }
1330         else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
1331                 ioc->prod_name = "LSI53C1035";
1332                 ioc->bus_type = SPI;
1333         }
1334         else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064) {
1335                 ioc->prod_name = "LSISAS1064";
1336                 ioc->bus_type = SAS;
1337                 ioc->errata_flag_1064 = 1;
1338         }
1339         else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) {
1340                 ioc->prod_name = "LSISAS1068";
1341                 ioc->bus_type = SAS;
1342                 ioc->errata_flag_1064 = 1;
1343         }
1344         else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064E) {
1345                 ioc->prod_name = "LSISAS1064E";
1346                 ioc->bus_type = SAS;
1347         }
1348         else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) {
1349                 ioc->prod_name = "LSISAS1068E";
1350                 ioc->bus_type = SAS;
1351         }
1352         else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
1353                 ioc->prod_name = "LSISAS1078";
1354                 ioc->bus_type = SAS;
1355         }
1356
1357         if (ioc->errata_flag_1064)
1358                 pci_disable_io_access(pdev);
1359
1360         sprintf(ioc->name, "ioc%d", ioc->id);
1361
1362         spin_lock_init(&ioc->FreeQlock);
1363
1364         /* Disable all! */
1365         CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1366         ioc->active = 0;
1367         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1368
1369         /* Set lookup ptr. */
1370         list_add_tail(&ioc->list, &ioc_list);
1371
1372         /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1373          */
1374         mpt_detect_bound_ports(ioc, pdev);
1375
1376         if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1377             CAN_SLEEP)) != 0){
1378                 printk(KERN_WARNING MYNAM
1379                   ": WARNING - %s did not initialize properly! (%d)\n",
1380                   ioc->name, r);
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         return r;
2672 }
2673
2674 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2675 /*
2676  *      SendPortEnable - Send PortEnable request to MPT adapter port.
2677  *      @ioc: Pointer to MPT_ADAPTER structure
2678  *      @portnum: Port number to enable
2679  *      @sleepFlag: Specifies whether the process can sleep
2680  *
2681  *      Send PortEnable to bring IOC to OPERATIONAL state.
2682  *
2683  *      Returns 0 for success, non-zero for failure.
2684  */
2685 static int
2686 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2687 {
2688         PortEnable_t             port_enable;
2689         MPIDefaultReply_t        reply_buf;
2690         int      rc;
2691         int      req_sz;
2692         int      reply_sz;
2693
2694         /*  Destination...  */
2695         reply_sz = sizeof(MPIDefaultReply_t);
2696         memset(&reply_buf, 0, reply_sz);
2697
2698         req_sz = sizeof(PortEnable_t);
2699         memset(&port_enable, 0, req_sz);
2700
2701         port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2702         port_enable.PortNumber = portnum;
2703 /*      port_enable.ChainOffset = 0;            */
2704 /*      port_enable.MsgFlags = 0;               */
2705 /*      port_enable.MsgContext = 0;             */
2706
2707         dinitprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
2708                         ioc->name, portnum, &port_enable));
2709
2710         /* RAID FW may take a long time to enable
2711          */
2712         if (((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2713             > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) ||
2714             (ioc->bus_type == SAS)) {
2715                 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2716                 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2717                 300 /*seconds*/, sleepFlag);
2718         } else {
2719                 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2720                 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2721                 30 /*seconds*/, sleepFlag);
2722         }
2723         return rc;
2724 }
2725
2726 /*
2727  *      ioc: Pointer to MPT_ADAPTER structure
2728  *      size - total FW bytes
2729  */
2730 void
2731 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
2732 {
2733         if (ioc->cached_fw)
2734                 return;  /* use already allocated memory */
2735         if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2736                 ioc->cached_fw = ioc->alt_ioc->cached_fw;  /* use alt_ioc's memory */
2737                 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
2738                 ioc->alloc_total += size;
2739                 ioc->alt_ioc->alloc_total -= size;
2740         } else {
2741                 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
2742                         ioc->alloc_total += size;
2743         }
2744 }
2745 /*
2746  * If alt_img is NULL, delete from ioc structure.
2747  * Else, delete a secondary image in same format.
2748  */
2749 void
2750 mpt_free_fw_memory(MPT_ADAPTER *ioc)
2751 {
2752         int sz;
2753
2754         sz = ioc->facts.FWImageSize;
2755         dinitprintk((KERN_INFO MYNAM "free_fw_memory: FW Image  @ %p[%p], sz=%d[%x] bytes\n",
2756                  ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2757         pci_free_consistent(ioc->pcidev, sz,
2758                         ioc->cached_fw, ioc->cached_fw_dma);
2759         ioc->cached_fw = NULL;
2760
2761         return;
2762 }
2763
2764
2765 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2766 /*
2767  *      mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
2768  *      @ioc: Pointer to MPT_ADAPTER structure
2769  *      @sleepFlag: Specifies whether the process can sleep
2770  *
2771  *      Returns 0 for success, >0 for handshake failure
2772  *              <0 for fw upload failure.
2773  *
2774  *      Remark: If bound IOC and a successful FWUpload was performed
2775  *      on the bound IOC, the second image is discarded
2776  *      and memory is free'd. Both channels must upload to prevent
2777  *      IOC from running in degraded mode.
2778  */
2779 static int
2780 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2781 {
2782         u8                       request[ioc->req_sz];
2783         u8                       reply[sizeof(FWUploadReply_t)];
2784         FWUpload_t              *prequest;
2785         FWUploadReply_t         *preply;
2786         FWUploadTCSGE_t         *ptcsge;
2787         int                      sgeoffset;
2788         u32                      flagsLength;
2789         int                      ii, sz, reply_sz;
2790         int                      cmdStatus;
2791
2792         /* If the image size is 0, we are done.
2793          */
2794         if ((sz = ioc->facts.FWImageSize) == 0)
2795                 return 0;
2796
2797         mpt_alloc_fw_memory(ioc, sz);
2798
2799         dinitprintk((KERN_INFO MYNAM ": FW Image  @ %p[%p], sz=%d[%x] bytes\n",
2800                  ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2801
2802         if (ioc->cached_fw == NULL) {
2803                 /* Major Failure.
2804                  */
2805                 return -ENOMEM;
2806         }
2807
2808         prequest = (FWUpload_t *)&request;
2809         preply = (FWUploadReply_t *)&reply;
2810
2811         /*  Destination...  */
2812         memset(prequest, 0, ioc->req_sz);
2813
2814         reply_sz = sizeof(reply);
2815         memset(preply, 0, reply_sz);
2816
2817         prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
2818         prequest->Function = MPI_FUNCTION_FW_UPLOAD;
2819
2820         ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
2821         ptcsge->DetailsLength = 12;
2822         ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
2823         ptcsge->ImageSize = cpu_to_le32(sz);
2824
2825         sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
2826
2827         flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
2828         mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
2829
2830         sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
2831         dinitprintk((KERN_INFO MYNAM ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
2832                         prequest, sgeoffset));
2833         DBG_DUMP_FW_REQUEST_FRAME(prequest)
2834
2835         ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
2836                                 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
2837
2838         dinitprintk((KERN_INFO MYNAM ": FW Upload completed rc=%x \n", ii));
2839
2840         cmdStatus = -EFAULT;
2841         if (ii == 0) {
2842                 /* Handshake transfer was complete and successful.
2843                  * Check the Reply Frame.
2844                  */
2845                 int status, transfer_sz;
2846                 status = le16_to_cpu(preply->IOCStatus);
2847                 if (status == MPI_IOCSTATUS_SUCCESS) {
2848                         transfer_sz = le32_to_cpu(preply->ActualImageSize);
2849                         if (transfer_sz == sz)
2850                                 cmdStatus = 0;
2851                 }
2852         }
2853         dinitprintk((MYIOC_s_INFO_FMT ": do_upload cmdStatus=%d \n",
2854                         ioc->name, cmdStatus));
2855
2856
2857         if (cmdStatus) {
2858
2859                 ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
2860                         ioc->name));
2861                 mpt_free_fw_memory(ioc);
2862         }
2863
2864         return cmdStatus;
2865 }
2866
2867 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2868 /*
2869  *      mpt_downloadboot - DownloadBoot code
2870  *      @ioc: Pointer to MPT_ADAPTER structure
2871  *      @flag: Specify which part of IOC memory is to be uploaded.
2872  *      @sleepFlag: Specifies whether the process can sleep
2873  *
2874  *      FwDownloadBoot requires Programmed IO access.
2875  *
2876  *      Returns 0 for success
2877  *              -1 FW Image size is 0
2878  *              -2 No valid cached_fw Pointer
2879  *              <0 for fw upload failure.
2880  */
2881 static int
2882 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
2883 {
2884         MpiExtImageHeader_t     *pExtImage;
2885         u32                      fwSize;
2886         u32                      diag0val;
2887         int                      count;
2888         u32                     *ptrFw;
2889         u32                      diagRwData;
2890         u32                      nextImage;
2891         u32                      load_addr;
2892         u32                      ioc_state=0;
2893
2894         ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
2895                                 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
2896
2897         CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2898         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2899         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2900         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2901         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2902         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2903
2904         CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
2905
2906         /* wait 1 msec */
2907         if (sleepFlag == CAN_SLEEP) {
2908                 msleep(1);
2909         } else {
2910                 mdelay (1);
2911         }
2912
2913         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2914         CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2915
2916         for (count = 0; count < 30; count ++) {
2917                 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2918                 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
2919                         ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
2920                                 ioc->name, count));
2921                         break;
2922                 }
2923                 /* wait .1 sec */
2924                 if (sleepFlag == CAN_SLEEP) {
2925                         msleep (100);
2926                 } else {
2927                         mdelay (100);
2928                 }
2929         }
2930
2931         if ( count == 30 ) {
2932                 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! "
2933                 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
2934                 ioc->name, diag0val));
2935                 return -3;
2936         }
2937
2938         CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2939         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2940         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2941         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2942         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2943         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2944
2945         /* Set the DiagRwEn and Disable ARM bits */
2946         CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
2947
2948         fwSize = (pFwHeader->ImageSize + 3)/4;
2949         ptrFw = (u32 *) pFwHeader;
2950
2951         /* Write the LoadStartAddress to the DiagRw Address Register
2952          * using Programmed IO
2953          */
2954         if (ioc->errata_flag_1064)
2955                 pci_enable_io_access(ioc->pcidev);
2956
2957         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
2958         ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
2959                 ioc->name, pFwHeader->LoadStartAddress));
2960
2961         ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n",
2962                                 ioc->name, fwSize*4, ptrFw));
2963         while (fwSize--) {
2964                 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2965         }
2966
2967         nextImage = pFwHeader->NextImageHeaderOffset;
2968         while (nextImage) {
2969                 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
2970
2971                 load_addr = pExtImage->LoadStartAddress;
2972
2973                 fwSize = (pExtImage->ImageSize + 3) >> 2;
2974                 ptrFw = (u32 *)pExtImage;
2975
2976                 ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
2977                                                 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
2978                 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
2979
2980                 while (fwSize--) {
2981                         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2982                 }
2983                 nextImage = pExtImage->NextImageHeaderOffset;
2984         }
2985
2986         /* Write the IopResetVectorRegAddr */
2987         ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name,      pFwHeader->IopResetRegAddr));
2988         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
2989
2990         /* Write the IopResetVectorValue */
2991         ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
2992         CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
2993
2994         /* Clear the internal flash bad bit - autoincrementing register,
2995          * so must do two writes.
2996          */
2997         if (ioc->bus_type == SPI) {
2998                 /*
2999                  * 1030 and 1035 H/W errata, workaround to access
3000                  * the ClearFlashBadSignatureBit
3001                  */
3002                 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3003                 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3004                 diagRwData |= 0x40000000;
3005                 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3006                 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3007
3008         } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3009                 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3010                 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3011                     MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3012
3013                 /* wait 1 msec */
3014                 if (sleepFlag == CAN_SLEEP) {
3015                         msleep (1);
3016                 } else {
3017                         mdelay (1);
3018                 }
3019         }
3020
3021         if (ioc->errata_flag_1064)
3022                 pci_disable_io_access(ioc->pcidev);
3023
3024         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3025         ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, "
3026                 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3027                 ioc->name, diag0val));
3028         diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3029         ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
3030                 ioc->name, diag0val));
3031         CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3032
3033         /* Write 0xFF to reset the sequencer */
3034         CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3035
3036         if (ioc->bus_type == SAS) {
3037                 ioc_state = mpt_GetIocState(ioc, 0);
3038                 if ( (GetIocFacts(ioc, sleepFlag,
3039                                 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3040                         ddlprintk((MYIOC_s_INFO_FMT "GetIocFacts failed: IocState=%x\n",
3041                                         ioc->name, ioc_state));
3042                         return -EFAULT;
3043                 }
3044         }
3045
3046         for (count=0; count<HZ*20; count++) {
3047                 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3048                         ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
3049                                         ioc->name, count, ioc_state));
3050                         if (ioc->bus_type == SAS) {
3051                                 return 0;
3052                         }
3053                         if ((SendIocInit(ioc, sleepFlag)) != 0) {
3054                                 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
3055                                         ioc->name));
3056                                 return -EFAULT;
3057                         }
3058                         ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit successful\n",
3059                                         ioc->name));
3060                         return 0;
3061                 }
3062                 if (sleepFlag == CAN_SLEEP) {
3063                         msleep (10);
3064                 } else {
3065                         mdelay (10);
3066                 }
3067         }
3068         ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! IocState=%x\n",
3069                 ioc->name, ioc_state));
3070         return -EFAULT;
3071 }
3072
3073 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3074 /*
3075  *      KickStart - Perform hard reset of MPT adapter.
3076  *      @ioc: Pointer to MPT_ADAPTER structure
3077  *      @force: Force hard reset
3078  *      @sleepFlag: Specifies whether the process can sleep
3079  *
3080  *      This routine places MPT adapter in diagnostic mode via the
3081  *      WriteSequence register, and then performs a hard reset of adapter
3082  *      via the Diagnostic register.
3083  *
3084  *      Inputs:   sleepflag - CAN_SLEEP (non-interrupt thread)
3085  *                      or NO_SLEEP (interrupt thread, use mdelay)
3086  *                force - 1 if doorbell active, board fault state
3087  *                              board operational, IOC_RECOVERY or
3088  *                              IOC_BRINGUP and there is an alt_ioc.
3089  *                        0 else
3090  *
3091  *      Returns:
3092  *               1 - hard reset, READY
3093  *               0 - no reset due to History bit, READY
3094  *              -1 - no reset due to History bit but not READY
3095  *                   OR reset but failed to come READY
3096  *              -2 - no reset, could not enter DIAG mode
3097  *              -3 - reset but bad FW bit
3098  */
3099 static int
3100 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3101 {
3102         int hard_reset_done = 0;
3103         u32 ioc_state=0;
3104         int cnt,cntdn;
3105
3106         dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
3107         if (ioc->bus_type == SPI) {
3108                 /* Always issue a Msg Unit Reset first. This will clear some
3109                  * SCSI bus hang conditions.
3110                  */
3111                 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3112
3113                 if (sleepFlag == CAN_SLEEP) {
3114                         msleep (1000);
3115                 } else {
3116                         mdelay (1000);
3117                 }
3118         }
3119
3120         hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3121         if (hard_reset_done < 0)
3122                 return hard_reset_done;
3123
3124         dinitprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
3125                         ioc->name));
3126
3127         cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2;     /* 2 seconds */
3128         for (cnt=0; cnt<cntdn; cnt++) {
3129                 ioc_state = mpt_GetIocState(ioc, 1);
3130                 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3131                         dinitprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
3132                                         ioc->name, cnt));
3133                         return hard_reset_done;
3134                 }
3135                 if (sleepFlag == CAN_SLEEP) {
3136                         msleep (10);
3137                 } else {
3138                         mdelay (10);
3139                 }
3140         }
3141
3142         printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3143                         ioc->name, ioc_state);
3144         return -1;
3145 }
3146
3147 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3148 /*
3149  *      mpt_diag_reset - Perform hard reset of the adapter.
3150  *      @ioc: Pointer to MPT_ADAPTER structure
3151  *      @ignore: Set if to honor and clear to ignore
3152  *              the reset history bit
3153  *      @sleepflag: CAN_SLEEP if called in a non-interrupt thread,
3154  *              else set to NO_SLEEP (use mdelay instead)
3155  *
3156  *      This routine places the adapter in diagnostic mode via the
3157  *      WriteSequence register and then performs a hard reset of adapter
3158  *      via the Diagnostic register. Adapter should be in ready state
3159  *      upon successful completion.
3160  *
3161  *      Returns:  1  hard reset successful
3162  *                0  no reset performed because reset history bit set
3163  *               -2  enabling diagnostic mode failed
3164  *               -3  diagnostic reset failed
3165  */
3166 static int
3167 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3168 {
3169         MPT_ADAPTER     *iocp=NULL;
3170         u32 diag0val;
3171         u32 doorbell;
3172         int hard_reset_done = 0;
3173         int count = 0;
3174 #ifdef MPT_DEBUG
3175         u32 diag1val = 0;
3176 #endif
3177
3178         if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3179                 drsprintk((MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3180                         "address=%p\n",  ioc->name, __FUNCTION__,
3181                         &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3182                 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3183                 if (sleepFlag == CAN_SLEEP)
3184                         msleep(1);
3185                 else
3186                         mdelay(1);
3187
3188                 for (count = 0; count < 60; count ++) {
3189                         doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3190                         doorbell &= MPI_IOC_STATE_MASK;
3191
3192                         drsprintk((MYIOC_s_INFO_FMT
3193                                 "looking for READY STATE: doorbell=%x"
3194                                 " count=%d\n",
3195                                 ioc->name, doorbell, count));
3196                         if (doorbell == MPI_IOC_STATE_READY) {
3197                                 return 0;
3198                         }
3199
3200                         /* wait 1 sec */
3201                         if (sleepFlag == CAN_SLEEP)
3202                                 msleep(1000);
3203                         else
3204                                 mdelay(1000);
3205                 }
3206                 return -1;
3207         }
3208
3209         /* Clear any existing interrupts */
3210         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3211
3212         /* Use "Diagnostic reset" method! (only thing available!) */
3213         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3214
3215 #ifdef MPT_DEBUG
3216         if (ioc->alt_ioc)
3217                 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3218         dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3219                         ioc->name, diag0val, diag1val));
3220 #endif
3221
3222         /* Do the reset if we are told to ignore the reset history
3223          * or if the reset history is 0
3224          */
3225         if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3226                 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3227                         /* Write magic sequence to WriteSequence register
3228                          * Loop until in diagnostic mode
3229                          */
3230                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3231                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3232                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3233                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3234                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3235                         CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3236
3237                         /* wait 100 msec */
3238                         if (sleepFlag == CAN_SLEEP) {
3239                                 msleep (100);
3240                         } else {
3241                                 mdelay (100);
3242                         }
3243
3244                         count++;
3245                         if (count > 20) {
3246                                 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3247                                                 ioc->name, diag0val);
3248                                 return -2;
3249
3250                         }
3251
3252                         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3253
3254                         dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3255                                         ioc->name, diag0val));
3256                 }
3257
3258 #ifdef MPT_DEBUG
3259                 if (ioc->alt_ioc)
3260                         diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3261                 dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3262                                 ioc->name, diag0val, diag1val));
3263 #endif
3264                 /*
3265                  * Disable the ARM (Bug fix)
3266                  *
3267                  */
3268                 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3269                 mdelay(1);
3270
3271                 /*
3272                  * Now hit the reset bit in the Diagnostic register
3273                  * (THE BIG HAMMER!) (Clears DRWE bit).
3274                  */
3275                 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3276                 hard_reset_done = 1;
3277                 dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
3278                                 ioc->name));
3279
3280                 /*
3281                  * Call each currently registered protocol IOC reset handler
3282                  * with pre-reset indication.
3283                  * NOTE: If we're doing _IOC_BRINGUP, there can be no
3284                  * MptResetHandlers[] registered yet.
3285                  */
3286                 {
3287                         int      ii;
3288                         int      r = 0;
3289
3290                         for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
3291                                 if (MptResetHandlers[ii]) {
3292                                         dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
3293                                                         ioc->name, ii));
3294                                         r += mpt_signal_reset(ii, ioc, MPT_IOC_PRE_RESET);
3295                                         if (ioc->alt_ioc) {
3296                                                 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3297                                                                 ioc->name, ioc->alt_ioc->name, ii));
3298                                                 r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3299                                         }
3300                                 }
3301                         }
3302                         /* FIXME?  Examine results here? */
3303                 }
3304
3305                 if (ioc->cached_fw)
3306                         iocp = ioc;
3307                 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3308                         iocp = ioc->alt_ioc;
3309                 if (iocp) {
3310                         /* If the DownloadBoot operation fails, the
3311                          * IOC will be left unusable. This is a fatal error
3312                          * case.  _diag_reset will return < 0
3313                          */
3314                         for (count = 0; count < 30; count ++) {
3315                                 diag0val = CHIPREG_READ32(&iocp->chip->Diagnostic);
3316                                 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3317                                         break;
3318                                 }
3319
3320                                 dprintk((MYIOC_s_INFO_FMT "cached_fw: diag0val=%x count=%d\n",
3321                                         iocp->name, diag0val, count));
3322                                 /* wait 1 sec */
3323                                 if (sleepFlag == CAN_SLEEP) {
3324                                         msleep (1000);
3325                                 } else {
3326                                         mdelay (1000);
3327                                 }
3328                         }
3329                         if ((count = mpt_downloadboot(ioc,
3330                                 (MpiFwHeader_t *)iocp->cached_fw, sleepFlag)) < 0) {
3331                                 printk(KERN_WARNING MYNAM
3332                                         ": firmware downloadboot failure (%d)!\n", count);
3333                         }
3334
3335                 } else {
3336                         /* Wait for FW to reload and for board
3337                          * to go to the READY state.
3338                          * Maximum wait is 60 seconds.
3339                          * If fail, no error will check again
3340                          * with calling program.
3341                          */
3342                         for (count = 0; count < 60; count ++) {
3343                                 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3344                                 doorbell &= MPI_IOC_STATE_MASK;
3345
3346                                 if (doorbell == MPI_IOC_STATE_READY) {
3347                                         break;
3348                                 }
3349
3350                                 /* wait 1 sec */
3351                                 if (sleepFlag == CAN_SLEEP) {
3352                                         msleep (1000);
3353                                 } else {
3354                                         mdelay (1000);
3355                                 }
3356                         }
3357                 }
3358         }
3359
3360         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3361 #ifdef MPT_DEBUG
3362         if (ioc->alt_ioc)
3363                 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3364         dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3365                 ioc->name, diag0val, diag1val));
3366 #endif
3367
3368         /* Clear RESET_HISTORY bit!  Place board in the
3369          * diagnostic mode to update the diag register.
3370          */
3371         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3372         count = 0;
3373         while ((diag0val & MPI_DIAG_DRWE) == 0) {
3374                 /* Write magic sequence to WriteSequence register
3375                  * Loop until in diagnostic mode
3376                  */
3377                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3378                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3379                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3380                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3381                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3382                 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3383
3384                 /* wait 100 msec */
3385                 if (sleepFlag == CAN_SLEEP) {
3386                         msleep (100);
3387                 } else {
3388                         mdelay (100);
3389                 }
3390
3391                 count++;
3392                 if (count > 20) {
3393                         printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3394                                         ioc->name, diag0val);
3395                         break;
3396                 }
3397                 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3398         }
3399         diag0val &= ~MPI_DIAG_RESET_HISTORY;
3400         CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3401         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3402         if (diag0val & MPI_DIAG_RESET_HISTORY) {
3403                 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3404                                 ioc->name);
3405         }
3406
3407         /* Disable Diagnostic Mode
3408          */
3409         CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3410
3411         /* Check FW reload status flags.
3412          */
3413         diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3414         if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3415                 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3416                                 ioc->name, diag0val);
3417                 return -3;
3418         }
3419
3420 #ifdef MPT_DEBUG
3421         if (ioc->alt_ioc)
3422                 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3423         dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3424                         ioc->name, diag0val, diag1val));
3425 #endif
3426
3427         /*
3428          * Reset flag that says we've enabled event notification
3429          */
3430         ioc->facts.EventState = 0;
3431
3432         if (ioc->alt_ioc)
3433                 ioc->alt_ioc->facts.EventState = 0;
3434
3435         return hard_reset_done;
3436 }
3437
3438 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3439 /*
3440  *      SendIocReset - Send IOCReset request to MPT adapter.
3441  *      @ioc: Pointer to MPT_ADAPTER structure
3442  *      @reset_type: reset type, expected values are
3443  *      %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3444  *
3445  *      Send IOCReset request to the MPT adapter.
3446  *
3447  *      Returns 0 for success, non-zero for failure.
3448  */
3449 static int
3450 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3451 {
3452         int r;
3453         u32 state;
3454         int cntdn, count;
3455
3456         drsprintk((KERN_INFO MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
3457                         ioc->name, reset_type));
3458         CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3459         if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3460                 return r;
3461
3462         /* FW ACK'd request, wait for READY state
3463          */
3464         count = 0;
3465         cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15;    /* 15 seconds */
3466
3467         while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3468                 cntdn--;
3469                 count++;
3470                 if (!cntdn) {
3471                         if (sleepFlag != CAN_SLEEP)
3472                                 count *= 10;
3473
3474                         printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3475                                         ioc->name, (int)((count+5)/HZ));
3476                         return -ETIME;
3477                 }
3478
3479                 if (sleepFlag == CAN_SLEEP) {
3480                         msleep(1);
3481                 } else {
3482                         mdelay (1);     /* 1 msec delay */
3483                 }
3484         }
3485
3486         /* TODO!
3487          *  Cleanup all event stuff for this IOC; re-issue EventNotification
3488          *  request if needed.
3489          */
3490         if (ioc->facts.Function)
3491                 ioc->facts.EventState = 0;
3492
3493         return 0;
3494 }
3495
3496 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3497 /*
3498  *      initChainBuffers - Allocate memory for and initialize
3499  *      chain buffers, chain buffer control arrays and spinlock.
3500  *      @hd: Pointer to MPT_SCSI_HOST structure
3501  *      @init: If set, initialize the spin lock.
3502  */
3503 static int
3504 initChainBuffers(MPT_ADAPTER *ioc)
3505 {
3506         u8              *mem;
3507         int             sz, ii, num_chain;
3508         int             scale, num_sge, numSGE;
3509
3510         /* ReqToChain size must equal the req_depth
3511          * index = req_idx
3512          */
3513         if (ioc->ReqToChain == NULL) {
3514                 sz = ioc->req_depth * sizeof(int);
3515                 mem = kmalloc(sz, GFP_ATOMIC);
3516                 if (mem == NULL)
3517                         return -1;
3518
3519                 ioc->ReqToChain = (int *) mem;
3520                 dinitprintk((KERN_INFO MYNAM ": %s ReqToChain alloc  @ %p, sz=%d bytes\n",
3521                                 ioc->name, mem, sz));
3522                 mem = kmalloc(sz, GFP_ATOMIC);
3523                 if (mem == NULL)
3524                         return -1;
3525
3526                 ioc->RequestNB = (int *) mem;
3527                 dinitprintk((KERN_INFO MYNAM ": %s RequestNB alloc  @ %p, sz=%d bytes\n",
3528                                 ioc->name, mem, sz));
3529         }
3530         for (ii = 0; ii < ioc->req_depth; ii++) {
3531                 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3532         }
3533
3534         /* ChainToChain size must equal the total number
3535          * of chain buffers to be allocated.
3536          * index = chain_idx
3537          *
3538          * Calculate the number of chain buffers needed(plus 1) per I/O
3539          * then multiply the the maximum number of simultaneous cmds
3540          *
3541          * num_sge = num sge in request frame + last chain buffer
3542          * scale = num sge per chain buffer if no chain element
3543          */
3544         scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3545         if (sizeof(dma_addr_t) == sizeof(u64))
3546                 num_sge =  scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3547         else
3548                 num_sge =  1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3549
3550         if (sizeof(dma_addr_t) == sizeof(u64)) {
3551                 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3552                         (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3553         } else {
3554                 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3555                         (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3556         }
3557         dinitprintk((KERN_INFO MYNAM ": %s num_sge=%d numSGE=%d\n",
3558                 ioc->name, num_sge, numSGE));
3559
3560         if ( numSGE > MPT_SCSI_SG_DEPTH )
3561                 numSGE = MPT_SCSI_SG_DEPTH;
3562
3563         num_chain = 1;
3564         while (numSGE - num_sge > 0) {
3565                 num_chain++;
3566                 num_sge += (scale - 1);
3567         }
3568         num_chain++;
3569
3570         dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
3571                 ioc->name, numSGE, num_sge, num_chain));
3572
3573         if (ioc->bus_type == SPI)
3574                 num_chain *= MPT_SCSI_CAN_QUEUE;
3575         else
3576                 num_chain *= MPT_FC_CAN_QUEUE;
3577
3578         ioc->num_chain = num_chain;
3579
3580         sz = num_chain * sizeof(int);
3581         if (ioc->ChainToChain == NULL) {
3582                 mem = kmalloc(sz, GFP_ATOMIC);
3583                 if (mem == NULL)
3584                         return -1;
3585
3586                 ioc->ChainToChain = (int *) mem;
3587                 dinitprintk((KERN_INFO MYNAM ": %s ChainToChain alloc @ %p, sz=%d bytes\n",
3588                                 ioc->name, mem, sz));
3589         } else {
3590                 mem = (u8 *) ioc->ChainToChain;
3591         }
3592         memset(mem, 0xFF, sz);
3593         return num_chain;
3594 }
3595
3596 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3597 /*
3598  *      PrimeIocFifos - Initialize IOC request and reply FIFOs.
3599  *      @ioc: Pointer to MPT_ADAPTER structure
3600  *
3601  *      This routine allocates memory for the MPT reply and request frame
3602  *      pools (if necessary), and primes the IOC reply FIFO with
3603  *      reply frames.
3604  *
3605  *      Returns 0 for success, non-zero for failure.
3606  */
3607 static int
3608 PrimeIocFifos(MPT_ADAPTER *ioc)
3609 {
3610         MPT_FRAME_HDR *mf;
3611         unsigned long flags;
3612         dma_addr_t alloc_dma;
3613         u8 *mem;
3614         int i, reply_sz, sz, total_size, num_chain;
3615
3616         /*  Prime reply FIFO...  */
3617
3618         if (ioc->reply_frames == NULL) {
3619                 if ( (num_chain = initChainBuffers(ioc)) < 0)
3620                         return -1;
3621
3622                 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3623                 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3624                                 ioc->name, ioc->reply_sz, ioc->reply_depth));
3625                 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d[%x] bytes\n",
3626                                 ioc->name, reply_sz, reply_sz));
3627
3628                 sz = (ioc->req_sz * ioc->req_depth);
3629                 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3630                                 ioc->name, ioc->req_sz, ioc->req_depth));
3631                 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d[%x] bytes\n",
3632                                 ioc->name, sz, sz));
3633                 total_size += sz;
3634
3635                 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3636                 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3637                                 ioc->name, ioc->req_sz, num_chain));
3638                 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3639                                 ioc->name, sz, sz, num_chain));
3640
3641                 total_size += sz;
3642                 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3643                 if (mem == NULL) {
3644                         printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3645                                 ioc->name);
3646                         goto out_fail;
3647                 }
3648
3649                 dinitprintk((KERN_INFO MYNAM ": %s.Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3650                                 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3651
3652                 memset(mem, 0, total_size);
3653                 ioc->alloc_total += total_size;
3654                 ioc->alloc = mem;
3655                 ioc->alloc_dma = alloc_dma;
3656                 ioc->alloc_sz = total_size;
3657                 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3658                 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3659
3660                 dinitprintk((KERN_INFO MYNAM ": %s ReplyBuffers @ %p[%p]\n",
3661                         ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3662
3663                 alloc_dma += reply_sz;
3664                 mem += reply_sz;
3665
3666                 /*  Request FIFO - WE manage this!  */
3667
3668                 ioc->req_frames = (MPT_FRAME_HDR *) mem;
3669                 ioc->req_frames_dma = alloc_dma;
3670
3671                 dinitprintk((KERN_INFO MYNAM ": %s RequestBuffers @ %p[%p]\n",
3672                                 ioc->name, mem, (void *)(ulong)alloc_dma));
3673
3674                 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3675
3676 #if defined(CONFIG_MTRR) && 0
3677                 /*
3678                  *  Enable Write Combining MTRR for IOC's memory region.
3679                  *  (at least as much as we can; "size and base must be
3680                  *  multiples of 4 kiB"
3681                  */
3682                 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
3683                                          sz,
3684                                          MTRR_TYPE_WRCOMB, 1);
3685                 dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
3686                                 ioc->name, ioc->req_frames_dma, sz));
3687 #endif
3688
3689                 for (i = 0; i < ioc->req_depth; i++) {
3690                         alloc_dma += ioc->req_sz;
3691                         mem += ioc->req_sz;
3692                 }
3693
3694                 ioc->ChainBuffer = mem;
3695                 ioc->ChainBufferDMA = alloc_dma;
3696
3697                 dinitprintk((KERN_INFO MYNAM " :%s ChainBuffers @ %p(%p)\n",
3698                         ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
3699
3700                 /* Initialize the free chain Q.
3701                 */
3702
3703                 INIT_LIST_HEAD(&ioc->FreeChainQ);
3704
3705                 /* Post the chain buffers to the FreeChainQ.
3706                 */
3707                 mem = (u8 *)ioc->ChainBuffer;
3708                 for (i=0; i < num_chain; i++) {
3709                         mf = (MPT_FRAME_HDR *) mem;
3710                         list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
3711                         mem += ioc->req_sz;
3712                 }
3713
3714                 /* Initialize Request frames linked list
3715                  */
3716                 alloc_dma = ioc->req_frames_dma;
3717                 mem = (u8 *) ioc->req_frames;
3718
3719                 spin_lock_irqsave(&ioc->FreeQlock, flags);
3720                 INIT_LIST_HEAD(&ioc->FreeQ);
3721                 for (i = 0; i < ioc->req_depth; i++) {
3722                         mf = (MPT_FRAME_HDR *) mem;
3723
3724                         /*  Queue REQUESTs *internally*!  */
3725                         list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
3726
3727                         mem += ioc->req_sz;
3728                 }
3729                 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3730
3731                 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3732                 ioc->sense_buf_pool =
3733                         pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3734                 if (ioc->sense_buf_pool == NULL) {
3735                         printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
3736                                 ioc->name);
3737                         goto out_fail;
3738                 }
3739
3740                 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
3741                 ioc->alloc_total += sz;
3742                 dinitprintk((KERN_INFO MYNAM ": %s.SenseBuffers @ %p[%p]\n",
3743                         ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
3744
3745         }
3746
3747         /* Post Reply frames to FIFO
3748          */
3749         alloc_dma = ioc->alloc_dma;
3750         dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffers @ %p[%p]\n",
3751                 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3752
3753         for (i = 0; i < ioc->reply_depth; i++) {
3754                 /*  Write each address to the IOC!  */
3755                 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
3756                 alloc_dma += ioc->reply_sz;
3757         }
3758
3759         return 0;
3760
3761 out_fail:
3762         if (ioc->alloc != NULL) {
3763                 sz = ioc->alloc_sz;
3764                 pci_free_consistent(ioc->pcidev,
3765                                 sz,
3766                                 ioc->alloc, ioc->alloc_dma);
3767                 ioc->reply_frames = NULL;
3768                 ioc->req_frames = NULL;
3769                 ioc->alloc_total -= sz;
3770         }
3771         if (ioc->sense_buf_pool != NULL) {
3772                 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3773                 pci_free_consistent(ioc->pcidev,
3774                                 sz,
3775                                 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
3776                 ioc->sense_buf_pool = NULL;
3777         }
3778         return -1;
3779 }
3780
3781 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3782 /**
3783  *      mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3784  *      from IOC via doorbell handshake method.
3785  *      @ioc: Pointer to MPT_ADAPTER structure
3786  *      @reqBytes: Size of the request in bytes
3787  *      @req: Pointer to MPT request frame
3788  *      @replyBytes: Expected size of the reply in bytes
3789  *      @u16reply: Pointer to area where reply should be written
3790  *      @maxwait: Max wait time for a reply (in seconds)
3791  *      @sleepFlag: Specifies whether the process can sleep
3792  *
3793  *      NOTES: It is the callers responsibility to byte-swap fields in the
3794  *      request which are greater than 1 byte in size.  It is also the
3795  *      callers responsibility to byte-swap response fields which are
3796  *      greater than 1 byte in size.
3797  *
3798  *      Returns 0 for success, non-zero for failure.
3799  */
3800 static int
3801 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
3802                 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
3803 {
3804         MPIDefaultReply_t *mptReply;
3805         int failcnt = 0;
3806         int t;
3807
3808         /*
3809          * Get ready to cache a handshake reply
3810          */
3811         ioc->hs_reply_idx = 0;
3812         mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3813         mptReply->MsgLength = 0;
3814
3815         /*
3816          * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
3817          * then tell IOC that we want to handshake a request of N words.
3818          * (WRITE u32val to Doorbell reg).
3819          */
3820         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3821         CHIPREG_WRITE32(&ioc->chip->Doorbell,
3822                         ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
3823                          ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
3824
3825         /*
3826          * Wait for IOC's doorbell handshake int
3827          */
3828         if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3829                 failcnt++;
3830
3831         dhsprintk((MYIOC_s_INFO_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
3832                         ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3833
3834         /* Read doorbell and check for active bit */
3835         if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
3836                         return -1;
3837
3838         /*
3839          * Clear doorbell int (WRITE 0 to IntStatus reg),
3840          * then wait for IOC to ACKnowledge that it's ready for
3841          * our handshake request.
3842          */
3843         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3844         if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3845                 failcnt++;
3846
3847         if (!failcnt) {
3848                 int      ii;
3849                 u8      *req_as_bytes = (u8 *) req;
3850
3851                 /*
3852                  * Stuff request words via doorbell handshake,
3853                  * with ACK from IOC for each.
3854                  */
3855                 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
3856                         u32 word = ((req_as_bytes[(ii*4) + 0] <<  0) |
3857                                     (req_as_bytes[(ii*4) + 1] <<  8) |
3858                                     (req_as_bytes[(ii*4) + 2] << 16) |
3859                                     (req_as_bytes[(ii*4) + 3] << 24));
3860
3861                         CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
3862                         if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3863                                 failcnt++;
3864                 }
3865
3866                 dhsprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
3867                 DBG_DUMP_REQUEST_FRAME_HDR(req)
3868
3869                 dhsprintk((MYIOC_s_INFO_FMT "HandShake request post done, WaitCnt=%d%s\n",
3870                                 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
3871
3872                 /*
3873                  * Wait for completion of doorbell handshake reply from the IOC
3874                  */
3875                 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
3876                         failcnt++;
3877
3878                 dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n",
3879                                 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
3880
3881                 /*
3882                  * Copy out the cached reply...
3883                  */
3884                 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
3885                         u16reply[ii] = ioc->hs_reply[ii];
3886         } else {
3887                 return -99;
3888         }
3889
3890         return -failcnt;
3891 }
3892
3893 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3894 /*
3895  *      WaitForDoorbellAck - Wait for IOC to clear the IOP_DOORBELL_STATUS bit
3896  *      in it's IntStatus register.
3897  *      @ioc: Pointer to MPT_ADAPTER structure
3898  *      @howlong: How long to wait (in seconds)
3899  *      @sleepFlag: Specifies whether the process can sleep
3900  *
3901  *      This routine waits (up to ~2 seconds max) for IOC doorbell
3902  *      handshake ACKnowledge.
3903  *
3904  *      Returns a negative value on failure, else wait loop count.
3905  */
3906 static int
3907 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3908 {
3909         int cntdn;
3910         int count = 0;
3911         u32 intstat=0;
3912
3913         cntdn = 1000 * howlong;
3914
3915         if (sleepFlag == CAN_SLEEP) {
3916                 while (--cntdn) {
3917                         msleep (1);
3918                         intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3919                         if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3920                                 break;
3921                         count++;
3922                 }
3923         } else {
3924                 while (--cntdn) {
3925                         mdelay (1);
3926                         intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3927                         if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3928                                 break;
3929                         count++;
3930                 }
3931         }
3932
3933         if (cntdn) {
3934                 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (count=%d)\n",
3935                                 ioc->name, count));
3936                 return count;
3937         }
3938
3939         printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
3940                         ioc->name, count, intstat);
3941         return -1;
3942 }
3943
3944 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3945 /*
3946  *      WaitForDoorbellInt - Wait for IOC to set the HIS_DOORBELL_INTERRUPT bit
3947  *      in it's IntStatus register.
3948  *      @ioc: Pointer to MPT_ADAPTER structure
3949  *      @howlong: How long to wait (in seconds)
3950  *      @sleepFlag: Specifies whether the process can sleep
3951  *
3952  *      This routine waits (up to ~2 seconds max) for IOC doorbell interrupt.
3953  *
3954  *      Returns a negative value on failure, else wait loop count.
3955  */
3956 static int
3957 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3958 {
3959         int cntdn;
3960         int count = 0;
3961         u32 intstat=0;
3962
3963         cntdn = 1000 * howlong;
3964         if (sleepFlag == CAN_SLEEP) {
3965                 while (--cntdn) {
3966                         intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3967                         if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3968                                 break;
3969                         msleep(1);
3970                         count++;
3971                 }
3972         } else {
3973                 while (--cntdn) {
3974                         intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3975                         if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3976                                 break;
3977                         mdelay(1);
3978                         count++;
3979                 }
3980         }
3981
3982         if (cntdn) {
3983                 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
3984                                 ioc->name, count, howlong));
3985                 return count;
3986         }
3987
3988         printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
3989                         ioc->name, count, intstat);
3990         return -1;
3991 }
3992
3993 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3994 /*
3995  *      WaitForDoorbellReply - Wait for and capture a IOC handshake reply.
3996  *      @ioc: Pointer to MPT_ADAPTER structure
3997  *      @howlong: How long to wait (in seconds)
3998  *      @sleepFlag: Specifies whether the process can sleep
3999  *
4000  *      This routine polls the IOC for a handshake reply, 16 bits at a time.
4001  *      Reply is cached to IOC private area large enough to hold a maximum
4002  *      of 128 bytes of reply data.
4003  *
4004  *      Returns a negative value on failure, else size of reply in WORDS.
4005  */
4006 static int
4007 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4008 {
4009         int u16cnt = 0;
4010         int failcnt = 0;
4011         int t;
4012         u16 *hs_reply = ioc->hs_reply;
4013         volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4014         u16 hword;
4015
4016         hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4017
4018         /*
4019          * Get first two u16's so we can look at IOC's intended reply MsgLength
4020          */
4021         u16cnt=0;
4022         if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4023                 failcnt++;
4024         } else {
4025                 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4026                 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4027                 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4028                         failcnt++;
4029                 else {
4030                         hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4031                         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4032                 }
4033         }
4034
4035         dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4036                         ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4037                         failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4038
4039         /*
4040          * If no error (and IOC said MsgLength is > 0), piece together
4041          * reply 16 bits at a time.
4042          */
4043         for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4044                 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4045                         failcnt++;
4046                 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4047                 /* don't overflow our IOC hs_reply[] buffer! */
4048                 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4049                         hs_reply[u16cnt] = hword;
4050                 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4051         }
4052
4053         if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4054                 failcnt++;
4055         CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4056
4057         if (failcnt) {
4058                 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4059                                 ioc->name);
4060                 return -failcnt;
4061         }
4062 #if 0
4063         else if (u16cnt != (2 * mptReply->MsgLength)) {
4064                 return -101;
4065         }
4066         else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4067                 return -102;
4068         }
4069 #endif
4070
4071         dhsprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
4072         DBG_DUMP_REPLY_FRAME(mptReply)
4073
4074         dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4075                         ioc->name, t, u16cnt/2));
4076         return u16cnt/2;
4077 }
4078
4079 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4080 /*
4081  *      GetLanConfigPages - Fetch LANConfig pages.
4082  *      @ioc: Pointer to MPT_ADAPTER structure
4083  *
4084  *      Return: 0 for success
4085  *      -ENOMEM if no memory available
4086  *              -EPERM if not allowed due to ISR context
4087  *              -EAGAIN if no msg frames currently available
4088  *              -EFAULT for non-successful reply or no reply (timeout)
4089  */
4090 static int
4091 GetLanConfigPages(MPT_ADAPTER *ioc)
4092 {
4093         ConfigPageHeader_t       hdr;
4094         CONFIGPARMS              cfg;
4095         LANPage0_t              *ppage0_alloc;
4096         dma_addr_t               page0_dma;
4097         LANPage1_t              *ppage1_alloc;
4098         dma_addr_t               page1_dma;
4099         int                      rc = 0;
4100         int                      data_sz;
4101         int                      copy_sz;
4102
4103         /* Get LAN Page 0 header */
4104         hdr.PageVersion = 0;
4105         hdr.PageLength = 0;
4106         hdr.PageNumber = 0;
4107         hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4108         cfg.cfghdr.hdr = &hdr;
4109         cfg.physAddr = -1;
4110         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4111         cfg.dir = 0;
4112         cfg.pageAddr = 0;
4113         cfg.timeout = 0;
4114
4115         if ((rc = mpt_config(ioc, &cfg)) != 0)
4116                 return rc;
4117
4118         if (hdr.PageLength > 0) {
4119                 data_sz = hdr.PageLength * 4;
4120                 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4121                 rc = -ENOMEM;
4122                 if (ppage0_alloc) {
4123                         memset((u8 *)ppage0_alloc, 0, data_sz);
4124                         cfg.physAddr = page0_dma;
4125                         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4126
4127                         if ((rc = mpt_config(ioc, &cfg)) == 0) {
4128                                 /* save the data */
4129                                 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4130                                 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4131
4132                         }
4133
4134                         pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4135
4136                         /* FIXME!
4137                          *      Normalize endianness of structure data,
4138                          *      by byte-swapping all > 1 byte fields!
4139                          */
4140
4141                 }
4142
4143                 if (rc)
4144                         return rc;
4145         }
4146
4147         /* Get LAN Page 1 header */
4148         hdr.PageVersion = 0;
4149         hdr.PageLength = 0;
4150         hdr.PageNumber = 1;
4151         hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4152         cfg.cfghdr.hdr = &hdr;
4153         cfg.physAddr = -1;
4154         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4155         cfg.dir = 0;
4156         cfg.pageAddr = 0;
4157
4158         if ((rc = mpt_config(ioc, &cfg)) != 0)
4159                 return rc;
4160
4161         if (hdr.PageLength == 0)
4162                 return 0;
4163
4164         data_sz = hdr.PageLength * 4;
4165         rc = -ENOMEM;
4166         ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4167         if (ppage1_alloc) {
4168                 memset((u8 *)ppage1_alloc, 0, data_sz);
4169                 cfg.physAddr = page1_dma;
4170                 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4171
4172                 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4173                         /* save the data */
4174                         copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4175                         memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4176                 }
4177
4178                 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4179
4180                 /* FIXME!
4181                  *      Normalize endianness of structure data,
4182                  *      by byte-swapping all > 1 byte fields!
4183                  */
4184
4185         }
4186
4187         return rc;
4188 }
4189
4190 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4191 /*
4192  *      mptbase_sas_persist_operation - Perform operation on SAS Persitent Table
4193  *      @ioc: Pointer to MPT_ADAPTER structure
4194  *      @sas_address: 64bit SAS Address for operation.
4195  *      @target_id: specified target for operation
4196  *      @bus: specified bus for operation
4197  *      @persist_opcode: see below
4198  *
4199  *      MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4200  *              devices not currently present.
4201  *      MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4202  *
4203  *      NOTE: Don't use not this function during interrupt time.
4204  *
4205  *      Returns: 0 for success, non-zero error
4206  */
4207
4208 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4209 int
4210 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4211 {
4212         SasIoUnitControlRequest_t       *sasIoUnitCntrReq;
4213         SasIoUnitControlReply_t         *sasIoUnitCntrReply;
4214         MPT_FRAME_HDR                   *mf = NULL;
4215         MPIHeader_t                     *mpi_hdr;
4216
4217
4218         /* insure garbage is not sent to fw */
4219         switch(persist_opcode) {
4220
4221         case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4222         case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4223                 break;
4224
4225         default:
4226                 return -1;
4227                 break;
4228         }
4229
4230         printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4231
4232         /* Get a MF for this command.
4233          */
4234         if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4235                 printk("%s: no msg frames!\n",__FUNCTION__);
4236                 return -1;
4237         }
4238
4239         mpi_hdr = (MPIHeader_t *) mf;
4240         sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4241         memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4242         sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4243         sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4244         sasIoUnitCntrReq->Operation = persist_opcode;
4245
4246         init_timer(&ioc->persist_timer);
4247         ioc->persist_timer.data = (unsigned long) ioc;
4248         ioc->persist_timer.function = mpt_timer_expired;
4249         ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4250         ioc->persist_wait_done=0;
4251         add_timer(&ioc->persist_timer);
4252         mpt_put_msg_frame(mpt_base_index, ioc, mf);
4253         wait_event(mpt_waitq, ioc->persist_wait_done);
4254
4255         sasIoUnitCntrReply =
4256             (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4257         if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4258                 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4259                     __FUNCTION__,
4260                     sasIoUnitCntrReply->IOCStatus,
4261                     sasIoUnitCntrReply->IOCLogInfo);
4262                 return -1;
4263         }
4264
4265         printk("%s: success\n",__FUNCTION__);
4266         return 0;
4267 }
4268
4269 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4270
4271 static void
4272 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4273     MpiEventDataRaid_t * pRaidEventData)
4274 {
4275         int     volume;
4276         int     reason;
4277         int     disk;
4278         int     status;
4279         int     flags;
4280         int     state;
4281
4282         volume  = pRaidEventData->VolumeID;
4283         reason  = pRaidEventData->ReasonCode;
4284         disk    = pRaidEventData->PhysDiskNum;
4285         status  = le32_to_cpu(pRaidEventData->SettingsStatus);
4286         flags   = (status >> 0) & 0xff;
4287         state   = (status >> 8) & 0xff;
4288
4289         if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4290                 return;
4291         }
4292
4293         if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4294              reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4295             (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4296                 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d\n",
4297                         ioc->name, disk);
4298         } else {
4299                 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4300                         ioc->name, volume);
4301         }
4302
4303         switch(reason) {
4304         case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4305                 printk(MYIOC_s_INFO_FMT "  volume has been created\n",
4306                         ioc->name);
4307                 break;
4308
4309         case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4310
4311                 printk(MYIOC_s_INFO_FMT "  volume has been deleted\n",
4312                         ioc->name);
4313                 break;
4314
4315         case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4316                 printk(MYIOC_s_INFO_FMT "  volume settings have been changed\n",
4317                         ioc->name);
4318                 break;
4319
4320         case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4321                 printk(MYIOC_s_INFO_FMT "  volume is now %s%s%s%s\n",
4322                         ioc->name,
4323                         state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4324                          ? "optimal"
4325                          : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4326                           ? "degraded"
4327                           : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4328                            ? "failed"
4329                            : "state unknown",
4330                         flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4331                          ? ", enabled" : "",
4332                         flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4333                          ? ", quiesced" : "",
4334                         flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4335                          ? ", resync in progress" : "" );
4336                 break;
4337
4338         case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4339                 printk(MYIOC_s_INFO_FMT "  volume membership of PhysDisk %d has changed\n",
4340                         ioc->name, disk);
4341                 break;
4342
4343         case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4344                 printk(MYIOC_s_INFO_FMT "  PhysDisk has been created\n",
4345                         ioc->name);
4346                 break;
4347
4348         case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4349                 printk(MYIOC_s_INFO_FMT "  PhysDisk has been deleted\n",
4350                         ioc->name);
4351                 break;
4352
4353         case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4354                 printk(MYIOC_s_INFO_FMT "  PhysDisk settings have been changed\n",
4355                         ioc->name);
4356                 break;
4357
4358         case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4359                 printk(MYIOC_s_INFO_FMT "  PhysDisk is now %s%s%s\n",
4360                         ioc->name,
4361                         state == MPI_PHYSDISK0_STATUS_ONLINE
4362                          ? "online"
4363                          : state == MPI_PHYSDISK0_STATUS_MISSING
4364                           ? "missing"
4365                           : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4366                            ? "not compatible"
4367                            : state == MPI_PHYSDISK0_STATUS_FAILED
4368                             ? "failed"
4369                             : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4370                              ? "initializing"
4371                              : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4372                               ? "offline requested"
4373                               : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4374                                ? "failed requested"
4375                                : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4376                                 ? "offline"
4377                                 : "state unknown",
4378                         flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4379                          ? ", out of sync" : "",
4380                         flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4381                          ? ", quiesced" : "" );
4382                 break;
4383
4384         case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4385                 printk(MYIOC_s_INFO_FMT "  Domain Validation needed for PhysDisk %d\n",
4386                         ioc->name, disk);
4387                 break;
4388
4389         case MPI_EVENT_RAID_RC_SMART_DATA:
4390                 printk(MYIOC_s_INFO_FMT "  SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4391                         ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4392                 break;
4393
4394         case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4395                 printk(MYIOC_s_INFO_FMT "  replacement of PhysDisk %d has started\n",
4396                         ioc->name, disk);
4397                 break;
4398         }
4399 }
4400
4401 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4402 /*
4403  *      GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4404  *      @ioc: Pointer to MPT_ADAPTER structure
4405  *
4406  *      Returns: 0 for success
4407  *      -ENOMEM if no memory available
4408  *              -EPERM if not allowed due to ISR context
4409  *              -EAGAIN if no msg frames currently available
4410  *              -EFAULT for non-successful reply or no reply (timeout)
4411  */
4412 static int
4413 GetIoUnitPage2(MPT_ADAPTER *ioc)
4414 {
4415         ConfigPageHeader_t       hdr;
4416         CONFIGPARMS              cfg;
4417         IOUnitPage2_t           *ppage_alloc;
4418         dma_addr_t               page_dma;
4419         int                      data_sz;
4420         int                      rc;
4421
4422         /* Get the page header */
4423         hdr.PageVersion = 0;
4424         hdr.PageLength = 0;
4425         hdr.PageNumber = 2;
4426         hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4427         cfg.cfghdr.hdr = &hdr;
4428         cfg.physAddr = -1;
4429         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4430         cfg.dir = 0;
4431         cfg.pageAddr = 0;
4432         cfg.timeout = 0;
4433
4434         if ((rc = mpt_config(ioc, &cfg)) != 0)
4435                 return rc;
4436
4437         if (hdr.PageLength == 0)
4438                 return 0;
4439
4440         /* Read the config page */
4441         data_sz = hdr.PageLength * 4;
4442         rc = -ENOMEM;
4443         ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4444         if (ppage_alloc) {
4445                 memset((u8 *)ppage_alloc, 0, data_sz);
4446                 cfg.physAddr = page_dma;
4447                 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4448
4449                 /* If Good, save data */
4450                 if ((rc = mpt_config(ioc, &cfg)) == 0)
4451                         ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4452
4453                 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4454         }
4455
4456         return rc;
4457 }
4458
4459 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4460 /*      mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4461  *      @ioc: Pointer to a Adapter Strucutre
4462  *      @portnum: IOC port number
4463  *
4464  *      Return: -EFAULT if read of config page header fails
4465  *                      or if no nvram
4466  *      If read of SCSI Port Page 0 fails,
4467  *              NVRAM = MPT_HOST_NVRAM_INVALID  (0xFFFFFFFF)
4468  *              Adapter settings: async, narrow
4469  *              Return 1
4470  *      If read of SCSI Port Page 2 fails,
4471  *              Adapter settings valid
4472  *              NVRAM = MPT_HOST_NVRAM_INVALID  (0xFFFFFFFF)
4473  *              Return 1
4474  *      Else
4475  *              Both valid
4476  *              Return 0
4477  *      CHECK - what type of locking mechanisms should be used????
4478  */
4479 static int
4480 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4481 {
4482         u8                      *pbuf;
4483         dma_addr_t               buf_dma;
4484         CONFIGPARMS              cfg;
4485         ConfigPageHeader_t       header;
4486         int                      ii;
4487         int                      data, rc = 0;
4488
4489         /* Allocate memory
4490          */
4491         if (!ioc->spi_data.nvram) {
4492                 int      sz;
4493                 u8      *mem;
4494                 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4495                 mem = kmalloc(sz, GFP_ATOMIC);
4496                 if (mem == NULL)
4497                         return -EFAULT;
4498
4499                 ioc->spi_data.nvram = (int *) mem;
4500
4501                 dprintk((MYIOC_s_INFO_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4502                         ioc->name, ioc->spi_data.nvram, sz));
4503         }
4504
4505         /* Invalidate NVRAM information
4506          */
4507         for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4508                 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4509         }
4510
4511         /* Read SPP0 header, allocate memory, then read page.
4512          */
4513         header.PageVersion = 0;
4514         header.PageLength = 0;
4515         header.PageNumber = 0;
4516         header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4517         cfg.cfghdr.hdr = &header;
4518         cfg.physAddr = -1;
4519         cfg.pageAddr = portnum;
4520         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4521         cfg.dir = 0;
4522         cfg.timeout = 0;        /* use default */
4523         if (mpt_config(ioc, &cfg) != 0)
4524                  return -EFAULT;
4525
4526         if (header.PageLength > 0) {
4527                 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4528                 if (pbuf) {
4529                         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4530                         cfg.physAddr = buf_dma;
4531                         if (mpt_config(ioc, &cfg) != 0) {
4532                                 ioc->spi_data.maxBusWidth = MPT_NARROW;
4533                                 ioc->spi_data.maxSyncOffset = 0;
4534                                 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4535                                 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4536                                 rc = 1;
4537                                 ddvprintk((MYIOC_s_INFO_FMT "Unable to read PortPage0 minSyncFactor=%x\n",
4538                                         ioc->name, ioc->spi_data.minSyncFactor));
4539                         } else {
4540                                 /* Save the Port Page 0 data
4541                                  */
4542                                 SCSIPortPage0_t  *pPP0 = (SCSIPortPage0_t  *) pbuf;
4543                                 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4544                                 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4545
4546                                 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4547                                         ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4548                                         ddvprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
4549                                                 ioc->name, pPP0->Capabilities));
4550                                 }
4551                                 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4552                                 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4553                                 if (data) {
4554                                         ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4555                                         data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4556                                         ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4557                                         ddvprintk((MYIOC_s_INFO_FMT "PortPage0 minSyncFactor=%x\n",
4558                                                 ioc->name, ioc->spi_data.minSyncFactor));
4559                                 } else {
4560                                         ioc->spi_data.maxSyncOffset = 0;
4561                                         ioc->spi_data.minSyncFactor = MPT_ASYNC;
4562                                 }
4563
4564                                 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4565
4566                                 /* Update the minSyncFactor based on bus type.
4567                                  */
4568                                 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4569                                         (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE))  {
4570
4571                                         if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4572                                                 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4573                                                 ddvprintk((MYIOC_s_INFO_FMT "HVD or SE detected, minSyncFactor=%x\n",
4574                                                         ioc->name, ioc->spi_data.minSyncFactor));
4575                                         }
4576                                 }
4577                         }
4578                         if (pbuf) {
4579                                 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4580                         }
4581                 }
4582         }
4583
4584         /* SCSI Port Page 2 - Read the header then the page.
4585          */
4586         header.PageVersion = 0;
4587         header.PageLength = 0;
4588         header.PageNumber = 2;
4589         header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4590         cfg.cfghdr.hdr = &header;
4591         cfg.physAddr = -1;
4592         cfg.pageAddr = portnum;
4593         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4594         cfg.dir = 0;
4595         if (mpt_config(ioc, &cfg) != 0)
4596                 return -EFAULT;
4597
4598         if (header.PageLength > 0) {
4599                 /* Allocate memory and read SCSI Port Page 2
4600                  */
4601                 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4602                 if (pbuf) {
4603                         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4604                         cfg.physAddr = buf_dma;
4605                         if (mpt_config(ioc, &cfg) != 0) {
4606                                 /* Nvram data is left with INVALID mark
4607                                  */
4608                                 rc = 1;
4609                         } else {
4610                                 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t  *) pbuf;
4611                                 MpiDeviceInfo_t *pdevice = NULL;
4612
4613                                 /*
4614                                  * Save "Set to Avoid SCSI Bus Resets" flag
4615                                  */
4616                                 ioc->spi_data.bus_reset =
4617                                     (le32_to_cpu(pPP2->PortFlags) &
4618                                 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
4619                                     0 : 1 ;
4620
4621                                 /* Save the Port Page 2 data
4622                                  * (reformat into a 32bit quantity)
4623                                  */
4624                                 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4625                                 ioc->spi_data.PortFlags = data;
4626                                 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4627                                         pdevice = &pPP2->DeviceSettings[ii];
4628                                         data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4629                                                 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4630                                         ioc->spi_data.nvram[ii] = data;
4631                                 }
4632                         }
4633
4634                         pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4635                 }
4636         }
4637
4638         /* Update Adapter limits with those from NVRAM
4639          * Comment: Don't need to do this. Target performance
4640          * parameters will never exceed the adapters limits.
4641          */
4642
4643         return rc;
4644 }
4645
4646 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4647 /*      mpt_readScsiDevicePageHeaders - save version and length of SDP1
4648  *      @ioc: Pointer to a Adapter Strucutre
4649  *      @portnum: IOC port number
4650  *
4651  *      Return: -EFAULT if read of config page header fails
4652  *              or 0 if success.
4653  */
4654 static int
4655 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4656 {
4657         CONFIGPARMS              cfg;
4658         ConfigPageHeader_t       header;
4659
4660         /* Read the SCSI Device Page 1 header
4661          */
4662         header.PageVersion = 0;
4663         header.PageLength = 0;
4664         header.PageNumber = 1;
4665         header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4666         cfg.cfghdr.hdr = &header;
4667         cfg.physAddr = -1;
4668         cfg.pageAddr = portnum;
4669         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4670         cfg.dir = 0;
4671         cfg.timeout = 0;
4672         if (mpt_config(ioc, &cfg) != 0)
4673                  return -EFAULT;
4674
4675         ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
4676         ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
4677
4678         header.PageVersion = 0;
4679         header.PageLength = 0;
4680         header.PageNumber = 0;
4681         header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4682         if (mpt_config(ioc, &cfg) != 0)
4683                  return -EFAULT;
4684
4685         ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
4686         ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
4687
4688         dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
4689                         ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
4690
4691         dcprintk((MYIOC_s_INFO_FMT "Headers: 1: version %d length %d\n",
4692                         ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
4693         return 0;
4694 }
4695
4696 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4697 /**
4698  *      mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4699  *      @ioc: Pointer to a Adapter Strucutre
4700  *      @portnum: IOC port number
4701  *
4702  *      Return:
4703  *      0 on success
4704  *      -EFAULT if read of config page header fails or data pointer not NULL
4705  *      -ENOMEM if pci_alloc failed
4706  */
4707 int
4708 mpt_findImVolumes(MPT_ADAPTER *ioc)
4709 {
4710         IOCPage2_t              *pIoc2;
4711         u8                      *mem;
4712         ConfigPageIoc2RaidVol_t *pIocRv;
4713         dma_addr_t               ioc2_dma;
4714         CONFIGPARMS              cfg;
4715         ConfigPageHeader_t       header;
4716         int                      jj;
4717         int                      rc = 0;
4718         int                      iocpage2sz;
4719         u8                       nVols, nPhys;
4720         u8                       vid, vbus, vioc;
4721
4722         /* Read IOCP2 header then the page.
4723          */
4724         header.PageVersion = 0;
4725         header.PageLength = 0;
4726         header.PageNumber = 2;
4727         header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4728         cfg.cfghdr.hdr = &header;
4729         cfg.physAddr = -1;
4730         cfg.pageAddr = 0;
4731         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4732         cfg.dir = 0;
4733         cfg.timeout = 0;
4734         if (mpt_config(ioc, &cfg) != 0)
4735                  return -EFAULT;
4736
4737         if (header.PageLength == 0)
4738                 return -EFAULT;
4739
4740         iocpage2sz = header.PageLength * 4;
4741         pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
4742         if (!pIoc2)
4743                 return -ENOMEM;
4744
4745         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4746         cfg.physAddr = ioc2_dma;
4747         if (mpt_config(ioc, &cfg) != 0)
4748                 goto done_and_free;
4749
4750         if ( (mem = (u8 *)ioc->raid_data.pIocPg2) == NULL ) {
4751                 mem = kmalloc(iocpage2sz, GFP_ATOMIC);
4752                 if (mem) {
4753                         ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
4754                 } else {
4755                         goto done_and_free;
4756                 }
4757         }
4758         memcpy(mem, (u8 *)pIoc2, iocpage2sz);
4759
4760         /* Identify RAID Volume Id's */
4761         nVols = pIoc2->NumActiveVolumes;
4762         if ( nVols == 0) {
4763                 /* No RAID Volume.
4764                  */
4765                 goto done_and_free;
4766         } else {
4767                 /* At least 1 RAID Volume
4768                  */
4769                 pIocRv = pIoc2->RaidVolume;
4770                 ioc->raid_data.isRaid = 0;
4771                 for (jj = 0; jj < nVols; jj++, pIocRv++) {
4772                         vid = pIocRv->VolumeID;
4773                         vbus = pIocRv->VolumeBus;
4774                         vioc = pIocRv->VolumeIOC;
4775
4776                         /* find the match
4777                          */
4778                         if (vbus == 0) {
4779                                 ioc->raid_data.isRaid |= (1 << vid);
4780                         } else {
4781                                 /* Error! Always bus 0
4782                                  */
4783                         }
4784                 }
4785         }
4786
4787         /* Identify Hidden Physical Disk Id's */
4788         nPhys = pIoc2->NumActivePhysDisks;
4789         if (nPhys == 0) {
4790                 /* No physical disks.
4791                  */
4792         } else {
4793                 mpt_read_ioc_pg_3(ioc);
4794         }
4795
4796 done_and_free:
4797         pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
4798
4799         return rc;
4800 }
4801
4802 static int
4803 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
4804 {
4805         IOCPage3_t              *pIoc3;
4806         u8                      *mem;
4807         CONFIGPARMS              cfg;
4808         ConfigPageHeader_t       header;
4809         dma_addr_t               ioc3_dma;
4810         int                      iocpage3sz = 0;
4811
4812         /* Free the old page
4813          */
4814         kfree(ioc->raid_data.pIocPg3);
4815         ioc->raid_data.pIocPg3 = NULL;
4816
4817         /* There is at least one physical disk.
4818          * Read and save IOC Page 3
4819          */
4820         header.PageVersion = 0;
4821         header.PageLength = 0;
4822         header.PageNumber = 3;
4823         header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4824         cfg.cfghdr.hdr = &header;
4825         cfg.physAddr = -1;
4826         cfg.pageAddr = 0;
4827         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4828         cfg.dir = 0;
4829         cfg.timeout = 0;
4830         if (mpt_config(ioc, &cfg) != 0)
4831                 return 0;
4832
4833         if (header.PageLength == 0)
4834                 return 0;
4835
4836         /* Read Header good, alloc memory
4837          */
4838         iocpage3sz = header.PageLength * 4;
4839         pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
4840         if (!pIoc3)
4841                 return 0;
4842
4843         /* Read the Page and save the data
4844          * into malloc'd memory.
4845          */
4846         cfg.physAddr = ioc3_dma;
4847         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4848         if (mpt_config(ioc, &cfg) == 0) {
4849                 mem = kmalloc(iocpage3sz, GFP_ATOMIC);
4850                 if (mem) {
4851                         memcpy(mem, (u8 *)pIoc3, iocpage3sz);
4852                         ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
4853                 }
4854         }
4855
4856         pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
4857
4858         return 0;
4859 }
4860
4861 static void
4862 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
4863 {
4864         IOCPage4_t              *pIoc4;
4865         CONFIGPARMS              cfg;
4866         ConfigPageHeader_t       header;
4867         dma_addr_t               ioc4_dma;
4868         int                      iocpage4sz;
4869
4870         /* Read and save IOC Page 4
4871          */
4872         header.PageVersion = 0;
4873         header.PageLength = 0;
4874         header.PageNumber = 4;
4875         header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4876         cfg.cfghdr.hdr = &header;
4877         cfg.physAddr = -1;
4878         cfg.pageAddr = 0;
4879         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4880         cfg.dir = 0;
4881         cfg.timeout = 0;
4882         if (mpt_config(ioc, &cfg) != 0)
4883                 return;
4884
4885         if (header.PageLength == 0)
4886                 return;
4887
4888         if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
4889                 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
4890                 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
4891                 if (!pIoc4)
4892                         return;
4893                 ioc->alloc_total += iocpage4sz;
4894         } else {
4895                 ioc4_dma = ioc->spi_data.IocPg4_dma;
4896                 iocpage4sz = ioc->spi_data.IocPg4Sz;
4897         }
4898
4899         /* Read the Page into dma memory.
4900          */
4901         cfg.physAddr = ioc4_dma;
4902         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4903         if (mpt_config(ioc, &cfg) == 0) {
4904                 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
4905                 ioc->spi_data.IocPg4_dma = ioc4_dma;
4906                 ioc->spi_data.IocPg4Sz = iocpage4sz;
4907         } else {
4908                 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
4909                 ioc->spi_data.pIocPg4 = NULL;
4910                 ioc->alloc_total -= iocpage4sz;
4911         }
4912 }
4913
4914 static void
4915 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
4916 {
4917         IOCPage1_t              *pIoc1;
4918         CONFIGPARMS              cfg;
4919         ConfigPageHeader_t       header;
4920         dma_addr_t               ioc1_dma;
4921         int                      iocpage1sz = 0;
4922         u32                      tmp;
4923
4924         /* Check the Coalescing Timeout in IOC Page 1
4925          */
4926         header.PageVersion = 0;
4927         header.PageLength = 0;
4928         header.PageNumber = 1;
4929         header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4930         cfg.cfghdr.hdr = &header;
4931         cfg.physAddr = -1;
4932         cfg.pageAddr = 0;
4933         cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4934         cfg.dir = 0;
4935         cfg.timeout = 0;
4936         if (mpt_config(ioc, &cfg) != 0)
4937                 return;
4938
4939         if (header.PageLength == 0)
4940                 return;
4941
4942         /* Read Header good, alloc memory
4943          */
4944         iocpage1sz = header.PageLength * 4;
4945         pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
4946         if (!pIoc1)
4947                 return;
4948
4949         /* Read the Page and check coalescing timeout
4950          */
4951         cfg.physAddr = ioc1_dma;
4952         cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4953         if (mpt_config(ioc, &cfg) == 0) {
4954                 
4955                 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
4956                 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
4957                         tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
4958
4959                         dprintk((MYIOC_s_INFO_FMT "Coalescing Enabled Timeout = %d\n",
4960                                         ioc->name, tmp));
4961
4962                         if (tmp > MPT_COALESCING_TIMEOUT) {
4963                                 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
4964
4965                                 /* Write NVRAM and current
4966                                  */
4967                                 cfg.dir = 1;
4968                                 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4969                                 if (mpt_config(ioc, &cfg) == 0) {
4970                                         dprintk((MYIOC_s_INFO_FMT "Reset Current Coalescing Timeout to = %d\n",
4971                                                         ioc->name, MPT_COALESCING_TIMEOUT));
4972
4973                                         cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
4974                                         if (mpt_config(ioc, &cfg) == 0) {
4975                                                 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout to = %d\n",
4976                                                                 ioc->name, MPT_COALESCING_TIMEOUT));
4977                                         } else {
4978                                                 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout Failed\n",
4979                                                                         ioc->name));
4980                                         }
4981
4982                                 } else {
4983                                         dprintk((MYIOC_s_WARN_FMT "Reset of Current Coalescing Timeout Failed!\n",
4984                                                                 ioc->name));
4985                                 }
4986                         }
4987
4988                 } else {
4989                         dprintk((MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
4990                 }
4991         }
4992
4993         pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
4994
4995         return;
4996 }
4997
4998 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4999 /*
5000  *      SendEventNotification - Send EventNotification (on or off) request
5001  *      to MPT adapter.
5002  *      @ioc: Pointer to MPT_ADAPTER structure
5003  *      @EvSwitch: Event switch flags
5004  */
5005 static int
5006 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5007 {
5008         EventNotification_t     *evnp;
5009
5010         evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5011         if (evnp == NULL) {
5012                 devtverboseprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5013                                 ioc->name));
5014                 return 0;
5015         }
5016         memset(evnp, 0, sizeof(*evnp));
5017
5018         devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5019
5020         evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5021         evnp->ChainOffset = 0;
5022         evnp->MsgFlags = 0;
5023         evnp->Switch = EvSwitch;
5024
5025         mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5026
5027         return 0;
5028 }
5029
5030 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5031 /**
5032  *      SendEventAck - Send EventAck request to MPT adapter.
5033  *      @ioc: Pointer to MPT_ADAPTER structure
5034  *      @evnp: Pointer to original EventNotification request
5035  */
5036 static int
5037 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5038 {
5039         EventAck_t      *pAck;
5040
5041         if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5042                 dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
5043                     ioc->name,__FUNCTION__));
5044                 return -1;
5045         }
5046
5047         devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
5048
5049         pAck->Function     = MPI_FUNCTION_EVENT_ACK;
5050         pAck->ChainOffset  = 0;
5051         pAck->Reserved[0]  = pAck->Reserved[1] = 0;
5052         pAck->MsgFlags     = 0;
5053         pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
5054         pAck->Event        = evnp->Event;
5055         pAck->EventContext = evnp->EventContext;
5056
5057         mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5058
5059         return 0;
5060 }
5061
5062 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5063 /**
5064  *      mpt_config - Generic function to issue config message
5065  *      @ioc - Pointer to an adapter structure
5066  *      @cfg - Pointer to a configuration structure. Struct contains
5067  *              action, page address, direction, physical address
5068  *              and pointer to a configuration page header
5069  *              Page header is updated.
5070  *
5071  *      Returns 0 for success
5072  *      -EPERM if not allowed due to ISR context
5073  *      -EAGAIN if no msg frames currently available
5074  *      -EFAULT for non-successful reply or no reply (timeout)
5075  */
5076 int
5077 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5078 {
5079         Config_t        *pReq;
5080         ConfigExtendedPageHeader_t  *pExtHdr = NULL;
5081         MPT_FRAME_HDR   *mf;
5082         unsigned long    flags;
5083         int              ii, rc;
5084         int              flagsLength;
5085         int              in_isr;
5086
5087         /*      Prevent calling wait_event() (below), if caller happens
5088          *      to be in ISR context, because that is fatal!
5089          */
5090         in_isr = in_interrupt();
5091         if (in_isr) {
5092                 dcprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5093                                 ioc->name));
5094                 return -EPERM;
5095         }
5096
5097         /* Get and Populate a free Frame
5098          */
5099         if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5100                 dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5101                                 ioc->name));
5102                 return -EAGAIN;
5103         }
5104         pReq = (Config_t *)mf;
5105         pReq->Action = pCfg->action;
5106         pReq->Reserved = 0;
5107         pReq->ChainOffset = 0;
5108         pReq->Function = MPI_FUNCTION_CONFIG;
5109
5110         /* Assume page type is not extended and clear "reserved" fields. */
5111         pReq->ExtPageLength = 0;
5112         pReq->ExtPageType = 0;
5113         pReq->MsgFlags = 0;
5114
5115         for (ii=0; ii < 8; ii++)
5116                 pReq->Reserved2[ii] = 0;
5117
5118         pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5119         pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5120         pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5121         pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5122
5123         if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5124                 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5125                 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5126                 pReq->ExtPageType = pExtHdr->ExtPageType;
5127                 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5128
5129                 /* Page Length must be treated as a reserved field for the extended header. */
5130                 pReq->Header.PageLength = 0;
5131         }
5132
5133         pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5134
5135         /* Add a SGE to the config request.
5136          */
5137         if (pCfg->dir)
5138                 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5139         else
5140                 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5141
5142         if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5143                 flagsLength |= pExtHdr->ExtPageLength * 4;
5144
5145                 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5146                         ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5147         }
5148         else {
5149                 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5150
5151                 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5152                         ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5153         }
5154
5155         mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5156
5157         /* Append pCfg pointer to end of mf
5158          */
5159         *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) =  (void *) pCfg;
5160
5161         /* Initalize the timer
5162          */
5163         init_timer(&pCfg->timer);
5164         pCfg->timer.data = (unsigned long) ioc;
5165         pCfg->timer.function = mpt_timer_expired;
5166         pCfg->wait_done = 0;
5167
5168         /* Set the timer; ensure 10 second minimum */
5169         if (pCfg->timeout < 10)
5170                 pCfg->timer.expires = jiffies + HZ*10;
5171         else
5172                 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5173
5174         /* Add to end of Q, set timer and then issue this command */
5175         spin_lock_irqsave(&ioc->FreeQlock, flags);
5176         list_add_tail(&pCfg->linkage, &ioc->configQ);
5177         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5178
5179         add_timer(&pCfg->timer);
5180         mpt_put_msg_frame(mpt_base_index, ioc, mf);
5181         wait_event(mpt_waitq, pCfg->wait_done);
5182
5183         /* mf has been freed - do not access */
5184
5185         rc = pCfg->status;
5186
5187         return rc;
5188 }
5189
5190 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5191 /*
5192  *      mpt_timer_expired - Call back for timer process.
5193  *      Used only internal config functionality.
5194  *      @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5195  */
5196 static void
5197 mpt_timer_expired(unsigned long data)
5198 {
5199         MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5200
5201         dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name));
5202
5203         /* Perform a FW reload */
5204         if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5205                 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5206
5207         /* No more processing.
5208          * Hard reset clean-up will wake up
5209          * process and free all resources.
5210          */
5211         dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name));
5212
5213         return;
5214 }
5215
5216 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5217 /*
5218  *      mpt_ioc_reset - Base cleanup for hard reset
5219  *      @ioc: Pointer to the adapter structure
5220  *      @reset_phase: Indicates pre- or post-reset functionality
5221  *
5222  *      Remark: Free's resources with internally generated commands.
5223  */
5224 static int
5225 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5226 {
5227         CONFIGPARMS *pCfg;
5228         unsigned long flags;
5229
5230         dprintk((KERN_WARNING MYNAM
5231                         ": IOC %s_reset routed to MPT base driver!\n",
5232                         reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5233                         reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5234
5235         if (reset_phase == MPT_IOC_SETUP_RESET) {
5236                 ;
5237         } else if (reset_phase == MPT_IOC_PRE_RESET) {
5238                 /* If the internal config Q is not empty -
5239                  * delete timer. MF resources will be freed when
5240                  * the FIFO's are primed.
5241                  */
5242                 spin_lock_irqsave(&ioc->FreeQlock, flags);
5243                 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5244                         del_timer(&pCfg->timer);
5245                 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5246
5247         } else {
5248                 CONFIGPARMS *pNext;
5249
5250                 /* Search the configQ for internal commands.
5251                  * Flush the Q, and wake up all suspended threads.
5252                  */
5253                 spin_lock_irqsave(&ioc->FreeQlock, flags);
5254                 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5255                         list_del(&pCfg->linkage);
5256
5257                         pCfg->status = MPT_CONFIG_ERROR;
5258                         pCfg->wait_done = 1;
5259                         wake_up(&mpt_waitq);
5260                 }
5261                 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5262         }
5263
5264         return 1;               /* currently means nothing really */
5265 }
5266
5267
5268 #ifdef CONFIG_PROC_FS           /* { */
5269 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5270 /*
5271  *      procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5272  */
5273 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5274 /*
5275  *      procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5276  *
5277  *      Returns 0 for success, non-zero for failure.
5278  */
5279 static int
5280 procmpt_create(void)
5281 {
5282         struct proc_dir_entry   *ent;
5283
5284         mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5285         if (mpt_proc_root_dir == NULL)
5286                 return -ENOTDIR;
5287
5288         ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5289         if (ent)
5290                 ent->read_proc = procmpt_summary_read;
5291
5292         ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5293         if (ent)
5294                 ent->read_proc = procmpt_version_read;
5295
5296         return 0;
5297 }
5298
5299 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5300 /*
5301  *      procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5302  *
5303  *      Returns 0 for success, non-zero for failure.
5304  */
5305 static void
5306 procmpt_destroy(void)
5307 {
5308         remove_proc_entry("version", mpt_proc_root_dir);
5309         remove_proc_entry("summary", mpt_proc_root_dir);
5310         remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5311 }
5312
5313 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5314 /*
5315  *      procmpt_summary_read - Handle read request from /proc/mpt/summary
5316  *      or from /proc/mpt/iocN/summary.
5317  *      @buf: Pointer to area to write information
5318  *      @start: Pointer to start pointer
5319  *      @offset: Offset to start writing
5320  *      @request:
5321  *      @eof: Pointer to EOF integer
5322  *      @data: Pointer
5323  *
5324  *      Returns number of characters written to process performing the read.
5325  */
5326 static int
5327 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5328 {
5329         MPT_ADAPTER *ioc;
5330         char *out = buf;
5331         int len;
5332
5333         if (data) {
5334                 int more = 0;
5335
5336                 ioc = data;
5337                 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5338
5339                 out += more;
5340         } else {
5341                 list_for_each_entry(ioc, &ioc_list, list) {
5342                         int     more = 0;
5343
5344                         mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5345
5346                         out += more;
5347                         if ((out-buf) >= request)
5348                                 break;
5349                 }
5350         }
5351
5352         len = out - buf;
5353
5354         MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5355 }
5356
5357 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5358 /*
5359  *      procmpt_version_read - Handle read request from /proc/mpt/version.
5360  *      @buf: Pointer to area to write information
5361  *      @start: Pointer to start pointer
5362  *      @offset: Offset to start writing
5363  *      @request:
5364  *      @eof: Pointer to EOF integer
5365  *      @data: Pointer
5366  *
5367  *      Returns number of characters written to process performing the read.
5368  */
5369 static int
5370 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5371 {
5372         int      ii;
5373         int      scsi, fc, sas, lan, ctl, targ, dmp;
5374         char    *drvname;
5375         int      len;
5376
5377         len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5378         len += sprintf(buf+len, "  Fusion MPT base driver\n");
5379
5380         scsi = fc = sas = lan = ctl = targ = dmp = 0;
5381         for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5382                 drvname = NULL;
5383                 if (MptCallbacks[ii]) {
5384                         switch (MptDriverClass[ii]) {
5385                         case MPTSPI_DRIVER:
5386                                 if (!scsi++) drvname = "SPI host";
5387                                 break;
5388                         case MPTFC_DRIVER:
5389                                 if (!fc++) drvname = "FC host";
5390                                 break;
5391                         case MPTSAS_DRIVER:
5392                                 if (!sas++) drvname = "SAS host";
5393                                 break;
5394                         case MPTLAN_DRIVER:
5395                                 if (!lan++) drvname = "LAN";
5396                                 break;
5397                         case MPTSTM_DRIVER:
5398                                 if (!targ++) drvname = "SCSI target";
5399                                 break;
5400                         case MPTCTL_DRIVER:
5401                                 if (!ctl++) drvname = "ioctl";
5402                                 break;
5403                         }
5404
5405                         if (drvname)
5406                                 len += sprintf(buf+len, "  Fusion MPT %s driver\n", drvname);
5407                 }
5408         }
5409
5410         MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5411 }
5412
5413 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5414 /*
5415  *      procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5416  *      @buf: Pointer to area to write information
5417  *      @start: Pointer to start pointer
5418  *      @offset: Offset to start writing
5419  *      @request:
5420  *      @eof: Pointer to EOF integer
5421  *      @data: Pointer
5422  *
5423  *      Returns number of characters written to process performing the read.
5424  */
5425 static int
5426 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5427 {
5428         MPT_ADAPTER     *ioc = data;
5429         int              len;
5430         char             expVer[32];
5431         int              sz;
5432         int              p;
5433
5434         mpt_get_fw_exp_ver(expVer, ioc);
5435
5436         len = sprintf(buf, "%s:", ioc->name);
5437         if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5438                 len += sprintf(buf+len, "  (f/w download boot flag set)");
5439 //      if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5440 //              len += sprintf(buf+len, "  CONFIG_CHECKSUM_FAIL!");
5441
5442         len += sprintf(buf+len, "\n  ProductID = 0x%04x (%s)\n",
5443                         ioc->facts.ProductID,
5444                         ioc->prod_name);
5445         len += sprintf(buf+len, "  FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5446         if (ioc->facts.FWImageSize)
5447                 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5448         len += sprintf(buf+len, "\n  MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5449         len += sprintf(buf+len, "  FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5450         len += sprintf(buf+len, "  EventState = 0x%02x\n", ioc->facts.EventState);
5451
5452         len += sprintf(buf+len, "  CurrentHostMfaHighAddr = 0x%08x\n",
5453                         ioc->facts.CurrentHostMfaHighAddr);
5454         len += sprintf(buf+len, "  CurrentSenseBufferHighAddr = 0x%08x\n",
5455                         ioc->facts.CurrentSenseBufferHighAddr);
5456
5457         len += sprintf(buf+len, "  MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5458         len += sprintf(buf+len, "  MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5459
5460         len += sprintf(buf+len, "  RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5461                                         (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
5462         /*
5463          *  Rounding UP to nearest 4-kB boundary here...
5464          */
5465         sz = (ioc->req_sz * ioc->req_depth) + 128;
5466         sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5467         len += sprintf(buf+len, "    {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5468                                         ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5469         len += sprintf(buf+len, "    {MaxReqSz=%d}   {MaxReqDepth=%d}\n",
5470                                         4*ioc->facts.RequestFrameSize,
5471                                         ioc->facts.GlobalCredits);
5472
5473         len += sprintf(buf+len, "  Frames   @ 0x%p (Dma @ 0x%p)\n",
5474                                         (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
5475         sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5476         len += sprintf(buf+len, "    {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5477                                         ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5478         len += sprintf(buf+len, "    {MaxRepSz=%d}   {MaxRepDepth=%d}\n",
5479                                         ioc->facts.CurReplyFrameSize,
5480                                         ioc->facts.ReplyQueueDepth);
5481
5482         len += sprintf(buf+len, "  MaxDevices = %d\n",
5483                         (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5484         len += sprintf(buf+len, "  MaxBuses = %d\n", ioc->facts.MaxBuses);
5485
5486         /* per-port info */
5487         for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5488                 len += sprintf(buf+len, "  PortNumber = %d (of %d)\n",
5489                                 p+1,
5490                                 ioc->facts.NumberOfPorts);
5491                 if (ioc->bus_type == FC) {
5492                         if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5493                                 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5494                                 len += sprintf(buf+len, "    LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5495                                                 a[5], a[4], a[3], a[2], a[1], a[0]);
5496                         }
5497                         len += sprintf(buf+len, "    WWN = %08X%08X:%08X%08X\n",
5498                                         ioc->fc_port_page0[p].WWNN.High,
5499                                         ioc->fc_port_page0[p].WWNN.Low,
5500                                         ioc->fc_port_page0[p].WWPN.High,
5501                                         ioc->fc_port_page0[p].WWPN.Low);
5502                 }
5503         }
5504
5505         MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5506 }
5507
5508 #endif          /* CONFIG_PROC_FS } */
5509
5510 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5511 static void
5512 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
5513 {
5514         buf[0] ='\0';
5515         if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
5516                 sprintf(buf, " (Exp %02d%02d)",
5517                         (ioc->facts.FWVersion.Word >> 16) & 0x00FF,     /* Month */
5518                         (ioc->facts.FWVersion.Word >> 8) & 0x1F);       /* Day */
5519
5520                 /* insider hack! */
5521                 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
5522                         strcat(buf, " [MDBG]");
5523         }
5524 }
5525
5526 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5527 /**
5528  *      mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5529  *      @ioc: Pointer to MPT_ADAPTER structure
5530  *      @buffer: Pointer to buffer where IOC summary info should be written
5531  *      @size: Pointer to number of bytes we wrote (set by this routine)
5532  *      @len: Offset at which to start writing in buffer
5533  *      @showlan: Display LAN stuff?
5534  *
5535  *      This routine writes (english readable) ASCII text, which represents
5536  *      a summary of IOC information, to a buffer.
5537  */
5538 void
5539 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
5540 {
5541         char expVer[32];
5542         int y;
5543
5544         mpt_get_fw_exp_ver(expVer, ioc);
5545
5546         /*
5547          *  Shorter summary of attached ioc's...
5548          */
5549         y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
5550                         ioc->name,
5551                         ioc->prod_name,
5552                         MPT_FW_REV_MAGIC_ID_STRING,     /* "FwRev=" or somesuch */
5553                         ioc->facts.FWVersion.Word,
5554                         expVer,
5555                         ioc->facts.NumberOfPorts,
5556                         ioc->req_depth);
5557
5558         if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
5559                 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5560                 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
5561                         a[5], a[4], a[3], a[2], a[1], a[0]);
5562         }
5563
5564         y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
5565
5566         if (!ioc->active)
5567                 y += sprintf(buffer+len+y, " (disabled)");
5568
5569         y += sprintf(buffer+len+y, "\n");
5570
5571         *size = y;
5572 }
5573
5574 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5575 /*
5576  *      Reset Handling
5577  */
5578 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5579 /**
5580  *      mpt_HardResetHandler - Generic reset handler, issue SCSI Task
5581  *      Management call based on input arg values.  If TaskMgmt fails,
5582  *      return associated SCSI request.
5583  *      @ioc: Pointer to MPT_ADAPTER structure
5584  *      @sleepFlag: Indicates if sleep or schedule must be called.
5585  *
5586  *      Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
5587  *      or a non-interrupt thread.  In the former, must not call schedule().
5588  *
5589  *      Remark: A return of -1 is a FATAL error case, as it means a
5590  *      FW reload/initialization failed.
5591  *
5592  *      Returns 0 for SUCCESS or -1 if FAILED.
5593  */
5594 int
5595 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5596 {
5597         int              rc;
5598         unsigned long    flags;
5599
5600         dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
5601 #ifdef MFCNT
5602         printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
5603         printk("MF count 0x%x !\n", ioc->mfcnt);
5604 #endif
5605
5606         /* Reset the adapter. Prevent more than 1 call to
5607          * mpt_do_ioc_recovery at any instant in time.
5608          */
5609         spin_lock_irqsave(&ioc->diagLock, flags);
5610         if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
5611                 spin_unlock_irqrestore(&ioc->diagLock, flags);
5612                 return 0;
5613         } else {
5614                 ioc->diagPending = 1;
5615         }
5616         spin_unlock_irqrestore(&ioc->diagLock, flags);
5617
5618         /* FIXME: If do_ioc_recovery fails, repeat....
5619          */
5620
5621         /* The SCSI driver needs to adjust timeouts on all current
5622          * commands prior to the diagnostic reset being issued.
5623          * Prevents timeouts occurring during a diagnostic reset...very bad.
5624          * For all other protocol drivers, this is a no-op.
5625          */
5626         {
5627                 int      ii;
5628                 int      r = 0;
5629
5630                 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5631                         if (MptResetHandlers[ii]) {
5632                                 dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
5633                                                 ioc->name, ii));
5634                                 r += mpt_signal_reset(ii, ioc, MPT_IOC_SETUP_RESET);
5635                                 if (ioc->alt_ioc) {
5636                                         dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
5637                                                         ioc->name, ioc->alt_ioc->name, ii));
5638                                         r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
5639                                 }
5640                         }
5641                 }
5642         }
5643
5644         if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
5645                 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
5646                         rc, ioc->name);
5647         }
5648         ioc->reload_fw = 0;
5649         if (ioc->alt_ioc)
5650                 ioc->alt_ioc->reload_fw = 0;
5651
5652         spin_lock_irqsave(&ioc->diagLock, flags);
5653         ioc->diagPending = 0;
5654         if (ioc->alt_ioc)
5655                 ioc->alt_ioc->diagPending = 0;
5656         spin_unlock_irqrestore(&ioc->diagLock, flags);
5657
5658         dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
5659
5660         return rc;
5661 }
5662
5663 # define EVENT_DESCR_STR_SZ             100
5664
5665 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5666 static void
5667 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5668 {
5669         char *ds = NULL;
5670
5671         switch(event) {
5672         case MPI_EVENT_NONE:
5673                 ds = "None";
5674                 break;
5675         case MPI_EVENT_LOG_DATA:
5676                 ds = "Log Data";
5677                 break;
5678         case MPI_EVENT_STATE_CHANGE:
5679                 ds = "State Change";
5680                 break;
5681         case MPI_EVENT_UNIT_ATTENTION:
5682                 ds = "Unit Attention";
5683                 break;
5684         case MPI_EVENT_IOC_BUS_RESET:
5685                 ds = "IOC Bus Reset";
5686                 break;
5687         case MPI_EVENT_EXT_BUS_RESET:
5688                 ds = "External Bus Reset";
5689                 break;
5690         case MPI_EVENT_RESCAN:
5691                 ds = "Bus Rescan Event";
5692                 /* Ok, do we need to do anything here? As far as
5693                    I can tell, this is when a new device gets added
5694                    to the loop. */
5695                 break;
5696         case MPI_EVENT_LINK_STATUS_CHANGE:
5697                 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
5698                         ds = "Link Status(FAILURE) Change";
5699                 else
5700                         ds = "Link Status(ACTIVE) Change";
5701                 break;
5702         case MPI_EVENT_LOOP_STATE_CHANGE:
5703                 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
5704                         ds = "Loop State(LIP) Change";
5705                 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
5706                         ds = "Loop State(LPE) Change";          /* ??? */
5707                 else
5708                         ds = "Loop State(LPB) Change";          /* ??? */
5709                 break;
5710         case MPI_EVENT_LOGOUT:
5711                 ds = "Logout";
5712                 break;
5713         case MPI_EVENT_EVENT_CHANGE:
5714                 if (evData0)
5715                         ds = "Events ON";
5716                 else
5717                         ds = "Events OFF";
5718                 break;
5719         case MPI_EVENT_INTEGRATED_RAID:
5720         {
5721                 u8 ReasonCode = (u8)(evData0 >> 16);
5722                 switch (ReasonCode) {
5723                 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
5724                         ds = "Integrated Raid: Volume Created";
5725                         break;
5726                 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
5727                         ds = "Integrated Raid: Volume Deleted";
5728                         break;
5729                 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
5730                         ds = "Integrated Raid: Volume Settings Changed";
5731                         break;
5732                 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
5733                         ds = "Integrated Raid: Volume Status Changed";
5734                         break;
5735                 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
5736                         ds = "Integrated Raid: Volume Physdisk Changed";
5737                         break;
5738                 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
5739                         ds = "Integrated Raid: Physdisk Created";
5740                         break;
5741                 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
5742                         ds = "Integrated Raid: Physdisk Deleted";
5743                         break;
5744                 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
5745                         ds = "Integrated Raid: Physdisk Settings Changed";
5746                         break;
5747                 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
5748                         ds = "Integrated Raid: Physdisk Status Changed";
5749                         break;
5750                 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
5751                         ds = "Integrated Raid: Domain Validation Needed";
5752                         break;
5753                 case MPI_EVENT_RAID_RC_SMART_DATA :
5754                         ds = "Integrated Raid; Smart Data";
5755                         break;
5756                 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
5757                         ds = "Integrated Raid: Replace Action Started";
5758                         break;
5759                 default:
5760                         ds = "Integrated Raid";
5761                 break;
5762                 }
5763                 break;
5764         }
5765         case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
5766                 ds = "SCSI Device Status Change";
5767                 break;
5768         case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
5769         {
5770                 u8 id = (u8)(evData0);
5771                 u8 ReasonCode = (u8)(evData0 >> 16);
5772                 switch (ReasonCode) {
5773                 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
5774                         snprintf(evStr, EVENT_DESCR_STR_SZ,
5775                             "SAS Device Status Change: Added: id=%d", id);
5776                         break;
5777                 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
5778                         snprintf(evStr, EVENT_DESCR_STR_SZ,
5779                             "SAS Device Status Change: Deleted: id=%d", id);
5780                         break;
5781                 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
5782                         snprintf(evStr, EVENT_DESCR_STR_SZ,
5783                             "SAS Device Status Change: SMART Data: id=%d",
5784                             id);
5785                         break;
5786                 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
5787                         snprintf(evStr, EVENT_DESCR_STR_SZ,
5788                             "SAS Device Status Change: No Persistancy: id=%d", id);
5789                         break;
5790                 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
5791                         snprintf(evStr, EVENT_DESCR_STR_SZ,
5792                             "SAS Device Status Change: Internal Device Reset : id=%d", id);
5793                         break;
5794                 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
5795                         snprintf(evStr, EVENT_DESCR_STR_SZ,
5796                             "SAS Device Status Change: Internal Task Abort : id=%d", id);
5797                         break;
5798                 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
5799                         snprintf(evStr, EVENT_DESCR_STR_SZ,
5800                             "SAS Device Status Change: Internal Abort Task Set : id=%d", id);
5801                         break;
5802                 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
5803                         snprintf(evStr, EVENT_DESCR_STR_SZ,
5804                             "SAS Device Status Change: Internal Clear Task Set : id=%d", id);
5805                         break;
5806                 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
5807                         snprintf(evStr, EVENT_DESCR_STR_SZ,
5808                             "SAS Device Status Change: Internal Query Task : id=%d", id);
5809                         break;
5810                 default:
5811                         snprintf(evStr, EVENT_DESCR_STR_SZ,
5812                             "SAS Device Status Change: Unknown: id=%d", id);
5813                         break;
5814                 }
5815                 break;
5816         }
5817         case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
5818                 ds = "Bus Timer Expired";
5819                 break;
5820         case MPI_EVENT_QUEUE_FULL:
5821                 ds = "Queue Full";
5822                 break;
5823         case MPI_EVENT_SAS_SES:
5824                 ds = "SAS SES Event";
5825                 break;
5826         case MPI_EVENT_PERSISTENT_TABLE_FULL:
5827                 ds = "Persistent Table Full";
5828                 break;
5829         case MPI_EVENT_SAS_PHY_LINK_STATUS:
5830         {
5831                 u8 LinkRates = (u8)(evData0 >> 8);
5832                 u8 PhyNumber = (u8)(evData0);
5833                 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
5834                         MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
5835                 switch (LinkRates) {
5836                 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
5837                         snprintf(evStr, EVENT_DESCR_STR_SZ,
5838                            "SAS PHY Link Status: Phy=%d:"
5839                            " Rate Unknown",PhyNumber);
5840                         break;
5841                 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
5842                         snprintf(evStr, EVENT_DESCR_STR_SZ,
5843                            "SAS PHY Link Status: Phy=%d:"
5844                            " Phy Disabled",PhyNumber);
5845                         break;
5846                 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
5847                         snprintf(evStr, EVENT_DESCR_STR_SZ,
5848                            "SAS PHY Link Status: Phy=%d:"
5849                            " Failed Speed Nego",PhyNumber);
5850                         break;
5851                 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
5852                         snprintf(evStr, EVENT_DESCR_STR_SZ,
5853                            "SAS PHY Link Status: Phy=%d:"
5854                            " Sata OOB Completed",PhyNumber);
5855                         break;
5856                 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
5857                         snprintf(evStr, EVENT_DESCR_STR_SZ,
5858                            "SAS PHY Link Status: Phy=%d:"
5859                            " Rate 1.5 Gbps",PhyNumber);
5860                         break;
5861                 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
5862                         snprintf(evStr, EVENT_DESCR_STR_SZ,
5863                            "SAS PHY Link Status: Phy=%d:"
5864                            " Rate 3.0 Gpbs",PhyNumber);
5865                         break;
5866                 default:
5867                         snprintf(evStr, EVENT_DESCR_STR_SZ,
5868                            "SAS PHY Link Status: Phy=%d", PhyNumber);
5869                         break;
5870                 }
5871                 break;
5872         }
5873         case MPI_EVENT_SAS_DISCOVERY_ERROR:
5874                 ds = "SAS Discovery Error";
5875                 break;
5876         case MPI_EVENT_IR_RESYNC_UPDATE:
5877         {
5878                 u8 resync_complete = (u8)(evData0 >> 16);
5879                 snprintf(evStr, EVENT_DESCR_STR_SZ,
5880                     "IR Resync Update: Complete = %d:",resync_complete);
5881                 break;
5882         }
5883         case MPI_EVENT_IR2:
5884         {
5885                 u8 ReasonCode = (u8)(evData0 >> 16);
5886                 switch (ReasonCode) {
5887                 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
5888                         ds = "IR2: LD State Changed";
5889                         break;
5890                 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
5891                         ds = "IR2: PD State Changed";
5892                         break;
5893                 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
5894                         ds = "IR2: Bad Block Table Full";
5895                         break;
5896                 case MPI_EVENT_IR2_RC_PD_INSERTED:
5897                         ds = "IR2: PD Inserted";
5898                         break;
5899                 case MPI_EVENT_IR2_RC_PD_REMOVED:
5900                         ds = "IR2: PD Removed";
5901                         break;
5902                 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
5903                         ds = "IR2: Foreign CFG Detected";
5904                         break;
5905                 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
5906                         ds = "IR2: Rebuild Medium Error";
5907                         break;
5908                 default:
5909                         ds = "IR2";
5910                 break;
5911                 }
5912                 break;
5913         }
5914         case MPI_EVENT_SAS_DISCOVERY:
5915         {
5916                 if (evData0)
5917                         ds = "SAS Discovery: Start";
5918                 else
5919                         ds = "SAS Discovery: Stop";
5920                 break;
5921         }
5922         case MPI_EVENT_LOG_ENTRY_ADDED:
5923                 ds = "SAS Log Entry Added";
5924                 break;
5925
5926         /*
5927          *  MPT base "custom" events may be added here...
5928          */
5929         default:
5930                 ds = "Unknown";
5931                 break;
5932         }
5933         if (ds)
5934                 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
5935 }
5936
5937 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5938 /*
5939  *      ProcessEventNotification - Route a received EventNotificationReply to
5940  *      all currently regeistered event handlers.
5941  *      @ioc: Pointer to MPT_ADAPTER structure
5942  *      @pEventReply: Pointer to EventNotification reply frame
5943  *      @evHandlers: Pointer to integer, number of event handlers
5944  *
5945  *      Returns sum of event handlers return values.
5946  */
5947 static int
5948 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
5949 {
5950         u16 evDataLen;
5951         u32 evData0 = 0;
5952 //      u32 evCtx;
5953         int ii;
5954         int r = 0;
5955         int handlers = 0;
5956         char evStr[EVENT_DESCR_STR_SZ];
5957         u8 event;
5958
5959         /*
5960          *  Do platform normalization of values
5961          */
5962         event = le32_to_cpu(pEventReply->Event) & 0xFF;
5963 //      evCtx = le32_to_cpu(pEventReply->EventContext);
5964         evDataLen = le16_to_cpu(pEventReply->EventDataLength);
5965         if (evDataLen) {
5966                 evData0 = le32_to_cpu(pEventReply->Data[0]);
5967         }
5968
5969         EventDescriptionStr(event, evData0, evStr);
5970         devtprintk((MYIOC_s_INFO_FMT "MPT event:(%02Xh) : %s\n",
5971                         ioc->name,
5972                         event,
5973                         evStr));
5974
5975 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_VERBOSE_EVENTS)
5976         printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
5977         for (ii = 0; ii < evDataLen; ii++)
5978                 printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
5979         printk("\n");
5980 #endif
5981
5982         /*
5983          *  Do general / base driver event processing
5984          */
5985         switch(event) {
5986         case MPI_EVENT_EVENT_CHANGE:            /* 0A */
5987                 if (evDataLen) {
5988                         u8 evState = evData0 & 0xFF;
5989
5990                         /* CHECKME! What if evState unexpectedly says OFF (0)? */
5991
5992                         /* Update EventState field in cached IocFacts */
5993                         if (ioc->facts.Function) {
5994                                 ioc->facts.EventState = evState;
5995                         }
5996                 }
5997                 break;
5998         case MPI_EVENT_INTEGRATED_RAID:
5999                 mptbase_raid_process_event_data(ioc,
6000                     (MpiEventDataRaid_t *)pEventReply->Data);
6001                 break;
6002         default:
6003                 break;
6004         }
6005
6006         /*
6007          * Should this event be logged? Events are written sequentially.
6008          * When buffer is full, start again at the top.
6009          */
6010         if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6011                 int idx;
6012
6013                 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
6014
6015                 ioc->events[idx].event = event;
6016                 ioc->events[idx].eventContext = ioc->eventContext;
6017
6018                 for (ii = 0; ii < 2; ii++) {
6019                         if (ii < evDataLen)
6020                                 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6021                         else
6022                                 ioc->events[idx].data[ii] =  0;
6023                 }
6024
6025                 ioc->eventContext++;
6026         }
6027
6028
6029         /*
6030          *  Call each currently registered protocol event handler.
6031          */
6032         for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
6033                 if (MptEvHandlers[ii]) {
6034                         devtverboseprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
6035                                         ioc->name, ii));
6036                         r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
6037                         handlers++;
6038                 }
6039         }
6040         /* FIXME?  Examine results here? */
6041
6042         /*
6043          *  If needed, send (a single) EventAck.
6044          */
6045         if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6046                 devtverboseprintk((MYIOC_s_WARN_FMT
6047                         "EventAck required\n",ioc->name));
6048                 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6049                         devtverboseprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
6050                                         ioc->name, ii));
6051                 }
6052         }
6053
6054         *evHandlers = handlers;
6055         return r;
6056 }
6057
6058 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6059 /*
6060  *      mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6061  *      @ioc: Pointer to MPT_ADAPTER structure
6062  *      @log_info: U32 LogInfo reply word from the IOC
6063  *
6064  *      Refer to lsi/mpi_log_fc.h.
6065  */
6066 static void
6067 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6068 {
6069         static char *subcl_str[8] = {
6070                 "FCP Initiator", "FCP Target", "LAN", "MPI Message Layer",
6071                 "FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
6072         };
6073         u8 subcl = (log_info >> 24) & 0x7;
6074
6075         printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}\n",
6076                         ioc->name, log_info, subcl_str[subcl]);
6077 }
6078
6079 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6080 /*
6081  *      mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6082  *      @ioc: Pointer to MPT_ADAPTER structure
6083  *      @mr: Pointer to MPT reply frame
6084  *      @log_info: U32 LogInfo word from the IOC
6085  *
6086  *      Refer to lsi/sp_log.h.
6087  */
6088 static void
6089 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6090 {
6091         u32 info = log_info & 0x00FF0000;
6092         char *desc = "unknown";
6093
6094         switch (info) {
6095         case 0x00010000:
6096                 desc = "bug! MID not found";
6097                 if (ioc->reload_fw == 0)
6098                         ioc->reload_fw++;
6099                 break;
6100
6101         case 0x00020000:
6102                 desc = "Parity Error";
6103                 break;
6104
6105         case 0x00030000:
6106                 desc = "ASYNC Outbound Overrun";
6107                 break;
6108
6109         case 0x00040000:
6110                 desc = "SYNC Offset Error";
6111                 break;
6112
6113         case 0x00050000:
6114                 desc = "BM Change";
6115                 break;
6116
6117         case 0x00060000:
6118                 desc = "Msg In Overflow";
6119                 break;
6120
6121         case 0x00070000:
6122                 desc = "DMA Error";
6123                 break;
6124
6125         case 0x00080000:
6126                 desc = "Outbound DMA Overrun";
6127                 break;
6128
6129         case 0x00090000:
6130                 desc = "Task Management";
6131                 break;
6132
6133         case 0x000A0000:
6134                 desc = "Device Problem";
6135                 break;
6136
6137         case 0x000B0000:
6138                 desc = "Invalid Phase Change";
6139                 break;
6140
6141         case 0x000C0000:
6142                 desc = "Untagged Table Size";
6143                 break;
6144
6145         }
6146
6147         printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6148 }
6149
6150 /* strings for sas loginfo */
6151         static char *originator_str[] = {
6152                 "IOP",                                          /* 00h */
6153                 "PL",                                           /* 01h */
6154                 "IR"                                            /* 02h */
6155         };
6156         static char *iop_code_str[] = {
6157                 NULL,                                           /* 00h */
6158                 "Invalid SAS Address",                          /* 01h */
6159                 NULL,                                           /* 02h */
6160                 "Invalid Page",                                 /* 03h */
6161                 "Diag Message Error",                           /* 04h */
6162                 "Task Terminated",                              /* 05h */
6163                 "Enclosure Management",                         /* 06h */
6164                 "Target Mode"                                   /* 07h */
6165         };
6166         static char *pl_code_str[] = {
6167                 NULL,                                           /* 00h */
6168                 "Open Failure",                                 /* 01h */
6169                 "Invalid Scatter Gather List",                  /* 02h */
6170                 "Wrong Relative Offset or Frame Length",        /* 03h */
6171                 "Frame Transfer Error",                         /* 04h */
6172                 "Transmit Frame Connected Low",                 /* 05h */
6173                 "SATA Non-NCQ RW Error Bit Set",                /* 06h */
6174                 "SATA Read Log Receive Data Error",             /* 07h */
6175                 "SATA NCQ Fail All Commands After Error",       /* 08h */
6176                 "SATA Error in Receive Set Device Bit FIS",     /* 09h */
6177                 "Receive Frame Invalid Message",                /* 0Ah */
6178                 "Receive Context Message Valid Error",          /* 0Bh */
6179                 "Receive Frame Current Frame Error",            /* 0Ch */
6180                 "SATA Link Down",                               /* 0Dh */
6181                 "Discovery SATA Init W IOS",                    /* 0Eh */
6182                 "Config Invalid Page",                          /* 0Fh */
6183                 "Discovery SATA Init Timeout",                  /* 10h */
6184                 "Reset",                                        /* 11h */
6185                 "Abort",                                        /* 12h */
6186                 "IO Not Yet Executed",                          /* 13h */
6187                 "IO Executed",                                  /* 14h */
6188                 "Persistant Reservation Out Not Affiliation Owner", /* 15h */
6189                 "Open Transmit DMA Abort",                      /* 16h */
6190                 "IO Device Missing Delay Retry",                /* 17h */
6191                 NULL,                                           /* 18h */
6192                 NULL,                                           /* 19h */
6193                 NULL,                                           /* 1Ah */
6194                 NULL,                                           /* 1Bh */
6195                 NULL,                                           /* 1Ch */
6196                 NULL,                                           /* 1Dh */
6197                 NULL,                                           /* 1Eh */
6198                 NULL,                                           /* 1Fh */
6199                 "Enclosure Management"                          /* 20h */
6200         };
6201
6202 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6203 /*
6204  *      mpt_sas_log_info - Log information returned from SAS IOC.
6205  *      @ioc: Pointer to MPT_ADAPTER structure
6206  *      @log_info: U32 LogInfo reply word from the IOC
6207  *
6208  *      Refer to lsi/mpi_log_sas.h.
6209  */
6210 static void
6211 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6212 {
6213 union loginfo_type {
6214         u32     loginfo;
6215         struct {
6216                 u32     subcode:16;
6217                 u32     code:8;
6218                 u32     originator:4;
6219                 u32     bus_type:4;
6220         }dw;
6221 };
6222         union loginfo_type sas_loginfo;
6223         char *code_desc = NULL;
6224
6225         sas_loginfo.loginfo = log_info;
6226         if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
6227             (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
6228                 return;
6229         if ((sas_loginfo.dw.originator == 0 /*IOP*/) &&
6230             (sas_loginfo.dw.code < sizeof(iop_code_str)/sizeof(char*))) {
6231                 code_desc = iop_code_str[sas_loginfo.dw.code];
6232         }else if ((sas_loginfo.dw.originator == 1 /*PL*/) &&
6233             (sas_loginfo.dw.code < sizeof(pl_code_str)/sizeof(char*) )) {
6234                 code_desc = pl_code_str[sas_loginfo.dw.code];
6235         }
6236
6237         if (code_desc != NULL)
6238                 printk(MYIOC_s_INFO_FMT
6239                         "LogInfo(0x%08x): Originator={%s}, Code={%s},"
6240                         " SubCode(0x%04x)\n",
6241                         ioc->name,
6242                         log_info,
6243                         originator_str[sas_loginfo.dw.originator],
6244                         code_desc,
6245                         sas_loginfo.dw.subcode);
6246         else
6247                 printk(MYIOC_s_INFO_FMT
6248                         "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
6249                         " SubCode(0x%04x)\n",
6250                         ioc->name,
6251                         log_info,
6252                         originator_str[sas_loginfo.dw.originator],
6253                         sas_loginfo.dw.code,
6254                         sas_loginfo.dw.subcode);
6255 }
6256
6257 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6258 /*
6259  *      mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
6260  *      @ioc: Pointer to MPT_ADAPTER structure
6261  *      @ioc_status: U32 IOCStatus word from IOC
6262  *      @mf: Pointer to MPT request frame
6263  *
6264  *      Refer to lsi/mpi.h.
6265  */
6266 static void
6267 mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
6268 {
6269         u32 status = ioc_status & MPI_IOCSTATUS_MASK;
6270         char *desc = NULL;
6271
6272         switch (status) {
6273         case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
6274                 desc = "Invalid Function";
6275                 break;
6276
6277         case MPI_IOCSTATUS_BUSY: /* 0x0002 */
6278                 desc = "Busy";
6279                 break;
6280
6281         case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
6282                 desc = "Invalid SGL";
6283                 break;
6284
6285         case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
6286                 desc = "Internal Error";
6287                 break;
6288
6289         case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
6290                 desc = "Reserved";
6291                 break;
6292
6293         case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
6294                 desc = "Insufficient Resources";
6295                 break;
6296
6297         case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
6298                 desc = "Invalid Field";
6299                 break;
6300
6301         case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
6302                 desc = "Invalid State";
6303                 break;
6304
6305         case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
6306         case MPI_IOCSTATUS_CONFIG_INVALID_TYPE:   /* 0x0021 */
6307         case MPI_IOCSTATUS_CONFIG_INVALID_PAGE:   /* 0x0022 */
6308         case MPI_IOCSTATUS_CONFIG_INVALID_DATA:   /* 0x0023 */
6309         case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS:    /* 0x0024 */
6310         case MPI_IOCSTATUS_CONFIG_CANT_COMMIT:    /* 0x0025 */
6311                 /* No message for Config IOCStatus values */
6312                 break;
6313
6314         case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
6315                 /* No message for recovered error
6316                 desc = "SCSI Recovered Error";
6317                 */
6318                 break;
6319
6320         case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
6321                 desc = "SCSI Invalid Bus";
6322                 break;
6323
6324         case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
6325                 desc = "SCSI Invalid TargetID";
6326                 break;
6327
6328         case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
6329           {
6330                 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
6331                 U8 cdb = pScsiReq->CDB[0];
6332                 if (cdb != 0x12) { /* Inquiry is issued for device scanning */
6333                         desc = "SCSI Device Not There";
6334                 }
6335                 break;
6336           }
6337
6338         case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
6339                 desc = "SCSI Data Overrun";
6340                 break;
6341
6342         case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
6343                 /* This error is checked in scsi_io_done(). Skip.
6344                 desc = "SCSI Data Underrun";
6345                 */
6346                 break;
6347
6348         case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
6349                 desc = "SCSI I/O Data Error";
6350                 break;
6351
6352         case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
6353                 desc = "SCSI Protocol Error";
6354                 break;
6355
6356         case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
6357                 desc = "SCSI Task Terminated";
6358                 break;
6359
6360         case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
6361                 desc = "SCSI Residual Mismatch";
6362                 break;
6363
6364         case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
6365                 desc = "SCSI Task Management Failed";
6366                 break;
6367
6368         case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
6369                 desc = "SCSI IOC Terminated";
6370                 break;
6371
6372         case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
6373                 desc = "SCSI Ext Terminated";
6374                 break;
6375
6376         default:
6377                 desc = "Others";
6378                 break;
6379         }
6380         if (desc != NULL)
6381                 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc);
6382 }
6383
6384 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6385 EXPORT_SYMBOL(mpt_attach);
6386 EXPORT_SYMBOL(mpt_detach);
6387 #ifdef CONFIG_PM
6388 EXPORT_SYMBOL(mpt_resume);
6389 EXPORT_SYMBOL(mpt_suspend);
6390 #endif
6391 EXPORT_SYMBOL(ioc_list);
6392 EXPORT_SYMBOL(mpt_proc_root_dir);
6393 EXPORT_SYMBOL(mpt_register);
6394 EXPORT_SYMBOL(mpt_deregister);
6395 EXPORT_SYMBOL(mpt_event_register);
6396 EXPORT_SYMBOL(mpt_event_deregister);
6397 EXPORT_SYMBOL(mpt_reset_register);
6398 EXPORT_SYMBOL(mpt_reset_deregister);
6399 EXPORT_SYMBOL(mpt_device_driver_register);
6400 EXPORT_SYMBOL(mpt_device_driver_deregister);
6401 EXPORT_SYMBOL(mpt_get_msg_frame);
6402 EXPORT_SYMBOL(mpt_put_msg_frame);
6403 EXPORT_SYMBOL(mpt_free_msg_frame);
6404 EXPORT_SYMBOL(mpt_add_sge);
6405 EXPORT_SYMBOL(mpt_send_handshake_request);
6406 EXPORT_SYMBOL(mpt_verify_adapter);
6407 EXPORT_SYMBOL(mpt_GetIocState);
6408 EXPORT_SYMBOL(mpt_print_ioc_summary);
6409 EXPORT_SYMBOL(mpt_lan_index);
6410 EXPORT_SYMBOL(mpt_stm_index);
6411 EXPORT_SYMBOL(mpt_HardResetHandler);
6412 EXPORT_SYMBOL(mpt_config);
6413 EXPORT_SYMBOL(mpt_findImVolumes);
6414 EXPORT_SYMBOL(mpt_alloc_fw_memory);
6415 EXPORT_SYMBOL(mpt_free_fw_memory);
6416 EXPORT_SYMBOL(mptbase_sas_persist_operation);
6417
6418 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6419 /*
6420  *      fusion_init - Fusion MPT base driver initialization routine.
6421  *
6422  *      Returns 0 for success, non-zero for failure.
6423  */
6424 static int __init
6425 fusion_init(void)
6426 {
6427         int i;
6428
6429         show_mptmod_ver(my_NAME, my_VERSION);
6430         printk(KERN_INFO COPYRIGHT "\n");
6431
6432         for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
6433                 MptCallbacks[i] = NULL;
6434                 MptDriverClass[i] = MPTUNKNOWN_DRIVER;
6435                 MptEvHandlers[i] = NULL;
6436                 MptResetHandlers[i] = NULL;
6437         }
6438
6439         /*  Register ourselves (mptbase) in order to facilitate
6440          *  EventNotification handling.
6441          */
6442         mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
6443
6444         /* Register for hard reset handling callbacks.
6445          */
6446         if (mpt_reset_register(mpt_base_index, mpt_ioc_reset) == 0) {
6447                 dprintk((KERN_INFO MYNAM ": Register for IOC reset notification\n"));
6448         } else {
6449                 /* FIXME! */
6450         }
6451
6452 #ifdef CONFIG_PROC_FS
6453         (void) procmpt_create();
6454 #endif
6455         return 0;
6456 }
6457
6458 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6459 /*
6460  *      fusion_exit - Perform driver unload cleanup.
6461  *
6462  *      This routine frees all resources associated with each MPT adapter
6463  *      and removes all %MPT_PROCFS_MPTBASEDIR entries.
6464  */
6465 static void __exit
6466 fusion_exit(void)
6467 {
6468
6469         dexitprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
6470
6471         mpt_reset_deregister(mpt_base_index);
6472
6473 #ifdef CONFIG_PROC_FS
6474         procmpt_destroy();
6475 #endif
6476 }
6477
6478 module_init(fusion_init);
6479 module_exit(fusion_exit);