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