2 * linux/drivers/message/fusion/mptbase.c
3 * High performance SCSI + LAN / Fibre Channel device drivers.
4 * This is the Fusion MPT base driver which supports multiple
5 * (SCSI + LAN) specialized protocol drivers.
6 * For use with PCI chip/adapter(s):
7 * LSIFC9xx/LSI409xx Fibre Channel
8 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
11 * There are lots of people not mentioned below that deserve credit
12 * and thanks but won't get it here - sorry in advance that you
15 * This driver would not exist if not for Alan Cox's development
16 * of the linux i2o driver.
18 * A special thanks to Noah Romer (LSI Logic) for tons of work
19 * and tough debugging on the LAN driver, especially early on;-)
20 * And to Roger Hickerson (LSI Logic) for tirelessly supporting
21 * this driver project.
23 * A special thanks to Pamela Delaney (LSI Logic) for tons of work
24 * and countless enhancements while adding support for the 1030
25 * chip family. Pam has been instrumental in the development of
26 * of the 2.xx.xx series fusion drivers, and her contributions are
27 * far too numerous to hope to list in one place.
29 * All manner of help from Stephen Shirron (LSI Logic):
30 * low-level FC analysis, debug + various fixes in FCxx firmware,
31 * initial port to alpha platform, various driver code optimizations,
32 * being a faithful sounding board on all sorts of issues & ideas,
35 * A huge debt of gratitude is owed to David S. Miller (DaveM)
36 * for fixing much of the stupid and broken stuff in the early
37 * driver while porting to sparc64 platform. THANK YOU!
39 * Special thanks goes to the I2O LAN driver people at the
40 * University of Helsinki, who, unbeknownst to them, provided
41 * the inspiration and initial structure for this driver.
43 * A really huge debt of gratitude is owed to Eddie C. Dost
44 * for gobs of hard work fixing and optimizing LAN code.
47 * Copyright (c) 1999-2004 LSI Logic Corporation
48 * Originally By: Steven J. Ralston
49 * (mailto:sjralston1@netscape.net)
50 * (mailto:mpt_linux_developer@lsil.com)
52 * $Id: mptbase.c,v 1.126 2002/12/16 15:28:45 pdelaney Exp $
54 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
56 This program is free software; you can redistribute it and/or modify
57 it under the terms of the GNU General Public License as published by
58 the Free Software Foundation; version 2 of the License.
60 This program is distributed in the hope that it will be useful,
61 but WITHOUT ANY WARRANTY; without even the implied warranty of
62 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
63 GNU General Public License for more details.
66 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
67 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
68 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
69 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
70 solely responsible for determining the appropriateness of using and
71 distributing the Program and assumes all risks associated with its
72 exercise of rights under this Agreement, including but not limited to
73 the risks and costs of program errors, damage to or loss of data,
74 programs or equipment, and unavailability or interruption of operations.
76 DISCLAIMER OF LIABILITY
77 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
78 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
79 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
80 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
81 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
82 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
83 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
85 You should have received a copy of the GNU General Public License
86 along with this program; if not, write to the Free Software
87 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
89 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
91 #include <linux/config.h>
92 #include <linux/version.h>
93 #include <linux/kernel.h>
94 #include <linux/module.h>
95 #include <linux/errno.h>
96 #include <linux/init.h>
97 #include <linux/slab.h>
98 #include <linux/types.h>
99 #include <linux/pci.h>
100 #include <linux/kdev_t.h>
101 #include <linux/blkdev.h>
102 #include <linux/delay.h>
103 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
106 #include <asm/mtrr.h>
109 #include <asm/irq.h> /* needed for __irq_itoa() proto */
114 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
115 #define my_NAME "Fusion MPT base driver"
116 #define my_VERSION MPT_LINUX_VERSION_COMMON
117 #define MYNAM "mptbase"
119 MODULE_AUTHOR(MODULEAUTHOR);
120 MODULE_DESCRIPTION(my_NAME);
121 MODULE_LICENSE("GPL");
124 * cmd line parameters
127 static int mfcounter = 0;
128 #define PRINT_MF_COUNT 20000
131 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
135 int mpt_lan_index = -1;
136 int mpt_stm_index = -1;
138 struct proc_dir_entry *mpt_proc_root_dir;
140 DmpServices_t *DmpService;
142 void *mpt_v_ASCQ_TablePtr;
143 const char **mpt_ScsiOpcodesPtr;
144 int mpt_ASCQ_TableSz;
147 #define WHOINIT_UNKNOWN 0xAA
149 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
153 /* Adapter lookup table */
154 MPT_ADAPTER *mpt_adapters[MPT_MAX_ADAPTERS];
155 static MPT_ADAPTER_TRACKER MptAdapters;
156 /* Callback lookup table */
157 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
158 /* Protocol driver class lookup table */
159 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
160 /* Event handler lookup table */
161 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
162 /* Reset handler lookup table */
163 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
164 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
166 static int FusionInitCalled = 0;
167 static int mpt_base_index = -1;
168 static int last_drv_idx = -1;
169 static int isense_idx = -1;
171 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
173 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
177 static irqreturn_t mpt_interrupt(int irq, void *bus_id, struct pt_regs *r);
178 static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
180 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
181 static void mpt_detect_bound_ports(MPT_ADAPTER *this, struct pci_dev *pdev);
182 static void mpt_adapter_disable(MPT_ADAPTER *ioc, int freeup);
183 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
185 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
186 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
187 //static u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
188 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
189 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
190 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
191 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
192 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
193 static int mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag);
194 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
195 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
196 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
197 static int PrimeIocFifos(MPT_ADAPTER *ioc);
198 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
199 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
200 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
201 static int GetLanConfigPages(MPT_ADAPTER *ioc);
202 static int GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
203 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
204 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
205 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
206 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
207 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
208 static void mpt_timer_expired(unsigned long data);
209 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
210 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
212 #ifdef CONFIG_PROC_FS
213 static int procmpt_create(void);
214 static int procmpt_destroy(void);
215 static int procmpt_summary_read(char *buf, char **start, off_t offset,
216 int request, int *eof, void *data);
217 static int procmpt_version_read(char *buf, char **start, off_t offset,
218 int request, int *eof, void *data);
219 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
220 int request, int *eof, void *data);
222 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
224 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
225 static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
226 static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
227 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
228 static void mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info);
230 /* module entry point */
231 static int __devinit mptbase_probe (struct pci_dev *, const struct pci_device_id *);
232 static void __devexit mptbase_remove(struct pci_dev *);
233 static void mptbase_shutdown(struct device * );
234 static int __init fusion_init (void);
235 static void __exit fusion_exit (void);
237 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
239 * more Private data...
241 #ifdef CONFIG_PROC_FS
242 struct _mpt_proc_list {
244 int (*f)(char *, char **, off_t, int, int *, void *);
245 } mpt_proc_list[] = {
246 { "summary", procmpt_summary_read},
247 { "version", procmpt_version_read},
249 #define MPT_PROC_ENTRIES (sizeof(mpt_proc_list)/sizeof(mpt_proc_list[0]))
251 struct _mpt_ioc_proc_list {
253 int (*f)(char *, char **, off_t, int, int *, void *);
254 } mpt_ioc_proc_list[] = {
255 { "info", procmpt_iocinfo_read},
256 { "summary", procmpt_summary_read},
258 #define MPT_IOC_PROC_ENTRIES (sizeof(mpt_ioc_proc_list)/sizeof(mpt_ioc_proc_list[0]))
262 /****************************************************************************
266 static struct pci_device_id mptbase_pci_table[] = {
267 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC909,
268 PCI_ANY_ID, PCI_ANY_ID },
269 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929,
270 PCI_ANY_ID, PCI_ANY_ID },
271 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919,
272 PCI_ANY_ID, PCI_ANY_ID },
273 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929X,
274 PCI_ANY_ID, PCI_ANY_ID },
275 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919X,
276 PCI_ANY_ID, PCI_ANY_ID },
277 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1030,
278 PCI_ANY_ID, PCI_ANY_ID },
279 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_1030_53C1035,
280 PCI_ANY_ID, PCI_ANY_ID },
281 {0} /* Terminating entry */
283 MODULE_DEVICE_TABLE(pci, mptbase_pci_table);
285 #define CHIPREG_READ32(addr) readl(addr)
286 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
287 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
288 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
290 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
292 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
293 * @irq: irq number (not used)
294 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
295 * @r: pt_regs pointer (not used)
297 * This routine is registered via the request_irq() kernel API call,
298 * and handles all interrupts generated from a specific MPT adapter
299 * (also referred to as a IO Controller or IOC).
300 * This routine must clear the interrupt from the adapter and does
301 * so by reading the reply FIFO. Multiple replies may be processed
302 * per single call to this routine; up to MPT_MAX_REPLIES_PER_ISR
303 * which is currently set to 32 in mptbase.h.
305 * This routine handles register-level access of the adapter but
306 * dispatches (calls) a protocol-specific callback routine to handle
307 * the protocol-specific details of the MPT request completion.
310 mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
325 * Verify ioc pointer is ok
329 iocCmp = mpt_adapter_find_first();
330 while ((ioc != iocCmp) && iocCmp)
331 iocCmp = mpt_adapter_find_next(iocCmp);
334 printk(KERN_WARNING "mpt_interrupt: Invalid ioc!\n");
341 * Drain the reply FIFO!
343 * NOTES: I've seen up to 10 replies processed in this loop, so far...
344 * Update: I've seen up to 9182 replies processed in this loop! ??
345 * Update: Limit ourselves to processing max of N replies
350 if ((pa = CHIPREG_READ32(&ioc->chip->ReplyFifo)) == 0xFFFFFFFF)
357 * Check for non-TURBO reply!
359 if (pa & MPI_ADDRESS_REPLY_A_BIT) {
363 /* non-TURBO reply! Hmmm, something may be up...
364 * Newest turbo reply mechanism; get address
365 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
368 /* Map DMA address of reply header to cpu address.
369 * pa is 32 bits - but the dma address may be 32 or 64 bits
370 * get offset based only only the low addresses
372 reply_dma_low = (pa = (pa << 1));
373 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
374 (reply_dma_low - ioc->reply_frames_low_dma));
376 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
377 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
378 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
380 dprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p\n",
382 DBG_DUMP_REPLY_FRAME(mr)
384 /* NEW! 20010301 -sralston
385 * Check/log IOC log info
387 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
388 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
389 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
390 if ((int)ioc->chip_type <= (int)FC929)
391 mpt_fc_log_info(ioc, log_info);
393 mpt_sp_log_info(ioc, log_info);
395 if (ioc_stat & MPI_IOCSTATUS_MASK) {
396 if ((int)ioc->chip_type <= (int)FC929)
399 mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
403 * Process turbo (context) reply...
405 dirqprintk((MYIOC_s_INFO_FMT "Got TURBO reply(=%08x)\n", ioc->name, pa));
406 type = (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT);
407 if (type == MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET) {
408 cb_idx = mpt_stm_index;
410 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
411 } else if (type == MPI_CONTEXT_REPLY_TYPE_LAN) {
412 cb_idx = mpt_lan_index;
414 * BUG FIX! 20001218 -sralston
415 * Blind set of mf to NULL here was fatal
416 * after lan_reply says "freeme"
417 * Fix sort of combined with an optimization here;
418 * added explicit check for case where lan_reply
419 * was just returning 1 and doing nothing else.
420 * For this case skip the callback, but set up
421 * proper mf value first here:-)
423 if ((pa & 0x58000000) == 0x58000000) {
424 req_idx = pa & 0x0000FFFF;
425 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
428 * IMPORTANT! Invalidate the callback!
434 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
436 req_idx = pa & 0x0000FFFF;
437 cb_idx = (pa & 0x00FF0000) >> 16;
438 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
441 pa = 0; /* No reply flush! */
445 if ((int)ioc->chip_type > (int)FC929) {
446 /* Verify mf, mr are reasonable.
448 if ((mf) && ((mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))
449 || (mf < ioc->req_frames)) ) {
450 printk(MYIOC_s_WARN_FMT
451 "mpt_interrupt: Invalid mf (%p) req_idx (%d)!\n", ioc->name, (void *)mf, req_idx);
456 if ((pa) && (mr) && ((mr >= MPT_INDEX_2_RFPTR(ioc, ioc->req_depth))
457 || (mr < ioc->reply_frames)) ) {
458 printk(MYIOC_s_WARN_FMT
459 "mpt_interrupt: Invalid rf (%p)!\n", ioc->name, (void *)mr);
464 if (cb_idx > (MPT_MAX_PROTOCOL_DRIVERS-1)) {
465 printk(MYIOC_s_WARN_FMT
466 "mpt_interrupt: Invalid cb_idx (%d)!\n", ioc->name, cb_idx);
474 /* Check for (valid) IO callback! */
476 /* Do the callback! */
477 freeme = (*(MptCallbacks[cb_idx]))(ioc, mf, mr);
481 /* Flush (non-TURBO) reply with a WRITE! */
482 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
488 /* Put Request back on FreeQ! */
489 spin_lock_irqsave(&ioc->FreeQlock, flags);
490 Q_ADD_TAIL(&ioc->FreeQ, &mf->u.frame.linkage, MPT_FRAME_HDR);
494 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
498 } /* drain reply FIFO */
503 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
505 * mpt_base_reply - MPT base driver's callback routine; all base driver
506 * "internal" request/reply processing is routed here.
507 * Currently used for EventNotification and EventAck handling.
508 * @ioc: Pointer to MPT_ADAPTER structure
509 * @mf: Pointer to original MPT request frame
510 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
512 * Returns 1 indicating original alloc'd request frame ptr
513 * should be freed, or 0 if it shouldn't.
516 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
521 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name));
524 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
525 printk(MYIOC_s_ERR_FMT "NULL or BAD request frame ptr! (=%p)\n",
526 ioc->name, (void *)mf);
531 dprintk((MYIOC_s_ERR_FMT "Unexpected NULL Event (turbo?) reply!\n",
536 if (!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
537 dmfprintk((KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf));
538 DBG_DUMP_REQUEST_FRAME_HDR(mf)
541 func = reply->u.hdr.Function;
542 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n",
545 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
546 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
550 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
551 if (results != evHandlers) {
552 /* CHECKME! Any special handling needed here? */
553 dprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
554 ioc->name, evHandlers, results));
558 * Hmmm... It seems that EventNotificationReply is an exception
559 * to the rule of one reply per request.
561 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
564 #ifdef CONFIG_PROC_FS
565 // LogEvent(ioc, pEvReply);
568 } else if (func == MPI_FUNCTION_EVENT_ACK) {
569 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
571 } else if (func == MPI_FUNCTION_CONFIG ||
572 func == MPI_FUNCTION_TOOLBOX) {
576 dcprintk((MYIOC_s_INFO_FMT "config_complete (mf=%p,mr=%p)\n",
577 ioc->name, mf, reply));
579 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
582 /* disable timer and remove from linked list */
583 del_timer(&pCfg->timer);
585 spin_lock_irqsave(&ioc->FreeQlock, flags);
586 Q_DEL_ITEM(&pCfg->linkage);
587 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
590 * If IOC Status is SUCCESS, save the header
591 * and set the status code to GOOD.
593 pCfg->status = MPT_CONFIG_ERROR;
595 ConfigReply_t *pReply = (ConfigReply_t *)reply;
598 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
599 dcprintk((KERN_NOTICE " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
600 status, le32_to_cpu(pReply->IOCLogInfo)));
602 pCfg->status = status;
603 if (status == MPI_IOCSTATUS_SUCCESS) {
604 pCfg->hdr->PageVersion = pReply->Header.PageVersion;
605 pCfg->hdr->PageLength = pReply->Header.PageLength;
606 pCfg->hdr->PageNumber = pReply->Header.PageNumber;
607 pCfg->hdr->PageType = pReply->Header.PageType;
612 * Wake up the original calling thread
618 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
623 * Conditionally tell caller to free the original
624 * EventNotification/EventAck/unexpected request frame!
629 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
631 * mpt_register - Register protocol-specific main callback handler.
632 * @cbfunc: callback function pointer
633 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
635 * This routine is called by a protocol-specific driver (SCSI host,
636 * LAN, SCSI target) to register it's reply callback routine. Each
637 * protocol-specific driver must do this before it will be able to
638 * use any IOC resources, such as obtaining request frames.
640 * NOTES: The SCSI protocol driver currently calls this routine thrice
641 * in order to register separate callbacks; one for "normal" SCSI IO;
642 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
644 * Returns a positive integer valued "handle" in the
645 * range (and S.O.D. order) {N,...,7,6,5,...,1} if successful.
646 * Any non-positive return value (including zero!) should be considered
647 * an error by the caller.
650 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
658 * Handle possibility of the mptscsih_detect() routine getting
659 * called *before* fusion_init!
661 if (!FusionInitCalled) {
662 dprintk((KERN_INFO MYNAM ": Hmmm, calling fusion_init from mpt_register!\n"));
664 * NOTE! We'll get recursion here, as fusion_init()
665 * calls mpt_register()!
673 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
674 * (slot/handle 0 is reserved!)
676 for (i = MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
677 if (MptCallbacks[i] == NULL) {
678 MptCallbacks[i] = cbfunc;
679 MptDriverClass[i] = dclass;
680 MptEvHandlers[i] = NULL;
689 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
691 * mpt_deregister - Deregister a protocol drivers resources.
692 * @cb_idx: previously registered callback handle
694 * Each protocol-specific driver should call this routine when it's
695 * module is unloaded.
698 mpt_deregister(int cb_idx)
700 if ((cb_idx >= 0) && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
701 MptCallbacks[cb_idx] = NULL;
702 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
703 MptEvHandlers[cb_idx] = NULL;
706 if (isense_idx != -1 && isense_idx <= cb_idx)
711 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
713 * mpt_event_register - Register protocol-specific event callback
715 * @cb_idx: previously registered (via mpt_register) callback handle
716 * @ev_cbfunc: callback function
718 * This routine can be called by one or more protocol-specific drivers
719 * if/when they choose to be notified of MPT events.
721 * Returns 0 for success.
724 mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc)
726 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
729 MptEvHandlers[cb_idx] = ev_cbfunc;
733 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
735 * mpt_event_deregister - Deregister protocol-specific event callback
737 * @cb_idx: previously registered callback handle
739 * Each protocol-specific driver should call this routine
740 * when it does not (or can no longer) handle events,
741 * or when it's module is unloaded.
744 mpt_event_deregister(int cb_idx)
746 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
749 MptEvHandlers[cb_idx] = NULL;
752 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
754 * mpt_reset_register - Register protocol-specific IOC reset handler.
755 * @cb_idx: previously registered (via mpt_register) callback handle
756 * @reset_func: reset function
758 * This routine can be called by one or more protocol-specific drivers
759 * if/when they choose to be notified of IOC resets.
761 * Returns 0 for success.
764 mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func)
766 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
769 MptResetHandlers[cb_idx] = reset_func;
773 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
775 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
776 * @cb_idx: previously registered callback handle
778 * Each protocol-specific driver should call this routine
779 * when it does not (or can no longer) handle IOC reset handling,
780 * or when it's module is unloaded.
783 mpt_reset_deregister(int cb_idx)
785 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
788 MptResetHandlers[cb_idx] = NULL;
791 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
793 * mpt_device_driver_register - Register device driver hooks
796 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
801 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) {
806 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
808 /* call per pci device probe entry point */
809 for(ioc = mpt_adapter_find_first(); ioc != NULL;
810 ioc = mpt_adapter_find_next(ioc)) {
811 if(dd_cbfunc->probe) {
812 error = dd_cbfunc->probe(ioc->pcidev,
813 ioc->pcidev->driver->id_table);
822 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
824 * mpt_device_driver_deregister - DeRegister device driver hooks
827 mpt_device_driver_deregister(int cb_idx)
829 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
832 MptDeviceDriverHandlers[cb_idx] = NULL;
836 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
838 * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
839 * allocated per MPT adapter.
840 * @handle: Handle of registered MPT protocol driver
841 * @iocid: IOC unique identifier (integer)
843 * Returns pointer to a MPT request frame or %NULL if none are available
844 * or IOC is not active.
847 mpt_get_msg_frame(int handle, int iocid)
853 /* validate handle and ioc identifier */
854 iocp = mpt_adapters[iocid];
858 printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n");
861 /* If interrupts are not attached, do not return a request frame */
865 spin_lock_irqsave(&iocp->FreeQlock, flags);
866 if (! Q_IS_EMPTY(&iocp->FreeQ)) {
869 mf = iocp->FreeQ.head;
870 Q_DEL_ITEM(&mf->u.frame.linkage);
871 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
872 req_offset = (u8 *)mf - (u8 *)iocp->req_frames;
874 mf->u.frame.hwhdr.msgctxu.fld.req_idx =
875 cpu_to_le16(req_offset / iocp->req_sz);
876 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
883 spin_unlock_irqrestore(&iocp->FreeQlock, flags);
887 printk(KERN_WARNING "IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", iocp->mfcnt, iocp->req_depth);
889 if (mfcounter == PRINT_MF_COUNT)
890 printk(KERN_INFO "MF Count 0x%x Max 0x%x \n", iocp->mfcnt, iocp->req_depth);
893 dmfprintk((KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",
894 iocp->name, handle, iocid, mf));
898 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
900 * mpt_put_msg_frame - Send a protocol specific MPT request frame
902 * @handle: Handle of registered MPT protocol driver
903 * @iocid: IOC unique identifier (integer)
904 * @mf: Pointer to MPT request frame
906 * This routine posts a MPT request frame to the request post FIFO of a
907 * specific MPT adapter.
910 mpt_put_msg_frame(int handle, int iocid, MPT_FRAME_HDR *mf)
914 iocp = mpt_adapters[iocid];
919 /* ensure values are reset properly! */
920 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
921 req_offset = (u8 *)mf - (u8 *)iocp->req_frames;
923 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_offset / iocp->req_sz);
924 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
926 #ifdef MPT_DEBUG_MSG_FRAME
928 u32 *m = mf->u.frame.hwhdr.__hdr;
931 printk(KERN_INFO MYNAM ": %s: About to Put msg frame @ %p:\n" KERN_INFO " ",
933 n = iocp->req_sz/4 - 1;
936 for (ii=0; ii<=n; ii++) {
937 if (ii && ((ii%8)==0))
938 printk("\n" KERN_INFO " ");
939 printk(" %08x", le32_to_cpu(m[ii]));
945 mf_dma_addr = iocp->req_frames_low_dma + req_offset;
946 CHIPREG_WRITE32(&iocp->chip->RequestFifo, mf_dma_addr);
949 "mpt_put_msg_frame: Invalid iocid=%d\n", iocid);
954 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
956 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
957 * @handle: Handle of registered MPT protocol driver
958 * @iocid: IOC unique identifier (integer)
959 * @mf: Pointer to MPT request frame
961 * This routine places a MPT request frame back on the MPT adapter's
965 mpt_free_msg_frame(int handle, int iocid, MPT_FRAME_HDR *mf)
970 iocp = mpt_adapters[iocid];
972 /* Put Request back on FreeQ! */
973 spin_lock_irqsave(&iocp->FreeQlock, flags);
974 Q_ADD_TAIL(&iocp->FreeQ, &mf->u.frame.linkage, MPT_FRAME_HDR);
978 spin_unlock_irqrestore(&iocp->FreeQlock, flags);
982 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
984 * mpt_add_sge - Place a simple SGE at address pAddr.
985 * @pAddr: virtual address for SGE
986 * @flagslength: SGE flags and data transfer length
987 * @dma_addr: Physical address
989 * This routine places a MPT request frame back on the MPT adapter's
993 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
995 if (sizeof(dma_addr_t) == sizeof(u64)) {
996 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
997 u32 tmp = dma_addr & 0xFFFFFFFF;
999 pSge->FlagsLength = cpu_to_le32(flagslength);
1000 pSge->Address.Low = cpu_to_le32(tmp);
1001 tmp = (u32) ((u64)dma_addr >> 32);
1002 pSge->Address.High = cpu_to_le32(tmp);
1005 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
1006 pSge->FlagsLength = cpu_to_le32(flagslength);
1007 pSge->Address = cpu_to_le32(dma_addr);
1011 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1013 * mpt_add_chain - Place a chain SGE at address pAddr.
1014 * @pAddr: virtual address for SGE
1015 * @next: nextChainOffset value (u32's)
1016 * @length: length of next SGL segment
1017 * @dma_addr: Physical address
1019 * This routine places a MPT request frame back on the MPT adapter's
1023 mpt_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1025 if (sizeof(dma_addr_t) == sizeof(u64)) {
1026 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
1027 u32 tmp = dma_addr & 0xFFFFFFFF;
1029 pChain->Length = cpu_to_le16(length);
1030 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
1032 pChain->NextChainOffset = next;
1034 pChain->Address.Low = cpu_to_le32(tmp);
1035 tmp = (u32) ((u64)dma_addr >> 32);
1036 pChain->Address.High = cpu_to_le32(tmp);
1038 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
1039 pChain->Length = cpu_to_le16(length);
1040 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
1041 pChain->NextChainOffset = next;
1042 pChain->Address = cpu_to_le32(dma_addr);
1046 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1048 * mpt_send_handshake_request - Send MPT request via doorbell
1050 * @handle: Handle of registered MPT protocol driver
1051 * @iocid: IOC unique identifier (integer)
1052 * @reqBytes: Size of the request in bytes
1053 * @req: Pointer to MPT request frame
1054 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1056 * This routine is used exclusively to send MptScsiTaskMgmt
1057 * requests since they are required to be sent via doorbell handshake.
1059 * NOTE: It is the callers responsibility to byte-swap fields in the
1060 * request which are greater than 1 byte in size.
1062 * Returns 0 for success, non-zero for failure.
1065 mpt_send_handshake_request(int handle, int iocid, int reqBytes, u32 *req, int sleepFlag)
1070 iocp = mpt_adapters[iocid];
1075 /* State is known to be good upon entering
1076 * this function so issue the bus reset
1081 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1082 * setting cb_idx/req_idx. But ONLY if this request
1083 * is in proper (pre-alloc'd) request buffer range...
1085 ii = MFPTR_2_MPT_INDEX(iocp,(MPT_FRAME_HDR*)req);
1086 if (reqBytes >= 12 && ii >= 0 && ii < iocp->req_depth) {
1087 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
1088 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
1089 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
1092 /* Make sure there are no doorbells */
1093 CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
1095 CHIPREG_WRITE32(&iocp->chip->Doorbell,
1096 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1097 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1099 /* Wait for IOC doorbell int */
1100 if ((ii = WaitForDoorbellInt(iocp, 5, sleepFlag)) < 0) {
1104 /* Read doorbell and check for active bit */
1105 if (!(CHIPREG_READ32(&iocp->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1108 dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
1111 CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
1113 if ((r = WaitForDoorbellAck(iocp, 5, sleepFlag)) < 0) {
1117 /* Send request via doorbell handshake */
1118 req_as_bytes = (u8 *) req;
1119 for (ii = 0; ii < reqBytes/4; ii++) {
1122 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1123 (req_as_bytes[(ii*4) + 1] << 8) |
1124 (req_as_bytes[(ii*4) + 2] << 16) |
1125 (req_as_bytes[(ii*4) + 3] << 24));
1126 CHIPREG_WRITE32(&iocp->chip->Doorbell, word);
1127 if ((r = WaitForDoorbellAck(iocp, 5, sleepFlag)) < 0) {
1133 if (r >= 0 && WaitForDoorbellInt(iocp, 10, sleepFlag) >= 0)
1138 /* Make sure there are no doorbells */
1139 CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
1145 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1147 * mpt_adapter_find_first - Find first MPT adapter pointer.
1149 * Returns first MPT adapter pointer or %NULL if no MPT adapters
1153 mpt_adapter_find_first(void)
1157 if (! Q_IS_EMPTY(&MptAdapters))
1158 this = MptAdapters.head;
1165 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1167 * mpt_adapter_find_next - Find next MPT adapter pointer.
1168 * @prev: Pointer to previous MPT adapter
1170 * Returns next MPT adapter pointer or %NULL if there are no more.
1173 mpt_adapter_find_next(MPT_ADAPTER *prev)
1177 if (prev && (prev->forw != (MPT_ADAPTER*)&MptAdapters.head))
1186 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1188 * mpt_verify_adapter - Given a unique IOC identifier, set pointer to
1189 * the associated MPT adapter structure.
1190 * @iocid: IOC unique identifier (integer)
1191 * @iocpp: Pointer to pointer to IOC adapter
1193 * Returns iocid and sets iocpp.
1196 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1201 if (iocid >= MPT_MAX_ADAPTERS)
1204 p = mpt_adapters[iocid];
1212 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1214 * mptbase_probe - Install a PCI intelligent MPT adapter.
1215 * @pdev: Pointer to pci_dev structure
1217 * This routine performs all the steps necessary to bring the IOC of
1218 * a MPT adapter to a OPERATIONAL state. This includes registering
1219 * memory regions, registering the interrupt, and allocating request
1220 * and reply memory pools.
1222 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1225 * Returns 0 for success, non-zero for failure.
1227 * TODO: Add support for polled controllers
1229 static int __devinit
1230 mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1234 unsigned long mem_phys;
1240 u64 mask = 0xffffffffffffffffULL;
1244 if (pci_enable_device(pdev))
1247 if (!pci_set_dma_mask(pdev, mask)) {
1248 dprintk((KERN_INFO MYNAM
1249 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1250 } else if (pci_set_dma_mask(pdev, (u64) 0xffffffff)) {
1251 printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1255 if (!pci_set_consistent_dma_mask(pdev, mask))
1256 dprintk((KERN_INFO MYNAM
1257 ": Using 64 bit consistent mask\n"));
1259 dprintk((KERN_INFO MYNAM
1260 ": Not using 64 bit consistent mask\n"));
1262 ioc = kmalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1264 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1267 memset(ioc, 0, sizeof(MPT_ADAPTER));
1268 ioc->alloc_total = sizeof(MPT_ADAPTER);
1269 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1270 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1274 ioc->diagPending = 0;
1275 spin_lock_init(&ioc->diagLock);
1277 /* Initialize the event logging.
1279 ioc->eventTypes = 0; /* None */
1280 ioc->eventContext = 0;
1281 ioc->eventLogSize = 0;
1288 ioc->cached_fw = NULL;
1290 /* Initilize SCSI Config Data structure
1292 memset(&ioc->spi_data, 0, sizeof(ScsiCfgData));
1294 /* Initialize the running configQ head.
1296 Q_INIT(&ioc->configQ, Q_ITEM);
1298 /* Find lookup slot. */
1299 for (ii=0; ii < MPT_MAX_ADAPTERS; ii++) {
1300 if (mpt_adapters[ii] == NULL) {
1301 ioc->id = ii; /* Assign adapter unique id (lookup) */
1305 if (ii == MPT_MAX_ADAPTERS) {
1306 printk(KERN_ERR MYNAM ": ERROR - mpt_adapters[%d] table overflow!\n", ii);
1311 mem_phys = msize = 0;
1313 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1314 if (pdev->PCI_BASEADDR_FLAGS(ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1315 /* Get I/O space! */
1316 port = pdev->PCI_BASEADDR_START(ii);
1317 psize = PCI_BASEADDR_SIZE(pdev,ii);
1320 mem_phys = pdev->PCI_BASEADDR_START(ii);
1321 msize = PCI_BASEADDR_SIZE(pdev,ii);
1325 ioc->mem_size = msize;
1327 if (ii == DEVICE_COUNT_RESOURCE) {
1328 printk(KERN_ERR MYNAM ": ERROR - MPT adapter has no memory regions defined!\n");
1333 dprintk((KERN_INFO MYNAM ": MPT adapter @ %lx, msize=%dd bytes\n", mem_phys, msize));
1334 dprintk((KERN_INFO MYNAM ": (port i/o @ %lx, psize=%dd bytes)\n", port, psize));
1337 /* Get logical ptr for PciMem0 space */
1338 /*mem = ioremap(mem_phys, msize);*/
1339 mem = ioremap(mem_phys, 0x100);
1341 printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1346 dprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1348 dprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1349 &ioc->facts, &ioc->pfacts[0]));
1351 ioc->mem_phys = mem_phys;
1352 ioc->chip = (SYSIF_REGS*)mem;
1354 /* Save Port IO values incase we need to do downloadboot */
1356 u8 *pmem = (u8*)port;
1357 ioc->pio_mem_phys = port;
1358 ioc->pio_chip = (SYSIF_REGS*)pmem;
1361 ioc->chip_type = FCUNK;
1362 if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC909) {
1363 ioc->chip_type = FC909;
1364 ioc->prod_name = "LSIFC909";
1366 if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
1367 ioc->chip_type = FC929;
1368 ioc->prod_name = "LSIFC929";
1370 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) {
1371 ioc->chip_type = FC919;
1372 ioc->prod_name = "LSIFC919";
1374 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) {
1375 ioc->chip_type = FC929X;
1376 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1377 if (revision < XL_929) {
1378 ioc->prod_name = "LSIFC929X";
1379 /* 929X Chip Fix. Set Split transactions level
1380 * for PCIX. Set MOST bits to zero.
1382 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1384 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1386 ioc->prod_name = "LSIFC929XL";
1387 /* 929XL Chip Fix. Set MMRBC to 0x08.
1389 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1391 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1394 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) {
1395 ioc->chip_type = FC919X;
1396 ioc->prod_name = "LSIFC919X";
1397 /* 919X Chip Fix. Set Split transactions level
1398 * for PCIX. Set MOST bits to zero.
1400 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1402 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1404 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
1405 ioc->chip_type = C1030;
1406 ioc->prod_name = "LSI53C1030";
1407 /* 1030 Chip Fix. Disable Split transactions
1408 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1410 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1411 if (revision < C0_1030) {
1412 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1414 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1417 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
1418 ioc->chip_type = C1035;
1419 ioc->prod_name = "LSI53C1035";
1422 sprintf(ioc->name, "ioc%d", ioc->id);
1424 Q_INIT(&ioc->FreeQ, MPT_FRAME_HDR);
1425 spin_lock_init(&ioc->FreeQlock);
1428 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1430 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1432 /* tack onto tail of our MPT adapter list */
1433 Q_ADD_TAIL(&MptAdapters, ioc, MPT_ADAPTER);
1435 /* Set lookup ptr. */
1436 mpt_adapters[ioc->id] = ioc;
1440 r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc);
1444 printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %d!\n",
1445 ioc->name, pdev->irq);
1447 printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %s!\n",
1448 ioc->name, __irq_itoa(pdev->irq));
1451 mpt_adapters[ioc->id] = NULL;
1457 ioc->pci_irq = pdev->irq;
1459 pci_set_master(pdev); /* ?? */
1460 pci_set_drvdata(pdev, ioc);
1463 dprintk((KERN_INFO MYNAM ": %s installed at interrupt %d\n", ioc->name, pdev->irq));
1465 dprintk((KERN_INFO MYNAM ": %s installed at interrupt %s\n", ioc->name, __irq_itoa(pdev->irq)));
1469 /* NEW! 20010220 -sralston
1470 * Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1472 if ((ioc->chip_type == FC929) || (ioc->chip_type == C1030)
1473 || (ioc->chip_type == C1035) || (ioc->chip_type == FC929X))
1474 mpt_detect_bound_ports(ioc, pdev);
1476 if ((r = mpt_do_ioc_recovery(ioc,
1477 MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0) {
1478 printk(KERN_WARNING MYNAM
1479 ": WARNING - %s did not initialize properly! (%d)\n",
1483 mpt_adapters[ioc->id] = NULL;
1484 free_irq(ioc->pci_irq, ioc);
1487 pci_set_drvdata(pdev, NULL);
1491 /* call per device driver probe entry point */
1492 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1493 if(MptDeviceDriverHandlers[ii] &&
1494 MptDeviceDriverHandlers[ii]->probe) {
1495 MptDeviceDriverHandlers[ii]->probe(pdev,id);
1502 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1504 * mptbase_remove - Remove a PCI intelligent MPT adapter.
1505 * @pdev: Pointer to pci_dev structure
1509 static void __devexit
1510 mptbase_remove(struct pci_dev *pdev)
1512 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1515 /* call per device driver remove entry point */
1516 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1517 if(MptDeviceDriverHandlers[ii] &&
1518 MptDeviceDriverHandlers[ii]->remove) {
1519 MptDeviceDriverHandlers[ii]->remove(pdev);
1523 /* Disable interrupts! */
1524 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1527 mpt_sync_irq(pdev->irq);
1529 /* Clear any lingering interrupt */
1530 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1532 CHIPREG_READ32(&ioc->chip->IntStatus);
1535 mpt_adapter_dispose(ioc);
1537 pci_set_drvdata(pdev, NULL);
1540 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1542 * mptbase_shutdown -
1546 mptbase_shutdown(struct device * dev)
1550 /* call per device driver shutdown entry point */
1551 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1552 if(MptDeviceDriverHandlers[ii] &&
1553 MptDeviceDriverHandlers[ii]->shutdown) {
1554 MptDeviceDriverHandlers[ii]->shutdown(dev);
1561 /**************************************************************************
1565 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1567 * mptbase_suspend - Fusion MPT base driver suspend routine.
1572 mptbase_suspend(struct pci_dev *pdev, u32 state)
1575 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1581 device_state=1; /* D1 */;
1585 device_state=3; /* D3 */;
1588 return -EAGAIN /*FIXME*/;
1592 printk(MYIOC_s_INFO_FMT
1593 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1594 ioc->name, pdev, pci_name(pdev), device_state);
1596 /* call per device driver suspend entry point */
1597 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1598 if(MptDeviceDriverHandlers[ii] &&
1599 MptDeviceDriverHandlers[ii]->suspend) {
1600 MptDeviceDriverHandlers[ii]->suspend(pdev, state);
1604 pci_save_state(pdev, ioc->PciState);
1606 /* put ioc into READY_STATE */
1607 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1608 printk(MYIOC_s_ERR_FMT
1609 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1612 /* disable interrupts */
1613 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1616 /* Clear any lingering interrupt */
1617 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1619 pci_disable_device(pdev);
1620 pci_set_power_state(pdev, device_state);
1625 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1627 * mptbase_resume - Fusion MPT base driver resume routine.
1632 mptbase_resume(struct pci_dev *pdev)
1634 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1635 u32 device_state = pdev->current_state;
1639 printk(MYIOC_s_INFO_FMT
1640 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1641 ioc->name, pdev, pci_name(pdev), device_state);
1643 pci_set_power_state(pdev, 0);
1644 pci_restore_state(pdev, ioc->PciState);
1645 pci_enable_device(pdev);
1647 /* enable interrupts */
1648 CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
1651 /* F/W not running */
1652 if(!CHIPREG_READ32(&ioc->chip->Doorbell)) {
1653 /* enable domain validation flags */
1654 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
1655 ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_NEED_DV;
1659 printk(MYIOC_s_INFO_FMT
1660 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1662 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1663 CHIPREG_READ32(&ioc->chip->Doorbell));
1665 /* bring ioc to operational state */
1666 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1667 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1668 printk(MYIOC_s_INFO_FMT
1669 "pci-resume: Cannot recover, error:[%x]\n",
1670 ioc->name, recovery_state);
1672 printk(MYIOC_s_INFO_FMT
1673 "pci-resume: success\n", ioc->name);
1676 /* call per device driver resume entry point */
1677 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1678 if(MptDeviceDriverHandlers[ii] &&
1679 MptDeviceDriverHandlers[ii]->resume) {
1680 MptDeviceDriverHandlers[ii]->resume(pdev);
1688 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1690 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1691 * @ioc: Pointer to MPT adapter structure
1692 * @reason: Event word / reason
1693 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1695 * This routine performs all the steps necessary to bring the IOC
1696 * to a OPERATIONAL state.
1698 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1703 * -1 if failed to get board READY
1704 * -2 if READY but IOCFacts Failed
1705 * -3 if READY but PrimeIOCFifos Failed
1706 * -4 if READY but IOCInit Failed
1709 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1711 int hard_reset_done = 0;
1712 int alt_ioc_ready = 0;
1718 int reset_alt_ioc_active = 0;
1720 printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1721 ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1723 /* Disable reply interrupts (also blocks FreeQ) */
1724 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1728 if (ioc->alt_ioc->active)
1729 reset_alt_ioc_active = 1;
1731 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1732 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1733 ioc->alt_ioc->active = 0;
1737 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1740 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1741 if (hard_reset_done == -4) {
1742 printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1745 if (reset_alt_ioc_active && ioc->alt_ioc) {
1746 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1747 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1748 ioc->alt_ioc->name));
1749 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
1750 ioc->alt_ioc->active = 1;
1754 printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1760 /* hard_reset_done = 0 if a soft reset was performed
1761 * and 1 if a hard reset was performed.
1763 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1764 if ((r = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1767 printk(KERN_WARNING MYNAM
1768 ": alt-%s: (%d) Not ready WARNING!\n",
1769 ioc->alt_ioc->name, r);
1772 /* Get IOC facts! Allow 1 retry */
1773 if ((r = GetIocFacts(ioc, sleepFlag, reason)) != 0)
1774 r = GetIocFacts(ioc, sleepFlag, reason);
1778 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1779 MptDisplayIocCapabilities(ioc);
1782 if (alt_ioc_ready) {
1783 if ((r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1784 /* Retry - alt IOC was initialized once
1786 r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1790 reset_alt_ioc_active = 0;
1791 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1792 MptDisplayIocCapabilities(ioc->alt_ioc);
1796 /* Prime reply & request queues!
1797 * (mucho alloc's) Must be done prior to
1798 * init as upper addresses are needed for init.
1799 * If fails, continue with alt-ioc processing
1801 if ((ret == 0) && ((r = PrimeIocFifos(ioc)) != 0))
1804 /* May need to check/upload firmware & data here!
1805 * If fails, continue with alt-ioc processing
1807 if ((ret == 0) && ((r = SendIocInit(ioc, sleepFlag)) != 0))
1810 if (alt_ioc_ready && ((r = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
1811 printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1812 ioc->alt_ioc->name, r);
1814 reset_alt_ioc_active = 0;
1817 if (alt_ioc_ready) {
1818 if ((r = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
1820 reset_alt_ioc_active = 0;
1821 printk(KERN_WARNING MYNAM
1822 ": alt-%s: (%d) init failure WARNING!\n",
1823 ioc->alt_ioc->name, r);
1827 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
1828 if (ioc->upload_fw) {
1829 ddlprintk((MYIOC_s_INFO_FMT
1830 "firmware upload required!\n", ioc->name));
1832 /* Controller is not operational, cannot do upload
1835 r = mpt_do_upload(ioc, sleepFlag);
1837 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
1840 /* Handle the alt IOC too */
1841 if ((alt_ioc_ready) && (ioc->alt_ioc->upload_fw)){
1842 ddlprintk((MYIOC_s_INFO_FMT
1843 "Alt-ioc firmware upload required!\n",
1845 r = mpt_do_upload(ioc->alt_ioc, sleepFlag);
1847 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
1853 /* Enable! (reply interrupt) */
1854 CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
1858 if (reset_alt_ioc_active && ioc->alt_ioc) {
1859 /* (re)Enable alt-IOC! (reply interrupt) */
1860 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1861 ioc->alt_ioc->name));
1862 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
1863 ioc->alt_ioc->active = 1;
1866 /* NEW! 20010120 -sralston
1867 * Enable MPT base driver management of EventNotification
1868 * and EventAck handling.
1870 if ((ret == 0) && (!ioc->facts.EventState))
1871 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
1873 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
1874 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
1876 /* (Bugzilla:fibrebugs, #513)
1877 * Bug fix (part 2)! 20010905 -sralston
1878 * Add additional "reason" check before call to GetLanConfigPages
1879 * (combined with GetIoUnitPage2 call). This prevents a somewhat
1880 * recursive scenario; GetLanConfigPages times out, timer expired
1881 * routine calls HardResetHandler, which calls into here again,
1882 * and we try GetLanConfigPages again...
1884 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1885 if ((int)ioc->chip_type <= (int)FC929) {
1887 * Pre-fetch FC port WWN and stuff...
1888 * (FCPortPage0_t stuff)
1890 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1891 (void) GetFcPortPage0(ioc, ii);
1894 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
1895 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
1897 * Pre-fetch the ports LAN MAC address!
1898 * (LANPage1_t stuff)
1900 (void) GetLanConfigPages(ioc);
1903 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
1904 dprintk((MYIOC_s_INFO_FMT "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
1905 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0] ));
1910 /* Get NVRAM and adapter maximums from SPP 0 and 2
1912 mpt_GetScsiPortSettings(ioc, 0);
1914 /* Get version and length of SDP 1
1916 mpt_readScsiDevicePageHeaders(ioc, 0);
1920 if (ioc->facts.MsgVersion >= 0x0102)
1921 mpt_findImVolumes(ioc);
1923 /* Check, and possibly reset, the coalescing value
1925 mpt_read_ioc_pg_1(ioc);
1927 mpt_read_ioc_pg_4(ioc);
1930 GetIoUnitPage2(ioc);
1934 * Call each currently registered protocol IOC reset handler
1935 * with post-reset indication.
1936 * NOTE: If we're doing _IOC_BRINGUP, there can be no
1937 * MptResetHandlers[] registered yet.
1939 if (hard_reset_done) {
1941 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
1942 if ((ret == 0) && MptResetHandlers[ii]) {
1943 dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
1945 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET);
1949 if (alt_ioc_ready && MptResetHandlers[ii]) {
1950 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
1951 ioc->name, ioc->alt_ioc->name, ii));
1952 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
1956 /* FIXME? Examine results here? */
1962 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1964 * mpt_detect_bound_ports - Search for PCI bus/dev_function
1965 * which matches PCI bus/dev_function (+/-1) for newly discovered 929,
1966 * 929X, 1030 or 1035.
1967 * @ioc: Pointer to MPT adapter structure
1968 * @pdev: Pointer to (struct pci_dev) structure
1970 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
1971 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
1974 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
1976 MPT_ADAPTER *ioc_srch = mpt_adapter_find_first();
1977 unsigned int match_lo, match_hi;
1979 match_lo = pdev->devfn-1;
1980 match_hi = pdev->devfn+1;
1981 dprintk((MYIOC_s_INFO_FMT "PCI bus/devfn=%x/%x, searching for devfn match on %x or %x\n",
1982 ioc->name, pdev->bus->number, pdev->devfn, match_lo, match_hi));
1984 while (ioc_srch != NULL) {
1985 struct pci_dev *_pcidev = ioc_srch->pcidev;
1987 if ((_pcidev->device == pdev->device) &&
1988 (_pcidev->bus->number == pdev->bus->number) &&
1989 (_pcidev->devfn == match_lo || _pcidev->devfn == match_hi) ) {
1990 /* Paranoia checks */
1991 if (ioc->alt_ioc != NULL) {
1992 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1993 ioc->name, ioc->alt_ioc->name);
1995 } else if (ioc_srch->alt_ioc != NULL) {
1996 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1997 ioc_srch->name, ioc_srch->alt_ioc->name);
2000 dprintk((KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
2001 ioc->name, ioc_srch->name));
2002 ioc_srch->alt_ioc = ioc;
2003 ioc->alt_ioc = ioc_srch;
2006 ioc_srch = mpt_adapter_find_next(ioc_srch);
2010 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2012 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2013 * @this: Pointer to MPT adapter structure
2014 * @free: Free up alloc'd reply, request, etc.
2017 mpt_adapter_disable(MPT_ADAPTER *this, int freeup)
2024 /* Disable the FW */
2025 state = mpt_GetIocState(this, 1);
2026 if (state == MPI_IOC_STATE_OPERATIONAL) {
2027 SendIocReset(this, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, NO_SLEEP);
2030 if (this->cached_fw != NULL) {
2031 ddlprintk((KERN_INFO MYNAM ": Pushing FW onto adapter\n"));
2033 if ((ret = mpt_downloadboot(this, NO_SLEEP)) < 0) {
2034 printk(KERN_WARNING MYNAM
2035 ": firmware downloadboot failure (%d)!\n", ret);
2039 /* Disable adapter interrupts! */
2040 CHIPREG_WRITE32(&this->chip->IntMask, 0xFFFFFFFF);
2042 /* Clear any lingering interrupt */
2043 CHIPREG_WRITE32(&this->chip->IntStatus, 0);
2045 if (freeup && this->fifo_pool != NULL) {
2046 pci_free_consistent(this->pcidev,
2048 this->fifo_pool, this->fifo_pool_dma);
2049 this->reply_frames = NULL;
2050 this->reply_alloc = NULL;
2051 this->req_frames = NULL;
2052 this->req_alloc = NULL;
2053 this->chain_alloc = NULL;
2054 this->fifo_pool = NULL;
2055 this->alloc_total -= this->fifo_pool_sz;
2057 if (freeup && this->sense_buf_pool != NULL) {
2058 sz = (this->req_depth * MPT_SENSE_BUFFER_ALLOC);
2059 pci_free_consistent(this->pcidev, sz,
2060 this->sense_buf_pool, this->sense_buf_pool_dma);
2061 this->sense_buf_pool = NULL;
2062 this->alloc_total -= sz;
2065 if (freeup && this->events != NULL){
2066 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2067 kfree(this->events);
2068 this->events = NULL;
2069 this->alloc_total -= sz;
2072 if (freeup && this->cached_fw != NULL) {
2075 while ((ii < this->num_fw_frags) && (this->cached_fw[ii]!= NULL)) {
2076 sz = this->cached_fw[ii]->size;
2077 pci_free_consistent(this->pcidev, sz,
2078 this->cached_fw[ii]->fw, this->cached_fw[ii]->fw_dma);
2079 this->cached_fw[ii]->fw = NULL;
2080 this->alloc_total -= sz;
2082 kfree(this->cached_fw[ii]);
2083 this->cached_fw[ii] = NULL;
2084 this->alloc_total -= sizeof(fw_image_t);
2089 kfree(this->cached_fw);
2090 this->cached_fw = NULL;
2091 sz = this->num_fw_frags * sizeof(void *);
2092 this->alloc_total -= sz;
2095 if (freeup && this->spi_data.nvram != NULL) {
2096 kfree(this->spi_data.nvram);
2097 this->spi_data.nvram = NULL;
2100 if (freeup && this->spi_data.pIocPg3 != NULL) {
2101 kfree(this->spi_data.pIocPg3);
2102 this->spi_data.pIocPg3 = NULL;
2105 if (freeup && this->spi_data.pIocPg4 != NULL) {
2106 sz = this->spi_data.IocPg4Sz;
2107 pci_free_consistent(this->pcidev, sz,
2108 this->spi_data.pIocPg4,
2109 this->spi_data.IocPg4_dma);
2110 this->spi_data.pIocPg4 = NULL;
2111 this->alloc_total -= sz;
2116 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2118 * mpt_adapter_dispose - Free all resources associated with a MPT
2120 * @this: Pointer to MPT adapter structure
2122 * This routine unregisters h/w resources and frees all alloc'd memory
2123 * associated with a MPT adapter structure.
2126 mpt_adapter_dispose(MPT_ADAPTER *this)
2129 int sz_first, sz_last;
2131 sz_first = this->alloc_total;
2133 if (this->alt_ioc != NULL) {
2134 this->alt_ioc->alt_ioc = NULL;
2135 this->alt_ioc = NULL;
2138 mpt_adapter_disable(this, 1);
2140 if (this->pci_irq != -1) {
2141 free_irq(this->pci_irq, this);
2145 if (this->memmap != NULL)
2146 iounmap((u8 *) this->memmap);
2148 #if defined(CONFIG_MTRR) && 0
2149 if (this->mtrr_reg > 0) {
2150 mtrr_del(this->mtrr_reg, 0, 0);
2151 dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", this->name));
2155 /* Zap the adapter lookup ptr! */
2156 mpt_adapters[this->id] = NULL;
2158 sz_last = this->alloc_total;
2159 dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
2160 this->name, sz_first-sz_last+(int)sizeof(*this), sz_first));
2165 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2167 * MptDisplayIocCapabilities - Disply IOC's capacilities.
2168 * @ioc: Pointer to MPT adapter structure
2171 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2175 printk(KERN_INFO "%s: ", ioc->name);
2176 if (ioc->prod_name && strlen(ioc->prod_name) > 3)
2177 printk("%s: ", ioc->prod_name+3);
2178 printk("Capabilities={");
2180 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2181 printk("Initiator");
2185 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2186 printk("%sTarget", i ? "," : "");
2190 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2191 printk("%sLAN", i ? "," : "");
2197 * This would probably evoke more questions than it's worth
2199 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2200 printk("%sLogBusAddr", i ? "," : "");
2208 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2210 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2211 * @ioc: Pointer to MPT_ADAPTER structure
2212 * @force: Force hard KickStart of IOC
2213 * @sleepFlag: Specifies whether the process can sleep
2216 * 1 - DIAG reset and READY
2217 * 0 - READY initially OR soft reset and READY
2218 * -1 - Any failure on KickStart
2219 * -2 - Msg Unit Reset Failed
2220 * -3 - IO Unit Reset Failed
2221 * -4 - IOC owned by a PEER
2224 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2229 int hard_reset_done = 0;
2234 /* Get current [raw] IOC state */
2235 ioc_state = mpt_GetIocState(ioc, 0);
2236 dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
2239 * Check to see if IOC got left/stuck in doorbell handshake
2240 * grip of death. If so, hard reset the IOC.
2242 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2244 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2248 /* Is it already READY? */
2249 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY) {
2250 if ((int)ioc->chip_type <= (int)FC929)
2253 /* Workaround from broken 1030 FW.
2254 * Force a diagnostic reset if fails.
2256 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2264 * Check to see if IOC is in FAULT state.
2266 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2268 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2270 printk(KERN_WARNING " FAULT code = %04xh\n",
2271 ioc_state & MPI_DOORBELL_DATA_MASK);
2275 * Hmmm... Did it get left operational?
2277 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2278 dprintk((MYIOC_s_WARN_FMT "IOC operational unexpected\n",
2282 * If PCI Peer, exit.
2283 * Else, if no fault conditions are present, issue a MessageUnitReset
2284 * Else, fall through to KickStart case
2286 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2287 dprintk((KERN_WARNING MYNAM
2288 ": whoinit 0x%x\n statefault %d force %d\n",
2289 whoinit, statefault, force));
2290 if (whoinit == MPI_WHOINIT_PCI_PEER)
2293 if ((statefault == 0 ) && (force == 0)) {
2294 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2301 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2302 if (hard_reset_done < 0)
2306 * Loop here waiting for IOC to come READY.
2309 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
2311 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2312 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2314 * BIOS or previous driver load left IOC in OP state.
2315 * Reset messaging FIFOs.
2317 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2318 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2321 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2323 * Something is wrong. Try to get IOC back
2326 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2327 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2334 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2335 ioc->name, (ii+5)/HZ);
2339 if (sleepFlag == CAN_SLEEP) {
2340 set_current_state(TASK_INTERRUPTIBLE);
2341 schedule_timeout(1);
2343 mdelay (1); /* 1 msec delay */
2348 if (statefault < 3) {
2349 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2351 statefault==1 ? "stuck handshake" : "IOC FAULT");
2354 return hard_reset_done;
2357 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2359 * mpt_GetIocState - Get the current state of a MPT adapter.
2360 * @ioc: Pointer to MPT_ADAPTER structure
2361 * @cooked: Request raw or cooked IOC state
2363 * Returns all IOC Doorbell register bits if cooked==0, else just the
2364 * Doorbell bits in MPI_IOC_STATE_MASK.
2367 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2372 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2373 // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2374 sc = s & MPI_IOC_STATE_MASK;
2377 ioc->last_state = sc;
2379 return cooked ? sc : s;
2382 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2384 * GetIocFacts - Send IOCFacts request to MPT adapter.
2385 * @ioc: Pointer to MPT_ADAPTER structure
2386 * @sleepFlag: Specifies whether the process can sleep
2387 * @reason: If recovery, only update facts.
2389 * Returns 0 for success, non-zero for failure.
2392 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2394 IOCFacts_t get_facts;
2395 IOCFactsReply_t *facts;
2401 /* IOC *must* NOT be in RESET state! */
2402 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2403 printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2409 facts = &ioc->facts;
2411 /* Destination (reply area)... */
2412 reply_sz = sizeof(*facts);
2413 memset(facts, 0, reply_sz);
2415 /* Request area (get_facts on the stack right now!) */
2416 req_sz = sizeof(get_facts);
2417 memset(&get_facts, 0, req_sz);
2419 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2420 /* Assert: All other get_facts fields are zero! */
2422 dprintk((MYIOC_s_INFO_FMT "Sending get IocFacts request\n", ioc->name));
2424 /* No non-zero fields in the get_facts request are greater than
2425 * 1 byte in size, so we can just fire it off as is.
2427 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2428 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2433 * Now byte swap (GRRR) the necessary fields before any further
2434 * inspection of reply contents.
2436 * But need to do some sanity checks on MsgLength (byte) field
2437 * to make sure we don't zero IOC's req_sz!
2439 /* Did we get a valid reply? */
2440 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2441 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2443 * If not been here, done that, save off first WhoInit value
2445 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2446 ioc->FirstWhoInit = facts->WhoInit;
2449 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2450 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2451 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2452 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2453 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2454 status = facts->IOCStatus & MPI_IOCSTATUS_MASK;
2455 /* CHECKME! IOCStatus, IOCLogInfo */
2457 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2458 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2461 * FC f/w version changed between 1.1 and 1.2
2462 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2463 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2465 if (facts->MsgVersion < 0x0102) {
2467 * Handle old FC f/w style, convert to new...
2469 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2470 facts->FWVersion.Word =
2471 ((oldv<<12) & 0xFF000000) |
2472 ((oldv<<8) & 0x000FFF00);
2474 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2476 facts->ProductID = le16_to_cpu(facts->ProductID);
2477 facts->CurrentHostMfaHighAddr =
2478 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2479 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2480 facts->CurrentSenseBufferHighAddr =
2481 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2482 facts->CurReplyFrameSize =
2483 le16_to_cpu(facts->CurReplyFrameSize);
2486 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2487 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2488 * to 14 in MPI-1.01.0x.
2490 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2491 facts->MsgVersion > 0x0100) {
2492 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2495 if (!facts->RequestFrameSize) {
2496 /* Something is wrong! */
2497 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2502 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2504 * Set values for this IOC's request & reply frame sizes,
2505 * and request & reply queue depths...
2507 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2508 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2509 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2510 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2512 dprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
2513 ioc->name, ioc->reply_sz, ioc->reply_depth));
2514 dprintk((MYIOC_s_INFO_FMT "req_sz =%3d, req_depth =%4d\n",
2515 ioc->name, ioc->req_sz, ioc->req_depth));
2517 /* Get port facts! */
2518 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2522 printk(MYIOC_s_ERR_FMT "Invalid IOC facts reply!\n",
2530 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2532 * GetPortFacts - Send PortFacts request to MPT adapter.
2533 * @ioc: Pointer to MPT_ADAPTER structure
2534 * @portnum: Port number
2535 * @sleepFlag: Specifies whether the process can sleep
2537 * Returns 0 for success, non-zero for failure.
2540 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2542 PortFacts_t get_pfacts;
2543 PortFactsReply_t *pfacts;
2548 /* IOC *must* NOT be in RESET state! */
2549 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2550 printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2556 pfacts = &ioc->pfacts[portnum];
2558 /* Destination (reply area)... */
2559 reply_sz = sizeof(*pfacts);
2560 memset(pfacts, 0, reply_sz);
2562 /* Request area (get_pfacts on the stack right now!) */
2563 req_sz = sizeof(get_pfacts);
2564 memset(&get_pfacts, 0, req_sz);
2566 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2567 get_pfacts.PortNumber = portnum;
2568 /* Assert: All other get_pfacts fields are zero! */
2570 dprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
2571 ioc->name, portnum));
2573 /* No non-zero fields in the get_pfacts request are greater than
2574 * 1 byte in size, so we can just fire it off as is.
2576 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2577 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2581 /* Did we get a valid reply? */
2583 /* Now byte swap the necessary fields in the response. */
2584 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2585 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2586 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2587 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2588 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2589 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2590 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2591 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2592 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2597 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2599 * SendIocInit - Send IOCInit request to MPT adapter.
2600 * @ioc: Pointer to MPT_ADAPTER structure
2601 * @sleepFlag: Specifies whether the process can sleep
2603 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2605 * Returns 0 for success, non-zero for failure.
2608 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2611 MPIDefaultReply_t init_reply;
2617 memset(&ioc_init, 0, sizeof(ioc_init));
2618 memset(&init_reply, 0, sizeof(init_reply));
2620 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2621 /* ioc_init.ChainOffset = 0; */
2622 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2623 /* ioc_init.Flags = 0; */
2625 /* If we are in a recovery mode and we uploaded the FW image,
2626 * then this pointer is not NULL. Skip the upload a second time.
2627 * Set this flag if cached_fw set for either IOC.
2631 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) {
2632 if ((ioc->cached_fw) || (ioc->alt_ioc && ioc->alt_ioc->cached_fw))
2633 ioc_init.Flags = MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE;
2637 ddlprintk((MYIOC_s_INFO_FMT "flags %d, upload_fw %d \n",
2638 ioc->name, ioc_init.Flags, ioc->upload_fw));
2640 if ((int)ioc->chip_type <= (int)FC929) {
2641 ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
2643 ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
2645 ioc_init.MaxBuses = MPT_MAX_BUS;
2647 /* ioc_init.MsgFlags = 0; */
2648 /* ioc_init.MsgContext = cpu_to_le32(0x00000000); */
2649 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2651 ioc->facts.RequestFrameSize = ioc_init.ReplyFrameSize;
2653 if (sizeof(dma_addr_t) == sizeof(u64)) {
2654 /* Save the upper 32-bits of the request
2655 * (reply) and sense buffers.
2657 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->req_frames_dma >> 32));
2658 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2660 /* Force 32-bit addressing */
2661 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2662 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2665 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2666 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2668 dprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
2669 ioc->name, &ioc_init));
2671 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2672 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2676 /* No need to byte swap the multibyte fields in the reply
2677 * since we don't even look at it's contents.
2680 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0)
2683 /* YIKES! SUPER IMPORTANT!!!
2684 * Poll IocState until _OPERATIONAL while IOC is doing
2685 * LoopInit and TargetDiscovery!
2688 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2689 state = mpt_GetIocState(ioc, 1);
2690 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2691 if (sleepFlag == CAN_SLEEP) {
2692 set_current_state(TASK_INTERRUPTIBLE);
2693 schedule_timeout(1);
2699 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2700 ioc->name, (count+5)/HZ);
2704 state = mpt_GetIocState(ioc, 1);
2707 dhsprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2713 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2715 * SendPortEnable - Send PortEnable request to MPT adapter port.
2716 * @ioc: Pointer to MPT_ADAPTER structure
2717 * @portnum: Port number to enable
2718 * @sleepFlag: Specifies whether the process can sleep
2720 * Send PortEnable to bring IOC to OPERATIONAL state.
2722 * Returns 0 for success, non-zero for failure.
2725 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2727 PortEnable_t port_enable;
2728 MPIDefaultReply_t reply_buf;
2733 /* Destination... */
2734 reply_sz = sizeof(MPIDefaultReply_t);
2735 memset(&reply_buf, 0, reply_sz);
2737 req_sz = sizeof(PortEnable_t);
2738 memset(&port_enable, 0, req_sz);
2740 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2741 port_enable.PortNumber = portnum;
2742 /* port_enable.ChainOffset = 0; */
2743 /* port_enable.MsgFlags = 0; */
2744 /* port_enable.MsgContext = 0; */
2746 dprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
2747 ioc->name, portnum, &port_enable));
2749 /* RAID FW may take a long time to enable
2751 if ((int)ioc->chip_type <= (int)FC929) {
2752 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2753 reply_sz, (u16*)&reply_buf, 65 /*seconds*/, sleepFlag);
2755 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2756 reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag);
2762 /* We do not even look at the reply, so we need not
2763 * swap the multi-byte fields.
2770 * Inputs: size - total FW bytes
2771 * Outputs: frags - number of fragments needed
2772 * Return NULL if failed.
2775 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size, int *frags, int *alloc_sz)
2777 fw_image_t **cached_fw;
2780 int alloc_total = 0;
2781 int bytes_left, bytes, num_frags;
2786 sz = ioc->num_fw_frags * sizeof(void *);
2787 mem = kmalloc(sz, GFP_ATOMIC);
2792 cached_fw = (fw_image_t **)mem;
2795 /* malloc fragment memory
2796 * fw_image_t struct and dma for fw data
2802 while((bytes_left) && (num_frags < ioc->num_fw_frags)) {
2803 if (cached_fw[ii] == NULL) {
2804 mem = kmalloc(sizeof(fw_image_t), GFP_ATOMIC);
2808 memset(mem, 0, sizeof(fw_image_t));
2809 cached_fw[ii] = (fw_image_t *)mem;
2810 alloc_total += sizeof(fw_image_t);
2813 mem = pci_alloc_consistent(ioc->pcidev, bytes, &fw_dma);
2815 if (bytes > 0x10000)
2817 else if (bytes > 0x8000)
2819 else if (bytes > 0x4000)
2821 else if (bytes > 0x2000)
2823 else if (bytes > 0x1000)
2831 cached_fw[ii]->fw = mem;
2832 cached_fw[ii]->fw_dma = fw_dma;
2833 cached_fw[ii]->size = bytes;
2834 memset(mem, 0, bytes);
2835 alloc_total += bytes;
2837 bytes_left -= bytes;
2846 mpt_free_fw_memory(ioc, cached_fw);
2851 *alloc_sz = alloc_total;
2853 return (void *) cached_fw;
2857 * If alt_img is NULL, delete from ioc structure.
2858 * Else, delete a secondary image in same format.
2861 mpt_free_fw_memory(MPT_ADAPTER *ioc, fw_image_t **alt_img)
2863 fw_image_t **cached_fw;
2866 int alloc_freed = 0;
2868 if (alt_img != NULL)
2869 cached_fw = alt_img;
2871 cached_fw = ioc->cached_fw;
2873 if (cached_fw == NULL)
2877 while ((ii < ioc->num_fw_frags) && (cached_fw[ii]!= NULL)) {
2878 sz = cached_fw[ii]->size;
2880 pci_free_consistent(ioc->pcidev, sz,
2881 cached_fw[ii]->fw, cached_fw[ii]->fw_dma);
2883 cached_fw[ii]->fw = NULL;
2886 kfree(cached_fw[ii]);
2887 cached_fw[ii] = NULL;
2888 alloc_freed += sizeof(fw_image_t);
2895 sz = ioc->num_fw_frags * sizeof(void *);
2898 if (alt_img == NULL)
2899 ioc->alloc_total -= alloc_freed;
2905 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2907 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
2908 * @ioc: Pointer to MPT_ADAPTER structure
2909 * @sleepFlag: Specifies whether the process can sleep
2911 * Returns 0 for success, >0 for handshake failure
2912 * <0 for fw upload failure.
2914 * Remark: If bound IOC and a successful FWUpload was performed
2915 * on the bound IOC, the second image is discarded
2916 * and memory is free'd. Both channels must upload to prevent
2917 * IOC from running in degraded mode.
2920 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2922 u8 request[ioc->req_sz];
2923 u8 reply[sizeof(FWUploadReply_t)];
2924 FWUpload_t *prequest;
2925 FWUploadReply_t *preply;
2926 FWUploadTCSGE_t *ptcsge;
2928 int ii, sz, reply_sz;
2929 int cmdStatus, freeMem = 0;
2930 int num_frags, alloc_sz;
2932 /* If the image size is 0 or if the pointer is
2933 * not NULL (error), we are done.
2935 if (((sz = ioc->facts.FWImageSize) == 0) || ioc->cached_fw)
2938 ioc->num_fw_frags = ioc->req_sz - sizeof(FWUpload_t) + sizeof(dma_addr_t) + sizeof(u32) -1;
2939 ioc->num_fw_frags /= sizeof(dma_addr_t) + sizeof(u32);
2941 ioc->cached_fw = (fw_image_t **) mpt_alloc_fw_memory(ioc,
2942 ioc->facts.FWImageSize, &num_frags, &alloc_sz);
2944 if (ioc->cached_fw == NULL) {
2947 mpt_free_fw_memory(ioc, NULL);
2948 ioc->cached_fw = NULL;
2952 ioc->alloc_total += alloc_sz;
2954 ddlprintk((KERN_INFO MYNAM ": FW Image @ %p, sz=%d bytes\n",
2955 (void *)(ulong)ioc->cached_fw, ioc->facts.FWImageSize));
2957 prequest = (FWUpload_t *)&request;
2958 preply = (FWUploadReply_t *)&reply;
2960 /* Destination... */
2961 memset(prequest, 0, ioc->req_sz);
2963 reply_sz = sizeof(reply);
2964 memset(preply, 0, reply_sz);
2966 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
2967 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
2968 prequest->MsgContext = 0; /* anything */
2970 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
2971 ptcsge->Reserved = 0;
2972 ptcsge->ContextSize = 0;
2973 ptcsge->DetailsLength = 12;
2974 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
2975 ptcsge->Reserved1 = 0;
2976 ptcsge->ImageOffset = 0;
2977 ptcsge->ImageSize = cpu_to_le32(sz);
2979 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
2981 for (ii = 0; ii < (num_frags-1); ii++) {
2982 mpt_add_sge(&request[sgeoffset], MPT_SGE_FLAGS_SIMPLE_ELEMENT |
2983 MPT_SGE_FLAGS_ADDRESSING | MPT_TRANSFER_IOC_TO_HOST |
2984 (u32) ioc->cached_fw[ii]->size, ioc->cached_fw[ii]->fw_dma);
2986 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
2989 mpt_add_sge(&request[sgeoffset],
2990 MPT_SGE_FLAGS_SSIMPLE_READ |(u32) ioc->cached_fw[ii]->size,
2991 ioc->cached_fw[ii]->fw_dma);
2993 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
2995 dprintk((MYIOC_s_INFO_FMT "Sending FW Upload (req @ %p) size %d \n",
2996 ioc->name, prequest, sgeoffset));
2998 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
2999 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
3001 cmdStatus = -EFAULT;
3003 /* Handshake transfer was complete and successful.
3004 * Check the Reply Frame.
3006 int status, transfer_sz;
3007 status = le16_to_cpu(preply->IOCStatus);
3008 if (status == MPI_IOCSTATUS_SUCCESS) {
3009 transfer_sz = le32_to_cpu(preply->ActualImageSize);
3010 if (transfer_sz == sz)
3014 ddlprintk((MYIOC_s_INFO_FMT ": do_upload status %d \n",
3015 ioc->name, cmdStatus));
3017 /* Check to see if we have a copy of this image in
3018 * host memory already.
3020 if (cmdStatus == 0) {
3022 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3026 /* We already have a copy of this image or
3027 * we had some type of an error - either the handshake
3028 * failed (i != 0) or the command did not complete successfully.
3030 if (cmdStatus || freeMem) {
3032 ddlprintk((MYIOC_s_INFO_FMT ": do_upload freeing %s image \n",
3033 ioc->name, cmdStatus ? "incomplete" : "duplicate"));
3034 mpt_free_fw_memory(ioc, NULL);
3035 ioc->cached_fw = NULL;
3041 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3043 * mpt_downloadboot - DownloadBoot code
3044 * @ioc: Pointer to MPT_ADAPTER structure
3045 * @flag: Specify which part of IOC memory is to be uploaded.
3046 * @sleepFlag: Specifies whether the process can sleep
3048 * FwDownloadBoot requires Programmed IO access.
3050 * Returns 0 for success
3051 * -1 FW Image size is 0
3052 * -2 No valid cached_fw Pointer
3053 * <0 for fw upload failure.
3056 mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
3058 MpiFwHeader_t *FwHdr;
3059 MpiExtImageHeader_t *ExtHdr;
3060 fw_image_t **pCached=NULL;
3072 int max_idx, fw_idx, ext_idx;
3075 ddlprintk((MYIOC_s_INFO_FMT "DbGb0: downloadboot entered.\n",
3078 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3080 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3081 ddlprintk((MYIOC_s_INFO_FMT "DbGb1: diag0=%08x, diag1=%08x\n",
3082 ioc->name, diag0val, diag1val));
3085 ddlprintk((MYIOC_s_INFO_FMT "fw size 0x%x, ioc FW Ptr %p\n",
3086 ioc->name, ioc->facts.FWImageSize, ioc->cached_fw));
3088 ddlprintk((MYIOC_s_INFO_FMT "alt ioc FW Ptr %p\n",
3089 ioc->name, ioc->alt_ioc->cached_fw));
3091 /* Get dma_addr and data transfer size.
3093 if ((fw_sz = ioc->facts.FWImageSize) == 0)
3096 /* Get the DMA from ioc or ioc->alt_ioc */
3097 if (ioc->cached_fw != NULL)
3098 pCached = (fw_image_t **)ioc->cached_fw;
3099 else if (ioc->alt_ioc && (ioc->alt_ioc->cached_fw != NULL))
3100 pCached = (fw_image_t **)ioc->alt_ioc->cached_fw;
3104 ddlprintk((MYIOC_s_INFO_FMT "DbGb2: FW Image @ %p\n",
3105 ioc->name, pCached));
3107 /* Write magic sequence to WriteSequence register
3108 * until enter diagnostic mode
3110 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3111 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3112 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3113 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3114 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3115 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3116 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3117 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3120 if (sleepFlag == CAN_SLEEP) {
3121 set_current_state(TASK_INTERRUPTIBLE);
3122 schedule_timeout(100 * HZ / 1000);
3129 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3130 ioc->name, diag0val);
3135 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3138 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3139 ddlprintk((MYIOC_s_INFO_FMT "DbGb3: diag0=%08x, diag1=%08x\n",
3140 ioc->name, diag0val, diag1val));
3142 ddlprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3143 ioc->name, diag0val));
3146 /* Set the DiagRwEn and Disable ARM bits */
3147 diag0val |= (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM);
3148 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3152 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3154 ddlprintk((MYIOC_s_INFO_FMT "DbGb3: diag0=%08x, diag1=%08x\n",
3155 ioc->name, diag0val, diag1val));
3158 /* max_idx = 1 + maximum valid buffer index
3161 while (pCached[max_idx])
3165 FwHdr = (MpiFwHeader_t *) pCached[fw_idx]->fw;
3166 ptru32 = (u32 *) FwHdr;
3167 count = (FwHdr->ImageSize + 3)/4;
3168 nextImage = FwHdr->NextImageHeaderOffset;
3170 /* Write the LoadStartAddress to the DiagRw Address Register
3171 * using Programmed IO
3173 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, FwHdr->LoadStartAddress);
3174 ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
3175 ioc->name, FwHdr->LoadStartAddress));
3177 ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x u32's @ %p\n",
3178 ioc->name, count, ptru32));
3179 left_u32s = pCached[fw_idx]->size/4;
3181 if (left_u32s == 0) {
3183 if (fw_idx >= max_idx) {
3189 ptru32 = (u32 *) pCached[fw_idx]->fw;
3190 left_u32s = pCached[fw_idx]->size / 4;
3193 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptru32);
3197 /* left_u32s, fw_idx and ptru32 are all valid
3201 ext_offset = nextImage;
3202 while (ext_offset > pCached[ext_idx]->size) {
3204 if (ext_idx >= max_idx) {
3210 ext_offset -= pCached[ext_idx]->size;
3212 ptru32 = (u32 *) ((char *)pCached[ext_idx]->fw + ext_offset);
3213 left_u32s = pCached[ext_idx]->size - ext_offset;
3215 if ((left_u32s * 4) >= sizeof(MpiExtImageHeader_t)) {
3216 ExtHdr = (MpiExtImageHeader_t *) ptru32;
3217 count = (ExtHdr->ImageSize + 3 )/4;
3218 nextImage = ExtHdr->NextImageHeaderOffset;
3219 load_addr = ExtHdr->LoadStartAddress;
3221 u32 * ptmp = (u32 *)pCached[ext_idx+1]->fw;
3223 switch (left_u32s) {
3225 count = *(ptru32 + 2);
3226 nextImage = *(ptru32 + 3);
3227 load_addr = *(ptru32 + 4);
3230 count = *(ptru32 + 2);
3231 nextImage = *(ptru32 + 3);
3235 count = *(ptru32 + 2);
3237 load_addr = *(ptmp + 1);
3241 nextImage = *(ptmp + 1);
3242 load_addr = *(ptmp + 2);
3246 count = *(ptmp + 1);
3247 nextImage = *(ptmp + 2);
3248 load_addr = *(ptmp + 3);
3261 count = (count +3)/4;
3264 ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x u32's @ %p\n",
3265 ioc->name, count, ptru32));
3266 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3269 if (left_u32s == 0) {
3271 if (fw_idx >= max_idx) {
3277 ptru32 = (u32 *) pCached[fw_idx]->fw;
3278 left_u32s = pCached[fw_idx]->size / 4;
3281 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptru32);
3286 /* Write the IopResetVectorRegAddr */
3287 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr! \n", ioc->name));
3288 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, FwHdr->IopResetRegAddr);
3290 /* Write the IopResetVectorValue */
3291 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value! \n", ioc->name));
3292 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, FwHdr->IopResetVectorValue);
3294 /* Clear the internal flash bad bit - autoincrementing register,
3295 * so must do two writes.
3297 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3298 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3299 diagRwData |= 0x4000000;
3300 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3301 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3303 /* clear the RW enable and DISARM bits */
3304 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3305 diag0val &= ~(MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE | MPI_DIAG_FLASH_BAD_SIG);
3306 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3308 /* Write 0xFF to reset the sequencer */
3309 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3314 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3316 * KickStart - Perform hard reset of MPT adapter.
3317 * @ioc: Pointer to MPT_ADAPTER structure
3318 * @force: Force hard reset
3319 * @sleepFlag: Specifies whether the process can sleep
3321 * This routine places MPT adapter in diagnostic mode via the
3322 * WriteSequence register, and then performs a hard reset of adapter
3323 * via the Diagnostic register.
3325 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3326 * or NO_SLEEP (interrupt thread, use mdelay)
3327 * force - 1 if doorbell active, board fault state
3328 * board operational, IOC_RECOVERY or
3329 * IOC_BRINGUP and there is an alt_ioc.
3333 * 1 - hard reset, READY
3334 * 0 - no reset due to History bit, READY
3335 * -1 - no reset due to History bit but not READY
3336 * OR reset but failed to come READY
3337 * -2 - no reset, could not enter DIAG mode
3338 * -3 - reset but bad FW bit
3341 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3343 int hard_reset_done = 0;
3347 dprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
3348 if ((int)ioc->chip_type > (int)FC929) {
3349 /* Always issue a Msg Unit Reset first. This will clear some
3350 * SCSI bus hang conditions.
3352 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3354 if (sleepFlag == CAN_SLEEP) {
3355 set_current_state(TASK_INTERRUPTIBLE);
3356 schedule_timeout(HZ);
3362 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3363 if (hard_reset_done < 0)
3364 return hard_reset_done;
3366 dprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
3369 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 20; /* 20 seconds */
3370 for (cnt=0; cnt<cntdn; cnt++) {
3371 if ((ioc_state = mpt_GetIocState(ioc, 1)) == MPI_IOC_STATE_READY) {
3372 dprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
3374 return hard_reset_done;
3376 if (sleepFlag == CAN_SLEEP) {
3377 set_current_state(TASK_INTERRUPTIBLE);
3378 schedule_timeout(1);
3384 printk(MYIOC_s_ERR_FMT "Failed to come READY after reset!\n",
3389 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3391 * mpt_diag_reset - Perform hard reset of the adapter.
3392 * @ioc: Pointer to MPT_ADAPTER structure
3393 * @ignore: Set if to honor and clear to ignore
3394 * the reset history bit
3395 * @sleepflag: CAN_SLEEP if called in a non-interrupt thread,
3396 * else set to NO_SLEEP (use mdelay instead)
3398 * This routine places the adapter in diagnostic mode via the
3399 * WriteSequence register and then performs a hard reset of adapter
3400 * via the Diagnostic register. Adapter should be in ready state
3401 * upon successful completion.
3403 * Returns: 1 hard reset successful
3404 * 0 no reset performed because reset history bit set
3405 * -2 enabling diagnostic mode failed
3406 * -3 diagnostic reset failed
3409 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3413 int hard_reset_done = 0;
3419 /* Clear any existing interrupts */
3420 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3422 /* Use "Diagnostic reset" method! (only thing available!) */
3423 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3427 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3428 dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3429 ioc->name, diag0val, diag1val));
3432 /* Do the reset if we are told to ignore the reset history
3433 * or if the reset history is 0
3435 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3436 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3437 /* Write magic sequence to WriteSequence register
3438 * Loop until in diagnostic mode
3440 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3441 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3442 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3443 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3444 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3445 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3448 if (sleepFlag == CAN_SLEEP) {
3449 set_current_state(TASK_INTERRUPTIBLE);
3450 schedule_timeout(100 * HZ / 1000);
3457 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3458 ioc->name, diag0val);
3463 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3465 dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3466 ioc->name, diag0val));
3471 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3472 dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3473 ioc->name, diag0val, diag1val));
3475 /* Write the PreventIocBoot bit */
3476 if ((ioc->cached_fw) || (ioc->alt_ioc && ioc->alt_ioc->cached_fw)) {
3477 diag0val |= MPI_DIAG_PREVENT_IOC_BOOT;
3478 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3482 * Disable the ARM (Bug fix)
3485 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3489 * Now hit the reset bit in the Diagnostic register
3490 * (THE BIG HAMMER!) (Clears DRWE bit).
3492 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3493 hard_reset_done = 1;
3494 dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
3498 * Call each currently registered protocol IOC reset handler
3499 * with pre-reset indication.
3500 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3501 * MptResetHandlers[] registered yet.
3507 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
3508 if (MptResetHandlers[ii]) {
3509 dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
3511 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_PRE_RESET);
3513 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3514 ioc->name, ioc->alt_ioc->name, ii));
3515 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_PRE_RESET);
3519 /* FIXME? Examine results here? */
3522 if ((ioc->cached_fw) || (ioc->alt_ioc && ioc->alt_ioc->cached_fw)) {
3523 /* If the DownloadBoot operation fails, the
3524 * IOC will be left unusable. This is a fatal error
3525 * case. _diag_reset will return < 0
3527 for (count = 0; count < 30; count ++) {
3528 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3531 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3532 dprintk((MYIOC_s_INFO_FMT
3533 "DbG2b: diag0=%08x, diag1=%08x\n",
3534 ioc->name, diag0val, diag1val));
3536 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3541 if (sleepFlag == CAN_SLEEP) {
3542 set_current_state(TASK_INTERRUPTIBLE);
3543 schedule_timeout(HZ);
3548 if ((count = mpt_downloadboot(ioc, sleepFlag)) < 0) {
3549 printk(KERN_WARNING MYNAM
3550 ": firmware downloadboot failure (%d)!\n", count);
3554 /* Wait for FW to reload and for board
3555 * to go to the READY state.
3556 * Maximum wait is 60 seconds.
3557 * If fail, no error will check again
3558 * with calling program.
3560 for (count = 0; count < 60; count ++) {
3561 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3562 doorbell &= MPI_IOC_STATE_MASK;
3564 if (doorbell == MPI_IOC_STATE_READY) {
3569 if (sleepFlag == CAN_SLEEP) {
3570 set_current_state(TASK_INTERRUPTIBLE);
3571 schedule_timeout(HZ);
3579 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3582 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3583 dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3584 ioc->name, diag0val, diag1val));
3587 /* Clear RESET_HISTORY bit! Place board in the
3588 * diagnostic mode to update the diag register.
3590 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3592 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3593 /* Write magic sequence to WriteSequence register
3594 * Loop until in diagnostic mode
3596 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3597 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3598 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3599 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3600 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3603 if (sleepFlag == CAN_SLEEP) {
3604 set_current_state(TASK_INTERRUPTIBLE);
3605 schedule_timeout(100 * HZ / 1000);
3612 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3613 ioc->name, diag0val);
3616 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3618 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3619 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3620 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3621 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3622 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3626 /* Disable Diagnostic Mode
3628 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3630 /* Check FW reload status flags.
3632 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3633 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3634 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3635 ioc->name, diag0val);
3641 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3642 dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3643 ioc->name, diag0val, diag1val));
3647 * Reset flag that says we've enabled event notification
3649 ioc->facts.EventState = 0;
3652 ioc->alt_ioc->facts.EventState = 0;
3654 return hard_reset_done;
3657 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3659 * SendIocReset - Send IOCReset request to MPT adapter.
3660 * @ioc: Pointer to MPT_ADAPTER structure
3661 * @reset_type: reset type, expected values are
3662 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3664 * Send IOCReset request to the MPT adapter.
3666 * Returns 0 for success, non-zero for failure.
3669 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3675 dprintk((KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
3676 ioc->name, reset_type));
3677 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3678 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3681 /* FW ACK'd request, wait for READY state
3684 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3686 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3690 if (sleepFlag != CAN_SLEEP)
3693 printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3694 ioc->name, (count+5)/HZ);
3698 if (sleepFlag == CAN_SLEEP) {
3699 set_current_state(TASK_INTERRUPTIBLE);
3700 schedule_timeout(1);
3702 mdelay (1); /* 1 msec delay */
3707 * Cleanup all event stuff for this IOC; re-issue EventNotification
3708 * request if needed.
3710 if (ioc->facts.Function)
3711 ioc->facts.EventState = 0;
3716 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3718 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3719 * @ioc: Pointer to MPT_ADAPTER structure
3721 * This routine allocates memory for the MPT reply and request frame
3722 * pools (if necessary), and primes the IOC reply FIFO with
3725 * Returns 0 for success, non-zero for failure.
3728 PrimeIocFifos(MPT_ADAPTER *ioc)
3732 unsigned long flags;
3733 dma_addr_t aligned_mem_dma;
3736 int chain_buffer_sz, reply_buffer_sz, request_buffer_sz;
3737 int scale, num_sge, num_chain;
3739 /* request buffer size, rounding UP to nearest 4-kB boundary */
3740 request_buffer_sz = (ioc->req_sz * ioc->req_depth) + 128;
3741 request_buffer_sz = ((request_buffer_sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
3743 /* reply buffer size */
3744 reply_buffer_sz = (ioc->reply_sz * ioc->reply_depth) + 128;
3746 /* chain buffer size, copied from from mptscsih_initChainBuffers()
3748 * Calculate the number of chain buffers needed(plus 1) per I/O
3749 * then multiply the the maximum number of simultaneous cmds
3751 * num_sge = num sge in request frame + last chain buffer
3752 * scale = num sge per chain buffer if no chain element
3755 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3756 if (sizeof(dma_addr_t) == sizeof(u64))
3757 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3759 num_sge = 1 + scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3762 while (MPT_SCSI_SG_DEPTH - num_sge > 0) {
3764 num_sge += (scale - 1);
3768 if ((int)ioc->chip_type > (int) FC929)
3769 num_chain *= MPT_SCSI_CAN_QUEUE;
3771 num_chain *= MPT_FC_CAN_QUEUE;
3773 chain_buffer_sz = num_chain * ioc->req_sz;
3775 if(ioc->fifo_pool == NULL) {
3777 ioc->fifo_pool_sz = request_buffer_sz +
3778 reply_buffer_sz + chain_buffer_sz;
3780 ioc->fifo_pool = pci_alloc_consistent(ioc->pcidev,
3781 ioc->fifo_pool_sz, &ioc->fifo_pool_dma);
3783 if( ioc->fifo_pool == NULL)
3786 ioc->alloc_total += ioc->fifo_pool_sz;
3787 memset(ioc->fifo_pool, 0, ioc->fifo_pool_sz);
3789 /* reply fifo pointers */
3790 ioc->reply_alloc = ioc->fifo_pool;
3791 ioc->reply_alloc_dma = ioc->fifo_pool_dma;
3792 /* request fifo pointers */
3793 ioc->req_alloc = ioc->reply_alloc+reply_buffer_sz;
3794 ioc->req_alloc_dma = ioc->reply_alloc_dma+reply_buffer_sz;
3795 /* chain buffer pointers */
3796 ioc->chain_alloc = ioc->req_alloc+request_buffer_sz;
3797 ioc->chain_alloc_dma = ioc->req_alloc_dma+request_buffer_sz;
3798 ioc->chain_alloc_sz = chain_buffer_sz;
3800 /* Prime reply FIFO... */
3801 dprintk((KERN_INFO MYNAM ": %s.reply_alloc @ %p[%p], sz=%d bytes\n",
3802 ioc->name, mem, (void *)(ulong)ioc->reply_alloc_dma, reply_buffer_sz));
3804 b = (unsigned long) ioc->reply_alloc;
3805 b = (b + (0x80UL - 1UL)) & ~(0x80UL - 1UL); /* round up to 128-byte boundary */
3806 aligned_mem = (u8 *) b;
3807 ioc->reply_frames = (MPT_FRAME_HDR *) aligned_mem;
3808 ioc->reply_frames_dma =
3809 (ioc->reply_alloc_dma + (aligned_mem - ioc->reply_alloc));
3811 ioc->reply_frames_low_dma = (u32) (ioc->reply_frames_dma & 0xFFFFFFFF);
3813 /* Request FIFO - WE manage this! */
3814 dprintk((KERN_INFO MYNAM ": %s.req_alloc @ %p[%p], sz=%d bytes\n",
3815 ioc->name, mem, (void *)(ulong)ioc->req_alloc_dma, request_buffer_sz));
3817 b = (unsigned long) ioc->req_alloc;
3818 b = (b + (0x80UL - 1UL)) & ~(0x80UL - 1UL); /* round up to 128-byte boundary */
3819 aligned_mem = (u8 *) b;
3820 ioc->req_frames = (MPT_FRAME_HDR *) aligned_mem;
3821 ioc->req_frames_dma =
3822 (ioc->req_alloc_dma + (aligned_mem - ioc->req_alloc));
3824 ioc->req_frames_low_dma = (u32) (ioc->req_frames_dma & 0xFFFFFFFF);
3826 #if defined(CONFIG_MTRR) && 0
3828 * Enable Write Combining MTRR for IOC's memory region.
3829 * (at least as much as we can; "size and base must be
3830 * multiples of 4 kiB"
3832 ioc->mtrr_reg = mtrr_add(ioc->fifo_pool,
3834 MTRR_TYPE_WRCOMB, 1);
3835 dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
3836 ioc->name, ioc->fifo_pool, ioc->fifo_pool_sz));
3839 } /* ioc->fifo_pool == NULL */
3841 /* Post Reply frames to FIFO
3843 aligned_mem_dma = ioc->reply_frames_dma;
3844 dprintk((KERN_INFO MYNAM ": %s.reply_frames @ %p[%p]\n",
3845 ioc->name, ioc->reply_frames, (void *)(ulong)aligned_mem_dma));
3847 for (i = 0; i < ioc->reply_depth; i++) {
3848 /* Write each address to the IOC! */
3849 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, aligned_mem_dma);
3850 aligned_mem_dma += ioc->reply_sz;
3854 /* Initialize Request frames linked list
3856 aligned_mem_dma = ioc->req_frames_dma;
3857 aligned_mem = (u8 *) ioc->req_frames;
3858 dprintk((KERN_INFO MYNAM ": %s.req_frames @ %p[%p]\n",
3859 ioc->name, aligned_mem, (void *)(ulong)aligned_mem_dma));
3861 spin_lock_irqsave(&ioc->FreeQlock, flags);
3862 Q_INIT(&ioc->FreeQ, MPT_FRAME_HDR);
3863 for (i = 0; i < ioc->req_depth; i++) {
3864 mf = (MPT_FRAME_HDR *) aligned_mem;
3866 /* Queue REQUESTs *internally*! */
3867 Q_ADD_TAIL(&ioc->FreeQ.head, &mf->u.frame.linkage, MPT_FRAME_HDR);
3868 aligned_mem += ioc->req_sz;
3870 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3873 if (ioc->sense_buf_pool == NULL) {
3874 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3875 ioc->sense_buf_pool =
3876 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3877 if (ioc->sense_buf_pool == NULL)
3880 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
3881 ioc->alloc_total += sz;
3887 if (ioc->fifo_pool != NULL) {
3888 pci_free_consistent(ioc->pcidev,
3890 ioc->fifo_pool, ioc->fifo_pool_dma);
3891 ioc->reply_frames = NULL;
3892 ioc->reply_alloc = NULL;
3893 ioc->req_frames = NULL;
3894 ioc->req_alloc = NULL;
3895 ioc->chain_alloc = NULL;
3896 ioc->fifo_pool = NULL;
3897 ioc->alloc_total -= ioc->fifo_pool_sz;
3898 #if defined(CONFIG_MTRR) && 0
3899 if (ioc->mtrr_reg > 0) {
3900 mtrr_del(ioc->mtrr_reg, 0, 0);
3901 dprintk((MYIOC_s_INFO_FMT "MTRR region de-registered\n",
3906 if (ioc->sense_buf_pool != NULL) {
3907 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3908 pci_free_consistent(ioc->pcidev,
3910 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
3911 ioc->sense_buf_pool = NULL;
3916 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3918 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3919 * from IOC via doorbell handshake method.
3920 * @ioc: Pointer to MPT_ADAPTER structure
3921 * @reqBytes: Size of the request in bytes
3922 * @req: Pointer to MPT request frame
3923 * @replyBytes: Expected size of the reply in bytes
3924 * @u16reply: Pointer to area where reply should be written
3925 * @maxwait: Max wait time for a reply (in seconds)
3926 * @sleepFlag: Specifies whether the process can sleep
3928 * NOTES: It is the callers responsibility to byte-swap fields in the
3929 * request which are greater than 1 byte in size. It is also the
3930 * callers responsibility to byte-swap response fields which are
3931 * greater than 1 byte in size.
3933 * Returns 0 for success, non-zero for failure.
3936 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
3937 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
3939 MPIDefaultReply_t *mptReply;
3944 * Get ready to cache a handshake reply
3946 ioc->hs_reply_idx = 0;
3947 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3948 mptReply->MsgLength = 0;
3951 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
3952 * then tell IOC that we want to handshake a request of N words.
3953 * (WRITE u32val to Doorbell reg).
3955 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3956 CHIPREG_WRITE32(&ioc->chip->Doorbell,
3957 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
3958 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
3961 * Wait for IOC's doorbell handshake int
3963 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3966 dhsprintk((MYIOC_s_INFO_FMT "HandShake request start, WaitCnt=%d%s\n",
3967 ioc->name, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3969 /* Read doorbell and check for active bit */
3970 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
3974 * Clear doorbell int (WRITE 0 to IntStatus reg),
3975 * then wait for IOC to ACKnowledge that it's ready for
3976 * our handshake request.
3978 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3979 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3984 u8 *req_as_bytes = (u8 *) req;
3987 * Stuff request words via doorbell handshake,
3988 * with ACK from IOC for each.
3990 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
3991 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
3992 (req_as_bytes[(ii*4) + 1] << 8) |
3993 (req_as_bytes[(ii*4) + 2] << 16) |
3994 (req_as_bytes[(ii*4) + 3] << 24));
3996 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
3997 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4001 dmfprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
4002 DBG_DUMP_REQUEST_FRAME_HDR(req)
4004 dhsprintk((MYIOC_s_INFO_FMT "HandShake request post done, WaitCnt=%d%s\n",
4005 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4008 * Wait for completion of doorbell handshake reply from the IOC
4010 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4014 * Copy out the cached reply...
4016 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4017 u16reply[ii] = ioc->hs_reply[ii];
4025 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4027 * WaitForDoorbellAck - Wait for IOC to clear the IOP_DOORBELL_STATUS bit
4028 * in it's IntStatus register.
4029 * @ioc: Pointer to MPT_ADAPTER structure
4030 * @howlong: How long to wait (in seconds)
4031 * @sleepFlag: Specifies whether the process can sleep
4033 * This routine waits (up to ~2 seconds max) for IOC doorbell
4034 * handshake ACKnowledge.
4036 * Returns a negative value on failure, else wait loop count.
4039 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4045 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
4047 if (sleepFlag == CAN_SLEEP) {
4049 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4050 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4052 set_current_state(TASK_INTERRUPTIBLE);
4053 schedule_timeout(1);
4058 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4059 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4067 dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (cnt=%d)\n",
4072 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout(%d)!\n",
4073 ioc->name, (count+5)/HZ);
4077 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4079 * WaitForDoorbellInt - Wait for IOC to set the HIS_DOORBELL_INTERRUPT bit
4080 * in it's IntStatus register.
4081 * @ioc: Pointer to MPT_ADAPTER structure
4082 * @howlong: How long to wait (in seconds)
4083 * @sleepFlag: Specifies whether the process can sleep
4085 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt.
4087 * Returns a negative value on failure, else wait loop count.
4090 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4096 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
4097 if (sleepFlag == CAN_SLEEP) {
4099 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4100 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4102 set_current_state(TASK_INTERRUPTIBLE);
4103 schedule_timeout(1);
4108 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4109 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4117 dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d)\n",
4122 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout(%d)!\n",
4123 ioc->name, (count+5)/HZ);
4127 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4129 * WaitForDoorbellReply - Wait for and capture a IOC handshake reply.
4130 * @ioc: Pointer to MPT_ADAPTER structure
4131 * @howlong: How long to wait (in seconds)
4132 * @sleepFlag: Specifies whether the process can sleep
4134 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4135 * Reply is cached to IOC private area large enough to hold a maximum
4136 * of 128 bytes of reply data.
4138 * Returns a negative value on failure, else size of reply in WORDS.
4141 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4146 u16 *hs_reply = ioc->hs_reply;
4147 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4150 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4153 * Get first two u16's so we can look at IOC's intended reply MsgLength
4156 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4159 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4160 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4161 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4164 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4165 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4169 dhsprintk((MYIOC_s_INFO_FMT "First handshake reply word=%08x%s\n",
4170 ioc->name, le32_to_cpu(*(u32 *)hs_reply),
4171 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4174 * If no error (and IOC said MsgLength is > 0), piece together
4175 * reply 16 bits at a time.
4177 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4178 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4180 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4181 /* don't overflow our IOC hs_reply[] buffer! */
4182 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4183 hs_reply[u16cnt] = hword;
4184 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4187 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4189 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4192 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4197 else if (u16cnt != (2 * mptReply->MsgLength)) {
4200 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4205 dmfprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
4206 DBG_DUMP_REPLY_FRAME(mptReply)
4208 dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY (sz=%d)\n",
4209 ioc->name, u16cnt/2));
4213 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4215 * GetLanConfigPages - Fetch LANConfig pages.
4216 * @ioc: Pointer to MPT_ADAPTER structure
4218 * Return: 0 for success
4219 * -ENOMEM if no memory available
4220 * -EPERM if not allowed due to ISR context
4221 * -EAGAIN if no msg frames currently available
4222 * -EFAULT for non-successful reply or no reply (timeout)
4225 GetLanConfigPages(MPT_ADAPTER *ioc)
4227 ConfigPageHeader_t hdr;
4229 LANPage0_t *ppage0_alloc;
4230 dma_addr_t page0_dma;
4231 LANPage1_t *ppage1_alloc;
4232 dma_addr_t page1_dma;
4237 /* Get LAN Page 0 header */
4238 hdr.PageVersion = 0;
4241 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4244 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4249 if ((rc = mpt_config(ioc, &cfg)) != 0)
4252 if (hdr.PageLength > 0) {
4253 data_sz = hdr.PageLength * 4;
4254 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4257 memset((u8 *)ppage0_alloc, 0, data_sz);
4258 cfg.physAddr = page0_dma;
4259 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4261 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4263 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4264 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4268 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4271 * Normalize endianness of structure data,
4272 * by byte-swapping all > 1 byte fields!
4281 /* Get LAN Page 1 header */
4282 hdr.PageVersion = 0;
4285 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4288 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4292 if ((rc = mpt_config(ioc, &cfg)) != 0)
4295 if (hdr.PageLength == 0)
4298 data_sz = hdr.PageLength * 4;
4300 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4302 memset((u8 *)ppage1_alloc, 0, data_sz);
4303 cfg.physAddr = page1_dma;
4304 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4306 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4308 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4309 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4312 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4315 * Normalize endianness of structure data,
4316 * by byte-swapping all > 1 byte fields!
4324 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4326 * GetFcPortPage0 - Fetch FCPort config Page0.
4327 * @ioc: Pointer to MPT_ADAPTER structure
4328 * @portnum: IOC Port number
4330 * Return: 0 for success
4331 * -ENOMEM if no memory available
4332 * -EPERM if not allowed due to ISR context
4333 * -EAGAIN if no msg frames currently available
4334 * -EFAULT for non-successful reply or no reply (timeout)
4337 GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
4339 ConfigPageHeader_t hdr;
4341 FCPortPage0_t *ppage0_alloc;
4342 FCPortPage0_t *pp0dest;
4343 dma_addr_t page0_dma;
4348 /* Get FCPort Page 0 header */
4349 hdr.PageVersion = 0;
4352 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
4355 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4357 cfg.pageAddr = portnum;
4360 if ((rc = mpt_config(ioc, &cfg)) != 0)
4363 if (hdr.PageLength == 0)
4366 data_sz = hdr.PageLength * 4;
4368 ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4370 memset((u8 *)ppage0_alloc, 0, data_sz);
4371 cfg.physAddr = page0_dma;
4372 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4374 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4376 pp0dest = &ioc->fc_port_page0[portnum];
4377 copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
4378 memcpy(pp0dest, ppage0_alloc, copy_sz);
4381 * Normalize endianness of structure data,
4382 * by byte-swapping all > 1 byte fields!
4384 pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
4385 pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
4386 pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
4387 pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
4388 pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
4389 pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
4390 pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
4391 pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
4392 pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
4393 pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
4394 pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
4395 pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
4396 pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
4397 pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
4398 pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
4399 pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
4403 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4409 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4411 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4412 * @ioc: Pointer to MPT_ADAPTER structure
4414 * Returns: 0 for success
4415 * -ENOMEM if no memory available
4416 * -EPERM if not allowed due to ISR context
4417 * -EAGAIN if no msg frames currently available
4418 * -EFAULT for non-successful reply or no reply (timeout)
4421 GetIoUnitPage2(MPT_ADAPTER *ioc)
4423 ConfigPageHeader_t hdr;
4425 IOUnitPage2_t *ppage_alloc;
4426 dma_addr_t page_dma;
4430 /* Get the page header */
4431 hdr.PageVersion = 0;
4434 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4437 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4442 if ((rc = mpt_config(ioc, &cfg)) != 0)
4445 if (hdr.PageLength == 0)
4448 /* Read the config page */
4449 data_sz = hdr.PageLength * 4;
4451 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4453 memset((u8 *)ppage_alloc, 0, data_sz);
4454 cfg.physAddr = page_dma;
4455 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4457 /* If Good, save data */
4458 if ((rc = mpt_config(ioc, &cfg)) == 0)
4459 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4461 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4467 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4468 /* mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4469 * @ioc: Pointer to a Adapter Strucutre
4470 * @portnum: IOC port number
4472 * Return: -EFAULT if read of config page header fails
4474 * If read of SCSI Port Page 0 fails,
4475 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4476 * Adapter settings: async, narrow
4478 * If read of SCSI Port Page 2 fails,
4479 * Adapter settings valid
4480 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4485 * CHECK - what type of locking mechanisms should be used????
4488 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4493 ConfigPageHeader_t header;
4499 if (!ioc->spi_data.nvram) {
4502 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4503 mem = kmalloc(sz, GFP_ATOMIC);
4507 ioc->spi_data.nvram = (int *) mem;
4509 dprintk((MYIOC_s_INFO_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4510 ioc->name, ioc->spi_data.nvram, sz));
4513 /* Invalidate NVRAM information
4515 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4516 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4519 /* Read SPP0 header, allocate memory, then read page.
4521 header.PageVersion = 0;
4522 header.PageLength = 0;
4523 header.PageNumber = 0;
4524 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4527 cfg.pageAddr = portnum;
4528 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4530 cfg.timeout = 0; /* use default */
4531 if (mpt_config(ioc, &cfg) != 0)
4534 if (header.PageLength > 0) {
4535 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4537 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4538 cfg.physAddr = buf_dma;
4539 if (mpt_config(ioc, &cfg) != 0) {
4540 ioc->spi_data.maxBusWidth = MPT_NARROW;
4541 ioc->spi_data.maxSyncOffset = 0;
4542 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4543 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4546 /* Save the Port Page 0 data
4548 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4549 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4550 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4552 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 )
4553 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4555 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4556 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4558 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4559 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4560 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4562 ioc->spi_data.maxSyncOffset = 0;
4563 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4566 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4568 /* Update the minSyncFactor based on bus type.
4570 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4571 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4573 if (ioc->spi_data.minSyncFactor < MPT_ULTRA)
4574 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4578 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4583 /* SCSI Port Page 2 - Read the header then the page.
4585 header.PageVersion = 0;
4586 header.PageLength = 0;
4587 header.PageNumber = 2;
4588 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4591 cfg.pageAddr = portnum;
4592 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4594 if (mpt_config(ioc, &cfg) != 0)
4597 if (header.PageLength > 0) {
4598 /* Allocate memory and read SCSI Port Page 2
4600 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4602 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4603 cfg.physAddr = buf_dma;
4604 if (mpt_config(ioc, &cfg) != 0) {
4605 /* Nvram data is left with INVALID mark
4609 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4610 MpiDeviceInfo_t *pdevice = NULL;
4612 /* Save the Port Page 2 data
4613 * (reformat into a 32bit quantity)
4615 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4616 ioc->spi_data.PortFlags = data;
4617 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4618 pdevice = &pPP2->DeviceSettings[ii];
4619 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4620 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4621 ioc->spi_data.nvram[ii] = data;
4625 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4629 /* Update Adapter limits with those from NVRAM
4630 * Comment: Don't need to do this. Target performance
4631 * parameters will never exceed the adapters limits.
4637 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4638 /* mpt_readScsiDevicePageHeaders - save version and length of SDP1
4639 * @ioc: Pointer to a Adapter Strucutre
4640 * @portnum: IOC port number
4642 * Return: -EFAULT if read of config page header fails
4646 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4649 ConfigPageHeader_t header;
4651 /* Read the SCSI Device Page 1 header
4653 header.PageVersion = 0;
4654 header.PageLength = 0;
4655 header.PageNumber = 1;
4656 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4659 cfg.pageAddr = portnum;
4660 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4663 if (mpt_config(ioc, &cfg) != 0)
4666 ioc->spi_data.sdp1version = cfg.hdr->PageVersion;
4667 ioc->spi_data.sdp1length = cfg.hdr->PageLength;
4669 header.PageVersion = 0;
4670 header.PageLength = 0;
4671 header.PageNumber = 0;
4672 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4673 if (mpt_config(ioc, &cfg) != 0)
4676 ioc->spi_data.sdp0version = cfg.hdr->PageVersion;
4677 ioc->spi_data.sdp0length = cfg.hdr->PageLength;
4679 dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
4680 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
4682 dcprintk((MYIOC_s_INFO_FMT "Headers: 1: version %d length %d\n",
4683 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
4687 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4689 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4690 * @ioc: Pointer to a Adapter Strucutre
4691 * @portnum: IOC port number
4695 * -EFAULT if read of config page header fails or data pointer not NULL
4696 * -ENOMEM if pci_alloc failed
4699 mpt_findImVolumes(MPT_ADAPTER *ioc)
4703 ConfigPageIoc2RaidVol_t *pIocRv;
4704 dma_addr_t ioc2_dma;
4706 ConfigPageHeader_t header;
4713 /* Read IOCP2 header then the page.
4715 header.PageVersion = 0;
4716 header.PageLength = 0;
4717 header.PageNumber = 2;
4718 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4722 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4725 if (mpt_config(ioc, &cfg) != 0)
4728 if (header.PageLength == 0)
4731 iocpage2sz = header.PageLength * 4;
4732 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
4736 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4737 cfg.physAddr = ioc2_dma;
4738 if (mpt_config(ioc, &cfg) != 0)
4741 if ( (mem = (u8 *)ioc->spi_data.pIocPg2) == NULL ) {
4742 mem = kmalloc(iocpage2sz, GFP_ATOMIC);
4744 ioc->spi_data.pIocPg2 = (IOCPage2_t *) mem;
4749 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
4751 /* Identify RAID Volume Id's */
4752 nVols = pIoc2->NumActiveVolumes;
4758 /* At least 1 RAID Volume
4760 pIocRv = pIoc2->RaidVolume;
4761 ioc->spi_data.isRaid = 0;
4762 for (jj = 0; jj < nVols; jj++, pIocRv++) {
4763 vid = pIocRv->VolumeID;
4764 vbus = pIocRv->VolumeBus;
4765 vioc = pIocRv->VolumeIOC;
4770 ioc->spi_data.isRaid |= (1 << vid);
4772 /* Error! Always bus 0
4778 /* Identify Hidden Physical Disk Id's */
4779 nPhys = pIoc2->NumActivePhysDisks;
4781 /* No physical disks.
4784 mpt_read_ioc_pg_3(ioc);
4788 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
4794 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
4799 ConfigPageHeader_t header;
4800 dma_addr_t ioc3_dma;
4803 /* Free the old page
4805 if (ioc->spi_data.pIocPg3) {
4806 kfree(ioc->spi_data.pIocPg3);
4807 ioc->spi_data.pIocPg3 = NULL;
4810 /* There is at least one physical disk.
4811 * Read and save IOC Page 3
4813 header.PageVersion = 0;
4814 header.PageLength = 0;
4815 header.PageNumber = 3;
4816 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4820 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4823 if (mpt_config(ioc, &cfg) != 0)
4826 if (header.PageLength == 0)
4829 /* Read Header good, alloc memory
4831 iocpage3sz = header.PageLength * 4;
4832 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
4836 /* Read the Page and save the data
4837 * into malloc'd memory.
4839 cfg.physAddr = ioc3_dma;
4840 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4841 if (mpt_config(ioc, &cfg) == 0) {
4842 mem = kmalloc(iocpage3sz, GFP_ATOMIC);
4844 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
4845 ioc->spi_data.pIocPg3 = (IOCPage3_t *) mem;
4849 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
4855 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
4859 ConfigPageHeader_t header;
4860 dma_addr_t ioc4_dma;
4863 /* Read and save IOC Page 4
4865 header.PageVersion = 0;
4866 header.PageLength = 0;
4867 header.PageNumber = 4;
4868 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4872 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4875 if (mpt_config(ioc, &cfg) != 0)
4878 if (header.PageLength == 0)
4881 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
4882 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
4883 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
4887 ioc4_dma = ioc->spi_data.IocPg4_dma;
4888 iocpage4sz = ioc->spi_data.IocPg4Sz;
4891 /* Read the Page into dma memory.
4893 cfg.physAddr = ioc4_dma;
4894 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4895 if (mpt_config(ioc, &cfg) == 0) {
4896 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
4897 ioc->spi_data.IocPg4_dma = ioc4_dma;
4898 ioc->spi_data.IocPg4Sz = iocpage4sz;
4900 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
4901 ioc->spi_data.pIocPg4 = NULL;
4906 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
4910 ConfigPageHeader_t header;
4911 dma_addr_t ioc1_dma;
4915 /* Check the Coalescing Timeout in IOC Page 1
4917 header.PageVersion = 0;
4918 header.PageLength = 0;
4919 header.PageNumber = 1;
4920 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4924 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4927 if (mpt_config(ioc, &cfg) != 0)
4930 if (header.PageLength == 0)
4933 /* Read Header good, alloc memory
4935 iocpage1sz = header.PageLength * 4;
4936 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
4940 /* Read the Page and check coalescing timeout
4942 cfg.physAddr = ioc1_dma;
4943 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4944 if (mpt_config(ioc, &cfg) == 0) {
4946 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
4947 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
4948 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
4950 dprintk((MYIOC_s_INFO_FMT "Coalescing Enabled Timeout = %d\n",
4953 if (tmp > MPT_COALESCING_TIMEOUT) {
4954 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
4956 /* Write NVRAM and current
4959 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4960 if (mpt_config(ioc, &cfg) == 0) {
4961 dprintk((MYIOC_s_INFO_FMT "Reset Current Coalescing Timeout to = %d\n",
4962 ioc->name, MPT_COALESCING_TIMEOUT));
4964 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
4965 if (mpt_config(ioc, &cfg) == 0) {
4966 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout to = %d\n",
4967 ioc->name, MPT_COALESCING_TIMEOUT));
4969 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout Failed\n",
4974 dprintk((MYIOC_s_WARN_FMT "Reset of Current Coalescing Timeout Failed!\n",
4980 dprintk((MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
4984 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
4989 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4991 * SendEventNotification - Send EventNotification (on or off) request
4993 * @ioc: Pointer to MPT_ADAPTER structure
4994 * @EvSwitch: Event switch flags
4997 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
4999 EventNotification_t *evnp;
5001 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc->id);
5003 dprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5007 memset(evnp, 0, sizeof(*evnp));
5009 dprintk((MYIOC_s_INFO_FMT "Sending EventNotification(%d)\n", ioc->name, EvSwitch));
5011 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5012 evnp->ChainOffset = 0;
5014 evnp->Switch = EvSwitch;
5016 mpt_put_msg_frame(mpt_base_index, ioc->id, (MPT_FRAME_HDR *)evnp);
5021 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5023 * SendEventAck - Send EventAck request to MPT adapter.
5024 * @ioc: Pointer to MPT_ADAPTER structure
5025 * @evnp: Pointer to original EventNotification request
5028 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5032 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc->id)) == NULL) {
5033 printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK request frame!\n",
5037 memset(pAck, 0, sizeof(*pAck));
5039 dprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
5041 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5042 pAck->ChainOffset = 0;
5044 pAck->Event = evnp->Event;
5045 pAck->EventContext = evnp->EventContext;
5047 mpt_put_msg_frame(mpt_base_index, ioc->id, (MPT_FRAME_HDR *)pAck);
5052 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5054 * mpt_config - Generic function to issue config message
5055 * @ioc - Pointer to an adapter structure
5056 * @cfg - Pointer to a configuration structure. Struct contains
5057 * action, page address, direction, physical address
5058 * and pointer to a configuration page header
5059 * Page header is updated.
5061 * Returns 0 for success
5062 * -EPERM if not allowed due to ISR context
5063 * -EAGAIN if no msg frames currently available
5064 * -EFAULT for non-successful reply or no reply (timeout)
5067 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5071 unsigned long flags;
5076 /* (Bugzilla:fibrebugs, #513)
5077 * Bug fix (part 1)! 20010905 -sralston
5078 * Prevent calling wait_event() (below), if caller happens
5079 * to be in ISR context, because that is fatal!
5081 in_isr = in_interrupt();
5083 dcprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5088 /* Get and Populate a free Frame
5090 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc->id)) == NULL) {
5091 dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5095 pReq = (Config_t *)mf;
5096 pReq->Action = pCfg->action;
5098 pReq->ChainOffset = 0;
5099 pReq->Function = MPI_FUNCTION_CONFIG;
5100 pReq->ExtPageLength = 0;
5101 pReq->ExtPageType = 0;
5103 for (ii=0; ii < 8; ii++)
5104 pReq->Reserved2[ii] = 0;
5106 pReq->Header.PageVersion = pCfg->hdr->PageVersion;
5107 pReq->Header.PageLength = pCfg->hdr->PageLength;
5108 pReq->Header.PageNumber = pCfg->hdr->PageNumber;
5109 pReq->Header.PageType = (pCfg->hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5110 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5112 /* Add a SGE to the config request.
5115 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5117 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5119 flagsLength |= pCfg->hdr->PageLength * 4;
5121 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5123 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5124 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5126 /* Append pCfg pointer to end of mf
5128 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5130 /* Initalize the timer
5132 init_timer(&pCfg->timer);
5133 pCfg->timer.data = (unsigned long) ioc;
5134 pCfg->timer.function = mpt_timer_expired;
5135 pCfg->wait_done = 0;
5137 /* Set the timer; ensure 10 second minimum */
5138 if (pCfg->timeout < 10)
5139 pCfg->timer.expires = jiffies + HZ*10;
5141 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5143 /* Add to end of Q, set timer and then issue this command */
5144 spin_lock_irqsave(&ioc->FreeQlock, flags);
5145 Q_ADD_TAIL(&ioc->configQ.head, &pCfg->linkage, Q_ITEM);
5146 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5148 add_timer(&pCfg->timer);
5149 mpt_put_msg_frame(mpt_base_index, ioc->id, mf);
5150 wait_event(mpt_waitq, pCfg->wait_done);
5152 /* mf has been freed - do not access */
5159 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5161 * mpt_toolbox - Generic function to issue toolbox message
5162 * @ioc - Pointer to an adapter structure
5163 * @cfg - Pointer to a toolbox structure. Struct contains
5164 * action, page address, direction, physical address
5165 * and pointer to a configuration page header
5166 * Page header is updated.
5168 * Returns 0 for success
5169 * -EPERM if not allowed due to ISR context
5170 * -EAGAIN if no msg frames currently available
5171 * -EFAULT for non-successful reply or no reply (timeout)
5174 mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5176 ToolboxIstwiReadWriteRequest_t *pReq;
5178 unsigned long flags;
5183 /* (Bugzilla:fibrebugs, #513)
5184 * Bug fix (part 1)! 20010905 -sralston
5185 * Prevent calling wait_event() (below), if caller happens
5186 * to be in ISR context, because that is fatal!
5188 in_isr = in_interrupt();
5190 dcprintk((MYIOC_s_WARN_FMT "toobox request not allowed in ISR context!\n",
5195 /* Get and Populate a free Frame
5197 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc->id)) == NULL) {
5198 dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n",
5202 pReq = (ToolboxIstwiReadWriteRequest_t *)mf;
5203 pReq->Tool = pCfg->action;
5205 pReq->ChainOffset = 0;
5206 pReq->Function = MPI_FUNCTION_TOOLBOX;
5207 pReq->Reserved1 = 0;
5208 pReq->Reserved2 = 0;
5210 pReq->Flags = pCfg->dir;
5212 pReq->Reserved3 = 0;
5213 pReq->NumAddressBytes = 0x01;
5214 pReq->Reserved4 = 0;
5215 pReq->DataLength = 0x04;
5216 pReq->DeviceAddr = 0xB0;
5220 pReq->Reserved5 = 0;
5222 /* Add a SGE to the config request.
5225 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | 4;
5227 mpt_add_sge((char *)&pReq->SGL, flagsLength, pCfg->physAddr);
5229 dcprintk((MYIOC_s_INFO_FMT "Sending Toolbox request, Tool=%x\n",
5230 ioc->name, pReq->Tool));
5232 /* Append pCfg pointer to end of mf
5234 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5236 /* Initalize the timer
5238 init_timer(&pCfg->timer);
5239 pCfg->timer.data = (unsigned long) ioc;
5240 pCfg->timer.function = mpt_timer_expired;
5241 pCfg->wait_done = 0;
5243 /* Set the timer; ensure 10 second minimum */
5244 if (pCfg->timeout < 10)
5245 pCfg->timer.expires = jiffies + HZ*10;
5247 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5249 /* Add to end of Q, set timer and then issue this command */
5250 spin_lock_irqsave(&ioc->FreeQlock, flags);
5251 Q_ADD_TAIL(&ioc->configQ.head, &pCfg->linkage, Q_ITEM);
5252 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5254 add_timer(&pCfg->timer);
5255 mpt_put_msg_frame(mpt_base_index, ioc->id, mf);
5256 wait_event(mpt_waitq, pCfg->wait_done);
5258 /* mf has been freed - do not access */
5265 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5267 * mpt_timer_expired - Call back for timer process.
5268 * Used only internal config functionality.
5269 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5272 mpt_timer_expired(unsigned long data)
5274 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5276 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name));
5278 /* Perform a FW reload */
5279 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5280 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5282 /* No more processing.
5283 * Hard reset clean-up will wake up
5284 * process and free all resources.
5286 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name));
5291 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5293 * mpt_ioc_reset - Base cleanup for hard reset
5294 * @ioc: Pointer to the adapter structure
5295 * @reset_phase: Indicates pre- or post-reset functionality
5297 * Remark: Free's resources with internally generated commands.
5300 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5303 unsigned long flags;
5305 dprintk((KERN_WARNING MYNAM
5306 ": IOC %s_reset routed to MPT base driver!\n",
5307 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5308 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5310 if (reset_phase == MPT_IOC_SETUP_RESET) {
5312 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5313 /* If the internal config Q is not empty -
5314 * delete timer. MF resources will be freed when
5315 * the FIFO's are primed.
5317 spin_lock_irqsave(&ioc->FreeQlock, flags);
5318 if (! Q_IS_EMPTY(&ioc->configQ)){
5319 pCfg = (CONFIGPARMS *)ioc->configQ.head;
5321 del_timer(&pCfg->timer);
5322 pCfg = (CONFIGPARMS *) (pCfg->linkage.forw);
5323 } while (pCfg != (CONFIGPARMS *)&ioc->configQ);
5325 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5330 /* Search the configQ for internal commands.
5331 * Flush the Q, and wake up all suspended threads.
5333 spin_lock_irqsave(&ioc->FreeQlock, flags);
5334 if (! Q_IS_EMPTY(&ioc->configQ)){
5335 pCfg = (CONFIGPARMS *)ioc->configQ.head;
5337 pNext = (CONFIGPARMS *) pCfg->linkage.forw;
5339 Q_DEL_ITEM(&pCfg->linkage);
5341 pCfg->status = MPT_CONFIG_ERROR;
5342 pCfg->wait_done = 1;
5343 wake_up(&mpt_waitq);
5346 } while (pCfg != (CONFIGPARMS *)&ioc->configQ);
5348 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5351 return 1; /* currently means nothing really */
5355 #ifdef CONFIG_PROC_FS /* { */
5356 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5358 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5360 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5362 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5364 * Returns 0 for success, non-zero for failure.
5367 procmpt_create(void)
5370 struct proc_dir_entry *ent;
5374 * BEWARE: If/when MPT_PROCFS_MPTBASEDIR changes from "mpt"
5375 * (single level) to multi level (e.g. "driver/message/fusion")
5376 * something here needs to change. -sralston
5378 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5379 if (mpt_proc_root_dir == NULL)
5382 for (ii=0; ii < MPT_PROC_ENTRIES; ii++) {
5383 ent = create_proc_entry(mpt_proc_list[ii].name,
5384 S_IFREG|S_IRUGO, mpt_proc_root_dir);
5386 printk(KERN_WARNING MYNAM
5387 ": WARNING - Could not create /proc/mpt/%s entry\n",
5388 mpt_proc_list[ii].name);
5391 ent->read_proc = mpt_proc_list[ii].f;
5395 ioc = mpt_adapter_find_first();
5396 while (ioc != NULL) {
5397 struct proc_dir_entry *dent;
5399 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
5401 if ((dent = proc_mkdir(ioc->name, mpt_proc_root_dir)) != NULL) {
5403 * And populate it with mpt_ioc_proc_list[] entries.
5405 for (ii=0; ii < MPT_IOC_PROC_ENTRIES; ii++) {
5406 ent = create_proc_entry(mpt_ioc_proc_list[ii].name,
5407 S_IFREG|S_IRUGO, dent);
5409 printk(KERN_WARNING MYNAM
5410 ": WARNING - Could not create /proc/mpt/%s/%s entry!\n",
5412 mpt_ioc_proc_list[ii].name);
5415 ent->read_proc = mpt_ioc_proc_list[ii].f;
5419 printk(MYIOC_s_WARN_FMT "Could not create /proc/mpt/%s subdir entry!\n",
5420 ioc->name, mpt_ioc_proc_list[ii].name);
5422 ioc = mpt_adapter_find_next(ioc);
5428 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5430 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5432 * Returns 0 for success, non-zero for failure.
5435 procmpt_destroy(void)
5440 if (!mpt_proc_root_dir)
5444 * BEWARE: If/when MPT_PROCFS_MPTBASEDIR changes from "mpt"
5445 * (single level) to multi level (e.g. "driver/message/fusion")
5446 * something here needs to change. -sralston
5449 ioc = mpt_adapter_find_first();
5450 while (ioc != NULL) {
5454 namelen = sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
5457 * Tear down each "/proc/mpt/iocN" subdirectory.
5459 for (ii=0; ii < MPT_IOC_PROC_ENTRIES; ii++) {
5460 (void) sprintf(pname+namelen, "/%s", mpt_ioc_proc_list[ii].name);
5461 remove_proc_entry(pname, NULL);
5463 remove_proc_entry(ioc->name, mpt_proc_root_dir);
5464 ioc = mpt_adapter_find_next(ioc);
5467 for (ii=0; ii < MPT_PROC_ENTRIES; ii++)
5468 remove_proc_entry(mpt_proc_list[ii].name, mpt_proc_root_dir);
5470 if (atomic_read((atomic_t *)&mpt_proc_root_dir->count) == 0) {
5471 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5472 mpt_proc_root_dir = NULL;
5479 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5481 * procmpt_summary_read - Handle read request from /proc/mpt/summary
5482 * or from /proc/mpt/iocN/summary.
5483 * @buf: Pointer to area to write information
5484 * @start: Pointer to start pointer
5485 * @offset: Offset to start writing
5487 * @eof: Pointer to EOF integer
5490 * Returns number of characters written to process performing the read.
5493 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5500 ioc = mpt_adapter_find_first();
5507 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5510 if ((out-buf) >= request) {
5515 ioc = mpt_adapter_find_next(ioc);
5517 ioc = NULL; /* force exit for iocN */
5521 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5524 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5526 * procmpt_version_read - Handle read request from /proc/mpt/version.
5527 * @buf: Pointer to area to write information
5528 * @start: Pointer to start pointer
5529 * @offset: Offset to start writing
5531 * @eof: Pointer to EOF integer
5534 * Returns number of characters written to process performing the read.
5537 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5540 int scsi, lan, ctl, targ, dmp;
5544 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5545 len += sprintf(buf+len, " Fusion MPT base driver\n");
5547 scsi = lan = ctl = targ = dmp = 0;
5548 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5550 if (MptCallbacks[ii]) {
5551 switch (MptDriverClass[ii]) {
5552 case MPTSCSIH_DRIVER:
5553 if (!scsi++) drvname = "SCSI host";
5556 if (!lan++) drvname = "LAN";
5559 if (!targ++) drvname = "SCSI target";
5562 if (!ctl++) drvname = "ioctl";
5565 if (!dmp++) drvname = "DMP";
5570 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5572 * Handle isense special case, because it
5573 * doesn't do a formal mpt_register call.
5575 if (isense_idx == ii)
5576 len += sprintf(buf+len, " Fusion MPT isense driver\n");
5580 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5583 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5585 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5586 * @buf: Pointer to area to write information
5587 * @start: Pointer to start pointer
5588 * @offset: Offset to start writing
5590 * @eof: Pointer to EOF integer
5593 * Returns number of characters written to process performing the read.
5596 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5598 MPT_ADAPTER *ioc = data;
5604 mpt_get_fw_exp_ver(expVer, ioc);
5606 len = sprintf(buf, "%s:", ioc->name);
5607 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5608 len += sprintf(buf+len, " (f/w download boot flag set)");
5609 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5610 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5612 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
5613 ioc->facts.ProductID,
5615 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5616 if (ioc->facts.FWImageSize)
5617 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5618 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5619 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5620 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
5622 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
5623 ioc->facts.CurrentHostMfaHighAddr);
5624 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
5625 ioc->facts.CurrentSenseBufferHighAddr);
5627 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5628 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5630 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5631 (void *)ioc->req_alloc, (void *)(ulong)ioc->req_alloc_dma);
5633 * Rounding UP to nearest 4-kB boundary here...
5635 sz = (ioc->req_sz * ioc->req_depth) + 128;
5636 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5637 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5638 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5639 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
5640 4*ioc->facts.RequestFrameSize,
5641 ioc->facts.GlobalCredits);
5643 len += sprintf(buf+len, " ReplyFrames @ 0x%p (Dma @ 0x%p)\n",
5644 (void *)ioc->reply_alloc, (void *)(ulong)ioc->reply_alloc_dma);
5645 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5646 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5647 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5648 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
5649 ioc->facts.CurReplyFrameSize,
5650 ioc->facts.ReplyQueueDepth);
5652 len += sprintf(buf+len, " MaxDevices = %d\n",
5653 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5654 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
5657 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5658 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
5660 ioc->facts.NumberOfPorts);
5661 if ((int)ioc->chip_type <= (int)FC929) {
5662 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5663 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5664 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5665 a[5], a[4], a[3], a[2], a[1], a[0]);
5667 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
5668 ioc->fc_port_page0[p].WWNN.High,
5669 ioc->fc_port_page0[p].WWNN.Low,
5670 ioc->fc_port_page0[p].WWPN.High,
5671 ioc->fc_port_page0[p].WWPN.Low);
5675 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5678 #endif /* CONFIG_PROC_FS } */
5680 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5682 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
5685 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
5686 sprintf(buf, " (Exp %02d%02d)",
5687 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
5688 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
5691 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
5692 strcat(buf, " [MDBG]");
5696 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5698 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5699 * @ioc: Pointer to MPT_ADAPTER structure
5700 * @buffer: Pointer to buffer where IOC summary info should be written
5701 * @size: Pointer to number of bytes we wrote (set by this routine)
5702 * @len: Offset at which to start writing in buffer
5703 * @showlan: Display LAN stuff?
5705 * This routine writes (english readable) ASCII text, which represents
5706 * a summary of IOC information, to a buffer.
5709 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
5714 mpt_get_fw_exp_ver(expVer, ioc);
5717 * Shorter summary of attached ioc's...
5719 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
5722 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
5723 ioc->facts.FWVersion.Word,
5725 ioc->facts.NumberOfPorts,
5728 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
5729 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5730 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
5731 a[5], a[4], a[3], a[2], a[1], a[0]);
5735 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
5737 y += sprintf(buffer+len+y, ", IRQ=%s", __irq_itoa(ioc->pci_irq));
5741 y += sprintf(buffer+len+y, " (disabled)");
5743 y += sprintf(buffer+len+y, "\n");
5748 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5752 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5754 * mpt_HardResetHandler - Generic reset handler, issue SCSI Task
5755 * Management call based on input arg values. If TaskMgmt fails,
5756 * return associated SCSI request.
5757 * @ioc: Pointer to MPT_ADAPTER structure
5758 * @sleepFlag: Indicates if sleep or schedule must be called.
5760 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
5761 * or a non-interrupt thread. In the former, must not call schedule().
5763 * Remark: A return of -1 is a FATAL error case, as it means a
5764 * FW reload/initialization failed.
5766 * Returns 0 for SUCCESS or -1 if FAILED.
5769 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5772 unsigned long flags;
5774 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
5776 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
5777 printk("MF count 0x%x !\n", ioc->mfcnt);
5780 /* Reset the adapter. Prevent more than 1 call to
5781 * mpt_do_ioc_recovery at any instant in time.
5783 spin_lock_irqsave(&ioc->diagLock, flags);
5784 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
5785 spin_unlock_irqrestore(&ioc->diagLock, flags);
5788 ioc->diagPending = 1;
5790 spin_unlock_irqrestore(&ioc->diagLock, flags);
5792 /* FIXME: If do_ioc_recovery fails, repeat....
5795 /* The SCSI driver needs to adjust timeouts on all current
5796 * commands prior to the diagnostic reset being issued.
5797 * Prevents timeouts occuring during a diagnostic reset...very bad.
5798 * For all other protocol drivers, this is a no-op.
5804 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5805 if (MptResetHandlers[ii]) {
5806 dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
5808 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_SETUP_RESET);
5810 dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
5811 ioc->name, ioc->alt_ioc->name, ii));
5812 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_SETUP_RESET);
5818 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
5819 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
5824 ioc->alt_ioc->reload_fw = 0;
5826 spin_lock_irqsave(&ioc->diagLock, flags);
5827 ioc->diagPending = 0;
5829 ioc->alt_ioc->diagPending = 0;
5830 spin_unlock_irqrestore(&ioc->diagLock, flags);
5832 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
5837 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5839 EventDescriptionStr(u8 event, u32 evData0)
5844 case MPI_EVENT_NONE:
5847 case MPI_EVENT_LOG_DATA:
5850 case MPI_EVENT_STATE_CHANGE:
5851 ds = "State Change";
5853 case MPI_EVENT_UNIT_ATTENTION:
5854 ds = "Unit Attention";
5856 case MPI_EVENT_IOC_BUS_RESET:
5857 ds = "IOC Bus Reset";
5859 case MPI_EVENT_EXT_BUS_RESET:
5860 ds = "External Bus Reset";
5862 case MPI_EVENT_RESCAN:
5863 ds = "Bus Rescan Event";
5864 /* Ok, do we need to do anything here? As far as
5865 I can tell, this is when a new device gets added
5868 case MPI_EVENT_LINK_STATUS_CHANGE:
5869 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
5870 ds = "Link Status(FAILURE) Change";
5872 ds = "Link Status(ACTIVE) Change";
5874 case MPI_EVENT_LOOP_STATE_CHANGE:
5875 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
5876 ds = "Loop State(LIP) Change";
5877 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
5878 ds = "Loop State(LPE) Change"; /* ??? */
5880 ds = "Loop State(LPB) Change"; /* ??? */
5882 case MPI_EVENT_LOGOUT:
5885 case MPI_EVENT_EVENT_CHANGE:
5887 ds = "Events(ON) Change";
5889 ds = "Events(OFF) Change";
5891 case MPI_EVENT_INTEGRATED_RAID:
5892 ds = "Integrated Raid";
5895 * MPT base "custom" events may be added here...
5904 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5906 * ProcessEventNotification - Route a received EventNotificationReply to
5907 * all currently regeistered event handlers.
5908 * @ioc: Pointer to MPT_ADAPTER structure
5909 * @pEventReply: Pointer to EventNotification reply frame
5910 * @evHandlers: Pointer to integer, number of event handlers
5912 * Returns sum of event handlers return values.
5915 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
5927 * Do platform normalization of values
5929 event = le32_to_cpu(pEventReply->Event) & 0xFF;
5930 // evCtx = le32_to_cpu(pEventReply->EventContext);
5931 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
5933 evData0 = le32_to_cpu(pEventReply->Data[0]);
5936 evStr = EventDescriptionStr(event, evData0);
5937 dprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n",
5942 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_EVENTS)
5943 printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
5944 for (ii = 0; ii < evDataLen; ii++)
5945 printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
5950 * Do general / base driver event processing
5953 case MPI_EVENT_NONE: /* 00 */
5954 case MPI_EVENT_LOG_DATA: /* 01 */
5955 case MPI_EVENT_STATE_CHANGE: /* 02 */
5956 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
5957 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
5958 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
5959 case MPI_EVENT_RESCAN: /* 06 */
5960 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
5961 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
5962 case MPI_EVENT_LOGOUT: /* 09 */
5963 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
5964 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE: /* 0C */
5967 case MPI_EVENT_EVENT_CHANGE: /* 0A */
5969 u8 evState = evData0 & 0xFF;
5971 /* CHECKME! What if evState unexpectedly says OFF (0)? */
5973 /* Update EventState field in cached IocFacts */
5974 if (ioc->facts.Function) {
5975 ioc->facts.EventState = evState;
5982 * Should this event be logged? Events are written sequentially.
5983 * When buffer is full, start again at the top.
5985 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
5988 idx = ioc->eventContext % ioc->eventLogSize;
5990 ioc->events[idx].event = event;
5991 ioc->events[idx].eventContext = ioc->eventContext;
5993 for (ii = 0; ii < 2; ii++) {
5995 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
5997 ioc->events[idx].data[ii] = 0;
6000 ioc->eventContext++;
6005 * Call each currently registered protocol event handler.
6007 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
6008 if (MptEvHandlers[ii]) {
6009 dprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
6011 r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
6015 /* FIXME? Examine results here? */
6018 * If needed, send (a single) EventAck.
6020 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6021 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6022 printk(MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
6027 *evHandlers = handlers;
6031 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6033 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6034 * @ioc: Pointer to MPT_ADAPTER structure
6035 * @log_info: U32 LogInfo reply word from the IOC
6037 * Refer to lsi/fc_log.h.
6040 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6042 static char *subcl_str[8] = {
6043 "FCP Initiator", "FCP Target", "LAN", "MPI Message Layer",
6044 "FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
6046 u8 subcl = (log_info >> 24) & 0x7;
6047 // u32 SubCl = log_info & 0x27000000;
6049 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}",
6050 ioc->name, log_info, subcl_str[subcl]);
6053 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6055 * mpt_sp_log_info - Log information returned from SCSI Parallel IOC.
6056 * @ioc: Pointer to MPT_ADAPTER structure
6057 * @mr: Pointer to MPT reply frame
6058 * @log_info: U32 LogInfo word from the IOC
6060 * Refer to lsi/sp_log.h.
6063 mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
6065 u32 info = log_info & 0x00FF0000;
6066 char *desc = "unknown";
6070 desc = "bug! MID not found";
6071 if (ioc->reload_fw == 0)
6076 desc = "Parity Error";
6080 desc = "ASYNC Outbound Overrun";
6084 desc = "SYNC Offset Error";
6092 desc = "Msg In Overflow";
6100 desc = "Outbound DMA Overrun";
6104 desc = "Task Management";
6108 desc = "Device Problem";
6112 desc = "Invalid Phase Change";
6116 desc = "Untagged Table Size";
6121 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6124 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6126 * mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
6127 * @ioc: Pointer to MPT_ADAPTER structure
6128 * @ioc_status: U32 IOCStatus word from IOC
6129 * @mf: Pointer to MPT request frame
6131 * Refer to lsi/mpi.h.
6134 mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
6136 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
6140 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
6141 desc = "Invalid Function";
6144 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
6148 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
6149 desc = "Invalid SGL";
6152 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
6153 desc = "Internal Error";
6156 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
6160 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
6161 desc = "Insufficient Resources";
6164 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
6165 desc = "Invalid Field";
6168 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
6169 desc = "Invalid State";
6172 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
6173 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
6174 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
6175 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
6176 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
6177 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
6178 /* No message for Config IOCStatus values */
6181 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
6182 /* No message for recovered error
6183 desc = "SCSI Recovered Error";
6187 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
6188 desc = "SCSI Invalid Bus";
6191 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
6192 desc = "SCSI Invalid TargetID";
6195 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
6197 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
6198 U8 cdb = pScsiReq->CDB[0];
6199 if (cdb != 0x12) { /* Inquiry is issued for device scanning */
6200 desc = "SCSI Device Not There";
6205 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
6206 desc = "SCSI Data Overrun";
6209 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
6210 /* This error is checked in scsi_io_done(). Skip.
6211 desc = "SCSI Data Underrun";
6215 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
6216 desc = "SCSI I/O Data Error";
6219 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
6220 desc = "SCSI Protocol Error";
6223 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
6224 desc = "SCSI Task Terminated";
6227 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
6228 desc = "SCSI Residual Mismatch";
6231 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
6232 desc = "SCSI Task Management Failed";
6235 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
6236 desc = "SCSI IOC Terminated";
6239 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
6240 desc = "SCSI Ext Terminated";
6248 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc);
6251 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6253 * mpt_register_ascqops_strings - Register SCSI ASC/ASCQ and SCSI
6254 * OpCode strings from the (optional) isense module.
6255 * @ascqTable: Pointer to ASCQ_Table_t structure
6256 * @ascqtbl_sz: Number of entries in ASCQ_Table
6257 * @opsTable: Pointer to array of SCSI OpCode strings (char pointers)
6259 * Specialized driver registration routine for the isense driver.
6262 mpt_register_ascqops_strings(void *ascqTable, int ascqtbl_sz, const char **opsTable)
6266 if (ascqTable && ascqtbl_sz && opsTable) {
6267 mpt_v_ASCQ_TablePtr = ascqTable;
6268 mpt_ASCQ_TableSz = ascqtbl_sz;
6269 mpt_ScsiOpcodesPtr = opsTable;
6270 printk(KERN_INFO MYNAM ": English readable SCSI-3 strings enabled:-)\n");
6271 isense_idx = last_drv_idx;
6277 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6279 * mpt_deregister_ascqops_strings - Deregister SCSI ASC/ASCQ and SCSI
6280 * OpCode strings from the isense driver.
6282 * Specialized driver deregistration routine for the isense driver.
6285 mpt_deregister_ascqops_strings(void)
6287 mpt_v_ASCQ_TablePtr = NULL;
6288 mpt_ASCQ_TableSz = 0;
6289 mpt_ScsiOpcodesPtr = NULL;
6290 printk(KERN_INFO MYNAM ": English readable SCSI-3 strings disabled)-:\n");
6294 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6296 EXPORT_SYMBOL(mpt_adapters);
6297 EXPORT_SYMBOL(mpt_proc_root_dir);
6298 EXPORT_SYMBOL(DmpService);
6299 EXPORT_SYMBOL(mpt_register);
6300 EXPORT_SYMBOL(mpt_deregister);
6301 EXPORT_SYMBOL(mpt_event_register);
6302 EXPORT_SYMBOL(mpt_event_deregister);
6303 EXPORT_SYMBOL(mpt_reset_register);
6304 EXPORT_SYMBOL(mpt_reset_deregister);
6305 EXPORT_SYMBOL(mpt_device_driver_register);
6306 EXPORT_SYMBOL(mpt_device_driver_deregister);
6307 EXPORT_SYMBOL(mpt_get_msg_frame);
6308 EXPORT_SYMBOL(mpt_put_msg_frame);
6309 EXPORT_SYMBOL(mpt_free_msg_frame);
6310 EXPORT_SYMBOL(mpt_add_sge);
6311 EXPORT_SYMBOL(mpt_add_chain);
6312 EXPORT_SYMBOL(mpt_send_handshake_request);
6313 EXPORT_SYMBOL(mpt_handshake_req_reply_wait);
6314 EXPORT_SYMBOL(mpt_adapter_find_first);
6315 EXPORT_SYMBOL(mpt_adapter_find_next);
6316 EXPORT_SYMBOL(mpt_verify_adapter);
6317 EXPORT_SYMBOL(mpt_GetIocState);
6318 EXPORT_SYMBOL(mpt_print_ioc_summary);
6319 EXPORT_SYMBOL(mpt_lan_index);
6320 EXPORT_SYMBOL(mpt_stm_index);
6321 EXPORT_SYMBOL(mpt_HardResetHandler);
6322 EXPORT_SYMBOL(mpt_config);
6323 EXPORT_SYMBOL(mpt_toolbox);
6324 EXPORT_SYMBOL(mpt_findImVolumes);
6325 EXPORT_SYMBOL(mpt_read_ioc_pg_3);
6326 EXPORT_SYMBOL(mpt_alloc_fw_memory);
6327 EXPORT_SYMBOL(mpt_free_fw_memory);
6329 EXPORT_SYMBOL(mpt_register_ascqops_strings);
6330 EXPORT_SYMBOL(mpt_deregister_ascqops_strings);
6331 EXPORT_SYMBOL(mpt_v_ASCQ_TablePtr);
6332 EXPORT_SYMBOL(mpt_ASCQ_TableSz);
6333 EXPORT_SYMBOL(mpt_ScsiOpcodesPtr);
6336 static struct pci_driver mptbase_driver = {
6338 .id_table = mptbase_pci_table,
6339 .probe = mptbase_probe,
6340 .remove = __devexit_p(mptbase_remove),
6342 .shutdown = mptbase_shutdown,
6345 .suspend = mptbase_suspend,
6346 .resume = mptbase_resume,
6350 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6352 * fusion_init - Fusion MPT base driver initialization routine.
6354 * Returns 0 for success, non-zero for failure.
6362 if (FusionInitCalled++) {
6363 dprintk((KERN_INFO MYNAM ": INFO - Driver late-init entry point called\n"));
6367 show_mptmod_ver(my_NAME, my_VERSION);
6368 printk(KERN_INFO COPYRIGHT "\n");
6370 Q_INIT(&MptAdapters, MPT_ADAPTER); /* set to empty */
6371 for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
6372 MptCallbacks[i] = NULL;
6373 MptDriverClass[i] = MPTUNKNOWN_DRIVER;
6374 MptEvHandlers[i] = NULL;
6375 MptResetHandlers[i] = NULL;
6380 /* NEW! 20010120 -sralston
6381 * Register ourselves (mptbase) in order to facilitate
6382 * EventNotification handling.
6384 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
6386 /* Register for hard reset handling callbacks.
6388 if (mpt_reset_register(mpt_base_index, mpt_ioc_reset) == 0) {
6389 dprintk((KERN_INFO MYNAM ": Register for IOC reset notification\n"));
6394 r = pci_module_init(&mptbase_driver);
6398 #ifdef CONFIG_PROC_FS
6399 (void) procmpt_create();
6405 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6407 * fusion_exit - Perform driver unload cleanup.
6409 * This routine frees all resources associated with each MPT adapter
6410 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
6416 dprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
6418 /* Whups? 20010120 -sralston
6419 * Moved this *above* removal of all MptAdapters!
6421 #ifdef CONFIG_PROC_FS
6422 (void) procmpt_destroy();
6424 pci_unregister_driver(&mptbase_driver);
6425 mpt_reset_deregister(mpt_base_index);
6429 module_init(fusion_init);
6430 module_exit(fusion_exit);