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 DmpServices_t *DmpService;
143 #define WHOINIT_UNKNOWN 0xAA
145 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
149 /* Adapter link list */
151 /* Callback lookup table */
152 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
153 /* Protocol driver class lookup table */
154 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
155 /* Event handler lookup table */
156 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
157 /* Reset handler lookup table */
158 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
159 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
161 static int FusionInitCalled = 0;
162 static int mpt_base_index = -1;
163 static int last_drv_idx = -1;
165 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
167 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
171 static irqreturn_t mpt_interrupt(int irq, void *bus_id, struct pt_regs *r);
172 static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
174 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
175 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
176 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
177 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
179 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
180 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
181 //static u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
182 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
183 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
184 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
185 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
186 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
187 static int mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag);
188 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
189 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
190 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
191 static int PrimeIocFifos(MPT_ADAPTER *ioc);
192 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
193 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
194 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
195 static int GetLanConfigPages(MPT_ADAPTER *ioc);
196 static int GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
197 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
198 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
199 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
200 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
201 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
202 static void mpt_timer_expired(unsigned long data);
203 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
204 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
206 #ifdef CONFIG_PROC_FS
207 static int procmpt_summary_read(char *buf, char **start, off_t offset,
208 int request, int *eof, void *data);
209 static int procmpt_version_read(char *buf, char **start, off_t offset,
210 int request, int *eof, void *data);
211 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
212 int request, int *eof, void *data);
214 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
216 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
217 static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
218 static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
219 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
220 static void mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info);
222 /* module entry point */
223 static int __devinit mptbase_probe (struct pci_dev *, const struct pci_device_id *);
224 static void __devexit mptbase_remove(struct pci_dev *);
225 static void mptbase_shutdown(struct device * );
226 static int __init fusion_init (void);
227 static void __exit fusion_exit (void);
229 /****************************************************************************
233 static struct pci_device_id mptbase_pci_table[] = {
234 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC909,
235 PCI_ANY_ID, PCI_ANY_ID },
236 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929,
237 PCI_ANY_ID, PCI_ANY_ID },
238 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919,
239 PCI_ANY_ID, PCI_ANY_ID },
240 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929X,
241 PCI_ANY_ID, PCI_ANY_ID },
242 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919X,
243 PCI_ANY_ID, PCI_ANY_ID },
244 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1030,
245 PCI_ANY_ID, PCI_ANY_ID },
246 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_1030_53C1035,
247 PCI_ANY_ID, PCI_ANY_ID },
248 {0} /* Terminating entry */
250 MODULE_DEVICE_TABLE(pci, mptbase_pci_table);
252 #define CHIPREG_READ32(addr) readl_relaxed(addr)
253 #define CHIPREG_READ32_dmasync(addr) readl(addr)
254 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
255 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
256 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
258 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
260 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
261 * @irq: irq number (not used)
262 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
263 * @r: pt_regs pointer (not used)
265 * This routine is registered via the request_irq() kernel API call,
266 * and handles all interrupts generated from a specific MPT adapter
267 * (also referred to as a IO Controller or IOC).
268 * This routine must clear the interrupt from the adapter and does
269 * so by reading the reply FIFO. Multiple replies may be processed
270 * per single call to this routine; up to MPT_MAX_REPLIES_PER_ISR
271 * which is currently set to 32 in mptbase.h.
273 * This routine handles register-level access of the adapter but
274 * dispatches (calls) a protocol-specific callback routine to handle
275 * the protocol-specific details of the MPT request completion.
278 mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
289 ioc = (MPT_ADAPTER *)bus_id;
292 * Drain the reply FIFO!
294 * NOTES: I've seen up to 10 replies processed in this loop, so far...
295 * Update: I've seen up to 9182 replies processed in this loop! ??
296 * Update: Limit ourselves to processing max of N replies
301 if ((pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo)) == 0xFFFFFFFF)
308 * Check for non-TURBO reply!
310 if (pa & MPI_ADDRESS_REPLY_A_BIT) {
314 /* non-TURBO reply! Hmmm, something may be up...
315 * Newest turbo reply mechanism; get address
316 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
319 /* Map DMA address of reply header to cpu address.
320 * pa is 32 bits - but the dma address may be 32 or 64 bits
321 * get offset based only only the low addresses
323 reply_dma_low = (pa = (pa << 1));
324 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
325 (reply_dma_low - ioc->reply_frames_low_dma));
327 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
328 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
329 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
331 dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x\n",
332 ioc->name, mr, req_idx));
333 DBG_DUMP_REPLY_FRAME(mr)
335 /* NEW! 20010301 -sralston
336 * Check/log IOC log info
338 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
339 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
340 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
341 if ((int)ioc->chip_type <= (int)FC929)
342 mpt_fc_log_info(ioc, log_info);
344 mpt_sp_log_info(ioc, log_info);
346 if (ioc_stat & MPI_IOCSTATUS_MASK) {
347 if ((int)ioc->chip_type <= (int)FC929)
350 mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
354 * Process turbo (context) reply...
356 dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n", ioc->name, pa));
357 type = (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT);
358 if (type == MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET) {
359 cb_idx = mpt_stm_index;
361 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
362 } else if (type == MPI_CONTEXT_REPLY_TYPE_LAN) {
363 cb_idx = mpt_lan_index;
365 * BUG FIX! 20001218 -sralston
366 * Blind set of mf to NULL here was fatal
367 * after lan_reply says "freeme"
368 * Fix sort of combined with an optimization here;
369 * added explicit check for case where lan_reply
370 * was just returning 1 and doing nothing else.
371 * For this case skip the callback, but set up
372 * proper mf value first here:-)
374 if ((pa & 0x58000000) == 0x58000000) {
375 req_idx = pa & 0x0000FFFF;
376 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
379 * IMPORTANT! Invalidate the callback!
385 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
387 req_idx = pa & 0x0000FFFF;
388 cb_idx = (pa & 0x00FF0000) >> 16;
389 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
392 pa = 0; /* No reply flush! */
396 if ((int)ioc->chip_type > (int)FC929) {
397 /* Verify mf, mr are reasonable.
399 if ((mf) && ((mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))
400 || (mf < ioc->req_frames)) ) {
401 printk(MYIOC_s_WARN_FMT
402 "mpt_interrupt: Invalid mf (%p) req_idx (%d)!\n", ioc->name, (void *)mf, req_idx);
407 if ((pa) && (mr) && ((mr >= MPT_INDEX_2_RFPTR(ioc, ioc->req_depth))
408 || (mr < ioc->reply_frames)) ) {
409 printk(MYIOC_s_WARN_FMT
410 "mpt_interrupt: Invalid rf (%p)!\n", ioc->name, (void *)mr);
415 if (cb_idx > (MPT_MAX_PROTOCOL_DRIVERS-1)) {
416 printk(MYIOC_s_WARN_FMT
417 "mpt_interrupt: Invalid cb_idx (%d)!\n", ioc->name, cb_idx);
425 /* Check for (valid) IO callback! */
427 /* Do the callback! */
428 freeme = (*(MptCallbacks[cb_idx]))(ioc, mf, mr);
432 /* Flush (non-TURBO) reply with a WRITE! */
433 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
439 /* Put Request back on FreeQ! */
440 spin_lock_irqsave(&ioc->FreeQlock, flags);
441 Q_ADD_TAIL(&ioc->FreeQ, &mf->u.frame.linkage, MPT_FRAME_HDR);
445 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
449 } /* drain reply FIFO */
454 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
456 * mpt_base_reply - MPT base driver's callback routine; all base driver
457 * "internal" request/reply processing is routed here.
458 * Currently used for EventNotification and EventAck handling.
459 * @ioc: Pointer to MPT_ADAPTER structure
460 * @mf: Pointer to original MPT request frame
461 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
463 * Returns 1 indicating original alloc'd request frame ptr
464 * should be freed, or 0 if it shouldn't.
467 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
472 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name));
475 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
476 printk(MYIOC_s_ERR_FMT "NULL or BAD request frame ptr! (=%p)\n",
477 ioc->name, (void *)mf);
482 dprintk((MYIOC_s_ERR_FMT "Unexpected NULL Event (turbo?) reply!\n",
487 if (!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
488 dmfprintk((KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf));
489 DBG_DUMP_REQUEST_FRAME_HDR(mf)
492 func = reply->u.hdr.Function;
493 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n",
496 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
497 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
501 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
502 if (results != evHandlers) {
503 /* CHECKME! Any special handling needed here? */
504 devtprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
505 ioc->name, evHandlers, results));
509 * Hmmm... It seems that EventNotificationReply is an exception
510 * to the rule of one reply per request.
512 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
515 #ifdef CONFIG_PROC_FS
516 // LogEvent(ioc, pEvReply);
519 } else if (func == MPI_FUNCTION_EVENT_ACK) {
520 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
522 } else if (func == MPI_FUNCTION_CONFIG ||
523 func == MPI_FUNCTION_TOOLBOX) {
527 dcprintk((MYIOC_s_INFO_FMT "config_complete (mf=%p,mr=%p)\n",
528 ioc->name, mf, reply));
530 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
533 /* disable timer and remove from linked list */
534 del_timer(&pCfg->timer);
536 spin_lock_irqsave(&ioc->FreeQlock, flags);
537 Q_DEL_ITEM(&pCfg->linkage);
538 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
541 * If IOC Status is SUCCESS, save the header
542 * and set the status code to GOOD.
544 pCfg->status = MPT_CONFIG_ERROR;
546 ConfigReply_t *pReply = (ConfigReply_t *)reply;
549 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
550 dcprintk((KERN_NOTICE " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
551 status, le32_to_cpu(pReply->IOCLogInfo)));
553 pCfg->status = status;
554 if (status == MPI_IOCSTATUS_SUCCESS) {
555 pCfg->hdr->PageVersion = pReply->Header.PageVersion;
556 pCfg->hdr->PageLength = pReply->Header.PageLength;
557 pCfg->hdr->PageNumber = pReply->Header.PageNumber;
558 pCfg->hdr->PageType = pReply->Header.PageType;
563 * Wake up the original calling thread
569 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
574 * Conditionally tell caller to free the original
575 * EventNotification/EventAck/unexpected request frame!
580 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
582 * mpt_register - Register protocol-specific main callback handler.
583 * @cbfunc: callback function pointer
584 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
586 * This routine is called by a protocol-specific driver (SCSI host,
587 * LAN, SCSI target) to register it's reply callback routine. Each
588 * protocol-specific driver must do this before it will be able to
589 * use any IOC resources, such as obtaining request frames.
591 * NOTES: The SCSI protocol driver currently calls this routine thrice
592 * in order to register separate callbacks; one for "normal" SCSI IO;
593 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
595 * Returns a positive integer valued "handle" in the
596 * range (and S.O.D. order) {N,...,7,6,5,...,1} if successful.
597 * Any non-positive return value (including zero!) should be considered
598 * an error by the caller.
601 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
609 * Handle possibility of the mptscsih_detect() routine getting
610 * called *before* fusion_init!
612 if (!FusionInitCalled) {
613 dprintk((KERN_INFO MYNAM ": Hmmm, calling fusion_init from mpt_register!\n"));
615 * NOTE! We'll get recursion here, as fusion_init()
616 * calls mpt_register()!
624 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
625 * (slot/handle 0 is reserved!)
627 for (i = MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
628 if (MptCallbacks[i] == NULL) {
629 MptCallbacks[i] = cbfunc;
630 MptDriverClass[i] = dclass;
631 MptEvHandlers[i] = NULL;
640 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
642 * mpt_deregister - Deregister a protocol drivers resources.
643 * @cb_idx: previously registered callback handle
645 * Each protocol-specific driver should call this routine when it's
646 * module is unloaded.
649 mpt_deregister(int cb_idx)
651 if ((cb_idx >= 0) && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
652 MptCallbacks[cb_idx] = NULL;
653 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
654 MptEvHandlers[cb_idx] = NULL;
660 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
662 * mpt_event_register - Register protocol-specific event callback
664 * @cb_idx: previously registered (via mpt_register) callback handle
665 * @ev_cbfunc: callback function
667 * This routine can be called by one or more protocol-specific drivers
668 * if/when they choose to be notified of MPT events.
670 * Returns 0 for success.
673 mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc)
675 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
678 MptEvHandlers[cb_idx] = ev_cbfunc;
682 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
684 * mpt_event_deregister - Deregister protocol-specific event callback
686 * @cb_idx: previously registered callback handle
688 * Each protocol-specific driver should call this routine
689 * when it does not (or can no longer) handle events,
690 * or when it's module is unloaded.
693 mpt_event_deregister(int cb_idx)
695 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
698 MptEvHandlers[cb_idx] = NULL;
701 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
703 * mpt_reset_register - Register protocol-specific IOC reset handler.
704 * @cb_idx: previously registered (via mpt_register) callback handle
705 * @reset_func: reset function
707 * This routine can be called by one or more protocol-specific drivers
708 * if/when they choose to be notified of IOC resets.
710 * Returns 0 for success.
713 mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func)
715 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
718 MptResetHandlers[cb_idx] = reset_func;
722 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
724 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
725 * @cb_idx: previously registered callback handle
727 * Each protocol-specific driver should call this routine
728 * when it does not (or can no longer) handle IOC reset handling,
729 * or when it's module is unloaded.
732 mpt_reset_deregister(int cb_idx)
734 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
737 MptResetHandlers[cb_idx] = NULL;
740 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
742 * mpt_device_driver_register - Register device driver hooks
745 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
750 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) {
755 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
757 /* call per pci device probe entry point */
758 list_for_each_entry(ioc, &ioc_list, list) {
759 if(dd_cbfunc->probe) {
760 error = dd_cbfunc->probe(ioc->pcidev,
761 ioc->pcidev->driver->id_table);
770 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
772 * mpt_device_driver_deregister - DeRegister device driver hooks
775 mpt_device_driver_deregister(int cb_idx)
777 struct mpt_pci_driver *dd_cbfunc;
780 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
783 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
785 list_for_each_entry(ioc, &ioc_list, list) {
786 if (dd_cbfunc->remove)
787 dd_cbfunc->remove(ioc->pcidev);
790 MptDeviceDriverHandlers[cb_idx] = NULL;
794 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
796 * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
797 * allocated per MPT adapter.
798 * @handle: Handle of registered MPT protocol driver
799 * @ioc: Pointer to MPT adapter structure
801 * Returns pointer to a MPT request frame or %NULL if none are available
802 * or IOC is not active.
805 mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc)
809 u16 req_idx; /* Request index */
811 /* validate handle and ioc identifier */
815 printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n");
818 /* If interrupts are not attached, do not return a request frame */
822 spin_lock_irqsave(&ioc->FreeQlock, flags);
823 if (! Q_IS_EMPTY(&ioc->FreeQ)) {
826 mf = ioc->FreeQ.head;
827 Q_DEL_ITEM(&mf->u.frame.linkage);
828 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
829 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
831 req_idx = cpu_to_le16(req_offset / ioc->req_sz);
832 mf->u.frame.hwhdr.msgctxu.fld.req_idx = req_idx;
833 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
834 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; /* Default, will be changed if necessary in SG generation */
841 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
845 printk(KERN_WARNING "IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", ioc->mfcnt, ioc->req_depth);
847 if (mfcounter == PRINT_MF_COUNT)
848 printk(KERN_INFO "MF Count 0x%x Max 0x%x \n", ioc->mfcnt, ioc->req_depth);
851 dmfprintk((KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",
852 ioc->name, handle, ioc->id, mf));
856 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
858 * mpt_put_msg_frame - Send a protocol specific MPT request frame
860 * @handle: Handle of registered MPT protocol driver
861 * @ioc: Pointer to MPT adapter structure
862 * @mf: Pointer to MPT request frame
864 * This routine posts a MPT request frame to the request post FIFO of a
865 * specific MPT adapter.
868 mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
872 u16 req_idx; /* Request index */
874 /* ensure values are reset properly! */
875 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
876 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
878 req_idx = cpu_to_le16(req_offset / ioc->req_sz);
879 mf->u.frame.hwhdr.msgctxu.fld.req_idx = req_idx;
880 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
882 #ifdef MPT_DEBUG_MSG_FRAME
884 u32 *m = mf->u.frame.hwhdr.__hdr;
887 printk(KERN_INFO MYNAM ": %s: About to Put msg frame @ %p:\n" KERN_INFO " ",
889 n = ioc->req_sz/4 - 1;
892 for (ii=0; ii<=n; ii++) {
893 if (ii && ((ii%8)==0))
894 printk("\n" KERN_INFO " ");
895 printk(" %08x", le32_to_cpu(m[ii]));
901 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
902 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]));
903 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
906 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
908 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
909 * @handle: Handle of registered MPT protocol driver
910 * @ioc: Pointer to MPT adapter structure
911 * @mf: Pointer to MPT request frame
913 * This routine places a MPT request frame back on the MPT adapter's
917 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
921 /* Put Request back on FreeQ! */
922 spin_lock_irqsave(&ioc->FreeQlock, flags);
923 Q_ADD_TAIL(&ioc->FreeQ, &mf->u.frame.linkage, MPT_FRAME_HDR);
927 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
930 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
932 * mpt_add_sge - Place a simple SGE at address pAddr.
933 * @pAddr: virtual address for SGE
934 * @flagslength: SGE flags and data transfer length
935 * @dma_addr: Physical address
937 * This routine places a MPT request frame back on the MPT adapter's
941 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
943 if (sizeof(dma_addr_t) == sizeof(u64)) {
944 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
945 u32 tmp = dma_addr & 0xFFFFFFFF;
947 pSge->FlagsLength = cpu_to_le32(flagslength);
948 pSge->Address.Low = cpu_to_le32(tmp);
949 tmp = (u32) ((u64)dma_addr >> 32);
950 pSge->Address.High = cpu_to_le32(tmp);
953 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
954 pSge->FlagsLength = cpu_to_le32(flagslength);
955 pSge->Address = cpu_to_le32(dma_addr);
959 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
961 * mpt_add_chain - Place a chain SGE at address pAddr.
962 * @pAddr: virtual address for SGE
963 * @next: nextChainOffset value (u32's)
964 * @length: length of next SGL segment
965 * @dma_addr: Physical address
967 * This routine places a MPT request frame back on the MPT adapter's
971 mpt_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
973 if (sizeof(dma_addr_t) == sizeof(u64)) {
974 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
975 u32 tmp = dma_addr & 0xFFFFFFFF;
977 pChain->Length = cpu_to_le16(length);
978 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
980 pChain->NextChainOffset = next;
982 pChain->Address.Low = cpu_to_le32(tmp);
983 tmp = (u32) ((u64)dma_addr >> 32);
984 pChain->Address.High = cpu_to_le32(tmp);
986 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
987 pChain->Length = cpu_to_le16(length);
988 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
989 pChain->NextChainOffset = next;
990 pChain->Address = cpu_to_le32(dma_addr);
994 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
996 * mpt_send_handshake_request - Send MPT request via doorbell
998 * @handle: Handle of registered MPT protocol driver
999 * @ioc: Pointer to MPT adapter structure
1000 * @reqBytes: Size of the request in bytes
1001 * @req: Pointer to MPT request frame
1002 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1004 * This routine is used exclusively to send MptScsiTaskMgmt
1005 * requests since they are required to be sent via doorbell handshake.
1007 * NOTE: It is the callers responsibility to byte-swap fields in the
1008 * request which are greater than 1 byte in size.
1010 * Returns 0 for success, non-zero for failure.
1013 mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
1019 /* State is known to be good upon entering
1020 * this function so issue the bus reset
1025 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1026 * setting cb_idx/req_idx. But ONLY if this request
1027 * is in proper (pre-alloc'd) request buffer range...
1029 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
1030 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
1031 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
1032 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
1033 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
1036 /* Make sure there are no doorbells */
1037 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1039 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1040 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1041 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1043 /* Wait for IOC doorbell int */
1044 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1048 /* Read doorbell and check for active bit */
1049 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1052 dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
1055 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1057 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1061 /* Send request via doorbell handshake */
1062 req_as_bytes = (u8 *) req;
1063 for (ii = 0; ii < reqBytes/4; ii++) {
1066 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1067 (req_as_bytes[(ii*4) + 1] << 8) |
1068 (req_as_bytes[(ii*4) + 2] << 16) |
1069 (req_as_bytes[(ii*4) + 3] << 24));
1070 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1071 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1077 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1082 /* Make sure there are no doorbells */
1083 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1088 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1090 * mpt_verify_adapter - Given a unique IOC identifier, set pointer to
1091 * the associated MPT adapter structure.
1092 * @iocid: IOC unique identifier (integer)
1093 * @iocpp: Pointer to pointer to IOC adapter
1095 * Returns iocid and sets iocpp.
1098 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1102 list_for_each_entry(ioc,&ioc_list,list) {
1103 if (ioc->id == iocid) {
1113 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1115 * mptbase_probe - Install a PCI intelligent MPT adapter.
1116 * @pdev: Pointer to pci_dev structure
1118 * This routine performs all the steps necessary to bring the IOC of
1119 * a MPT adapter to a OPERATIONAL state. This includes registering
1120 * memory regions, registering the interrupt, and allocating request
1121 * and reply memory pools.
1123 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1126 * Returns 0 for success, non-zero for failure.
1128 * TODO: Add support for polled controllers
1130 static int __devinit
1131 mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1135 unsigned long mem_phys;
1141 u64 mask = 0xffffffffffffffffULL;
1144 static int mpt_ids = 0;
1145 #ifdef CONFIG_PROC_FS
1146 struct proc_dir_entry *dent, *ent;
1149 if (pci_enable_device(pdev))
1152 dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1154 if (!pci_set_dma_mask(pdev, mask)) {
1155 dprintk((KERN_INFO MYNAM
1156 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1157 } else if (pci_set_dma_mask(pdev, (u64) 0xffffffff)) {
1158 printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1162 if (!pci_set_consistent_dma_mask(pdev, mask))
1163 dprintk((KERN_INFO MYNAM
1164 ": Using 64 bit consistent mask\n"));
1166 dprintk((KERN_INFO MYNAM
1167 ": Not using 64 bit consistent mask\n"));
1169 ioc = kmalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1171 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1174 memset(ioc, 0, sizeof(MPT_ADAPTER));
1175 ioc->alloc_total = sizeof(MPT_ADAPTER);
1176 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1177 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1180 ioc->diagPending = 0;
1181 spin_lock_init(&ioc->diagLock);
1183 /* Initialize the event logging.
1185 ioc->eventTypes = 0; /* None */
1186 ioc->eventContext = 0;
1187 ioc->eventLogSize = 0;
1194 ioc->cached_fw = NULL;
1196 /* Initilize SCSI Config Data structure
1198 memset(&ioc->spi_data, 0, sizeof(ScsiCfgData));
1200 /* Initialize the running configQ head.
1202 Q_INIT(&ioc->configQ, Q_ITEM);
1204 /* Find lookup slot. */
1205 INIT_LIST_HEAD(&ioc->list);
1206 ioc->id = mpt_ids++;
1208 mem_phys = msize = 0;
1210 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1211 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1212 /* Get I/O space! */
1213 port = pci_resource_start(pdev, ii);
1214 psize = pci_resource_len(pdev,ii);
1217 mem_phys = pci_resource_start(pdev, ii);
1218 msize = pci_resource_len(pdev,ii);
1222 ioc->mem_size = msize;
1224 if (ii == DEVICE_COUNT_RESOURCE) {
1225 printk(KERN_ERR MYNAM ": ERROR - MPT adapter has no memory regions defined!\n");
1230 dinitprintk((KERN_INFO MYNAM ": MPT adapter @ %lx, msize=%dd bytes\n", mem_phys, msize));
1231 dinitprintk((KERN_INFO MYNAM ": (port i/o @ %lx, psize=%dd bytes)\n", port, psize));
1234 /* Get logical ptr for PciMem0 space */
1235 /*mem = ioremap(mem_phys, msize);*/
1236 mem = ioremap(mem_phys, 0x100);
1238 printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1243 dinitprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1245 dinitprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1246 &ioc->facts, &ioc->pfacts[0]));
1248 ioc->mem_phys = mem_phys;
1249 ioc->chip = (SYSIF_REGS*)mem;
1251 /* Save Port IO values in case we need to do downloadboot */
1253 u8 *pmem = (u8*)port;
1254 ioc->pio_mem_phys = port;
1255 ioc->pio_chip = (SYSIF_REGS*)pmem;
1258 ioc->chip_type = FCUNK;
1259 if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC909) {
1260 ioc->chip_type = FC909;
1261 ioc->prod_name = "LSIFC909";
1263 if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
1264 ioc->chip_type = FC929;
1265 ioc->prod_name = "LSIFC929";
1267 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) {
1268 ioc->chip_type = FC919;
1269 ioc->prod_name = "LSIFC919";
1271 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) {
1272 ioc->chip_type = FC929X;
1273 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1274 if (revision < XL_929) {
1275 ioc->prod_name = "LSIFC929X";
1276 /* 929X Chip Fix. Set Split transactions level
1277 * for PCIX. Set MOST bits to zero.
1279 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1281 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1283 ioc->prod_name = "LSIFC929XL";
1284 /* 929XL Chip Fix. Set MMRBC to 0x08.
1286 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1288 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1291 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) {
1292 ioc->chip_type = FC919X;
1293 ioc->prod_name = "LSIFC919X";
1294 /* 919X Chip Fix. Set Split transactions level
1295 * for PCIX. Set MOST bits to zero.
1297 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1299 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1301 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
1302 ioc->chip_type = C1030;
1303 ioc->prod_name = "LSI53C1030";
1304 /* 1030 Chip Fix. Disable Split transactions
1305 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1307 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1308 if (revision < C0_1030) {
1309 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1311 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1314 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
1315 ioc->chip_type = C1035;
1316 ioc->prod_name = "LSI53C1035";
1319 sprintf(ioc->name, "ioc%d", ioc->id);
1321 spin_lock_init(&ioc->FreeQlock);
1324 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1326 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1328 /* Set lookup ptr. */
1329 list_add_tail(&ioc->list, &ioc_list);
1333 r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc);
1337 printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %d!\n",
1338 ioc->name, pdev->irq);
1340 printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %s!\n",
1341 ioc->name, __irq_itoa(pdev->irq));
1343 list_del(&ioc->list);
1349 ioc->pci_irq = pdev->irq;
1351 pci_set_master(pdev); /* ?? */
1352 pci_set_drvdata(pdev, ioc);
1355 dprintk((KERN_INFO MYNAM ": %s installed at interrupt %d\n", ioc->name, pdev->irq));
1357 dprintk((KERN_INFO MYNAM ": %s installed at interrupt %s\n", ioc->name, __irq_itoa(pdev->irq)));
1361 /* NEW! 20010220 -sralston
1362 * Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1364 if ((ioc->chip_type == FC929) || (ioc->chip_type == C1030)
1365 || (ioc->chip_type == C1035) || (ioc->chip_type == FC929X))
1366 mpt_detect_bound_ports(ioc, pdev);
1368 if ((r = mpt_do_ioc_recovery(ioc,
1369 MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0) {
1370 printk(KERN_WARNING MYNAM
1371 ": WARNING - %s did not initialize properly! (%d)\n",
1374 list_del(&ioc->list);
1375 free_irq(ioc->pci_irq, ioc);
1378 pci_set_drvdata(pdev, NULL);
1382 /* call per device driver probe entry point */
1383 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1384 if(MptDeviceDriverHandlers[ii] &&
1385 MptDeviceDriverHandlers[ii]->probe) {
1386 MptDeviceDriverHandlers[ii]->probe(pdev,id);
1390 #ifdef CONFIG_PROC_FS
1392 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1394 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1396 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1398 ent->read_proc = procmpt_iocinfo_read;
1401 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1403 ent->read_proc = procmpt_summary_read;
1412 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1414 * mptbase_remove - Remove a PCI intelligent MPT adapter.
1415 * @pdev: Pointer to pci_dev structure
1419 static void __devexit
1420 mptbase_remove(struct pci_dev *pdev)
1422 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1426 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1427 remove_proc_entry(pname, NULL);
1428 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1429 remove_proc_entry(pname, NULL);
1430 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1431 remove_proc_entry(pname, NULL);
1433 /* call per device driver remove entry point */
1434 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1435 if(MptDeviceDriverHandlers[ii] &&
1436 MptDeviceDriverHandlers[ii]->remove) {
1437 MptDeviceDriverHandlers[ii]->remove(pdev);
1441 /* Disable interrupts! */
1442 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1445 synchronize_irq(pdev->irq);
1447 /* Clear any lingering interrupt */
1448 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1450 CHIPREG_READ32(&ioc->chip->IntStatus);
1452 mpt_adapter_dispose(ioc);
1454 pci_set_drvdata(pdev, NULL);
1457 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1459 * mptbase_shutdown -
1463 mptbase_shutdown(struct device * dev)
1467 /* call per device driver shutdown entry point */
1468 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1469 if(MptDeviceDriverHandlers[ii] &&
1470 MptDeviceDriverHandlers[ii]->shutdown) {
1471 MptDeviceDriverHandlers[ii]->shutdown(dev);
1478 /**************************************************************************
1482 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1484 * mptbase_suspend - Fusion MPT base driver suspend routine.
1489 mptbase_suspend(struct pci_dev *pdev, u32 state)
1492 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1498 device_state=1; /* D1 */;
1502 device_state=3; /* D3 */;
1505 return -EAGAIN /*FIXME*/;
1509 printk(MYIOC_s_INFO_FMT
1510 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1511 ioc->name, pdev, pci_name(pdev), device_state);
1513 /* call per device driver suspend entry point */
1514 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1515 if(MptDeviceDriverHandlers[ii] &&
1516 MptDeviceDriverHandlers[ii]->suspend) {
1517 MptDeviceDriverHandlers[ii]->suspend(pdev, state);
1521 pci_save_state(pdev, ioc->PciState);
1523 /* put ioc into READY_STATE */
1524 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1525 printk(MYIOC_s_ERR_FMT
1526 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1529 /* disable interrupts */
1530 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1533 /* Clear any lingering interrupt */
1534 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1536 pci_disable_device(pdev);
1537 pci_set_power_state(pdev, device_state);
1542 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1544 * mptbase_resume - Fusion MPT base driver resume routine.
1549 mptbase_resume(struct pci_dev *pdev)
1551 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1552 u32 device_state = pdev->current_state;
1556 printk(MYIOC_s_INFO_FMT
1557 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1558 ioc->name, pdev, pci_name(pdev), device_state);
1560 pci_set_power_state(pdev, 0);
1561 pci_restore_state(pdev, ioc->PciState);
1562 pci_enable_device(pdev);
1564 /* enable interrupts */
1565 CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
1568 /* F/W not running */
1569 if(!CHIPREG_READ32(&ioc->chip->Doorbell)) {
1570 /* enable domain validation flags */
1571 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
1572 ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_NEED_DV;
1576 printk(MYIOC_s_INFO_FMT
1577 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1579 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1580 CHIPREG_READ32(&ioc->chip->Doorbell));
1582 /* bring ioc to operational state */
1583 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1584 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1585 printk(MYIOC_s_INFO_FMT
1586 "pci-resume: Cannot recover, error:[%x]\n",
1587 ioc->name, recovery_state);
1589 printk(MYIOC_s_INFO_FMT
1590 "pci-resume: success\n", ioc->name);
1593 /* call per device driver resume entry point */
1594 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1595 if(MptDeviceDriverHandlers[ii] &&
1596 MptDeviceDriverHandlers[ii]->resume) {
1597 MptDeviceDriverHandlers[ii]->resume(pdev);
1605 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1607 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1608 * @ioc: Pointer to MPT adapter structure
1609 * @reason: Event word / reason
1610 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1612 * This routine performs all the steps necessary to bring the IOC
1613 * to a OPERATIONAL state.
1615 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1620 * -1 if failed to get board READY
1621 * -2 if READY but IOCFacts Failed
1622 * -3 if READY but PrimeIOCFifos Failed
1623 * -4 if READY but IOCInit Failed
1626 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1628 int hard_reset_done = 0;
1629 int alt_ioc_ready = 0;
1635 int reset_alt_ioc_active = 0;
1637 printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1638 ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1640 /* Disable reply interrupts (also blocks FreeQ) */
1641 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1645 if (ioc->alt_ioc->active)
1646 reset_alt_ioc_active = 1;
1648 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1649 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1650 ioc->alt_ioc->active = 0;
1654 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1657 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1658 if (hard_reset_done == -4) {
1659 printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1662 if (reset_alt_ioc_active && ioc->alt_ioc) {
1663 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1664 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1665 ioc->alt_ioc->name));
1666 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
1667 ioc->alt_ioc->active = 1;
1671 printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1677 /* hard_reset_done = 0 if a soft reset was performed
1678 * and 1 if a hard reset was performed.
1680 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1681 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1684 printk(KERN_WARNING MYNAM
1685 ": alt-%s: Not ready WARNING!\n",
1686 ioc->alt_ioc->name);
1689 for (ii=0; ii<5; ii++) {
1690 /* Get IOC facts! Allow 5 retries */
1691 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1697 dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1699 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1700 MptDisplayIocCapabilities(ioc);
1703 if (alt_ioc_ready) {
1704 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1705 dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1706 /* Retry - alt IOC was initialized once
1708 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1711 dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1713 reset_alt_ioc_active = 0;
1714 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1715 MptDisplayIocCapabilities(ioc->alt_ioc);
1719 /* Prime reply & request queues!
1720 * (mucho alloc's) Must be done prior to
1721 * init as upper addresses are needed for init.
1722 * If fails, continue with alt-ioc processing
1724 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
1727 /* May need to check/upload firmware & data here!
1728 * If fails, continue with alt-ioc processing
1730 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
1733 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
1734 printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1735 ioc->alt_ioc->name, rc);
1737 reset_alt_ioc_active = 0;
1740 if (alt_ioc_ready) {
1741 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
1743 reset_alt_ioc_active = 0;
1744 printk(KERN_WARNING MYNAM
1745 ": alt-%s: (%d) init failure WARNING!\n",
1746 ioc->alt_ioc->name, rc);
1750 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
1751 if (ioc->upload_fw) {
1752 ddlprintk((MYIOC_s_INFO_FMT
1753 "firmware upload required!\n", ioc->name));
1755 /* Controller is not operational, cannot do upload
1758 rc = mpt_do_upload(ioc, sleepFlag);
1760 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
1766 /* Enable! (reply interrupt) */
1767 CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
1771 if (reset_alt_ioc_active && ioc->alt_ioc) {
1772 /* (re)Enable alt-IOC! (reply interrupt) */
1773 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1774 ioc->alt_ioc->name));
1775 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
1776 ioc->alt_ioc->active = 1;
1779 /* NEW! 20010120 -sralston
1780 * Enable MPT base driver management of EventNotification
1781 * and EventAck handling.
1783 if ((ret == 0) && (!ioc->facts.EventState))
1784 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
1786 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
1787 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
1789 /* (Bugzilla:fibrebugs, #513)
1790 * Bug fix (part 2)! 20010905 -sralston
1791 * Add additional "reason" check before call to GetLanConfigPages
1792 * (combined with GetIoUnitPage2 call). This prevents a somewhat
1793 * recursive scenario; GetLanConfigPages times out, timer expired
1794 * routine calls HardResetHandler, which calls into here again,
1795 * and we try GetLanConfigPages again...
1797 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1798 if ((int)ioc->chip_type <= (int)FC929) {
1800 * Pre-fetch FC port WWN and stuff...
1801 * (FCPortPage0_t stuff)
1803 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1804 (void) GetFcPortPage0(ioc, ii);
1807 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
1808 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
1810 * Pre-fetch the ports LAN MAC address!
1811 * (LANPage1_t stuff)
1813 (void) GetLanConfigPages(ioc);
1816 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
1817 dprintk((MYIOC_s_INFO_FMT "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
1818 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0] ));
1823 /* Get NVRAM and adapter maximums from SPP 0 and 2
1825 mpt_GetScsiPortSettings(ioc, 0);
1827 /* Get version and length of SDP 1
1829 mpt_readScsiDevicePageHeaders(ioc, 0);
1833 if (ioc->facts.MsgVersion >= 0x0102)
1834 mpt_findImVolumes(ioc);
1836 /* Check, and possibly reset, the coalescing value
1838 mpt_read_ioc_pg_1(ioc);
1840 mpt_read_ioc_pg_4(ioc);
1843 GetIoUnitPage2(ioc);
1847 * Call each currently registered protocol IOC reset handler
1848 * with post-reset indication.
1849 * NOTE: If we're doing _IOC_BRINGUP, there can be no
1850 * MptResetHandlers[] registered yet.
1852 if (hard_reset_done) {
1854 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
1855 if ((ret == 0) && MptResetHandlers[ii]) {
1856 dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
1858 rc += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET);
1862 if (alt_ioc_ready && MptResetHandlers[ii]) {
1863 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
1864 ioc->name, ioc->alt_ioc->name, ii));
1865 rc += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
1869 /* FIXME? Examine results here? */
1875 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1877 * mpt_detect_bound_ports - Search for PCI bus/dev_function
1878 * which matches PCI bus/dev_function (+/-1) for newly discovered 929,
1879 * 929X, 1030 or 1035.
1880 * @ioc: Pointer to MPT adapter structure
1881 * @pdev: Pointer to (struct pci_dev) structure
1883 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
1884 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
1887 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
1889 unsigned int match_lo, match_hi;
1890 MPT_ADAPTER *ioc_srch;
1892 match_lo = pdev->devfn-1;
1893 match_hi = pdev->devfn+1;
1894 dprintk((MYIOC_s_INFO_FMT "PCI bus/devfn=%x/%x, searching for devfn match on %x or %x\n",
1895 ioc->name, pdev->bus->number, pdev->devfn, match_lo, match_hi));
1897 list_for_each_entry(ioc_srch, &ioc_list, list) {
1898 struct pci_dev *_pcidev = ioc_srch->pcidev;
1900 if ((_pcidev->device == pdev->device) &&
1901 (_pcidev->bus->number == pdev->bus->number) &&
1902 (_pcidev->devfn == match_lo || _pcidev->devfn == match_hi) ) {
1903 /* Paranoia checks */
1904 if (ioc->alt_ioc != NULL) {
1905 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1906 ioc->name, ioc->alt_ioc->name);
1908 } else if (ioc_srch->alt_ioc != NULL) {
1909 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1910 ioc_srch->name, ioc_srch->alt_ioc->name);
1913 dprintk((KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
1914 ioc->name, ioc_srch->name));
1915 ioc_srch->alt_ioc = ioc;
1916 ioc->alt_ioc = ioc_srch;
1922 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1924 * mpt_adapter_disable - Disable misbehaving MPT adapter.
1925 * @this: Pointer to MPT adapter structure
1928 mpt_adapter_disable(MPT_ADAPTER *ioc)
1933 if (ioc->cached_fw != NULL) {
1934 ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
1935 if ((ret = mpt_downloadboot(ioc, NO_SLEEP)) < 0) {
1936 printk(KERN_WARNING MYNAM
1937 ": firmware downloadboot failure (%d)!\n", ret);
1941 /* Disable adapter interrupts! */
1942 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1944 /* Clear any lingering interrupt */
1945 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1947 if (ioc->alloc != NULL) {
1949 dexitprintk((KERN_INFO MYNAM ": %s.free @ %p, sz=%d bytes\n",
1950 ioc->name, ioc->alloc, ioc->alloc_sz));
1951 pci_free_consistent(ioc->pcidev, sz,
1952 ioc->alloc, ioc->alloc_dma);
1953 ioc->reply_frames = NULL;
1954 ioc->req_frames = NULL;
1956 ioc->alloc_total -= sz;
1959 if (ioc->sense_buf_pool != NULL) {
1960 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
1961 pci_free_consistent(ioc->pcidev, sz,
1962 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
1963 ioc->sense_buf_pool = NULL;
1964 ioc->alloc_total -= sz;
1967 if (ioc->events != NULL){
1968 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
1971 ioc->alloc_total -= sz;
1974 if (ioc->cached_fw != NULL) {
1975 sz = ioc->facts.FWImageSize;
1976 pci_free_consistent(ioc->pcidev, sz,
1977 ioc->cached_fw, ioc->cached_fw_dma);
1978 ioc->cached_fw = NULL;
1979 ioc->alloc_total -= sz;
1982 if (ioc->spi_data.nvram != NULL) {
1983 kfree(ioc->spi_data.nvram);
1984 ioc->spi_data.nvram = NULL;
1987 if (ioc->spi_data.pIocPg3 != NULL) {
1988 kfree(ioc->spi_data.pIocPg3);
1989 ioc->spi_data.pIocPg3 = NULL;
1992 if (ioc->spi_data.pIocPg4 != NULL) {
1993 sz = ioc->spi_data.IocPg4Sz;
1994 pci_free_consistent(ioc->pcidev, sz,
1995 ioc->spi_data.pIocPg4,
1996 ioc->spi_data.IocPg4_dma);
1997 ioc->spi_data.pIocPg4 = NULL;
1998 ioc->alloc_total -= sz;
2001 if (ioc->ReqToChain != NULL) {
2002 kfree(ioc->ReqToChain);
2003 kfree(ioc->RequestNB);
2004 ioc->ReqToChain = NULL;
2007 if (ioc->ChainToChain != NULL) {
2008 kfree(ioc->ChainToChain);
2009 ioc->ChainToChain = NULL;
2013 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2015 * mpt_adapter_dispose - Free all resources associated with a MPT
2017 * @ioc: Pointer to MPT adapter structure
2019 * This routine unregisters h/w resources and frees all alloc'd memory
2020 * associated with a MPT adapter structure.
2023 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2026 int sz_first, sz_last;
2028 sz_first = ioc->alloc_total;
2030 mpt_adapter_disable(ioc);
2032 if (ioc->pci_irq != -1) {
2033 free_irq(ioc->pci_irq, ioc);
2037 if (ioc->memmap != NULL)
2038 iounmap((u8 *) ioc->memmap);
2040 #if defined(CONFIG_MTRR) && 0
2041 if (ioc->mtrr_reg > 0) {
2042 mtrr_del(ioc->mtrr_reg, 0, 0);
2043 dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
2047 /* Zap the adapter lookup ptr! */
2048 list_del(&ioc->list);
2050 sz_last = ioc->alloc_total;
2051 dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
2052 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2057 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2059 * MptDisplayIocCapabilities - Disply IOC's capacilities.
2060 * @ioc: Pointer to MPT adapter structure
2063 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2067 printk(KERN_INFO "%s: ", ioc->name);
2068 if (ioc->prod_name && strlen(ioc->prod_name) > 3)
2069 printk("%s: ", ioc->prod_name+3);
2070 printk("Capabilities={");
2072 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2073 printk("Initiator");
2077 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2078 printk("%sTarget", i ? "," : "");
2082 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2083 printk("%sLAN", i ? "," : "");
2089 * This would probably evoke more questions than it's worth
2091 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2092 printk("%sLogBusAddr", i ? "," : "");
2100 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2102 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2103 * @ioc: Pointer to MPT_ADAPTER structure
2104 * @force: Force hard KickStart of IOC
2105 * @sleepFlag: Specifies whether the process can sleep
2108 * 1 - DIAG reset and READY
2109 * 0 - READY initially OR soft reset and READY
2110 * -1 - Any failure on KickStart
2111 * -2 - Msg Unit Reset Failed
2112 * -3 - IO Unit Reset Failed
2113 * -4 - IOC owned by a PEER
2116 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2121 int hard_reset_done = 0;
2126 /* Get current [raw] IOC state */
2127 ioc_state = mpt_GetIocState(ioc, 0);
2128 dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
2131 * Check to see if IOC got left/stuck in doorbell handshake
2132 * grip of death. If so, hard reset the IOC.
2134 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2136 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2140 /* Is it already READY? */
2141 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY) {
2142 if ((int)ioc->chip_type <= (int)FC929)
2146 /* Workaround from broken 1030 FW.
2147 * Force a diagnostic reset if fails.
2149 /* if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2157 * Check to see if IOC is in FAULT state.
2159 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2161 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2163 printk(KERN_WARNING " FAULT code = %04xh\n",
2164 ioc_state & MPI_DOORBELL_DATA_MASK);
2168 * Hmmm... Did it get left operational?
2170 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2171 dinitprintk((MYIOC_s_WARN_FMT "IOC operational unexpected\n",
2175 * If PCI Peer, exit.
2176 * Else, if no fault conditions are present, issue a MessageUnitReset
2177 * Else, fall through to KickStart case
2179 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2180 dprintk((KERN_WARNING MYNAM
2181 ": whoinit 0x%x\n statefault %d force %d\n",
2182 whoinit, statefault, force));
2183 if (whoinit == MPI_WHOINIT_PCI_PEER)
2186 if ((statefault == 0 ) && (force == 0)) {
2187 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2194 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2195 if (hard_reset_done < 0)
2199 * Loop here waiting for IOC to come READY.
2202 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
2204 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2205 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2207 * BIOS or previous driver load left IOC in OP state.
2208 * Reset messaging FIFOs.
2210 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2211 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2214 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2216 * Something is wrong. Try to get IOC back
2219 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2220 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2227 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2228 ioc->name, (int)((ii+5)/HZ));
2232 if (sleepFlag == CAN_SLEEP) {
2233 set_current_state(TASK_INTERRUPTIBLE);
2234 schedule_timeout(1 * HZ / 1000);
2236 mdelay (1); /* 1 msec delay */
2241 if (statefault < 3) {
2242 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2244 statefault==1 ? "stuck handshake" : "IOC FAULT");
2247 return hard_reset_done;
2250 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2252 * mpt_GetIocState - Get the current state of a MPT adapter.
2253 * @ioc: Pointer to MPT_ADAPTER structure
2254 * @cooked: Request raw or cooked IOC state
2256 * Returns all IOC Doorbell register bits if cooked==0, else just the
2257 * Doorbell bits in MPI_IOC_STATE_MASK.
2260 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2265 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2266 // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2267 sc = s & MPI_IOC_STATE_MASK;
2270 ioc->last_state = sc;
2272 return cooked ? sc : s;
2275 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2277 * GetIocFacts - Send IOCFacts request to MPT adapter.
2278 * @ioc: Pointer to MPT_ADAPTER structure
2279 * @sleepFlag: Specifies whether the process can sleep
2280 * @reason: If recovery, only update facts.
2282 * Returns 0 for success, non-zero for failure.
2285 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2287 IOCFacts_t get_facts;
2288 IOCFactsReply_t *facts;
2296 /* IOC *must* NOT be in RESET state! */
2297 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2298 printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2304 facts = &ioc->facts;
2306 /* Destination (reply area)... */
2307 reply_sz = sizeof(*facts);
2308 memset(facts, 0, reply_sz);
2310 /* Request area (get_facts on the stack right now!) */
2311 req_sz = sizeof(get_facts);
2312 memset(&get_facts, 0, req_sz);
2314 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2315 /* Assert: All other get_facts fields are zero! */
2317 dinitprintk((MYIOC_s_INFO_FMT
2318 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2319 ioc->name, req_sz, reply_sz));
2321 /* No non-zero fields in the get_facts request are greater than
2322 * 1 byte in size, so we can just fire it off as is.
2324 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2325 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2330 * Now byte swap (GRRR) the necessary fields before any further
2331 * inspection of reply contents.
2333 * But need to do some sanity checks on MsgLength (byte) field
2334 * to make sure we don't zero IOC's req_sz!
2336 /* Did we get a valid reply? */
2337 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2338 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2340 * If not been here, done that, save off first WhoInit value
2342 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2343 ioc->FirstWhoInit = facts->WhoInit;
2346 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2347 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2348 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2349 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2350 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2351 status = facts->IOCStatus & MPI_IOCSTATUS_MASK;
2352 /* CHECKME! IOCStatus, IOCLogInfo */
2354 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2355 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2358 * FC f/w version changed between 1.1 and 1.2
2359 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2360 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2362 if (facts->MsgVersion < 0x0102) {
2364 * Handle old FC f/w style, convert to new...
2366 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2367 facts->FWVersion.Word =
2368 ((oldv<<12) & 0xFF000000) |
2369 ((oldv<<8) & 0x000FFF00);
2371 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2373 facts->ProductID = le16_to_cpu(facts->ProductID);
2374 facts->CurrentHostMfaHighAddr =
2375 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2376 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2377 facts->CurrentSenseBufferHighAddr =
2378 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2379 facts->CurReplyFrameSize =
2380 le16_to_cpu(facts->CurReplyFrameSize);
2383 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2384 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2385 * to 14 in MPI-1.01.0x.
2387 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2388 facts->MsgVersion > 0x0100) {
2389 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2392 sz = facts->FWImageSize;
2397 facts->FWImageSize = sz;
2399 if (!facts->RequestFrameSize) {
2400 /* Something is wrong! */
2401 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2406 r = sz = le32_to_cpu(facts->BlockSize);
2407 vv = ((63 / (sz * 4)) + 1) & 0x03;
2408 ioc->NB_for_64_byte_frame = vv;
2414 ioc->NBShiftFactor = shiftFactor;
2415 dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2416 ioc->name, vv, shiftFactor, r));
2418 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2420 * Set values for this IOC's request & reply frame sizes,
2421 * and request & reply queue depths...
2423 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2424 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2425 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2426 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2428 dinitprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
2429 ioc->name, ioc->reply_sz, ioc->reply_depth));
2430 dinitprintk((MYIOC_s_INFO_FMT "req_sz =%3d, req_depth =%4d\n",
2431 ioc->name, ioc->req_sz, ioc->req_depth));
2433 /* Get port facts! */
2434 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2438 printk(MYIOC_s_ERR_FMT
2439 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2440 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2441 RequestFrameSize)/sizeof(u32)));
2448 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2450 * GetPortFacts - Send PortFacts request to MPT adapter.
2451 * @ioc: Pointer to MPT_ADAPTER structure
2452 * @portnum: Port number
2453 * @sleepFlag: Specifies whether the process can sleep
2455 * Returns 0 for success, non-zero for failure.
2458 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2460 PortFacts_t get_pfacts;
2461 PortFactsReply_t *pfacts;
2466 /* IOC *must* NOT be in RESET state! */
2467 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2468 printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2474 pfacts = &ioc->pfacts[portnum];
2476 /* Destination (reply area)... */
2477 reply_sz = sizeof(*pfacts);
2478 memset(pfacts, 0, reply_sz);
2480 /* Request area (get_pfacts on the stack right now!) */
2481 req_sz = sizeof(get_pfacts);
2482 memset(&get_pfacts, 0, req_sz);
2484 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2485 get_pfacts.PortNumber = portnum;
2486 /* Assert: All other get_pfacts fields are zero! */
2488 dinitprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
2489 ioc->name, portnum));
2491 /* No non-zero fields in the get_pfacts request are greater than
2492 * 1 byte in size, so we can just fire it off as is.
2494 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2495 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2499 /* Did we get a valid reply? */
2501 /* Now byte swap the necessary fields in the response. */
2502 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2503 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2504 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2505 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2506 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2507 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2508 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2509 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2510 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2515 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2517 * SendIocInit - Send IOCInit request to MPT adapter.
2518 * @ioc: Pointer to MPT_ADAPTER structure
2519 * @sleepFlag: Specifies whether the process can sleep
2521 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2523 * Returns 0 for success, non-zero for failure.
2526 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2529 MPIDefaultReply_t init_reply;
2535 memset(&ioc_init, 0, sizeof(ioc_init));
2536 memset(&init_reply, 0, sizeof(init_reply));
2538 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2539 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2541 /* If we are in a recovery mode and we uploaded the FW image,
2542 * then this pointer is not NULL. Skip the upload a second time.
2543 * Set this flag if cached_fw set for either IOC.
2545 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2549 ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
2550 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2552 if ((int)ioc->chip_type <= (int)FC929) {
2553 ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
2555 ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
2557 ioc_init.MaxBuses = MPT_MAX_BUS;
2559 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2561 if (sizeof(dma_addr_t) == sizeof(u64)) {
2562 /* Save the upper 32-bits of the request
2563 * (reply) and sense buffers.
2565 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2566 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2568 /* Force 32-bit addressing */
2569 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2570 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2573 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2574 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2576 dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
2577 ioc->name, &ioc_init));
2579 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2580 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2584 /* No need to byte swap the multibyte fields in the reply
2585 * since we don't even look at it's contents.
2588 dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
2589 ioc->name, &ioc_init));
2591 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0)
2594 /* YIKES! SUPER IMPORTANT!!!
2595 * Poll IocState until _OPERATIONAL while IOC is doing
2596 * LoopInit and TargetDiscovery!
2599 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2600 state = mpt_GetIocState(ioc, 1);
2601 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2602 if (sleepFlag == CAN_SLEEP) {
2603 set_current_state(TASK_INTERRUPTIBLE);
2604 schedule_timeout(1 * HZ / 1000);
2610 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2611 ioc->name, (int)((count+5)/HZ));
2615 state = mpt_GetIocState(ioc, 1);
2618 dhsprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2624 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2626 * SendPortEnable - Send PortEnable request to MPT adapter port.
2627 * @ioc: Pointer to MPT_ADAPTER structure
2628 * @portnum: Port number to enable
2629 * @sleepFlag: Specifies whether the process can sleep
2631 * Send PortEnable to bring IOC to OPERATIONAL state.
2633 * Returns 0 for success, non-zero for failure.
2636 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2638 PortEnable_t port_enable;
2639 MPIDefaultReply_t reply_buf;
2644 /* Destination... */
2645 reply_sz = sizeof(MPIDefaultReply_t);
2646 memset(&reply_buf, 0, reply_sz);
2648 req_sz = sizeof(PortEnable_t);
2649 memset(&port_enable, 0, req_sz);
2651 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2652 port_enable.PortNumber = portnum;
2653 /* port_enable.ChainOffset = 0; */
2654 /* port_enable.MsgFlags = 0; */
2655 /* port_enable.MsgContext = 0; */
2657 dinitprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
2658 ioc->name, portnum, &port_enable));
2660 /* RAID FW may take a long time to enable
2662 if ((int)ioc->chip_type <= (int)FC929) {
2663 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2664 reply_sz, (u16*)&reply_buf, 65 /*seconds*/, sleepFlag);
2666 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2667 reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag);
2673 /* We do not even look at the reply, so we need not
2674 * swap the multi-byte fields.
2681 * ioc: Pointer to MPT_ADAPTER structure
2682 * size - total FW bytes
2685 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
2688 return; /* use already allocated memory */
2689 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2690 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
2691 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
2693 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
2694 ioc->alloc_total += size;
2698 * If alt_img is NULL, delete from ioc structure.
2699 * Else, delete a secondary image in same format.
2702 mpt_free_fw_memory(MPT_ADAPTER *ioc)
2706 sz = ioc->facts.FWImageSize;
2707 dinitprintk((KERN_WARNING MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
2708 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2709 pci_free_consistent(ioc->pcidev, sz,
2710 ioc->cached_fw, ioc->cached_fw_dma);
2711 ioc->cached_fw = NULL;
2717 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2719 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
2720 * @ioc: Pointer to MPT_ADAPTER structure
2721 * @sleepFlag: Specifies whether the process can sleep
2723 * Returns 0 for success, >0 for handshake failure
2724 * <0 for fw upload failure.
2726 * Remark: If bound IOC and a successful FWUpload was performed
2727 * on the bound IOC, the second image is discarded
2728 * and memory is free'd. Both channels must upload to prevent
2729 * IOC from running in degraded mode.
2732 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2734 u8 request[ioc->req_sz];
2735 u8 reply[sizeof(FWUploadReply_t)];
2736 FWUpload_t *prequest;
2737 FWUploadReply_t *preply;
2738 FWUploadTCSGE_t *ptcsge;
2741 int ii, sz, reply_sz;
2744 /* If the image size is 0, we are done.
2746 if ((sz = ioc->facts.FWImageSize) == 0)
2749 mpt_alloc_fw_memory(ioc, sz);
2751 dinitprintk((KERN_WARNING MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
2752 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2754 if (ioc->cached_fw == NULL) {
2760 prequest = (FWUpload_t *)&request;
2761 preply = (FWUploadReply_t *)&reply;
2763 /* Destination... */
2764 memset(prequest, 0, ioc->req_sz);
2766 reply_sz = sizeof(reply);
2767 memset(preply, 0, reply_sz);
2769 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
2770 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
2772 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
2773 ptcsge->DetailsLength = 12;
2774 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
2775 ptcsge->ImageSize = cpu_to_le32(sz);
2777 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
2779 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
2780 mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
2782 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
2783 dinitprintk((KERN_WARNING MYNAM "Sending FW Upload (req @ %p) sgeoffset=%d \n",
2784 prequest, sgeoffset));
2785 DBG_DUMP_FW_REQUEST_FRAME(prequest)
2787 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
2788 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
2790 dinitprintk((KERN_WARNING MYNAM "FW Upload completed rc=%x \n", ii));
2792 cmdStatus = -EFAULT;
2794 /* Handshake transfer was complete and successful.
2795 * Check the Reply Frame.
2797 int status, transfer_sz;
2798 status = le16_to_cpu(preply->IOCStatus);
2799 if (status == MPI_IOCSTATUS_SUCCESS) {
2800 transfer_sz = le32_to_cpu(preply->ActualImageSize);
2801 if (transfer_sz == sz)
2805 dinitprintk((MYIOC_s_INFO_FMT ": do_upload status %d \n",
2806 ioc->name, cmdStatus));
2811 ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
2813 mpt_free_fw_memory(ioc);
2819 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2821 * mpt_downloadboot - DownloadBoot code
2822 * @ioc: Pointer to MPT_ADAPTER structure
2823 * @flag: Specify which part of IOC memory is to be uploaded.
2824 * @sleepFlag: Specifies whether the process can sleep
2826 * FwDownloadBoot requires Programmed IO access.
2828 * Returns 0 for success
2829 * -1 FW Image size is 0
2830 * -2 No valid cached_fw Pointer
2831 * <0 for fw upload failure.
2834 mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
2836 MpiFwHeader_t *pFwHeader;
2837 MpiExtImageHeader_t *pExtImage;
2847 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x, ioc FW Ptr %p\n",
2848 ioc->name, ioc->facts.FWImageSize, ioc->cached_fw));
2850 if ( ioc->facts.FWImageSize == 0 )
2853 if (ioc->cached_fw == NULL)
2856 /* prevent a second downloadboot and memory free with alt_ioc */
2857 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
2858 ioc->alt_ioc->cached_fw = NULL;
2860 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2861 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2862 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2863 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2864 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2865 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2867 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
2870 if (sleepFlag == CAN_SLEEP) {
2871 set_current_state(TASK_INTERRUPTIBLE);
2872 schedule_timeout(1 * HZ / 1000);
2877 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2878 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2880 for (count = 0; count < 30; count ++) {
2881 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2882 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
2883 ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
2888 if (sleepFlag == CAN_SLEEP) {
2889 set_current_state(TASK_INTERRUPTIBLE);
2890 schedule_timeout(1000 * HZ / 1000);
2896 if ( count == 30 ) {
2897 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! Unable to RESET_ADAPTER diag0val=%x\n",
2898 ioc->name, diag0val));
2902 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2903 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2904 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2905 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2906 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2907 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2909 /* Set the DiagRwEn and Disable ARM bits */
2910 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
2912 pFwHeader = (MpiFwHeader_t *) ioc->cached_fw;
2913 fwSize = (pFwHeader->ImageSize + 3)/4;
2914 ptrFw = (u32 *) pFwHeader;
2916 /* Write the LoadStartAddress to the DiagRw Address Register
2917 * using Programmed IO
2919 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
2920 ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
2921 ioc->name, pFwHeader->LoadStartAddress));
2923 ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n",
2924 ioc->name, fwSize*4, ptrFw));
2926 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2929 nextImage = pFwHeader->NextImageHeaderOffset;
2931 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
2933 load_addr = pExtImage->LoadStartAddress;
2935 fwSize = (pExtImage->ImageSize + 3) >> 2;
2936 ptrFw = (u32 *)pExtImage;
2938 ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x bytes @ %p load_addr=%x\n",
2939 ioc->name, fwSize*4, ptrFw, load_addr));
2940 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
2943 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2945 nextImage = pExtImage->NextImageHeaderOffset;
2948 /* Write the IopResetVectorRegAddr */
2949 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
2950 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
2952 /* Write the IopResetVectorValue */
2953 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
2954 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
2956 /* Clear the internal flash bad bit - autoincrementing register,
2957 * so must do two writes.
2959 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
2960 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
2961 diagRwData |= 0x4000000;
2962 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
2963 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
2965 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2966 ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, turning off PREVENT_IOC_BOOT, DISABLE_ARM\n",
2967 ioc->name, diag0val));
2968 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM);
2969 ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
2970 ioc->name, diag0val));
2971 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
2973 /* Write 0xFF to reset the sequencer */
2974 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2976 for (count=0; count<HZ*20; count++) {
2977 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
2978 ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
2979 ioc->name, count, ioc_state));
2980 if ((SendIocInit(ioc, sleepFlag)) != 0) {
2981 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
2985 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit successful\n",
2989 if (sleepFlag == CAN_SLEEP) {
2990 set_current_state(TASK_INTERRUPTIBLE);
2991 schedule_timeout(10 * HZ / 1000);
2996 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! IocState=%x\n",
2997 ioc->name, ioc_state));
3001 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3003 * KickStart - Perform hard reset of MPT adapter.
3004 * @ioc: Pointer to MPT_ADAPTER structure
3005 * @force: Force hard reset
3006 * @sleepFlag: Specifies whether the process can sleep
3008 * This routine places MPT adapter in diagnostic mode via the
3009 * WriteSequence register, and then performs a hard reset of adapter
3010 * via the Diagnostic register.
3012 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3013 * or NO_SLEEP (interrupt thread, use mdelay)
3014 * force - 1 if doorbell active, board fault state
3015 * board operational, IOC_RECOVERY or
3016 * IOC_BRINGUP and there is an alt_ioc.
3020 * 1 - hard reset, READY
3021 * 0 - no reset due to History bit, READY
3022 * -1 - no reset due to History bit but not READY
3023 * OR reset but failed to come READY
3024 * -2 - no reset, could not enter DIAG mode
3025 * -3 - reset but bad FW bit
3028 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3030 int hard_reset_done = 0;
3034 dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
3035 if ((int)ioc->chip_type > (int)FC929) {
3036 /* Always issue a Msg Unit Reset first. This will clear some
3037 * SCSI bus hang conditions.
3039 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3041 if (sleepFlag == CAN_SLEEP) {
3042 set_current_state(TASK_INTERRUPTIBLE);
3043 schedule_timeout(1000 * HZ / 1000);
3049 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3050 if (hard_reset_done < 0)
3051 return hard_reset_done;
3053 dinitprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
3056 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3057 for (cnt=0; cnt<cntdn; cnt++) {
3058 ioc_state = mpt_GetIocState(ioc, 1);
3059 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3060 dinitprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
3062 return hard_reset_done;
3064 if (sleepFlag == CAN_SLEEP) {
3065 set_current_state(TASK_INTERRUPTIBLE);
3066 schedule_timeout(10 * HZ / 1000);
3072 printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3073 ioc->name, ioc_state);
3077 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3079 * mpt_diag_reset - Perform hard reset of the adapter.
3080 * @ioc: Pointer to MPT_ADAPTER structure
3081 * @ignore: Set if to honor and clear to ignore
3082 * the reset history bit
3083 * @sleepflag: CAN_SLEEP if called in a non-interrupt thread,
3084 * else set to NO_SLEEP (use mdelay instead)
3086 * This routine places the adapter in diagnostic mode via the
3087 * WriteSequence register and then performs a hard reset of adapter
3088 * via the Diagnostic register. Adapter should be in ready state
3089 * upon successful completion.
3091 * Returns: 1 hard reset successful
3092 * 0 no reset performed because reset history bit set
3093 * -2 enabling diagnostic mode failed
3094 * -3 diagnostic reset failed
3097 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3101 int hard_reset_done = 0;
3107 /* Clear any existing interrupts */
3108 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3110 /* Use "Diagnostic reset" method! (only thing available!) */
3111 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3115 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3116 dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3117 ioc->name, diag0val, diag1val));
3120 /* Do the reset if we are told to ignore the reset history
3121 * or if the reset history is 0
3123 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3124 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3125 /* Write magic sequence to WriteSequence register
3126 * Loop until in diagnostic mode
3128 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3129 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3130 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3131 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3132 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3133 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3136 if (sleepFlag == CAN_SLEEP) {
3137 set_current_state(TASK_INTERRUPTIBLE);
3138 schedule_timeout(100 * HZ / 1000);
3145 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3146 ioc->name, diag0val);
3151 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3153 dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3154 ioc->name, diag0val));
3159 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3160 dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3161 ioc->name, diag0val, diag1val));
3164 * Disable the ARM (Bug fix)
3167 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3171 * Now hit the reset bit in the Diagnostic register
3172 * (THE BIG HAMMER!) (Clears DRWE bit).
3174 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3175 hard_reset_done = 1;
3176 dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
3180 * Call each currently registered protocol IOC reset handler
3181 * with pre-reset indication.
3182 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3183 * MptResetHandlers[] registered yet.
3189 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
3190 if (MptResetHandlers[ii]) {
3191 dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
3193 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_PRE_RESET);
3195 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3196 ioc->name, ioc->alt_ioc->name, ii));
3197 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_PRE_RESET);
3201 /* FIXME? Examine results here? */
3204 if (ioc->cached_fw) {
3205 /* If the DownloadBoot operation fails, the
3206 * IOC will be left unusable. This is a fatal error
3207 * case. _diag_reset will return < 0
3209 for (count = 0; count < 30; count ++) {
3210 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3211 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3216 if (sleepFlag == CAN_SLEEP) {
3217 set_current_state(TASK_INTERRUPTIBLE);
3218 schedule_timeout(1000 * HZ / 1000);
3223 if ((count = mpt_downloadboot(ioc, sleepFlag)) < 0) {
3224 printk(KERN_WARNING MYNAM
3225 ": firmware downloadboot failure (%d)!\n", count);
3229 /* Wait for FW to reload and for board
3230 * to go to the READY state.
3231 * Maximum wait is 60 seconds.
3232 * If fail, no error will check again
3233 * with calling program.
3235 for (count = 0; count < 60; count ++) {
3236 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3237 doorbell &= MPI_IOC_STATE_MASK;
3239 if (doorbell == MPI_IOC_STATE_READY) {
3244 if (sleepFlag == CAN_SLEEP) {
3245 set_current_state(TASK_INTERRUPTIBLE);
3246 schedule_timeout(1000 * HZ / 1000);
3254 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3257 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3258 dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3259 ioc->name, diag0val, diag1val));
3262 /* Clear RESET_HISTORY bit! Place board in the
3263 * diagnostic mode to update the diag register.
3265 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3267 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3268 /* Write magic sequence to WriteSequence register
3269 * Loop until in diagnostic mode
3271 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3272 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3273 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3274 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3275 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3276 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3279 if (sleepFlag == CAN_SLEEP) {
3280 set_current_state(TASK_INTERRUPTIBLE);
3281 schedule_timeout(100 * HZ / 1000);
3288 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3289 ioc->name, diag0val);
3292 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3294 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3295 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3296 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3297 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3298 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3302 /* Disable Diagnostic Mode
3304 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3306 /* Check FW reload status flags.
3308 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3309 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3310 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3311 ioc->name, diag0val);
3317 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3318 dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3319 ioc->name, diag0val, diag1val));
3323 * Reset flag that says we've enabled event notification
3325 ioc->facts.EventState = 0;
3328 ioc->alt_ioc->facts.EventState = 0;
3330 return hard_reset_done;
3333 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3335 * SendIocReset - Send IOCReset request to MPT adapter.
3336 * @ioc: Pointer to MPT_ADAPTER structure
3337 * @reset_type: reset type, expected values are
3338 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3340 * Send IOCReset request to the MPT adapter.
3342 * Returns 0 for success, non-zero for failure.
3345 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3351 drsprintk((KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
3352 ioc->name, reset_type));
3353 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3354 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3357 /* FW ACK'd request, wait for READY state
3360 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3362 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3366 if (sleepFlag != CAN_SLEEP)
3369 printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3370 ioc->name, (int)((count+5)/HZ));
3374 if (sleepFlag == CAN_SLEEP) {
3375 set_current_state(TASK_INTERRUPTIBLE);
3376 schedule_timeout(1 * HZ / 1000);
3378 mdelay (1); /* 1 msec delay */
3383 * Cleanup all event stuff for this IOC; re-issue EventNotification
3384 * request if needed.
3386 if (ioc->facts.Function)
3387 ioc->facts.EventState = 0;
3392 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3394 * initChainBuffers - Allocate memory for and initialize
3395 * chain buffers, chain buffer control arrays and spinlock.
3396 * @hd: Pointer to MPT_SCSI_HOST structure
3397 * @init: If set, initialize the spin lock.
3400 initChainBuffers(MPT_ADAPTER *ioc)
3403 int sz, ii, num_chain;
3404 int scale, num_sge, numSGE;
3406 /* ReqToChain size must equal the req_depth
3409 if (ioc->ReqToChain == NULL) {
3410 sz = ioc->req_depth * sizeof(int);
3411 mem = kmalloc(sz, GFP_ATOMIC);
3415 ioc->ReqToChain = (int *) mem;
3416 dinitprintk((KERN_INFO MYNAM ": %s ReqToChain alloc @ %p, sz=%d bytes\n",
3417 ioc->name, mem, sz));
3418 mem = kmalloc(sz, GFP_ATOMIC);
3422 ioc->RequestNB = (int *) mem;
3423 dinitprintk((KERN_INFO MYNAM ": %s RequestNB alloc @ %p, sz=%d bytes\n",
3424 ioc->name, mem, sz));
3426 for (ii = 0; ii < ioc->req_depth; ii++) {
3427 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3430 /* ChainToChain size must equal the total number
3431 * of chain buffers to be allocated.
3434 * Calculate the number of chain buffers needed(plus 1) per I/O
3435 * then multiply the the maximum number of simultaneous cmds
3437 * num_sge = num sge in request frame + last chain buffer
3438 * scale = num sge per chain buffer if no chain element
3440 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3441 if (sizeof(dma_addr_t) == sizeof(u64))
3442 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3444 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3446 if (sizeof(dma_addr_t) == sizeof(u64)) {
3447 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3448 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3450 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3451 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3453 dinitprintk((KERN_INFO MYNAM ": %s num_sge=%d numSGE=%d\n",
3454 ioc->name, num_sge, numSGE));
3456 if ( numSGE > MPT_SCSI_SG_DEPTH )
3457 numSGE = MPT_SCSI_SG_DEPTH;
3460 while (numSGE - num_sge > 0) {
3462 num_sge += (scale - 1);
3466 dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
3467 ioc->name, numSGE, num_sge, num_chain));
3469 if ((int) ioc->chip_type > (int) FC929)
3470 num_chain *= MPT_SCSI_CAN_QUEUE;
3472 num_chain *= MPT_FC_CAN_QUEUE;
3474 ioc->num_chain = num_chain;
3476 sz = num_chain * sizeof(int);
3477 if (ioc->ChainToChain == NULL) {
3478 mem = kmalloc(sz, GFP_ATOMIC);
3482 ioc->ChainToChain = (int *) mem;
3483 dinitprintk((KERN_INFO MYNAM ": %s ChainToChain alloc @ %p, sz=%d bytes\n",
3484 ioc->name, mem, sz));
3486 mem = (u8 *) ioc->ChainToChain;
3488 memset(mem, 0xFF, sz);
3492 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3494 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3495 * @ioc: Pointer to MPT_ADAPTER structure
3497 * This routine allocates memory for the MPT reply and request frame
3498 * pools (if necessary), and primes the IOC reply FIFO with
3501 * Returns 0 for success, non-zero for failure.
3504 PrimeIocFifos(MPT_ADAPTER *ioc)
3507 unsigned long flags;
3508 dma_addr_t alloc_dma;
3510 int i, reply_sz, sz, total_size, num_chain;
3512 /* Prime reply FIFO... */
3514 if (ioc->reply_frames == NULL) {
3515 if ( (num_chain = initChainBuffers(ioc)) < 0)
3518 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3519 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3520 ioc->name, ioc->reply_sz, ioc->reply_depth));
3521 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d[%x] bytes\n",
3522 ioc->name, reply_sz, reply_sz));
3524 sz = (ioc->req_sz * ioc->req_depth);
3525 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3526 ioc->name, ioc->req_sz, ioc->req_depth));
3527 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d[%x] bytes\n",
3528 ioc->name, sz, sz));
3531 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3532 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3533 ioc->name, ioc->req_sz, num_chain));
3534 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3535 ioc->name, sz, sz, num_chain));
3538 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3540 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3545 dinitprintk((KERN_INFO MYNAM ": %s.Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3546 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3548 memset(mem, 0, total_size);
3549 ioc->alloc_total += total_size;
3551 ioc->alloc_dma = alloc_dma;
3552 ioc->alloc_sz = total_size;
3553 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3554 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3556 alloc_dma += reply_sz;
3559 /* Request FIFO - WE manage this! */
3561 ioc->req_frames = (MPT_FRAME_HDR *) mem;
3562 ioc->req_frames_dma = alloc_dma;
3564 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffers @ %p[%p]\n",
3565 ioc->name, mem, (void *)(ulong)alloc_dma));
3567 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3569 #if defined(CONFIG_MTRR) && 0
3571 * Enable Write Combining MTRR for IOC's memory region.
3572 * (at least as much as we can; "size and base must be
3573 * multiples of 4 kiB"
3575 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
3577 MTRR_TYPE_WRCOMB, 1);
3578 dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
3579 ioc->name, ioc->req_frames_dma, sz));
3582 for (i = 0; i < ioc->req_depth; i++) {
3583 alloc_dma += ioc->req_sz;
3587 ioc->ChainBuffer = mem;
3588 ioc->ChainBufferDMA = alloc_dma;
3590 dinitprintk((KERN_INFO MYNAM " :%s.ChainBuffers @ %p(%p)\n",
3591 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
3593 /* Initialize the free chain Q.
3596 Q_INIT(&ioc->FreeChainQ, MPT_FRAME_HDR);
3598 /* Post the chain buffers to the FreeChainQ.
3600 mem = (u8 *)ioc->ChainBuffer;
3601 for (i=0; i < num_chain; i++) {
3602 mf = (MPT_FRAME_HDR *) mem;
3603 Q_ADD_TAIL(&ioc->FreeChainQ.head, &mf->u.frame.linkage, MPT_FRAME_HDR);
3607 /* Initialize Request frames linked list
3609 alloc_dma = ioc->req_frames_dma;
3610 mem = (u8 *) ioc->req_frames;
3612 spin_lock_irqsave(&ioc->FreeQlock, flags);
3613 Q_INIT(&ioc->FreeQ, MPT_FRAME_HDR);
3614 for (i = 0; i < ioc->req_depth; i++) {
3615 mf = (MPT_FRAME_HDR *) mem;
3617 /* Queue REQUESTs *internally*! */
3618 Q_ADD_TAIL(&ioc->FreeQ.head, &mf->u.frame.linkage, MPT_FRAME_HDR);
3621 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3623 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3624 ioc->sense_buf_pool =
3625 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3626 if (ioc->sense_buf_pool == NULL) {
3627 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
3632 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
3633 ioc->alloc_total += sz;
3634 dinitprintk((KERN_INFO MYNAM ": %s.SenseBuffers @ %p[%p]\n",
3635 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
3639 /* Post Reply frames to FIFO
3641 alloc_dma = ioc->alloc_dma;
3642 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffers @ %p[%p]\n",
3643 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3645 for (i = 0; i < ioc->reply_depth; i++) {
3646 /* Write each address to the IOC! */
3647 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
3648 alloc_dma += ioc->reply_sz;
3654 if (ioc->alloc != NULL) {
3656 pci_free_consistent(ioc->pcidev,
3658 ioc->alloc, ioc->alloc_dma);
3659 ioc->reply_frames = NULL;
3660 ioc->req_frames = NULL;
3661 ioc->alloc_total -= sz;
3663 if (ioc->sense_buf_pool != NULL) {
3664 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3665 pci_free_consistent(ioc->pcidev,
3667 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
3668 ioc->sense_buf_pool = NULL;
3673 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3675 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3676 * from IOC via doorbell handshake method.
3677 * @ioc: Pointer to MPT_ADAPTER structure
3678 * @reqBytes: Size of the request in bytes
3679 * @req: Pointer to MPT request frame
3680 * @replyBytes: Expected size of the reply in bytes
3681 * @u16reply: Pointer to area where reply should be written
3682 * @maxwait: Max wait time for a reply (in seconds)
3683 * @sleepFlag: Specifies whether the process can sleep
3685 * NOTES: It is the callers responsibility to byte-swap fields in the
3686 * request which are greater than 1 byte in size. It is also the
3687 * callers responsibility to byte-swap response fields which are
3688 * greater than 1 byte in size.
3690 * Returns 0 for success, non-zero for failure.
3693 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
3694 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
3696 MPIDefaultReply_t *mptReply;
3701 * Get ready to cache a handshake reply
3703 ioc->hs_reply_idx = 0;
3704 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3705 mptReply->MsgLength = 0;
3708 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
3709 * then tell IOC that we want to handshake a request of N words.
3710 * (WRITE u32val to Doorbell reg).
3712 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3713 CHIPREG_WRITE32(&ioc->chip->Doorbell,
3714 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
3715 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
3718 * Wait for IOC's doorbell handshake int
3720 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3723 dhsprintk((MYIOC_s_INFO_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
3724 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3726 /* Read doorbell and check for active bit */
3727 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
3731 * Clear doorbell int (WRITE 0 to IntStatus reg),
3732 * then wait for IOC to ACKnowledge that it's ready for
3733 * our handshake request.
3735 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3736 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3741 u8 *req_as_bytes = (u8 *) req;
3744 * Stuff request words via doorbell handshake,
3745 * with ACK from IOC for each.
3747 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
3748 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
3749 (req_as_bytes[(ii*4) + 1] << 8) |
3750 (req_as_bytes[(ii*4) + 2] << 16) |
3751 (req_as_bytes[(ii*4) + 3] << 24));
3753 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
3754 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3758 dhsprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
3759 DBG_DUMP_REQUEST_FRAME_HDR(req)
3761 dhsprintk((MYIOC_s_INFO_FMT "HandShake request post done, WaitCnt=%d%s\n",
3762 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
3765 * Wait for completion of doorbell handshake reply from the IOC
3767 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
3770 dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n",
3771 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
3774 * Copy out the cached reply...
3776 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
3777 u16reply[ii] = ioc->hs_reply[ii];
3785 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3787 * WaitForDoorbellAck - Wait for IOC to clear the IOP_DOORBELL_STATUS bit
3788 * in it's IntStatus register.
3789 * @ioc: Pointer to MPT_ADAPTER structure
3790 * @howlong: How long to wait (in seconds)
3791 * @sleepFlag: Specifies whether the process can sleep
3793 * This routine waits (up to ~2 seconds max) for IOC doorbell
3794 * handshake ACKnowledge.
3796 * Returns a negative value on failure, else wait loop count.
3799 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3805 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
3807 if (sleepFlag == CAN_SLEEP) {
3809 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3810 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3812 set_current_state(TASK_INTERRUPTIBLE);
3813 schedule_timeout(1 * HZ / 1000);
3818 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3819 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3827 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (count=%d)\n",
3832 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
3833 ioc->name, count, intstat);
3837 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3839 * WaitForDoorbellInt - Wait for IOC to set the HIS_DOORBELL_INTERRUPT bit
3840 * in it's IntStatus register.
3841 * @ioc: Pointer to MPT_ADAPTER structure
3842 * @howlong: How long to wait (in seconds)
3843 * @sleepFlag: Specifies whether the process can sleep
3845 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt.
3847 * Returns a negative value on failure, else wait loop count.
3850 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3856 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
3857 if (sleepFlag == CAN_SLEEP) {
3859 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3860 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3862 set_current_state(TASK_INTERRUPTIBLE);
3863 schedule_timeout(1 * HZ / 1000);
3868 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3869 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3877 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
3878 ioc->name, count, howlong));
3882 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
3883 ioc->name, count, intstat);
3887 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3889 * WaitForDoorbellReply - Wait for and capture a IOC handshake reply.
3890 * @ioc: Pointer to MPT_ADAPTER structure
3891 * @howlong: How long to wait (in seconds)
3892 * @sleepFlag: Specifies whether the process can sleep
3894 * This routine polls the IOC for a handshake reply, 16 bits at a time.
3895 * Reply is cached to IOC private area large enough to hold a maximum
3896 * of 128 bytes of reply data.
3898 * Returns a negative value on failure, else size of reply in WORDS.
3901 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3906 u16 *hs_reply = ioc->hs_reply;
3907 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3910 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
3913 * Get first two u16's so we can look at IOC's intended reply MsgLength
3916 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
3919 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3920 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3921 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3924 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3925 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3929 dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
3930 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
3931 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3934 * If no error (and IOC said MsgLength is > 0), piece together
3935 * reply 16 bits at a time.
3937 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
3938 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3940 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3941 /* don't overflow our IOC hs_reply[] buffer! */
3942 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
3943 hs_reply[u16cnt] = hword;
3944 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3947 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3949 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3952 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
3957 else if (u16cnt != (2 * mptReply->MsgLength)) {
3960 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
3965 dhsprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
3966 DBG_DUMP_REPLY_FRAME(mptReply)
3968 dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
3969 ioc->name, t, u16cnt/2));
3973 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3975 * GetLanConfigPages - Fetch LANConfig pages.
3976 * @ioc: Pointer to MPT_ADAPTER structure
3978 * Return: 0 for success
3979 * -ENOMEM if no memory available
3980 * -EPERM if not allowed due to ISR context
3981 * -EAGAIN if no msg frames currently available
3982 * -EFAULT for non-successful reply or no reply (timeout)
3985 GetLanConfigPages(MPT_ADAPTER *ioc)
3987 ConfigPageHeader_t hdr;
3989 LANPage0_t *ppage0_alloc;
3990 dma_addr_t page0_dma;
3991 LANPage1_t *ppage1_alloc;
3992 dma_addr_t page1_dma;
3997 /* Get LAN Page 0 header */
3998 hdr.PageVersion = 0;
4001 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4004 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4009 if ((rc = mpt_config(ioc, &cfg)) != 0)
4012 if (hdr.PageLength > 0) {
4013 data_sz = hdr.PageLength * 4;
4014 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4017 memset((u8 *)ppage0_alloc, 0, data_sz);
4018 cfg.physAddr = page0_dma;
4019 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4021 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4023 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4024 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4028 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4031 * Normalize endianness of structure data,
4032 * by byte-swapping all > 1 byte fields!
4041 /* Get LAN Page 1 header */
4042 hdr.PageVersion = 0;
4045 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4048 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4052 if ((rc = mpt_config(ioc, &cfg)) != 0)
4055 if (hdr.PageLength == 0)
4058 data_sz = hdr.PageLength * 4;
4060 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4062 memset((u8 *)ppage1_alloc, 0, data_sz);
4063 cfg.physAddr = page1_dma;
4064 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4066 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4068 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4069 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4072 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4075 * Normalize endianness of structure data,
4076 * by byte-swapping all > 1 byte fields!
4084 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4086 * GetFcPortPage0 - Fetch FCPort config Page0.
4087 * @ioc: Pointer to MPT_ADAPTER structure
4088 * @portnum: IOC Port number
4090 * Return: 0 for success
4091 * -ENOMEM if no memory available
4092 * -EPERM if not allowed due to ISR context
4093 * -EAGAIN if no msg frames currently available
4094 * -EFAULT for non-successful reply or no reply (timeout)
4097 GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
4099 ConfigPageHeader_t hdr;
4101 FCPortPage0_t *ppage0_alloc;
4102 FCPortPage0_t *pp0dest;
4103 dma_addr_t page0_dma;
4108 /* Get FCPort Page 0 header */
4109 hdr.PageVersion = 0;
4112 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
4115 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4117 cfg.pageAddr = portnum;
4120 if ((rc = mpt_config(ioc, &cfg)) != 0)
4123 if (hdr.PageLength == 0)
4126 data_sz = hdr.PageLength * 4;
4128 ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4130 memset((u8 *)ppage0_alloc, 0, data_sz);
4131 cfg.physAddr = page0_dma;
4132 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4134 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4136 pp0dest = &ioc->fc_port_page0[portnum];
4137 copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
4138 memcpy(pp0dest, ppage0_alloc, copy_sz);
4141 * Normalize endianness of structure data,
4142 * by byte-swapping all > 1 byte fields!
4144 pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
4145 pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
4146 pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
4147 pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
4148 pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
4149 pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
4150 pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
4151 pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
4152 pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
4153 pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
4154 pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
4155 pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
4156 pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
4157 pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
4158 pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
4159 pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
4163 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4169 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4171 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4172 * @ioc: Pointer to MPT_ADAPTER structure
4174 * Returns: 0 for success
4175 * -ENOMEM if no memory available
4176 * -EPERM if not allowed due to ISR context
4177 * -EAGAIN if no msg frames currently available
4178 * -EFAULT for non-successful reply or no reply (timeout)
4181 GetIoUnitPage2(MPT_ADAPTER *ioc)
4183 ConfigPageHeader_t hdr;
4185 IOUnitPage2_t *ppage_alloc;
4186 dma_addr_t page_dma;
4190 /* Get the page header */
4191 hdr.PageVersion = 0;
4194 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4197 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4202 if ((rc = mpt_config(ioc, &cfg)) != 0)
4205 if (hdr.PageLength == 0)
4208 /* Read the config page */
4209 data_sz = hdr.PageLength * 4;
4211 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4213 memset((u8 *)ppage_alloc, 0, data_sz);
4214 cfg.physAddr = page_dma;
4215 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4217 /* If Good, save data */
4218 if ((rc = mpt_config(ioc, &cfg)) == 0)
4219 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4221 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4227 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4228 /* mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4229 * @ioc: Pointer to a Adapter Strucutre
4230 * @portnum: IOC port number
4232 * Return: -EFAULT if read of config page header fails
4234 * If read of SCSI Port Page 0 fails,
4235 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4236 * Adapter settings: async, narrow
4238 * If read of SCSI Port Page 2 fails,
4239 * Adapter settings valid
4240 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4245 * CHECK - what type of locking mechanisms should be used????
4248 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4253 ConfigPageHeader_t header;
4259 if (!ioc->spi_data.nvram) {
4262 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4263 mem = kmalloc(sz, GFP_ATOMIC);
4267 ioc->spi_data.nvram = (int *) mem;
4269 dprintk((MYIOC_s_INFO_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4270 ioc->name, ioc->spi_data.nvram, sz));
4273 /* Invalidate NVRAM information
4275 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4276 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4279 /* Read SPP0 header, allocate memory, then read page.
4281 header.PageVersion = 0;
4282 header.PageLength = 0;
4283 header.PageNumber = 0;
4284 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4287 cfg.pageAddr = portnum;
4288 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4290 cfg.timeout = 0; /* use default */
4291 if (mpt_config(ioc, &cfg) != 0)
4294 if (header.PageLength > 0) {
4295 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4297 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4298 cfg.physAddr = buf_dma;
4299 if (mpt_config(ioc, &cfg) != 0) {
4300 ioc->spi_data.maxBusWidth = MPT_NARROW;
4301 ioc->spi_data.maxSyncOffset = 0;
4302 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4303 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4306 /* Save the Port Page 0 data
4308 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4309 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4310 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4312 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4313 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4314 dinitprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
4315 ioc->name, pPP0->Capabilities));
4317 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4318 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4320 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4321 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4322 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4324 ioc->spi_data.maxSyncOffset = 0;
4325 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4328 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4330 /* Update the minSyncFactor based on bus type.
4332 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4333 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4335 if (ioc->spi_data.minSyncFactor < MPT_ULTRA)
4336 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4340 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4345 /* SCSI Port Page 2 - Read the header then the page.
4347 header.PageVersion = 0;
4348 header.PageLength = 0;
4349 header.PageNumber = 2;
4350 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4353 cfg.pageAddr = portnum;
4354 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4356 if (mpt_config(ioc, &cfg) != 0)
4359 if (header.PageLength > 0) {
4360 /* Allocate memory and read SCSI Port Page 2
4362 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4364 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4365 cfg.physAddr = buf_dma;
4366 if (mpt_config(ioc, &cfg) != 0) {
4367 /* Nvram data is left with INVALID mark
4371 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4372 MpiDeviceInfo_t *pdevice = NULL;
4374 /* Save the Port Page 2 data
4375 * (reformat into a 32bit quantity)
4377 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4378 ioc->spi_data.PortFlags = data;
4379 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4380 pdevice = &pPP2->DeviceSettings[ii];
4381 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4382 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4383 ioc->spi_data.nvram[ii] = data;
4387 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4391 /* Update Adapter limits with those from NVRAM
4392 * Comment: Don't need to do this. Target performance
4393 * parameters will never exceed the adapters limits.
4399 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4400 /* mpt_readScsiDevicePageHeaders - save version and length of SDP1
4401 * @ioc: Pointer to a Adapter Strucutre
4402 * @portnum: IOC port number
4404 * Return: -EFAULT if read of config page header fails
4408 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4411 ConfigPageHeader_t header;
4413 /* Read the SCSI Device Page 1 header
4415 header.PageVersion = 0;
4416 header.PageLength = 0;
4417 header.PageNumber = 1;
4418 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4421 cfg.pageAddr = portnum;
4422 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4425 if (mpt_config(ioc, &cfg) != 0)
4428 ioc->spi_data.sdp1version = cfg.hdr->PageVersion;
4429 ioc->spi_data.sdp1length = cfg.hdr->PageLength;
4431 header.PageVersion = 0;
4432 header.PageLength = 0;
4433 header.PageNumber = 0;
4434 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4435 if (mpt_config(ioc, &cfg) != 0)
4438 ioc->spi_data.sdp0version = cfg.hdr->PageVersion;
4439 ioc->spi_data.sdp0length = cfg.hdr->PageLength;
4441 dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
4442 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
4444 dcprintk((MYIOC_s_INFO_FMT "Headers: 1: version %d length %d\n",
4445 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
4449 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4451 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4452 * @ioc: Pointer to a Adapter Strucutre
4453 * @portnum: IOC port number
4457 * -EFAULT if read of config page header fails or data pointer not NULL
4458 * -ENOMEM if pci_alloc failed
4461 mpt_findImVolumes(MPT_ADAPTER *ioc)
4465 ConfigPageIoc2RaidVol_t *pIocRv;
4466 dma_addr_t ioc2_dma;
4468 ConfigPageHeader_t header;
4475 /* Read IOCP2 header then the page.
4477 header.PageVersion = 0;
4478 header.PageLength = 0;
4479 header.PageNumber = 2;
4480 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4484 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4487 if (mpt_config(ioc, &cfg) != 0)
4490 if (header.PageLength == 0)
4493 iocpage2sz = header.PageLength * 4;
4494 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
4498 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4499 cfg.physAddr = ioc2_dma;
4500 if (mpt_config(ioc, &cfg) != 0)
4503 if ( (mem = (u8 *)ioc->spi_data.pIocPg2) == NULL ) {
4504 mem = kmalloc(iocpage2sz, GFP_ATOMIC);
4506 ioc->spi_data.pIocPg2 = (IOCPage2_t *) mem;
4511 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
4513 /* Identify RAID Volume Id's */
4514 nVols = pIoc2->NumActiveVolumes;
4520 /* At least 1 RAID Volume
4522 pIocRv = pIoc2->RaidVolume;
4523 ioc->spi_data.isRaid = 0;
4524 for (jj = 0; jj < nVols; jj++, pIocRv++) {
4525 vid = pIocRv->VolumeID;
4526 vbus = pIocRv->VolumeBus;
4527 vioc = pIocRv->VolumeIOC;
4532 ioc->spi_data.isRaid |= (1 << vid);
4534 /* Error! Always bus 0
4540 /* Identify Hidden Physical Disk Id's */
4541 nPhys = pIoc2->NumActivePhysDisks;
4543 /* No physical disks.
4546 mpt_read_ioc_pg_3(ioc);
4550 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
4556 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
4561 ConfigPageHeader_t header;
4562 dma_addr_t ioc3_dma;
4565 /* Free the old page
4567 if (ioc->spi_data.pIocPg3) {
4568 kfree(ioc->spi_data.pIocPg3);
4569 ioc->spi_data.pIocPg3 = NULL;
4572 /* There is at least one physical disk.
4573 * Read and save IOC Page 3
4575 header.PageVersion = 0;
4576 header.PageLength = 0;
4577 header.PageNumber = 3;
4578 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4582 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4585 if (mpt_config(ioc, &cfg) != 0)
4588 if (header.PageLength == 0)
4591 /* Read Header good, alloc memory
4593 iocpage3sz = header.PageLength * 4;
4594 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
4598 /* Read the Page and save the data
4599 * into malloc'd memory.
4601 cfg.physAddr = ioc3_dma;
4602 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4603 if (mpt_config(ioc, &cfg) == 0) {
4604 mem = kmalloc(iocpage3sz, GFP_ATOMIC);
4606 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
4607 ioc->spi_data.pIocPg3 = (IOCPage3_t *) mem;
4611 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
4617 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
4621 ConfigPageHeader_t header;
4622 dma_addr_t ioc4_dma;
4625 /* Read and save IOC Page 4
4627 header.PageVersion = 0;
4628 header.PageLength = 0;
4629 header.PageNumber = 4;
4630 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4634 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4637 if (mpt_config(ioc, &cfg) != 0)
4640 if (header.PageLength == 0)
4643 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
4644 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
4645 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
4649 ioc4_dma = ioc->spi_data.IocPg4_dma;
4650 iocpage4sz = ioc->spi_data.IocPg4Sz;
4653 /* Read the Page into dma memory.
4655 cfg.physAddr = ioc4_dma;
4656 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4657 if (mpt_config(ioc, &cfg) == 0) {
4658 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
4659 ioc->spi_data.IocPg4_dma = ioc4_dma;
4660 ioc->spi_data.IocPg4Sz = iocpage4sz;
4662 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
4663 ioc->spi_data.pIocPg4 = NULL;
4668 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
4672 ConfigPageHeader_t header;
4673 dma_addr_t ioc1_dma;
4677 /* Check the Coalescing Timeout in IOC Page 1
4679 header.PageVersion = 0;
4680 header.PageLength = 0;
4681 header.PageNumber = 1;
4682 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4686 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4689 if (mpt_config(ioc, &cfg) != 0)
4692 if (header.PageLength == 0)
4695 /* Read Header good, alloc memory
4697 iocpage1sz = header.PageLength * 4;
4698 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
4702 /* Read the Page and check coalescing timeout
4704 cfg.physAddr = ioc1_dma;
4705 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4706 if (mpt_config(ioc, &cfg) == 0) {
4708 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
4709 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
4710 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
4712 dprintk((MYIOC_s_INFO_FMT "Coalescing Enabled Timeout = %d\n",
4715 if (tmp > MPT_COALESCING_TIMEOUT) {
4716 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
4718 /* Write NVRAM and current
4721 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4722 if (mpt_config(ioc, &cfg) == 0) {
4723 dprintk((MYIOC_s_INFO_FMT "Reset Current Coalescing Timeout to = %d\n",
4724 ioc->name, MPT_COALESCING_TIMEOUT));
4726 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
4727 if (mpt_config(ioc, &cfg) == 0) {
4728 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout to = %d\n",
4729 ioc->name, MPT_COALESCING_TIMEOUT));
4731 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout Failed\n",
4736 dprintk((MYIOC_s_WARN_FMT "Reset of Current Coalescing Timeout Failed!\n",
4742 dprintk((MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
4746 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
4751 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4753 * SendEventNotification - Send EventNotification (on or off) request
4755 * @ioc: Pointer to MPT_ADAPTER structure
4756 * @EvSwitch: Event switch flags
4759 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
4761 EventNotification_t *evnp;
4763 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
4765 dprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
4769 memset(evnp, 0, sizeof(*evnp));
4771 dprintk((MYIOC_s_INFO_FMT "Sending EventNotification(%d)\n", ioc->name, EvSwitch));
4773 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
4774 evnp->ChainOffset = 0;
4776 evnp->Switch = EvSwitch;
4778 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
4783 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4785 * SendEventAck - Send EventAck request to MPT adapter.
4786 * @ioc: Pointer to MPT_ADAPTER structure
4787 * @evnp: Pointer to original EventNotification request
4790 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
4794 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4795 printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK request frame!\n",
4799 memset(pAck, 0, sizeof(*pAck));
4801 dprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
4803 pAck->Function = MPI_FUNCTION_EVENT_ACK;
4804 pAck->ChainOffset = 0;
4806 pAck->Event = evnp->Event;
4807 pAck->EventContext = evnp->EventContext;
4809 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
4814 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4816 * mpt_config - Generic function to issue config message
4817 * @ioc - Pointer to an adapter structure
4818 * @cfg - Pointer to a configuration structure. Struct contains
4819 * action, page address, direction, physical address
4820 * and pointer to a configuration page header
4821 * Page header is updated.
4823 * Returns 0 for success
4824 * -EPERM if not allowed due to ISR context
4825 * -EAGAIN if no msg frames currently available
4826 * -EFAULT for non-successful reply or no reply (timeout)
4829 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
4833 unsigned long flags;
4838 /* (Bugzilla:fibrebugs, #513)
4839 * Bug fix (part 1)! 20010905 -sralston
4840 * Prevent calling wait_event() (below), if caller happens
4841 * to be in ISR context, because that is fatal!
4843 in_isr = in_interrupt();
4845 dcprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
4850 /* Get and Populate a free Frame
4852 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4853 dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
4857 pReq = (Config_t *)mf;
4858 pReq->Action = pCfg->action;
4860 pReq->ChainOffset = 0;
4861 pReq->Function = MPI_FUNCTION_CONFIG;
4862 pReq->ExtPageLength = 0;
4863 pReq->ExtPageType = 0;
4865 for (ii=0; ii < 8; ii++)
4866 pReq->Reserved2[ii] = 0;
4868 pReq->Header.PageVersion = pCfg->hdr->PageVersion;
4869 pReq->Header.PageLength = pCfg->hdr->PageLength;
4870 pReq->Header.PageNumber = pCfg->hdr->PageNumber;
4871 pReq->Header.PageType = (pCfg->hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
4872 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
4874 /* Add a SGE to the config request.
4877 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
4879 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
4881 flagsLength |= pCfg->hdr->PageLength * 4;
4883 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
4885 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
4886 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
4888 /* Append pCfg pointer to end of mf
4890 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
4892 /* Initalize the timer
4894 init_timer(&pCfg->timer);
4895 pCfg->timer.data = (unsigned long) ioc;
4896 pCfg->timer.function = mpt_timer_expired;
4897 pCfg->wait_done = 0;
4899 /* Set the timer; ensure 10 second minimum */
4900 if (pCfg->timeout < 10)
4901 pCfg->timer.expires = jiffies + HZ*10;
4903 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
4905 /* Add to end of Q, set timer and then issue this command */
4906 spin_lock_irqsave(&ioc->FreeQlock, flags);
4907 Q_ADD_TAIL(&ioc->configQ.head, &pCfg->linkage, Q_ITEM);
4908 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4910 add_timer(&pCfg->timer);
4911 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4912 wait_event(mpt_waitq, pCfg->wait_done);
4914 /* mf has been freed - do not access */
4921 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4923 * mpt_toolbox - Generic function to issue toolbox message
4924 * @ioc - Pointer to an adapter structure
4925 * @cfg - Pointer to a toolbox structure. Struct contains
4926 * action, page address, direction, physical address
4927 * and pointer to a configuration page header
4928 * Page header is updated.
4930 * Returns 0 for success
4931 * -EPERM if not allowed due to ISR context
4932 * -EAGAIN if no msg frames currently available
4933 * -EFAULT for non-successful reply or no reply (timeout)
4936 mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
4938 ToolboxIstwiReadWriteRequest_t *pReq;
4940 struct pci_dev *pdev;
4941 unsigned long flags;
4946 /* (Bugzilla:fibrebugs, #513)
4947 * Bug fix (part 1)! 20010905 -sralston
4948 * Prevent calling wait_event() (below), if caller happens
4949 * to be in ISR context, because that is fatal!
4951 in_isr = in_interrupt();
4953 dcprintk((MYIOC_s_WARN_FMT "toobox request not allowed in ISR context!\n",
4958 /* Get and Populate a free Frame
4960 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4961 dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n",
4965 pReq = (ToolboxIstwiReadWriteRequest_t *)mf;
4966 pReq->Tool = pCfg->action;
4968 pReq->ChainOffset = 0;
4969 pReq->Function = MPI_FUNCTION_TOOLBOX;
4970 pReq->Reserved1 = 0;
4971 pReq->Reserved2 = 0;
4973 pReq->Flags = pCfg->dir;
4975 pReq->Reserved3 = 0;
4976 pReq->NumAddressBytes = 0x01;
4977 pReq->Reserved4 = 0;
4978 pReq->DataLength = 0x04;
4979 pdev = (struct pci_dev *) ioc->pcidev;
4980 if (pdev->devfn & 1)
4981 pReq->DeviceAddr = 0xB2;
4983 pReq->DeviceAddr = 0xB0;
4987 pReq->Reserved5 = 0;
4989 /* Add a SGE to the config request.
4992 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | 4;
4994 mpt_add_sge((char *)&pReq->SGL, flagsLength, pCfg->physAddr);
4996 dcprintk((MYIOC_s_INFO_FMT "Sending Toolbox request, Tool=%x\n",
4997 ioc->name, pReq->Tool));
4999 /* Append pCfg pointer to end of mf
5001 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5003 /* Initalize the timer
5005 init_timer(&pCfg->timer);
5006 pCfg->timer.data = (unsigned long) ioc;
5007 pCfg->timer.function = mpt_timer_expired;
5008 pCfg->wait_done = 0;
5010 /* Set the timer; ensure 10 second minimum */
5011 if (pCfg->timeout < 10)
5012 pCfg->timer.expires = jiffies + HZ*10;
5014 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5016 /* Add to end of Q, set timer and then issue this command */
5017 spin_lock_irqsave(&ioc->FreeQlock, flags);
5018 Q_ADD_TAIL(&ioc->configQ.head, &pCfg->linkage, Q_ITEM);
5019 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5021 add_timer(&pCfg->timer);
5022 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5023 wait_event(mpt_waitq, pCfg->wait_done);
5025 /* mf has been freed - do not access */
5032 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5034 * mpt_timer_expired - Call back for timer process.
5035 * Used only internal config functionality.
5036 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5039 mpt_timer_expired(unsigned long data)
5041 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5043 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name));
5045 /* Perform a FW reload */
5046 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5047 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5049 /* No more processing.
5050 * Hard reset clean-up will wake up
5051 * process and free all resources.
5053 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name));
5058 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5060 * mpt_ioc_reset - Base cleanup for hard reset
5061 * @ioc: Pointer to the adapter structure
5062 * @reset_phase: Indicates pre- or post-reset functionality
5064 * Remark: Free's resources with internally generated commands.
5067 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5070 unsigned long flags;
5072 dprintk((KERN_WARNING MYNAM
5073 ": IOC %s_reset routed to MPT base driver!\n",
5074 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5075 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5077 if (reset_phase == MPT_IOC_SETUP_RESET) {
5079 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5080 /* If the internal config Q is not empty -
5081 * delete timer. MF resources will be freed when
5082 * the FIFO's are primed.
5084 spin_lock_irqsave(&ioc->FreeQlock, flags);
5085 if (! Q_IS_EMPTY(&ioc->configQ)){
5086 pCfg = (CONFIGPARMS *)ioc->configQ.head;
5088 del_timer(&pCfg->timer);
5089 pCfg = (CONFIGPARMS *) (pCfg->linkage.forw);
5090 } while (pCfg != (CONFIGPARMS *)&ioc->configQ);
5092 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5097 /* Search the configQ for internal commands.
5098 * Flush the Q, and wake up all suspended threads.
5100 spin_lock_irqsave(&ioc->FreeQlock, flags);
5101 if (! Q_IS_EMPTY(&ioc->configQ)){
5102 pCfg = (CONFIGPARMS *)ioc->configQ.head;
5104 pNext = (CONFIGPARMS *) pCfg->linkage.forw;
5106 Q_DEL_ITEM(&pCfg->linkage);
5108 pCfg->status = MPT_CONFIG_ERROR;
5109 pCfg->wait_done = 1;
5110 wake_up(&mpt_waitq);
5113 } while (pCfg != (CONFIGPARMS *)&ioc->configQ);
5115 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5118 return 1; /* currently means nothing really */
5122 #ifdef CONFIG_PROC_FS /* { */
5123 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5125 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5127 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5129 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5131 * Returns 0 for success, non-zero for failure.
5134 procmpt_create(void)
5136 struct proc_dir_entry *ent;
5138 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5139 if (mpt_proc_root_dir == NULL)
5142 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5144 ent->read_proc = procmpt_summary_read;
5146 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5148 ent->read_proc = procmpt_version_read;
5153 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5155 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5157 * Returns 0 for success, non-zero for failure.
5160 procmpt_destroy(void)
5162 remove_proc_entry("version", mpt_proc_root_dir);
5163 remove_proc_entry("summary", mpt_proc_root_dir);
5164 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5167 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5169 * procmpt_summary_read - Handle read request from /proc/mpt/summary
5170 * or from /proc/mpt/iocN/summary.
5171 * @buf: Pointer to area to write information
5172 * @start: Pointer to start pointer
5173 * @offset: Offset to start writing
5175 * @eof: Pointer to EOF integer
5178 * Returns number of characters written to process performing the read.
5181 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5191 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5195 list_for_each_entry(ioc, &ioc_list, list) {
5198 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5201 if ((out-buf) >= request)
5208 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5211 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5213 * procmpt_version_read - Handle read request from /proc/mpt/version.
5214 * @buf: Pointer to area to write information
5215 * @start: Pointer to start pointer
5216 * @offset: Offset to start writing
5218 * @eof: Pointer to EOF integer
5221 * Returns number of characters written to process performing the read.
5224 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5227 int scsi, lan, ctl, targ, dmp;
5231 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5232 len += sprintf(buf+len, " Fusion MPT base driver\n");
5234 scsi = lan = ctl = targ = dmp = 0;
5235 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5237 if (MptCallbacks[ii]) {
5238 switch (MptDriverClass[ii]) {
5239 case MPTSCSIH_DRIVER:
5240 if (!scsi++) drvname = "SCSI host";
5243 if (!lan++) drvname = "LAN";
5246 if (!targ++) drvname = "SCSI target";
5249 if (!ctl++) drvname = "ioctl";
5252 if (!dmp++) drvname = "DMP";
5257 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5261 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5264 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5266 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5267 * @buf: Pointer to area to write information
5268 * @start: Pointer to start pointer
5269 * @offset: Offset to start writing
5271 * @eof: Pointer to EOF integer
5274 * Returns number of characters written to process performing the read.
5277 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5279 MPT_ADAPTER *ioc = data;
5285 mpt_get_fw_exp_ver(expVer, ioc);
5287 len = sprintf(buf, "%s:", ioc->name);
5288 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5289 len += sprintf(buf+len, " (f/w download boot flag set)");
5290 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5291 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5293 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
5294 ioc->facts.ProductID,
5296 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5297 if (ioc->facts.FWImageSize)
5298 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5299 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5300 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5301 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
5303 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
5304 ioc->facts.CurrentHostMfaHighAddr);
5305 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
5306 ioc->facts.CurrentSenseBufferHighAddr);
5308 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5309 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5311 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5312 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
5314 * Rounding UP to nearest 4-kB boundary here...
5316 sz = (ioc->req_sz * ioc->req_depth) + 128;
5317 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5318 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5319 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5320 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
5321 4*ioc->facts.RequestFrameSize,
5322 ioc->facts.GlobalCredits);
5324 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
5325 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
5326 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5327 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5328 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5329 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
5330 ioc->facts.CurReplyFrameSize,
5331 ioc->facts.ReplyQueueDepth);
5333 len += sprintf(buf+len, " MaxDevices = %d\n",
5334 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5335 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
5338 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5339 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
5341 ioc->facts.NumberOfPorts);
5342 if ((int)ioc->chip_type <= (int)FC929) {
5343 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5344 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5345 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5346 a[5], a[4], a[3], a[2], a[1], a[0]);
5348 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
5349 ioc->fc_port_page0[p].WWNN.High,
5350 ioc->fc_port_page0[p].WWNN.Low,
5351 ioc->fc_port_page0[p].WWPN.High,
5352 ioc->fc_port_page0[p].WWPN.Low);
5356 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5359 #endif /* CONFIG_PROC_FS } */
5361 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5363 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
5366 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
5367 sprintf(buf, " (Exp %02d%02d)",
5368 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
5369 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
5372 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
5373 strcat(buf, " [MDBG]");
5377 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5379 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5380 * @ioc: Pointer to MPT_ADAPTER structure
5381 * @buffer: Pointer to buffer where IOC summary info should be written
5382 * @size: Pointer to number of bytes we wrote (set by this routine)
5383 * @len: Offset at which to start writing in buffer
5384 * @showlan: Display LAN stuff?
5386 * This routine writes (english readable) ASCII text, which represents
5387 * a summary of IOC information, to a buffer.
5390 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
5395 mpt_get_fw_exp_ver(expVer, ioc);
5398 * Shorter summary of attached ioc's...
5400 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
5403 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
5404 ioc->facts.FWVersion.Word,
5406 ioc->facts.NumberOfPorts,
5409 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
5410 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5411 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
5412 a[5], a[4], a[3], a[2], a[1], a[0]);
5416 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
5418 y += sprintf(buffer+len+y, ", IRQ=%s", __irq_itoa(ioc->pci_irq));
5422 y += sprintf(buffer+len+y, " (disabled)");
5424 y += sprintf(buffer+len+y, "\n");
5429 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5433 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5435 * mpt_HardResetHandler - Generic reset handler, issue SCSI Task
5436 * Management call based on input arg values. If TaskMgmt fails,
5437 * return associated SCSI request.
5438 * @ioc: Pointer to MPT_ADAPTER structure
5439 * @sleepFlag: Indicates if sleep or schedule must be called.
5441 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
5442 * or a non-interrupt thread. In the former, must not call schedule().
5444 * Remark: A return of -1 is a FATAL error case, as it means a
5445 * FW reload/initialization failed.
5447 * Returns 0 for SUCCESS or -1 if FAILED.
5450 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5453 unsigned long flags;
5455 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
5457 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
5458 printk("MF count 0x%x !\n", ioc->mfcnt);
5461 /* Reset the adapter. Prevent more than 1 call to
5462 * mpt_do_ioc_recovery at any instant in time.
5464 spin_lock_irqsave(&ioc->diagLock, flags);
5465 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
5466 spin_unlock_irqrestore(&ioc->diagLock, flags);
5469 ioc->diagPending = 1;
5471 spin_unlock_irqrestore(&ioc->diagLock, flags);
5473 /* FIXME: If do_ioc_recovery fails, repeat....
5476 /* The SCSI driver needs to adjust timeouts on all current
5477 * commands prior to the diagnostic reset being issued.
5478 * Prevents timeouts occuring during a diagnostic reset...very bad.
5479 * For all other protocol drivers, this is a no-op.
5485 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5486 if (MptResetHandlers[ii]) {
5487 dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
5489 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_SETUP_RESET);
5491 dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
5492 ioc->name, ioc->alt_ioc->name, ii));
5493 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_SETUP_RESET);
5499 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
5500 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
5505 ioc->alt_ioc->reload_fw = 0;
5507 spin_lock_irqsave(&ioc->diagLock, flags);
5508 ioc->diagPending = 0;
5510 ioc->alt_ioc->diagPending = 0;
5511 spin_unlock_irqrestore(&ioc->diagLock, flags);
5513 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
5518 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5520 EventDescriptionStr(u8 event, u32 evData0)
5525 case MPI_EVENT_NONE:
5528 case MPI_EVENT_LOG_DATA:
5531 case MPI_EVENT_STATE_CHANGE:
5532 ds = "State Change";
5534 case MPI_EVENT_UNIT_ATTENTION:
5535 ds = "Unit Attention";
5537 case MPI_EVENT_IOC_BUS_RESET:
5538 ds = "IOC Bus Reset";
5540 case MPI_EVENT_EXT_BUS_RESET:
5541 ds = "External Bus Reset";
5543 case MPI_EVENT_RESCAN:
5544 ds = "Bus Rescan Event";
5545 /* Ok, do we need to do anything here? As far as
5546 I can tell, this is when a new device gets added
5549 case MPI_EVENT_LINK_STATUS_CHANGE:
5550 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
5551 ds = "Link Status(FAILURE) Change";
5553 ds = "Link Status(ACTIVE) Change";
5555 case MPI_EVENT_LOOP_STATE_CHANGE:
5556 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
5557 ds = "Loop State(LIP) Change";
5558 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
5559 ds = "Loop State(LPE) Change"; /* ??? */
5561 ds = "Loop State(LPB) Change"; /* ??? */
5563 case MPI_EVENT_LOGOUT:
5566 case MPI_EVENT_EVENT_CHANGE:
5568 ds = "Events(ON) Change";
5570 ds = "Events(OFF) Change";
5572 case MPI_EVENT_INTEGRATED_RAID:
5573 ds = "Integrated Raid";
5576 * MPT base "custom" events may be added here...
5585 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5587 * ProcessEventNotification - Route a received EventNotificationReply to
5588 * all currently regeistered event handlers.
5589 * @ioc: Pointer to MPT_ADAPTER structure
5590 * @pEventReply: Pointer to EventNotification reply frame
5591 * @evHandlers: Pointer to integer, number of event handlers
5593 * Returns sum of event handlers return values.
5596 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
5608 * Do platform normalization of values
5610 event = le32_to_cpu(pEventReply->Event) & 0xFF;
5611 // evCtx = le32_to_cpu(pEventReply->EventContext);
5612 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
5614 evData0 = le32_to_cpu(pEventReply->Data[0]);
5617 evStr = EventDescriptionStr(event, evData0);
5618 devtprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n",
5623 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_EVENTS)
5624 printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
5625 for (ii = 0; ii < evDataLen; ii++)
5626 printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
5631 * Do general / base driver event processing
5634 case MPI_EVENT_NONE: /* 00 */
5635 case MPI_EVENT_LOG_DATA: /* 01 */
5636 case MPI_EVENT_STATE_CHANGE: /* 02 */
5637 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
5638 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
5639 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
5640 case MPI_EVENT_RESCAN: /* 06 */
5641 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
5642 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
5643 case MPI_EVENT_LOGOUT: /* 09 */
5644 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
5645 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE: /* 0C */
5648 case MPI_EVENT_EVENT_CHANGE: /* 0A */
5650 u8 evState = evData0 & 0xFF;
5652 /* CHECKME! What if evState unexpectedly says OFF (0)? */
5654 /* Update EventState field in cached IocFacts */
5655 if (ioc->facts.Function) {
5656 ioc->facts.EventState = evState;
5663 * Should this event be logged? Events are written sequentially.
5664 * When buffer is full, start again at the top.
5666 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
5669 idx = ioc->eventContext % ioc->eventLogSize;
5671 ioc->events[idx].event = event;
5672 ioc->events[idx].eventContext = ioc->eventContext;
5674 for (ii = 0; ii < 2; ii++) {
5676 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
5678 ioc->events[idx].data[ii] = 0;
5681 ioc->eventContext++;
5686 * Call each currently registered protocol event handler.
5688 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5689 if (MptEvHandlers[ii]) {
5690 devtprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
5692 r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
5696 /* FIXME? Examine results here? */
5699 * If needed, send (a single) EventAck.
5701 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
5702 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
5703 devtprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
5708 *evHandlers = handlers;
5712 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5714 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
5715 * @ioc: Pointer to MPT_ADAPTER structure
5716 * @log_info: U32 LogInfo reply word from the IOC
5718 * Refer to lsi/fc_log.h.
5721 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
5723 static char *subcl_str[8] = {
5724 "FCP Initiator", "FCP Target", "LAN", "MPI Message Layer",
5725 "FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
5727 u8 subcl = (log_info >> 24) & 0x7;
5729 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}\n",
5730 ioc->name, log_info, subcl_str[subcl]);
5733 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5735 * mpt_sp_log_info - Log information returned from SCSI Parallel IOC.
5736 * @ioc: Pointer to MPT_ADAPTER structure
5737 * @mr: Pointer to MPT reply frame
5738 * @log_info: U32 LogInfo word from the IOC
5740 * Refer to lsi/sp_log.h.
5743 mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
5745 u32 info = log_info & 0x00FF0000;
5746 char *desc = "unknown";
5750 desc = "bug! MID not found";
5751 if (ioc->reload_fw == 0)
5756 desc = "Parity Error";
5760 desc = "ASYNC Outbound Overrun";
5764 desc = "SYNC Offset Error";
5772 desc = "Msg In Overflow";
5780 desc = "Outbound DMA Overrun";
5784 desc = "Task Management";
5788 desc = "Device Problem";
5792 desc = "Invalid Phase Change";
5796 desc = "Untagged Table Size";
5801 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
5804 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5806 * mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
5807 * @ioc: Pointer to MPT_ADAPTER structure
5808 * @ioc_status: U32 IOCStatus word from IOC
5809 * @mf: Pointer to MPT request frame
5811 * Refer to lsi/mpi.h.
5814 mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
5816 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
5820 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
5821 desc = "Invalid Function";
5824 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
5828 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
5829 desc = "Invalid SGL";
5832 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
5833 desc = "Internal Error";
5836 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
5840 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
5841 desc = "Insufficient Resources";
5844 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
5845 desc = "Invalid Field";
5848 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
5849 desc = "Invalid State";
5852 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
5853 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
5854 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
5855 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
5856 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
5857 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
5858 /* No message for Config IOCStatus values */
5861 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
5862 /* No message for recovered error
5863 desc = "SCSI Recovered Error";
5867 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
5868 desc = "SCSI Invalid Bus";
5871 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
5872 desc = "SCSI Invalid TargetID";
5875 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
5877 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
5878 U8 cdb = pScsiReq->CDB[0];
5879 if (cdb != 0x12) { /* Inquiry is issued for device scanning */
5880 desc = "SCSI Device Not There";
5885 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
5886 desc = "SCSI Data Overrun";
5889 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
5890 /* This error is checked in scsi_io_done(). Skip.
5891 desc = "SCSI Data Underrun";
5895 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
5896 desc = "SCSI I/O Data Error";
5899 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
5900 desc = "SCSI Protocol Error";
5903 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
5904 desc = "SCSI Task Terminated";
5907 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
5908 desc = "SCSI Residual Mismatch";
5911 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
5912 desc = "SCSI Task Management Failed";
5915 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
5916 desc = "SCSI IOC Terminated";
5919 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
5920 desc = "SCSI Ext Terminated";
5928 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc);
5931 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5932 EXPORT_SYMBOL(ioc_list);
5933 EXPORT_SYMBOL(mpt_proc_root_dir);
5934 EXPORT_SYMBOL(DmpService);
5935 EXPORT_SYMBOL(mpt_register);
5936 EXPORT_SYMBOL(mpt_deregister);
5937 EXPORT_SYMBOL(mpt_event_register);
5938 EXPORT_SYMBOL(mpt_event_deregister);
5939 EXPORT_SYMBOL(mpt_reset_register);
5940 EXPORT_SYMBOL(mpt_reset_deregister);
5941 EXPORT_SYMBOL(mpt_device_driver_register);
5942 EXPORT_SYMBOL(mpt_device_driver_deregister);
5943 EXPORT_SYMBOL(mpt_get_msg_frame);
5944 EXPORT_SYMBOL(mpt_put_msg_frame);
5945 EXPORT_SYMBOL(mpt_free_msg_frame);
5946 EXPORT_SYMBOL(mpt_add_sge);
5947 EXPORT_SYMBOL(mpt_add_chain);
5948 EXPORT_SYMBOL(mpt_send_handshake_request);
5949 EXPORT_SYMBOL(mpt_handshake_req_reply_wait);
5950 EXPORT_SYMBOL(mpt_verify_adapter);
5951 EXPORT_SYMBOL(mpt_GetIocState);
5952 EXPORT_SYMBOL(mpt_print_ioc_summary);
5953 EXPORT_SYMBOL(mpt_lan_index);
5954 EXPORT_SYMBOL(mpt_stm_index);
5955 EXPORT_SYMBOL(mpt_HardResetHandler);
5956 EXPORT_SYMBOL(mpt_config);
5957 EXPORT_SYMBOL(mpt_toolbox);
5958 EXPORT_SYMBOL(mpt_findImVolumes);
5959 EXPORT_SYMBOL(mpt_read_ioc_pg_3);
5960 EXPORT_SYMBOL(mpt_alloc_fw_memory);
5961 EXPORT_SYMBOL(mpt_free_fw_memory);
5963 static struct pci_driver mptbase_driver = {
5965 .id_table = mptbase_pci_table,
5966 .probe = mptbase_probe,
5967 .remove = __devexit_p(mptbase_remove),
5969 .shutdown = mptbase_shutdown,
5972 .suspend = mptbase_suspend,
5973 .resume = mptbase_resume,
5977 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5979 * fusion_init - Fusion MPT base driver initialization routine.
5981 * Returns 0 for success, non-zero for failure.
5989 if (FusionInitCalled++) {
5990 dprintk((KERN_INFO MYNAM ": INFO - Driver late-init entry point called\n"));
5994 show_mptmod_ver(my_NAME, my_VERSION);
5995 printk(KERN_INFO COPYRIGHT "\n");
5997 for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
5998 MptCallbacks[i] = NULL;
5999 MptDriverClass[i] = MPTUNKNOWN_DRIVER;
6000 MptEvHandlers[i] = NULL;
6001 MptResetHandlers[i] = NULL;
6006 /* NEW! 20010120 -sralston
6007 * Register ourselves (mptbase) in order to facilitate
6008 * EventNotification handling.
6010 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
6012 /* Register for hard reset handling callbacks.
6014 if (mpt_reset_register(mpt_base_index, mpt_ioc_reset) == 0) {
6015 dprintk((KERN_INFO MYNAM ": Register for IOC reset notification\n"));
6020 #ifdef CONFIG_PROC_FS
6021 (void) procmpt_create();
6023 r = pci_module_init(&mptbase_driver);
6030 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6032 * fusion_exit - Perform driver unload cleanup.
6034 * This routine frees all resources associated with each MPT adapter
6035 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
6041 dexitprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
6043 pci_unregister_driver(&mptbase_driver);
6044 mpt_reset_deregister(mpt_base_index);
6046 #ifdef CONFIG_PROC_FS
6052 module_init(fusion_init);
6053 module_exit(fusion_exit);