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