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 (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1315 /* Get I/O space! */
1316 port = pci_resource_start(pdev, ii);
1317 psize = pci_resource_len(pdev,ii);
1320 mem_phys = pci_resource_start(pdev, ii);
1321 msize = pci_resource_len(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 synchronize_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, ioc->reply_alloc,
3803 (void *)(ulong)ioc->reply_alloc_dma, reply_buffer_sz));
3805 b = (unsigned long) ioc->reply_alloc;
3806 b = (b + (0x80UL - 1UL)) & ~(0x80UL - 1UL); /* round up to 128-byte boundary */
3807 aligned_mem = (u8 *) b;
3808 ioc->reply_frames = (MPT_FRAME_HDR *) aligned_mem;
3809 ioc->reply_frames_dma =
3810 (ioc->reply_alloc_dma + (aligned_mem - ioc->reply_alloc));
3812 ioc->reply_frames_low_dma = (u32) (ioc->reply_frames_dma & 0xFFFFFFFF);
3814 /* Request FIFO - WE manage this! */
3815 dprintk((KERN_INFO MYNAM ": %s.req_alloc @ %p[%p], sz=%d bytes\n",
3816 ioc->name, ioc->req_alloc,
3817 (void *)(ulong)ioc->req_alloc_dma, request_buffer_sz));
3819 b = (unsigned long) ioc->req_alloc;
3820 b = (b + (0x80UL - 1UL)) & ~(0x80UL - 1UL); /* round up to 128-byte boundary */
3821 aligned_mem = (u8 *) b;
3822 ioc->req_frames = (MPT_FRAME_HDR *) aligned_mem;
3823 ioc->req_frames_dma =
3824 (ioc->req_alloc_dma + (aligned_mem - ioc->req_alloc));
3826 ioc->req_frames_low_dma = (u32) (ioc->req_frames_dma & 0xFFFFFFFF);
3828 #if defined(CONFIG_MTRR) && 0
3830 * Enable Write Combining MTRR for IOC's memory region.
3831 * (at least as much as we can; "size and base must be
3832 * multiples of 4 kiB"
3834 ioc->mtrr_reg = mtrr_add(ioc->fifo_pool,
3836 MTRR_TYPE_WRCOMB, 1);
3837 dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
3838 ioc->name, ioc->fifo_pool, ioc->fifo_pool_sz));
3841 } /* ioc->fifo_pool == NULL */
3843 /* Post Reply frames to FIFO
3845 aligned_mem_dma = ioc->reply_frames_dma;
3846 dprintk((KERN_INFO MYNAM ": %s.reply_frames @ %p[%p]\n",
3847 ioc->name, ioc->reply_frames, (void *)(ulong)aligned_mem_dma));
3849 for (i = 0; i < ioc->reply_depth; i++) {
3850 /* Write each address to the IOC! */
3851 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, aligned_mem_dma);
3852 aligned_mem_dma += ioc->reply_sz;
3856 /* Initialize Request frames linked list
3858 aligned_mem_dma = ioc->req_frames_dma;
3859 aligned_mem = (u8 *) ioc->req_frames;
3860 dprintk((KERN_INFO MYNAM ": %s.req_frames @ %p[%p]\n",
3861 ioc->name, aligned_mem, (void *)(ulong)aligned_mem_dma));
3863 spin_lock_irqsave(&ioc->FreeQlock, flags);
3864 Q_INIT(&ioc->FreeQ, MPT_FRAME_HDR);
3865 for (i = 0; i < ioc->req_depth; i++) {
3866 mf = (MPT_FRAME_HDR *) aligned_mem;
3868 /* Queue REQUESTs *internally*! */
3869 Q_ADD_TAIL(&ioc->FreeQ.head, &mf->u.frame.linkage, MPT_FRAME_HDR);
3870 aligned_mem += ioc->req_sz;
3872 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3875 if (ioc->sense_buf_pool == NULL) {
3876 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3877 ioc->sense_buf_pool =
3878 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3879 if (ioc->sense_buf_pool == NULL)
3882 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
3883 ioc->alloc_total += sz;
3889 if (ioc->fifo_pool != NULL) {
3890 pci_free_consistent(ioc->pcidev,
3892 ioc->fifo_pool, ioc->fifo_pool_dma);
3893 ioc->reply_frames = NULL;
3894 ioc->reply_alloc = NULL;
3895 ioc->req_frames = NULL;
3896 ioc->req_alloc = NULL;
3897 ioc->chain_alloc = NULL;
3898 ioc->fifo_pool = NULL;
3899 ioc->alloc_total -= ioc->fifo_pool_sz;
3900 #if defined(CONFIG_MTRR) && 0
3901 if (ioc->mtrr_reg > 0) {
3902 mtrr_del(ioc->mtrr_reg, 0, 0);
3903 dprintk((MYIOC_s_INFO_FMT "MTRR region de-registered\n",
3908 if (ioc->sense_buf_pool != NULL) {
3909 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3910 pci_free_consistent(ioc->pcidev,
3912 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
3913 ioc->sense_buf_pool = NULL;
3918 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3920 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3921 * from IOC via doorbell handshake method.
3922 * @ioc: Pointer to MPT_ADAPTER structure
3923 * @reqBytes: Size of the request in bytes
3924 * @req: Pointer to MPT request frame
3925 * @replyBytes: Expected size of the reply in bytes
3926 * @u16reply: Pointer to area where reply should be written
3927 * @maxwait: Max wait time for a reply (in seconds)
3928 * @sleepFlag: Specifies whether the process can sleep
3930 * NOTES: It is the callers responsibility to byte-swap fields in the
3931 * request which are greater than 1 byte in size. It is also the
3932 * callers responsibility to byte-swap response fields which are
3933 * greater than 1 byte in size.
3935 * Returns 0 for success, non-zero for failure.
3938 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
3939 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
3941 MPIDefaultReply_t *mptReply;
3946 * Get ready to cache a handshake reply
3948 ioc->hs_reply_idx = 0;
3949 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3950 mptReply->MsgLength = 0;
3953 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
3954 * then tell IOC that we want to handshake a request of N words.
3955 * (WRITE u32val to Doorbell reg).
3957 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3958 CHIPREG_WRITE32(&ioc->chip->Doorbell,
3959 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
3960 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
3963 * Wait for IOC's doorbell handshake int
3965 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3968 dhsprintk((MYIOC_s_INFO_FMT "HandShake request start, WaitCnt=%d%s\n",
3969 ioc->name, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3971 /* Read doorbell and check for active bit */
3972 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
3976 * Clear doorbell int (WRITE 0 to IntStatus reg),
3977 * then wait for IOC to ACKnowledge that it's ready for
3978 * our handshake request.
3980 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3981 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3986 u8 *req_as_bytes = (u8 *) req;
3989 * Stuff request words via doorbell handshake,
3990 * with ACK from IOC for each.
3992 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
3993 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
3994 (req_as_bytes[(ii*4) + 1] << 8) |
3995 (req_as_bytes[(ii*4) + 2] << 16) |
3996 (req_as_bytes[(ii*4) + 3] << 24));
3998 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
3999 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4003 dmfprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
4004 DBG_DUMP_REQUEST_FRAME_HDR(req)
4006 dhsprintk((MYIOC_s_INFO_FMT "HandShake request post done, WaitCnt=%d%s\n",
4007 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4010 * Wait for completion of doorbell handshake reply from the IOC
4012 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4016 * Copy out the cached reply...
4018 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4019 u16reply[ii] = ioc->hs_reply[ii];
4027 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4029 * WaitForDoorbellAck - Wait for IOC to clear the IOP_DOORBELL_STATUS bit
4030 * in it's IntStatus register.
4031 * @ioc: Pointer to MPT_ADAPTER structure
4032 * @howlong: How long to wait (in seconds)
4033 * @sleepFlag: Specifies whether the process can sleep
4035 * This routine waits (up to ~2 seconds max) for IOC doorbell
4036 * handshake ACKnowledge.
4038 * Returns a negative value on failure, else wait loop count.
4041 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4047 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
4049 if (sleepFlag == CAN_SLEEP) {
4051 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4052 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4054 set_current_state(TASK_INTERRUPTIBLE);
4055 schedule_timeout(1);
4060 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4061 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4069 dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (cnt=%d)\n",
4074 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout(%d)!\n",
4075 ioc->name, (count+5)/HZ);
4079 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4081 * WaitForDoorbellInt - Wait for IOC to set the HIS_DOORBELL_INTERRUPT bit
4082 * in it's IntStatus register.
4083 * @ioc: Pointer to MPT_ADAPTER structure
4084 * @howlong: How long to wait (in seconds)
4085 * @sleepFlag: Specifies whether the process can sleep
4087 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt.
4089 * Returns a negative value on failure, else wait loop count.
4092 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4098 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
4099 if (sleepFlag == CAN_SLEEP) {
4101 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4102 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4104 set_current_state(TASK_INTERRUPTIBLE);
4105 schedule_timeout(1);
4110 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4111 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4119 dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d)\n",
4124 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout(%d)!\n",
4125 ioc->name, (count+5)/HZ);
4129 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4131 * WaitForDoorbellReply - Wait for and capture a IOC handshake reply.
4132 * @ioc: Pointer to MPT_ADAPTER structure
4133 * @howlong: How long to wait (in seconds)
4134 * @sleepFlag: Specifies whether the process can sleep
4136 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4137 * Reply is cached to IOC private area large enough to hold a maximum
4138 * of 128 bytes of reply data.
4140 * Returns a negative value on failure, else size of reply in WORDS.
4143 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4148 u16 *hs_reply = ioc->hs_reply;
4149 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4152 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4155 * Get first two u16's so we can look at IOC's intended reply MsgLength
4158 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4161 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4162 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4163 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4166 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4167 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4171 dhsprintk((MYIOC_s_INFO_FMT "First handshake reply word=%08x%s\n",
4172 ioc->name, le32_to_cpu(*(u32 *)hs_reply),
4173 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4176 * If no error (and IOC said MsgLength is > 0), piece together
4177 * reply 16 bits at a time.
4179 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4180 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4182 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4183 /* don't overflow our IOC hs_reply[] buffer! */
4184 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4185 hs_reply[u16cnt] = hword;
4186 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4189 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4191 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4194 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4199 else if (u16cnt != (2 * mptReply->MsgLength)) {
4202 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4207 dmfprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
4208 DBG_DUMP_REPLY_FRAME(mptReply)
4210 dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY (sz=%d)\n",
4211 ioc->name, u16cnt/2));
4215 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4217 * GetLanConfigPages - Fetch LANConfig pages.
4218 * @ioc: Pointer to MPT_ADAPTER structure
4220 * Return: 0 for success
4221 * -ENOMEM if no memory available
4222 * -EPERM if not allowed due to ISR context
4223 * -EAGAIN if no msg frames currently available
4224 * -EFAULT for non-successful reply or no reply (timeout)
4227 GetLanConfigPages(MPT_ADAPTER *ioc)
4229 ConfigPageHeader_t hdr;
4231 LANPage0_t *ppage0_alloc;
4232 dma_addr_t page0_dma;
4233 LANPage1_t *ppage1_alloc;
4234 dma_addr_t page1_dma;
4239 /* Get LAN Page 0 header */
4240 hdr.PageVersion = 0;
4243 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4246 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4251 if ((rc = mpt_config(ioc, &cfg)) != 0)
4254 if (hdr.PageLength > 0) {
4255 data_sz = hdr.PageLength * 4;
4256 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4259 memset((u8 *)ppage0_alloc, 0, data_sz);
4260 cfg.physAddr = page0_dma;
4261 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4263 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4265 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4266 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4270 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4273 * Normalize endianness of structure data,
4274 * by byte-swapping all > 1 byte fields!
4283 /* Get LAN Page 1 header */
4284 hdr.PageVersion = 0;
4287 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4290 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4294 if ((rc = mpt_config(ioc, &cfg)) != 0)
4297 if (hdr.PageLength == 0)
4300 data_sz = hdr.PageLength * 4;
4302 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4304 memset((u8 *)ppage1_alloc, 0, data_sz);
4305 cfg.physAddr = page1_dma;
4306 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4308 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4310 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4311 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4314 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4317 * Normalize endianness of structure data,
4318 * by byte-swapping all > 1 byte fields!
4326 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4328 * GetFcPortPage0 - Fetch FCPort config Page0.
4329 * @ioc: Pointer to MPT_ADAPTER structure
4330 * @portnum: IOC Port number
4332 * Return: 0 for success
4333 * -ENOMEM if no memory available
4334 * -EPERM if not allowed due to ISR context
4335 * -EAGAIN if no msg frames currently available
4336 * -EFAULT for non-successful reply or no reply (timeout)
4339 GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
4341 ConfigPageHeader_t hdr;
4343 FCPortPage0_t *ppage0_alloc;
4344 FCPortPage0_t *pp0dest;
4345 dma_addr_t page0_dma;
4350 /* Get FCPort Page 0 header */
4351 hdr.PageVersion = 0;
4354 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
4357 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4359 cfg.pageAddr = portnum;
4362 if ((rc = mpt_config(ioc, &cfg)) != 0)
4365 if (hdr.PageLength == 0)
4368 data_sz = hdr.PageLength * 4;
4370 ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4372 memset((u8 *)ppage0_alloc, 0, data_sz);
4373 cfg.physAddr = page0_dma;
4374 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4376 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4378 pp0dest = &ioc->fc_port_page0[portnum];
4379 copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
4380 memcpy(pp0dest, ppage0_alloc, copy_sz);
4383 * Normalize endianness of structure data,
4384 * by byte-swapping all > 1 byte fields!
4386 pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
4387 pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
4388 pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
4389 pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
4390 pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
4391 pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
4392 pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
4393 pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
4394 pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
4395 pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
4396 pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
4397 pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
4398 pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
4399 pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
4400 pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
4401 pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
4405 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4411 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4413 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4414 * @ioc: Pointer to MPT_ADAPTER structure
4416 * Returns: 0 for success
4417 * -ENOMEM if no memory available
4418 * -EPERM if not allowed due to ISR context
4419 * -EAGAIN if no msg frames currently available
4420 * -EFAULT for non-successful reply or no reply (timeout)
4423 GetIoUnitPage2(MPT_ADAPTER *ioc)
4425 ConfigPageHeader_t hdr;
4427 IOUnitPage2_t *ppage_alloc;
4428 dma_addr_t page_dma;
4432 /* Get the page header */
4433 hdr.PageVersion = 0;
4436 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4439 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4444 if ((rc = mpt_config(ioc, &cfg)) != 0)
4447 if (hdr.PageLength == 0)
4450 /* Read the config page */
4451 data_sz = hdr.PageLength * 4;
4453 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4455 memset((u8 *)ppage_alloc, 0, data_sz);
4456 cfg.physAddr = page_dma;
4457 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4459 /* If Good, save data */
4460 if ((rc = mpt_config(ioc, &cfg)) == 0)
4461 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4463 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4469 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4470 /* mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4471 * @ioc: Pointer to a Adapter Strucutre
4472 * @portnum: IOC port number
4474 * Return: -EFAULT if read of config page header fails
4476 * If read of SCSI Port Page 0 fails,
4477 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4478 * Adapter settings: async, narrow
4480 * If read of SCSI Port Page 2 fails,
4481 * Adapter settings valid
4482 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4487 * CHECK - what type of locking mechanisms should be used????
4490 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4495 ConfigPageHeader_t header;
4501 if (!ioc->spi_data.nvram) {
4504 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4505 mem = kmalloc(sz, GFP_ATOMIC);
4509 ioc->spi_data.nvram = (int *) mem;
4511 dprintk((MYIOC_s_INFO_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4512 ioc->name, ioc->spi_data.nvram, sz));
4515 /* Invalidate NVRAM information
4517 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4518 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4521 /* Read SPP0 header, allocate memory, then read page.
4523 header.PageVersion = 0;
4524 header.PageLength = 0;
4525 header.PageNumber = 0;
4526 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4529 cfg.pageAddr = portnum;
4530 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4532 cfg.timeout = 0; /* use default */
4533 if (mpt_config(ioc, &cfg) != 0)
4536 if (header.PageLength > 0) {
4537 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4539 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4540 cfg.physAddr = buf_dma;
4541 if (mpt_config(ioc, &cfg) != 0) {
4542 ioc->spi_data.maxBusWidth = MPT_NARROW;
4543 ioc->spi_data.maxSyncOffset = 0;
4544 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4545 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4548 /* Save the Port Page 0 data
4550 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4551 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4552 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4554 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 )
4555 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4557 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4558 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4560 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4561 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4562 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4564 ioc->spi_data.maxSyncOffset = 0;
4565 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4568 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4570 /* Update the minSyncFactor based on bus type.
4572 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4573 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4575 if (ioc->spi_data.minSyncFactor < MPT_ULTRA)
4576 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4580 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4585 /* SCSI Port Page 2 - Read the header then the page.
4587 header.PageVersion = 0;
4588 header.PageLength = 0;
4589 header.PageNumber = 2;
4590 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4593 cfg.pageAddr = portnum;
4594 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4596 if (mpt_config(ioc, &cfg) != 0)
4599 if (header.PageLength > 0) {
4600 /* Allocate memory and read SCSI Port Page 2
4602 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4604 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4605 cfg.physAddr = buf_dma;
4606 if (mpt_config(ioc, &cfg) != 0) {
4607 /* Nvram data is left with INVALID mark
4611 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4612 MpiDeviceInfo_t *pdevice = NULL;
4614 /* Save the Port Page 2 data
4615 * (reformat into a 32bit quantity)
4617 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4618 ioc->spi_data.PortFlags = data;
4619 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4620 pdevice = &pPP2->DeviceSettings[ii];
4621 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4622 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4623 ioc->spi_data.nvram[ii] = data;
4627 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4631 /* Update Adapter limits with those from NVRAM
4632 * Comment: Don't need to do this. Target performance
4633 * parameters will never exceed the adapters limits.
4639 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4640 /* mpt_readScsiDevicePageHeaders - save version and length of SDP1
4641 * @ioc: Pointer to a Adapter Strucutre
4642 * @portnum: IOC port number
4644 * Return: -EFAULT if read of config page header fails
4648 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4651 ConfigPageHeader_t header;
4653 /* Read the SCSI Device Page 1 header
4655 header.PageVersion = 0;
4656 header.PageLength = 0;
4657 header.PageNumber = 1;
4658 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4661 cfg.pageAddr = portnum;
4662 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4665 if (mpt_config(ioc, &cfg) != 0)
4668 ioc->spi_data.sdp1version = cfg.hdr->PageVersion;
4669 ioc->spi_data.sdp1length = cfg.hdr->PageLength;
4671 header.PageVersion = 0;
4672 header.PageLength = 0;
4673 header.PageNumber = 0;
4674 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4675 if (mpt_config(ioc, &cfg) != 0)
4678 ioc->spi_data.sdp0version = cfg.hdr->PageVersion;
4679 ioc->spi_data.sdp0length = cfg.hdr->PageLength;
4681 dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
4682 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
4684 dcprintk((MYIOC_s_INFO_FMT "Headers: 1: version %d length %d\n",
4685 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
4689 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4691 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4692 * @ioc: Pointer to a Adapter Strucutre
4693 * @portnum: IOC port number
4697 * -EFAULT if read of config page header fails or data pointer not NULL
4698 * -ENOMEM if pci_alloc failed
4701 mpt_findImVolumes(MPT_ADAPTER *ioc)
4705 ConfigPageIoc2RaidVol_t *pIocRv;
4706 dma_addr_t ioc2_dma;
4708 ConfigPageHeader_t header;
4715 /* Read IOCP2 header then the page.
4717 header.PageVersion = 0;
4718 header.PageLength = 0;
4719 header.PageNumber = 2;
4720 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4724 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4727 if (mpt_config(ioc, &cfg) != 0)
4730 if (header.PageLength == 0)
4733 iocpage2sz = header.PageLength * 4;
4734 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
4738 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4739 cfg.physAddr = ioc2_dma;
4740 if (mpt_config(ioc, &cfg) != 0)
4743 if ( (mem = (u8 *)ioc->spi_data.pIocPg2) == NULL ) {
4744 mem = kmalloc(iocpage2sz, GFP_ATOMIC);
4746 ioc->spi_data.pIocPg2 = (IOCPage2_t *) mem;
4751 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
4753 /* Identify RAID Volume Id's */
4754 nVols = pIoc2->NumActiveVolumes;
4760 /* At least 1 RAID Volume
4762 pIocRv = pIoc2->RaidVolume;
4763 ioc->spi_data.isRaid = 0;
4764 for (jj = 0; jj < nVols; jj++, pIocRv++) {
4765 vid = pIocRv->VolumeID;
4766 vbus = pIocRv->VolumeBus;
4767 vioc = pIocRv->VolumeIOC;
4772 ioc->spi_data.isRaid |= (1 << vid);
4774 /* Error! Always bus 0
4780 /* Identify Hidden Physical Disk Id's */
4781 nPhys = pIoc2->NumActivePhysDisks;
4783 /* No physical disks.
4786 mpt_read_ioc_pg_3(ioc);
4790 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
4796 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
4801 ConfigPageHeader_t header;
4802 dma_addr_t ioc3_dma;
4805 /* Free the old page
4807 if (ioc->spi_data.pIocPg3) {
4808 kfree(ioc->spi_data.pIocPg3);
4809 ioc->spi_data.pIocPg3 = NULL;
4812 /* There is at least one physical disk.
4813 * Read and save IOC Page 3
4815 header.PageVersion = 0;
4816 header.PageLength = 0;
4817 header.PageNumber = 3;
4818 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4822 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4825 if (mpt_config(ioc, &cfg) != 0)
4828 if (header.PageLength == 0)
4831 /* Read Header good, alloc memory
4833 iocpage3sz = header.PageLength * 4;
4834 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
4838 /* Read the Page and save the data
4839 * into malloc'd memory.
4841 cfg.physAddr = ioc3_dma;
4842 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4843 if (mpt_config(ioc, &cfg) == 0) {
4844 mem = kmalloc(iocpage3sz, GFP_ATOMIC);
4846 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
4847 ioc->spi_data.pIocPg3 = (IOCPage3_t *) mem;
4851 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
4857 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
4861 ConfigPageHeader_t header;
4862 dma_addr_t ioc4_dma;
4865 /* Read and save IOC Page 4
4867 header.PageVersion = 0;
4868 header.PageLength = 0;
4869 header.PageNumber = 4;
4870 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4874 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4877 if (mpt_config(ioc, &cfg) != 0)
4880 if (header.PageLength == 0)
4883 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
4884 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
4885 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
4889 ioc4_dma = ioc->spi_data.IocPg4_dma;
4890 iocpage4sz = ioc->spi_data.IocPg4Sz;
4893 /* Read the Page into dma memory.
4895 cfg.physAddr = ioc4_dma;
4896 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4897 if (mpt_config(ioc, &cfg) == 0) {
4898 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
4899 ioc->spi_data.IocPg4_dma = ioc4_dma;
4900 ioc->spi_data.IocPg4Sz = iocpage4sz;
4902 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
4903 ioc->spi_data.pIocPg4 = NULL;
4908 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
4912 ConfigPageHeader_t header;
4913 dma_addr_t ioc1_dma;
4917 /* Check the Coalescing Timeout in IOC Page 1
4919 header.PageVersion = 0;
4920 header.PageLength = 0;
4921 header.PageNumber = 1;
4922 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4926 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4929 if (mpt_config(ioc, &cfg) != 0)
4932 if (header.PageLength == 0)
4935 /* Read Header good, alloc memory
4937 iocpage1sz = header.PageLength * 4;
4938 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
4942 /* Read the Page and check coalescing timeout
4944 cfg.physAddr = ioc1_dma;
4945 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4946 if (mpt_config(ioc, &cfg) == 0) {
4948 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
4949 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
4950 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
4952 dprintk((MYIOC_s_INFO_FMT "Coalescing Enabled Timeout = %d\n",
4955 if (tmp > MPT_COALESCING_TIMEOUT) {
4956 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
4958 /* Write NVRAM and current
4961 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4962 if (mpt_config(ioc, &cfg) == 0) {
4963 dprintk((MYIOC_s_INFO_FMT "Reset Current Coalescing Timeout to = %d\n",
4964 ioc->name, MPT_COALESCING_TIMEOUT));
4966 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
4967 if (mpt_config(ioc, &cfg) == 0) {
4968 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout to = %d\n",
4969 ioc->name, MPT_COALESCING_TIMEOUT));
4971 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout Failed\n",
4976 dprintk((MYIOC_s_WARN_FMT "Reset of Current Coalescing Timeout Failed!\n",
4982 dprintk((MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
4986 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
4991 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4993 * SendEventNotification - Send EventNotification (on or off) request
4995 * @ioc: Pointer to MPT_ADAPTER structure
4996 * @EvSwitch: Event switch flags
4999 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5001 EventNotification_t *evnp;
5003 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc->id);
5005 dprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5009 memset(evnp, 0, sizeof(*evnp));
5011 dprintk((MYIOC_s_INFO_FMT "Sending EventNotification(%d)\n", ioc->name, EvSwitch));
5013 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5014 evnp->ChainOffset = 0;
5016 evnp->Switch = EvSwitch;
5018 mpt_put_msg_frame(mpt_base_index, ioc->id, (MPT_FRAME_HDR *)evnp);
5023 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5025 * SendEventAck - Send EventAck request to MPT adapter.
5026 * @ioc: Pointer to MPT_ADAPTER structure
5027 * @evnp: Pointer to original EventNotification request
5030 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5034 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc->id)) == NULL) {
5035 printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK request frame!\n",
5039 memset(pAck, 0, sizeof(*pAck));
5041 dprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
5043 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5044 pAck->ChainOffset = 0;
5046 pAck->Event = evnp->Event;
5047 pAck->EventContext = evnp->EventContext;
5049 mpt_put_msg_frame(mpt_base_index, ioc->id, (MPT_FRAME_HDR *)pAck);
5054 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5056 * mpt_config - Generic function to issue config message
5057 * @ioc - Pointer to an adapter structure
5058 * @cfg - Pointer to a configuration structure. Struct contains
5059 * action, page address, direction, physical address
5060 * and pointer to a configuration page header
5061 * Page header is updated.
5063 * Returns 0 for success
5064 * -EPERM if not allowed due to ISR context
5065 * -EAGAIN if no msg frames currently available
5066 * -EFAULT for non-successful reply or no reply (timeout)
5069 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5073 unsigned long flags;
5078 /* (Bugzilla:fibrebugs, #513)
5079 * Bug fix (part 1)! 20010905 -sralston
5080 * Prevent calling wait_event() (below), if caller happens
5081 * to be in ISR context, because that is fatal!
5083 in_isr = in_interrupt();
5085 dcprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5090 /* Get and Populate a free Frame
5092 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc->id)) == NULL) {
5093 dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5097 pReq = (Config_t *)mf;
5098 pReq->Action = pCfg->action;
5100 pReq->ChainOffset = 0;
5101 pReq->Function = MPI_FUNCTION_CONFIG;
5102 pReq->ExtPageLength = 0;
5103 pReq->ExtPageType = 0;
5105 for (ii=0; ii < 8; ii++)
5106 pReq->Reserved2[ii] = 0;
5108 pReq->Header.PageVersion = pCfg->hdr->PageVersion;
5109 pReq->Header.PageLength = pCfg->hdr->PageLength;
5110 pReq->Header.PageNumber = pCfg->hdr->PageNumber;
5111 pReq->Header.PageType = (pCfg->hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5112 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5114 /* Add a SGE to the config request.
5117 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5119 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5121 flagsLength |= pCfg->hdr->PageLength * 4;
5123 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5125 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5126 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5128 /* Append pCfg pointer to end of mf
5130 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5132 /* Initalize the timer
5134 init_timer(&pCfg->timer);
5135 pCfg->timer.data = (unsigned long) ioc;
5136 pCfg->timer.function = mpt_timer_expired;
5137 pCfg->wait_done = 0;
5139 /* Set the timer; ensure 10 second minimum */
5140 if (pCfg->timeout < 10)
5141 pCfg->timer.expires = jiffies + HZ*10;
5143 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5145 /* Add to end of Q, set timer and then issue this command */
5146 spin_lock_irqsave(&ioc->FreeQlock, flags);
5147 Q_ADD_TAIL(&ioc->configQ.head, &pCfg->linkage, Q_ITEM);
5148 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5150 add_timer(&pCfg->timer);
5151 mpt_put_msg_frame(mpt_base_index, ioc->id, mf);
5152 wait_event(mpt_waitq, pCfg->wait_done);
5154 /* mf has been freed - do not access */
5161 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5163 * mpt_toolbox - Generic function to issue toolbox message
5164 * @ioc - Pointer to an adapter structure
5165 * @cfg - Pointer to a toolbox structure. Struct contains
5166 * action, page address, direction, physical address
5167 * and pointer to a configuration page header
5168 * Page header is updated.
5170 * Returns 0 for success
5171 * -EPERM if not allowed due to ISR context
5172 * -EAGAIN if no msg frames currently available
5173 * -EFAULT for non-successful reply or no reply (timeout)
5176 mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5178 ToolboxIstwiReadWriteRequest_t *pReq;
5180 unsigned long flags;
5185 /* (Bugzilla:fibrebugs, #513)
5186 * Bug fix (part 1)! 20010905 -sralston
5187 * Prevent calling wait_event() (below), if caller happens
5188 * to be in ISR context, because that is fatal!
5190 in_isr = in_interrupt();
5192 dcprintk((MYIOC_s_WARN_FMT "toobox request not allowed in ISR context!\n",
5197 /* Get and Populate a free Frame
5199 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc->id)) == NULL) {
5200 dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n",
5204 pReq = (ToolboxIstwiReadWriteRequest_t *)mf;
5205 pReq->Tool = pCfg->action;
5207 pReq->ChainOffset = 0;
5208 pReq->Function = MPI_FUNCTION_TOOLBOX;
5209 pReq->Reserved1 = 0;
5210 pReq->Reserved2 = 0;
5212 pReq->Flags = pCfg->dir;
5214 pReq->Reserved3 = 0;
5215 pReq->NumAddressBytes = 0x01;
5216 pReq->Reserved4 = 0;
5217 pReq->DataLength = 0x04;
5218 pReq->DeviceAddr = 0xB0;
5222 pReq->Reserved5 = 0;
5224 /* Add a SGE to the config request.
5227 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | 4;
5229 mpt_add_sge((char *)&pReq->SGL, flagsLength, pCfg->physAddr);
5231 dcprintk((MYIOC_s_INFO_FMT "Sending Toolbox request, Tool=%x\n",
5232 ioc->name, pReq->Tool));
5234 /* Append pCfg pointer to end of mf
5236 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5238 /* Initalize the timer
5240 init_timer(&pCfg->timer);
5241 pCfg->timer.data = (unsigned long) ioc;
5242 pCfg->timer.function = mpt_timer_expired;
5243 pCfg->wait_done = 0;
5245 /* Set the timer; ensure 10 second minimum */
5246 if (pCfg->timeout < 10)
5247 pCfg->timer.expires = jiffies + HZ*10;
5249 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5251 /* Add to end of Q, set timer and then issue this command */
5252 spin_lock_irqsave(&ioc->FreeQlock, flags);
5253 Q_ADD_TAIL(&ioc->configQ.head, &pCfg->linkage, Q_ITEM);
5254 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5256 add_timer(&pCfg->timer);
5257 mpt_put_msg_frame(mpt_base_index, ioc->id, mf);
5258 wait_event(mpt_waitq, pCfg->wait_done);
5260 /* mf has been freed - do not access */
5267 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5269 * mpt_timer_expired - Call back for timer process.
5270 * Used only internal config functionality.
5271 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5274 mpt_timer_expired(unsigned long data)
5276 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5278 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name));
5280 /* Perform a FW reload */
5281 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5282 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5284 /* No more processing.
5285 * Hard reset clean-up will wake up
5286 * process and free all resources.
5288 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name));
5293 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5295 * mpt_ioc_reset - Base cleanup for hard reset
5296 * @ioc: Pointer to the adapter structure
5297 * @reset_phase: Indicates pre- or post-reset functionality
5299 * Remark: Free's resources with internally generated commands.
5302 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5305 unsigned long flags;
5307 dprintk((KERN_WARNING MYNAM
5308 ": IOC %s_reset routed to MPT base driver!\n",
5309 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5310 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5312 if (reset_phase == MPT_IOC_SETUP_RESET) {
5314 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5315 /* If the internal config Q is not empty -
5316 * delete timer. MF resources will be freed when
5317 * the FIFO's are primed.
5319 spin_lock_irqsave(&ioc->FreeQlock, flags);
5320 if (! Q_IS_EMPTY(&ioc->configQ)){
5321 pCfg = (CONFIGPARMS *)ioc->configQ.head;
5323 del_timer(&pCfg->timer);
5324 pCfg = (CONFIGPARMS *) (pCfg->linkage.forw);
5325 } while (pCfg != (CONFIGPARMS *)&ioc->configQ);
5327 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5332 /* Search the configQ for internal commands.
5333 * Flush the Q, and wake up all suspended threads.
5335 spin_lock_irqsave(&ioc->FreeQlock, flags);
5336 if (! Q_IS_EMPTY(&ioc->configQ)){
5337 pCfg = (CONFIGPARMS *)ioc->configQ.head;
5339 pNext = (CONFIGPARMS *) pCfg->linkage.forw;
5341 Q_DEL_ITEM(&pCfg->linkage);
5343 pCfg->status = MPT_CONFIG_ERROR;
5344 pCfg->wait_done = 1;
5345 wake_up(&mpt_waitq);
5348 } while (pCfg != (CONFIGPARMS *)&ioc->configQ);
5350 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5353 return 1; /* currently means nothing really */
5357 #ifdef CONFIG_PROC_FS /* { */
5358 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5360 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5362 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5364 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5366 * Returns 0 for success, non-zero for failure.
5369 procmpt_create(void)
5372 struct proc_dir_entry *ent;
5376 * BEWARE: If/when MPT_PROCFS_MPTBASEDIR changes from "mpt"
5377 * (single level) to multi level (e.g. "driver/message/fusion")
5378 * something here needs to change. -sralston
5380 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5381 if (mpt_proc_root_dir == NULL)
5384 for (ii=0; ii < MPT_PROC_ENTRIES; ii++) {
5385 ent = create_proc_entry(mpt_proc_list[ii].name,
5386 S_IFREG|S_IRUGO, mpt_proc_root_dir);
5388 printk(KERN_WARNING MYNAM
5389 ": WARNING - Could not create /proc/mpt/%s entry\n",
5390 mpt_proc_list[ii].name);
5393 ent->read_proc = mpt_proc_list[ii].f;
5397 ioc = mpt_adapter_find_first();
5398 while (ioc != NULL) {
5399 struct proc_dir_entry *dent;
5401 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
5403 if ((dent = proc_mkdir(ioc->name, mpt_proc_root_dir)) != NULL) {
5405 * And populate it with mpt_ioc_proc_list[] entries.
5407 for (ii=0; ii < MPT_IOC_PROC_ENTRIES; ii++) {
5408 ent = create_proc_entry(mpt_ioc_proc_list[ii].name,
5409 S_IFREG|S_IRUGO, dent);
5411 printk(KERN_WARNING MYNAM
5412 ": WARNING - Could not create /proc/mpt/%s/%s entry!\n",
5414 mpt_ioc_proc_list[ii].name);
5417 ent->read_proc = mpt_ioc_proc_list[ii].f;
5421 printk(MYIOC_s_WARN_FMT "Could not create /proc/mpt/%s subdir entry!\n",
5422 ioc->name, mpt_ioc_proc_list[ii].name);
5424 ioc = mpt_adapter_find_next(ioc);
5430 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5432 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5434 * Returns 0 for success, non-zero for failure.
5437 procmpt_destroy(void)
5442 if (!mpt_proc_root_dir)
5446 * BEWARE: If/when MPT_PROCFS_MPTBASEDIR changes from "mpt"
5447 * (single level) to multi level (e.g. "driver/message/fusion")
5448 * something here needs to change. -sralston
5451 ioc = mpt_adapter_find_first();
5452 while (ioc != NULL) {
5456 namelen = sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
5459 * Tear down each "/proc/mpt/iocN" subdirectory.
5461 for (ii=0; ii < MPT_IOC_PROC_ENTRIES; ii++) {
5462 (void) sprintf(pname+namelen, "/%s", mpt_ioc_proc_list[ii].name);
5463 remove_proc_entry(pname, NULL);
5465 remove_proc_entry(ioc->name, mpt_proc_root_dir);
5466 ioc = mpt_adapter_find_next(ioc);
5469 for (ii=0; ii < MPT_PROC_ENTRIES; ii++)
5470 remove_proc_entry(mpt_proc_list[ii].name, mpt_proc_root_dir);
5472 if (atomic_read((atomic_t *)&mpt_proc_root_dir->count) == 0) {
5473 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5474 mpt_proc_root_dir = NULL;
5481 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5483 * procmpt_summary_read - Handle read request from /proc/mpt/summary
5484 * or from /proc/mpt/iocN/summary.
5485 * @buf: Pointer to area to write information
5486 * @start: Pointer to start pointer
5487 * @offset: Offset to start writing
5489 * @eof: Pointer to EOF integer
5492 * Returns number of characters written to process performing the read.
5495 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5502 ioc = mpt_adapter_find_first();
5509 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5512 if ((out-buf) >= request) {
5517 ioc = mpt_adapter_find_next(ioc);
5519 ioc = NULL; /* force exit for iocN */
5523 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5526 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5528 * procmpt_version_read - Handle read request from /proc/mpt/version.
5529 * @buf: Pointer to area to write information
5530 * @start: Pointer to start pointer
5531 * @offset: Offset to start writing
5533 * @eof: Pointer to EOF integer
5536 * Returns number of characters written to process performing the read.
5539 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5542 int scsi, lan, ctl, targ, dmp;
5546 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5547 len += sprintf(buf+len, " Fusion MPT base driver\n");
5549 scsi = lan = ctl = targ = dmp = 0;
5550 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5552 if (MptCallbacks[ii]) {
5553 switch (MptDriverClass[ii]) {
5554 case MPTSCSIH_DRIVER:
5555 if (!scsi++) drvname = "SCSI host";
5558 if (!lan++) drvname = "LAN";
5561 if (!targ++) drvname = "SCSI target";
5564 if (!ctl++) drvname = "ioctl";
5567 if (!dmp++) drvname = "DMP";
5572 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5574 * Handle isense special case, because it
5575 * doesn't do a formal mpt_register call.
5577 if (isense_idx == ii)
5578 len += sprintf(buf+len, " Fusion MPT isense driver\n");
5582 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5585 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5587 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5588 * @buf: Pointer to area to write information
5589 * @start: Pointer to start pointer
5590 * @offset: Offset to start writing
5592 * @eof: Pointer to EOF integer
5595 * Returns number of characters written to process performing the read.
5598 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5600 MPT_ADAPTER *ioc = data;
5606 mpt_get_fw_exp_ver(expVer, ioc);
5608 len = sprintf(buf, "%s:", ioc->name);
5609 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5610 len += sprintf(buf+len, " (f/w download boot flag set)");
5611 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5612 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5614 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
5615 ioc->facts.ProductID,
5617 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5618 if (ioc->facts.FWImageSize)
5619 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5620 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5621 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5622 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
5624 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
5625 ioc->facts.CurrentHostMfaHighAddr);
5626 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
5627 ioc->facts.CurrentSenseBufferHighAddr);
5629 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5630 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5632 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5633 (void *)ioc->req_alloc, (void *)(ulong)ioc->req_alloc_dma);
5635 * Rounding UP to nearest 4-kB boundary here...
5637 sz = (ioc->req_sz * ioc->req_depth) + 128;
5638 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5639 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5640 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5641 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
5642 4*ioc->facts.RequestFrameSize,
5643 ioc->facts.GlobalCredits);
5645 len += sprintf(buf+len, " ReplyFrames @ 0x%p (Dma @ 0x%p)\n",
5646 (void *)ioc->reply_alloc, (void *)(ulong)ioc->reply_alloc_dma);
5647 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5648 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5649 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5650 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
5651 ioc->facts.CurReplyFrameSize,
5652 ioc->facts.ReplyQueueDepth);
5654 len += sprintf(buf+len, " MaxDevices = %d\n",
5655 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5656 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
5659 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5660 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
5662 ioc->facts.NumberOfPorts);
5663 if ((int)ioc->chip_type <= (int)FC929) {
5664 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5665 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5666 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5667 a[5], a[4], a[3], a[2], a[1], a[0]);
5669 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
5670 ioc->fc_port_page0[p].WWNN.High,
5671 ioc->fc_port_page0[p].WWNN.Low,
5672 ioc->fc_port_page0[p].WWPN.High,
5673 ioc->fc_port_page0[p].WWPN.Low);
5677 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5680 #endif /* CONFIG_PROC_FS } */
5682 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5684 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
5687 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
5688 sprintf(buf, " (Exp %02d%02d)",
5689 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
5690 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
5693 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
5694 strcat(buf, " [MDBG]");
5698 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5700 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5701 * @ioc: Pointer to MPT_ADAPTER structure
5702 * @buffer: Pointer to buffer where IOC summary info should be written
5703 * @size: Pointer to number of bytes we wrote (set by this routine)
5704 * @len: Offset at which to start writing in buffer
5705 * @showlan: Display LAN stuff?
5707 * This routine writes (english readable) ASCII text, which represents
5708 * a summary of IOC information, to a buffer.
5711 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
5716 mpt_get_fw_exp_ver(expVer, ioc);
5719 * Shorter summary of attached ioc's...
5721 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
5724 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
5725 ioc->facts.FWVersion.Word,
5727 ioc->facts.NumberOfPorts,
5730 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
5731 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5732 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
5733 a[5], a[4], a[3], a[2], a[1], a[0]);
5737 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
5739 y += sprintf(buffer+len+y, ", IRQ=%s", __irq_itoa(ioc->pci_irq));
5743 y += sprintf(buffer+len+y, " (disabled)");
5745 y += sprintf(buffer+len+y, "\n");
5750 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5754 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5756 * mpt_HardResetHandler - Generic reset handler, issue SCSI Task
5757 * Management call based on input arg values. If TaskMgmt fails,
5758 * return associated SCSI request.
5759 * @ioc: Pointer to MPT_ADAPTER structure
5760 * @sleepFlag: Indicates if sleep or schedule must be called.
5762 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
5763 * or a non-interrupt thread. In the former, must not call schedule().
5765 * Remark: A return of -1 is a FATAL error case, as it means a
5766 * FW reload/initialization failed.
5768 * Returns 0 for SUCCESS or -1 if FAILED.
5771 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5774 unsigned long flags;
5776 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
5778 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
5779 printk("MF count 0x%x !\n", ioc->mfcnt);
5782 /* Reset the adapter. Prevent more than 1 call to
5783 * mpt_do_ioc_recovery at any instant in time.
5785 spin_lock_irqsave(&ioc->diagLock, flags);
5786 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
5787 spin_unlock_irqrestore(&ioc->diagLock, flags);
5790 ioc->diagPending = 1;
5792 spin_unlock_irqrestore(&ioc->diagLock, flags);
5794 /* FIXME: If do_ioc_recovery fails, repeat....
5797 /* The SCSI driver needs to adjust timeouts on all current
5798 * commands prior to the diagnostic reset being issued.
5799 * Prevents timeouts occuring during a diagnostic reset...very bad.
5800 * For all other protocol drivers, this is a no-op.
5806 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5807 if (MptResetHandlers[ii]) {
5808 dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
5810 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_SETUP_RESET);
5812 dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
5813 ioc->name, ioc->alt_ioc->name, ii));
5814 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_SETUP_RESET);
5820 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
5821 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
5826 ioc->alt_ioc->reload_fw = 0;
5828 spin_lock_irqsave(&ioc->diagLock, flags);
5829 ioc->diagPending = 0;
5831 ioc->alt_ioc->diagPending = 0;
5832 spin_unlock_irqrestore(&ioc->diagLock, flags);
5834 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
5839 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5841 EventDescriptionStr(u8 event, u32 evData0)
5846 case MPI_EVENT_NONE:
5849 case MPI_EVENT_LOG_DATA:
5852 case MPI_EVENT_STATE_CHANGE:
5853 ds = "State Change";
5855 case MPI_EVENT_UNIT_ATTENTION:
5856 ds = "Unit Attention";
5858 case MPI_EVENT_IOC_BUS_RESET:
5859 ds = "IOC Bus Reset";
5861 case MPI_EVENT_EXT_BUS_RESET:
5862 ds = "External Bus Reset";
5864 case MPI_EVENT_RESCAN:
5865 ds = "Bus Rescan Event";
5866 /* Ok, do we need to do anything here? As far as
5867 I can tell, this is when a new device gets added
5870 case MPI_EVENT_LINK_STATUS_CHANGE:
5871 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
5872 ds = "Link Status(FAILURE) Change";
5874 ds = "Link Status(ACTIVE) Change";
5876 case MPI_EVENT_LOOP_STATE_CHANGE:
5877 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
5878 ds = "Loop State(LIP) Change";
5879 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
5880 ds = "Loop State(LPE) Change"; /* ??? */
5882 ds = "Loop State(LPB) Change"; /* ??? */
5884 case MPI_EVENT_LOGOUT:
5887 case MPI_EVENT_EVENT_CHANGE:
5889 ds = "Events(ON) Change";
5891 ds = "Events(OFF) Change";
5893 case MPI_EVENT_INTEGRATED_RAID:
5894 ds = "Integrated Raid";
5897 * MPT base "custom" events may be added here...
5906 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5908 * ProcessEventNotification - Route a received EventNotificationReply to
5909 * all currently regeistered event handlers.
5910 * @ioc: Pointer to MPT_ADAPTER structure
5911 * @pEventReply: Pointer to EventNotification reply frame
5912 * @evHandlers: Pointer to integer, number of event handlers
5914 * Returns sum of event handlers return values.
5917 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
5929 * Do platform normalization of values
5931 event = le32_to_cpu(pEventReply->Event) & 0xFF;
5932 // evCtx = le32_to_cpu(pEventReply->EventContext);
5933 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
5935 evData0 = le32_to_cpu(pEventReply->Data[0]);
5938 evStr = EventDescriptionStr(event, evData0);
5939 dprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n",
5944 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_EVENTS)
5945 printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
5946 for (ii = 0; ii < evDataLen; ii++)
5947 printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
5952 * Do general / base driver event processing
5955 case MPI_EVENT_NONE: /* 00 */
5956 case MPI_EVENT_LOG_DATA: /* 01 */
5957 case MPI_EVENT_STATE_CHANGE: /* 02 */
5958 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
5959 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
5960 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
5961 case MPI_EVENT_RESCAN: /* 06 */
5962 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
5963 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
5964 case MPI_EVENT_LOGOUT: /* 09 */
5965 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
5966 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE: /* 0C */
5969 case MPI_EVENT_EVENT_CHANGE: /* 0A */
5971 u8 evState = evData0 & 0xFF;
5973 /* CHECKME! What if evState unexpectedly says OFF (0)? */
5975 /* Update EventState field in cached IocFacts */
5976 if (ioc->facts.Function) {
5977 ioc->facts.EventState = evState;
5984 * Should this event be logged? Events are written sequentially.
5985 * When buffer is full, start again at the top.
5987 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
5990 idx = ioc->eventContext % ioc->eventLogSize;
5992 ioc->events[idx].event = event;
5993 ioc->events[idx].eventContext = ioc->eventContext;
5995 for (ii = 0; ii < 2; ii++) {
5997 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
5999 ioc->events[idx].data[ii] = 0;
6002 ioc->eventContext++;
6007 * Call each currently registered protocol event handler.
6009 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
6010 if (MptEvHandlers[ii]) {
6011 dprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
6013 r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
6017 /* FIXME? Examine results here? */
6020 * If needed, send (a single) EventAck.
6022 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6023 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6024 printk(MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
6029 *evHandlers = handlers;
6033 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6035 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6036 * @ioc: Pointer to MPT_ADAPTER structure
6037 * @log_info: U32 LogInfo reply word from the IOC
6039 * Refer to lsi/fc_log.h.
6042 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6044 static char *subcl_str[8] = {
6045 "FCP Initiator", "FCP Target", "LAN", "MPI Message Layer",
6046 "FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
6048 u8 subcl = (log_info >> 24) & 0x7;
6049 // u32 SubCl = log_info & 0x27000000;
6051 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}",
6052 ioc->name, log_info, subcl_str[subcl]);
6055 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6057 * mpt_sp_log_info - Log information returned from SCSI Parallel IOC.
6058 * @ioc: Pointer to MPT_ADAPTER structure
6059 * @mr: Pointer to MPT reply frame
6060 * @log_info: U32 LogInfo word from the IOC
6062 * Refer to lsi/sp_log.h.
6065 mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
6067 u32 info = log_info & 0x00FF0000;
6068 char *desc = "unknown";
6072 desc = "bug! MID not found";
6073 if (ioc->reload_fw == 0)
6078 desc = "Parity Error";
6082 desc = "ASYNC Outbound Overrun";
6086 desc = "SYNC Offset Error";
6094 desc = "Msg In Overflow";
6102 desc = "Outbound DMA Overrun";
6106 desc = "Task Management";
6110 desc = "Device Problem";
6114 desc = "Invalid Phase Change";
6118 desc = "Untagged Table Size";
6123 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6126 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6128 * mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
6129 * @ioc: Pointer to MPT_ADAPTER structure
6130 * @ioc_status: U32 IOCStatus word from IOC
6131 * @mf: Pointer to MPT request frame
6133 * Refer to lsi/mpi.h.
6136 mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
6138 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
6142 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
6143 desc = "Invalid Function";
6146 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
6150 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
6151 desc = "Invalid SGL";
6154 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
6155 desc = "Internal Error";
6158 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
6162 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
6163 desc = "Insufficient Resources";
6166 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
6167 desc = "Invalid Field";
6170 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
6171 desc = "Invalid State";
6174 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
6175 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
6176 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
6177 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
6178 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
6179 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
6180 /* No message for Config IOCStatus values */
6183 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
6184 /* No message for recovered error
6185 desc = "SCSI Recovered Error";
6189 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
6190 desc = "SCSI Invalid Bus";
6193 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
6194 desc = "SCSI Invalid TargetID";
6197 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
6199 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
6200 U8 cdb = pScsiReq->CDB[0];
6201 if (cdb != 0x12) { /* Inquiry is issued for device scanning */
6202 desc = "SCSI Device Not There";
6207 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
6208 desc = "SCSI Data Overrun";
6211 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
6212 /* This error is checked in scsi_io_done(). Skip.
6213 desc = "SCSI Data Underrun";
6217 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
6218 desc = "SCSI I/O Data Error";
6221 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
6222 desc = "SCSI Protocol Error";
6225 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
6226 desc = "SCSI Task Terminated";
6229 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
6230 desc = "SCSI Residual Mismatch";
6233 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
6234 desc = "SCSI Task Management Failed";
6237 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
6238 desc = "SCSI IOC Terminated";
6241 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
6242 desc = "SCSI Ext Terminated";
6250 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc);
6253 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6255 * mpt_register_ascqops_strings - Register SCSI ASC/ASCQ and SCSI
6256 * OpCode strings from the (optional) isense module.
6257 * @ascqTable: Pointer to ASCQ_Table_t structure
6258 * @ascqtbl_sz: Number of entries in ASCQ_Table
6259 * @opsTable: Pointer to array of SCSI OpCode strings (char pointers)
6261 * Specialized driver registration routine for the isense driver.
6264 mpt_register_ascqops_strings(void *ascqTable, int ascqtbl_sz, const char **opsTable)
6268 if (ascqTable && ascqtbl_sz && opsTable) {
6269 mpt_v_ASCQ_TablePtr = ascqTable;
6270 mpt_ASCQ_TableSz = ascqtbl_sz;
6271 mpt_ScsiOpcodesPtr = opsTable;
6272 printk(KERN_INFO MYNAM ": English readable SCSI-3 strings enabled:-)\n");
6273 isense_idx = last_drv_idx;
6279 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6281 * mpt_deregister_ascqops_strings - Deregister SCSI ASC/ASCQ and SCSI
6282 * OpCode strings from the isense driver.
6284 * Specialized driver deregistration routine for the isense driver.
6287 mpt_deregister_ascqops_strings(void)
6289 mpt_v_ASCQ_TablePtr = NULL;
6290 mpt_ASCQ_TableSz = 0;
6291 mpt_ScsiOpcodesPtr = NULL;
6292 printk(KERN_INFO MYNAM ": English readable SCSI-3 strings disabled)-:\n");
6296 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6298 EXPORT_SYMBOL(mpt_adapters);
6299 EXPORT_SYMBOL(mpt_proc_root_dir);
6300 EXPORT_SYMBOL(DmpService);
6301 EXPORT_SYMBOL(mpt_register);
6302 EXPORT_SYMBOL(mpt_deregister);
6303 EXPORT_SYMBOL(mpt_event_register);
6304 EXPORT_SYMBOL(mpt_event_deregister);
6305 EXPORT_SYMBOL(mpt_reset_register);
6306 EXPORT_SYMBOL(mpt_reset_deregister);
6307 EXPORT_SYMBOL(mpt_device_driver_register);
6308 EXPORT_SYMBOL(mpt_device_driver_deregister);
6309 EXPORT_SYMBOL(mpt_get_msg_frame);
6310 EXPORT_SYMBOL(mpt_put_msg_frame);
6311 EXPORT_SYMBOL(mpt_free_msg_frame);
6312 EXPORT_SYMBOL(mpt_add_sge);
6313 EXPORT_SYMBOL(mpt_add_chain);
6314 EXPORT_SYMBOL(mpt_send_handshake_request);
6315 EXPORT_SYMBOL(mpt_handshake_req_reply_wait);
6316 EXPORT_SYMBOL(mpt_adapter_find_first);
6317 EXPORT_SYMBOL(mpt_adapter_find_next);
6318 EXPORT_SYMBOL(mpt_verify_adapter);
6319 EXPORT_SYMBOL(mpt_GetIocState);
6320 EXPORT_SYMBOL(mpt_print_ioc_summary);
6321 EXPORT_SYMBOL(mpt_lan_index);
6322 EXPORT_SYMBOL(mpt_stm_index);
6323 EXPORT_SYMBOL(mpt_HardResetHandler);
6324 EXPORT_SYMBOL(mpt_config);
6325 EXPORT_SYMBOL(mpt_toolbox);
6326 EXPORT_SYMBOL(mpt_findImVolumes);
6327 EXPORT_SYMBOL(mpt_read_ioc_pg_3);
6328 EXPORT_SYMBOL(mpt_alloc_fw_memory);
6329 EXPORT_SYMBOL(mpt_free_fw_memory);
6331 EXPORT_SYMBOL(mpt_register_ascqops_strings);
6332 EXPORT_SYMBOL(mpt_deregister_ascqops_strings);
6333 EXPORT_SYMBOL(mpt_v_ASCQ_TablePtr);
6334 EXPORT_SYMBOL(mpt_ASCQ_TableSz);
6335 EXPORT_SYMBOL(mpt_ScsiOpcodesPtr);
6338 static struct pci_driver mptbase_driver = {
6340 .id_table = mptbase_pci_table,
6341 .probe = mptbase_probe,
6342 .remove = __devexit_p(mptbase_remove),
6344 .shutdown = mptbase_shutdown,
6347 .suspend = mptbase_suspend,
6348 .resume = mptbase_resume,
6352 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6354 * fusion_init - Fusion MPT base driver initialization routine.
6356 * Returns 0 for success, non-zero for failure.
6364 if (FusionInitCalled++) {
6365 dprintk((KERN_INFO MYNAM ": INFO - Driver late-init entry point called\n"));
6369 show_mptmod_ver(my_NAME, my_VERSION);
6370 printk(KERN_INFO COPYRIGHT "\n");
6372 Q_INIT(&MptAdapters, MPT_ADAPTER); /* set to empty */
6373 for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
6374 MptCallbacks[i] = NULL;
6375 MptDriverClass[i] = MPTUNKNOWN_DRIVER;
6376 MptEvHandlers[i] = NULL;
6377 MptResetHandlers[i] = NULL;
6382 /* NEW! 20010120 -sralston
6383 * Register ourselves (mptbase) in order to facilitate
6384 * EventNotification handling.
6386 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
6388 /* Register for hard reset handling callbacks.
6390 if (mpt_reset_register(mpt_base_index, mpt_ioc_reset) == 0) {
6391 dprintk((KERN_INFO MYNAM ": Register for IOC reset notification\n"));
6396 r = pci_module_init(&mptbase_driver);
6400 #ifdef CONFIG_PROC_FS
6401 (void) procmpt_create();
6407 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6409 * fusion_exit - Perform driver unload cleanup.
6411 * This routine frees all resources associated with each MPT adapter
6412 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
6418 dprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
6420 /* Whups? 20010120 -sralston
6421 * Moved this *above* removal of all MptAdapters!
6423 #ifdef CONFIG_PROC_FS
6424 (void) procmpt_destroy();
6426 pci_unregister_driver(&mptbase_driver);
6427 mpt_reset_deregister(mpt_base_index);
6431 module_init(fusion_init);
6432 module_exit(fusion_exit);