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");
122 MODULE_VERSION(MPT_LINUX_VERSION_COMMON);
125 * cmd line parameters
128 static int mfcounter = 0;
129 #define PRINT_MF_COUNT 20000
132 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
136 int mpt_lan_index = -1;
137 int mpt_stm_index = -1;
139 struct proc_dir_entry *mpt_proc_root_dir;
141 #define WHOINIT_UNKNOWN 0xAA
143 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
147 /* Adapter link list */
149 /* Callback lookup table */
150 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
151 /* Protocol driver class lookup table */
152 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
153 /* Event handler lookup table */
154 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
155 /* Reset handler lookup table */
156 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
157 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
159 static int mpt_base_index = -1;
160 static int last_drv_idx = -1;
162 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
164 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
168 static irqreturn_t mpt_interrupt(int irq, void *bus_id, struct pt_regs *r);
169 static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
170 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
171 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
173 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
174 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
175 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
176 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
178 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
179 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
180 //static u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
181 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
182 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
183 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
184 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
185 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
186 static int mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag);
187 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
188 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
189 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
190 static int PrimeIocFifos(MPT_ADAPTER *ioc);
191 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
192 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
193 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
194 static int GetLanConfigPages(MPT_ADAPTER *ioc);
195 static int GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
196 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
197 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
198 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
199 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
200 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
201 static void mpt_timer_expired(unsigned long data);
202 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
203 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
205 #ifdef CONFIG_PROC_FS
206 static int procmpt_summary_read(char *buf, char **start, off_t offset,
207 int request, int *eof, void *data);
208 static int procmpt_version_read(char *buf, char **start, off_t offset,
209 int request, int *eof, void *data);
210 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
211 int request, int *eof, void *data);
213 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
215 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
216 static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
217 static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
218 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
219 static void mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info);
221 /* module entry point */
222 static int __devinit mptbase_probe (struct pci_dev *, const struct pci_device_id *);
223 static void __devexit mptbase_remove(struct pci_dev *);
224 static void mptbase_shutdown(struct device * );
225 static int __init fusion_init (void);
226 static void __exit fusion_exit (void);
228 /****************************************************************************
232 static struct pci_device_id mptbase_pci_table[] = {
233 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC909,
234 PCI_ANY_ID, PCI_ANY_ID },
235 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929,
236 PCI_ANY_ID, PCI_ANY_ID },
237 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919,
238 PCI_ANY_ID, PCI_ANY_ID },
239 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929X,
240 PCI_ANY_ID, PCI_ANY_ID },
241 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919X,
242 PCI_ANY_ID, PCI_ANY_ID },
243 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1030,
244 PCI_ANY_ID, PCI_ANY_ID },
245 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_1030_53C1035,
246 PCI_ANY_ID, PCI_ANY_ID },
247 {0} /* Terminating entry */
249 MODULE_DEVICE_TABLE(pci, mptbase_pci_table);
251 #define CHIPREG_READ32(addr) readl_relaxed(addr)
252 #define CHIPREG_READ32_dmasync(addr) readl(addr)
253 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
254 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
255 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
257 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
259 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
260 * @irq: irq number (not used)
261 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
262 * @r: pt_regs pointer (not used)
264 * This routine is registered via the request_irq() kernel API call,
265 * and handles all interrupts generated from a specific MPT adapter
266 * (also referred to as a IO Controller or IOC).
267 * This routine must clear the interrupt from the adapter and does
268 * so by reading the reply FIFO. Multiple replies may be processed
269 * per single call to this routine; up to MPT_MAX_REPLIES_PER_ISR
270 * which is currently set to 32 in mptbase.h.
272 * This routine handles register-level access of the adapter but
273 * dispatches (calls) a protocol-specific callback routine to handle
274 * the protocol-specific details of the MPT request completion.
277 mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
288 ioc = (MPT_ADAPTER *)bus_id;
291 * Drain the reply FIFO!
293 * NOTES: I've seen up to 10 replies processed in this loop, so far...
294 * Update: I've seen up to 9182 replies processed in this loop! ??
295 * Update: Limit ourselves to processing max of N replies
300 if ((pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo)) == 0xFFFFFFFF)
307 * Check for non-TURBO reply!
309 if (pa & MPI_ADDRESS_REPLY_A_BIT) {
313 /* non-TURBO reply! Hmmm, something may be up...
314 * Newest turbo reply mechanism; get address
315 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
318 /* Map DMA address of reply header to cpu address.
319 * pa is 32 bits - but the dma address may be 32 or 64 bits
320 * get offset based only only the low addresses
322 reply_dma_low = (pa = (pa << 1));
323 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
324 (reply_dma_low - ioc->reply_frames_low_dma));
326 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
327 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
328 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
330 dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x\n",
331 ioc->name, mr, req_idx));
332 DBG_DUMP_REPLY_FRAME(mr)
334 /* NEW! 20010301 -sralston
335 * Check/log IOC log info
337 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
338 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
339 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
340 if (ioc->bus_type == FC)
341 mpt_fc_log_info(ioc, log_info);
342 else if (ioc->bus_type == SCSI)
343 mpt_sp_log_info(ioc, log_info);
345 if (ioc_stat & MPI_IOCSTATUS_MASK) {
346 if (ioc->bus_type == SCSI)
347 mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
351 * Process turbo (context) reply...
353 dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n", ioc->name, pa));
354 type = (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT);
355 if (type == MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET) {
356 cb_idx = mpt_stm_index;
358 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
359 } else if (type == MPI_CONTEXT_REPLY_TYPE_LAN) {
360 cb_idx = mpt_lan_index;
362 * BUG FIX! 20001218 -sralston
363 * Blind set of mf to NULL here was fatal
364 * after lan_reply says "freeme"
365 * Fix sort of combined with an optimization here;
366 * added explicit check for case where lan_reply
367 * was just returning 1 and doing nothing else.
368 * For this case skip the callback, but set up
369 * proper mf value first here:-)
371 if ((pa & 0x58000000) == 0x58000000) {
372 req_idx = pa & 0x0000FFFF;
373 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
376 * IMPORTANT! Invalidate the callback!
382 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
384 req_idx = pa & 0x0000FFFF;
385 cb_idx = (pa & 0x00FF0000) >> 16;
386 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
389 pa = 0; /* No reply flush! */
393 if (ioc->bus_type == SCSI) {
394 /* Verify mf, mr are reasonable.
396 if ((mf) && ((mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))
397 || (mf < ioc->req_frames)) ) {
398 printk(MYIOC_s_WARN_FMT
399 "mpt_interrupt: Invalid mf (%p) req_idx (%d)!\n", ioc->name, (void *)mf, req_idx);
404 if ((pa) && (mr) && ((mr >= MPT_INDEX_2_RFPTR(ioc, ioc->req_depth))
405 || (mr < ioc->reply_frames)) ) {
406 printk(MYIOC_s_WARN_FMT
407 "mpt_interrupt: Invalid rf (%p)!\n", ioc->name, (void *)mr);
412 if (cb_idx > (MPT_MAX_PROTOCOL_DRIVERS-1)) {
413 printk(MYIOC_s_WARN_FMT
414 "mpt_interrupt: Invalid cb_idx (%d)!\n", ioc->name, cb_idx);
422 /* Check for (valid) IO callback! */
424 /* Do the callback! */
425 freeme = (*(MptCallbacks[cb_idx]))(ioc, mf, mr);
429 /* Flush (non-TURBO) reply with a WRITE! */
430 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
436 /* Put Request back on FreeQ! */
437 spin_lock_irqsave(&ioc->FreeQlock, flags);
438 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
442 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
446 } /* drain reply FIFO */
451 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
453 * mpt_base_reply - MPT base driver's callback routine; all base driver
454 * "internal" request/reply processing is routed here.
455 * Currently used for EventNotification and EventAck handling.
456 * @ioc: Pointer to MPT_ADAPTER structure
457 * @mf: Pointer to original MPT request frame
458 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
460 * Returns 1 indicating original alloc'd request frame ptr
461 * should be freed, or 0 if it shouldn't.
464 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
469 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name));
472 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
473 printk(MYIOC_s_ERR_FMT "NULL or BAD request frame ptr! (=%p)\n",
474 ioc->name, (void *)mf);
479 dprintk((MYIOC_s_ERR_FMT "Unexpected NULL Event (turbo?) reply!\n",
484 if (!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
485 dmfprintk((KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf));
486 DBG_DUMP_REQUEST_FRAME_HDR(mf)
489 func = reply->u.hdr.Function;
490 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n",
493 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
494 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
498 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
499 if (results != evHandlers) {
500 /* CHECKME! Any special handling needed here? */
501 devtprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
502 ioc->name, evHandlers, results));
506 * Hmmm... It seems that EventNotificationReply is an exception
507 * to the rule of one reply per request.
509 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
512 #ifdef CONFIG_PROC_FS
513 // LogEvent(ioc, pEvReply);
516 } else if (func == MPI_FUNCTION_EVENT_ACK) {
517 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
519 } else if (func == MPI_FUNCTION_CONFIG ||
520 func == MPI_FUNCTION_TOOLBOX) {
524 dcprintk((MYIOC_s_INFO_FMT "config_complete (mf=%p,mr=%p)\n",
525 ioc->name, mf, reply));
527 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
530 /* disable timer and remove from linked list */
531 del_timer(&pCfg->timer);
533 spin_lock_irqsave(&ioc->FreeQlock, flags);
534 list_del(&pCfg->linkage);
535 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
538 * If IOC Status is SUCCESS, save the header
539 * and set the status code to GOOD.
541 pCfg->status = MPT_CONFIG_ERROR;
543 ConfigReply_t *pReply = (ConfigReply_t *)reply;
546 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
547 dcprintk((KERN_NOTICE " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
548 status, le32_to_cpu(pReply->IOCLogInfo)));
550 pCfg->status = status;
551 if (status == MPI_IOCSTATUS_SUCCESS) {
552 pCfg->hdr->PageVersion = pReply->Header.PageVersion;
553 pCfg->hdr->PageLength = pReply->Header.PageLength;
554 pCfg->hdr->PageNumber = pReply->Header.PageNumber;
555 pCfg->hdr->PageType = pReply->Header.PageType;
560 * Wake up the original calling thread
566 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
571 * Conditionally tell caller to free the original
572 * EventNotification/EventAck/unexpected request frame!
577 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
579 * mpt_register - Register protocol-specific main callback handler.
580 * @cbfunc: callback function pointer
581 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
583 * This routine is called by a protocol-specific driver (SCSI host,
584 * LAN, SCSI target) to register it's reply callback routine. Each
585 * protocol-specific driver must do this before it will be able to
586 * use any IOC resources, such as obtaining request frames.
588 * NOTES: The SCSI protocol driver currently calls this routine thrice
589 * in order to register separate callbacks; one for "normal" SCSI IO;
590 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
592 * Returns a positive integer valued "handle" in the
593 * range (and S.O.D. order) {N,...,7,6,5,...,1} if successful.
594 * Any non-positive return value (including zero!) should be considered
595 * an error by the caller.
598 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
605 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
606 * (slot/handle 0 is reserved!)
608 for (i = MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
609 if (MptCallbacks[i] == NULL) {
610 MptCallbacks[i] = cbfunc;
611 MptDriverClass[i] = dclass;
612 MptEvHandlers[i] = NULL;
621 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
623 * mpt_deregister - Deregister a protocol drivers resources.
624 * @cb_idx: previously registered callback handle
626 * Each protocol-specific driver should call this routine when it's
627 * module is unloaded.
630 mpt_deregister(int cb_idx)
632 if ((cb_idx >= 0) && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
633 MptCallbacks[cb_idx] = NULL;
634 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
635 MptEvHandlers[cb_idx] = NULL;
641 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
643 * mpt_event_register - Register protocol-specific event callback
645 * @cb_idx: previously registered (via mpt_register) callback handle
646 * @ev_cbfunc: callback function
648 * This routine can be called by one or more protocol-specific drivers
649 * if/when they choose to be notified of MPT events.
651 * Returns 0 for success.
654 mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc)
656 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
659 MptEvHandlers[cb_idx] = ev_cbfunc;
663 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
665 * mpt_event_deregister - Deregister protocol-specific event callback
667 * @cb_idx: previously registered callback handle
669 * Each protocol-specific driver should call this routine
670 * when it does not (or can no longer) handle events,
671 * or when it's module is unloaded.
674 mpt_event_deregister(int cb_idx)
676 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
679 MptEvHandlers[cb_idx] = NULL;
682 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
684 * mpt_reset_register - Register protocol-specific IOC reset handler.
685 * @cb_idx: previously registered (via mpt_register) callback handle
686 * @reset_func: reset function
688 * This routine can be called by one or more protocol-specific drivers
689 * if/when they choose to be notified of IOC resets.
691 * Returns 0 for success.
694 mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func)
696 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
699 MptResetHandlers[cb_idx] = reset_func;
703 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
705 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
706 * @cb_idx: previously registered callback handle
708 * Each protocol-specific driver should call this routine
709 * when it does not (or can no longer) handle IOC reset handling,
710 * or when it's module is unloaded.
713 mpt_reset_deregister(int cb_idx)
715 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
718 MptResetHandlers[cb_idx] = NULL;
721 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
723 * mpt_device_driver_register - Register device driver hooks
726 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
731 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) {
736 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
738 /* call per pci device probe entry point */
739 list_for_each_entry(ioc, &ioc_list, list) {
740 if(dd_cbfunc->probe) {
741 error = dd_cbfunc->probe(ioc->pcidev,
742 ioc->pcidev->driver->id_table);
751 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
753 * mpt_device_driver_deregister - DeRegister device driver hooks
756 mpt_device_driver_deregister(int cb_idx)
758 struct mpt_pci_driver *dd_cbfunc;
761 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
764 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
766 list_for_each_entry(ioc, &ioc_list, list) {
767 if (dd_cbfunc->remove)
768 dd_cbfunc->remove(ioc->pcidev);
771 MptDeviceDriverHandlers[cb_idx] = NULL;
775 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
777 * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
778 * allocated per MPT adapter.
779 * @handle: Handle of registered MPT protocol driver
780 * @ioc: Pointer to MPT adapter structure
782 * Returns pointer to a MPT request frame or %NULL if none are available
783 * or IOC is not active.
786 mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc)
790 u16 req_idx; /* Request index */
792 /* validate handle and ioc identifier */
796 printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n");
799 /* If interrupts are not attached, do not return a request frame */
803 spin_lock_irqsave(&ioc->FreeQlock, flags);
804 if (!list_empty(&ioc->FreeQ)) {
807 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
808 u.frame.linkage.list);
809 list_del(&mf->u.frame.linkage.list);
810 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
811 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
813 req_idx = cpu_to_le16(req_offset / ioc->req_sz);
814 mf->u.frame.hwhdr.msgctxu.fld.req_idx = req_idx;
815 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
816 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; /* Default, will be changed if necessary in SG generation */
823 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
827 printk(KERN_WARNING "IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", ioc->mfcnt, ioc->req_depth);
829 if (mfcounter == PRINT_MF_COUNT)
830 printk(KERN_INFO "MF Count 0x%x Max 0x%x \n", ioc->mfcnt, ioc->req_depth);
833 dmfprintk((KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",
834 ioc->name, handle, ioc->id, mf));
838 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
840 * mpt_put_msg_frame - Send a protocol specific MPT request frame
842 * @handle: Handle of registered MPT protocol driver
843 * @ioc: Pointer to MPT adapter structure
844 * @mf: Pointer to MPT request frame
846 * This routine posts a MPT request frame to the request post FIFO of a
847 * specific MPT adapter.
850 mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
854 u16 req_idx; /* Request index */
856 /* ensure values are reset properly! */
857 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
858 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
860 req_idx = cpu_to_le16(req_offset / ioc->req_sz);
861 mf->u.frame.hwhdr.msgctxu.fld.req_idx = req_idx;
862 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
864 #ifdef MPT_DEBUG_MSG_FRAME
866 u32 *m = mf->u.frame.hwhdr.__hdr;
869 printk(KERN_INFO MYNAM ": %s: About to Put msg frame @ %p:\n" KERN_INFO " ",
871 n = ioc->req_sz/4 - 1;
874 for (ii=0; ii<=n; ii++) {
875 if (ii && ((ii%8)==0))
876 printk("\n" KERN_INFO " ");
877 printk(" %08x", le32_to_cpu(m[ii]));
883 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
884 dsgprintk((MYIOC_s_INFO_FMT "mf_dma_addr=%x req_idx=%d RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx, ioc->RequestNB[req_idx]));
885 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
888 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
890 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
891 * @handle: Handle of registered MPT protocol driver
892 * @ioc: Pointer to MPT adapter structure
893 * @mf: Pointer to MPT request frame
895 * This routine places a MPT request frame back on the MPT adapter's
899 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
903 /* Put Request back on FreeQ! */
904 spin_lock_irqsave(&ioc->FreeQlock, flags);
905 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
909 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
912 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
914 * mpt_add_sge - Place a simple SGE at address pAddr.
915 * @pAddr: virtual address for SGE
916 * @flagslength: SGE flags and data transfer length
917 * @dma_addr: Physical address
919 * This routine places a MPT request frame back on the MPT adapter's
923 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
925 if (sizeof(dma_addr_t) == sizeof(u64)) {
926 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
927 u32 tmp = dma_addr & 0xFFFFFFFF;
929 pSge->FlagsLength = cpu_to_le32(flagslength);
930 pSge->Address.Low = cpu_to_le32(tmp);
931 tmp = (u32) ((u64)dma_addr >> 32);
932 pSge->Address.High = cpu_to_le32(tmp);
935 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
936 pSge->FlagsLength = cpu_to_le32(flagslength);
937 pSge->Address = cpu_to_le32(dma_addr);
941 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
943 * mpt_send_handshake_request - Send MPT request via doorbell
945 * @handle: Handle of registered MPT protocol driver
946 * @ioc: Pointer to MPT adapter structure
947 * @reqBytes: Size of the request in bytes
948 * @req: Pointer to MPT request frame
949 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
951 * This routine is used exclusively to send MptScsiTaskMgmt
952 * requests since they are required to be sent via doorbell handshake.
954 * NOTE: It is the callers responsibility to byte-swap fields in the
955 * request which are greater than 1 byte in size.
957 * Returns 0 for success, non-zero for failure.
960 mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
966 /* State is known to be good upon entering
967 * this function so issue the bus reset
972 * Emulate what mpt_put_msg_frame() does /wrt to sanity
973 * setting cb_idx/req_idx. But ONLY if this request
974 * is in proper (pre-alloc'd) request buffer range...
976 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
977 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
978 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
979 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
980 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
983 /* Make sure there are no doorbells */
984 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
986 CHIPREG_WRITE32(&ioc->chip->Doorbell,
987 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
988 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
990 /* Wait for IOC doorbell int */
991 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
995 /* Read doorbell and check for active bit */
996 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
999 dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
1002 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1004 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1008 /* Send request via doorbell handshake */
1009 req_as_bytes = (u8 *) req;
1010 for (ii = 0; ii < reqBytes/4; ii++) {
1013 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1014 (req_as_bytes[(ii*4) + 1] << 8) |
1015 (req_as_bytes[(ii*4) + 2] << 16) |
1016 (req_as_bytes[(ii*4) + 3] << 24));
1017 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1018 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1024 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1029 /* Make sure there are no doorbells */
1030 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1035 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1037 * mpt_verify_adapter - Given a unique IOC identifier, set pointer to
1038 * the associated MPT adapter structure.
1039 * @iocid: IOC unique identifier (integer)
1040 * @iocpp: Pointer to pointer to IOC adapter
1042 * Returns iocid and sets iocpp.
1045 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1049 list_for_each_entry(ioc,&ioc_list,list) {
1050 if (ioc->id == iocid) {
1060 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1062 * mptbase_probe - Install a PCI intelligent MPT adapter.
1063 * @pdev: Pointer to pci_dev structure
1065 * This routine performs all the steps necessary to bring the IOC of
1066 * a MPT adapter to a OPERATIONAL state. This includes registering
1067 * memory regions, registering the interrupt, and allocating request
1068 * and reply memory pools.
1070 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1073 * Returns 0 for success, non-zero for failure.
1075 * TODO: Add support for polled controllers
1077 static int __devinit
1078 mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1082 unsigned long mem_phys;
1088 u64 mask = 0xffffffffffffffffULL;
1091 static int mpt_ids = 0;
1092 #ifdef CONFIG_PROC_FS
1093 struct proc_dir_entry *dent, *ent;
1096 if (pci_enable_device(pdev))
1099 dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1101 if (!pci_set_dma_mask(pdev, mask)) {
1102 dprintk((KERN_INFO MYNAM
1103 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1104 } else if (pci_set_dma_mask(pdev, (u64) 0xffffffff)) {
1105 printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1109 if (!pci_set_consistent_dma_mask(pdev, mask))
1110 dprintk((KERN_INFO MYNAM
1111 ": Using 64 bit consistent mask\n"));
1113 dprintk((KERN_INFO MYNAM
1114 ": Not using 64 bit consistent mask\n"));
1116 ioc = kmalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1118 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1121 memset(ioc, 0, sizeof(MPT_ADAPTER));
1122 ioc->alloc_total = sizeof(MPT_ADAPTER);
1123 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1124 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1127 ioc->diagPending = 0;
1128 spin_lock_init(&ioc->diagLock);
1130 /* Initialize the event logging.
1132 ioc->eventTypes = 0; /* None */
1133 ioc->eventContext = 0;
1134 ioc->eventLogSize = 0;
1141 ioc->cached_fw = NULL;
1143 /* Initilize SCSI Config Data structure
1145 memset(&ioc->spi_data, 0, sizeof(ScsiCfgData));
1147 /* Initialize the running configQ head.
1149 INIT_LIST_HEAD(&ioc->configQ);
1151 /* Find lookup slot. */
1152 INIT_LIST_HEAD(&ioc->list);
1153 ioc->id = mpt_ids++;
1155 mem_phys = msize = 0;
1157 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1158 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1159 /* Get I/O space! */
1160 port = pci_resource_start(pdev, ii);
1161 psize = pci_resource_len(pdev,ii);
1164 mem_phys = pci_resource_start(pdev, ii);
1165 msize = pci_resource_len(pdev,ii);
1169 ioc->mem_size = msize;
1171 if (ii == DEVICE_COUNT_RESOURCE) {
1172 printk(KERN_ERR MYNAM ": ERROR - MPT adapter has no memory regions defined!\n");
1177 dinitprintk((KERN_INFO MYNAM ": MPT adapter @ %lx, msize=%dd bytes\n", mem_phys, msize));
1178 dinitprintk((KERN_INFO MYNAM ": (port i/o @ %lx, psize=%dd bytes)\n", port, psize));
1181 /* Get logical ptr for PciMem0 space */
1182 /*mem = ioremap(mem_phys, msize);*/
1183 mem = ioremap(mem_phys, 0x100);
1185 printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1190 dinitprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1192 dinitprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1193 &ioc->facts, &ioc->pfacts[0]));
1195 ioc->mem_phys = mem_phys;
1196 ioc->chip = (SYSIF_REGS __iomem *)mem;
1198 /* Save Port IO values in case we need to do downloadboot */
1200 u8 *pmem = (u8*)port;
1201 ioc->pio_mem_phys = port;
1202 ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1205 if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC909) {
1206 ioc->prod_name = "LSIFC909";
1209 if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
1210 ioc->prod_name = "LSIFC929";
1213 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) {
1214 ioc->prod_name = "LSIFC919";
1217 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) {
1218 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1220 if (revision < XL_929) {
1221 ioc->prod_name = "LSIFC929X";
1222 /* 929X Chip Fix. Set Split transactions level
1223 * for PCIX. Set MOST bits to zero.
1225 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1227 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1229 ioc->prod_name = "LSIFC929XL";
1230 /* 929XL Chip Fix. Set MMRBC to 0x08.
1232 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1234 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1237 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) {
1238 ioc->prod_name = "LSIFC919X";
1240 /* 919X Chip Fix. Set Split transactions level
1241 * for PCIX. Set MOST bits to zero.
1243 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1245 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1247 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
1248 ioc->prod_name = "LSI53C1030";
1249 ioc->bus_type = SCSI;
1250 /* 1030 Chip Fix. Disable Split transactions
1251 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1253 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1254 if (revision < C0_1030) {
1255 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1257 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1260 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
1261 ioc->prod_name = "LSI53C1035";
1262 ioc->bus_type = SCSI;
1265 sprintf(ioc->name, "ioc%d", ioc->id);
1267 spin_lock_init(&ioc->FreeQlock);
1270 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1272 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1274 /* Set lookup ptr. */
1275 list_add_tail(&ioc->list, &ioc_list);
1279 r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc);
1283 printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %d!\n",
1284 ioc->name, pdev->irq);
1286 printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %s!\n",
1287 ioc->name, __irq_itoa(pdev->irq));
1289 list_del(&ioc->list);
1295 ioc->pci_irq = pdev->irq;
1297 pci_set_master(pdev); /* ?? */
1298 pci_set_drvdata(pdev, ioc);
1301 dprintk((KERN_INFO MYNAM ": %s installed at interrupt %d\n", ioc->name, pdev->irq));
1303 dprintk((KERN_INFO MYNAM ": %s installed at interrupt %s\n", ioc->name, __irq_itoa(pdev->irq)));
1307 /* NEW! 20010220 -sralston
1308 * Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1310 mpt_detect_bound_ports(ioc, pdev);
1312 if ((r = mpt_do_ioc_recovery(ioc,
1313 MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0) {
1314 printk(KERN_WARNING MYNAM
1315 ": WARNING - %s did not initialize properly! (%d)\n",
1318 list_del(&ioc->list);
1319 free_irq(ioc->pci_irq, ioc);
1322 pci_set_drvdata(pdev, NULL);
1326 /* call per device driver probe entry point */
1327 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1328 if(MptDeviceDriverHandlers[ii] &&
1329 MptDeviceDriverHandlers[ii]->probe) {
1330 MptDeviceDriverHandlers[ii]->probe(pdev,id);
1334 #ifdef CONFIG_PROC_FS
1336 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1338 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1340 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1342 ent->read_proc = procmpt_iocinfo_read;
1345 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1347 ent->read_proc = procmpt_summary_read;
1356 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1358 * mptbase_remove - Remove a PCI intelligent MPT adapter.
1359 * @pdev: Pointer to pci_dev structure
1363 static void __devexit
1364 mptbase_remove(struct pci_dev *pdev)
1366 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1370 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1371 remove_proc_entry(pname, NULL);
1372 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1373 remove_proc_entry(pname, NULL);
1374 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1375 remove_proc_entry(pname, NULL);
1377 /* call per device driver remove entry point */
1378 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1379 if(MptDeviceDriverHandlers[ii] &&
1380 MptDeviceDriverHandlers[ii]->remove) {
1381 MptDeviceDriverHandlers[ii]->remove(pdev);
1385 /* Disable interrupts! */
1386 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1389 synchronize_irq(pdev->irq);
1391 /* Clear any lingering interrupt */
1392 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1394 CHIPREG_READ32(&ioc->chip->IntStatus);
1396 mpt_adapter_dispose(ioc);
1398 pci_set_drvdata(pdev, NULL);
1401 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1403 * mptbase_shutdown -
1407 mptbase_shutdown(struct device * dev)
1411 /* call per device driver shutdown entry point */
1412 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1413 if(MptDeviceDriverHandlers[ii] &&
1414 MptDeviceDriverHandlers[ii]->shutdown) {
1415 MptDeviceDriverHandlers[ii]->shutdown(dev);
1422 /**************************************************************************
1426 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1428 * mptbase_suspend - Fusion MPT base driver suspend routine.
1433 mptbase_suspend(struct pci_dev *pdev, u32 state)
1436 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1442 device_state=1; /* D1 */;
1446 device_state=3; /* D3 */;
1449 return -EAGAIN /*FIXME*/;
1453 printk(MYIOC_s_INFO_FMT
1454 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1455 ioc->name, pdev, pci_name(pdev), device_state);
1457 /* call per device driver suspend entry point */
1458 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1459 if(MptDeviceDriverHandlers[ii] &&
1460 MptDeviceDriverHandlers[ii]->suspend) {
1461 MptDeviceDriverHandlers[ii]->suspend(pdev, state);
1465 pci_save_state(pdev);
1467 /* put ioc into READY_STATE */
1468 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1469 printk(MYIOC_s_ERR_FMT
1470 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1473 /* disable interrupts */
1474 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1477 /* Clear any lingering interrupt */
1478 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1480 pci_disable_device(pdev);
1481 pci_set_power_state(pdev, device_state);
1486 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1488 * mptbase_resume - Fusion MPT base driver resume routine.
1493 mptbase_resume(struct pci_dev *pdev)
1495 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1496 u32 device_state = pdev->current_state;
1500 printk(MYIOC_s_INFO_FMT
1501 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1502 ioc->name, pdev, pci_name(pdev), device_state);
1504 pci_set_power_state(pdev, 0);
1505 pci_restore_state(pdev);
1506 pci_enable_device(pdev);
1508 /* enable interrupts */
1509 CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
1512 /* F/W not running */
1513 if(!CHIPREG_READ32(&ioc->chip->Doorbell)) {
1514 /* enable domain validation flags */
1515 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
1516 ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_NEED_DV;
1520 printk(MYIOC_s_INFO_FMT
1521 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1523 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1524 CHIPREG_READ32(&ioc->chip->Doorbell));
1526 /* bring ioc to operational state */
1527 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1528 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1529 printk(MYIOC_s_INFO_FMT
1530 "pci-resume: Cannot recover, error:[%x]\n",
1531 ioc->name, recovery_state);
1533 printk(MYIOC_s_INFO_FMT
1534 "pci-resume: success\n", ioc->name);
1537 /* call per device driver resume entry point */
1538 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1539 if(MptDeviceDriverHandlers[ii] &&
1540 MptDeviceDriverHandlers[ii]->resume) {
1541 MptDeviceDriverHandlers[ii]->resume(pdev);
1549 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1551 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1552 * @ioc: Pointer to MPT adapter structure
1553 * @reason: Event word / reason
1554 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1556 * This routine performs all the steps necessary to bring the IOC
1557 * to a OPERATIONAL state.
1559 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1564 * -1 if failed to get board READY
1565 * -2 if READY but IOCFacts Failed
1566 * -3 if READY but PrimeIOCFifos Failed
1567 * -4 if READY but IOCInit Failed
1570 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1572 int hard_reset_done = 0;
1573 int alt_ioc_ready = 0;
1579 int reset_alt_ioc_active = 0;
1581 printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1582 ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1584 /* Disable reply interrupts (also blocks FreeQ) */
1585 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1589 if (ioc->alt_ioc->active)
1590 reset_alt_ioc_active = 1;
1592 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1593 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1594 ioc->alt_ioc->active = 0;
1598 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1601 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1602 if (hard_reset_done == -4) {
1603 printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1606 if (reset_alt_ioc_active && ioc->alt_ioc) {
1607 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1608 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1609 ioc->alt_ioc->name));
1610 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
1611 ioc->alt_ioc->active = 1;
1615 printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1621 /* hard_reset_done = 0 if a soft reset was performed
1622 * and 1 if a hard reset was performed.
1624 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1625 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1628 printk(KERN_WARNING MYNAM
1629 ": alt-%s: Not ready WARNING!\n",
1630 ioc->alt_ioc->name);
1633 for (ii=0; ii<5; ii++) {
1634 /* Get IOC facts! Allow 5 retries */
1635 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1641 dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1643 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1644 MptDisplayIocCapabilities(ioc);
1647 if (alt_ioc_ready) {
1648 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1649 dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1650 /* Retry - alt IOC was initialized once
1652 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1655 dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1657 reset_alt_ioc_active = 0;
1658 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1659 MptDisplayIocCapabilities(ioc->alt_ioc);
1663 /* Prime reply & request queues!
1664 * (mucho alloc's) Must be done prior to
1665 * init as upper addresses are needed for init.
1666 * If fails, continue with alt-ioc processing
1668 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
1671 /* May need to check/upload firmware & data here!
1672 * If fails, continue with alt-ioc processing
1674 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
1677 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
1678 printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1679 ioc->alt_ioc->name, rc);
1681 reset_alt_ioc_active = 0;
1684 if (alt_ioc_ready) {
1685 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
1687 reset_alt_ioc_active = 0;
1688 printk(KERN_WARNING MYNAM
1689 ": alt-%s: (%d) init failure WARNING!\n",
1690 ioc->alt_ioc->name, rc);
1694 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
1695 if (ioc->upload_fw) {
1696 ddlprintk((MYIOC_s_INFO_FMT
1697 "firmware upload required!\n", ioc->name));
1699 /* Controller is not operational, cannot do upload
1702 rc = mpt_do_upload(ioc, sleepFlag);
1704 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
1710 /* Enable! (reply interrupt) */
1711 CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
1715 if (reset_alt_ioc_active && ioc->alt_ioc) {
1716 /* (re)Enable alt-IOC! (reply interrupt) */
1717 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1718 ioc->alt_ioc->name));
1719 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
1720 ioc->alt_ioc->active = 1;
1723 /* NEW! 20010120 -sralston
1724 * Enable MPT base driver management of EventNotification
1725 * and EventAck handling.
1727 if ((ret == 0) && (!ioc->facts.EventState))
1728 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
1730 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
1731 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
1733 /* (Bugzilla:fibrebugs, #513)
1734 * Bug fix (part 2)! 20010905 -sralston
1735 * Add additional "reason" check before call to GetLanConfigPages
1736 * (combined with GetIoUnitPage2 call). This prevents a somewhat
1737 * recursive scenario; GetLanConfigPages times out, timer expired
1738 * routine calls HardResetHandler, which calls into here again,
1739 * and we try GetLanConfigPages again...
1741 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1742 if (ioc->bus_type == FC) {
1744 * Pre-fetch FC port WWN and stuff...
1745 * (FCPortPage0_t stuff)
1747 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1748 (void) GetFcPortPage0(ioc, ii);
1751 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
1752 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
1754 * Pre-fetch the ports LAN MAC address!
1755 * (LANPage1_t stuff)
1757 (void) GetLanConfigPages(ioc);
1760 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
1761 dprintk((MYIOC_s_INFO_FMT "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
1762 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0] ));
1767 /* Get NVRAM and adapter maximums from SPP 0 and 2
1769 mpt_GetScsiPortSettings(ioc, 0);
1771 /* Get version and length of SDP 1
1773 mpt_readScsiDevicePageHeaders(ioc, 0);
1777 if (ioc->facts.MsgVersion >= 0x0102)
1778 mpt_findImVolumes(ioc);
1780 /* Check, and possibly reset, the coalescing value
1782 mpt_read_ioc_pg_1(ioc);
1784 mpt_read_ioc_pg_4(ioc);
1787 GetIoUnitPage2(ioc);
1791 * Call each currently registered protocol IOC reset handler
1792 * with post-reset indication.
1793 * NOTE: If we're doing _IOC_BRINGUP, there can be no
1794 * MptResetHandlers[] registered yet.
1796 if (hard_reset_done) {
1798 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
1799 if ((ret == 0) && MptResetHandlers[ii]) {
1800 dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
1802 rc += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET);
1806 if (alt_ioc_ready && MptResetHandlers[ii]) {
1807 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
1808 ioc->name, ioc->alt_ioc->name, ii));
1809 rc += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
1813 /* FIXME? Examine results here? */
1819 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1821 * mpt_detect_bound_ports - Search for PCI bus/dev_function
1822 * which matches PCI bus/dev_function (+/-1) for newly discovered 929,
1823 * 929X, 1030 or 1035.
1824 * @ioc: Pointer to MPT adapter structure
1825 * @pdev: Pointer to (struct pci_dev) structure
1827 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
1828 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
1831 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
1833 unsigned int match_lo, match_hi;
1834 MPT_ADAPTER *ioc_srch;
1836 match_lo = pdev->devfn-1;
1837 match_hi = pdev->devfn+1;
1838 dprintk((MYIOC_s_INFO_FMT "PCI bus/devfn=%x/%x, searching for devfn match on %x or %x\n",
1839 ioc->name, pdev->bus->number, pdev->devfn, match_lo, match_hi));
1841 list_for_each_entry(ioc_srch, &ioc_list, list) {
1842 struct pci_dev *_pcidev = ioc_srch->pcidev;
1844 if ((_pcidev->device == pdev->device) &&
1845 (_pcidev->bus->number == pdev->bus->number) &&
1846 (_pcidev->devfn == match_lo || _pcidev->devfn == match_hi) ) {
1847 /* Paranoia checks */
1848 if (ioc->alt_ioc != NULL) {
1849 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1850 ioc->name, ioc->alt_ioc->name);
1852 } else if (ioc_srch->alt_ioc != NULL) {
1853 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1854 ioc_srch->name, ioc_srch->alt_ioc->name);
1857 dprintk((KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
1858 ioc->name, ioc_srch->name));
1859 ioc_srch->alt_ioc = ioc;
1860 ioc->alt_ioc = ioc_srch;
1866 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1868 * mpt_adapter_disable - Disable misbehaving MPT adapter.
1869 * @this: Pointer to MPT adapter structure
1872 mpt_adapter_disable(MPT_ADAPTER *ioc)
1877 if (ioc->cached_fw != NULL) {
1878 ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
1879 if ((ret = mpt_downloadboot(ioc, NO_SLEEP)) < 0) {
1880 printk(KERN_WARNING MYNAM
1881 ": firmware downloadboot failure (%d)!\n", ret);
1885 /* Disable adapter interrupts! */
1886 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1888 /* Clear any lingering interrupt */
1889 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1891 if (ioc->alloc != NULL) {
1893 dexitprintk((KERN_INFO MYNAM ": %s.free @ %p, sz=%d bytes\n",
1894 ioc->name, ioc->alloc, ioc->alloc_sz));
1895 pci_free_consistent(ioc->pcidev, sz,
1896 ioc->alloc, ioc->alloc_dma);
1897 ioc->reply_frames = NULL;
1898 ioc->req_frames = NULL;
1900 ioc->alloc_total -= sz;
1903 if (ioc->sense_buf_pool != NULL) {
1904 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
1905 pci_free_consistent(ioc->pcidev, sz,
1906 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
1907 ioc->sense_buf_pool = NULL;
1908 ioc->alloc_total -= sz;
1911 if (ioc->events != NULL){
1912 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
1915 ioc->alloc_total -= sz;
1918 if (ioc->cached_fw != NULL) {
1919 sz = ioc->facts.FWImageSize;
1920 pci_free_consistent(ioc->pcidev, sz,
1921 ioc->cached_fw, ioc->cached_fw_dma);
1922 ioc->cached_fw = NULL;
1923 ioc->alloc_total -= sz;
1926 if (ioc->spi_data.nvram != NULL) {
1927 kfree(ioc->spi_data.nvram);
1928 ioc->spi_data.nvram = NULL;
1931 if (ioc->spi_data.pIocPg3 != NULL) {
1932 kfree(ioc->spi_data.pIocPg3);
1933 ioc->spi_data.pIocPg3 = NULL;
1936 if (ioc->spi_data.pIocPg4 != NULL) {
1937 sz = ioc->spi_data.IocPg4Sz;
1938 pci_free_consistent(ioc->pcidev, sz,
1939 ioc->spi_data.pIocPg4,
1940 ioc->spi_data.IocPg4_dma);
1941 ioc->spi_data.pIocPg4 = NULL;
1942 ioc->alloc_total -= sz;
1945 if (ioc->ReqToChain != NULL) {
1946 kfree(ioc->ReqToChain);
1947 kfree(ioc->RequestNB);
1948 ioc->ReqToChain = NULL;
1951 if (ioc->ChainToChain != NULL) {
1952 kfree(ioc->ChainToChain);
1953 ioc->ChainToChain = NULL;
1957 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1959 * mpt_adapter_dispose - Free all resources associated with a MPT
1961 * @ioc: Pointer to MPT adapter structure
1963 * This routine unregisters h/w resources and frees all alloc'd memory
1964 * associated with a MPT adapter structure.
1967 mpt_adapter_dispose(MPT_ADAPTER *ioc)
1970 int sz_first, sz_last;
1972 sz_first = ioc->alloc_total;
1974 mpt_adapter_disable(ioc);
1976 if (ioc->pci_irq != -1) {
1977 free_irq(ioc->pci_irq, ioc);
1981 if (ioc->memmap != NULL)
1982 iounmap(ioc->memmap);
1984 #if defined(CONFIG_MTRR) && 0
1985 if (ioc->mtrr_reg > 0) {
1986 mtrr_del(ioc->mtrr_reg, 0, 0);
1987 dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
1991 /* Zap the adapter lookup ptr! */
1992 list_del(&ioc->list);
1994 sz_last = ioc->alloc_total;
1995 dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
1996 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2001 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2003 * MptDisplayIocCapabilities - Disply IOC's capacilities.
2004 * @ioc: Pointer to MPT adapter structure
2007 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2011 printk(KERN_INFO "%s: ", ioc->name);
2012 if (ioc->prod_name && strlen(ioc->prod_name) > 3)
2013 printk("%s: ", ioc->prod_name+3);
2014 printk("Capabilities={");
2016 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2017 printk("Initiator");
2021 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2022 printk("%sTarget", i ? "," : "");
2026 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2027 printk("%sLAN", i ? "," : "");
2033 * This would probably evoke more questions than it's worth
2035 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2036 printk("%sLogBusAddr", i ? "," : "");
2044 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2046 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2047 * @ioc: Pointer to MPT_ADAPTER structure
2048 * @force: Force hard KickStart of IOC
2049 * @sleepFlag: Specifies whether the process can sleep
2052 * 1 - DIAG reset and READY
2053 * 0 - READY initially OR soft reset and READY
2054 * -1 - Any failure on KickStart
2055 * -2 - Msg Unit Reset Failed
2056 * -3 - IO Unit Reset Failed
2057 * -4 - IOC owned by a PEER
2060 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2065 int hard_reset_done = 0;
2070 /* Get current [raw] IOC state */
2071 ioc_state = mpt_GetIocState(ioc, 0);
2072 dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
2075 * Check to see if IOC got left/stuck in doorbell handshake
2076 * grip of death. If so, hard reset the IOC.
2078 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2080 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2084 /* Is it already READY? */
2085 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2089 * Check to see if IOC is in FAULT state.
2091 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2093 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2095 printk(KERN_WARNING " FAULT code = %04xh\n",
2096 ioc_state & MPI_DOORBELL_DATA_MASK);
2100 * Hmmm... Did it get left operational?
2102 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2103 dinitprintk((MYIOC_s_WARN_FMT "IOC operational unexpected\n",
2107 * If PCI Peer, exit.
2108 * Else, if no fault conditions are present, issue a MessageUnitReset
2109 * Else, fall through to KickStart case
2111 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2112 dprintk((KERN_WARNING MYNAM
2113 ": whoinit 0x%x\n statefault %d force %d\n",
2114 whoinit, statefault, force));
2115 if (whoinit == MPI_WHOINIT_PCI_PEER)
2118 if ((statefault == 0 ) && (force == 0)) {
2119 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2126 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2127 if (hard_reset_done < 0)
2131 * Loop here waiting for IOC to come READY.
2134 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
2136 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2137 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2139 * BIOS or previous driver load left IOC in OP state.
2140 * Reset messaging FIFOs.
2142 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2143 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2146 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2148 * Something is wrong. Try to get IOC back
2151 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2152 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2159 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2160 ioc->name, (int)((ii+5)/HZ));
2164 if (sleepFlag == CAN_SLEEP) {
2165 msleep_interruptible(1);
2167 mdelay (1); /* 1 msec delay */
2172 if (statefault < 3) {
2173 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2175 statefault==1 ? "stuck handshake" : "IOC FAULT");
2178 return hard_reset_done;
2181 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2183 * mpt_GetIocState - Get the current state of a MPT adapter.
2184 * @ioc: Pointer to MPT_ADAPTER structure
2185 * @cooked: Request raw or cooked IOC state
2187 * Returns all IOC Doorbell register bits if cooked==0, else just the
2188 * Doorbell bits in MPI_IOC_STATE_MASK.
2191 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2196 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2197 // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2198 sc = s & MPI_IOC_STATE_MASK;
2201 ioc->last_state = sc;
2203 return cooked ? sc : s;
2206 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2208 * GetIocFacts - Send IOCFacts request to MPT adapter.
2209 * @ioc: Pointer to MPT_ADAPTER structure
2210 * @sleepFlag: Specifies whether the process can sleep
2211 * @reason: If recovery, only update facts.
2213 * Returns 0 for success, non-zero for failure.
2216 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2218 IOCFacts_t get_facts;
2219 IOCFactsReply_t *facts;
2227 /* IOC *must* NOT be in RESET state! */
2228 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2229 printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2235 facts = &ioc->facts;
2237 /* Destination (reply area)... */
2238 reply_sz = sizeof(*facts);
2239 memset(facts, 0, reply_sz);
2241 /* Request area (get_facts on the stack right now!) */
2242 req_sz = sizeof(get_facts);
2243 memset(&get_facts, 0, req_sz);
2245 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2246 /* Assert: All other get_facts fields are zero! */
2248 dinitprintk((MYIOC_s_INFO_FMT
2249 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2250 ioc->name, req_sz, reply_sz));
2252 /* No non-zero fields in the get_facts request are greater than
2253 * 1 byte in size, so we can just fire it off as is.
2255 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2256 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2261 * Now byte swap (GRRR) the necessary fields before any further
2262 * inspection of reply contents.
2264 * But need to do some sanity checks on MsgLength (byte) field
2265 * to make sure we don't zero IOC's req_sz!
2267 /* Did we get a valid reply? */
2268 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2269 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2271 * If not been here, done that, save off first WhoInit value
2273 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2274 ioc->FirstWhoInit = facts->WhoInit;
2277 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2278 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2279 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2280 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2281 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2282 status = facts->IOCStatus & MPI_IOCSTATUS_MASK;
2283 /* CHECKME! IOCStatus, IOCLogInfo */
2285 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2286 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2289 * FC f/w version changed between 1.1 and 1.2
2290 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2291 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2293 if (facts->MsgVersion < 0x0102) {
2295 * Handle old FC f/w style, convert to new...
2297 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2298 facts->FWVersion.Word =
2299 ((oldv<<12) & 0xFF000000) |
2300 ((oldv<<8) & 0x000FFF00);
2302 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2304 facts->ProductID = le16_to_cpu(facts->ProductID);
2305 facts->CurrentHostMfaHighAddr =
2306 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2307 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2308 facts->CurrentSenseBufferHighAddr =
2309 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2310 facts->CurReplyFrameSize =
2311 le16_to_cpu(facts->CurReplyFrameSize);
2314 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2315 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2316 * to 14 in MPI-1.01.0x.
2318 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2319 facts->MsgVersion > 0x0100) {
2320 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2323 sz = facts->FWImageSize;
2328 facts->FWImageSize = sz;
2330 if (!facts->RequestFrameSize) {
2331 /* Something is wrong! */
2332 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2337 r = sz = le32_to_cpu(facts->BlockSize);
2338 vv = ((63 / (sz * 4)) + 1) & 0x03;
2339 ioc->NB_for_64_byte_frame = vv;
2345 ioc->NBShiftFactor = shiftFactor;
2346 dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2347 ioc->name, vv, shiftFactor, r));
2349 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2351 * Set values for this IOC's request & reply frame sizes,
2352 * and request & reply queue depths...
2354 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2355 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2356 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2357 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2359 dinitprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
2360 ioc->name, ioc->reply_sz, ioc->reply_depth));
2361 dinitprintk((MYIOC_s_INFO_FMT "req_sz =%3d, req_depth =%4d\n",
2362 ioc->name, ioc->req_sz, ioc->req_depth));
2364 /* Get port facts! */
2365 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2369 printk(MYIOC_s_ERR_FMT
2370 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2371 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2372 RequestFrameSize)/sizeof(u32)));
2379 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2381 * GetPortFacts - Send PortFacts request to MPT adapter.
2382 * @ioc: Pointer to MPT_ADAPTER structure
2383 * @portnum: Port number
2384 * @sleepFlag: Specifies whether the process can sleep
2386 * Returns 0 for success, non-zero for failure.
2389 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2391 PortFacts_t get_pfacts;
2392 PortFactsReply_t *pfacts;
2397 /* IOC *must* NOT be in RESET state! */
2398 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2399 printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2405 pfacts = &ioc->pfacts[portnum];
2407 /* Destination (reply area)... */
2408 reply_sz = sizeof(*pfacts);
2409 memset(pfacts, 0, reply_sz);
2411 /* Request area (get_pfacts on the stack right now!) */
2412 req_sz = sizeof(get_pfacts);
2413 memset(&get_pfacts, 0, req_sz);
2415 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2416 get_pfacts.PortNumber = portnum;
2417 /* Assert: All other get_pfacts fields are zero! */
2419 dinitprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
2420 ioc->name, portnum));
2422 /* No non-zero fields in the get_pfacts request are greater than
2423 * 1 byte in size, so we can just fire it off as is.
2425 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2426 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2430 /* Did we get a valid reply? */
2432 /* Now byte swap the necessary fields in the response. */
2433 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2434 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2435 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2436 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2437 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2438 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2439 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2440 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2441 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2446 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2448 * SendIocInit - Send IOCInit request to MPT adapter.
2449 * @ioc: Pointer to MPT_ADAPTER structure
2450 * @sleepFlag: Specifies whether the process can sleep
2452 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2454 * Returns 0 for success, non-zero for failure.
2457 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2460 MPIDefaultReply_t init_reply;
2466 memset(&ioc_init, 0, sizeof(ioc_init));
2467 memset(&init_reply, 0, sizeof(init_reply));
2469 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2470 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2472 /* If we are in a recovery mode and we uploaded the FW image,
2473 * then this pointer is not NULL. Skip the upload a second time.
2474 * Set this flag if cached_fw set for either IOC.
2476 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2480 ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
2481 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2483 if (ioc->bus_type == FC)
2484 ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
2486 ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
2488 ioc_init.MaxBuses = MPT_MAX_BUS;
2490 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2492 if (sizeof(dma_addr_t) == sizeof(u64)) {
2493 /* Save the upper 32-bits of the request
2494 * (reply) and sense buffers.
2496 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2497 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2499 /* Force 32-bit addressing */
2500 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2501 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2504 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2505 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2507 dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
2508 ioc->name, &ioc_init));
2510 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2511 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2515 /* No need to byte swap the multibyte fields in the reply
2516 * since we don't even look at it's contents.
2519 dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
2520 ioc->name, &ioc_init));
2522 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0)
2525 /* YIKES! SUPER IMPORTANT!!!
2526 * Poll IocState until _OPERATIONAL while IOC is doing
2527 * LoopInit and TargetDiscovery!
2530 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2531 state = mpt_GetIocState(ioc, 1);
2532 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2533 if (sleepFlag == CAN_SLEEP) {
2534 msleep_interruptible(1);
2540 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2541 ioc->name, (int)((count+5)/HZ));
2545 state = mpt_GetIocState(ioc, 1);
2548 dhsprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2554 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2556 * SendPortEnable - Send PortEnable request to MPT adapter port.
2557 * @ioc: Pointer to MPT_ADAPTER structure
2558 * @portnum: Port number to enable
2559 * @sleepFlag: Specifies whether the process can sleep
2561 * Send PortEnable to bring IOC to OPERATIONAL state.
2563 * Returns 0 for success, non-zero for failure.
2566 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2568 PortEnable_t port_enable;
2569 MPIDefaultReply_t reply_buf;
2574 /* Destination... */
2575 reply_sz = sizeof(MPIDefaultReply_t);
2576 memset(&reply_buf, 0, reply_sz);
2578 req_sz = sizeof(PortEnable_t);
2579 memset(&port_enable, 0, req_sz);
2581 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2582 port_enable.PortNumber = portnum;
2583 /* port_enable.ChainOffset = 0; */
2584 /* port_enable.MsgFlags = 0; */
2585 /* port_enable.MsgContext = 0; */
2587 dinitprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
2588 ioc->name, portnum, &port_enable));
2590 /* RAID FW may take a long time to enable
2592 if (ioc->bus_type == FC) {
2593 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2594 reply_sz, (u16*)&reply_buf, 65 /*seconds*/, sleepFlag);
2596 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2597 reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag);
2603 /* We do not even look at the reply, so we need not
2604 * swap the multi-byte fields.
2611 * ioc: Pointer to MPT_ADAPTER structure
2612 * size - total FW bytes
2615 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
2618 return; /* use already allocated memory */
2619 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2620 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
2621 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
2623 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
2624 ioc->alloc_total += size;
2628 * If alt_img is NULL, delete from ioc structure.
2629 * Else, delete a secondary image in same format.
2632 mpt_free_fw_memory(MPT_ADAPTER *ioc)
2636 sz = ioc->facts.FWImageSize;
2637 dinitprintk((KERN_WARNING MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
2638 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2639 pci_free_consistent(ioc->pcidev, sz,
2640 ioc->cached_fw, ioc->cached_fw_dma);
2641 ioc->cached_fw = NULL;
2647 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2649 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
2650 * @ioc: Pointer to MPT_ADAPTER structure
2651 * @sleepFlag: Specifies whether the process can sleep
2653 * Returns 0 for success, >0 for handshake failure
2654 * <0 for fw upload failure.
2656 * Remark: If bound IOC and a successful FWUpload was performed
2657 * on the bound IOC, the second image is discarded
2658 * and memory is free'd. Both channels must upload to prevent
2659 * IOC from running in degraded mode.
2662 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2664 u8 request[ioc->req_sz];
2665 u8 reply[sizeof(FWUploadReply_t)];
2666 FWUpload_t *prequest;
2667 FWUploadReply_t *preply;
2668 FWUploadTCSGE_t *ptcsge;
2671 int ii, sz, reply_sz;
2674 /* If the image size is 0, we are done.
2676 if ((sz = ioc->facts.FWImageSize) == 0)
2679 mpt_alloc_fw_memory(ioc, sz);
2681 dinitprintk((KERN_WARNING MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
2682 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2684 if (ioc->cached_fw == NULL) {
2690 prequest = (FWUpload_t *)&request;
2691 preply = (FWUploadReply_t *)&reply;
2693 /* Destination... */
2694 memset(prequest, 0, ioc->req_sz);
2696 reply_sz = sizeof(reply);
2697 memset(preply, 0, reply_sz);
2699 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
2700 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
2702 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
2703 ptcsge->DetailsLength = 12;
2704 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
2705 ptcsge->ImageSize = cpu_to_le32(sz);
2707 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
2709 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
2710 mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
2712 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
2713 dinitprintk((KERN_WARNING MYNAM "Sending FW Upload (req @ %p) sgeoffset=%d \n",
2714 prequest, sgeoffset));
2715 DBG_DUMP_FW_REQUEST_FRAME(prequest)
2717 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
2718 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
2720 dinitprintk((KERN_WARNING MYNAM "FW Upload completed rc=%x \n", ii));
2722 cmdStatus = -EFAULT;
2724 /* Handshake transfer was complete and successful.
2725 * Check the Reply Frame.
2727 int status, transfer_sz;
2728 status = le16_to_cpu(preply->IOCStatus);
2729 if (status == MPI_IOCSTATUS_SUCCESS) {
2730 transfer_sz = le32_to_cpu(preply->ActualImageSize);
2731 if (transfer_sz == sz)
2735 dinitprintk((MYIOC_s_INFO_FMT ": do_upload status %d \n",
2736 ioc->name, cmdStatus));
2741 ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
2743 mpt_free_fw_memory(ioc);
2749 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2751 * mpt_downloadboot - DownloadBoot code
2752 * @ioc: Pointer to MPT_ADAPTER structure
2753 * @flag: Specify which part of IOC memory is to be uploaded.
2754 * @sleepFlag: Specifies whether the process can sleep
2756 * FwDownloadBoot requires Programmed IO access.
2758 * Returns 0 for success
2759 * -1 FW Image size is 0
2760 * -2 No valid cached_fw Pointer
2761 * <0 for fw upload failure.
2764 mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
2766 MpiFwHeader_t *pFwHeader;
2767 MpiExtImageHeader_t *pExtImage;
2777 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x, ioc FW Ptr %p\n",
2778 ioc->name, ioc->facts.FWImageSize, ioc->cached_fw));
2780 if ( ioc->facts.FWImageSize == 0 )
2783 if (ioc->cached_fw == NULL)
2786 /* prevent a second downloadboot and memory free with alt_ioc */
2787 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
2788 ioc->alt_ioc->cached_fw = NULL;
2790 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2791 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2792 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2793 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2794 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2795 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2797 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
2800 if (sleepFlag == CAN_SLEEP) {
2801 msleep_interruptible(1);
2806 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2807 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2809 for (count = 0; count < 30; count ++) {
2810 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2811 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
2812 ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
2817 if (sleepFlag == CAN_SLEEP) {
2818 msleep_interruptible (1000);
2824 if ( count == 30 ) {
2825 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! Unable to RESET_ADAPTER diag0val=%x\n",
2826 ioc->name, diag0val));
2830 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2831 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2832 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2833 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2834 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2835 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2837 /* Set the DiagRwEn and Disable ARM bits */
2838 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
2840 pFwHeader = (MpiFwHeader_t *) ioc->cached_fw;
2841 fwSize = (pFwHeader->ImageSize + 3)/4;
2842 ptrFw = (u32 *) pFwHeader;
2844 /* Write the LoadStartAddress to the DiagRw Address Register
2845 * using Programmed IO
2847 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
2848 ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
2849 ioc->name, pFwHeader->LoadStartAddress));
2851 ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n",
2852 ioc->name, fwSize*4, ptrFw));
2854 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2857 nextImage = pFwHeader->NextImageHeaderOffset;
2859 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
2861 load_addr = pExtImage->LoadStartAddress;
2863 fwSize = (pExtImage->ImageSize + 3) >> 2;
2864 ptrFw = (u32 *)pExtImage;
2866 ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x bytes @ %p load_addr=%x\n",
2867 ioc->name, fwSize*4, ptrFw, load_addr));
2868 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
2871 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2873 nextImage = pExtImage->NextImageHeaderOffset;
2876 /* Write the IopResetVectorRegAddr */
2877 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
2878 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
2880 /* Write the IopResetVectorValue */
2881 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
2882 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
2884 /* Clear the internal flash bad bit - autoincrementing register,
2885 * so must do two writes.
2887 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
2888 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
2889 diagRwData |= 0x4000000;
2890 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
2891 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
2893 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2894 ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, turning off PREVENT_IOC_BOOT, DISABLE_ARM\n",
2895 ioc->name, diag0val));
2896 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM);
2897 ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
2898 ioc->name, diag0val));
2899 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
2901 /* Write 0xFF to reset the sequencer */
2902 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2904 for (count=0; count<HZ*20; count++) {
2905 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
2906 ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
2907 ioc->name, count, ioc_state));
2908 if ((SendIocInit(ioc, sleepFlag)) != 0) {
2909 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
2913 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit successful\n",
2917 if (sleepFlag == CAN_SLEEP) {
2918 msleep_interruptible (10);
2923 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! IocState=%x\n",
2924 ioc->name, ioc_state));
2928 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2930 * KickStart - Perform hard reset of MPT adapter.
2931 * @ioc: Pointer to MPT_ADAPTER structure
2932 * @force: Force hard reset
2933 * @sleepFlag: Specifies whether the process can sleep
2935 * This routine places MPT adapter in diagnostic mode via the
2936 * WriteSequence register, and then performs a hard reset of adapter
2937 * via the Diagnostic register.
2939 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
2940 * or NO_SLEEP (interrupt thread, use mdelay)
2941 * force - 1 if doorbell active, board fault state
2942 * board operational, IOC_RECOVERY or
2943 * IOC_BRINGUP and there is an alt_ioc.
2947 * 1 - hard reset, READY
2948 * 0 - no reset due to History bit, READY
2949 * -1 - no reset due to History bit but not READY
2950 * OR reset but failed to come READY
2951 * -2 - no reset, could not enter DIAG mode
2952 * -3 - reset but bad FW bit
2955 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
2957 int hard_reset_done = 0;
2961 dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
2962 if (ioc->bus_type == SCSI) {
2963 /* Always issue a Msg Unit Reset first. This will clear some
2964 * SCSI bus hang conditions.
2966 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
2968 if (sleepFlag == CAN_SLEEP) {
2969 msleep_interruptible (1000);
2975 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
2976 if (hard_reset_done < 0)
2977 return hard_reset_done;
2979 dinitprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
2982 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
2983 for (cnt=0; cnt<cntdn; cnt++) {
2984 ioc_state = mpt_GetIocState(ioc, 1);
2985 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
2986 dinitprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
2988 return hard_reset_done;
2990 if (sleepFlag == CAN_SLEEP) {
2991 msleep_interruptible (10);
2997 printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
2998 ioc->name, ioc_state);
3002 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3004 * mpt_diag_reset - Perform hard reset of the adapter.
3005 * @ioc: Pointer to MPT_ADAPTER structure
3006 * @ignore: Set if to honor and clear to ignore
3007 * the reset history bit
3008 * @sleepflag: CAN_SLEEP if called in a non-interrupt thread,
3009 * else set to NO_SLEEP (use mdelay instead)
3011 * This routine places the adapter in diagnostic mode via the
3012 * WriteSequence register and then performs a hard reset of adapter
3013 * via the Diagnostic register. Adapter should be in ready state
3014 * upon successful completion.
3016 * Returns: 1 hard reset successful
3017 * 0 no reset performed because reset history bit set
3018 * -2 enabling diagnostic mode failed
3019 * -3 diagnostic reset failed
3022 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3026 int hard_reset_done = 0;
3032 /* Clear any existing interrupts */
3033 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3035 /* Use "Diagnostic reset" method! (only thing available!) */
3036 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3040 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3041 dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3042 ioc->name, diag0val, diag1val));
3045 /* Do the reset if we are told to ignore the reset history
3046 * or if the reset history is 0
3048 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3049 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3050 /* Write magic sequence to WriteSequence register
3051 * Loop until in diagnostic mode
3053 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3054 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3055 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3056 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3057 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3058 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3061 if (sleepFlag == CAN_SLEEP) {
3062 msleep_interruptible (100);
3069 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3070 ioc->name, diag0val);
3075 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3077 dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3078 ioc->name, diag0val));
3083 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3084 dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3085 ioc->name, diag0val, diag1val));
3088 * Disable the ARM (Bug fix)
3091 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3095 * Now hit the reset bit in the Diagnostic register
3096 * (THE BIG HAMMER!) (Clears DRWE bit).
3098 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3099 hard_reset_done = 1;
3100 dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
3104 * Call each currently registered protocol IOC reset handler
3105 * with pre-reset indication.
3106 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3107 * MptResetHandlers[] registered yet.
3113 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
3114 if (MptResetHandlers[ii]) {
3115 dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
3117 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_PRE_RESET);
3119 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3120 ioc->name, ioc->alt_ioc->name, ii));
3121 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_PRE_RESET);
3125 /* FIXME? Examine results here? */
3128 if (ioc->cached_fw) {
3129 /* If the DownloadBoot operation fails, the
3130 * IOC will be left unusable. This is a fatal error
3131 * case. _diag_reset will return < 0
3133 for (count = 0; count < 30; count ++) {
3134 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3135 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3140 if (sleepFlag == CAN_SLEEP) {
3141 set_current_state(TASK_INTERRUPTIBLE);
3142 schedule_timeout(1000 * HZ / 1000);
3147 if ((count = mpt_downloadboot(ioc, sleepFlag)) < 0) {
3148 printk(KERN_WARNING MYNAM
3149 ": firmware downloadboot failure (%d)!\n", count);
3153 /* Wait for FW to reload and for board
3154 * to go to the READY state.
3155 * Maximum wait is 60 seconds.
3156 * If fail, no error will check again
3157 * with calling program.
3159 for (count = 0; count < 60; count ++) {
3160 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3161 doorbell &= MPI_IOC_STATE_MASK;
3163 if (doorbell == MPI_IOC_STATE_READY) {
3168 if (sleepFlag == CAN_SLEEP) {
3169 msleep_interruptible (1000);
3177 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3180 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3181 dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3182 ioc->name, diag0val, diag1val));
3185 /* Clear RESET_HISTORY bit! Place board in the
3186 * diagnostic mode to update the diag register.
3188 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3190 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3191 /* Write magic sequence to WriteSequence register
3192 * Loop until in diagnostic mode
3194 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3195 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3196 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3197 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3198 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3199 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3202 if (sleepFlag == CAN_SLEEP) {
3203 msleep_interruptible (100);
3210 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3211 ioc->name, diag0val);
3214 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3216 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3217 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3218 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3219 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3220 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3224 /* Disable Diagnostic Mode
3226 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3228 /* Check FW reload status flags.
3230 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3231 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3232 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3233 ioc->name, diag0val);
3239 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3240 dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3241 ioc->name, diag0val, diag1val));
3245 * Reset flag that says we've enabled event notification
3247 ioc->facts.EventState = 0;
3250 ioc->alt_ioc->facts.EventState = 0;
3252 return hard_reset_done;
3255 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3257 * SendIocReset - Send IOCReset request to MPT adapter.
3258 * @ioc: Pointer to MPT_ADAPTER structure
3259 * @reset_type: reset type, expected values are
3260 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3262 * Send IOCReset request to the MPT adapter.
3264 * Returns 0 for success, non-zero for failure.
3267 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3273 drsprintk((KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
3274 ioc->name, reset_type));
3275 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3276 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3279 /* FW ACK'd request, wait for READY state
3282 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3284 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3288 if (sleepFlag != CAN_SLEEP)
3291 printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3292 ioc->name, (int)((count+5)/HZ));
3296 if (sleepFlag == CAN_SLEEP) {
3297 msleep_interruptible(1);
3299 mdelay (1); /* 1 msec delay */
3304 * Cleanup all event stuff for this IOC; re-issue EventNotification
3305 * request if needed.
3307 if (ioc->facts.Function)
3308 ioc->facts.EventState = 0;
3313 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3315 * initChainBuffers - Allocate memory for and initialize
3316 * chain buffers, chain buffer control arrays and spinlock.
3317 * @hd: Pointer to MPT_SCSI_HOST structure
3318 * @init: If set, initialize the spin lock.
3321 initChainBuffers(MPT_ADAPTER *ioc)
3324 int sz, ii, num_chain;
3325 int scale, num_sge, numSGE;
3327 /* ReqToChain size must equal the req_depth
3330 if (ioc->ReqToChain == NULL) {
3331 sz = ioc->req_depth * sizeof(int);
3332 mem = kmalloc(sz, GFP_ATOMIC);
3336 ioc->ReqToChain = (int *) mem;
3337 dinitprintk((KERN_INFO MYNAM ": %s ReqToChain alloc @ %p, sz=%d bytes\n",
3338 ioc->name, mem, sz));
3339 mem = kmalloc(sz, GFP_ATOMIC);
3343 ioc->RequestNB = (int *) mem;
3344 dinitprintk((KERN_INFO MYNAM ": %s RequestNB alloc @ %p, sz=%d bytes\n",
3345 ioc->name, mem, sz));
3347 for (ii = 0; ii < ioc->req_depth; ii++) {
3348 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3351 /* ChainToChain size must equal the total number
3352 * of chain buffers to be allocated.
3355 * Calculate the number of chain buffers needed(plus 1) per I/O
3356 * then multiply the the maximum number of simultaneous cmds
3358 * num_sge = num sge in request frame + last chain buffer
3359 * scale = num sge per chain buffer if no chain element
3361 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3362 if (sizeof(dma_addr_t) == sizeof(u64))
3363 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3365 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3367 if (sizeof(dma_addr_t) == sizeof(u64)) {
3368 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3369 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3371 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3372 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3374 dinitprintk((KERN_INFO MYNAM ": %s num_sge=%d numSGE=%d\n",
3375 ioc->name, num_sge, numSGE));
3377 if ( numSGE > MPT_SCSI_SG_DEPTH )
3378 numSGE = MPT_SCSI_SG_DEPTH;
3381 while (numSGE - num_sge > 0) {
3383 num_sge += (scale - 1);
3387 dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
3388 ioc->name, numSGE, num_sge, num_chain));
3390 if (ioc->bus_type == SCSI)
3391 num_chain *= MPT_SCSI_CAN_QUEUE;
3393 num_chain *= MPT_FC_CAN_QUEUE;
3395 ioc->num_chain = num_chain;
3397 sz = num_chain * sizeof(int);
3398 if (ioc->ChainToChain == NULL) {
3399 mem = kmalloc(sz, GFP_ATOMIC);
3403 ioc->ChainToChain = (int *) mem;
3404 dinitprintk((KERN_INFO MYNAM ": %s ChainToChain alloc @ %p, sz=%d bytes\n",
3405 ioc->name, mem, sz));
3407 mem = (u8 *) ioc->ChainToChain;
3409 memset(mem, 0xFF, sz);
3413 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3415 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3416 * @ioc: Pointer to MPT_ADAPTER structure
3418 * This routine allocates memory for the MPT reply and request frame
3419 * pools (if necessary), and primes the IOC reply FIFO with
3422 * Returns 0 for success, non-zero for failure.
3425 PrimeIocFifos(MPT_ADAPTER *ioc)
3428 unsigned long flags;
3429 dma_addr_t alloc_dma;
3431 int i, reply_sz, sz, total_size, num_chain;
3433 /* Prime reply FIFO... */
3435 if (ioc->reply_frames == NULL) {
3436 if ( (num_chain = initChainBuffers(ioc)) < 0)
3439 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3440 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3441 ioc->name, ioc->reply_sz, ioc->reply_depth));
3442 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d[%x] bytes\n",
3443 ioc->name, reply_sz, reply_sz));
3445 sz = (ioc->req_sz * ioc->req_depth);
3446 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3447 ioc->name, ioc->req_sz, ioc->req_depth));
3448 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d[%x] bytes\n",
3449 ioc->name, sz, sz));
3452 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3453 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3454 ioc->name, ioc->req_sz, num_chain));
3455 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3456 ioc->name, sz, sz, num_chain));
3459 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3461 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3466 dinitprintk((KERN_INFO MYNAM ": %s.Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3467 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3469 memset(mem, 0, total_size);
3470 ioc->alloc_total += total_size;
3472 ioc->alloc_dma = alloc_dma;
3473 ioc->alloc_sz = total_size;
3474 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3475 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3477 alloc_dma += reply_sz;
3480 /* Request FIFO - WE manage this! */
3482 ioc->req_frames = (MPT_FRAME_HDR *) mem;
3483 ioc->req_frames_dma = alloc_dma;
3485 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffers @ %p[%p]\n",
3486 ioc->name, mem, (void *)(ulong)alloc_dma));
3488 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3490 #if defined(CONFIG_MTRR) && 0
3492 * Enable Write Combining MTRR for IOC's memory region.
3493 * (at least as much as we can; "size and base must be
3494 * multiples of 4 kiB"
3496 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
3498 MTRR_TYPE_WRCOMB, 1);
3499 dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
3500 ioc->name, ioc->req_frames_dma, sz));
3503 for (i = 0; i < ioc->req_depth; i++) {
3504 alloc_dma += ioc->req_sz;
3508 ioc->ChainBuffer = mem;
3509 ioc->ChainBufferDMA = alloc_dma;
3511 dinitprintk((KERN_INFO MYNAM " :%s.ChainBuffers @ %p(%p)\n",
3512 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
3514 /* Initialize the free chain Q.
3517 INIT_LIST_HEAD(&ioc->FreeChainQ);
3519 /* Post the chain buffers to the FreeChainQ.
3521 mem = (u8 *)ioc->ChainBuffer;
3522 for (i=0; i < num_chain; i++) {
3523 mf = (MPT_FRAME_HDR *) mem;
3524 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
3528 /* Initialize Request frames linked list
3530 alloc_dma = ioc->req_frames_dma;
3531 mem = (u8 *) ioc->req_frames;
3533 spin_lock_irqsave(&ioc->FreeQlock, flags);
3534 INIT_LIST_HEAD(&ioc->FreeQ);
3535 for (i = 0; i < ioc->req_depth; i++) {
3536 mf = (MPT_FRAME_HDR *) mem;
3538 /* Queue REQUESTs *internally*! */
3539 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
3543 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3545 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3546 ioc->sense_buf_pool =
3547 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3548 if (ioc->sense_buf_pool == NULL) {
3549 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
3554 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
3555 ioc->alloc_total += sz;
3556 dinitprintk((KERN_INFO MYNAM ": %s.SenseBuffers @ %p[%p]\n",
3557 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
3561 /* Post Reply frames to FIFO
3563 alloc_dma = ioc->alloc_dma;
3564 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffers @ %p[%p]\n",
3565 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3567 for (i = 0; i < ioc->reply_depth; i++) {
3568 /* Write each address to the IOC! */
3569 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
3570 alloc_dma += ioc->reply_sz;
3576 if (ioc->alloc != NULL) {
3578 pci_free_consistent(ioc->pcidev,
3580 ioc->alloc, ioc->alloc_dma);
3581 ioc->reply_frames = NULL;
3582 ioc->req_frames = NULL;
3583 ioc->alloc_total -= sz;
3585 if (ioc->sense_buf_pool != NULL) {
3586 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3587 pci_free_consistent(ioc->pcidev,
3589 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
3590 ioc->sense_buf_pool = NULL;
3595 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3597 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3598 * from IOC via doorbell handshake method.
3599 * @ioc: Pointer to MPT_ADAPTER structure
3600 * @reqBytes: Size of the request in bytes
3601 * @req: Pointer to MPT request frame
3602 * @replyBytes: Expected size of the reply in bytes
3603 * @u16reply: Pointer to area where reply should be written
3604 * @maxwait: Max wait time for a reply (in seconds)
3605 * @sleepFlag: Specifies whether the process can sleep
3607 * NOTES: It is the callers responsibility to byte-swap fields in the
3608 * request which are greater than 1 byte in size. It is also the
3609 * callers responsibility to byte-swap response fields which are
3610 * greater than 1 byte in size.
3612 * Returns 0 for success, non-zero for failure.
3615 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
3616 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
3618 MPIDefaultReply_t *mptReply;
3623 * Get ready to cache a handshake reply
3625 ioc->hs_reply_idx = 0;
3626 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3627 mptReply->MsgLength = 0;
3630 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
3631 * then tell IOC that we want to handshake a request of N words.
3632 * (WRITE u32val to Doorbell reg).
3634 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3635 CHIPREG_WRITE32(&ioc->chip->Doorbell,
3636 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
3637 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
3640 * Wait for IOC's doorbell handshake int
3642 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3645 dhsprintk((MYIOC_s_INFO_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
3646 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3648 /* Read doorbell and check for active bit */
3649 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
3653 * Clear doorbell int (WRITE 0 to IntStatus reg),
3654 * then wait for IOC to ACKnowledge that it's ready for
3655 * our handshake request.
3657 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3658 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3663 u8 *req_as_bytes = (u8 *) req;
3666 * Stuff request words via doorbell handshake,
3667 * with ACK from IOC for each.
3669 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
3670 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
3671 (req_as_bytes[(ii*4) + 1] << 8) |
3672 (req_as_bytes[(ii*4) + 2] << 16) |
3673 (req_as_bytes[(ii*4) + 3] << 24));
3675 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
3676 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3680 dhsprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
3681 DBG_DUMP_REQUEST_FRAME_HDR(req)
3683 dhsprintk((MYIOC_s_INFO_FMT "HandShake request post done, WaitCnt=%d%s\n",
3684 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
3687 * Wait for completion of doorbell handshake reply from the IOC
3689 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
3692 dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n",
3693 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
3696 * Copy out the cached reply...
3698 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
3699 u16reply[ii] = ioc->hs_reply[ii];
3707 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3709 * WaitForDoorbellAck - Wait for IOC to clear the IOP_DOORBELL_STATUS bit
3710 * in it's IntStatus register.
3711 * @ioc: Pointer to MPT_ADAPTER structure
3712 * @howlong: How long to wait (in seconds)
3713 * @sleepFlag: Specifies whether the process can sleep
3715 * This routine waits (up to ~2 seconds max) for IOC doorbell
3716 * handshake ACKnowledge.
3718 * Returns a negative value on failure, else wait loop count.
3721 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3727 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
3729 if (sleepFlag == CAN_SLEEP) {
3731 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3732 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3734 msleep_interruptible (1);
3739 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3740 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3748 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (count=%d)\n",
3753 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
3754 ioc->name, count, intstat);
3758 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3760 * WaitForDoorbellInt - Wait for IOC to set the HIS_DOORBELL_INTERRUPT bit
3761 * in it's IntStatus register.
3762 * @ioc: Pointer to MPT_ADAPTER structure
3763 * @howlong: How long to wait (in seconds)
3764 * @sleepFlag: Specifies whether the process can sleep
3766 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt.
3768 * Returns a negative value on failure, else wait loop count.
3771 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3777 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
3778 if (sleepFlag == CAN_SLEEP) {
3780 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3781 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3783 msleep_interruptible(1);
3788 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3789 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3797 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
3798 ioc->name, count, howlong));
3802 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
3803 ioc->name, count, intstat);
3807 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3809 * WaitForDoorbellReply - Wait for and capture a IOC handshake reply.
3810 * @ioc: Pointer to MPT_ADAPTER structure
3811 * @howlong: How long to wait (in seconds)
3812 * @sleepFlag: Specifies whether the process can sleep
3814 * This routine polls the IOC for a handshake reply, 16 bits at a time.
3815 * Reply is cached to IOC private area large enough to hold a maximum
3816 * of 128 bytes of reply data.
3818 * Returns a negative value on failure, else size of reply in WORDS.
3821 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3826 u16 *hs_reply = ioc->hs_reply;
3827 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3830 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
3833 * Get first two u16's so we can look at IOC's intended reply MsgLength
3836 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
3839 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3840 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3841 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3844 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3845 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3849 dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
3850 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
3851 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3854 * If no error (and IOC said MsgLength is > 0), piece together
3855 * reply 16 bits at a time.
3857 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
3858 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3860 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3861 /* don't overflow our IOC hs_reply[] buffer! */
3862 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
3863 hs_reply[u16cnt] = hword;
3864 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3867 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3869 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3872 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
3877 else if (u16cnt != (2 * mptReply->MsgLength)) {
3880 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
3885 dhsprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
3886 DBG_DUMP_REPLY_FRAME(mptReply)
3888 dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
3889 ioc->name, t, u16cnt/2));
3893 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3895 * GetLanConfigPages - Fetch LANConfig pages.
3896 * @ioc: Pointer to MPT_ADAPTER structure
3898 * Return: 0 for success
3899 * -ENOMEM if no memory available
3900 * -EPERM if not allowed due to ISR context
3901 * -EAGAIN if no msg frames currently available
3902 * -EFAULT for non-successful reply or no reply (timeout)
3905 GetLanConfigPages(MPT_ADAPTER *ioc)
3907 ConfigPageHeader_t hdr;
3909 LANPage0_t *ppage0_alloc;
3910 dma_addr_t page0_dma;
3911 LANPage1_t *ppage1_alloc;
3912 dma_addr_t page1_dma;
3917 /* Get LAN Page 0 header */
3918 hdr.PageVersion = 0;
3921 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
3924 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
3929 if ((rc = mpt_config(ioc, &cfg)) != 0)
3932 if (hdr.PageLength > 0) {
3933 data_sz = hdr.PageLength * 4;
3934 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
3937 memset((u8 *)ppage0_alloc, 0, data_sz);
3938 cfg.physAddr = page0_dma;
3939 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
3941 if ((rc = mpt_config(ioc, &cfg)) == 0) {
3943 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
3944 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
3948 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
3951 * Normalize endianness of structure data,
3952 * by byte-swapping all > 1 byte fields!
3961 /* Get LAN Page 1 header */
3962 hdr.PageVersion = 0;
3965 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
3968 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
3972 if ((rc = mpt_config(ioc, &cfg)) != 0)
3975 if (hdr.PageLength == 0)
3978 data_sz = hdr.PageLength * 4;
3980 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
3982 memset((u8 *)ppage1_alloc, 0, data_sz);
3983 cfg.physAddr = page1_dma;
3984 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
3986 if ((rc = mpt_config(ioc, &cfg)) == 0) {
3988 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
3989 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
3992 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
3995 * Normalize endianness of structure data,
3996 * by byte-swapping all > 1 byte fields!
4004 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4006 * GetFcPortPage0 - Fetch FCPort config Page0.
4007 * @ioc: Pointer to MPT_ADAPTER structure
4008 * @portnum: IOC Port number
4010 * Return: 0 for success
4011 * -ENOMEM if no memory available
4012 * -EPERM if not allowed due to ISR context
4013 * -EAGAIN if no msg frames currently available
4014 * -EFAULT for non-successful reply or no reply (timeout)
4017 GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
4019 ConfigPageHeader_t hdr;
4021 FCPortPage0_t *ppage0_alloc;
4022 FCPortPage0_t *pp0dest;
4023 dma_addr_t page0_dma;
4028 /* Get FCPort Page 0 header */
4029 hdr.PageVersion = 0;
4032 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
4035 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4037 cfg.pageAddr = portnum;
4040 if ((rc = mpt_config(ioc, &cfg)) != 0)
4043 if (hdr.PageLength == 0)
4046 data_sz = hdr.PageLength * 4;
4048 ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4050 memset((u8 *)ppage0_alloc, 0, data_sz);
4051 cfg.physAddr = page0_dma;
4052 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4054 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4056 pp0dest = &ioc->fc_port_page0[portnum];
4057 copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
4058 memcpy(pp0dest, ppage0_alloc, copy_sz);
4061 * Normalize endianness of structure data,
4062 * by byte-swapping all > 1 byte fields!
4064 pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
4065 pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
4066 pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
4067 pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
4068 pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
4069 pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
4070 pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
4071 pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
4072 pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
4073 pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
4074 pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
4075 pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
4076 pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
4077 pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
4078 pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
4079 pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
4083 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4089 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4091 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4092 * @ioc: Pointer to MPT_ADAPTER structure
4094 * Returns: 0 for success
4095 * -ENOMEM if no memory available
4096 * -EPERM if not allowed due to ISR context
4097 * -EAGAIN if no msg frames currently available
4098 * -EFAULT for non-successful reply or no reply (timeout)
4101 GetIoUnitPage2(MPT_ADAPTER *ioc)
4103 ConfigPageHeader_t hdr;
4105 IOUnitPage2_t *ppage_alloc;
4106 dma_addr_t page_dma;
4110 /* Get the page header */
4111 hdr.PageVersion = 0;
4114 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4117 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4122 if ((rc = mpt_config(ioc, &cfg)) != 0)
4125 if (hdr.PageLength == 0)
4128 /* Read the config page */
4129 data_sz = hdr.PageLength * 4;
4131 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4133 memset((u8 *)ppage_alloc, 0, data_sz);
4134 cfg.physAddr = page_dma;
4135 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4137 /* If Good, save data */
4138 if ((rc = mpt_config(ioc, &cfg)) == 0)
4139 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4141 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4147 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4148 /* mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4149 * @ioc: Pointer to a Adapter Strucutre
4150 * @portnum: IOC port number
4152 * Return: -EFAULT if read of config page header fails
4154 * If read of SCSI Port Page 0 fails,
4155 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4156 * Adapter settings: async, narrow
4158 * If read of SCSI Port Page 2 fails,
4159 * Adapter settings valid
4160 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4165 * CHECK - what type of locking mechanisms should be used????
4168 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4173 ConfigPageHeader_t header;
4179 if (!ioc->spi_data.nvram) {
4182 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4183 mem = kmalloc(sz, GFP_ATOMIC);
4187 ioc->spi_data.nvram = (int *) mem;
4189 dprintk((MYIOC_s_INFO_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4190 ioc->name, ioc->spi_data.nvram, sz));
4193 /* Invalidate NVRAM information
4195 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4196 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4199 /* Read SPP0 header, allocate memory, then read page.
4201 header.PageVersion = 0;
4202 header.PageLength = 0;
4203 header.PageNumber = 0;
4204 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4207 cfg.pageAddr = portnum;
4208 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4210 cfg.timeout = 0; /* use default */
4211 if (mpt_config(ioc, &cfg) != 0)
4214 if (header.PageLength > 0) {
4215 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4217 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4218 cfg.physAddr = buf_dma;
4219 if (mpt_config(ioc, &cfg) != 0) {
4220 ioc->spi_data.maxBusWidth = MPT_NARROW;
4221 ioc->spi_data.maxSyncOffset = 0;
4222 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4223 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4226 /* Save the Port Page 0 data
4228 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4229 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4230 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4232 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4233 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4234 dinitprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
4235 ioc->name, pPP0->Capabilities));
4237 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4238 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4240 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4241 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4242 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4244 ioc->spi_data.maxSyncOffset = 0;
4245 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4248 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4250 /* Update the minSyncFactor based on bus type.
4252 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4253 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4255 if (ioc->spi_data.minSyncFactor < MPT_ULTRA)
4256 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4260 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4265 /* SCSI Port Page 2 - Read the header then the page.
4267 header.PageVersion = 0;
4268 header.PageLength = 0;
4269 header.PageNumber = 2;
4270 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4273 cfg.pageAddr = portnum;
4274 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4276 if (mpt_config(ioc, &cfg) != 0)
4279 if (header.PageLength > 0) {
4280 /* Allocate memory and read SCSI Port Page 2
4282 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4284 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4285 cfg.physAddr = buf_dma;
4286 if (mpt_config(ioc, &cfg) != 0) {
4287 /* Nvram data is left with INVALID mark
4291 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4292 MpiDeviceInfo_t *pdevice = NULL;
4294 /* Save the Port Page 2 data
4295 * (reformat into a 32bit quantity)
4297 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4298 ioc->spi_data.PortFlags = data;
4299 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4300 pdevice = &pPP2->DeviceSettings[ii];
4301 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4302 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4303 ioc->spi_data.nvram[ii] = data;
4307 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4311 /* Update Adapter limits with those from NVRAM
4312 * Comment: Don't need to do this. Target performance
4313 * parameters will never exceed the adapters limits.
4319 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4320 /* mpt_readScsiDevicePageHeaders - save version and length of SDP1
4321 * @ioc: Pointer to a Adapter Strucutre
4322 * @portnum: IOC port number
4324 * Return: -EFAULT if read of config page header fails
4328 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4331 ConfigPageHeader_t header;
4333 /* Read the SCSI Device Page 1 header
4335 header.PageVersion = 0;
4336 header.PageLength = 0;
4337 header.PageNumber = 1;
4338 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4341 cfg.pageAddr = portnum;
4342 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4345 if (mpt_config(ioc, &cfg) != 0)
4348 ioc->spi_data.sdp1version = cfg.hdr->PageVersion;
4349 ioc->spi_data.sdp1length = cfg.hdr->PageLength;
4351 header.PageVersion = 0;
4352 header.PageLength = 0;
4353 header.PageNumber = 0;
4354 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4355 if (mpt_config(ioc, &cfg) != 0)
4358 ioc->spi_data.sdp0version = cfg.hdr->PageVersion;
4359 ioc->spi_data.sdp0length = cfg.hdr->PageLength;
4361 dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
4362 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
4364 dcprintk((MYIOC_s_INFO_FMT "Headers: 1: version %d length %d\n",
4365 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
4369 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4371 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4372 * @ioc: Pointer to a Adapter Strucutre
4373 * @portnum: IOC port number
4377 * -EFAULT if read of config page header fails or data pointer not NULL
4378 * -ENOMEM if pci_alloc failed
4381 mpt_findImVolumes(MPT_ADAPTER *ioc)
4385 ConfigPageIoc2RaidVol_t *pIocRv;
4386 dma_addr_t ioc2_dma;
4388 ConfigPageHeader_t header;
4395 /* Read IOCP2 header then the page.
4397 header.PageVersion = 0;
4398 header.PageLength = 0;
4399 header.PageNumber = 2;
4400 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4404 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4407 if (mpt_config(ioc, &cfg) != 0)
4410 if (header.PageLength == 0)
4413 iocpage2sz = header.PageLength * 4;
4414 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
4418 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4419 cfg.physAddr = ioc2_dma;
4420 if (mpt_config(ioc, &cfg) != 0)
4423 if ( (mem = (u8 *)ioc->spi_data.pIocPg2) == NULL ) {
4424 mem = kmalloc(iocpage2sz, GFP_ATOMIC);
4426 ioc->spi_data.pIocPg2 = (IOCPage2_t *) mem;
4431 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
4433 /* Identify RAID Volume Id's */
4434 nVols = pIoc2->NumActiveVolumes;
4440 /* At least 1 RAID Volume
4442 pIocRv = pIoc2->RaidVolume;
4443 ioc->spi_data.isRaid = 0;
4444 for (jj = 0; jj < nVols; jj++, pIocRv++) {
4445 vid = pIocRv->VolumeID;
4446 vbus = pIocRv->VolumeBus;
4447 vioc = pIocRv->VolumeIOC;
4452 ioc->spi_data.isRaid |= (1 << vid);
4454 /* Error! Always bus 0
4460 /* Identify Hidden Physical Disk Id's */
4461 nPhys = pIoc2->NumActivePhysDisks;
4463 /* No physical disks.
4466 mpt_read_ioc_pg_3(ioc);
4470 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
4476 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
4481 ConfigPageHeader_t header;
4482 dma_addr_t ioc3_dma;
4485 /* Free the old page
4487 if (ioc->spi_data.pIocPg3) {
4488 kfree(ioc->spi_data.pIocPg3);
4489 ioc->spi_data.pIocPg3 = NULL;
4492 /* There is at least one physical disk.
4493 * Read and save IOC Page 3
4495 header.PageVersion = 0;
4496 header.PageLength = 0;
4497 header.PageNumber = 3;
4498 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4502 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4505 if (mpt_config(ioc, &cfg) != 0)
4508 if (header.PageLength == 0)
4511 /* Read Header good, alloc memory
4513 iocpage3sz = header.PageLength * 4;
4514 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
4518 /* Read the Page and save the data
4519 * into malloc'd memory.
4521 cfg.physAddr = ioc3_dma;
4522 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4523 if (mpt_config(ioc, &cfg) == 0) {
4524 mem = kmalloc(iocpage3sz, GFP_ATOMIC);
4526 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
4527 ioc->spi_data.pIocPg3 = (IOCPage3_t *) mem;
4531 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
4537 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
4541 ConfigPageHeader_t header;
4542 dma_addr_t ioc4_dma;
4545 /* Read and save IOC Page 4
4547 header.PageVersion = 0;
4548 header.PageLength = 0;
4549 header.PageNumber = 4;
4550 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4554 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4557 if (mpt_config(ioc, &cfg) != 0)
4560 if (header.PageLength == 0)
4563 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
4564 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
4565 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
4569 ioc4_dma = ioc->spi_data.IocPg4_dma;
4570 iocpage4sz = ioc->spi_data.IocPg4Sz;
4573 /* Read the Page into dma memory.
4575 cfg.physAddr = ioc4_dma;
4576 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4577 if (mpt_config(ioc, &cfg) == 0) {
4578 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
4579 ioc->spi_data.IocPg4_dma = ioc4_dma;
4580 ioc->spi_data.IocPg4Sz = iocpage4sz;
4582 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
4583 ioc->spi_data.pIocPg4 = NULL;
4588 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
4592 ConfigPageHeader_t header;
4593 dma_addr_t ioc1_dma;
4597 /* Check the Coalescing Timeout in IOC Page 1
4599 header.PageVersion = 0;
4600 header.PageLength = 0;
4601 header.PageNumber = 1;
4602 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4606 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4609 if (mpt_config(ioc, &cfg) != 0)
4612 if (header.PageLength == 0)
4615 /* Read Header good, alloc memory
4617 iocpage1sz = header.PageLength * 4;
4618 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
4622 /* Read the Page and check coalescing timeout
4624 cfg.physAddr = ioc1_dma;
4625 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4626 if (mpt_config(ioc, &cfg) == 0) {
4628 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
4629 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
4630 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
4632 dprintk((MYIOC_s_INFO_FMT "Coalescing Enabled Timeout = %d\n",
4635 if (tmp > MPT_COALESCING_TIMEOUT) {
4636 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
4638 /* Write NVRAM and current
4641 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4642 if (mpt_config(ioc, &cfg) == 0) {
4643 dprintk((MYIOC_s_INFO_FMT "Reset Current Coalescing Timeout to = %d\n",
4644 ioc->name, MPT_COALESCING_TIMEOUT));
4646 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
4647 if (mpt_config(ioc, &cfg) == 0) {
4648 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout to = %d\n",
4649 ioc->name, MPT_COALESCING_TIMEOUT));
4651 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout Failed\n",
4656 dprintk((MYIOC_s_WARN_FMT "Reset of Current Coalescing Timeout Failed!\n",
4662 dprintk((MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
4666 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
4671 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4673 * SendEventNotification - Send EventNotification (on or off) request
4675 * @ioc: Pointer to MPT_ADAPTER structure
4676 * @EvSwitch: Event switch flags
4679 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
4681 EventNotification_t *evnp;
4683 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
4685 dprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
4689 memset(evnp, 0, sizeof(*evnp));
4691 dprintk((MYIOC_s_INFO_FMT "Sending EventNotification(%d)\n", ioc->name, EvSwitch));
4693 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
4694 evnp->ChainOffset = 0;
4696 evnp->Switch = EvSwitch;
4698 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
4703 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4705 * SendEventAck - Send EventAck request to MPT adapter.
4706 * @ioc: Pointer to MPT_ADAPTER structure
4707 * @evnp: Pointer to original EventNotification request
4710 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
4714 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4715 printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK request frame!\n",
4719 memset(pAck, 0, sizeof(*pAck));
4721 dprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
4723 pAck->Function = MPI_FUNCTION_EVENT_ACK;
4724 pAck->ChainOffset = 0;
4726 pAck->Event = evnp->Event;
4727 pAck->EventContext = evnp->EventContext;
4729 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
4734 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4736 * mpt_config - Generic function to issue config message
4737 * @ioc - Pointer to an adapter structure
4738 * @cfg - Pointer to a configuration structure. Struct contains
4739 * action, page address, direction, physical address
4740 * and pointer to a configuration page header
4741 * Page header is updated.
4743 * Returns 0 for success
4744 * -EPERM if not allowed due to ISR context
4745 * -EAGAIN if no msg frames currently available
4746 * -EFAULT for non-successful reply or no reply (timeout)
4749 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
4753 unsigned long flags;
4758 /* (Bugzilla:fibrebugs, #513)
4759 * Bug fix (part 1)! 20010905 -sralston
4760 * Prevent calling wait_event() (below), if caller happens
4761 * to be in ISR context, because that is fatal!
4763 in_isr = in_interrupt();
4765 dcprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
4770 /* Get and Populate a free Frame
4772 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4773 dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
4777 pReq = (Config_t *)mf;
4778 pReq->Action = pCfg->action;
4780 pReq->ChainOffset = 0;
4781 pReq->Function = MPI_FUNCTION_CONFIG;
4782 pReq->ExtPageLength = 0;
4783 pReq->ExtPageType = 0;
4785 for (ii=0; ii < 8; ii++)
4786 pReq->Reserved2[ii] = 0;
4788 pReq->Header.PageVersion = pCfg->hdr->PageVersion;
4789 pReq->Header.PageLength = pCfg->hdr->PageLength;
4790 pReq->Header.PageNumber = pCfg->hdr->PageNumber;
4791 pReq->Header.PageType = (pCfg->hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
4792 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
4794 /* Add a SGE to the config request.
4797 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
4799 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
4801 flagsLength |= pCfg->hdr->PageLength * 4;
4803 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
4805 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
4806 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
4808 /* Append pCfg pointer to end of mf
4810 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
4812 /* Initalize the timer
4814 init_timer(&pCfg->timer);
4815 pCfg->timer.data = (unsigned long) ioc;
4816 pCfg->timer.function = mpt_timer_expired;
4817 pCfg->wait_done = 0;
4819 /* Set the timer; ensure 10 second minimum */
4820 if (pCfg->timeout < 10)
4821 pCfg->timer.expires = jiffies + HZ*10;
4823 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
4825 /* Add to end of Q, set timer and then issue this command */
4826 spin_lock_irqsave(&ioc->FreeQlock, flags);
4827 list_add_tail(&pCfg->linkage, &ioc->configQ);
4828 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4830 add_timer(&pCfg->timer);
4831 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4832 wait_event(mpt_waitq, pCfg->wait_done);
4834 /* mf has been freed - do not access */
4841 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4843 * mpt_toolbox - Generic function to issue toolbox message
4844 * @ioc - Pointer to an adapter structure
4845 * @cfg - Pointer to a toolbox structure. Struct contains
4846 * action, page address, direction, physical address
4847 * and pointer to a configuration page header
4848 * Page header is updated.
4850 * Returns 0 for success
4851 * -EPERM if not allowed due to ISR context
4852 * -EAGAIN if no msg frames currently available
4853 * -EFAULT for non-successful reply or no reply (timeout)
4856 mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
4858 ToolboxIstwiReadWriteRequest_t *pReq;
4860 struct pci_dev *pdev;
4861 unsigned long flags;
4866 /* (Bugzilla:fibrebugs, #513)
4867 * Bug fix (part 1)! 20010905 -sralston
4868 * Prevent calling wait_event() (below), if caller happens
4869 * to be in ISR context, because that is fatal!
4871 in_isr = in_interrupt();
4873 dcprintk((MYIOC_s_WARN_FMT "toobox request not allowed in ISR context!\n",
4878 /* Get and Populate a free Frame
4880 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4881 dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n",
4885 pReq = (ToolboxIstwiReadWriteRequest_t *)mf;
4886 pReq->Tool = pCfg->action;
4888 pReq->ChainOffset = 0;
4889 pReq->Function = MPI_FUNCTION_TOOLBOX;
4890 pReq->Reserved1 = 0;
4891 pReq->Reserved2 = 0;
4893 pReq->Flags = pCfg->dir;
4895 pReq->Reserved3 = 0;
4896 pReq->NumAddressBytes = 0x01;
4897 pReq->Reserved4 = 0;
4898 pReq->DataLength = 0x04;
4899 pdev = (struct pci_dev *) ioc->pcidev;
4900 if (pdev->devfn & 1)
4901 pReq->DeviceAddr = 0xB2;
4903 pReq->DeviceAddr = 0xB0;
4907 pReq->Reserved5 = 0;
4909 /* Add a SGE to the config request.
4912 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | 4;
4914 mpt_add_sge((char *)&pReq->SGL, flagsLength, pCfg->physAddr);
4916 dcprintk((MYIOC_s_INFO_FMT "Sending Toolbox request, Tool=%x\n",
4917 ioc->name, pReq->Tool));
4919 /* Append pCfg pointer to end of mf
4921 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
4923 /* Initalize the timer
4925 init_timer(&pCfg->timer);
4926 pCfg->timer.data = (unsigned long) ioc;
4927 pCfg->timer.function = mpt_timer_expired;
4928 pCfg->wait_done = 0;
4930 /* Set the timer; ensure 10 second minimum */
4931 if (pCfg->timeout < 10)
4932 pCfg->timer.expires = jiffies + HZ*10;
4934 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
4936 /* Add to end of Q, set timer and then issue this command */
4937 spin_lock_irqsave(&ioc->FreeQlock, flags);
4938 list_add_tail(&pCfg->linkage, &ioc->configQ);
4939 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4941 add_timer(&pCfg->timer);
4942 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4943 wait_event(mpt_waitq, pCfg->wait_done);
4945 /* mf has been freed - do not access */
4952 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4954 * mpt_timer_expired - Call back for timer process.
4955 * Used only internal config functionality.
4956 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
4959 mpt_timer_expired(unsigned long data)
4961 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
4963 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name));
4965 /* Perform a FW reload */
4966 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
4967 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
4969 /* No more processing.
4970 * Hard reset clean-up will wake up
4971 * process and free all resources.
4973 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name));
4978 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4980 * mpt_ioc_reset - Base cleanup for hard reset
4981 * @ioc: Pointer to the adapter structure
4982 * @reset_phase: Indicates pre- or post-reset functionality
4984 * Remark: Free's resources with internally generated commands.
4987 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
4990 unsigned long flags;
4992 dprintk((KERN_WARNING MYNAM
4993 ": IOC %s_reset routed to MPT base driver!\n",
4994 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
4995 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
4997 if (reset_phase == MPT_IOC_SETUP_RESET) {
4999 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5000 /* If the internal config Q is not empty -
5001 * delete timer. MF resources will be freed when
5002 * the FIFO's are primed.
5004 spin_lock_irqsave(&ioc->FreeQlock, flags);
5005 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5006 del_timer(&pCfg->timer);
5007 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5012 /* Search the configQ for internal commands.
5013 * Flush the Q, and wake up all suspended threads.
5015 spin_lock_irqsave(&ioc->FreeQlock, flags);
5016 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5017 list_del(&pCfg->linkage);
5019 pCfg->status = MPT_CONFIG_ERROR;
5020 pCfg->wait_done = 1;
5021 wake_up(&mpt_waitq);
5023 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5026 return 1; /* currently means nothing really */
5030 #ifdef CONFIG_PROC_FS /* { */
5031 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5033 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5035 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5037 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5039 * Returns 0 for success, non-zero for failure.
5042 procmpt_create(void)
5044 struct proc_dir_entry *ent;
5046 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5047 if (mpt_proc_root_dir == NULL)
5050 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5052 ent->read_proc = procmpt_summary_read;
5054 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5056 ent->read_proc = procmpt_version_read;
5061 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5063 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5065 * Returns 0 for success, non-zero for failure.
5068 procmpt_destroy(void)
5070 remove_proc_entry("version", mpt_proc_root_dir);
5071 remove_proc_entry("summary", mpt_proc_root_dir);
5072 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5075 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5077 * procmpt_summary_read - Handle read request from /proc/mpt/summary
5078 * or from /proc/mpt/iocN/summary.
5079 * @buf: Pointer to area to write information
5080 * @start: Pointer to start pointer
5081 * @offset: Offset to start writing
5083 * @eof: Pointer to EOF integer
5086 * Returns number of characters written to process performing the read.
5089 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5099 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5103 list_for_each_entry(ioc, &ioc_list, list) {
5106 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5109 if ((out-buf) >= request)
5116 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5119 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5121 * procmpt_version_read - Handle read request from /proc/mpt/version.
5122 * @buf: Pointer to area to write information
5123 * @start: Pointer to start pointer
5124 * @offset: Offset to start writing
5126 * @eof: Pointer to EOF integer
5129 * Returns number of characters written to process performing the read.
5132 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5135 int scsi, lan, ctl, targ, dmp;
5139 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5140 len += sprintf(buf+len, " Fusion MPT base driver\n");
5142 scsi = lan = ctl = targ = dmp = 0;
5143 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5145 if (MptCallbacks[ii]) {
5146 switch (MptDriverClass[ii]) {
5147 case MPTSCSIH_DRIVER:
5148 if (!scsi++) drvname = "SCSI host";
5151 if (!lan++) drvname = "LAN";
5154 if (!targ++) drvname = "SCSI target";
5157 if (!ctl++) drvname = "ioctl";
5162 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5166 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5169 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5171 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5172 * @buf: Pointer to area to write information
5173 * @start: Pointer to start pointer
5174 * @offset: Offset to start writing
5176 * @eof: Pointer to EOF integer
5179 * Returns number of characters written to process performing the read.
5182 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5184 MPT_ADAPTER *ioc = data;
5190 mpt_get_fw_exp_ver(expVer, ioc);
5192 len = sprintf(buf, "%s:", ioc->name);
5193 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5194 len += sprintf(buf+len, " (f/w download boot flag set)");
5195 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5196 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5198 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
5199 ioc->facts.ProductID,
5201 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5202 if (ioc->facts.FWImageSize)
5203 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5204 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5205 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5206 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
5208 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
5209 ioc->facts.CurrentHostMfaHighAddr);
5210 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
5211 ioc->facts.CurrentSenseBufferHighAddr);
5213 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5214 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5216 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5217 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
5219 * Rounding UP to nearest 4-kB boundary here...
5221 sz = (ioc->req_sz * ioc->req_depth) + 128;
5222 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5223 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5224 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5225 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
5226 4*ioc->facts.RequestFrameSize,
5227 ioc->facts.GlobalCredits);
5229 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
5230 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
5231 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5232 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5233 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5234 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
5235 ioc->facts.CurReplyFrameSize,
5236 ioc->facts.ReplyQueueDepth);
5238 len += sprintf(buf+len, " MaxDevices = %d\n",
5239 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5240 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
5243 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5244 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
5246 ioc->facts.NumberOfPorts);
5247 if (ioc->bus_type == FC) {
5248 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5249 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5250 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5251 a[5], a[4], a[3], a[2], a[1], a[0]);
5253 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
5254 ioc->fc_port_page0[p].WWNN.High,
5255 ioc->fc_port_page0[p].WWNN.Low,
5256 ioc->fc_port_page0[p].WWPN.High,
5257 ioc->fc_port_page0[p].WWPN.Low);
5261 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5264 #endif /* CONFIG_PROC_FS } */
5266 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5268 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
5271 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
5272 sprintf(buf, " (Exp %02d%02d)",
5273 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
5274 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
5277 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
5278 strcat(buf, " [MDBG]");
5282 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5284 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5285 * @ioc: Pointer to MPT_ADAPTER structure
5286 * @buffer: Pointer to buffer where IOC summary info should be written
5287 * @size: Pointer to number of bytes we wrote (set by this routine)
5288 * @len: Offset at which to start writing in buffer
5289 * @showlan: Display LAN stuff?
5291 * This routine writes (english readable) ASCII text, which represents
5292 * a summary of IOC information, to a buffer.
5295 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
5300 mpt_get_fw_exp_ver(expVer, ioc);
5303 * Shorter summary of attached ioc's...
5305 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
5308 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
5309 ioc->facts.FWVersion.Word,
5311 ioc->facts.NumberOfPorts,
5314 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
5315 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5316 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
5317 a[5], a[4], a[3], a[2], a[1], a[0]);
5321 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
5323 y += sprintf(buffer+len+y, ", IRQ=%s", __irq_itoa(ioc->pci_irq));
5327 y += sprintf(buffer+len+y, " (disabled)");
5329 y += sprintf(buffer+len+y, "\n");
5334 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5338 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5340 * mpt_HardResetHandler - Generic reset handler, issue SCSI Task
5341 * Management call based on input arg values. If TaskMgmt fails,
5342 * return associated SCSI request.
5343 * @ioc: Pointer to MPT_ADAPTER structure
5344 * @sleepFlag: Indicates if sleep or schedule must be called.
5346 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
5347 * or a non-interrupt thread. In the former, must not call schedule().
5349 * Remark: A return of -1 is a FATAL error case, as it means a
5350 * FW reload/initialization failed.
5352 * Returns 0 for SUCCESS or -1 if FAILED.
5355 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5358 unsigned long flags;
5360 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
5362 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
5363 printk("MF count 0x%x !\n", ioc->mfcnt);
5366 /* Reset the adapter. Prevent more than 1 call to
5367 * mpt_do_ioc_recovery at any instant in time.
5369 spin_lock_irqsave(&ioc->diagLock, flags);
5370 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
5371 spin_unlock_irqrestore(&ioc->diagLock, flags);
5374 ioc->diagPending = 1;
5376 spin_unlock_irqrestore(&ioc->diagLock, flags);
5378 /* FIXME: If do_ioc_recovery fails, repeat....
5381 /* The SCSI driver needs to adjust timeouts on all current
5382 * commands prior to the diagnostic reset being issued.
5383 * Prevents timeouts occuring during a diagnostic reset...very bad.
5384 * For all other protocol drivers, this is a no-op.
5390 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5391 if (MptResetHandlers[ii]) {
5392 dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
5394 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_SETUP_RESET);
5396 dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
5397 ioc->name, ioc->alt_ioc->name, ii));
5398 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_SETUP_RESET);
5404 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
5405 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
5410 ioc->alt_ioc->reload_fw = 0;
5412 spin_lock_irqsave(&ioc->diagLock, flags);
5413 ioc->diagPending = 0;
5415 ioc->alt_ioc->diagPending = 0;
5416 spin_unlock_irqrestore(&ioc->diagLock, flags);
5418 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
5423 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5425 EventDescriptionStr(u8 event, u32 evData0)
5430 case MPI_EVENT_NONE:
5433 case MPI_EVENT_LOG_DATA:
5436 case MPI_EVENT_STATE_CHANGE:
5437 ds = "State Change";
5439 case MPI_EVENT_UNIT_ATTENTION:
5440 ds = "Unit Attention";
5442 case MPI_EVENT_IOC_BUS_RESET:
5443 ds = "IOC Bus Reset";
5445 case MPI_EVENT_EXT_BUS_RESET:
5446 ds = "External Bus Reset";
5448 case MPI_EVENT_RESCAN:
5449 ds = "Bus Rescan Event";
5450 /* Ok, do we need to do anything here? As far as
5451 I can tell, this is when a new device gets added
5454 case MPI_EVENT_LINK_STATUS_CHANGE:
5455 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
5456 ds = "Link Status(FAILURE) Change";
5458 ds = "Link Status(ACTIVE) Change";
5460 case MPI_EVENT_LOOP_STATE_CHANGE:
5461 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
5462 ds = "Loop State(LIP) Change";
5463 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
5464 ds = "Loop State(LPE) Change"; /* ??? */
5466 ds = "Loop State(LPB) Change"; /* ??? */
5468 case MPI_EVENT_LOGOUT:
5471 case MPI_EVENT_EVENT_CHANGE:
5473 ds = "Events(ON) Change";
5475 ds = "Events(OFF) Change";
5477 case MPI_EVENT_INTEGRATED_RAID:
5478 ds = "Integrated Raid";
5481 * MPT base "custom" events may be added here...
5490 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5492 * ProcessEventNotification - Route a received EventNotificationReply to
5493 * all currently regeistered event handlers.
5494 * @ioc: Pointer to MPT_ADAPTER structure
5495 * @pEventReply: Pointer to EventNotification reply frame
5496 * @evHandlers: Pointer to integer, number of event handlers
5498 * Returns sum of event handlers return values.
5501 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
5513 * Do platform normalization of values
5515 event = le32_to_cpu(pEventReply->Event) & 0xFF;
5516 // evCtx = le32_to_cpu(pEventReply->EventContext);
5517 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
5519 evData0 = le32_to_cpu(pEventReply->Data[0]);
5522 evStr = EventDescriptionStr(event, evData0);
5523 devtprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n",
5528 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_EVENTS)
5529 printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
5530 for (ii = 0; ii < evDataLen; ii++)
5531 printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
5536 * Do general / base driver event processing
5539 case MPI_EVENT_NONE: /* 00 */
5540 case MPI_EVENT_LOG_DATA: /* 01 */
5541 case MPI_EVENT_STATE_CHANGE: /* 02 */
5542 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
5543 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
5544 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
5545 case MPI_EVENT_RESCAN: /* 06 */
5546 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
5547 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
5548 case MPI_EVENT_LOGOUT: /* 09 */
5549 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
5550 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE: /* 0C */
5553 case MPI_EVENT_EVENT_CHANGE: /* 0A */
5555 u8 evState = evData0 & 0xFF;
5557 /* CHECKME! What if evState unexpectedly says OFF (0)? */
5559 /* Update EventState field in cached IocFacts */
5560 if (ioc->facts.Function) {
5561 ioc->facts.EventState = evState;
5568 * Should this event be logged? Events are written sequentially.
5569 * When buffer is full, start again at the top.
5571 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
5574 idx = ioc->eventContext % ioc->eventLogSize;
5576 ioc->events[idx].event = event;
5577 ioc->events[idx].eventContext = ioc->eventContext;
5579 for (ii = 0; ii < 2; ii++) {
5581 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
5583 ioc->events[idx].data[ii] = 0;
5586 ioc->eventContext++;
5591 * Call each currently registered protocol event handler.
5593 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5594 if (MptEvHandlers[ii]) {
5595 devtprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
5597 r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
5601 /* FIXME? Examine results here? */
5604 * If needed, send (a single) EventAck.
5606 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
5607 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
5608 devtprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
5613 *evHandlers = handlers;
5617 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5619 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
5620 * @ioc: Pointer to MPT_ADAPTER structure
5621 * @log_info: U32 LogInfo reply word from the IOC
5623 * Refer to lsi/fc_log.h.
5626 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
5628 static char *subcl_str[8] = {
5629 "FCP Initiator", "FCP Target", "LAN", "MPI Message Layer",
5630 "FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
5632 u8 subcl = (log_info >> 24) & 0x7;
5634 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}\n",
5635 ioc->name, log_info, subcl_str[subcl]);
5638 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5640 * mpt_sp_log_info - Log information returned from SCSI Parallel IOC.
5641 * @ioc: Pointer to MPT_ADAPTER structure
5642 * @mr: Pointer to MPT reply frame
5643 * @log_info: U32 LogInfo word from the IOC
5645 * Refer to lsi/sp_log.h.
5648 mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
5650 u32 info = log_info & 0x00FF0000;
5651 char *desc = "unknown";
5655 desc = "bug! MID not found";
5656 if (ioc->reload_fw == 0)
5661 desc = "Parity Error";
5665 desc = "ASYNC Outbound Overrun";
5669 desc = "SYNC Offset Error";
5677 desc = "Msg In Overflow";
5685 desc = "Outbound DMA Overrun";
5689 desc = "Task Management";
5693 desc = "Device Problem";
5697 desc = "Invalid Phase Change";
5701 desc = "Untagged Table Size";
5706 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
5709 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5711 * mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
5712 * @ioc: Pointer to MPT_ADAPTER structure
5713 * @ioc_status: U32 IOCStatus word from IOC
5714 * @mf: Pointer to MPT request frame
5716 * Refer to lsi/mpi.h.
5719 mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
5721 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
5725 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
5726 desc = "Invalid Function";
5729 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
5733 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
5734 desc = "Invalid SGL";
5737 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
5738 desc = "Internal Error";
5741 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
5745 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
5746 desc = "Insufficient Resources";
5749 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
5750 desc = "Invalid Field";
5753 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
5754 desc = "Invalid State";
5757 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
5758 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
5759 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
5760 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
5761 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
5762 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
5763 /* No message for Config IOCStatus values */
5766 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
5767 /* No message for recovered error
5768 desc = "SCSI Recovered Error";
5772 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
5773 desc = "SCSI Invalid Bus";
5776 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
5777 desc = "SCSI Invalid TargetID";
5780 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
5782 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
5783 U8 cdb = pScsiReq->CDB[0];
5784 if (cdb != 0x12) { /* Inquiry is issued for device scanning */
5785 desc = "SCSI Device Not There";
5790 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
5791 desc = "SCSI Data Overrun";
5794 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
5795 /* This error is checked in scsi_io_done(). Skip.
5796 desc = "SCSI Data Underrun";
5800 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
5801 desc = "SCSI I/O Data Error";
5804 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
5805 desc = "SCSI Protocol Error";
5808 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
5809 desc = "SCSI Task Terminated";
5812 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
5813 desc = "SCSI Residual Mismatch";
5816 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
5817 desc = "SCSI Task Management Failed";
5820 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
5821 desc = "SCSI IOC Terminated";
5824 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
5825 desc = "SCSI Ext Terminated";
5833 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc);
5836 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5837 EXPORT_SYMBOL(ioc_list);
5838 EXPORT_SYMBOL(mpt_proc_root_dir);
5839 EXPORT_SYMBOL(mpt_register);
5840 EXPORT_SYMBOL(mpt_deregister);
5841 EXPORT_SYMBOL(mpt_event_register);
5842 EXPORT_SYMBOL(mpt_event_deregister);
5843 EXPORT_SYMBOL(mpt_reset_register);
5844 EXPORT_SYMBOL(mpt_reset_deregister);
5845 EXPORT_SYMBOL(mpt_device_driver_register);
5846 EXPORT_SYMBOL(mpt_device_driver_deregister);
5847 EXPORT_SYMBOL(mpt_get_msg_frame);
5848 EXPORT_SYMBOL(mpt_put_msg_frame);
5849 EXPORT_SYMBOL(mpt_free_msg_frame);
5850 EXPORT_SYMBOL(mpt_add_sge);
5851 EXPORT_SYMBOL(mpt_send_handshake_request);
5852 EXPORT_SYMBOL(mpt_verify_adapter);
5853 EXPORT_SYMBOL(mpt_GetIocState);
5854 EXPORT_SYMBOL(mpt_print_ioc_summary);
5855 EXPORT_SYMBOL(mpt_lan_index);
5856 EXPORT_SYMBOL(mpt_stm_index);
5857 EXPORT_SYMBOL(mpt_HardResetHandler);
5858 EXPORT_SYMBOL(mpt_config);
5859 EXPORT_SYMBOL(mpt_toolbox);
5860 EXPORT_SYMBOL(mpt_findImVolumes);
5861 EXPORT_SYMBOL(mpt_read_ioc_pg_3);
5862 EXPORT_SYMBOL(mpt_alloc_fw_memory);
5863 EXPORT_SYMBOL(mpt_free_fw_memory);
5865 static struct pci_driver mptbase_driver = {
5867 .id_table = mptbase_pci_table,
5868 .probe = mptbase_probe,
5869 .remove = __devexit_p(mptbase_remove),
5871 .shutdown = mptbase_shutdown,
5874 .suspend = mptbase_suspend,
5875 .resume = mptbase_resume,
5879 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5881 * fusion_init - Fusion MPT base driver initialization routine.
5883 * Returns 0 for success, non-zero for failure.
5891 show_mptmod_ver(my_NAME, my_VERSION);
5892 printk(KERN_INFO COPYRIGHT "\n");
5894 for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
5895 MptCallbacks[i] = NULL;
5896 MptDriverClass[i] = MPTUNKNOWN_DRIVER;
5897 MptEvHandlers[i] = NULL;
5898 MptResetHandlers[i] = NULL;
5901 /* NEW! 20010120 -sralston
5902 * Register ourselves (mptbase) in order to facilitate
5903 * EventNotification handling.
5905 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
5907 /* Register for hard reset handling callbacks.
5909 if (mpt_reset_register(mpt_base_index, mpt_ioc_reset) == 0) {
5910 dprintk((KERN_INFO MYNAM ": Register for IOC reset notification\n"));
5915 #ifdef CONFIG_PROC_FS
5916 (void) procmpt_create();
5918 r = pci_module_init(&mptbase_driver);
5925 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5927 * fusion_exit - Perform driver unload cleanup.
5929 * This routine frees all resources associated with each MPT adapter
5930 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
5936 dexitprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
5938 pci_unregister_driver(&mptbase_driver);
5939 mpt_reset_deregister(mpt_base_index);
5941 #ifdef CONFIG_PROC_FS
5947 module_init(fusion_init);
5948 module_exit(fusion_exit);