2 * linux/drivers/message/fusion/mptbase.c
3 * High performance SCSI + LAN / Fibre Channel device drivers.
4 * This is the Fusion MPT base driver which supports multiple
5 * (SCSI + LAN) specialized protocol drivers.
6 * For use with PCI chip/adapter(s):
7 * LSIFC9xx/LSI409xx Fibre Channel
8 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
11 * There are lots of people not mentioned below that deserve credit
12 * and thanks but won't get it here - sorry in advance that you
15 * This driver would not exist if not for Alan Cox's development
16 * of the linux i2o driver.
18 * A special thanks to Noah Romer (LSI Logic) for tons of work
19 * and tough debugging on the LAN driver, especially early on;-)
20 * And to Roger Hickerson (LSI Logic) for tirelessly supporting
21 * this driver project.
23 * A special thanks to Pamela Delaney (LSI Logic) for tons of work
24 * and countless enhancements while adding support for the 1030
25 * chip family. Pam has been instrumental in the development of
26 * of the 2.xx.xx series fusion drivers, and her contributions are
27 * far too numerous to hope to list in one place.
29 * All manner of help from Stephen Shirron (LSI Logic):
30 * low-level FC analysis, debug + various fixes in FCxx firmware,
31 * initial port to alpha platform, various driver code optimizations,
32 * being a faithful sounding board on all sorts of issues & ideas,
35 * A huge debt of gratitude is owed to David S. Miller (DaveM)
36 * for fixing much of the stupid and broken stuff in the early
37 * driver while porting to sparc64 platform. THANK YOU!
39 * Special thanks goes to the I2O LAN driver people at the
40 * University of Helsinki, who, unbeknownst to them, provided
41 * the inspiration and initial structure for this driver.
43 * A really huge debt of gratitude is owed to Eddie C. Dost
44 * for gobs of hard work fixing and optimizing LAN code.
47 * Copyright (c) 1999-2004 LSI Logic Corporation
48 * Originally By: Steven J. Ralston
49 * (mailto:sjralston1@netscape.net)
50 * (mailto:mpt_linux_developer@lsil.com)
52 * $Id: mptbase.c,v 1.126 2002/12/16 15:28:45 pdelaney Exp $
54 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
56 This program is free software; you can redistribute it and/or modify
57 it under the terms of the GNU General Public License as published by
58 the Free Software Foundation; version 2 of the License.
60 This program is distributed in the hope that it will be useful,
61 but WITHOUT ANY WARRANTY; without even the implied warranty of
62 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
63 GNU General Public License for more details.
66 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
67 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
68 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
69 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
70 solely responsible for determining the appropriateness of using and
71 distributing the Program and assumes all risks associated with its
72 exercise of rights under this Agreement, including but not limited to
73 the risks and costs of program errors, damage to or loss of data,
74 programs or equipment, and unavailability or interruption of operations.
76 DISCLAIMER OF LIABILITY
77 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
78 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
79 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
80 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
81 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
82 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
83 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
85 You should have received a copy of the GNU General Public License
86 along with this program; if not, write to the Free Software
87 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
89 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
91 #include <linux/config.h>
92 #include <linux/version.h>
93 #include <linux/kernel.h>
94 #include <linux/module.h>
95 #include <linux/errno.h>
96 #include <linux/init.h>
97 #include <linux/slab.h>
98 #include <linux/types.h>
99 #include <linux/pci.h>
100 #include <linux/kdev_t.h>
101 #include <linux/blkdev.h>
102 #include <linux/delay.h>
103 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
106 #include <asm/mtrr.h>
109 #include <asm/irq.h> /* needed for __irq_itoa() proto */
114 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
115 #define my_NAME "Fusion MPT base driver"
116 #define my_VERSION MPT_LINUX_VERSION_COMMON
117 #define MYNAM "mptbase"
119 MODULE_AUTHOR(MODULEAUTHOR);
120 MODULE_DESCRIPTION(my_NAME);
121 MODULE_LICENSE("GPL");
124 * cmd line parameters
127 static int mfcounter = 0;
128 #define PRINT_MF_COUNT 20000
131 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
135 int mpt_lan_index = -1;
136 int mpt_stm_index = -1;
138 struct proc_dir_entry *mpt_proc_root_dir;
140 DmpServices_t *DmpService;
142 void *mpt_v_ASCQ_TablePtr;
143 const char **mpt_ScsiOpcodesPtr;
144 int mpt_ASCQ_TableSz;
147 #define WHOINIT_UNKNOWN 0xAA
149 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
153 /* Adapter link list */
155 /* Callback lookup table */
156 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
157 /* Protocol driver class lookup table */
158 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
159 /* Event handler lookup table */
160 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
161 /* Reset handler lookup table */
162 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
163 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
165 static int FusionInitCalled = 0;
166 static int mpt_base_index = -1;
167 static int last_drv_idx = -1;
168 static int isense_idx = -1;
170 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
172 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
176 static irqreturn_t mpt_interrupt(int irq, void *bus_id, struct pt_regs *r);
177 static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
179 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
180 static void mpt_detect_bound_ports(MPT_ADAPTER *this, struct pci_dev *pdev);
181 static void mpt_adapter_disable(MPT_ADAPTER *ioc, int freeup);
182 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
184 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
185 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
186 //static u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
187 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
188 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
189 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
190 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
191 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
192 static int mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag);
193 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
194 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
195 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
196 static int PrimeIocFifos(MPT_ADAPTER *ioc);
197 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
198 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
199 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
200 static int GetLanConfigPages(MPT_ADAPTER *ioc);
201 static int GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
202 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
203 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
204 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
205 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
206 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
207 static void mpt_timer_expired(unsigned long data);
208 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
209 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
211 #ifdef CONFIG_PROC_FS
212 static int procmpt_summary_read(char *buf, char **start, off_t offset,
213 int request, int *eof, void *data);
214 static int procmpt_version_read(char *buf, char **start, off_t offset,
215 int request, int *eof, void *data);
216 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
217 int request, int *eof, void *data);
219 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
221 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
222 static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
223 static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
224 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
225 static void mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info);
227 /* module entry point */
228 static int __devinit mptbase_probe (struct pci_dev *, const struct pci_device_id *);
229 static void __devexit mptbase_remove(struct pci_dev *);
230 static void mptbase_shutdown(struct device * );
231 static int __init fusion_init (void);
232 static void __exit fusion_exit (void);
234 /****************************************************************************
238 static struct pci_device_id mptbase_pci_table[] = {
239 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC909,
240 PCI_ANY_ID, PCI_ANY_ID },
241 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929,
242 PCI_ANY_ID, PCI_ANY_ID },
243 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919,
244 PCI_ANY_ID, PCI_ANY_ID },
245 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929X,
246 PCI_ANY_ID, PCI_ANY_ID },
247 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919X,
248 PCI_ANY_ID, PCI_ANY_ID },
249 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1030,
250 PCI_ANY_ID, PCI_ANY_ID },
251 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_1030_53C1035,
252 PCI_ANY_ID, PCI_ANY_ID },
253 {0} /* Terminating entry */
255 MODULE_DEVICE_TABLE(pci, mptbase_pci_table);
257 #define CHIPREG_READ32(addr) readl_relaxed(addr)
258 #define CHIPREG_READ32_dmasync(addr) readl(addr)
259 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
260 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
261 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
263 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
265 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
266 * @irq: irq number (not used)
267 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
268 * @r: pt_regs pointer (not used)
270 * This routine is registered via the request_irq() kernel API call,
271 * and handles all interrupts generated from a specific MPT adapter
272 * (also referred to as a IO Controller or IOC).
273 * This routine must clear the interrupt from the adapter and does
274 * so by reading the reply FIFO. Multiple replies may be processed
275 * per single call to this routine; up to MPT_MAX_REPLIES_PER_ISR
276 * which is currently set to 32 in mptbase.h.
278 * This routine handles register-level access of the adapter but
279 * dispatches (calls) a protocol-specific callback routine to handle
280 * the protocol-specific details of the MPT request completion.
283 mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
297 * Drain the reply FIFO!
299 * NOTES: I've seen up to 10 replies processed in this loop, so far...
300 * Update: I've seen up to 9182 replies processed in this loop! ??
301 * Update: Limit ourselves to processing max of N replies
306 if ((pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo)) == 0xFFFFFFFF)
313 * Check for non-TURBO reply!
315 if (pa & MPI_ADDRESS_REPLY_A_BIT) {
319 /* non-TURBO reply! Hmmm, something may be up...
320 * Newest turbo reply mechanism; get address
321 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
324 /* Map DMA address of reply header to cpu address.
325 * pa is 32 bits - but the dma address may be 32 or 64 bits
326 * get offset based only only the low addresses
328 reply_dma_low = (pa = (pa << 1));
329 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
330 (reply_dma_low - ioc->reply_frames_low_dma));
332 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
333 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
334 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
336 dprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p\n",
338 DBG_DUMP_REPLY_FRAME(mr)
340 /* NEW! 20010301 -sralston
341 * Check/log IOC log info
343 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
344 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
345 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
346 if ((int)ioc->chip_type <= (int)FC929)
347 mpt_fc_log_info(ioc, log_info);
349 mpt_sp_log_info(ioc, log_info);
351 if (ioc_stat & MPI_IOCSTATUS_MASK) {
352 if ((int)ioc->chip_type <= (int)FC929)
355 mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
359 * Process turbo (context) reply...
361 dirqprintk((MYIOC_s_INFO_FMT "Got TURBO reply(=%08x)\n", ioc->name, pa));
362 type = (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT);
363 if (type == MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET) {
364 cb_idx = mpt_stm_index;
366 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
367 } else if (type == MPI_CONTEXT_REPLY_TYPE_LAN) {
368 cb_idx = mpt_lan_index;
370 * BUG FIX! 20001218 -sralston
371 * Blind set of mf to NULL here was fatal
372 * after lan_reply says "freeme"
373 * Fix sort of combined with an optimization here;
374 * added explicit check for case where lan_reply
375 * was just returning 1 and doing nothing else.
376 * For this case skip the callback, but set up
377 * proper mf value first here:-)
379 if ((pa & 0x58000000) == 0x58000000) {
380 req_idx = pa & 0x0000FFFF;
381 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
384 * IMPORTANT! Invalidate the callback!
390 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
392 req_idx = pa & 0x0000FFFF;
393 cb_idx = (pa & 0x00FF0000) >> 16;
394 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
397 pa = 0; /* No reply flush! */
401 if ((int)ioc->chip_type > (int)FC929) {
402 /* Verify mf, mr are reasonable.
404 if ((mf) && ((mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))
405 || (mf < ioc->req_frames)) ) {
406 printk(MYIOC_s_WARN_FMT
407 "mpt_interrupt: Invalid mf (%p) req_idx (%d)!\n", ioc->name, (void *)mf, req_idx);
412 if ((pa) && (mr) && ((mr >= MPT_INDEX_2_RFPTR(ioc, ioc->req_depth))
413 || (mr < ioc->reply_frames)) ) {
414 printk(MYIOC_s_WARN_FMT
415 "mpt_interrupt: Invalid rf (%p)!\n", ioc->name, (void *)mr);
420 if (cb_idx > (MPT_MAX_PROTOCOL_DRIVERS-1)) {
421 printk(MYIOC_s_WARN_FMT
422 "mpt_interrupt: Invalid cb_idx (%d)!\n", ioc->name, cb_idx);
430 /* Check for (valid) IO callback! */
432 /* Do the callback! */
433 freeme = (*(MptCallbacks[cb_idx]))(ioc, mf, mr);
437 /* Flush (non-TURBO) reply with a WRITE! */
438 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
444 /* Put Request back on FreeQ! */
445 spin_lock_irqsave(&ioc->FreeQlock, flags);
446 Q_ADD_TAIL(&ioc->FreeQ, &mf->u.frame.linkage, MPT_FRAME_HDR);
450 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
454 } /* drain reply FIFO */
459 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
461 * mpt_base_reply - MPT base driver's callback routine; all base driver
462 * "internal" request/reply processing is routed here.
463 * Currently used for EventNotification and EventAck handling.
464 * @ioc: Pointer to MPT_ADAPTER structure
465 * @mf: Pointer to original MPT request frame
466 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
468 * Returns 1 indicating original alloc'd request frame ptr
469 * should be freed, or 0 if it shouldn't.
472 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
477 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name));
480 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
481 printk(MYIOC_s_ERR_FMT "NULL or BAD request frame ptr! (=%p)\n",
482 ioc->name, (void *)mf);
487 dprintk((MYIOC_s_ERR_FMT "Unexpected NULL Event (turbo?) reply!\n",
492 if (!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
493 dmfprintk((KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf));
494 DBG_DUMP_REQUEST_FRAME_HDR(mf)
497 func = reply->u.hdr.Function;
498 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n",
501 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
502 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
506 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
507 if (results != evHandlers) {
508 /* CHECKME! Any special handling needed here? */
509 dprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
510 ioc->name, evHandlers, results));
514 * Hmmm... It seems that EventNotificationReply is an exception
515 * to the rule of one reply per request.
517 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
520 #ifdef CONFIG_PROC_FS
521 // LogEvent(ioc, pEvReply);
524 } else if (func == MPI_FUNCTION_EVENT_ACK) {
525 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
527 } else if (func == MPI_FUNCTION_CONFIG ||
528 func == MPI_FUNCTION_TOOLBOX) {
532 dcprintk((MYIOC_s_INFO_FMT "config_complete (mf=%p,mr=%p)\n",
533 ioc->name, mf, reply));
535 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
538 /* disable timer and remove from linked list */
539 del_timer(&pCfg->timer);
541 spin_lock_irqsave(&ioc->FreeQlock, flags);
542 Q_DEL_ITEM(&pCfg->linkage);
543 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
546 * If IOC Status is SUCCESS, save the header
547 * and set the status code to GOOD.
549 pCfg->status = MPT_CONFIG_ERROR;
551 ConfigReply_t *pReply = (ConfigReply_t *)reply;
554 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
555 dcprintk((KERN_NOTICE " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
556 status, le32_to_cpu(pReply->IOCLogInfo)));
558 pCfg->status = status;
559 if (status == MPI_IOCSTATUS_SUCCESS) {
560 pCfg->hdr->PageVersion = pReply->Header.PageVersion;
561 pCfg->hdr->PageLength = pReply->Header.PageLength;
562 pCfg->hdr->PageNumber = pReply->Header.PageNumber;
563 pCfg->hdr->PageType = pReply->Header.PageType;
568 * Wake up the original calling thread
574 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
579 * Conditionally tell caller to free the original
580 * EventNotification/EventAck/unexpected request frame!
585 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
587 * mpt_register - Register protocol-specific main callback handler.
588 * @cbfunc: callback function pointer
589 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
591 * This routine is called by a protocol-specific driver (SCSI host,
592 * LAN, SCSI target) to register it's reply callback routine. Each
593 * protocol-specific driver must do this before it will be able to
594 * use any IOC resources, such as obtaining request frames.
596 * NOTES: The SCSI protocol driver currently calls this routine thrice
597 * in order to register separate callbacks; one for "normal" SCSI IO;
598 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
600 * Returns a positive integer valued "handle" in the
601 * range (and S.O.D. order) {N,...,7,6,5,...,1} if successful.
602 * Any non-positive return value (including zero!) should be considered
603 * an error by the caller.
606 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
614 * Handle possibility of the mptscsih_detect() routine getting
615 * called *before* fusion_init!
617 if (!FusionInitCalled) {
618 dprintk((KERN_INFO MYNAM ": Hmmm, calling fusion_init from mpt_register!\n"));
620 * NOTE! We'll get recursion here, as fusion_init()
621 * calls mpt_register()!
629 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
630 * (slot/handle 0 is reserved!)
632 for (i = MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
633 if (MptCallbacks[i] == NULL) {
634 MptCallbacks[i] = cbfunc;
635 MptDriverClass[i] = dclass;
636 MptEvHandlers[i] = NULL;
645 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
647 * mpt_deregister - Deregister a protocol drivers resources.
648 * @cb_idx: previously registered callback handle
650 * Each protocol-specific driver should call this routine when it's
651 * module is unloaded.
654 mpt_deregister(int cb_idx)
656 if ((cb_idx >= 0) && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
657 MptCallbacks[cb_idx] = NULL;
658 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
659 MptEvHandlers[cb_idx] = NULL;
662 if (isense_idx != -1 && isense_idx <= cb_idx)
667 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
669 * mpt_event_register - Register protocol-specific event callback
671 * @cb_idx: previously registered (via mpt_register) callback handle
672 * @ev_cbfunc: callback function
674 * This routine can be called by one or more protocol-specific drivers
675 * if/when they choose to be notified of MPT events.
677 * Returns 0 for success.
680 mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc)
682 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
685 MptEvHandlers[cb_idx] = ev_cbfunc;
689 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
691 * mpt_event_deregister - Deregister protocol-specific event callback
693 * @cb_idx: previously registered callback handle
695 * Each protocol-specific driver should call this routine
696 * when it does not (or can no longer) handle events,
697 * or when it's module is unloaded.
700 mpt_event_deregister(int cb_idx)
702 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
705 MptEvHandlers[cb_idx] = NULL;
708 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
710 * mpt_reset_register - Register protocol-specific IOC reset handler.
711 * @cb_idx: previously registered (via mpt_register) callback handle
712 * @reset_func: reset function
714 * This routine can be called by one or more protocol-specific drivers
715 * if/when they choose to be notified of IOC resets.
717 * Returns 0 for success.
720 mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func)
722 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
725 MptResetHandlers[cb_idx] = reset_func;
729 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
731 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
732 * @cb_idx: previously registered callback handle
734 * Each protocol-specific driver should call this routine
735 * when it does not (or can no longer) handle IOC reset handling,
736 * or when it's module is unloaded.
739 mpt_reset_deregister(int cb_idx)
741 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
744 MptResetHandlers[cb_idx] = NULL;
747 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
749 * mpt_device_driver_register - Register device driver hooks
752 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
757 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) {
762 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
764 /* call per pci device probe entry point */
765 list_for_each_entry(ioc, &ioc_list, list) {
766 if(dd_cbfunc->probe) {
767 error = dd_cbfunc->probe(ioc->pcidev,
768 ioc->pcidev->driver->id_table);
777 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
779 * mpt_device_driver_deregister - DeRegister device driver hooks
782 mpt_device_driver_deregister(int cb_idx)
784 struct mpt_pci_driver *dd_cbfunc;
787 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
790 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
792 list_for_each_entry(ioc, &ioc_list, list) {
793 if (dd_cbfunc->remove)
794 dd_cbfunc->remove(ioc->pcidev);
797 MptDeviceDriverHandlers[cb_idx] = NULL;
801 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
803 * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
804 * allocated per MPT adapter.
805 * @handle: Handle of registered MPT protocol driver
806 * @iocid: IOC unique identifier (integer)
808 * Returns pointer to a MPT request frame or %NULL if none are available
809 * or IOC is not active.
812 mpt_get_msg_frame(int handle, MPT_ADAPTER *iocp)
819 printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n");
822 /* If interrupts are not attached, do not return a request frame */
826 spin_lock_irqsave(&iocp->FreeQlock, flags);
827 if (! Q_IS_EMPTY(&iocp->FreeQ)) {
830 mf = iocp->FreeQ.head;
831 Q_DEL_ITEM(&mf->u.frame.linkage);
832 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
833 req_offset = (u8 *)mf - (u8 *)iocp->req_frames;
835 mf->u.frame.hwhdr.msgctxu.fld.req_idx =
836 cpu_to_le16(req_offset / iocp->req_sz);
837 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
844 spin_unlock_irqrestore(&iocp->FreeQlock, flags);
848 printk(KERN_WARNING "IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", iocp->mfcnt, iocp->req_depth);
850 if (mfcounter == PRINT_MF_COUNT)
851 printk(KERN_INFO "MF Count 0x%x Max 0x%x \n", iocp->mfcnt, iocp->req_depth);
854 dmfprintk((KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",
855 iocp->name, handle, iocid, mf));
859 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
861 * mpt_put_msg_frame - Send a protocol specific MPT request frame
863 * @handle: Handle of registered MPT protocol driver
864 * @iocid: IOC unique identifier (integer)
865 * @mf: Pointer to MPT request frame
867 * This routine posts a MPT request frame to the request post FIFO of a
868 * specific MPT adapter.
871 mpt_put_msg_frame(int handle, MPT_ADAPTER *iocp, MPT_FRAME_HDR *mf)
876 /* ensure values are reset properly! */
877 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
878 req_offset = (u8 *)mf - (u8 *)iocp->req_frames;
880 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_offset / iocp->req_sz);
881 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
883 #ifdef MPT_DEBUG_MSG_FRAME
885 u32 *m = mf->u.frame.hwhdr.__hdr;
888 printk(KERN_INFO MYNAM ": %s: About to Put msg frame @ %p:\n" KERN_INFO " ",
890 n = iocp->req_sz/4 - 1;
893 for (ii=0; ii<=n; ii++) {
894 if (ii && ((ii%8)==0))
895 printk("\n" KERN_INFO " ");
896 printk(" %08x", le32_to_cpu(m[ii]));
902 mf_dma_addr = iocp->req_frames_low_dma + req_offset;
903 CHIPREG_WRITE32(&iocp->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 * @iocid: IOC unique identifier (integer)
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(int handle, MPT_ADAPTER *iocp, MPT_FRAME_HDR *mf)
921 /* Put Request back on FreeQ! */
922 spin_lock_irqsave(&iocp->FreeQlock, flags);
923 Q_ADD_TAIL(&iocp->FreeQ, &mf->u.frame.linkage, MPT_FRAME_HDR);
927 spin_unlock_irqrestore(&iocp->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 * @iocid: IOC unique identifier (integer)
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 *iocp, 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(iocp,(MPT_FRAME_HDR*)req);
1030 if (reqBytes >= 12 && ii >= 0 && ii < iocp->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(&iocp->chip->IntStatus, 0);
1038 CHIPREG_WRITE32(&iocp->chip->Doorbell,
1039 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1040 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1042 /* Wait for IOC doorbell int */
1043 ii = WaitForDoorbellInt(iocp, 5, sleepFlag);
1047 /* Read doorbell and check for active bit */
1048 if (!(CHIPREG_READ32(&iocp->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1051 dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
1054 CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
1056 r = WaitForDoorbellAck(iocp, 5, sleepFlag);
1060 /* Send request via doorbell handshake */
1061 req_as_bytes = (u8 *) req;
1062 for (ii = 0; ii < reqBytes/4; ii++) {
1065 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1066 (req_as_bytes[(ii*4) + 1] << 8) |
1067 (req_as_bytes[(ii*4) + 2] << 16) |
1068 (req_as_bytes[(ii*4) + 3] << 24));
1069 CHIPREG_WRITE32(&iocp->chip->Doorbell, word);
1070 r = WaitForDoorbellAck(iocp, 5, sleepFlag);
1077 if (r >= 0 && WaitForDoorbellInt(iocp, 10, sleepFlag) >= 0)
1082 /* Make sure there are no doorbells */
1083 CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
1087 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1089 * mpt_verify_adapter - Given a unique IOC identifier, set pointer to
1090 * the associated MPT adapter structure.
1091 * @iocid: IOC unique identifier (integer)
1092 * @iocpp: Pointer to pointer to IOC adapter
1094 * Returns iocid and sets iocpp.
1097 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1101 list_for_each_entry(ioc,&ioc_list,list) {
1102 if (ioc->id == iocid) {
1112 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1114 * mptbase_probe - Install a PCI intelligent MPT adapter.
1115 * @pdev: Pointer to pci_dev structure
1117 * This routine performs all the steps necessary to bring the IOC of
1118 * a MPT adapter to a OPERATIONAL state. This includes registering
1119 * memory regions, registering the interrupt, and allocating request
1120 * and reply memory pools.
1122 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1125 * Returns 0 for success, non-zero for failure.
1127 * TODO: Add support for polled controllers
1129 static int __devinit
1130 mptbase_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1134 unsigned long mem_phys;
1140 u64 mask = 0xffffffffffffffffULL;
1143 static int mpt_ids = 0;
1144 struct proc_dir_entry *dent, *ent;
1146 if (pci_enable_device(pdev))
1149 if (!pci_set_dma_mask(pdev, mask)) {
1150 dprintk((KERN_INFO MYNAM
1151 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1152 } else if (pci_set_dma_mask(pdev, (u64) 0xffffffff)) {
1153 printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1157 if (!pci_set_consistent_dma_mask(pdev, mask))
1158 dprintk((KERN_INFO MYNAM
1159 ": Using 64 bit consistent mask\n"));
1161 dprintk((KERN_INFO MYNAM
1162 ": Not using 64 bit consistent mask\n"));
1164 ioc = kmalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1166 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1169 memset(ioc, 0, sizeof(MPT_ADAPTER));
1170 ioc->alloc_total = sizeof(MPT_ADAPTER);
1171 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1172 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1176 ioc->diagPending = 0;
1177 spin_lock_init(&ioc->diagLock);
1179 /* Initialize the event logging.
1181 ioc->eventTypes = 0; /* None */
1182 ioc->eventContext = 0;
1183 ioc->eventLogSize = 0;
1190 ioc->cached_fw = NULL;
1192 /* Initilize SCSI Config Data structure
1194 memset(&ioc->spi_data, 0, sizeof(ScsiCfgData));
1196 /* Initialize the running configQ head.
1198 Q_INIT(&ioc->configQ, Q_ITEM);
1200 /* Find lookup slot. */
1201 INIT_LIST_HEAD(&ioc->list);
1202 ioc->id = mpt_ids++;
1204 mem_phys = msize = 0;
1206 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1207 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1208 /* Get I/O space! */
1209 port = pci_resource_start(pdev, ii);
1210 psize = pci_resource_len(pdev,ii);
1213 mem_phys = pci_resource_start(pdev, ii);
1214 msize = pci_resource_len(pdev,ii);
1218 ioc->mem_size = msize;
1220 if (ii == DEVICE_COUNT_RESOURCE) {
1221 printk(KERN_ERR MYNAM ": ERROR - MPT adapter has no memory regions defined!\n");
1226 dprintk((KERN_INFO MYNAM ": MPT adapter @ %lx, msize=%dd bytes\n", mem_phys, msize));
1227 dprintk((KERN_INFO MYNAM ": (port i/o @ %lx, psize=%dd bytes)\n", port, psize));
1230 /* Get logical ptr for PciMem0 space */
1231 /*mem = ioremap(mem_phys, msize);*/
1232 mem = ioremap(mem_phys, 0x100);
1234 printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1239 dprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1241 dprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1242 &ioc->facts, &ioc->pfacts[0]));
1244 ioc->mem_phys = mem_phys;
1245 ioc->chip = (SYSIF_REGS*)mem;
1247 /* Save Port IO values incase we need to do downloadboot */
1249 u8 *pmem = (u8*)port;
1250 ioc->pio_mem_phys = port;
1251 ioc->pio_chip = (SYSIF_REGS*)pmem;
1254 ioc->chip_type = FCUNK;
1255 if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC909) {
1256 ioc->chip_type = FC909;
1257 ioc->prod_name = "LSIFC909";
1259 if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
1260 ioc->chip_type = FC929;
1261 ioc->prod_name = "LSIFC929";
1263 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) {
1264 ioc->chip_type = FC919;
1265 ioc->prod_name = "LSIFC919";
1267 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) {
1268 ioc->chip_type = FC929X;
1269 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1270 if (revision < XL_929) {
1271 ioc->prod_name = "LSIFC929X";
1272 /* 929X Chip Fix. Set Split transactions level
1273 * for PCIX. Set MOST bits to zero.
1275 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1277 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1279 ioc->prod_name = "LSIFC929XL";
1280 /* 929XL Chip Fix. Set MMRBC to 0x08.
1282 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1284 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1287 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) {
1288 ioc->chip_type = FC919X;
1289 ioc->prod_name = "LSIFC919X";
1290 /* 919X Chip Fix. Set Split transactions level
1291 * for PCIX. Set MOST bits to zero.
1293 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1295 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1297 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
1298 ioc->chip_type = C1030;
1299 ioc->prod_name = "LSI53C1030";
1300 /* 1030 Chip Fix. Disable Split transactions
1301 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1303 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1304 if (revision < C0_1030) {
1305 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1307 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1310 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
1311 ioc->chip_type = C1035;
1312 ioc->prod_name = "LSI53C1035";
1315 sprintf(ioc->name, "ioc%d", ioc->id);
1317 Q_INIT(&ioc->FreeQ, MPT_FRAME_HDR);
1318 spin_lock_init(&ioc->FreeQlock);
1321 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1323 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1325 /* Set lookup ptr. */
1326 list_add_tail(&ioc->list, &ioc_list);
1330 r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc);
1334 printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %d!\n",
1335 ioc->name, pdev->irq);
1337 printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %s!\n",
1338 ioc->name, __irq_itoa(pdev->irq));
1341 list_del(&ioc->list);
1347 ioc->pci_irq = pdev->irq;
1349 pci_set_master(pdev); /* ?? */
1350 pci_set_drvdata(pdev, ioc);
1353 dprintk((KERN_INFO MYNAM ": %s installed at interrupt %d\n", ioc->name, pdev->irq));
1355 dprintk((KERN_INFO MYNAM ": %s installed at interrupt %s\n", ioc->name, __irq_itoa(pdev->irq)));
1359 /* NEW! 20010220 -sralston
1360 * Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1362 if ((ioc->chip_type == FC929) || (ioc->chip_type == C1030)
1363 || (ioc->chip_type == C1035) || (ioc->chip_type == FC929X))
1364 mpt_detect_bound_ports(ioc, pdev);
1366 if ((r = mpt_do_ioc_recovery(ioc,
1367 MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0) {
1368 printk(KERN_WARNING MYNAM
1369 ": WARNING - %s did not initialize properly! (%d)\n",
1373 list_del(&ioc->list);
1374 free_irq(ioc->pci_irq, ioc);
1377 pci_set_drvdata(pdev, NULL);
1381 /* call per device driver probe entry point */
1382 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1383 if(MptDeviceDriverHandlers[ii] &&
1384 MptDeviceDriverHandlers[ii]->probe) {
1385 MptDeviceDriverHandlers[ii]->probe(pdev,id);
1390 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1392 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1394 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1396 ent->read_proc = procmpt_iocinfo_read;
1399 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1401 ent->read_proc = procmpt_summary_read;
1409 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1411 * mptbase_remove - Remove a PCI intelligent MPT adapter.
1412 * @pdev: Pointer to pci_dev structure
1416 static void __devexit
1417 mptbase_remove(struct pci_dev *pdev)
1419 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1423 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1424 remove_proc_entry(pname, NULL);
1425 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1426 remove_proc_entry(pname, NULL);
1427 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1428 remove_proc_entry(pname, NULL);
1430 /* call per device driver remove entry point */
1431 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1432 if(MptDeviceDriverHandlers[ii] &&
1433 MptDeviceDriverHandlers[ii]->remove) {
1434 MptDeviceDriverHandlers[ii]->remove(pdev);
1438 /* Disable interrupts! */
1439 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1442 synchronize_irq(pdev->irq);
1444 /* Clear any lingering interrupt */
1445 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1447 CHIPREG_READ32(&ioc->chip->IntStatus);
1449 mpt_adapter_dispose(ioc);
1451 pci_set_drvdata(pdev, NULL);
1454 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1456 * mptbase_shutdown -
1460 mptbase_shutdown(struct device * dev)
1464 /* call per device driver shutdown entry point */
1465 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1466 if(MptDeviceDriverHandlers[ii] &&
1467 MptDeviceDriverHandlers[ii]->shutdown) {
1468 MptDeviceDriverHandlers[ii]->shutdown(dev);
1475 /**************************************************************************
1479 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1481 * mptbase_suspend - Fusion MPT base driver suspend routine.
1486 mptbase_suspend(struct pci_dev *pdev, u32 state)
1489 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1495 device_state=1; /* D1 */;
1499 device_state=3; /* D3 */;
1502 return -EAGAIN /*FIXME*/;
1506 printk(MYIOC_s_INFO_FMT
1507 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1508 ioc->name, pdev, pci_name(pdev), device_state);
1510 /* call per device driver suspend entry point */
1511 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1512 if(MptDeviceDriverHandlers[ii] &&
1513 MptDeviceDriverHandlers[ii]->suspend) {
1514 MptDeviceDriverHandlers[ii]->suspend(pdev, state);
1518 pci_save_state(pdev, ioc->PciState);
1520 /* put ioc into READY_STATE */
1521 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1522 printk(MYIOC_s_ERR_FMT
1523 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1526 /* disable interrupts */
1527 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1530 /* Clear any lingering interrupt */
1531 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1533 pci_disable_device(pdev);
1534 pci_set_power_state(pdev, device_state);
1539 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1541 * mptbase_resume - Fusion MPT base driver resume routine.
1546 mptbase_resume(struct pci_dev *pdev)
1548 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1549 u32 device_state = pdev->current_state;
1553 printk(MYIOC_s_INFO_FMT
1554 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1555 ioc->name, pdev, pci_name(pdev), device_state);
1557 pci_set_power_state(pdev, 0);
1558 pci_restore_state(pdev, ioc->PciState);
1559 pci_enable_device(pdev);
1561 /* enable interrupts */
1562 CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
1565 /* F/W not running */
1566 if(!CHIPREG_READ32(&ioc->chip->Doorbell)) {
1567 /* enable domain validation flags */
1568 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
1569 ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_NEED_DV;
1573 printk(MYIOC_s_INFO_FMT
1574 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1576 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1577 CHIPREG_READ32(&ioc->chip->Doorbell));
1579 /* bring ioc to operational state */
1580 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1581 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1582 printk(MYIOC_s_INFO_FMT
1583 "pci-resume: Cannot recover, error:[%x]\n",
1584 ioc->name, recovery_state);
1586 printk(MYIOC_s_INFO_FMT
1587 "pci-resume: success\n", ioc->name);
1590 /* call per device driver resume entry point */
1591 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1592 if(MptDeviceDriverHandlers[ii] &&
1593 MptDeviceDriverHandlers[ii]->resume) {
1594 MptDeviceDriverHandlers[ii]->resume(pdev);
1602 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1604 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1605 * @ioc: Pointer to MPT adapter structure
1606 * @reason: Event word / reason
1607 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1609 * This routine performs all the steps necessary to bring the IOC
1610 * to a OPERATIONAL state.
1612 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1617 * -1 if failed to get board READY
1618 * -2 if READY but IOCFacts Failed
1619 * -3 if READY but PrimeIOCFifos Failed
1620 * -4 if READY but IOCInit Failed
1623 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1625 int hard_reset_done = 0;
1626 int alt_ioc_ready = 0;
1632 int reset_alt_ioc_active = 0;
1634 printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1635 ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1637 /* Disable reply interrupts (also blocks FreeQ) */
1638 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1642 if (ioc->alt_ioc->active)
1643 reset_alt_ioc_active = 1;
1645 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1646 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1647 ioc->alt_ioc->active = 0;
1651 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1654 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1655 if (hard_reset_done == -4) {
1656 printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1659 if (reset_alt_ioc_active && ioc->alt_ioc) {
1660 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1661 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1662 ioc->alt_ioc->name));
1663 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
1664 ioc->alt_ioc->active = 1;
1668 printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1674 /* hard_reset_done = 0 if a soft reset was performed
1675 * and 1 if a hard reset was performed.
1677 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1678 if ((r = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1681 printk(KERN_WARNING MYNAM
1682 ": alt-%s: (%d) Not ready WARNING!\n",
1683 ioc->alt_ioc->name, r);
1686 for (ii=0; ii<5; ii++) {
1687 /* Get IOC facts! Allow 1 retry */
1688 if ((r = GetIocFacts(ioc, sleepFlag, reason)) != 0) {
1689 dinitprintk((MYIOC_s_INFO_FMT
1690 "ii=%d IocFacts failed r=%x\n", ioc->name, ii, r));
1696 dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed r=%x\n", ioc->name, r));
1698 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1699 MptDisplayIocCapabilities(ioc);
1702 if (alt_ioc_ready) {
1703 if ((r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1704 dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed r=%x\n", ioc->name, r));
1705 /* Retry - alt IOC was initialized once
1707 r = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1710 dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed r=%x\n", ioc->name, r));
1712 reset_alt_ioc_active = 0;
1713 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1714 MptDisplayIocCapabilities(ioc->alt_ioc);
1718 /* Prime reply & request queues!
1719 * (mucho alloc's) Must be done prior to
1720 * init as upper addresses are needed for init.
1721 * If fails, continue with alt-ioc processing
1723 if ((ret == 0) && ((r = PrimeIocFifos(ioc)) != 0))
1726 /* May need to check/upload firmware & data here!
1727 * If fails, continue with alt-ioc processing
1729 if ((ret == 0) && ((r = SendIocInit(ioc, sleepFlag)) != 0))
1732 if (alt_ioc_ready && ((r = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
1733 printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1734 ioc->alt_ioc->name, r);
1736 reset_alt_ioc_active = 0;
1739 if (alt_ioc_ready) {
1740 if ((r = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
1742 reset_alt_ioc_active = 0;
1743 printk(KERN_WARNING MYNAM
1744 ": alt-%s: (%d) init failure WARNING!\n",
1745 ioc->alt_ioc->name, r);
1749 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
1750 if (ioc->upload_fw) {
1751 ddlprintk((MYIOC_s_INFO_FMT
1752 "firmware upload required!\n", ioc->name));
1754 /* Controller is not operational, cannot do upload
1757 r = mpt_do_upload(ioc, sleepFlag);
1759 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
1762 /* Handle the alt IOC too */
1763 if ((alt_ioc_ready) && (ioc->alt_ioc->upload_fw)){
1764 ddlprintk((MYIOC_s_INFO_FMT
1765 "Alt-ioc firmware upload required!\n",
1767 r = mpt_do_upload(ioc->alt_ioc, sleepFlag);
1769 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
1775 /* Enable! (reply interrupt) */
1776 CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
1780 if (reset_alt_ioc_active && ioc->alt_ioc) {
1781 /* (re)Enable alt-IOC! (reply interrupt) */
1782 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1783 ioc->alt_ioc->name));
1784 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
1785 ioc->alt_ioc->active = 1;
1788 /* NEW! 20010120 -sralston
1789 * Enable MPT base driver management of EventNotification
1790 * and EventAck handling.
1792 if ((ret == 0) && (!ioc->facts.EventState))
1793 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
1795 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
1796 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
1798 /* (Bugzilla:fibrebugs, #513)
1799 * Bug fix (part 2)! 20010905 -sralston
1800 * Add additional "reason" check before call to GetLanConfigPages
1801 * (combined with GetIoUnitPage2 call). This prevents a somewhat
1802 * recursive scenario; GetLanConfigPages times out, timer expired
1803 * routine calls HardResetHandler, which calls into here again,
1804 * and we try GetLanConfigPages again...
1806 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1807 if ((int)ioc->chip_type <= (int)FC929) {
1809 * Pre-fetch FC port WWN and stuff...
1810 * (FCPortPage0_t stuff)
1812 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1813 (void) GetFcPortPage0(ioc, ii);
1816 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
1817 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
1819 * Pre-fetch the ports LAN MAC address!
1820 * (LANPage1_t stuff)
1822 (void) GetLanConfigPages(ioc);
1825 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
1826 dprintk((MYIOC_s_INFO_FMT "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
1827 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0] ));
1832 /* Get NVRAM and adapter maximums from SPP 0 and 2
1834 mpt_GetScsiPortSettings(ioc, 0);
1836 /* Get version and length of SDP 1
1838 mpt_readScsiDevicePageHeaders(ioc, 0);
1842 if (ioc->facts.MsgVersion >= 0x0102)
1843 mpt_findImVolumes(ioc);
1845 /* Check, and possibly reset, the coalescing value
1847 mpt_read_ioc_pg_1(ioc);
1849 mpt_read_ioc_pg_4(ioc);
1852 GetIoUnitPage2(ioc);
1856 * Call each currently registered protocol IOC reset handler
1857 * with post-reset indication.
1858 * NOTE: If we're doing _IOC_BRINGUP, there can be no
1859 * MptResetHandlers[] registered yet.
1861 if (hard_reset_done) {
1863 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
1864 if ((ret == 0) && MptResetHandlers[ii]) {
1865 dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
1867 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET);
1871 if (alt_ioc_ready && MptResetHandlers[ii]) {
1872 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
1873 ioc->name, ioc->alt_ioc->name, ii));
1874 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
1878 /* FIXME? Examine results here? */
1884 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1886 * mpt_detect_bound_ports - Search for PCI bus/dev_function
1887 * which matches PCI bus/dev_function (+/-1) for newly discovered 929,
1888 * 929X, 1030 or 1035.
1889 * @ioc: Pointer to MPT adapter structure
1890 * @pdev: Pointer to (struct pci_dev) structure
1892 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
1893 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
1896 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
1898 unsigned int match_lo, match_hi;
1899 MPT_ADAPTER *ioc_srch;
1901 match_lo = pdev->devfn-1;
1902 match_hi = pdev->devfn+1;
1903 dprintk((MYIOC_s_INFO_FMT "PCI bus/devfn=%x/%x, searching for devfn match on %x or %x\n",
1904 ioc->name, pdev->bus->number, pdev->devfn, match_lo, match_hi));
1906 list_for_each_entry(ioc_srch, &ioc_list, list) {
1907 struct pci_dev *_pcidev = ioc_srch->pcidev;
1909 if ((_pcidev->device == pdev->device) &&
1910 (_pcidev->bus->number == pdev->bus->number) &&
1911 (_pcidev->devfn == match_lo || _pcidev->devfn == match_hi) ) {
1912 /* Paranoia checks */
1913 if (ioc->alt_ioc != NULL) {
1914 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1915 ioc->name, ioc->alt_ioc->name);
1917 } else if (ioc_srch->alt_ioc != NULL) {
1918 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1919 ioc_srch->name, ioc_srch->alt_ioc->name);
1922 dprintk((KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
1923 ioc->name, ioc_srch->name));
1924 ioc_srch->alt_ioc = ioc;
1925 ioc->alt_ioc = ioc_srch;
1931 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1933 * mpt_adapter_disable - Disable misbehaving MPT adapter.
1934 * @this: Pointer to MPT adapter structure
1935 * @free: Free up alloc'd reply, request, etc.
1938 mpt_adapter_disable(MPT_ADAPTER *this, int freeup)
1944 if (this->cached_fw != NULL) {
1945 ddlprintk((KERN_INFO MYNAM ": Pushing FW onto adapter\n"));
1947 if ((ret = mpt_downloadboot(this, NO_SLEEP)) < 0) {
1948 printk(KERN_WARNING MYNAM
1949 ": firmware downloadboot failure (%d)!\n", ret);
1953 /* Disable adapter interrupts! */
1954 CHIPREG_WRITE32(&this->chip->IntMask, 0xFFFFFFFF);
1956 /* Clear any lingering interrupt */
1957 CHIPREG_WRITE32(&this->chip->IntStatus, 0);
1959 if (freeup && this->fifo_pool != NULL) {
1960 pci_free_consistent(this->pcidev,
1962 this->fifo_pool, this->fifo_pool_dma);
1963 this->reply_frames = NULL;
1964 this->reply_alloc = NULL;
1965 this->req_frames = NULL;
1966 this->req_alloc = NULL;
1967 this->chain_alloc = NULL;
1968 this->fifo_pool = NULL;
1969 this->alloc_total -= this->fifo_pool_sz;
1971 if (freeup && this->sense_buf_pool != NULL) {
1972 sz = (this->req_depth * MPT_SENSE_BUFFER_ALLOC);
1973 pci_free_consistent(this->pcidev, sz,
1974 this->sense_buf_pool, this->sense_buf_pool_dma);
1975 this->sense_buf_pool = NULL;
1976 this->alloc_total -= sz;
1979 if (freeup && this->events != NULL){
1980 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
1981 kfree(this->events);
1982 this->events = NULL;
1983 this->alloc_total -= sz;
1986 if (freeup && this->cached_fw != NULL) {
1988 sz = this->facts.FWImageSize;
1989 pci_free_consistent(this->pcidev, sz,
1990 this->cached_fw, this->cached_fw_dma);
1991 this->cached_fw = NULL;
1992 this->alloc_total -= sz;
1995 if (freeup && this->spi_data.nvram != NULL) {
1996 kfree(this->spi_data.nvram);
1997 this->spi_data.nvram = NULL;
2000 if (freeup && this->spi_data.pIocPg3 != NULL) {
2001 kfree(this->spi_data.pIocPg3);
2002 this->spi_data.pIocPg3 = NULL;
2005 if (freeup && this->spi_data.pIocPg4 != NULL) {
2006 sz = this->spi_data.IocPg4Sz;
2007 pci_free_consistent(this->pcidev, sz,
2008 this->spi_data.pIocPg4,
2009 this->spi_data.IocPg4_dma);
2010 this->spi_data.pIocPg4 = NULL;
2011 this->alloc_total -= sz;
2016 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2018 * mpt_adapter_dispose - Free all resources associated with a MPT
2020 * @this: Pointer to MPT adapter structure
2022 * This routine unregisters h/w resources and frees all alloc'd memory
2023 * associated with a MPT adapter structure.
2026 mpt_adapter_dispose(MPT_ADAPTER *this)
2029 int sz_first, sz_last;
2031 sz_first = this->alloc_total;
2033 mpt_adapter_disable(this, 1);
2035 if (this->pci_irq != -1) {
2036 free_irq(this->pci_irq, this);
2040 if (this->memmap != NULL)
2041 iounmap((u8 *) this->memmap);
2043 #if defined(CONFIG_MTRR) && 0
2044 if (this->mtrr_reg > 0) {
2045 mtrr_del(this->mtrr_reg, 0, 0);
2046 dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", this->name));
2050 /* Zap the adapter lookup ptr! */
2051 list_del(&this->list);
2053 sz_last = this->alloc_total;
2054 dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
2055 this->name, sz_first-sz_last+(int)sizeof(*this), sz_first));
2060 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2062 * MptDisplayIocCapabilities - Disply IOC's capacilities.
2063 * @ioc: Pointer to MPT adapter structure
2066 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2070 printk(KERN_INFO "%s: ", ioc->name);
2071 if (ioc->prod_name && strlen(ioc->prod_name) > 3)
2072 printk("%s: ", ioc->prod_name+3);
2073 printk("Capabilities={");
2075 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2076 printk("Initiator");
2080 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2081 printk("%sTarget", i ? "," : "");
2085 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2086 printk("%sLAN", i ? "," : "");
2092 * This would probably evoke more questions than it's worth
2094 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2095 printk("%sLogBusAddr", i ? "," : "");
2103 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2105 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2106 * @ioc: Pointer to MPT_ADAPTER structure
2107 * @force: Force hard KickStart of IOC
2108 * @sleepFlag: Specifies whether the process can sleep
2111 * 1 - DIAG reset and READY
2112 * 0 - READY initially OR soft reset and READY
2113 * -1 - Any failure on KickStart
2114 * -2 - Msg Unit Reset Failed
2115 * -3 - IO Unit Reset Failed
2116 * -4 - IOC owned by a PEER
2119 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2124 int hard_reset_done = 0;
2129 /* Get current [raw] IOC state */
2130 ioc_state = mpt_GetIocState(ioc, 0);
2131 dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
2134 * Check to see if IOC got left/stuck in doorbell handshake
2135 * grip of death. If so, hard reset the IOC.
2137 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2139 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2143 /* Is it already READY? */
2144 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY) {
2145 if ((int)ioc->chip_type <= (int)FC929)
2149 /* Workaround from broken 1030 FW.
2150 * Force a diagnostic reset if fails.
2152 /* if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2160 * Check to see if IOC is in FAULT state.
2162 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2164 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2166 printk(KERN_WARNING " FAULT code = %04xh\n",
2167 ioc_state & MPI_DOORBELL_DATA_MASK);
2171 * Hmmm... Did it get left operational?
2173 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2174 dinitprintk((MYIOC_s_WARN_FMT "IOC operational unexpected\n",
2178 * If PCI Peer, exit.
2179 * Else, if no fault conditions are present, issue a MessageUnitReset
2180 * Else, fall through to KickStart case
2182 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2183 dprintk((KERN_WARNING MYNAM
2184 ": whoinit 0x%x\n statefault %d force %d\n",
2185 whoinit, statefault, force));
2186 if (whoinit == MPI_WHOINIT_PCI_PEER)
2189 if ((statefault == 0 ) && (force == 0)) {
2190 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2197 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2198 if (hard_reset_done < 0)
2202 * Loop here waiting for IOC to come READY.
2205 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
2207 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2208 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2210 * BIOS or previous driver load left IOC in OP state.
2211 * Reset messaging FIFOs.
2213 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2214 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2217 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2219 * Something is wrong. Try to get IOC back
2222 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2223 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2230 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2231 ioc->name, (ii+5)/HZ);
2235 if (sleepFlag == CAN_SLEEP) {
2236 set_current_state(TASK_INTERRUPTIBLE);
2237 schedule_timeout(1);
2239 mdelay (1); /* 1 msec delay */
2244 if (statefault < 3) {
2245 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2247 statefault==1 ? "stuck handshake" : "IOC FAULT");
2250 return hard_reset_done;
2253 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2255 * mpt_GetIocState - Get the current state of a MPT adapter.
2256 * @ioc: Pointer to MPT_ADAPTER structure
2257 * @cooked: Request raw or cooked IOC state
2259 * Returns all IOC Doorbell register bits if cooked==0, else just the
2260 * Doorbell bits in MPI_IOC_STATE_MASK.
2263 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2268 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2269 // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2270 sc = s & MPI_IOC_STATE_MASK;
2273 ioc->last_state = sc;
2275 return cooked ? sc : s;
2278 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2280 * GetIocFacts - Send IOCFacts request to MPT adapter.
2281 * @ioc: Pointer to MPT_ADAPTER structure
2282 * @sleepFlag: Specifies whether the process can sleep
2283 * @reason: If recovery, only update facts.
2285 * Returns 0 for success, non-zero for failure.
2288 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2290 IOCFacts_t get_facts;
2291 IOCFactsReply_t *facts;
2297 /* IOC *must* NOT be in RESET state! */
2298 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2299 printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2305 facts = &ioc->facts;
2307 /* Destination (reply area)... */
2308 reply_sz = sizeof(*facts);
2309 memset(facts, 0, reply_sz);
2311 /* Request area (get_facts on the stack right now!) */
2312 req_sz = sizeof(get_facts);
2313 memset(&get_facts, 0, req_sz);
2315 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2316 /* Assert: All other get_facts fields are zero! */
2318 dinitprintk((MYIOC_s_INFO_FMT "Sending get IocFacts request\n", ioc->name));
2320 /* No non-zero fields in the get_facts request are greater than
2321 * 1 byte in size, so we can just fire it off as is.
2323 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2324 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2329 * Now byte swap (GRRR) the necessary fields before any further
2330 * inspection of reply contents.
2332 * But need to do some sanity checks on MsgLength (byte) field
2333 * to make sure we don't zero IOC's req_sz!
2335 /* Did we get a valid reply? */
2336 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2337 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2339 * If not been here, done that, save off first WhoInit value
2341 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2342 ioc->FirstWhoInit = facts->WhoInit;
2345 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2346 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2347 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2348 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2349 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2350 status = facts->IOCStatus & MPI_IOCSTATUS_MASK;
2351 /* CHECKME! IOCStatus, IOCLogInfo */
2353 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2354 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2357 * FC f/w version changed between 1.1 and 1.2
2358 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2359 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2361 if (facts->MsgVersion < 0x0102) {
2363 * Handle old FC f/w style, convert to new...
2365 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2366 facts->FWVersion.Word =
2367 ((oldv<<12) & 0xFF000000) |
2368 ((oldv<<8) & 0x000FFF00);
2370 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2372 facts->ProductID = le16_to_cpu(facts->ProductID);
2373 facts->CurrentHostMfaHighAddr =
2374 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2375 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2376 facts->CurrentSenseBufferHighAddr =
2377 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2378 facts->CurReplyFrameSize =
2379 le16_to_cpu(facts->CurReplyFrameSize);
2382 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2383 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2384 * to 14 in MPI-1.01.0x.
2386 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2387 facts->MsgVersion > 0x0100) {
2388 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2391 if (!facts->RequestFrameSize) {
2392 /* Something is wrong! */
2393 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2398 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2400 * Set values for this IOC's request & reply frame sizes,
2401 * and request & reply queue depths...
2403 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2404 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2405 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2406 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2408 dprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
2409 ioc->name, ioc->reply_sz, ioc->reply_depth));
2410 dprintk((MYIOC_s_INFO_FMT "req_sz =%3d, req_depth =%4d\n",
2411 ioc->name, ioc->req_sz, ioc->req_depth));
2413 /* Get port facts! */
2414 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2418 printk(MYIOC_s_ERR_FMT
2419 "Invalid IOC facts reply, msgLength=%d offsetof=%d!\n",
2420 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2421 RequestFrameSize)/sizeof(u32)));
2428 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2430 * GetPortFacts - Send PortFacts request to MPT adapter.
2431 * @ioc: Pointer to MPT_ADAPTER structure
2432 * @portnum: Port number
2433 * @sleepFlag: Specifies whether the process can sleep
2435 * Returns 0 for success, non-zero for failure.
2438 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2440 PortFacts_t get_pfacts;
2441 PortFactsReply_t *pfacts;
2446 /* IOC *must* NOT be in RESET state! */
2447 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2448 printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2454 pfacts = &ioc->pfacts[portnum];
2456 /* Destination (reply area)... */
2457 reply_sz = sizeof(*pfacts);
2458 memset(pfacts, 0, reply_sz);
2460 /* Request area (get_pfacts on the stack right now!) */
2461 req_sz = sizeof(get_pfacts);
2462 memset(&get_pfacts, 0, req_sz);
2464 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2465 get_pfacts.PortNumber = portnum;
2466 /* Assert: All other get_pfacts fields are zero! */
2468 dprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
2469 ioc->name, portnum));
2471 /* No non-zero fields in the get_pfacts request are greater than
2472 * 1 byte in size, so we can just fire it off as is.
2474 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2475 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2479 /* Did we get a valid reply? */
2481 /* Now byte swap the necessary fields in the response. */
2482 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2483 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2484 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2485 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2486 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2487 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2488 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2489 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2490 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2495 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2497 * SendIocInit - Send IOCInit request to MPT adapter.
2498 * @ioc: Pointer to MPT_ADAPTER structure
2499 * @sleepFlag: Specifies whether the process can sleep
2501 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2503 * Returns 0 for success, non-zero for failure.
2506 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2509 MPIDefaultReply_t init_reply;
2515 memset(&ioc_init, 0, sizeof(ioc_init));
2516 memset(&init_reply, 0, sizeof(init_reply));
2518 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2519 /* ioc_init.ChainOffset = 0; */
2520 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2521 /* ioc_init.Flags = 0; */
2523 /* If we are in a recovery mode and we uploaded the FW image,
2524 * then this pointer is not NULL. Skip the upload a second time.
2525 * Set this flag if cached_fw set for either IOC.
2529 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) {
2530 if ((ioc->cached_fw) || (ioc->alt_ioc && ioc->alt_ioc->cached_fw))
2531 ioc_init.Flags = MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE;
2535 ddlprintk((MYIOC_s_INFO_FMT "flags %d, upload_fw %d \n",
2536 ioc->name, ioc_init.Flags, ioc->upload_fw));
2538 if ((int)ioc->chip_type <= (int)FC929) {
2539 ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
2541 ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
2543 ioc_init.MaxBuses = MPT_MAX_BUS;
2545 /* ioc_init.MsgFlags = 0; */
2546 /* ioc_init.MsgContext = cpu_to_le32(0x00000000); */
2547 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2549 ioc->facts.RequestFrameSize = ioc_init.ReplyFrameSize;
2551 if (sizeof(dma_addr_t) == sizeof(u64)) {
2552 /* Save the upper 32-bits of the request
2553 * (reply) and sense buffers.
2555 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->req_frames_dma >> 32));
2556 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2558 /* Force 32-bit addressing */
2559 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2560 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2563 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2564 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2566 dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
2567 ioc->name, &ioc_init));
2569 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2570 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2574 /* No need to byte swap the multibyte fields in the reply
2575 * since we don't even look at it's contents.
2578 dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
2579 ioc->name, &ioc_init));
2581 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0)
2584 /* YIKES! SUPER IMPORTANT!!!
2585 * Poll IocState until _OPERATIONAL while IOC is doing
2586 * LoopInit and TargetDiscovery!
2589 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2590 state = mpt_GetIocState(ioc, 1);
2591 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2592 if (sleepFlag == CAN_SLEEP) {
2593 set_current_state(TASK_INTERRUPTIBLE);
2594 schedule_timeout(1);
2600 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2601 ioc->name, (count+5)/HZ);
2605 state = mpt_GetIocState(ioc, 1);
2608 dhsprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2614 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2616 * SendPortEnable - Send PortEnable request to MPT adapter port.
2617 * @ioc: Pointer to MPT_ADAPTER structure
2618 * @portnum: Port number to enable
2619 * @sleepFlag: Specifies whether the process can sleep
2621 * Send PortEnable to bring IOC to OPERATIONAL state.
2623 * Returns 0 for success, non-zero for failure.
2626 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2628 PortEnable_t port_enable;
2629 MPIDefaultReply_t reply_buf;
2634 /* Destination... */
2635 reply_sz = sizeof(MPIDefaultReply_t);
2636 memset(&reply_buf, 0, reply_sz);
2638 req_sz = sizeof(PortEnable_t);
2639 memset(&port_enable, 0, req_sz);
2641 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2642 port_enable.PortNumber = portnum;
2643 /* port_enable.ChainOffset = 0; */
2644 /* port_enable.MsgFlags = 0; */
2645 /* port_enable.MsgContext = 0; */
2647 dprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
2648 ioc->name, portnum, &port_enable));
2650 /* RAID FW may take a long time to enable
2652 if ((int)ioc->chip_type <= (int)FC929) {
2653 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2654 reply_sz, (u16*)&reply_buf, 65 /*seconds*/, sleepFlag);
2656 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2657 reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag);
2663 /* We do not even look at the reply, so we need not
2664 * swap the multi-byte fields.
2671 * Inputs: size - total FW bytes
2672 * Outputs: frags - number of fragments needed
2673 * Return NULL if failed.
2676 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
2681 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
2682 ioc->alloc_total += size;
2686 * If alt_img is NULL, delete from ioc structure.
2687 * Else, delete a secondary image in same format.
2690 mpt_free_fw_memory(MPT_ADAPTER *ioc)
2694 sz = ioc->facts.FWImageSize;
2695 pci_free_consistent(ioc->pcidev, sz,
2696 ioc->cached_fw, ioc->cached_fw_dma);
2697 ioc->cached_fw = NULL;
2703 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2705 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
2706 * @ioc: Pointer to MPT_ADAPTER structure
2707 * @sleepFlag: Specifies whether the process can sleep
2709 * Returns 0 for success, >0 for handshake failure
2710 * <0 for fw upload failure.
2712 * Remark: If bound IOC and a successful FWUpload was performed
2713 * on the bound IOC, the second image is discarded
2714 * and memory is free'd. Both channels must upload to prevent
2715 * IOC from running in degraded mode.
2718 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2720 u8 request[ioc->req_sz];
2721 u8 reply[sizeof(FWUploadReply_t)];
2722 FWUpload_t *prequest;
2723 FWUploadReply_t *preply;
2724 FWUploadTCSGE_t *ptcsge;
2727 int ii, sz, reply_sz;
2728 int cmdStatus, freeMem = 0;
2730 /* If the image size is 0 or if the pointer is
2731 * not NULL (error), we are done.
2733 if (((sz = ioc->facts.FWImageSize) == 0) || ioc->cached_fw)
2741 mpt_alloc_fw_memory(ioc, sz);
2743 if (ioc->cached_fw == NULL) {
2749 dinitprintk((KERN_WARNING MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
2750 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2752 prequest = (FWUpload_t *)&request;
2753 preply = (FWUploadReply_t *)&reply;
2755 /* Destination... */
2756 memset(prequest, 0, ioc->req_sz);
2758 reply_sz = sizeof(reply);
2759 memset(preply, 0, reply_sz);
2761 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
2762 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
2764 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
2765 ptcsge->DetailsLength = 12;
2766 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
2767 ptcsge->ImageSize = cpu_to_le32(sz);
2769 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
2771 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
2772 mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
2774 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
2775 dinitprintk((KERN_WARNING MYNAM "Sending FW Upload (req @ %p) sgeoffset=%d \n",
2776 prequest, sgeoffset));
2777 DBG_DUMP_FW_REQUEST_FRAME(prequest)
2779 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
2780 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
2782 dinitprintk((KERN_WARNING MYNAM "FW Upload completed rc=%x \n", ii));
2784 cmdStatus = -EFAULT;
2786 /* Handshake transfer was complete and successful.
2787 * Check the Reply Frame.
2789 int status, transfer_sz;
2790 status = le16_to_cpu(preply->IOCStatus);
2791 if (status == MPI_IOCSTATUS_SUCCESS) {
2792 transfer_sz = le32_to_cpu(preply->ActualImageSize);
2793 if (transfer_sz == sz)
2797 dinitprintk((MYIOC_s_INFO_FMT ": do_upload status %d \n",
2798 ioc->name, cmdStatus));
2800 /* Check to see if we have a copy of this image in
2801 * host memory already.
2803 if (cmdStatus == 0) {
2805 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
2809 /* We already have a copy of this image or
2810 * we had some type of an error - either the handshake
2811 * failed (i != 0) or the command did not complete successfully.
2813 if (cmdStatus || freeMem) {
2815 ddlprintk((MYIOC_s_INFO_FMT ": do_upload freeing %s image \n",
2816 ioc->name, cmdStatus ? "incomplete" : "duplicate"));
2817 mpt_free_fw_memory(ioc);
2823 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2825 * mpt_downloadboot - DownloadBoot code
2826 * @ioc: Pointer to MPT_ADAPTER structure
2827 * @flag: Specify which part of IOC memory is to be uploaded.
2828 * @sleepFlag: Specifies whether the process can sleep
2830 * FwDownloadBoot requires Programmed IO access.
2832 * Returns 0 for success
2833 * -1 FW Image size is 0
2834 * -2 No valid cached_fw Pointer
2835 * <0 for fw upload failure.
2838 mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
2840 MpiFwHeader_t *pFwHeader;
2841 MpiExtImageHeader_t *pExtImage;
2854 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x, ioc FW Ptr %p\n",
2855 ioc->name, ioc->facts.FWImageSize, ioc->cached_fw));
2857 /* Get dma_addr and data transfer size.
2859 if ( ioc->facts.FWImageSize == 0 )
2862 /* Get the DMA from ioc or ioc->alt_ioc */
2863 if (ioc->cached_fw == NULL)
2866 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2867 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2868 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2869 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2870 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2871 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2873 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2874 diag0val |= (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM);
2875 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
2878 if (sleepFlag == CAN_SLEEP) {
2879 set_current_state(TASK_INTERRUPTIBLE);
2880 schedule_timeout(100 * HZ / 1000);
2885 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2887 for (count = 0; count < 30; count ++) {
2888 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2889 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
2890 ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
2895 if (sleepFlag == CAN_SLEEP) {
2896 set_current_state(TASK_INTERRUPTIBLE);
2897 schedule_timeout(HZ);
2903 if ( count == 30 ) {
2904 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! Unable to RESET_ADAPTER diag0val=%x\n",
2905 ioc->name, diag0val));
2909 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2910 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2911 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2912 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2913 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2914 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2916 /* Set the DiagRwEn and Disable ARM bits */
2917 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2918 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (diag0val | MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
2920 pFwHeader = (MpiFwHeader_t *) ioc->cached_fw;
2921 fwSize = (pFwHeader->ImageSize + 3)/4;
2922 ptrFw = (u32 *) pFwHeader;
2924 /* Write the LoadStartAddress to the DiagRw Address Register
2925 * using Programmed IO
2927 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
2928 ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
2929 ioc->name, pFwHeader->LoadStartAddress));
2931 ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n",
2932 ioc->name, fwSize*4, ptrFw));
2934 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2937 nextImage = pFwHeader->NextImageHeaderOffset;
2939 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
2941 load_addr = pExtImage->LoadStartAddress;
2943 fwSize = (pExtImage->ImageSize + 3) >> 2;
2944 ptrFw = (u32 *)pExtImage;
2946 ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x bytes @ %p load_addr=%x\n",
2947 ioc->name, fwSize*4, ptrFw, load_addr));
2948 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
2951 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2953 nextImage = pExtImage->NextImageHeaderOffset;
2956 /* Write the IopResetVectorRegAddr */
2957 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
2958 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
2960 /* Write the IopResetVectorValue */
2961 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
2962 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
2964 /* clear the PREVENT_IOC_BOOT bit */
2965 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2966 ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, turning off PREVENT_IOC_BOOT\n",
2967 ioc->name, diag0val));
2968 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT);
2969 ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
2970 ioc->name, diag0val));
2971 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
2973 /* Clear the internal flash bad bit - autoincrementing register,
2974 * so must do two writes.
2976 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
2977 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
2978 diagRwData |= 0x4000000;
2979 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
2980 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
2982 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2983 ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, turning off DISABLE_ARM, RW_ENABLE, RESET_HISTORY\n",
2984 ioc->name, diag0val));
2985 diag0val &= ~(MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE | MPI_DIAG_RESET_HISTORY);
2986 ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
2987 ioc->name, diag0val));
2988 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
2991 if (sleepFlag == CAN_SLEEP) {
2992 ddlprintk((MYIOC_s_INFO_FMT "CAN_SLEEP 100 msec before reset the sequencer\n", ioc->name));
2993 set_current_state(TASK_INTERRUPTIBLE);
2994 schedule_timeout(100 * HZ / 1000);
2996 ddlprintk((MYIOC_s_INFO_FMT "mdelay 100 msec before reset the sequencer\n", ioc->name));
3000 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3001 if ( diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_DISABLE_ARM) ) {
3002 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed, diag0val=%x FLASH_BAD_SIG | DISABLE_ARM on\n ",
3003 ioc->name, diag0val));
3005 /* Write 0xFF to reset the sequencer */
3006 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3008 for (count=0; count<HZ*20; count++) {
3009 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3010 ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
3011 ioc->name, count, ioc_state));
3012 /* if ((r = GetIocFacts(ioc, sleepFlag, MPT_HOSTEVENT_IOC_BRINGUP)) != 0) {
3013 if ((r = GetIocFacts(ioc, sleepFlag, MPT_HOSTEVENT_IOC_BRINGUP)) != 0) {
3014 ddlprintk((MYIOC_s_INFO_FMT "GetIocFacts failed\n",
3020 /* if (sleepFlag == CAN_SLEEP) {
3021 set_current_state(TASK_INTERRUPTIBLE);
3022 schedule_timeout(5000 * HZ / 1000);
3029 if (sleepFlag == CAN_SLEEP) {
3030 set_current_state(TASK_INTERRUPTIBLE);
3031 schedule_timeout(1);
3036 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! IocState=%x\n",
3037 ioc->name, ioc_state));
3041 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3043 * KickStart - Perform hard reset of MPT adapter.
3044 * @ioc: Pointer to MPT_ADAPTER structure
3045 * @force: Force hard reset
3046 * @sleepFlag: Specifies whether the process can sleep
3048 * This routine places MPT adapter in diagnostic mode via the
3049 * WriteSequence register, and then performs a hard reset of adapter
3050 * via the Diagnostic register.
3052 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3053 * or NO_SLEEP (interrupt thread, use mdelay)
3054 * force - 1 if doorbell active, board fault state
3055 * board operational, IOC_RECOVERY or
3056 * IOC_BRINGUP and there is an alt_ioc.
3060 * 1 - hard reset, READY
3061 * 0 - no reset due to History bit, READY
3062 * -1 - no reset due to History bit but not READY
3063 * OR reset but failed to come READY
3064 * -2 - no reset, could not enter DIAG mode
3065 * -3 - reset but bad FW bit
3068 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3070 int hard_reset_done = 0;
3074 dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
3075 if ((int)ioc->chip_type > (int)FC929) {
3076 /* Always issue a Msg Unit Reset first. This will clear some
3077 * SCSI bus hang conditions.
3079 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3081 if (sleepFlag == CAN_SLEEP) {
3082 set_current_state(TASK_INTERRUPTIBLE);
3083 schedule_timeout(HZ);
3089 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3090 if (hard_reset_done < 0)
3091 return hard_reset_done;
3093 dprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
3096 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 20; /* 20 seconds */
3097 for (cnt=0; cnt<cntdn; cnt++) {
3098 if ((ioc_state = mpt_GetIocState(ioc, 1)) == MPI_IOC_STATE_READY) {
3099 dprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
3101 return hard_reset_done;
3103 if (sleepFlag == CAN_SLEEP) {
3104 set_current_state(TASK_INTERRUPTIBLE);
3105 schedule_timeout(1);
3111 printk(MYIOC_s_ERR_FMT "Failed to come READY after reset!\n",
3116 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3118 * mpt_diag_reset - Perform hard reset of the adapter.
3119 * @ioc: Pointer to MPT_ADAPTER structure
3120 * @ignore: Set if to honor and clear to ignore
3121 * the reset history bit
3122 * @sleepflag: CAN_SLEEP if called in a non-interrupt thread,
3123 * else set to NO_SLEEP (use mdelay instead)
3125 * This routine places the adapter in diagnostic mode via the
3126 * WriteSequence register and then performs a hard reset of adapter
3127 * via the Diagnostic register. Adapter should be in ready state
3128 * upon successful completion.
3130 * Returns: 1 hard reset successful
3131 * 0 no reset performed because reset history bit set
3132 * -2 enabling diagnostic mode failed
3133 * -3 diagnostic reset failed
3136 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3140 int hard_reset_done = 0;
3146 /* Clear any existing interrupts */
3147 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3149 /* Use "Diagnostic reset" method! (only thing available!) */
3150 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3154 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3155 dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3156 ioc->name, diag0val, diag1val));
3159 /* Do the reset if we are told to ignore the reset history
3160 * or if the reset history is 0
3162 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3163 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3164 /* Write magic sequence to WriteSequence register
3165 * Loop until in diagnostic mode
3167 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3168 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3169 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3170 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3171 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3172 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3175 if (sleepFlag == CAN_SLEEP) {
3176 set_current_state(TASK_INTERRUPTIBLE);
3177 schedule_timeout(100 * HZ / 1000);
3184 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3185 ioc->name, diag0val);
3190 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3192 dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3193 ioc->name, diag0val));
3198 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3199 dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3200 ioc->name, diag0val, diag1val));
3202 /* Write the PreventIocBoot bit */
3203 if ((ioc->cached_fw) || (ioc->alt_ioc && ioc->alt_ioc->cached_fw)) {
3204 diag0val |= MPI_DIAG_PREVENT_IOC_BOOT;
3205 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3209 * Disable the ARM (Bug fix)
3212 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3216 * Now hit the reset bit in the Diagnostic register
3217 * (THE BIG HAMMER!) (Clears DRWE bit).
3219 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3220 hard_reset_done = 1;
3221 dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
3225 * Call each currently registered protocol IOC reset handler
3226 * with pre-reset indication.
3227 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3228 * MptResetHandlers[] registered yet.
3234 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
3235 if (MptResetHandlers[ii]) {
3236 dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
3238 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_PRE_RESET);
3240 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3241 ioc->name, ioc->alt_ioc->name, ii));
3242 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_PRE_RESET);
3246 /* FIXME? Examine results here? */
3249 if ((ioc->cached_fw) || (ioc->alt_ioc && ioc->alt_ioc->cached_fw)) {
3250 /* If the DownloadBoot operation fails, the
3251 * IOC will be left unusable. This is a fatal error
3252 * case. _diag_reset will return < 0
3254 for (count = 0; count < 30; count ++) {
3255 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3258 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3259 dprintk((MYIOC_s_INFO_FMT
3260 "DbG2b: diag0=%08x, diag1=%08x\n",
3261 ioc->name, diag0val, diag1val));
3263 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3268 if (sleepFlag == CAN_SLEEP) {
3269 set_current_state(TASK_INTERRUPTIBLE);
3270 schedule_timeout(HZ);
3275 if ((count = mpt_downloadboot(ioc, sleepFlag)) < 0) {
3276 printk(KERN_WARNING MYNAM
3277 ": firmware downloadboot failure (%d)!\n", count);
3281 /* Wait for FW to reload and for board
3282 * to go to the READY state.
3283 * Maximum wait is 60 seconds.
3284 * If fail, no error will check again
3285 * with calling program.
3287 for (count = 0; count < 60; count ++) {
3288 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3289 doorbell &= MPI_IOC_STATE_MASK;
3291 if (doorbell == MPI_IOC_STATE_READY) {
3296 if (sleepFlag == CAN_SLEEP) {
3297 set_current_state(TASK_INTERRUPTIBLE);
3298 schedule_timeout(HZ);
3306 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3309 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3310 dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3311 ioc->name, diag0val, diag1val));
3314 /* Clear RESET_HISTORY bit! Place board in the
3315 * diagnostic mode to update the diag register.
3317 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3319 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3320 /* Write magic sequence to WriteSequence register
3321 * Loop until in diagnostic mode
3323 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3324 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3325 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3326 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3327 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3328 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3331 if (sleepFlag == CAN_SLEEP) {
3332 set_current_state(TASK_INTERRUPTIBLE);
3333 schedule_timeout(100 * HZ / 1000);
3340 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3341 ioc->name, diag0val);
3344 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3346 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3347 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3348 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3349 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3350 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3354 /* Disable Diagnostic Mode
3356 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3358 /* Check FW reload status flags.
3360 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3361 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3362 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3363 ioc->name, diag0val);
3369 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3370 dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3371 ioc->name, diag0val, diag1val));
3375 * Reset flag that says we've enabled event notification
3377 ioc->facts.EventState = 0;
3380 ioc->alt_ioc->facts.EventState = 0;
3382 return hard_reset_done;
3385 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3387 * SendIocReset - Send IOCReset request to MPT adapter.
3388 * @ioc: Pointer to MPT_ADAPTER structure
3389 * @reset_type: reset type, expected values are
3390 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3392 * Send IOCReset request to the MPT adapter.
3394 * Returns 0 for success, non-zero for failure.
3397 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3403 drsprintk((KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
3404 ioc->name, reset_type));
3405 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3406 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3409 /* FW ACK'd request, wait for READY state
3412 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3414 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3418 if (sleepFlag != CAN_SLEEP)
3421 printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3422 ioc->name, (count+5)/HZ);
3426 if (sleepFlag == CAN_SLEEP) {
3427 set_current_state(TASK_INTERRUPTIBLE);
3428 schedule_timeout(1);
3430 mdelay (1); /* 1 msec delay */
3435 * Cleanup all event stuff for this IOC; re-issue EventNotification
3436 * request if needed.
3438 if (ioc->facts.Function)
3439 ioc->facts.EventState = 0;
3444 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3446 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3447 * @ioc: Pointer to MPT_ADAPTER structure
3449 * This routine allocates memory for the MPT reply and request frame
3450 * pools (if necessary), and primes the IOC reply FIFO with
3453 * Returns 0 for success, non-zero for failure.
3456 PrimeIocFifos(MPT_ADAPTER *ioc)
3460 unsigned long flags;
3461 dma_addr_t aligned_mem_dma;
3464 int chain_buffer_sz, reply_buffer_sz, request_buffer_sz;
3465 int scale, num_sge, num_chain;
3467 /* request buffer size, rounding UP to nearest 4-kB boundary */
3468 request_buffer_sz = (ioc->req_sz * ioc->req_depth) + 128;
3469 request_buffer_sz = ((request_buffer_sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
3471 /* reply buffer size */
3472 reply_buffer_sz = (ioc->reply_sz * ioc->reply_depth) + 128;
3474 /* chain buffer size, copied from from mptscsih_initChainBuffers()
3476 * Calculate the number of chain buffers needed(plus 1) per I/O
3477 * then multiply the the maximum number of simultaneous cmds
3479 * num_sge = num sge in request frame + last chain buffer
3480 * scale = num sge per chain buffer if no chain element
3483 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3484 if (sizeof(dma_addr_t) == sizeof(u64))
3485 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3487 num_sge = 1 + scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3490 while (MPT_SCSI_SG_DEPTH - num_sge > 0) {
3492 num_sge += (scale - 1);
3496 if ((int)ioc->chip_type > (int) FC929)
3497 num_chain *= MPT_SCSI_CAN_QUEUE;
3499 num_chain *= MPT_FC_CAN_QUEUE;
3501 chain_buffer_sz = num_chain * ioc->req_sz;
3503 if(ioc->fifo_pool == NULL) {
3505 ioc->fifo_pool_sz = request_buffer_sz +
3506 reply_buffer_sz + chain_buffer_sz;
3508 ioc->fifo_pool = pci_alloc_consistent(ioc->pcidev,
3509 ioc->fifo_pool_sz, &ioc->fifo_pool_dma);
3511 if( ioc->fifo_pool == NULL)
3514 ioc->alloc_total += ioc->fifo_pool_sz;
3515 memset(ioc->fifo_pool, 0, ioc->fifo_pool_sz);
3517 /* reply fifo pointers */
3518 ioc->reply_alloc = ioc->fifo_pool;
3519 ioc->reply_alloc_dma = ioc->fifo_pool_dma;
3520 /* request fifo pointers */
3521 ioc->req_alloc = ioc->reply_alloc+reply_buffer_sz;
3522 ioc->req_alloc_dma = ioc->reply_alloc_dma+reply_buffer_sz;
3523 /* chain buffer pointers */
3524 ioc->chain_alloc = ioc->req_alloc+request_buffer_sz;
3525 ioc->chain_alloc_dma = ioc->req_alloc_dma+request_buffer_sz;
3526 ioc->chain_alloc_sz = chain_buffer_sz;
3528 /* Prime reply FIFO... */
3529 dprintk((KERN_INFO MYNAM ": %s.reply_alloc @ %p[%p], sz=%d bytes\n",
3530 ioc->name, ioc->reply_alloc,
3531 (void *)(ulong)ioc->reply_alloc_dma, reply_buffer_sz));
3533 b = (unsigned long) ioc->reply_alloc;
3534 b = (b + (0x80UL - 1UL)) & ~(0x80UL - 1UL); /* round up to 128-byte boundary */
3535 aligned_mem = (u8 *) b;
3536 ioc->reply_frames = (MPT_FRAME_HDR *) aligned_mem;
3537 ioc->reply_frames_dma =
3538 (ioc->reply_alloc_dma + (aligned_mem - ioc->reply_alloc));
3540 ioc->reply_frames_low_dma = (u32) (ioc->reply_frames_dma & 0xFFFFFFFF);
3542 /* Request FIFO - WE manage this! */
3543 dprintk((KERN_INFO MYNAM ": %s.req_alloc @ %p[%p], sz=%d bytes\n",
3544 ioc->name, ioc->req_alloc,
3545 (void *)(ulong)ioc->req_alloc_dma, request_buffer_sz));
3547 b = (unsigned long) ioc->req_alloc;
3548 b = (b + (0x80UL - 1UL)) & ~(0x80UL - 1UL); /* round up to 128-byte boundary */
3549 aligned_mem = (u8 *) b;
3550 ioc->req_frames = (MPT_FRAME_HDR *) aligned_mem;
3551 ioc->req_frames_dma =
3552 (ioc->req_alloc_dma + (aligned_mem - ioc->req_alloc));
3554 ioc->req_frames_low_dma = (u32) (ioc->req_frames_dma & 0xFFFFFFFF);
3556 #if defined(CONFIG_MTRR) && 0
3558 * Enable Write Combining MTRR for IOC's memory region.
3559 * (at least as much as we can; "size and base must be
3560 * multiples of 4 kiB"
3562 ioc->mtrr_reg = mtrr_add(ioc->fifo_pool,
3564 MTRR_TYPE_WRCOMB, 1);
3565 dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
3566 ioc->name, ioc->fifo_pool, ioc->fifo_pool_sz));
3569 } /* ioc->fifo_pool == NULL */
3571 /* Post Reply frames to FIFO
3573 aligned_mem_dma = ioc->reply_frames_dma;
3574 dprintk((KERN_INFO MYNAM ": %s.reply_frames @ %p[%p]\n",
3575 ioc->name, ioc->reply_frames, (void *)(ulong)aligned_mem_dma));
3577 for (i = 0; i < ioc->reply_depth; i++) {
3578 /* Write each address to the IOC! */
3579 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, aligned_mem_dma);
3580 aligned_mem_dma += ioc->reply_sz;
3584 /* Initialize Request frames linked list
3586 aligned_mem_dma = ioc->req_frames_dma;
3587 aligned_mem = (u8 *) ioc->req_frames;
3588 dprintk((KERN_INFO MYNAM ": %s.req_frames @ %p[%p]\n",
3589 ioc->name, aligned_mem, (void *)(ulong)aligned_mem_dma));
3591 spin_lock_irqsave(&ioc->FreeQlock, flags);
3592 Q_INIT(&ioc->FreeQ, MPT_FRAME_HDR);
3593 for (i = 0; i < ioc->req_depth; i++) {
3594 mf = (MPT_FRAME_HDR *) aligned_mem;
3596 /* Queue REQUESTs *internally*! */
3597 Q_ADD_TAIL(&ioc->FreeQ.head, &mf->u.frame.linkage, MPT_FRAME_HDR);
3598 aligned_mem += ioc->req_sz;
3600 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3603 if (ioc->sense_buf_pool == NULL) {
3604 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3605 ioc->sense_buf_pool =
3606 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3607 if (ioc->sense_buf_pool == NULL)
3610 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
3611 ioc->alloc_total += sz;
3617 if (ioc->fifo_pool != NULL) {
3618 pci_free_consistent(ioc->pcidev,
3620 ioc->fifo_pool, ioc->fifo_pool_dma);
3621 ioc->reply_frames = NULL;
3622 ioc->reply_alloc = NULL;
3623 ioc->req_frames = NULL;
3624 ioc->req_alloc = NULL;
3625 ioc->chain_alloc = NULL;
3626 ioc->fifo_pool = NULL;
3627 ioc->alloc_total -= ioc->fifo_pool_sz;
3628 #if defined(CONFIG_MTRR) && 0
3629 if (ioc->mtrr_reg > 0) {
3630 mtrr_del(ioc->mtrr_reg, 0, 0);
3631 dprintk((MYIOC_s_INFO_FMT "MTRR region de-registered\n",
3636 if (ioc->sense_buf_pool != NULL) {
3637 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3638 pci_free_consistent(ioc->pcidev,
3640 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
3641 ioc->sense_buf_pool = NULL;
3646 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3648 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3649 * from IOC via doorbell handshake method.
3650 * @ioc: Pointer to MPT_ADAPTER structure
3651 * @reqBytes: Size of the request in bytes
3652 * @req: Pointer to MPT request frame
3653 * @replyBytes: Expected size of the reply in bytes
3654 * @u16reply: Pointer to area where reply should be written
3655 * @maxwait: Max wait time for a reply (in seconds)
3656 * @sleepFlag: Specifies whether the process can sleep
3658 * NOTES: It is the callers responsibility to byte-swap fields in the
3659 * request which are greater than 1 byte in size. It is also the
3660 * callers responsibility to byte-swap response fields which are
3661 * greater than 1 byte in size.
3663 * Returns 0 for success, non-zero for failure.
3666 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
3667 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
3669 MPIDefaultReply_t *mptReply;
3674 * Get ready to cache a handshake reply
3676 ioc->hs_reply_idx = 0;
3677 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3678 mptReply->MsgLength = 0;
3681 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
3682 * then tell IOC that we want to handshake a request of N words.
3683 * (WRITE u32val to Doorbell reg).
3685 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3686 CHIPREG_WRITE32(&ioc->chip->Doorbell,
3687 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
3688 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
3691 * Wait for IOC's doorbell handshake int
3693 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3696 dhsprintk((MYIOC_s_INFO_FMT "HandShake request start, WaitCnt=%d%s\n",
3697 ioc->name, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3699 /* Read doorbell and check for active bit */
3700 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
3704 * Clear doorbell int (WRITE 0 to IntStatus reg),
3705 * then wait for IOC to ACKnowledge that it's ready for
3706 * our handshake request.
3708 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3709 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3714 u8 *req_as_bytes = (u8 *) req;
3717 * Stuff request words via doorbell handshake,
3718 * with ACK from IOC for each.
3720 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
3721 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
3722 (req_as_bytes[(ii*4) + 1] << 8) |
3723 (req_as_bytes[(ii*4) + 2] << 16) |
3724 (req_as_bytes[(ii*4) + 3] << 24));
3726 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
3727 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3731 dmfprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
3732 DBG_DUMP_REQUEST_FRAME_HDR(req)
3734 dhsprintk((MYIOC_s_INFO_FMT "HandShake request post done, WaitCnt=%d%s\n",
3735 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
3738 * Wait for completion of doorbell handshake reply from the IOC
3740 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
3743 dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n",
3744 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
3747 * Copy out the cached reply...
3749 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
3750 u16reply[ii] = ioc->hs_reply[ii];
3758 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3760 * WaitForDoorbellAck - Wait for IOC to clear the IOP_DOORBELL_STATUS bit
3761 * in it's IntStatus register.
3762 * @ioc: Pointer to MPT_ADAPTER structure
3763 * @howlong: How long to wait (in seconds)
3764 * @sleepFlag: Specifies whether the process can sleep
3766 * This routine waits (up to ~2 seconds max) for IOC doorbell
3767 * handshake ACKnowledge.
3769 * Returns a negative value on failure, else wait loop count.
3772 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3778 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
3780 if (sleepFlag == CAN_SLEEP) {
3782 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3783 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3785 set_current_state(TASK_INTERRUPTIBLE);
3786 schedule_timeout(1);
3791 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3792 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3800 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (count=%d)\n",
3805 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
3806 ioc->name, count, intstat);
3810 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3812 * WaitForDoorbellInt - Wait for IOC to set the HIS_DOORBELL_INTERRUPT bit
3813 * in it's IntStatus register.
3814 * @ioc: Pointer to MPT_ADAPTER structure
3815 * @howlong: How long to wait (in seconds)
3816 * @sleepFlag: Specifies whether the process can sleep
3818 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt.
3820 * Returns a negative value on failure, else wait loop count.
3823 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3829 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
3830 if (sleepFlag == CAN_SLEEP) {
3832 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3833 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3835 set_current_state(TASK_INTERRUPTIBLE);
3836 schedule_timeout(1);
3841 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3842 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3850 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
3851 ioc->name, count, howlong));
3855 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
3856 ioc->name, count, intstat);
3860 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3862 * WaitForDoorbellReply - Wait for and capture a IOC handshake reply.
3863 * @ioc: Pointer to MPT_ADAPTER structure
3864 * @howlong: How long to wait (in seconds)
3865 * @sleepFlag: Specifies whether the process can sleep
3867 * This routine polls the IOC for a handshake reply, 16 bits at a time.
3868 * Reply is cached to IOC private area large enough to hold a maximum
3869 * of 128 bytes of reply data.
3871 * Returns a negative value on failure, else size of reply in WORDS.
3874 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3879 u16 *hs_reply = ioc->hs_reply;
3880 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3883 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
3886 * Get first two u16's so we can look at IOC's intended reply MsgLength
3889 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
3892 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3893 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3894 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3897 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3898 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3902 dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
3903 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
3904 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3907 * If no error (and IOC said MsgLength is > 0), piece together
3908 * reply 16 bits at a time.
3910 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
3911 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3913 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3914 /* don't overflow our IOC hs_reply[] buffer! */
3915 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
3916 hs_reply[u16cnt] = hword;
3917 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3920 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3922 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3925 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
3930 else if (u16cnt != (2 * mptReply->MsgLength)) {
3933 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
3938 dmfprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
3939 DBG_DUMP_REPLY_FRAME(mptReply)
3941 dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
3942 ioc->name, t, u16cnt/2));
3946 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3948 * GetLanConfigPages - Fetch LANConfig pages.
3949 * @ioc: Pointer to MPT_ADAPTER structure
3951 * Return: 0 for success
3952 * -ENOMEM if no memory available
3953 * -EPERM if not allowed due to ISR context
3954 * -EAGAIN if no msg frames currently available
3955 * -EFAULT for non-successful reply or no reply (timeout)
3958 GetLanConfigPages(MPT_ADAPTER *ioc)
3960 ConfigPageHeader_t hdr;
3962 LANPage0_t *ppage0_alloc;
3963 dma_addr_t page0_dma;
3964 LANPage1_t *ppage1_alloc;
3965 dma_addr_t page1_dma;
3970 /* Get LAN Page 0 header */
3971 hdr.PageVersion = 0;
3974 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
3977 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
3982 if ((rc = mpt_config(ioc, &cfg)) != 0)
3985 if (hdr.PageLength > 0) {
3986 data_sz = hdr.PageLength * 4;
3987 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
3990 memset((u8 *)ppage0_alloc, 0, data_sz);
3991 cfg.physAddr = page0_dma;
3992 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
3994 if ((rc = mpt_config(ioc, &cfg)) == 0) {
3996 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
3997 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4001 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4004 * Normalize endianness of structure data,
4005 * by byte-swapping all > 1 byte fields!
4014 /* Get LAN Page 1 header */
4015 hdr.PageVersion = 0;
4018 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4021 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4025 if ((rc = mpt_config(ioc, &cfg)) != 0)
4028 if (hdr.PageLength == 0)
4031 data_sz = hdr.PageLength * 4;
4033 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4035 memset((u8 *)ppage1_alloc, 0, data_sz);
4036 cfg.physAddr = page1_dma;
4037 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4039 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4041 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4042 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4045 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4048 * Normalize endianness of structure data,
4049 * by byte-swapping all > 1 byte fields!
4057 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4059 * GetFcPortPage0 - Fetch FCPort config Page0.
4060 * @ioc: Pointer to MPT_ADAPTER structure
4061 * @portnum: IOC Port number
4063 * Return: 0 for success
4064 * -ENOMEM if no memory available
4065 * -EPERM if not allowed due to ISR context
4066 * -EAGAIN if no msg frames currently available
4067 * -EFAULT for non-successful reply or no reply (timeout)
4070 GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
4072 ConfigPageHeader_t hdr;
4074 FCPortPage0_t *ppage0_alloc;
4075 FCPortPage0_t *pp0dest;
4076 dma_addr_t page0_dma;
4081 /* Get FCPort Page 0 header */
4082 hdr.PageVersion = 0;
4085 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
4088 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4090 cfg.pageAddr = portnum;
4093 if ((rc = mpt_config(ioc, &cfg)) != 0)
4096 if (hdr.PageLength == 0)
4099 data_sz = hdr.PageLength * 4;
4101 ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4103 memset((u8 *)ppage0_alloc, 0, data_sz);
4104 cfg.physAddr = page0_dma;
4105 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4107 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4109 pp0dest = &ioc->fc_port_page0[portnum];
4110 copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
4111 memcpy(pp0dest, ppage0_alloc, copy_sz);
4114 * Normalize endianness of structure data,
4115 * by byte-swapping all > 1 byte fields!
4117 pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
4118 pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
4119 pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
4120 pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
4121 pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
4122 pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
4123 pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
4124 pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
4125 pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
4126 pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
4127 pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
4128 pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
4129 pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
4130 pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
4131 pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
4132 pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
4136 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4142 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4144 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4145 * @ioc: Pointer to MPT_ADAPTER structure
4147 * Returns: 0 for success
4148 * -ENOMEM if no memory available
4149 * -EPERM if not allowed due to ISR context
4150 * -EAGAIN if no msg frames currently available
4151 * -EFAULT for non-successful reply or no reply (timeout)
4154 GetIoUnitPage2(MPT_ADAPTER *ioc)
4156 ConfigPageHeader_t hdr;
4158 IOUnitPage2_t *ppage_alloc;
4159 dma_addr_t page_dma;
4163 /* Get the page header */
4164 hdr.PageVersion = 0;
4167 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4170 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4175 if ((rc = mpt_config(ioc, &cfg)) != 0)
4178 if (hdr.PageLength == 0)
4181 /* Read the config page */
4182 data_sz = hdr.PageLength * 4;
4184 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4186 memset((u8 *)ppage_alloc, 0, data_sz);
4187 cfg.physAddr = page_dma;
4188 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4190 /* If Good, save data */
4191 if ((rc = mpt_config(ioc, &cfg)) == 0)
4192 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4194 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4200 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4201 /* mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4202 * @ioc: Pointer to a Adapter Strucutre
4203 * @portnum: IOC port number
4205 * Return: -EFAULT if read of config page header fails
4207 * If read of SCSI Port Page 0 fails,
4208 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4209 * Adapter settings: async, narrow
4211 * If read of SCSI Port Page 2 fails,
4212 * Adapter settings valid
4213 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4218 * CHECK - what type of locking mechanisms should be used????
4221 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4226 ConfigPageHeader_t header;
4232 if (!ioc->spi_data.nvram) {
4235 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4236 mem = kmalloc(sz, GFP_ATOMIC);
4240 ioc->spi_data.nvram = (int *) mem;
4242 dprintk((MYIOC_s_INFO_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4243 ioc->name, ioc->spi_data.nvram, sz));
4246 /* Invalidate NVRAM information
4248 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4249 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4252 /* Read SPP0 header, allocate memory, then read page.
4254 header.PageVersion = 0;
4255 header.PageLength = 0;
4256 header.PageNumber = 0;
4257 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4260 cfg.pageAddr = portnum;
4261 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4263 cfg.timeout = 0; /* use default */
4264 if (mpt_config(ioc, &cfg) != 0)
4267 if (header.PageLength > 0) {
4268 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4270 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4271 cfg.physAddr = buf_dma;
4272 if (mpt_config(ioc, &cfg) != 0) {
4273 ioc->spi_data.maxBusWidth = MPT_NARROW;
4274 ioc->spi_data.maxSyncOffset = 0;
4275 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4276 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4279 /* Save the Port Page 0 data
4281 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4282 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4283 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4285 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 )
4286 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4288 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4289 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4291 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4292 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4293 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4295 ioc->spi_data.maxSyncOffset = 0;
4296 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4299 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4301 /* Update the minSyncFactor based on bus type.
4303 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4304 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4306 if (ioc->spi_data.minSyncFactor < MPT_ULTRA)
4307 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4311 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4316 /* SCSI Port Page 2 - Read the header then the page.
4318 header.PageVersion = 0;
4319 header.PageLength = 0;
4320 header.PageNumber = 2;
4321 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4324 cfg.pageAddr = portnum;
4325 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4327 if (mpt_config(ioc, &cfg) != 0)
4330 if (header.PageLength > 0) {
4331 /* Allocate memory and read SCSI Port Page 2
4333 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4335 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4336 cfg.physAddr = buf_dma;
4337 if (mpt_config(ioc, &cfg) != 0) {
4338 /* Nvram data is left with INVALID mark
4342 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4343 MpiDeviceInfo_t *pdevice = NULL;
4345 /* Save the Port Page 2 data
4346 * (reformat into a 32bit quantity)
4348 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4349 ioc->spi_data.PortFlags = data;
4350 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4351 pdevice = &pPP2->DeviceSettings[ii];
4352 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4353 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4354 ioc->spi_data.nvram[ii] = data;
4358 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4362 /* Update Adapter limits with those from NVRAM
4363 * Comment: Don't need to do this. Target performance
4364 * parameters will never exceed the adapters limits.
4370 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4371 /* mpt_readScsiDevicePageHeaders - save version and length of SDP1
4372 * @ioc: Pointer to a Adapter Strucutre
4373 * @portnum: IOC port number
4375 * Return: -EFAULT if read of config page header fails
4379 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4382 ConfigPageHeader_t header;
4384 /* Read the SCSI Device Page 1 header
4386 header.PageVersion = 0;
4387 header.PageLength = 0;
4388 header.PageNumber = 1;
4389 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4392 cfg.pageAddr = portnum;
4393 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4396 if (mpt_config(ioc, &cfg) != 0)
4399 ioc->spi_data.sdp1version = cfg.hdr->PageVersion;
4400 ioc->spi_data.sdp1length = cfg.hdr->PageLength;
4402 header.PageVersion = 0;
4403 header.PageLength = 0;
4404 header.PageNumber = 0;
4405 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4406 if (mpt_config(ioc, &cfg) != 0)
4409 ioc->spi_data.sdp0version = cfg.hdr->PageVersion;
4410 ioc->spi_data.sdp0length = cfg.hdr->PageLength;
4412 dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
4413 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
4415 dcprintk((MYIOC_s_INFO_FMT "Headers: 1: version %d length %d\n",
4416 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
4420 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4422 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4423 * @ioc: Pointer to a Adapter Strucutre
4424 * @portnum: IOC port number
4428 * -EFAULT if read of config page header fails or data pointer not NULL
4429 * -ENOMEM if pci_alloc failed
4432 mpt_findImVolumes(MPT_ADAPTER *ioc)
4436 ConfigPageIoc2RaidVol_t *pIocRv;
4437 dma_addr_t ioc2_dma;
4439 ConfigPageHeader_t header;
4446 /* Read IOCP2 header then the page.
4448 header.PageVersion = 0;
4449 header.PageLength = 0;
4450 header.PageNumber = 2;
4451 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4455 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4458 if (mpt_config(ioc, &cfg) != 0)
4461 if (header.PageLength == 0)
4464 iocpage2sz = header.PageLength * 4;
4465 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
4469 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4470 cfg.physAddr = ioc2_dma;
4471 if (mpt_config(ioc, &cfg) != 0)
4474 if ( (mem = (u8 *)ioc->spi_data.pIocPg2) == NULL ) {
4475 mem = kmalloc(iocpage2sz, GFP_ATOMIC);
4477 ioc->spi_data.pIocPg2 = (IOCPage2_t *) mem;
4482 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
4484 /* Identify RAID Volume Id's */
4485 nVols = pIoc2->NumActiveVolumes;
4491 /* At least 1 RAID Volume
4493 pIocRv = pIoc2->RaidVolume;
4494 ioc->spi_data.isRaid = 0;
4495 for (jj = 0; jj < nVols; jj++, pIocRv++) {
4496 vid = pIocRv->VolumeID;
4497 vbus = pIocRv->VolumeBus;
4498 vioc = pIocRv->VolumeIOC;
4503 ioc->spi_data.isRaid |= (1 << vid);
4505 /* Error! Always bus 0
4511 /* Identify Hidden Physical Disk Id's */
4512 nPhys = pIoc2->NumActivePhysDisks;
4514 /* No physical disks.
4517 mpt_read_ioc_pg_3(ioc);
4521 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
4527 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
4532 ConfigPageHeader_t header;
4533 dma_addr_t ioc3_dma;
4536 /* Free the old page
4538 if (ioc->spi_data.pIocPg3) {
4539 kfree(ioc->spi_data.pIocPg3);
4540 ioc->spi_data.pIocPg3 = NULL;
4543 /* There is at least one physical disk.
4544 * Read and save IOC Page 3
4546 header.PageVersion = 0;
4547 header.PageLength = 0;
4548 header.PageNumber = 3;
4549 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4553 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4556 if (mpt_config(ioc, &cfg) != 0)
4559 if (header.PageLength == 0)
4562 /* Read Header good, alloc memory
4564 iocpage3sz = header.PageLength * 4;
4565 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
4569 /* Read the Page and save the data
4570 * into malloc'd memory.
4572 cfg.physAddr = ioc3_dma;
4573 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4574 if (mpt_config(ioc, &cfg) == 0) {
4575 mem = kmalloc(iocpage3sz, GFP_ATOMIC);
4577 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
4578 ioc->spi_data.pIocPg3 = (IOCPage3_t *) mem;
4582 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
4588 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
4592 ConfigPageHeader_t header;
4593 dma_addr_t ioc4_dma;
4596 /* Read and save IOC Page 4
4598 header.PageVersion = 0;
4599 header.PageLength = 0;
4600 header.PageNumber = 4;
4601 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4605 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4608 if (mpt_config(ioc, &cfg) != 0)
4611 if (header.PageLength == 0)
4614 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
4615 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
4616 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
4620 ioc4_dma = ioc->spi_data.IocPg4_dma;
4621 iocpage4sz = ioc->spi_data.IocPg4Sz;
4624 /* Read the Page into dma memory.
4626 cfg.physAddr = ioc4_dma;
4627 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4628 if (mpt_config(ioc, &cfg) == 0) {
4629 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
4630 ioc->spi_data.IocPg4_dma = ioc4_dma;
4631 ioc->spi_data.IocPg4Sz = iocpage4sz;
4633 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
4634 ioc->spi_data.pIocPg4 = NULL;
4639 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
4643 ConfigPageHeader_t header;
4644 dma_addr_t ioc1_dma;
4648 /* Check the Coalescing Timeout in IOC Page 1
4650 header.PageVersion = 0;
4651 header.PageLength = 0;
4652 header.PageNumber = 1;
4653 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4657 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4660 if (mpt_config(ioc, &cfg) != 0)
4663 if (header.PageLength == 0)
4666 /* Read Header good, alloc memory
4668 iocpage1sz = header.PageLength * 4;
4669 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
4673 /* Read the Page and check coalescing timeout
4675 cfg.physAddr = ioc1_dma;
4676 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4677 if (mpt_config(ioc, &cfg) == 0) {
4679 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
4680 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
4681 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
4683 dprintk((MYIOC_s_INFO_FMT "Coalescing Enabled Timeout = %d\n",
4686 if (tmp > MPT_COALESCING_TIMEOUT) {
4687 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
4689 /* Write NVRAM and current
4692 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4693 if (mpt_config(ioc, &cfg) == 0) {
4694 dprintk((MYIOC_s_INFO_FMT "Reset Current Coalescing Timeout to = %d\n",
4695 ioc->name, MPT_COALESCING_TIMEOUT));
4697 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
4698 if (mpt_config(ioc, &cfg) == 0) {
4699 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout to = %d\n",
4700 ioc->name, MPT_COALESCING_TIMEOUT));
4702 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout Failed\n",
4707 dprintk((MYIOC_s_WARN_FMT "Reset of Current Coalescing Timeout Failed!\n",
4713 dprintk((MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
4717 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
4722 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4724 * SendEventNotification - Send EventNotification (on or off) request
4726 * @ioc: Pointer to MPT_ADAPTER structure
4727 * @EvSwitch: Event switch flags
4730 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
4732 EventNotification_t *evnp;
4734 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
4736 dprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
4740 memset(evnp, 0, sizeof(*evnp));
4742 dprintk((MYIOC_s_INFO_FMT "Sending EventNotification(%d)\n", ioc->name, EvSwitch));
4744 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
4745 evnp->ChainOffset = 0;
4747 evnp->Switch = EvSwitch;
4749 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
4754 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4756 * SendEventAck - Send EventAck request to MPT adapter.
4757 * @ioc: Pointer to MPT_ADAPTER structure
4758 * @evnp: Pointer to original EventNotification request
4761 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
4765 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4766 printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK request frame!\n",
4770 memset(pAck, 0, sizeof(*pAck));
4772 dprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
4774 pAck->Function = MPI_FUNCTION_EVENT_ACK;
4775 pAck->ChainOffset = 0;
4777 pAck->Event = evnp->Event;
4778 pAck->EventContext = evnp->EventContext;
4780 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
4785 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4787 * mpt_config - Generic function to issue config message
4788 * @ioc - Pointer to an adapter structure
4789 * @cfg - Pointer to a configuration structure. Struct contains
4790 * action, page address, direction, physical address
4791 * and pointer to a configuration page header
4792 * Page header is updated.
4794 * Returns 0 for success
4795 * -EPERM if not allowed due to ISR context
4796 * -EAGAIN if no msg frames currently available
4797 * -EFAULT for non-successful reply or no reply (timeout)
4800 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
4804 unsigned long flags;
4809 /* (Bugzilla:fibrebugs, #513)
4810 * Bug fix (part 1)! 20010905 -sralston
4811 * Prevent calling wait_event() (below), if caller happens
4812 * to be in ISR context, because that is fatal!
4814 in_isr = in_interrupt();
4816 dcprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
4821 /* Get and Populate a free Frame
4823 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4824 dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
4828 pReq = (Config_t *)mf;
4829 pReq->Action = pCfg->action;
4831 pReq->ChainOffset = 0;
4832 pReq->Function = MPI_FUNCTION_CONFIG;
4833 pReq->ExtPageLength = 0;
4834 pReq->ExtPageType = 0;
4836 for (ii=0; ii < 8; ii++)
4837 pReq->Reserved2[ii] = 0;
4839 pReq->Header.PageVersion = pCfg->hdr->PageVersion;
4840 pReq->Header.PageLength = pCfg->hdr->PageLength;
4841 pReq->Header.PageNumber = pCfg->hdr->PageNumber;
4842 pReq->Header.PageType = (pCfg->hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
4843 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
4845 /* Add a SGE to the config request.
4848 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
4850 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
4852 flagsLength |= pCfg->hdr->PageLength * 4;
4854 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
4856 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
4857 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
4859 /* Append pCfg pointer to end of mf
4861 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
4863 /* Initalize the timer
4865 init_timer(&pCfg->timer);
4866 pCfg->timer.data = (unsigned long) ioc;
4867 pCfg->timer.function = mpt_timer_expired;
4868 pCfg->wait_done = 0;
4870 /* Set the timer; ensure 10 second minimum */
4871 if (pCfg->timeout < 10)
4872 pCfg->timer.expires = jiffies + HZ*10;
4874 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
4876 /* Add to end of Q, set timer and then issue this command */
4877 spin_lock_irqsave(&ioc->FreeQlock, flags);
4878 Q_ADD_TAIL(&ioc->configQ.head, &pCfg->linkage, Q_ITEM);
4879 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4881 add_timer(&pCfg->timer);
4882 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4883 wait_event(mpt_waitq, pCfg->wait_done);
4885 /* mf has been freed - do not access */
4892 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4894 * mpt_toolbox - Generic function to issue toolbox message
4895 * @ioc - Pointer to an adapter structure
4896 * @cfg - Pointer to a toolbox structure. Struct contains
4897 * action, page address, direction, physical address
4898 * and pointer to a configuration page header
4899 * Page header is updated.
4901 * Returns 0 for success
4902 * -EPERM if not allowed due to ISR context
4903 * -EAGAIN if no msg frames currently available
4904 * -EFAULT for non-successful reply or no reply (timeout)
4907 mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
4909 ToolboxIstwiReadWriteRequest_t *pReq;
4910 struct pci_dev *pdev;
4912 unsigned long flags;
4917 /* (Bugzilla:fibrebugs, #513)
4918 * Bug fix (part 1)! 20010905 -sralston
4919 * Prevent calling wait_event() (below), if caller happens
4920 * to be in ISR context, because that is fatal!
4922 in_isr = in_interrupt();
4924 dcprintk((MYIOC_s_WARN_FMT "toobox request not allowed in ISR context!\n",
4929 /* Get and Populate a free Frame
4931 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4932 dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n",
4936 pReq = (ToolboxIstwiReadWriteRequest_t *)mf;
4937 pReq->Tool = pCfg->action;
4939 pReq->ChainOffset = 0;
4940 pReq->Function = MPI_FUNCTION_TOOLBOX;
4941 pReq->Reserved1 = 0;
4942 pReq->Reserved2 = 0;
4944 pReq->Flags = pCfg->dir;
4946 pReq->Reserved3 = 0;
4947 pReq->NumAddressBytes = 0x01;
4948 pReq->Reserved4 = 0;
4949 pReq->DataLength = 0x04;
4950 pdev = (struct pci_dev *) ioc->pcidev;
4951 if (pdev->devfn & 1)
4952 pReq->DeviceAddr = 0xB2;
4954 pReq->DeviceAddr = 0xB0;
4958 pReq->Reserved5 = 0;
4960 /* Add a SGE to the config request.
4963 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | 4;
4965 mpt_add_sge((char *)&pReq->SGL, flagsLength, pCfg->physAddr);
4967 dcprintk((MYIOC_s_INFO_FMT "Sending Toolbox request, Tool=%x\n",
4968 ioc->name, pReq->Tool));
4970 /* Append pCfg pointer to end of mf
4972 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
4974 /* Initalize the timer
4976 init_timer(&pCfg->timer);
4977 pCfg->timer.data = (unsigned long) ioc;
4978 pCfg->timer.function = mpt_timer_expired;
4979 pCfg->wait_done = 0;
4981 /* Set the timer; ensure 10 second minimum */
4982 if (pCfg->timeout < 10)
4983 pCfg->timer.expires = jiffies + HZ*10;
4985 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
4987 /* Add to end of Q, set timer and then issue this command */
4988 spin_lock_irqsave(&ioc->FreeQlock, flags);
4989 Q_ADD_TAIL(&ioc->configQ.head, &pCfg->linkage, Q_ITEM);
4990 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4992 add_timer(&pCfg->timer);
4993 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4994 wait_event(mpt_waitq, pCfg->wait_done);
4996 /* mf has been freed - do not access */
5003 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5005 * mpt_timer_expired - Call back for timer process.
5006 * Used only internal config functionality.
5007 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5010 mpt_timer_expired(unsigned long data)
5012 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5014 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name));
5016 /* Perform a FW reload */
5017 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5018 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5020 /* No more processing.
5021 * Hard reset clean-up will wake up
5022 * process and free all resources.
5024 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name));
5029 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5031 * mpt_ioc_reset - Base cleanup for hard reset
5032 * @ioc: Pointer to the adapter structure
5033 * @reset_phase: Indicates pre- or post-reset functionality
5035 * Remark: Free's resources with internally generated commands.
5038 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5041 unsigned long flags;
5043 dprintk((KERN_WARNING MYNAM
5044 ": IOC %s_reset routed to MPT base driver!\n",
5045 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5046 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5048 if (reset_phase == MPT_IOC_SETUP_RESET) {
5050 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5051 /* If the internal config Q is not empty -
5052 * delete timer. MF resources will be freed when
5053 * the FIFO's are primed.
5055 spin_lock_irqsave(&ioc->FreeQlock, flags);
5056 if (! Q_IS_EMPTY(&ioc->configQ)){
5057 pCfg = (CONFIGPARMS *)ioc->configQ.head;
5059 del_timer(&pCfg->timer);
5060 pCfg = (CONFIGPARMS *) (pCfg->linkage.forw);
5061 } while (pCfg != (CONFIGPARMS *)&ioc->configQ);
5063 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5068 /* Search the configQ for internal commands.
5069 * Flush the Q, and wake up all suspended threads.
5071 spin_lock_irqsave(&ioc->FreeQlock, flags);
5072 if (! Q_IS_EMPTY(&ioc->configQ)){
5073 pCfg = (CONFIGPARMS *)ioc->configQ.head;
5075 pNext = (CONFIGPARMS *) pCfg->linkage.forw;
5077 Q_DEL_ITEM(&pCfg->linkage);
5079 pCfg->status = MPT_CONFIG_ERROR;
5080 pCfg->wait_done = 1;
5081 wake_up(&mpt_waitq);
5084 } while (pCfg != (CONFIGPARMS *)&ioc->configQ);
5086 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5089 return 1; /* currently means nothing really */
5093 #ifdef CONFIG_PROC_FS /* { */
5094 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5096 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5098 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5100 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5102 * Returns 0 for success, non-zero for failure.
5105 procmpt_create(void)
5107 struct proc_dir_entry *ent;
5109 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5110 if (mpt_proc_root_dir == NULL)
5113 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5115 ent->read_proc = procmpt_summary_read;
5117 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5119 ent->read_proc = procmpt_version_read;
5124 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5126 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5128 * Returns 0 for success, non-zero for failure.
5131 procmpt_destroy(void)
5133 remove_proc_entry("version", mpt_proc_root_dir);
5134 remove_proc_entry("summary", mpt_proc_root_dir);
5135 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5138 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5140 * procmpt_summary_read - Handle read request from /proc/mpt/summary
5141 * or from /proc/mpt/iocN/summary.
5142 * @buf: Pointer to area to write information
5143 * @start: Pointer to start pointer
5144 * @offset: Offset to start writing
5146 * @eof: Pointer to EOF integer
5149 * Returns number of characters written to process performing the read.
5152 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5162 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5166 list_for_each_entry(ioc, &ioc_list, list) {
5169 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5172 if ((out-buf) >= request)
5179 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5182 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5184 * procmpt_version_read - Handle read request from /proc/mpt/version.
5185 * @buf: Pointer to area to write information
5186 * @start: Pointer to start pointer
5187 * @offset: Offset to start writing
5189 * @eof: Pointer to EOF integer
5192 * Returns number of characters written to process performing the read.
5195 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5198 int scsi, lan, ctl, targ, dmp;
5202 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5203 len += sprintf(buf+len, " Fusion MPT base driver\n");
5205 scsi = lan = ctl = targ = dmp = 0;
5206 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5208 if (MptCallbacks[ii]) {
5209 switch (MptDriverClass[ii]) {
5210 case MPTSCSIH_DRIVER:
5211 if (!scsi++) drvname = "SCSI host";
5214 if (!lan++) drvname = "LAN";
5217 if (!targ++) drvname = "SCSI target";
5220 if (!ctl++) drvname = "ioctl";
5223 if (!dmp++) drvname = "DMP";
5228 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5230 * Handle isense special case, because it
5231 * doesn't do a formal mpt_register call.
5233 if (isense_idx == ii)
5234 len += sprintf(buf+len, " Fusion MPT isense driver\n");
5238 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5241 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5243 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5244 * @buf: Pointer to area to write information
5245 * @start: Pointer to start pointer
5246 * @offset: Offset to start writing
5248 * @eof: Pointer to EOF integer
5251 * Returns number of characters written to process performing the read.
5254 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5256 MPT_ADAPTER *ioc = data;
5262 mpt_get_fw_exp_ver(expVer, ioc);
5264 len = sprintf(buf, "%s:", ioc->name);
5265 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5266 len += sprintf(buf+len, " (f/w download boot flag set)");
5267 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5268 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5270 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
5271 ioc->facts.ProductID,
5273 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5274 if (ioc->facts.FWImageSize)
5275 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5276 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5277 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5278 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
5280 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
5281 ioc->facts.CurrentHostMfaHighAddr);
5282 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
5283 ioc->facts.CurrentSenseBufferHighAddr);
5285 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5286 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5288 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5289 (void *)ioc->req_alloc, (void *)(ulong)ioc->req_alloc_dma);
5291 * Rounding UP to nearest 4-kB boundary here...
5293 sz = (ioc->req_sz * ioc->req_depth) + 128;
5294 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5295 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5296 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5297 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
5298 4*ioc->facts.RequestFrameSize,
5299 ioc->facts.GlobalCredits);
5301 len += sprintf(buf+len, " ReplyFrames @ 0x%p (Dma @ 0x%p)\n",
5302 (void *)ioc->reply_alloc, (void *)(ulong)ioc->reply_alloc_dma);
5303 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5304 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5305 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5306 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
5307 ioc->facts.CurReplyFrameSize,
5308 ioc->facts.ReplyQueueDepth);
5310 len += sprintf(buf+len, " MaxDevices = %d\n",
5311 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5312 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
5315 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5316 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
5318 ioc->facts.NumberOfPorts);
5319 if ((int)ioc->chip_type <= (int)FC929) {
5320 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5321 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5322 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5323 a[5], a[4], a[3], a[2], a[1], a[0]);
5325 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
5326 ioc->fc_port_page0[p].WWNN.High,
5327 ioc->fc_port_page0[p].WWNN.Low,
5328 ioc->fc_port_page0[p].WWPN.High,
5329 ioc->fc_port_page0[p].WWPN.Low);
5333 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5336 #endif /* CONFIG_PROC_FS } */
5338 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5340 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
5343 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
5344 sprintf(buf, " (Exp %02d%02d)",
5345 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
5346 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
5349 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
5350 strcat(buf, " [MDBG]");
5354 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5356 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5357 * @ioc: Pointer to MPT_ADAPTER structure
5358 * @buffer: Pointer to buffer where IOC summary info should be written
5359 * @size: Pointer to number of bytes we wrote (set by this routine)
5360 * @len: Offset at which to start writing in buffer
5361 * @showlan: Display LAN stuff?
5363 * This routine writes (english readable) ASCII text, which represents
5364 * a summary of IOC information, to a buffer.
5367 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
5372 mpt_get_fw_exp_ver(expVer, ioc);
5375 * Shorter summary of attached ioc's...
5377 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
5380 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
5381 ioc->facts.FWVersion.Word,
5383 ioc->facts.NumberOfPorts,
5386 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
5387 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5388 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
5389 a[5], a[4], a[3], a[2], a[1], a[0]);
5393 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
5395 y += sprintf(buffer+len+y, ", IRQ=%s", __irq_itoa(ioc->pci_irq));
5399 y += sprintf(buffer+len+y, " (disabled)");
5401 y += sprintf(buffer+len+y, "\n");
5406 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5410 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5412 * mpt_HardResetHandler - Generic reset handler, issue SCSI Task
5413 * Management call based on input arg values. If TaskMgmt fails,
5414 * return associated SCSI request.
5415 * @ioc: Pointer to MPT_ADAPTER structure
5416 * @sleepFlag: Indicates if sleep or schedule must be called.
5418 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
5419 * or a non-interrupt thread. In the former, must not call schedule().
5421 * Remark: A return of -1 is a FATAL error case, as it means a
5422 * FW reload/initialization failed.
5424 * Returns 0 for SUCCESS or -1 if FAILED.
5427 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5430 unsigned long flags;
5432 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
5434 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
5435 printk("MF count 0x%x !\n", ioc->mfcnt);
5438 /* Reset the adapter. Prevent more than 1 call to
5439 * mpt_do_ioc_recovery at any instant in time.
5441 spin_lock_irqsave(&ioc->diagLock, flags);
5442 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
5443 spin_unlock_irqrestore(&ioc->diagLock, flags);
5446 ioc->diagPending = 1;
5448 spin_unlock_irqrestore(&ioc->diagLock, flags);
5450 /* FIXME: If do_ioc_recovery fails, repeat....
5453 /* The SCSI driver needs to adjust timeouts on all current
5454 * commands prior to the diagnostic reset being issued.
5455 * Prevents timeouts occuring during a diagnostic reset...very bad.
5456 * For all other protocol drivers, this is a no-op.
5462 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5463 if (MptResetHandlers[ii]) {
5464 dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
5466 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_SETUP_RESET);
5468 dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
5469 ioc->name, ioc->alt_ioc->name, ii));
5470 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_SETUP_RESET);
5476 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
5477 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
5482 ioc->alt_ioc->reload_fw = 0;
5484 spin_lock_irqsave(&ioc->diagLock, flags);
5485 ioc->diagPending = 0;
5487 ioc->alt_ioc->diagPending = 0;
5488 spin_unlock_irqrestore(&ioc->diagLock, flags);
5490 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
5495 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5497 EventDescriptionStr(u8 event, u32 evData0)
5502 case MPI_EVENT_NONE:
5505 case MPI_EVENT_LOG_DATA:
5508 case MPI_EVENT_STATE_CHANGE:
5509 ds = "State Change";
5511 case MPI_EVENT_UNIT_ATTENTION:
5512 ds = "Unit Attention";
5514 case MPI_EVENT_IOC_BUS_RESET:
5515 ds = "IOC Bus Reset";
5517 case MPI_EVENT_EXT_BUS_RESET:
5518 ds = "External Bus Reset";
5520 case MPI_EVENT_RESCAN:
5521 ds = "Bus Rescan Event";
5522 /* Ok, do we need to do anything here? As far as
5523 I can tell, this is when a new device gets added
5526 case MPI_EVENT_LINK_STATUS_CHANGE:
5527 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
5528 ds = "Link Status(FAILURE) Change";
5530 ds = "Link Status(ACTIVE) Change";
5532 case MPI_EVENT_LOOP_STATE_CHANGE:
5533 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
5534 ds = "Loop State(LIP) Change";
5535 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
5536 ds = "Loop State(LPE) Change"; /* ??? */
5538 ds = "Loop State(LPB) Change"; /* ??? */
5540 case MPI_EVENT_LOGOUT:
5543 case MPI_EVENT_EVENT_CHANGE:
5545 ds = "Events(ON) Change";
5547 ds = "Events(OFF) Change";
5549 case MPI_EVENT_INTEGRATED_RAID:
5550 ds = "Integrated Raid";
5553 * MPT base "custom" events may be added here...
5562 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5564 * ProcessEventNotification - Route a received EventNotificationReply to
5565 * all currently regeistered event handlers.
5566 * @ioc: Pointer to MPT_ADAPTER structure
5567 * @pEventReply: Pointer to EventNotification reply frame
5568 * @evHandlers: Pointer to integer, number of event handlers
5570 * Returns sum of event handlers return values.
5573 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
5585 * Do platform normalization of values
5587 event = le32_to_cpu(pEventReply->Event) & 0xFF;
5588 // evCtx = le32_to_cpu(pEventReply->EventContext);
5589 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
5591 evData0 = le32_to_cpu(pEventReply->Data[0]);
5594 evStr = EventDescriptionStr(event, evData0);
5595 dprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n",
5600 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_EVENTS)
5601 printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
5602 for (ii = 0; ii < evDataLen; ii++)
5603 printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
5608 * Do general / base driver event processing
5611 case MPI_EVENT_NONE: /* 00 */
5612 case MPI_EVENT_LOG_DATA: /* 01 */
5613 case MPI_EVENT_STATE_CHANGE: /* 02 */
5614 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
5615 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
5616 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
5617 case MPI_EVENT_RESCAN: /* 06 */
5618 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
5619 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
5620 case MPI_EVENT_LOGOUT: /* 09 */
5621 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
5622 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE: /* 0C */
5625 case MPI_EVENT_EVENT_CHANGE: /* 0A */
5627 u8 evState = evData0 & 0xFF;
5629 /* CHECKME! What if evState unexpectedly says OFF (0)? */
5631 /* Update EventState field in cached IocFacts */
5632 if (ioc->facts.Function) {
5633 ioc->facts.EventState = evState;
5640 * Should this event be logged? Events are written sequentially.
5641 * When buffer is full, start again at the top.
5643 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
5646 idx = ioc->eventContext % ioc->eventLogSize;
5648 ioc->events[idx].event = event;
5649 ioc->events[idx].eventContext = ioc->eventContext;
5651 for (ii = 0; ii < 2; ii++) {
5653 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
5655 ioc->events[idx].data[ii] = 0;
5658 ioc->eventContext++;
5663 * Call each currently registered protocol event handler.
5665 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5666 if (MptEvHandlers[ii]) {
5667 dprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
5669 r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
5673 /* FIXME? Examine results here? */
5676 * If needed, send (a single) EventAck.
5678 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
5679 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
5680 printk(MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
5685 *evHandlers = handlers;
5689 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5691 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
5692 * @ioc: Pointer to MPT_ADAPTER structure
5693 * @log_info: U32 LogInfo reply word from the IOC
5695 * Refer to lsi/fc_log.h.
5698 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
5700 static char *subcl_str[8] = {
5701 "FCP Initiator", "FCP Target", "LAN", "MPI Message Layer",
5702 "FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
5704 u8 subcl = (log_info >> 24) & 0x7;
5705 // u32 SubCl = log_info & 0x27000000;
5707 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}",
5708 ioc->name, log_info, subcl_str[subcl]);
5711 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5713 * mpt_sp_log_info - Log information returned from SCSI Parallel IOC.
5714 * @ioc: Pointer to MPT_ADAPTER structure
5715 * @mr: Pointer to MPT reply frame
5716 * @log_info: U32 LogInfo word from the IOC
5718 * Refer to lsi/sp_log.h.
5721 mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
5723 u32 info = log_info & 0x00FF0000;
5724 char *desc = "unknown";
5728 desc = "bug! MID not found";
5729 if (ioc->reload_fw == 0)
5734 desc = "Parity Error";
5738 desc = "ASYNC Outbound Overrun";
5742 desc = "SYNC Offset Error";
5750 desc = "Msg In Overflow";
5758 desc = "Outbound DMA Overrun";
5762 desc = "Task Management";
5766 desc = "Device Problem";
5770 desc = "Invalid Phase Change";
5774 desc = "Untagged Table Size";
5779 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
5782 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5784 * mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
5785 * @ioc: Pointer to MPT_ADAPTER structure
5786 * @ioc_status: U32 IOCStatus word from IOC
5787 * @mf: Pointer to MPT request frame
5789 * Refer to lsi/mpi.h.
5792 mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
5794 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
5798 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
5799 desc = "Invalid Function";
5802 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
5806 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
5807 desc = "Invalid SGL";
5810 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
5811 desc = "Internal Error";
5814 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
5818 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
5819 desc = "Insufficient Resources";
5822 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
5823 desc = "Invalid Field";
5826 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
5827 desc = "Invalid State";
5830 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
5831 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
5832 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
5833 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
5834 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
5835 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
5836 /* No message for Config IOCStatus values */
5839 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
5840 /* No message for recovered error
5841 desc = "SCSI Recovered Error";
5845 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
5846 desc = "SCSI Invalid Bus";
5849 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
5850 desc = "SCSI Invalid TargetID";
5853 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
5855 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
5856 U8 cdb = pScsiReq->CDB[0];
5857 if (cdb != 0x12) { /* Inquiry is issued for device scanning */
5858 desc = "SCSI Device Not There";
5863 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
5864 desc = "SCSI Data Overrun";
5867 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
5868 /* This error is checked in scsi_io_done(). Skip.
5869 desc = "SCSI Data Underrun";
5873 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
5874 desc = "SCSI I/O Data Error";
5877 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
5878 desc = "SCSI Protocol Error";
5881 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
5882 desc = "SCSI Task Terminated";
5885 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
5886 desc = "SCSI Residual Mismatch";
5889 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
5890 desc = "SCSI Task Management Failed";
5893 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
5894 desc = "SCSI IOC Terminated";
5897 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
5898 desc = "SCSI Ext Terminated";
5906 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc);
5909 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5911 * mpt_register_ascqops_strings - Register SCSI ASC/ASCQ and SCSI
5912 * OpCode strings from the (optional) isense module.
5913 * @ascqTable: Pointer to ASCQ_Table_t structure
5914 * @ascqtbl_sz: Number of entries in ASCQ_Table
5915 * @opsTable: Pointer to array of SCSI OpCode strings (char pointers)
5917 * Specialized driver registration routine for the isense driver.
5920 mpt_register_ascqops_strings(void *ascqTable, int ascqtbl_sz, const char **opsTable)
5924 if (ascqTable && ascqtbl_sz && opsTable) {
5925 mpt_v_ASCQ_TablePtr = ascqTable;
5926 mpt_ASCQ_TableSz = ascqtbl_sz;
5927 mpt_ScsiOpcodesPtr = opsTable;
5928 printk(KERN_INFO MYNAM ": English readable SCSI-3 strings enabled:-)\n");
5929 isense_idx = last_drv_idx;
5935 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5937 * mpt_deregister_ascqops_strings - Deregister SCSI ASC/ASCQ and SCSI
5938 * OpCode strings from the isense driver.
5940 * Specialized driver deregistration routine for the isense driver.
5943 mpt_deregister_ascqops_strings(void)
5945 mpt_v_ASCQ_TablePtr = NULL;
5946 mpt_ASCQ_TableSz = 0;
5947 mpt_ScsiOpcodesPtr = NULL;
5948 printk(KERN_INFO MYNAM ": English readable SCSI-3 strings disabled)-:\n");
5952 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5954 EXPORT_SYMBOL(ioc_list);
5955 EXPORT_SYMBOL(mpt_proc_root_dir);
5956 EXPORT_SYMBOL(DmpService);
5957 EXPORT_SYMBOL(mpt_register);
5958 EXPORT_SYMBOL(mpt_deregister);
5959 EXPORT_SYMBOL(mpt_event_register);
5960 EXPORT_SYMBOL(mpt_event_deregister);
5961 EXPORT_SYMBOL(mpt_reset_register);
5962 EXPORT_SYMBOL(mpt_reset_deregister);
5963 EXPORT_SYMBOL(mpt_device_driver_register);
5964 EXPORT_SYMBOL(mpt_device_driver_deregister);
5965 EXPORT_SYMBOL(mpt_get_msg_frame);
5966 EXPORT_SYMBOL(mpt_put_msg_frame);
5967 EXPORT_SYMBOL(mpt_free_msg_frame);
5968 EXPORT_SYMBOL(mpt_add_sge);
5969 EXPORT_SYMBOL(mpt_add_chain);
5970 EXPORT_SYMBOL(mpt_send_handshake_request);
5971 EXPORT_SYMBOL(mpt_handshake_req_reply_wait);
5972 EXPORT_SYMBOL(mpt_verify_adapter);
5973 EXPORT_SYMBOL(mpt_GetIocState);
5974 EXPORT_SYMBOL(mpt_print_ioc_summary);
5975 EXPORT_SYMBOL(mpt_lan_index);
5976 EXPORT_SYMBOL(mpt_stm_index);
5977 EXPORT_SYMBOL(mpt_HardResetHandler);
5978 EXPORT_SYMBOL(mpt_config);
5979 EXPORT_SYMBOL(mpt_toolbox);
5980 EXPORT_SYMBOL(mpt_findImVolumes);
5981 EXPORT_SYMBOL(mpt_read_ioc_pg_3);
5982 EXPORT_SYMBOL(mpt_alloc_fw_memory);
5983 EXPORT_SYMBOL(mpt_free_fw_memory);
5985 EXPORT_SYMBOL(mpt_register_ascqops_strings);
5986 EXPORT_SYMBOL(mpt_deregister_ascqops_strings);
5987 EXPORT_SYMBOL(mpt_v_ASCQ_TablePtr);
5988 EXPORT_SYMBOL(mpt_ASCQ_TableSz);
5989 EXPORT_SYMBOL(mpt_ScsiOpcodesPtr);
5992 static struct pci_driver mptbase_driver = {
5994 .id_table = mptbase_pci_table,
5995 .probe = mptbase_probe,
5996 .remove = __devexit_p(mptbase_remove),
5998 .shutdown = mptbase_shutdown,
6001 .suspend = mptbase_suspend,
6002 .resume = mptbase_resume,
6006 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6008 * fusion_init - Fusion MPT base driver initialization routine.
6010 * Returns 0 for success, non-zero for failure.
6018 if (FusionInitCalled++) {
6019 dprintk((KERN_INFO MYNAM ": INFO - Driver late-init entry point called\n"));
6023 show_mptmod_ver(my_NAME, my_VERSION);
6024 printk(KERN_INFO COPYRIGHT "\n");
6026 for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
6027 MptCallbacks[i] = NULL;
6028 MptDriverClass[i] = MPTUNKNOWN_DRIVER;
6029 MptEvHandlers[i] = NULL;
6030 MptResetHandlers[i] = NULL;
6035 /* NEW! 20010120 -sralston
6036 * Register ourselves (mptbase) in order to facilitate
6037 * EventNotification handling.
6039 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
6041 /* Register for hard reset handling callbacks.
6043 if (mpt_reset_register(mpt_base_index, mpt_ioc_reset) == 0) {
6044 dprintk((KERN_INFO MYNAM ": Register for IOC reset notification\n"));
6049 #ifdef CONFIG_PROC_FS
6050 (void) procmpt_create();
6052 r = pci_module_init(&mptbase_driver);
6059 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6061 * fusion_exit - Perform driver unload cleanup.
6063 * This routine frees all resources associated with each MPT adapter
6064 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
6070 dexitprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
6072 pci_unregister_driver(&mptbase_driver);
6073 mpt_reset_deregister(mpt_base_index);
6075 #ifdef CONFIG_PROC_FS
6081 module_init(fusion_init);
6082 module_exit(fusion_exit);