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 #define WHOINIT_UNKNOWN 0xAA
144 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
148 /* Adapter link list */
150 /* Callback lookup table */
151 static MPT_CALLBACK MptCallbacks
[MPT_MAX_PROTOCOL_DRIVERS
];
152 /* Protocol driver class lookup table */
153 static int MptDriverClass
[MPT_MAX_PROTOCOL_DRIVERS
];
154 /* Event handler lookup table */
155 static MPT_EVHANDLER MptEvHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
156 /* Reset handler lookup table */
157 static MPT_RESETHANDLER MptResetHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
158 static struct mpt_pci_driver
*MptDeviceDriverHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
160 static int FusionInitCalled
= 0;
161 static int mpt_base_index
= -1;
162 static int last_drv_idx
= -1;
164 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq
);
166 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
170 static irqreturn_t
mpt_interrupt(int irq
, void *bus_id
, struct pt_regs
*r
);
171 static int mpt_base_reply(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*req
, MPT_FRAME_HDR
*reply
);
173 static int mpt_do_ioc_recovery(MPT_ADAPTER
*ioc
, u32 reason
, int sleepFlag
);
174 static void mpt_detect_bound_ports(MPT_ADAPTER
*ioc
, struct pci_dev
*pdev
);
175 static void mpt_adapter_disable(MPT_ADAPTER
*ioc
);
176 static void mpt_adapter_dispose(MPT_ADAPTER
*ioc
);
178 static void MptDisplayIocCapabilities(MPT_ADAPTER
*ioc
);
179 static int MakeIocReady(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
);
180 //static u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
181 static int GetIocFacts(MPT_ADAPTER
*ioc
, int sleepFlag
, int reason
);
182 static int GetPortFacts(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
);
183 static int SendIocInit(MPT_ADAPTER
*ioc
, int sleepFlag
);
184 static int SendPortEnable(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
);
185 static int mpt_do_upload(MPT_ADAPTER
*ioc
, int sleepFlag
);
186 static int mpt_downloadboot(MPT_ADAPTER
*ioc
, int sleepFlag
);
187 static int mpt_diag_reset(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
);
188 static int KickStart(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
);
189 static int SendIocReset(MPT_ADAPTER
*ioc
, u8 reset_type
, int sleepFlag
);
190 static int PrimeIocFifos(MPT_ADAPTER
*ioc
);
191 static int WaitForDoorbellAck(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
192 static int WaitForDoorbellInt(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
193 static int WaitForDoorbellReply(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
194 static int GetLanConfigPages(MPT_ADAPTER
*ioc
);
195 static int GetFcPortPage0(MPT_ADAPTER
*ioc
, int portnum
);
196 static int GetIoUnitPage2(MPT_ADAPTER
*ioc
);
197 static int mpt_GetScsiPortSettings(MPT_ADAPTER
*ioc
, int portnum
);
198 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER
*ioc
, int portnum
);
199 static void mpt_read_ioc_pg_1(MPT_ADAPTER
*ioc
);
200 static void mpt_read_ioc_pg_4(MPT_ADAPTER
*ioc
);
201 static void mpt_timer_expired(unsigned long data
);
202 static int SendEventNotification(MPT_ADAPTER
*ioc
, u8 EvSwitch
);
203 static int SendEventAck(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*evnp
);
205 #ifdef CONFIG_PROC_FS
206 static int procmpt_summary_read(char *buf
, char **start
, off_t offset
,
207 int request
, int *eof
, void *data
);
208 static int procmpt_version_read(char *buf
, char **start
, off_t offset
,
209 int request
, int *eof
, void *data
);
210 static int procmpt_iocinfo_read(char *buf
, char **start
, off_t offset
,
211 int request
, int *eof
, void *data
);
213 static void mpt_get_fw_exp_ver(char *buf
, MPT_ADAPTER
*ioc
);
215 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
216 static int ProcessEventNotification(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*evReply
, int *evHandlers
);
217 static void mpt_sp_ioc_info(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
);
218 static void mpt_fc_log_info(MPT_ADAPTER
*ioc
, u32 log_info
);
219 static void mpt_sp_log_info(MPT_ADAPTER
*ioc
, u32 log_info
);
221 /* module entry point */
222 static int __devinit
mptbase_probe (struct pci_dev
*, const struct pci_device_id
*);
223 static void __devexit
mptbase_remove(struct pci_dev
*);
224 static void mptbase_shutdown(struct device
* );
225 static int __init
fusion_init (void);
226 static void __exit
fusion_exit (void);
228 /****************************************************************************
232 static struct pci_device_id mptbase_pci_table
[] = {
233 { PCI_VENDOR_ID_LSI_LOGIC
, PCI_DEVICE_ID_LSI_FC909
,
234 PCI_ANY_ID
, PCI_ANY_ID
},
235 { PCI_VENDOR_ID_LSI_LOGIC
, PCI_DEVICE_ID_LSI_FC929
,
236 PCI_ANY_ID
, PCI_ANY_ID
},
237 { PCI_VENDOR_ID_LSI_LOGIC
, PCI_DEVICE_ID_LSI_FC919
,
238 PCI_ANY_ID
, PCI_ANY_ID
},
239 { PCI_VENDOR_ID_LSI_LOGIC
, PCI_DEVICE_ID_LSI_FC929X
,
240 PCI_ANY_ID
, PCI_ANY_ID
},
241 { PCI_VENDOR_ID_LSI_LOGIC
, PCI_DEVICE_ID_LSI_FC919X
,
242 PCI_ANY_ID
, PCI_ANY_ID
},
243 { PCI_VENDOR_ID_LSI_LOGIC
, PCI_DEVICE_ID_LSI_53C1030
,
244 PCI_ANY_ID
, PCI_ANY_ID
},
245 { PCI_VENDOR_ID_LSI_LOGIC
, PCI_DEVICE_ID_LSI_1030_53C1035
,
246 PCI_ANY_ID
, PCI_ANY_ID
},
247 {0} /* Terminating entry */
249 MODULE_DEVICE_TABLE(pci
, mptbase_pci_table
);
251 #define CHIPREG_READ32(addr) readl_relaxed(addr)
252 #define CHIPREG_READ32_dmasync(addr) readl(addr)
253 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
254 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
255 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
257 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
259 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
260 * @irq: irq number (not used)
261 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
262 * @r: pt_regs pointer (not used)
264 * This routine is registered via the request_irq() kernel API call,
265 * and handles all interrupts generated from a specific MPT adapter
266 * (also referred to as a IO Controller or IOC).
267 * This routine must clear the interrupt from the adapter and does
268 * so by reading the reply FIFO. Multiple replies may be processed
269 * per single call to this routine; up to MPT_MAX_REPLIES_PER_ISR
270 * which is currently set to 32 in mptbase.h.
272 * This routine handles register-level access of the adapter but
273 * dispatches (calls) a protocol-specific callback routine to handle
274 * the protocol-specific details of the MPT request completion.
277 mpt_interrupt(int irq
, void *bus_id
, struct pt_regs
*r
)
288 ioc
= (MPT_ADAPTER
*)bus_id
;
291 * Drain the reply FIFO!
293 * NOTES: I've seen up to 10 replies processed in this loop, so far...
294 * Update: I've seen up to 9182 replies processed in this loop! ??
295 * Update: Limit ourselves to processing max of N replies
300 if ((pa
= CHIPREG_READ32_dmasync(&ioc
->chip
->ReplyFifo
)) == 0xFFFFFFFF)
307 * Check for non-TURBO reply!
309 if (pa
& MPI_ADDRESS_REPLY_A_BIT
) {
313 /* non-TURBO reply! Hmmm, something may be up...
314 * Newest turbo reply mechanism; get address
315 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
318 /* Map DMA address of reply header to cpu address.
319 * pa is 32 bits - but the dma address may be 32 or 64 bits
320 * get offset based only only the low addresses
322 reply_dma_low
= (pa
= (pa
<< 1));
323 mr
= (MPT_FRAME_HDR
*)((u8
*)ioc
->reply_frames
+
324 (reply_dma_low
- ioc
->reply_frames_low_dma
));
326 req_idx
= le16_to_cpu(mr
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
327 cb_idx
= mr
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
;
328 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
330 dmfprintk((MYIOC_s_INFO_FMT
"Got non-TURBO reply=%p req_idx=%x\n",
331 ioc
->name
, mr
, req_idx
));
332 DBG_DUMP_REPLY_FRAME(mr
)
334 /* NEW! 20010301 -sralston
335 * Check/log IOC log info
337 ioc_stat
= le16_to_cpu(mr
->u
.reply
.IOCStatus
);
338 if (ioc_stat
& MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE
) {
339 u32 log_info
= le32_to_cpu(mr
->u
.reply
.IOCLogInfo
);
340 if ((int)ioc
->chip_type
<= (int)FC929
)
341 mpt_fc_log_info(ioc
, log_info
);
343 mpt_sp_log_info(ioc
, log_info
);
345 if (ioc_stat
& MPI_IOCSTATUS_MASK
) {
346 if ((int)ioc
->chip_type
<= (int)FC929
)
349 mpt_sp_ioc_info(ioc
, (u32
)ioc_stat
, mf
);
353 * Process turbo (context) reply...
355 dmfprintk((MYIOC_s_INFO_FMT
"Got TURBO reply req_idx=%08x\n", ioc
->name
, pa
));
356 type
= (pa
>> MPI_CONTEXT_REPLY_TYPE_SHIFT
);
357 if (type
== MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET
) {
358 cb_idx
= mpt_stm_index
;
360 mr
= (MPT_FRAME_HDR
*) CAST_U32_TO_PTR(pa
);
361 } else if (type
== MPI_CONTEXT_REPLY_TYPE_LAN
) {
362 cb_idx
= mpt_lan_index
;
364 * BUG FIX! 20001218 -sralston
365 * Blind set of mf to NULL here was fatal
366 * after lan_reply says "freeme"
367 * Fix sort of combined with an optimization here;
368 * added explicit check for case where lan_reply
369 * was just returning 1 and doing nothing else.
370 * For this case skip the callback, but set up
371 * proper mf value first here:-)
373 if ((pa
& 0x58000000) == 0x58000000) {
374 req_idx
= pa
& 0x0000FFFF;
375 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
378 * IMPORTANT! Invalidate the callback!
384 mr
= (MPT_FRAME_HDR
*) CAST_U32_TO_PTR(pa
);
386 req_idx
= pa
& 0x0000FFFF;
387 cb_idx
= (pa
& 0x00FF0000) >> 16;
388 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
391 pa
= 0; /* No reply flush! */
395 if ((int)ioc
->chip_type
> (int)FC929
) {
396 /* Verify mf, mr are reasonable.
398 if ((mf
) && ((mf
>= MPT_INDEX_2_MFPTR(ioc
, ioc
->req_depth
))
399 || (mf
< ioc
->req_frames
)) ) {
400 printk(MYIOC_s_WARN_FMT
401 "mpt_interrupt: Invalid mf (%p) req_idx (%d)!\n", ioc
->name
, (void *)mf
, req_idx
);
406 if ((pa
) && (mr
) && ((mr
>= MPT_INDEX_2_RFPTR(ioc
, ioc
->req_depth
))
407 || (mr
< ioc
->reply_frames
)) ) {
408 printk(MYIOC_s_WARN_FMT
409 "mpt_interrupt: Invalid rf (%p)!\n", ioc
->name
, (void *)mr
);
414 if (cb_idx
> (MPT_MAX_PROTOCOL_DRIVERS
-1)) {
415 printk(MYIOC_s_WARN_FMT
416 "mpt_interrupt: Invalid cb_idx (%d)!\n", ioc
->name
, cb_idx
);
424 /* Check for (valid) IO callback! */
426 /* Do the callback! */
427 freeme
= (*(MptCallbacks
[cb_idx
]))(ioc
, mf
, mr
);
431 /* Flush (non-TURBO) reply with a WRITE! */
432 CHIPREG_WRITE32(&ioc
->chip
->ReplyFifo
, pa
);
438 /* Put Request back on FreeQ! */
439 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
440 Q_ADD_TAIL(&ioc
->FreeQ
, &mf
->u
.frame
.linkage
, MPT_FRAME_HDR
);
444 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
448 } /* drain reply FIFO */
453 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
455 * mpt_base_reply - MPT base driver's callback routine; all base driver
456 * "internal" request/reply processing is routed here.
457 * Currently used for EventNotification and EventAck handling.
458 * @ioc: Pointer to MPT_ADAPTER structure
459 * @mf: Pointer to original MPT request frame
460 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
462 * Returns 1 indicating original alloc'd request frame ptr
463 * should be freed, or 0 if it shouldn't.
466 mpt_base_reply(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
, MPT_FRAME_HDR
*reply
)
471 dprintk((MYIOC_s_INFO_FMT
"mpt_base_reply() called\n", ioc
->name
));
474 (mf
>= MPT_INDEX_2_MFPTR(ioc
, ioc
->req_depth
))) {
475 printk(MYIOC_s_ERR_FMT
"NULL or BAD request frame ptr! (=%p)\n",
476 ioc
->name
, (void *)mf
);
481 dprintk((MYIOC_s_ERR_FMT
"Unexpected NULL Event (turbo?) reply!\n",
486 if (!(reply
->u
.hdr
.MsgFlags
& MPI_MSGFLAGS_CONTINUATION_REPLY
)) {
487 dmfprintk((KERN_INFO MYNAM
": Original request frame (@%p) header\n", mf
));
488 DBG_DUMP_REQUEST_FRAME_HDR(mf
)
491 func
= reply
->u
.hdr
.Function
;
492 dprintk((MYIOC_s_INFO_FMT
"mpt_base_reply, Function=%02Xh\n",
495 if (func
== MPI_FUNCTION_EVENT_NOTIFICATION
) {
496 EventNotificationReply_t
*pEvReply
= (EventNotificationReply_t
*) reply
;
500 results
= ProcessEventNotification(ioc
, pEvReply
, &evHandlers
);
501 if (results
!= evHandlers
) {
502 /* CHECKME! Any special handling needed here? */
503 devtprintk((MYIOC_s_WARN_FMT
"Called %d event handlers, sum results = %d\n",
504 ioc
->name
, evHandlers
, results
));
508 * Hmmm... It seems that EventNotificationReply is an exception
509 * to the rule of one reply per request.
511 if (pEvReply
->MsgFlags
& MPI_MSGFLAGS_CONTINUATION_REPLY
)
514 #ifdef CONFIG_PROC_FS
515 // LogEvent(ioc, pEvReply);
518 } else if (func
== MPI_FUNCTION_EVENT_ACK
) {
519 dprintk((MYIOC_s_INFO_FMT
"mpt_base_reply, EventAck reply received\n",
521 } else if (func
== MPI_FUNCTION_CONFIG
||
522 func
== MPI_FUNCTION_TOOLBOX
) {
526 dcprintk((MYIOC_s_INFO_FMT
"config_complete (mf=%p,mr=%p)\n",
527 ioc
->name
, mf
, reply
));
529 pCfg
= * ((CONFIGPARMS
**)((u8
*) mf
+ ioc
->req_sz
- sizeof(void *)));
532 /* disable timer and remove from linked list */
533 del_timer(&pCfg
->timer
);
535 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
536 Q_DEL_ITEM(&pCfg
->linkage
);
537 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
540 * If IOC Status is SUCCESS, save the header
541 * and set the status code to GOOD.
543 pCfg
->status
= MPT_CONFIG_ERROR
;
545 ConfigReply_t
*pReply
= (ConfigReply_t
*)reply
;
548 status
= le16_to_cpu(pReply
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
549 dcprintk((KERN_NOTICE
" IOCStatus=%04xh, IOCLogInfo=%08xh\n",
550 status
, le32_to_cpu(pReply
->IOCLogInfo
)));
552 pCfg
->status
= status
;
553 if (status
== MPI_IOCSTATUS_SUCCESS
) {
554 pCfg
->hdr
->PageVersion
= pReply
->Header
.PageVersion
;
555 pCfg
->hdr
->PageLength
= pReply
->Header
.PageLength
;
556 pCfg
->hdr
->PageNumber
= pReply
->Header
.PageNumber
;
557 pCfg
->hdr
->PageType
= pReply
->Header
.PageType
;
562 * Wake up the original calling thread
568 printk(MYIOC_s_ERR_FMT
"Unexpected msg function (=%02Xh) reply received!\n",
573 * Conditionally tell caller to free the original
574 * EventNotification/EventAck/unexpected request frame!
579 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
581 * mpt_register - Register protocol-specific main callback handler.
582 * @cbfunc: callback function pointer
583 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
585 * This routine is called by a protocol-specific driver (SCSI host,
586 * LAN, SCSI target) to register it's reply callback routine. Each
587 * protocol-specific driver must do this before it will be able to
588 * use any IOC resources, such as obtaining request frames.
590 * NOTES: The SCSI protocol driver currently calls this routine thrice
591 * in order to register separate callbacks; one for "normal" SCSI IO;
592 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
594 * Returns a positive integer valued "handle" in the
595 * range (and S.O.D. order) {N,...,7,6,5,...,1} if successful.
596 * Any non-positive return value (including zero!) should be considered
597 * an error by the caller.
600 mpt_register(MPT_CALLBACK cbfunc
, MPT_DRIVER_CLASS dclass
)
608 * Handle possibility of the mptscsih_detect() routine getting
609 * called *before* fusion_init!
611 if (!FusionInitCalled
) {
612 dprintk((KERN_INFO MYNAM
": Hmmm, calling fusion_init from mpt_register!\n"));
614 * NOTE! We'll get recursion here, as fusion_init()
615 * calls mpt_register()!
623 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
624 * (slot/handle 0 is reserved!)
626 for (i
= MPT_MAX_PROTOCOL_DRIVERS
-1; i
; i
--) {
627 if (MptCallbacks
[i
] == NULL
) {
628 MptCallbacks
[i
] = cbfunc
;
629 MptDriverClass
[i
] = dclass
;
630 MptEvHandlers
[i
] = NULL
;
639 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
641 * mpt_deregister - Deregister a protocol drivers resources.
642 * @cb_idx: previously registered callback handle
644 * Each protocol-specific driver should call this routine when it's
645 * module is unloaded.
648 mpt_deregister(int cb_idx
)
650 if ((cb_idx
>= 0) && (cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
)) {
651 MptCallbacks
[cb_idx
] = NULL
;
652 MptDriverClass
[cb_idx
] = MPTUNKNOWN_DRIVER
;
653 MptEvHandlers
[cb_idx
] = NULL
;
659 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
661 * mpt_event_register - Register protocol-specific event callback
663 * @cb_idx: previously registered (via mpt_register) callback handle
664 * @ev_cbfunc: callback function
666 * This routine can be called by one or more protocol-specific drivers
667 * if/when they choose to be notified of MPT events.
669 * Returns 0 for success.
672 mpt_event_register(int cb_idx
, MPT_EVHANDLER ev_cbfunc
)
674 if (cb_idx
< 1 || cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
677 MptEvHandlers
[cb_idx
] = ev_cbfunc
;
681 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
683 * mpt_event_deregister - Deregister protocol-specific event callback
685 * @cb_idx: previously registered callback handle
687 * Each protocol-specific driver should call this routine
688 * when it does not (or can no longer) handle events,
689 * or when it's module is unloaded.
692 mpt_event_deregister(int cb_idx
)
694 if (cb_idx
< 1 || cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
697 MptEvHandlers
[cb_idx
] = NULL
;
700 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
702 * mpt_reset_register - Register protocol-specific IOC reset handler.
703 * @cb_idx: previously registered (via mpt_register) callback handle
704 * @reset_func: reset function
706 * This routine can be called by one or more protocol-specific drivers
707 * if/when they choose to be notified of IOC resets.
709 * Returns 0 for success.
712 mpt_reset_register(int cb_idx
, MPT_RESETHANDLER reset_func
)
714 if (cb_idx
< 1 || cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
717 MptResetHandlers
[cb_idx
] = reset_func
;
721 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
723 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
724 * @cb_idx: previously registered callback handle
726 * Each protocol-specific driver should call this routine
727 * when it does not (or can no longer) handle IOC reset handling,
728 * or when it's module is unloaded.
731 mpt_reset_deregister(int cb_idx
)
733 if (cb_idx
< 1 || cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
736 MptResetHandlers
[cb_idx
] = NULL
;
739 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
741 * mpt_device_driver_register - Register device driver hooks
744 mpt_device_driver_register(struct mpt_pci_driver
* dd_cbfunc
, int cb_idx
)
749 if (cb_idx
< 1 || cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
) {
754 MptDeviceDriverHandlers
[cb_idx
] = dd_cbfunc
;
756 /* call per pci device probe entry point */
757 list_for_each_entry(ioc
, &ioc_list
, list
) {
758 if(dd_cbfunc
->probe
) {
759 error
= dd_cbfunc
->probe(ioc
->pcidev
,
760 ioc
->pcidev
->driver
->id_table
);
769 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
771 * mpt_device_driver_deregister - DeRegister device driver hooks
774 mpt_device_driver_deregister(int cb_idx
)
776 struct mpt_pci_driver
*dd_cbfunc
;
779 if (cb_idx
< 1 || cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
782 dd_cbfunc
= MptDeviceDriverHandlers
[cb_idx
];
784 list_for_each_entry(ioc
, &ioc_list
, list
) {
785 if (dd_cbfunc
->remove
)
786 dd_cbfunc
->remove(ioc
->pcidev
);
789 MptDeviceDriverHandlers
[cb_idx
] = NULL
;
793 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
795 * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
796 * allocated per MPT adapter.
797 * @handle: Handle of registered MPT protocol driver
798 * @ioc: Pointer to MPT adapter structure
800 * Returns pointer to a MPT request frame or %NULL if none are available
801 * or IOC is not active.
804 mpt_get_msg_frame(int handle
, MPT_ADAPTER
*ioc
)
808 u16 req_idx
; /* Request index */
810 /* validate handle and ioc identifier */
814 printk(KERN_WARNING
"IOC Not Active! mpt_get_msg_frame returning NULL!\n");
817 /* If interrupts are not attached, do not return a request frame */
821 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
822 if (! Q_IS_EMPTY(&ioc
->FreeQ
)) {
825 mf
= ioc
->FreeQ
.head
;
826 Q_DEL_ITEM(&mf
->u
.frame
.linkage
);
827 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= handle
; /* byte */
828 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
830 req_idx
= cpu_to_le16(req_offset
/ ioc
->req_sz
);
831 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= req_idx
;
832 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
833 ioc
->RequestNB
[req_idx
] = ioc
->NB_for_64_byte_frame
; /* Default, will be changed if necessary in SG generation */
840 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
844 printk(KERN_WARNING
"IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", ioc
->mfcnt
, ioc
->req_depth
);
846 if (mfcounter
== PRINT_MF_COUNT
)
847 printk(KERN_INFO
"MF Count 0x%x Max 0x%x \n", ioc
->mfcnt
, ioc
->req_depth
);
850 dmfprintk((KERN_INFO MYNAM
": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",
851 ioc
->name
, handle
, ioc
->id
, mf
));
855 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
857 * mpt_put_msg_frame - Send a protocol specific MPT request frame
859 * @handle: Handle of registered MPT protocol driver
860 * @ioc: Pointer to MPT adapter structure
861 * @mf: Pointer to MPT request frame
863 * This routine posts a MPT request frame to the request post FIFO of a
864 * specific MPT adapter.
867 mpt_put_msg_frame(int handle
, MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
871 u16 req_idx
; /* Request index */
873 /* ensure values are reset properly! */
874 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= handle
; /* byte */
875 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
877 req_idx
= cpu_to_le16(req_offset
/ ioc
->req_sz
);
878 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= req_idx
;
879 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
881 #ifdef MPT_DEBUG_MSG_FRAME
883 u32
*m
= mf
->u
.frame
.hwhdr
.__hdr
;
886 printk(KERN_INFO MYNAM
": %s: About to Put msg frame @ %p:\n" KERN_INFO
" ",
888 n
= ioc
->req_sz
/4 - 1;
891 for (ii
=0; ii
<=n
; ii
++) {
892 if (ii
&& ((ii
%8)==0))
893 printk("\n" KERN_INFO
" ");
894 printk(" %08x", le32_to_cpu(m
[ii
]));
900 mf_dma_addr
= (ioc
->req_frames_low_dma
+ req_offset
) | ioc
->RequestNB
[req_idx
];
901 dsgprintk((MYIOC_s_INFO_FMT
"mf_dma_addr=%x req_idx=%d RequestNB=%x\n", ioc
->name
, mf_dma_addr
, req_idx
, ioc
->RequestNB
[req_idx
]));
902 CHIPREG_WRITE32(&ioc
->chip
->RequestFifo
, mf_dma_addr
);
905 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
907 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
908 * @handle: Handle of registered MPT protocol driver
909 * @ioc: Pointer to MPT adapter structure
910 * @mf: Pointer to MPT request frame
912 * This routine places a MPT request frame back on the MPT adapter's
916 mpt_free_msg_frame(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
920 /* Put Request back on FreeQ! */
921 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
922 Q_ADD_TAIL(&ioc
->FreeQ
, &mf
->u
.frame
.linkage
, MPT_FRAME_HDR
);
926 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
929 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
931 * mpt_add_sge - Place a simple SGE at address pAddr.
932 * @pAddr: virtual address for SGE
933 * @flagslength: SGE flags and data transfer length
934 * @dma_addr: Physical address
936 * This routine places a MPT request frame back on the MPT adapter's
940 mpt_add_sge(char *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
942 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
943 SGESimple64_t
*pSge
= (SGESimple64_t
*) pAddr
;
944 u32 tmp
= dma_addr
& 0xFFFFFFFF;
946 pSge
->FlagsLength
= cpu_to_le32(flagslength
);
947 pSge
->Address
.Low
= cpu_to_le32(tmp
);
948 tmp
= (u32
) ((u64
)dma_addr
>> 32);
949 pSge
->Address
.High
= cpu_to_le32(tmp
);
952 SGESimple32_t
*pSge
= (SGESimple32_t
*) pAddr
;
953 pSge
->FlagsLength
= cpu_to_le32(flagslength
);
954 pSge
->Address
= cpu_to_le32(dma_addr
);
958 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
960 * mpt_add_chain - Place a chain SGE at address pAddr.
961 * @pAddr: virtual address for SGE
962 * @next: nextChainOffset value (u32's)
963 * @length: length of next SGL segment
964 * @dma_addr: Physical address
966 * This routine places a MPT request frame back on the MPT adapter's
970 mpt_add_chain(char *pAddr
, u8 next
, u16 length
, dma_addr_t dma_addr
)
972 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
973 SGEChain64_t
*pChain
= (SGEChain64_t
*) pAddr
;
974 u32 tmp
= dma_addr
& 0xFFFFFFFF;
976 pChain
->Length
= cpu_to_le16(length
);
977 pChain
->Flags
= MPI_SGE_FLAGS_CHAIN_ELEMENT
| mpt_addr_size();
979 pChain
->NextChainOffset
= next
;
981 pChain
->Address
.Low
= cpu_to_le32(tmp
);
982 tmp
= (u32
) ((u64
)dma_addr
>> 32);
983 pChain
->Address
.High
= cpu_to_le32(tmp
);
985 SGEChain32_t
*pChain
= (SGEChain32_t
*) pAddr
;
986 pChain
->Length
= cpu_to_le16(length
);
987 pChain
->Flags
= MPI_SGE_FLAGS_CHAIN_ELEMENT
| mpt_addr_size();
988 pChain
->NextChainOffset
= next
;
989 pChain
->Address
= cpu_to_le32(dma_addr
);
993 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
995 * mpt_send_handshake_request - Send MPT request via doorbell
997 * @handle: Handle of registered MPT protocol driver
998 * @ioc: Pointer to MPT adapter structure
999 * @reqBytes: Size of the request in bytes
1000 * @req: Pointer to MPT request frame
1001 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1003 * This routine is used exclusively to send MptScsiTaskMgmt
1004 * requests since they are required to be sent via doorbell handshake.
1006 * NOTE: It is the callers responsibility to byte-swap fields in the
1007 * request which are greater than 1 byte in size.
1009 * Returns 0 for success, non-zero for failure.
1012 mpt_send_handshake_request(int handle
, MPT_ADAPTER
*ioc
, int reqBytes
, u32
*req
, int sleepFlag
)
1018 /* State is known to be good upon entering
1019 * this function so issue the bus reset
1024 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1025 * setting cb_idx/req_idx. But ONLY if this request
1026 * is in proper (pre-alloc'd) request buffer range...
1028 ii
= MFPTR_2_MPT_INDEX(ioc
,(MPT_FRAME_HDR
*)req
);
1029 if (reqBytes
>= 12 && ii
>= 0 && ii
< ioc
->req_depth
) {
1030 MPT_FRAME_HDR
*mf
= (MPT_FRAME_HDR
*)req
;
1031 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(ii
);
1032 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= handle
;
1035 /* Make sure there are no doorbells */
1036 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1038 CHIPREG_WRITE32(&ioc
->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 if ((ii
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0) {
1047 /* Read doorbell and check for active bit */
1048 if (!(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & MPI_DOORBELL_ACTIVE
))
1051 dhsprintk((KERN_INFO MYNAM
": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
1054 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1056 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
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(&ioc
->chip
->Doorbell
, word
);
1070 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1076 if (r
>= 0 && WaitForDoorbellInt(ioc
, 10, sleepFlag
) >= 0)
1081 /* Make sure there are no doorbells */
1082 CHIPREG_WRITE32(&ioc
->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 #ifdef CONFIG_PROC_FS
1145 struct proc_dir_entry
*dent
, *ent
;
1148 if (pci_enable_device(pdev
))
1151 dinitprintk((KERN_WARNING MYNAM
": mpt_adapter_install\n"));
1153 if (!pci_set_dma_mask(pdev
, mask
)) {
1154 dprintk((KERN_INFO MYNAM
1155 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1156 } else if (pci_set_dma_mask(pdev
, (u64
) 0xffffffff)) {
1157 printk(KERN_WARNING MYNAM
": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1161 if (!pci_set_consistent_dma_mask(pdev
, mask
))
1162 dprintk((KERN_INFO MYNAM
1163 ": Using 64 bit consistent mask\n"));
1165 dprintk((KERN_INFO MYNAM
1166 ": Not using 64 bit consistent mask\n"));
1168 ioc
= kmalloc(sizeof(MPT_ADAPTER
), GFP_ATOMIC
);
1170 printk(KERN_ERR MYNAM
": ERROR - Insufficient memory to add adapter!\n");
1173 memset(ioc
, 0, sizeof(MPT_ADAPTER
));
1174 ioc
->alloc_total
= sizeof(MPT_ADAPTER
);
1175 ioc
->req_sz
= MPT_DEFAULT_FRAME_SIZE
; /* avoid div by zero! */
1176 ioc
->reply_sz
= MPT_REPLY_FRAME_SIZE
;
1179 ioc
->diagPending
= 0;
1180 spin_lock_init(&ioc
->diagLock
);
1182 /* Initialize the event logging.
1184 ioc
->eventTypes
= 0; /* None */
1185 ioc
->eventContext
= 0;
1186 ioc
->eventLogSize
= 0;
1193 ioc
->cached_fw
= NULL
;
1195 /* Initilize SCSI Config Data structure
1197 memset(&ioc
->spi_data
, 0, sizeof(ScsiCfgData
));
1199 /* Initialize the running configQ head.
1201 Q_INIT(&ioc
->configQ
, Q_ITEM
);
1203 /* Find lookup slot. */
1204 INIT_LIST_HEAD(&ioc
->list
);
1205 ioc
->id
= mpt_ids
++;
1207 mem_phys
= msize
= 0;
1209 for (ii
=0; ii
< DEVICE_COUNT_RESOURCE
; ii
++) {
1210 if (pci_resource_flags(pdev
, ii
) & PCI_BASE_ADDRESS_SPACE_IO
) {
1211 /* Get I/O space! */
1212 port
= pci_resource_start(pdev
, ii
);
1213 psize
= pci_resource_len(pdev
,ii
);
1216 mem_phys
= pci_resource_start(pdev
, ii
);
1217 msize
= pci_resource_len(pdev
,ii
);
1221 ioc
->mem_size
= msize
;
1223 if (ii
== DEVICE_COUNT_RESOURCE
) {
1224 printk(KERN_ERR MYNAM
": ERROR - MPT adapter has no memory regions defined!\n");
1229 dinitprintk((KERN_INFO MYNAM
": MPT adapter @ %lx, msize=%dd bytes\n", mem_phys
, msize
));
1230 dinitprintk((KERN_INFO MYNAM
": (port i/o @ %lx, psize=%dd bytes)\n", port
, psize
));
1233 /* Get logical ptr for PciMem0 space */
1234 /*mem = ioremap(mem_phys, msize);*/
1235 mem
= ioremap(mem_phys
, 0x100);
1237 printk(KERN_ERR MYNAM
": ERROR - Unable to map adapter memory!\n");
1242 dinitprintk((KERN_INFO MYNAM
": mem = %p, mem_phys = %lx\n", mem
, mem_phys
));
1244 dinitprintk((KERN_INFO MYNAM
": facts @ %p, pfacts[0] @ %p\n",
1245 &ioc
->facts
, &ioc
->pfacts
[0]));
1247 ioc
->mem_phys
= mem_phys
;
1248 ioc
->chip
= (SYSIF_REGS
*)mem
;
1250 /* Save Port IO values in case we need to do downloadboot */
1252 u8
*pmem
= (u8
*)port
;
1253 ioc
->pio_mem_phys
= port
;
1254 ioc
->pio_chip
= (SYSIF_REGS
*)pmem
;
1257 ioc
->chip_type
= FCUNK
;
1258 if (pdev
->device
== MPI_MANUFACTPAGE_DEVICEID_FC909
) {
1259 ioc
->chip_type
= FC909
;
1260 ioc
->prod_name
= "LSIFC909";
1262 if (pdev
->device
== MPI_MANUFACTPAGE_DEVICEID_FC929
) {
1263 ioc
->chip_type
= FC929
;
1264 ioc
->prod_name
= "LSIFC929";
1266 else if (pdev
->device
== MPI_MANUFACTPAGE_DEVICEID_FC919
) {
1267 ioc
->chip_type
= FC919
;
1268 ioc
->prod_name
= "LSIFC919";
1270 else if (pdev
->device
== MPI_MANUFACTPAGE_DEVICEID_FC929X
) {
1271 ioc
->chip_type
= FC929X
;
1272 pci_read_config_byte(pdev
, PCI_CLASS_REVISION
, &revision
);
1273 if (revision
< XL_929
) {
1274 ioc
->prod_name
= "LSIFC929X";
1275 /* 929X Chip Fix. Set Split transactions level
1276 * for PCIX. Set MOST bits to zero.
1278 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1280 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1282 ioc
->prod_name
= "LSIFC929XL";
1283 /* 929XL Chip Fix. Set MMRBC to 0x08.
1285 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1287 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1290 else if (pdev
->device
== MPI_MANUFACTPAGE_DEVICEID_FC919X
) {
1291 ioc
->chip_type
= FC919X
;
1292 ioc
->prod_name
= "LSIFC919X";
1293 /* 919X Chip Fix. Set Split transactions level
1294 * for PCIX. Set MOST bits to zero.
1296 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1298 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1300 else if (pdev
->device
== MPI_MANUFACTPAGE_DEVID_53C1030
) {
1301 ioc
->chip_type
= C1030
;
1302 ioc
->prod_name
= "LSI53C1030";
1303 /* 1030 Chip Fix. Disable Split transactions
1304 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1306 pci_read_config_byte(pdev
, PCI_CLASS_REVISION
, &revision
);
1307 if (revision
< C0_1030
) {
1308 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1310 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1313 else if (pdev
->device
== MPI_MANUFACTPAGE_DEVID_1030_53C1035
) {
1314 ioc
->chip_type
= C1035
;
1315 ioc
->prod_name
= "LSI53C1035";
1318 sprintf(ioc
->name
, "ioc%d", ioc
->id
);
1320 spin_lock_init(&ioc
->FreeQlock
);
1323 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1325 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1327 /* Set lookup ptr. */
1328 list_add_tail(&ioc
->list
, &ioc_list
);
1332 r
= request_irq(pdev
->irq
, mpt_interrupt
, SA_SHIRQ
, ioc
->name
, ioc
);
1336 printk(MYIOC_s_ERR_FMT
"Unable to allocate interrupt %d!\n",
1337 ioc
->name
, pdev
->irq
);
1339 printk(MYIOC_s_ERR_FMT
"Unable to allocate interrupt %s!\n",
1340 ioc
->name
, __irq_itoa(pdev
->irq
));
1342 list_del(&ioc
->list
);
1348 ioc
->pci_irq
= pdev
->irq
;
1350 pci_set_master(pdev
); /* ?? */
1351 pci_set_drvdata(pdev
, ioc
);
1354 dprintk((KERN_INFO MYNAM
": %s installed at interrupt %d\n", ioc
->name
, pdev
->irq
));
1356 dprintk((KERN_INFO MYNAM
": %s installed at interrupt %s\n", ioc
->name
, __irq_itoa(pdev
->irq
)));
1360 /* NEW! 20010220 -sralston
1361 * Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1363 if ((ioc
->chip_type
== FC929
) || (ioc
->chip_type
== C1030
)
1364 || (ioc
->chip_type
== C1035
) || (ioc
->chip_type
== FC929X
))
1365 mpt_detect_bound_ports(ioc
, pdev
);
1367 if ((r
= mpt_do_ioc_recovery(ioc
,
1368 MPT_HOSTEVENT_IOC_BRINGUP
, CAN_SLEEP
)) != 0) {
1369 printk(KERN_WARNING MYNAM
1370 ": 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
);
1389 #ifdef CONFIG_PROC_FS
1391 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1393 dent
= proc_mkdir(ioc
->name
, mpt_proc_root_dir
);
1395 ent
= create_proc_entry("info", S_IFREG
|S_IRUGO
, dent
);
1397 ent
->read_proc
= procmpt_iocinfo_read
;
1400 ent
= create_proc_entry("summary", S_IFREG
|S_IRUGO
, dent
);
1402 ent
->read_proc
= procmpt_summary_read
;
1411 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1413 * mptbase_remove - Remove a PCI intelligent MPT adapter.
1414 * @pdev: Pointer to pci_dev structure
1418 static void __devexit
1419 mptbase_remove(struct pci_dev
*pdev
)
1421 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1425 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/summary", ioc
->name
);
1426 remove_proc_entry(pname
, NULL
);
1427 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/info", ioc
->name
);
1428 remove_proc_entry(pname
, NULL
);
1429 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s", ioc
->name
);
1430 remove_proc_entry(pname
, NULL
);
1432 /* call per device driver remove entry point */
1433 for(ii
=0; ii
<MPT_MAX_PROTOCOL_DRIVERS
; ii
++) {
1434 if(MptDeviceDriverHandlers
[ii
] &&
1435 MptDeviceDriverHandlers
[ii
]->remove
) {
1436 MptDeviceDriverHandlers
[ii
]->remove(pdev
);
1440 /* Disable interrupts! */
1441 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1444 synchronize_irq(pdev
->irq
);
1446 /* Clear any lingering interrupt */
1447 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1449 CHIPREG_READ32(&ioc
->chip
->IntStatus
);
1451 mpt_adapter_dispose(ioc
);
1453 pci_set_drvdata(pdev
, NULL
);
1456 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1458 * mptbase_shutdown -
1462 mptbase_shutdown(struct device
* dev
)
1466 /* call per device driver shutdown entry point */
1467 for(ii
=0; ii
<MPT_MAX_PROTOCOL_DRIVERS
; ii
++) {
1468 if(MptDeviceDriverHandlers
[ii
] &&
1469 MptDeviceDriverHandlers
[ii
]->shutdown
) {
1470 MptDeviceDriverHandlers
[ii
]->shutdown(dev
);
1477 /**************************************************************************
1481 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1483 * mptbase_suspend - Fusion MPT base driver suspend routine.
1488 mptbase_suspend(struct pci_dev
*pdev
, u32 state
)
1491 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1497 device_state
=1; /* D1 */;
1501 device_state
=3; /* D3 */;
1504 return -EAGAIN
/*FIXME*/;
1508 printk(MYIOC_s_INFO_FMT
1509 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1510 ioc
->name
, pdev
, pci_name(pdev
), device_state
);
1512 /* call per device driver suspend entry point */
1513 for(ii
=0; ii
<MPT_MAX_PROTOCOL_DRIVERS
; ii
++) {
1514 if(MptDeviceDriverHandlers
[ii
] &&
1515 MptDeviceDriverHandlers
[ii
]->suspend
) {
1516 MptDeviceDriverHandlers
[ii
]->suspend(pdev
, state
);
1520 pci_save_state(pdev
, ioc
->PciState
);
1522 /* put ioc into READY_STATE */
1523 if(SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, CAN_SLEEP
)) {
1524 printk(MYIOC_s_ERR_FMT
1525 "pci-suspend: IOC msg unit reset failed!\n", ioc
->name
);
1528 /* disable interrupts */
1529 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1532 /* Clear any lingering interrupt */
1533 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1535 pci_disable_device(pdev
);
1536 pci_set_power_state(pdev
, device_state
);
1541 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1543 * mptbase_resume - Fusion MPT base driver resume routine.
1548 mptbase_resume(struct pci_dev
*pdev
)
1550 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1551 u32 device_state
= pdev
->current_state
;
1555 printk(MYIOC_s_INFO_FMT
1556 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1557 ioc
->name
, pdev
, pci_name(pdev
), device_state
);
1559 pci_set_power_state(pdev
, 0);
1560 pci_restore_state(pdev
, ioc
->PciState
);
1561 pci_enable_device(pdev
);
1563 /* enable interrupts */
1564 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, ~(MPI_HIM_RIM
));
1567 /* F/W not running */
1568 if(!CHIPREG_READ32(&ioc
->chip
->Doorbell
)) {
1569 /* enable domain validation flags */
1570 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
1571 ioc
->spi_data
.dvStatus
[ii
] |= MPT_SCSICFG_NEED_DV
;
1575 printk(MYIOC_s_INFO_FMT
1576 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1578 (mpt_GetIocState(ioc
, 1) >> MPI_IOC_STATE_SHIFT
),
1579 CHIPREG_READ32(&ioc
->chip
->Doorbell
));
1581 /* bring ioc to operational state */
1582 if ((recovery_state
= mpt_do_ioc_recovery(ioc
,
1583 MPT_HOSTEVENT_IOC_RECOVER
, CAN_SLEEP
)) != 0) {
1584 printk(MYIOC_s_INFO_FMT
1585 "pci-resume: Cannot recover, error:[%x]\n",
1586 ioc
->name
, recovery_state
);
1588 printk(MYIOC_s_INFO_FMT
1589 "pci-resume: success\n", ioc
->name
);
1592 /* call per device driver resume entry point */
1593 for(ii
=0; ii
<MPT_MAX_PROTOCOL_DRIVERS
; ii
++) {
1594 if(MptDeviceDriverHandlers
[ii
] &&
1595 MptDeviceDriverHandlers
[ii
]->resume
) {
1596 MptDeviceDriverHandlers
[ii
]->resume(pdev
);
1604 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1606 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1607 * @ioc: Pointer to MPT adapter structure
1608 * @reason: Event word / reason
1609 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1611 * This routine performs all the steps necessary to bring the IOC
1612 * to a OPERATIONAL state.
1614 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1619 * -1 if failed to get board READY
1620 * -2 if READY but IOCFacts Failed
1621 * -3 if READY but PrimeIOCFifos Failed
1622 * -4 if READY but IOCInit Failed
1625 mpt_do_ioc_recovery(MPT_ADAPTER
*ioc
, u32 reason
, int sleepFlag
)
1627 int hard_reset_done
= 0;
1628 int alt_ioc_ready
= 0;
1634 int reset_alt_ioc_active
= 0;
1636 printk(KERN_INFO MYNAM
": Initiating %s %s\n",
1637 ioc
->name
, reason
==MPT_HOSTEVENT_IOC_BRINGUP
? "bringup" : "recovery");
1639 /* Disable reply interrupts (also blocks FreeQ) */
1640 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1644 if (ioc
->alt_ioc
->active
)
1645 reset_alt_ioc_active
= 1;
1647 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1648 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
, 0xFFFFFFFF);
1649 ioc
->alt_ioc
->active
= 0;
1653 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)
1656 if ((hard_reset_done
= MakeIocReady(ioc
, hard
, sleepFlag
)) < 0) {
1657 if (hard_reset_done
== -4) {
1658 printk(KERN_WARNING MYNAM
": %s Owned by PEER..skipping!\n",
1661 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
1662 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1663 dprintk((KERN_INFO MYNAM
": alt-%s reply irq re-enabled\n",
1664 ioc
->alt_ioc
->name
));
1665 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
, ~(MPI_HIM_RIM
));
1666 ioc
->alt_ioc
->active
= 1;
1670 printk(KERN_WARNING MYNAM
": %s NOT READY WARNING!\n",
1676 /* hard_reset_done = 0 if a soft reset was performed
1677 * and 1 if a hard reset was performed.
1679 if (hard_reset_done
&& reset_alt_ioc_active
&& ioc
->alt_ioc
) {
1680 if ((rc
= MakeIocReady(ioc
->alt_ioc
, 0, sleepFlag
)) == 0)
1683 printk(KERN_WARNING MYNAM
1684 ": alt-%s: Not ready WARNING!\n",
1685 ioc
->alt_ioc
->name
);
1688 for (ii
=0; ii
<5; ii
++) {
1689 /* Get IOC facts! Allow 5 retries */
1690 if ((rc
= GetIocFacts(ioc
, sleepFlag
, reason
)) == 0)
1696 dinitprintk((MYIOC_s_INFO_FMT
"Retry IocFacts failed rc=%x\n", ioc
->name
, rc
));
1698 } else if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
1699 MptDisplayIocCapabilities(ioc
);
1702 if (alt_ioc_ready
) {
1703 if ((rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
)) != 0) {
1704 dinitprintk((MYIOC_s_INFO_FMT
"Initial Alt IocFacts failed rc=%x\n", ioc
->name
, rc
));
1705 /* Retry - alt IOC was initialized once
1707 rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
);
1710 dinitprintk((MYIOC_s_INFO_FMT
"Retry Alt IocFacts failed rc=%x\n", ioc
->name
, rc
));
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) && ((rc
= PrimeIocFifos(ioc
)) != 0))
1726 /* May need to check/upload firmware & data here!
1727 * If fails, continue with alt-ioc processing
1729 if ((ret
== 0) && ((rc
= SendIocInit(ioc
, sleepFlag
)) != 0))
1732 if (alt_ioc_ready
&& ((rc
= PrimeIocFifos(ioc
->alt_ioc
)) != 0)) {
1733 printk(KERN_WARNING MYNAM
": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1734 ioc
->alt_ioc
->name
, rc
);
1736 reset_alt_ioc_active
= 0;
1739 if (alt_ioc_ready
) {
1740 if ((rc
= 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
, rc
);
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 rc
= mpt_do_upload(ioc
, sleepFlag
);
1759 printk(KERN_WARNING MYNAM
": firmware upload failure!\n");
1765 /* Enable! (reply interrupt) */
1766 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, ~(MPI_HIM_RIM
));
1770 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
1771 /* (re)Enable alt-IOC! (reply interrupt) */
1772 dprintk((KERN_INFO MYNAM
": alt-%s reply irq re-enabled\n",
1773 ioc
->alt_ioc
->name
));
1774 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
, ~(MPI_HIM_RIM
));
1775 ioc
->alt_ioc
->active
= 1;
1778 /* NEW! 20010120 -sralston
1779 * Enable MPT base driver management of EventNotification
1780 * and EventAck handling.
1782 if ((ret
== 0) && (!ioc
->facts
.EventState
))
1783 (void) SendEventNotification(ioc
, 1); /* 1=Enable EventNotification */
1785 if (ioc
->alt_ioc
&& alt_ioc_ready
&& !ioc
->alt_ioc
->facts
.EventState
)
1786 (void) SendEventNotification(ioc
->alt_ioc
, 1); /* 1=Enable EventNotification */
1788 /* (Bugzilla:fibrebugs, #513)
1789 * Bug fix (part 2)! 20010905 -sralston
1790 * Add additional "reason" check before call to GetLanConfigPages
1791 * (combined with GetIoUnitPage2 call). This prevents a somewhat
1792 * recursive scenario; GetLanConfigPages times out, timer expired
1793 * routine calls HardResetHandler, which calls into here again,
1794 * and we try GetLanConfigPages again...
1796 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)) {
1797 if ((int)ioc
->chip_type
<= (int)FC929
) {
1799 * Pre-fetch FC port WWN and stuff...
1800 * (FCPortPage0_t stuff)
1802 for (ii
=0; ii
< ioc
->facts
.NumberOfPorts
; ii
++) {
1803 (void) GetFcPortPage0(ioc
, ii
);
1806 if ((ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) &&
1807 (ioc
->lan_cnfg_page0
.Header
.PageLength
== 0)) {
1809 * Pre-fetch the ports LAN MAC address!
1810 * (LANPage1_t stuff)
1812 (void) GetLanConfigPages(ioc
);
1815 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
1816 dprintk((MYIOC_s_INFO_FMT
"LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
1817 ioc
->name
, a
[5], a
[4], a
[3], a
[2], a
[1], a
[0] ));
1822 /* Get NVRAM and adapter maximums from SPP 0 and 2
1824 mpt_GetScsiPortSettings(ioc
, 0);
1826 /* Get version and length of SDP 1
1828 mpt_readScsiDevicePageHeaders(ioc
, 0);
1832 if (ioc
->facts
.MsgVersion
>= 0x0102)
1833 mpt_findImVolumes(ioc
);
1835 /* Check, and possibly reset, the coalescing value
1837 mpt_read_ioc_pg_1(ioc
);
1839 mpt_read_ioc_pg_4(ioc
);
1842 GetIoUnitPage2(ioc
);
1846 * Call each currently registered protocol IOC reset handler
1847 * with post-reset indication.
1848 * NOTE: If we're doing _IOC_BRINGUP, there can be no
1849 * MptResetHandlers[] registered yet.
1851 if (hard_reset_done
) {
1853 for (ii
=MPT_MAX_PROTOCOL_DRIVERS
-1; ii
; ii
--) {
1854 if ((ret
== 0) && MptResetHandlers
[ii
]) {
1855 dprintk((MYIOC_s_INFO_FMT
"Calling IOC post_reset handler #%d\n",
1857 rc
+= (*(MptResetHandlers
[ii
]))(ioc
, MPT_IOC_POST_RESET
);
1861 if (alt_ioc_ready
&& MptResetHandlers
[ii
]) {
1862 dprintk((MYIOC_s_INFO_FMT
"Calling alt-%s post_reset handler #%d\n",
1863 ioc
->name
, ioc
->alt_ioc
->name
, ii
));
1864 rc
+= (*(MptResetHandlers
[ii
]))(ioc
->alt_ioc
, MPT_IOC_POST_RESET
);
1868 /* FIXME? Examine results here? */
1874 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1876 * mpt_detect_bound_ports - Search for PCI bus/dev_function
1877 * which matches PCI bus/dev_function (+/-1) for newly discovered 929,
1878 * 929X, 1030 or 1035.
1879 * @ioc: Pointer to MPT adapter structure
1880 * @pdev: Pointer to (struct pci_dev) structure
1882 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
1883 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
1886 mpt_detect_bound_ports(MPT_ADAPTER
*ioc
, struct pci_dev
*pdev
)
1888 unsigned int match_lo
, match_hi
;
1889 MPT_ADAPTER
*ioc_srch
;
1891 match_lo
= pdev
->devfn
-1;
1892 match_hi
= pdev
->devfn
+1;
1893 dprintk((MYIOC_s_INFO_FMT
"PCI bus/devfn=%x/%x, searching for devfn match on %x or %x\n",
1894 ioc
->name
, pdev
->bus
->number
, pdev
->devfn
, match_lo
, match_hi
));
1896 list_for_each_entry(ioc_srch
, &ioc_list
, list
) {
1897 struct pci_dev
*_pcidev
= ioc_srch
->pcidev
;
1899 if ((_pcidev
->device
== pdev
->device
) &&
1900 (_pcidev
->bus
->number
== pdev
->bus
->number
) &&
1901 (_pcidev
->devfn
== match_lo
|| _pcidev
->devfn
== match_hi
) ) {
1902 /* Paranoia checks */
1903 if (ioc
->alt_ioc
!= NULL
) {
1904 printk(KERN_WARNING MYNAM
": Oops, already bound (%s <==> %s)!\n",
1905 ioc
->name
, ioc
->alt_ioc
->name
);
1907 } else if (ioc_srch
->alt_ioc
!= NULL
) {
1908 printk(KERN_WARNING MYNAM
": Oops, already bound (%s <==> %s)!\n",
1909 ioc_srch
->name
, ioc_srch
->alt_ioc
->name
);
1912 dprintk((KERN_INFO MYNAM
": FOUND! binding %s <==> %s\n",
1913 ioc
->name
, ioc_srch
->name
));
1914 ioc_srch
->alt_ioc
= ioc
;
1915 ioc
->alt_ioc
= ioc_srch
;
1921 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1923 * mpt_adapter_disable - Disable misbehaving MPT adapter.
1924 * @this: Pointer to MPT adapter structure
1927 mpt_adapter_disable(MPT_ADAPTER
*ioc
)
1932 if (ioc
->cached_fw
!= NULL
) {
1933 ddlprintk((KERN_INFO MYNAM
": mpt_adapter_disable: Pushing FW onto adapter\n"));
1934 if ((ret
= mpt_downloadboot(ioc
, NO_SLEEP
)) < 0) {
1935 printk(KERN_WARNING MYNAM
1936 ": firmware downloadboot failure (%d)!\n", ret
);
1940 /* Disable adapter interrupts! */
1941 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1943 /* Clear any lingering interrupt */
1944 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1946 if (ioc
->alloc
!= NULL
) {
1948 dexitprintk((KERN_INFO MYNAM
": %s.free @ %p, sz=%d bytes\n",
1949 ioc
->name
, ioc
->alloc
, ioc
->alloc_sz
));
1950 pci_free_consistent(ioc
->pcidev
, sz
,
1951 ioc
->alloc
, ioc
->alloc_dma
);
1952 ioc
->reply_frames
= NULL
;
1953 ioc
->req_frames
= NULL
;
1955 ioc
->alloc_total
-= sz
;
1958 if (ioc
->sense_buf_pool
!= NULL
) {
1959 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
1960 pci_free_consistent(ioc
->pcidev
, sz
,
1961 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
1962 ioc
->sense_buf_pool
= NULL
;
1963 ioc
->alloc_total
-= sz
;
1966 if (ioc
->events
!= NULL
){
1967 sz
= MPTCTL_EVENT_LOG_SIZE
* sizeof(MPT_IOCTL_EVENTS
);
1970 ioc
->alloc_total
-= sz
;
1973 if (ioc
->cached_fw
!= NULL
) {
1974 sz
= ioc
->facts
.FWImageSize
;
1975 pci_free_consistent(ioc
->pcidev
, sz
,
1976 ioc
->cached_fw
, ioc
->cached_fw_dma
);
1977 ioc
->cached_fw
= NULL
;
1978 ioc
->alloc_total
-= sz
;
1981 if (ioc
->spi_data
.nvram
!= NULL
) {
1982 kfree(ioc
->spi_data
.nvram
);
1983 ioc
->spi_data
.nvram
= NULL
;
1986 if (ioc
->spi_data
.pIocPg3
!= NULL
) {
1987 kfree(ioc
->spi_data
.pIocPg3
);
1988 ioc
->spi_data
.pIocPg3
= NULL
;
1991 if (ioc
->spi_data
.pIocPg4
!= NULL
) {
1992 sz
= ioc
->spi_data
.IocPg4Sz
;
1993 pci_free_consistent(ioc
->pcidev
, sz
,
1994 ioc
->spi_data
.pIocPg4
,
1995 ioc
->spi_data
.IocPg4_dma
);
1996 ioc
->spi_data
.pIocPg4
= NULL
;
1997 ioc
->alloc_total
-= sz
;
2000 if (ioc
->ReqToChain
!= NULL
) {
2001 kfree(ioc
->ReqToChain
);
2002 kfree(ioc
->RequestNB
);
2003 ioc
->ReqToChain
= NULL
;
2006 if (ioc
->ChainToChain
!= NULL
) {
2007 kfree(ioc
->ChainToChain
);
2008 ioc
->ChainToChain
= NULL
;
2012 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2014 * mpt_adapter_dispose - Free all resources associated with a MPT
2016 * @ioc: Pointer to MPT adapter structure
2018 * This routine unregisters h/w resources and frees all alloc'd memory
2019 * associated with a MPT adapter structure.
2022 mpt_adapter_dispose(MPT_ADAPTER
*ioc
)
2025 int sz_first
, sz_last
;
2027 sz_first
= ioc
->alloc_total
;
2029 mpt_adapter_disable(ioc
);
2031 if (ioc
->pci_irq
!= -1) {
2032 free_irq(ioc
->pci_irq
, ioc
);
2036 if (ioc
->memmap
!= NULL
)
2037 iounmap((u8
*) ioc
->memmap
);
2039 #if defined(CONFIG_MTRR) && 0
2040 if (ioc
->mtrr_reg
> 0) {
2041 mtrr_del(ioc
->mtrr_reg
, 0, 0);
2042 dprintk((KERN_INFO MYNAM
": %s: MTRR region de-registered\n", ioc
->name
));
2046 /* Zap the adapter lookup ptr! */
2047 list_del(&ioc
->list
);
2049 sz_last
= ioc
->alloc_total
;
2050 dprintk((KERN_INFO MYNAM
": %s: free'd %d of %d bytes\n",
2051 ioc
->name
, sz_first
-sz_last
+(int)sizeof(*ioc
), sz_first
));
2056 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2058 * MptDisplayIocCapabilities - Disply IOC's capacilities.
2059 * @ioc: Pointer to MPT adapter structure
2062 MptDisplayIocCapabilities(MPT_ADAPTER
*ioc
)
2066 printk(KERN_INFO
"%s: ", ioc
->name
);
2067 if (ioc
->prod_name
&& strlen(ioc
->prod_name
) > 3)
2068 printk("%s: ", ioc
->prod_name
+3);
2069 printk("Capabilities={");
2071 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_INITIATOR
) {
2072 printk("Initiator");
2076 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2077 printk("%sTarget", i
? "," : "");
2081 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
2082 printk("%sLAN", i
? "," : "");
2088 * This would probably evoke more questions than it's worth
2090 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2091 printk("%sLogBusAddr", i
? "," : "");
2099 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2101 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2102 * @ioc: Pointer to MPT_ADAPTER structure
2103 * @force: Force hard KickStart of IOC
2104 * @sleepFlag: Specifies whether the process can sleep
2107 * 1 - DIAG reset and READY
2108 * 0 - READY initially OR soft reset and READY
2109 * -1 - Any failure on KickStart
2110 * -2 - Msg Unit Reset Failed
2111 * -3 - IO Unit Reset Failed
2112 * -4 - IOC owned by a PEER
2115 MakeIocReady(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
2120 int hard_reset_done
= 0;
2125 /* Get current [raw] IOC state */
2126 ioc_state
= mpt_GetIocState(ioc
, 0);
2127 dhsprintk((KERN_INFO MYNAM
"::MakeIocReady, %s [raw] state=%08x\n", ioc
->name
, ioc_state
));
2130 * Check to see if IOC got left/stuck in doorbell handshake
2131 * grip of death. If so, hard reset the IOC.
2133 if (ioc_state
& MPI_DOORBELL_ACTIVE
) {
2135 printk(MYIOC_s_WARN_FMT
"Unexpected doorbell active!\n",
2139 /* Is it already READY? */
2140 if (!statefault
&& (ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_READY
) {
2141 if ((int)ioc
->chip_type
<= (int)FC929
)
2145 /* Workaround from broken 1030 FW.
2146 * Force a diagnostic reset if fails.
2148 /* if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2156 * Check to see if IOC is in FAULT state.
2158 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
2160 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state!!!\n",
2162 printk(KERN_WARNING
" FAULT code = %04xh\n",
2163 ioc_state
& MPI_DOORBELL_DATA_MASK
);
2167 * Hmmm... Did it get left operational?
2169 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_OPERATIONAL
) {
2170 dinitprintk((MYIOC_s_WARN_FMT
"IOC operational unexpected\n",
2174 * If PCI Peer, exit.
2175 * Else, if no fault conditions are present, issue a MessageUnitReset
2176 * Else, fall through to KickStart case
2178 whoinit
= (ioc_state
& MPI_DOORBELL_WHO_INIT_MASK
) >> MPI_DOORBELL_WHO_INIT_SHIFT
;
2179 dprintk((KERN_WARNING MYNAM
2180 ": whoinit 0x%x\n statefault %d force %d\n",
2181 whoinit
, statefault
, force
));
2182 if (whoinit
== MPI_WHOINIT_PCI_PEER
)
2185 if ((statefault
== 0 ) && (force
== 0)) {
2186 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) == 0)
2193 hard_reset_done
= KickStart(ioc
, statefault
||force
, sleepFlag
);
2194 if (hard_reset_done
< 0)
2198 * Loop here waiting for IOC to come READY.
2201 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 15; /* 15 seconds */
2203 while ((ioc_state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
2204 if (ioc_state
== MPI_IOC_STATE_OPERATIONAL
) {
2206 * BIOS or previous driver load left IOC in OP state.
2207 * Reset messaging FIFOs.
2209 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) != 0) {
2210 printk(MYIOC_s_ERR_FMT
"IOC msg unit reset failed!\n", ioc
->name
);
2213 } else if (ioc_state
== MPI_IOC_STATE_RESET
) {
2215 * Something is wrong. Try to get IOC back
2218 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IO_UNIT_RESET
, sleepFlag
)) != 0) {
2219 printk(MYIOC_s_ERR_FMT
"IO unit reset failed!\n", ioc
->name
);
2226 printk(MYIOC_s_ERR_FMT
"Wait IOC_READY state timeout(%d)!\n",
2227 ioc
->name
, (int)((ii
+5)/HZ
));
2231 if (sleepFlag
== CAN_SLEEP
) {
2232 set_current_state(TASK_INTERRUPTIBLE
);
2233 schedule_timeout(1 * HZ
/ 1000);
2235 mdelay (1); /* 1 msec delay */
2240 if (statefault
< 3) {
2241 printk(MYIOC_s_INFO_FMT
"Recovered from %s\n",
2243 statefault
==1 ? "stuck handshake" : "IOC FAULT");
2246 return hard_reset_done
;
2249 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2251 * mpt_GetIocState - Get the current state of a MPT adapter.
2252 * @ioc: Pointer to MPT_ADAPTER structure
2253 * @cooked: Request raw or cooked IOC state
2255 * Returns all IOC Doorbell register bits if cooked==0, else just the
2256 * Doorbell bits in MPI_IOC_STATE_MASK.
2259 mpt_GetIocState(MPT_ADAPTER
*ioc
, int cooked
)
2264 s
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
2265 // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2266 sc
= s
& MPI_IOC_STATE_MASK
;
2269 ioc
->last_state
= sc
;
2271 return cooked
? sc
: s
;
2274 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2276 * GetIocFacts - Send IOCFacts request to MPT adapter.
2277 * @ioc: Pointer to MPT_ADAPTER structure
2278 * @sleepFlag: Specifies whether the process can sleep
2279 * @reason: If recovery, only update facts.
2281 * Returns 0 for success, non-zero for failure.
2284 GetIocFacts(MPT_ADAPTER
*ioc
, int sleepFlag
, int reason
)
2286 IOCFacts_t get_facts
;
2287 IOCFactsReply_t
*facts
;
2295 /* IOC *must* NOT be in RESET state! */
2296 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
2297 printk(KERN_ERR MYNAM
": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2303 facts
= &ioc
->facts
;
2305 /* Destination (reply area)... */
2306 reply_sz
= sizeof(*facts
);
2307 memset(facts
, 0, reply_sz
);
2309 /* Request area (get_facts on the stack right now!) */
2310 req_sz
= sizeof(get_facts
);
2311 memset(&get_facts
, 0, req_sz
);
2313 get_facts
.Function
= MPI_FUNCTION_IOC_FACTS
;
2314 /* Assert: All other get_facts fields are zero! */
2316 dinitprintk((MYIOC_s_INFO_FMT
2317 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2318 ioc
->name
, req_sz
, reply_sz
));
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 sz
= facts
->FWImageSize
;
2396 facts
->FWImageSize
= sz
;
2398 if (!facts
->RequestFrameSize
) {
2399 /* Something is wrong! */
2400 printk(MYIOC_s_ERR_FMT
"IOC reported invalid 0 request size!\n",
2405 r
= sz
= le32_to_cpu(facts
->BlockSize
);
2406 vv
= ((63 / (sz
* 4)) + 1) & 0x03;
2407 ioc
->NB_for_64_byte_frame
= vv
;
2413 ioc
->NBShiftFactor
= shiftFactor
;
2414 dinitprintk((MYIOC_s_INFO_FMT
"NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2415 ioc
->name
, vv
, shiftFactor
, r
));
2417 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2419 * Set values for this IOC's request & reply frame sizes,
2420 * and request & reply queue depths...
2422 ioc
->req_sz
= min(MPT_DEFAULT_FRAME_SIZE
, facts
->RequestFrameSize
* 4);
2423 ioc
->req_depth
= min_t(int, MPT_MAX_REQ_DEPTH
, facts
->GlobalCredits
);
2424 ioc
->reply_sz
= MPT_REPLY_FRAME_SIZE
;
2425 ioc
->reply_depth
= min_t(int, MPT_DEFAULT_REPLY_DEPTH
, facts
->ReplyQueueDepth
);
2427 dinitprintk((MYIOC_s_INFO_FMT
"reply_sz=%3d, reply_depth=%4d\n",
2428 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
2429 dinitprintk((MYIOC_s_INFO_FMT
"req_sz =%3d, req_depth =%4d\n",
2430 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
2432 /* Get port facts! */
2433 if ( (r
= GetPortFacts(ioc
, 0, sleepFlag
)) != 0 )
2437 printk(MYIOC_s_ERR_FMT
2438 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2439 ioc
->name
, facts
->MsgLength
, (offsetof(IOCFactsReply_t
,
2440 RequestFrameSize
)/sizeof(u32
)));
2447 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2449 * GetPortFacts - Send PortFacts request to MPT adapter.
2450 * @ioc: Pointer to MPT_ADAPTER structure
2451 * @portnum: Port number
2452 * @sleepFlag: Specifies whether the process can sleep
2454 * Returns 0 for success, non-zero for failure.
2457 GetPortFacts(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
2459 PortFacts_t get_pfacts
;
2460 PortFactsReply_t
*pfacts
;
2465 /* IOC *must* NOT be in RESET state! */
2466 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
2467 printk(KERN_ERR MYNAM
": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2473 pfacts
= &ioc
->pfacts
[portnum
];
2475 /* Destination (reply area)... */
2476 reply_sz
= sizeof(*pfacts
);
2477 memset(pfacts
, 0, reply_sz
);
2479 /* Request area (get_pfacts on the stack right now!) */
2480 req_sz
= sizeof(get_pfacts
);
2481 memset(&get_pfacts
, 0, req_sz
);
2483 get_pfacts
.Function
= MPI_FUNCTION_PORT_FACTS
;
2484 get_pfacts
.PortNumber
= portnum
;
2485 /* Assert: All other get_pfacts fields are zero! */
2487 dinitprintk((MYIOC_s_INFO_FMT
"Sending get PortFacts(%d) request\n",
2488 ioc
->name
, portnum
));
2490 /* No non-zero fields in the get_pfacts request are greater than
2491 * 1 byte in size, so we can just fire it off as is.
2493 ii
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&get_pfacts
,
2494 reply_sz
, (u16
*)pfacts
, 5 /*seconds*/, sleepFlag
);
2498 /* Did we get a valid reply? */
2500 /* Now byte swap the necessary fields in the response. */
2501 pfacts
->MsgContext
= le32_to_cpu(pfacts
->MsgContext
);
2502 pfacts
->IOCStatus
= le16_to_cpu(pfacts
->IOCStatus
);
2503 pfacts
->IOCLogInfo
= le32_to_cpu(pfacts
->IOCLogInfo
);
2504 pfacts
->MaxDevices
= le16_to_cpu(pfacts
->MaxDevices
);
2505 pfacts
->PortSCSIID
= le16_to_cpu(pfacts
->PortSCSIID
);
2506 pfacts
->ProtocolFlags
= le16_to_cpu(pfacts
->ProtocolFlags
);
2507 pfacts
->MaxPostedCmdBuffers
= le16_to_cpu(pfacts
->MaxPostedCmdBuffers
);
2508 pfacts
->MaxPersistentIDs
= le16_to_cpu(pfacts
->MaxPersistentIDs
);
2509 pfacts
->MaxLanBuckets
= le16_to_cpu(pfacts
->MaxLanBuckets
);
2514 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2516 * SendIocInit - Send IOCInit request to MPT adapter.
2517 * @ioc: Pointer to MPT_ADAPTER structure
2518 * @sleepFlag: Specifies whether the process can sleep
2520 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2522 * Returns 0 for success, non-zero for failure.
2525 SendIocInit(MPT_ADAPTER
*ioc
, int sleepFlag
)
2528 MPIDefaultReply_t init_reply
;
2534 memset(&ioc_init
, 0, sizeof(ioc_init
));
2535 memset(&init_reply
, 0, sizeof(init_reply
));
2537 ioc_init
.WhoInit
= MPI_WHOINIT_HOST_DRIVER
;
2538 ioc_init
.Function
= MPI_FUNCTION_IOC_INIT
;
2540 /* If we are in a recovery mode and we uploaded the FW image,
2541 * then this pointer is not NULL. Skip the upload a second time.
2542 * Set this flag if cached_fw set for either IOC.
2544 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
2548 ddlprintk((MYIOC_s_INFO_FMT
"upload_fw %d facts.Flags=%x\n",
2549 ioc
->name
, ioc
->upload_fw
, ioc
->facts
.Flags
));
2551 if ((int)ioc
->chip_type
<= (int)FC929
) {
2552 ioc_init
.MaxDevices
= MPT_MAX_FC_DEVICES
;
2554 ioc_init
.MaxDevices
= MPT_MAX_SCSI_DEVICES
;
2556 ioc_init
.MaxBuses
= MPT_MAX_BUS
;
2558 ioc_init
.ReplyFrameSize
= cpu_to_le16(ioc
->reply_sz
); /* in BYTES */
2560 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
2561 /* Save the upper 32-bits of the request
2562 * (reply) and sense buffers.
2564 ioc_init
.HostMfaHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->alloc_dma
>> 32));
2565 ioc_init
.SenseBufferHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->sense_buf_pool_dma
>> 32));
2567 /* Force 32-bit addressing */
2568 ioc_init
.HostMfaHighAddr
= cpu_to_le32(0);
2569 ioc_init
.SenseBufferHighAddr
= cpu_to_le32(0);
2572 ioc
->facts
.CurrentHostMfaHighAddr
= ioc_init
.HostMfaHighAddr
;
2573 ioc
->facts
.CurrentSenseBufferHighAddr
= ioc_init
.SenseBufferHighAddr
;
2575 dhsprintk((MYIOC_s_INFO_FMT
"Sending IOCInit (req @ %p)\n",
2576 ioc
->name
, &ioc_init
));
2578 r
= mpt_handshake_req_reply_wait(ioc
, sizeof(IOCInit_t
), (u32
*)&ioc_init
,
2579 sizeof(MPIDefaultReply_t
), (u16
*)&init_reply
, 10 /*seconds*/, sleepFlag
);
2583 /* No need to byte swap the multibyte fields in the reply
2584 * since we don't even look at it's contents.
2587 dhsprintk((MYIOC_s_INFO_FMT
"Sending PortEnable (req @ %p)\n",
2588 ioc
->name
, &ioc_init
));
2590 if ((r
= SendPortEnable(ioc
, 0, sleepFlag
)) != 0)
2593 /* YIKES! SUPER IMPORTANT!!!
2594 * Poll IocState until _OPERATIONAL while IOC is doing
2595 * LoopInit and TargetDiscovery!
2598 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 60; /* 60 seconds */
2599 state
= mpt_GetIocState(ioc
, 1);
2600 while (state
!= MPI_IOC_STATE_OPERATIONAL
&& --cntdn
) {
2601 if (sleepFlag
== CAN_SLEEP
) {
2602 set_current_state(TASK_INTERRUPTIBLE
);
2603 schedule_timeout(1 * HZ
/ 1000);
2609 printk(MYIOC_s_ERR_FMT
"Wait IOC_OP state timeout(%d)!\n",
2610 ioc
->name
, (int)((count
+5)/HZ
));
2614 state
= mpt_GetIocState(ioc
, 1);
2617 dhsprintk((MYIOC_s_INFO_FMT
"INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2623 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2625 * SendPortEnable - Send PortEnable request to MPT adapter port.
2626 * @ioc: Pointer to MPT_ADAPTER structure
2627 * @portnum: Port number to enable
2628 * @sleepFlag: Specifies whether the process can sleep
2630 * Send PortEnable to bring IOC to OPERATIONAL state.
2632 * Returns 0 for success, non-zero for failure.
2635 SendPortEnable(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
2637 PortEnable_t port_enable
;
2638 MPIDefaultReply_t reply_buf
;
2643 /* Destination... */
2644 reply_sz
= sizeof(MPIDefaultReply_t
);
2645 memset(&reply_buf
, 0, reply_sz
);
2647 req_sz
= sizeof(PortEnable_t
);
2648 memset(&port_enable
, 0, req_sz
);
2650 port_enable
.Function
= MPI_FUNCTION_PORT_ENABLE
;
2651 port_enable
.PortNumber
= portnum
;
2652 /* port_enable.ChainOffset = 0; */
2653 /* port_enable.MsgFlags = 0; */
2654 /* port_enable.MsgContext = 0; */
2656 dinitprintk((MYIOC_s_INFO_FMT
"Sending Port(%d)Enable (req @ %p)\n",
2657 ioc
->name
, portnum
, &port_enable
));
2659 /* RAID FW may take a long time to enable
2661 if ((int)ioc
->chip_type
<= (int)FC929
) {
2662 ii
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&port_enable
,
2663 reply_sz
, (u16
*)&reply_buf
, 65 /*seconds*/, sleepFlag
);
2665 ii
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&port_enable
,
2666 reply_sz
, (u16
*)&reply_buf
, 300 /*seconds*/, sleepFlag
);
2672 /* We do not even look at the reply, so we need not
2673 * swap the multi-byte fields.
2680 * ioc: Pointer to MPT_ADAPTER structure
2681 * size - total FW bytes
2684 mpt_alloc_fw_memory(MPT_ADAPTER
*ioc
, int size
)
2687 return; /* use already allocated memory */
2688 if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
) {
2689 ioc
->cached_fw
= ioc
->alt_ioc
->cached_fw
; /* use alt_ioc's memory */
2690 ioc
->cached_fw_dma
= ioc
->alt_ioc
->cached_fw_dma
;
2692 if ( (ioc
->cached_fw
= pci_alloc_consistent(ioc
->pcidev
, size
, &ioc
->cached_fw_dma
) ) )
2693 ioc
->alloc_total
+= size
;
2697 * If alt_img is NULL, delete from ioc structure.
2698 * Else, delete a secondary image in same format.
2701 mpt_free_fw_memory(MPT_ADAPTER
*ioc
)
2705 sz
= ioc
->facts
.FWImageSize
;
2706 dinitprintk((KERN_WARNING MYNAM
"free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
2707 ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
2708 pci_free_consistent(ioc
->pcidev
, sz
,
2709 ioc
->cached_fw
, ioc
->cached_fw_dma
);
2710 ioc
->cached_fw
= NULL
;
2716 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2718 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
2719 * @ioc: Pointer to MPT_ADAPTER structure
2720 * @sleepFlag: Specifies whether the process can sleep
2722 * Returns 0 for success, >0 for handshake failure
2723 * <0 for fw upload failure.
2725 * Remark: If bound IOC and a successful FWUpload was performed
2726 * on the bound IOC, the second image is discarded
2727 * and memory is free'd. Both channels must upload to prevent
2728 * IOC from running in degraded mode.
2731 mpt_do_upload(MPT_ADAPTER
*ioc
, int sleepFlag
)
2733 u8 request
[ioc
->req_sz
];
2734 u8 reply
[sizeof(FWUploadReply_t
)];
2735 FWUpload_t
*prequest
;
2736 FWUploadReply_t
*preply
;
2737 FWUploadTCSGE_t
*ptcsge
;
2740 int ii
, sz
, reply_sz
;
2743 /* If the image size is 0, we are done.
2745 if ((sz
= ioc
->facts
.FWImageSize
) == 0)
2748 mpt_alloc_fw_memory(ioc
, sz
);
2750 dinitprintk((KERN_WARNING MYNAM
": FW Image @ %p[%p], sz=%d[%x] bytes\n",
2751 ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
2753 if (ioc
->cached_fw
== NULL
) {
2759 prequest
= (FWUpload_t
*)&request
;
2760 preply
= (FWUploadReply_t
*)&reply
;
2762 /* Destination... */
2763 memset(prequest
, 0, ioc
->req_sz
);
2765 reply_sz
= sizeof(reply
);
2766 memset(preply
, 0, reply_sz
);
2768 prequest
->ImageType
= MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM
;
2769 prequest
->Function
= MPI_FUNCTION_FW_UPLOAD
;
2771 ptcsge
= (FWUploadTCSGE_t
*) &prequest
->SGL
;
2772 ptcsge
->DetailsLength
= 12;
2773 ptcsge
->Flags
= MPI_SGE_FLAGS_TRANSACTION_ELEMENT
;
2774 ptcsge
->ImageSize
= cpu_to_le32(sz
);
2776 sgeoffset
= sizeof(FWUpload_t
) - sizeof(SGE_MPI_UNION
) + sizeof(FWUploadTCSGE_t
);
2778 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
| sz
;
2779 mpt_add_sge(&request
[sgeoffset
], flagsLength
, ioc
->cached_fw_dma
);
2781 sgeoffset
+= sizeof(u32
) + sizeof(dma_addr_t
);
2782 dinitprintk((KERN_WARNING MYNAM
"Sending FW Upload (req @ %p) sgeoffset=%d \n",
2783 prequest
, sgeoffset
));
2784 DBG_DUMP_FW_REQUEST_FRAME(prequest
)
2786 ii
= mpt_handshake_req_reply_wait(ioc
, sgeoffset
, (u32
*)prequest
,
2787 reply_sz
, (u16
*)preply
, 65 /*seconds*/, sleepFlag
);
2789 dinitprintk((KERN_WARNING MYNAM
"FW Upload completed rc=%x \n", ii
));
2791 cmdStatus
= -EFAULT
;
2793 /* Handshake transfer was complete and successful.
2794 * Check the Reply Frame.
2796 int status
, transfer_sz
;
2797 status
= le16_to_cpu(preply
->IOCStatus
);
2798 if (status
== MPI_IOCSTATUS_SUCCESS
) {
2799 transfer_sz
= le32_to_cpu(preply
->ActualImageSize
);
2800 if (transfer_sz
== sz
)
2804 dinitprintk((MYIOC_s_INFO_FMT
": do_upload status %d \n",
2805 ioc
->name
, cmdStatus
));
2810 ddlprintk((MYIOC_s_INFO_FMT
": fw upload failed, freeing image \n",
2812 mpt_free_fw_memory(ioc
);
2818 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2820 * mpt_downloadboot - DownloadBoot code
2821 * @ioc: Pointer to MPT_ADAPTER structure
2822 * @flag: Specify which part of IOC memory is to be uploaded.
2823 * @sleepFlag: Specifies whether the process can sleep
2825 * FwDownloadBoot requires Programmed IO access.
2827 * Returns 0 for success
2828 * -1 FW Image size is 0
2829 * -2 No valid cached_fw Pointer
2830 * <0 for fw upload failure.
2833 mpt_downloadboot(MPT_ADAPTER
*ioc
, int sleepFlag
)
2835 MpiFwHeader_t
*pFwHeader
;
2836 MpiExtImageHeader_t
*pExtImage
;
2846 ddlprintk((MYIOC_s_INFO_FMT
"downloadboot: fw size 0x%x, ioc FW Ptr %p\n",
2847 ioc
->name
, ioc
->facts
.FWImageSize
, ioc
->cached_fw
));
2849 if ( ioc
->facts
.FWImageSize
== 0 )
2852 if (ioc
->cached_fw
== NULL
)
2855 /* prevent a second downloadboot and memory free with alt_ioc */
2856 if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
)
2857 ioc
->alt_ioc
->cached_fw
= NULL
;
2859 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
2860 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
2861 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
2862 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
2863 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
2864 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
2866 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
));
2869 if (sleepFlag
== CAN_SLEEP
) {
2870 set_current_state(TASK_INTERRUPTIBLE
);
2871 schedule_timeout(1 * HZ
/ 1000);
2876 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
2877 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
2879 for (count
= 0; count
< 30; count
++) {
2880 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
2881 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
2882 ddlprintk((MYIOC_s_INFO_FMT
"RESET_ADAPTER cleared, count=%d\n",
2887 if (sleepFlag
== CAN_SLEEP
) {
2888 set_current_state(TASK_INTERRUPTIBLE
);
2889 schedule_timeout(1000 * HZ
/ 1000);
2895 if ( count
== 30 ) {
2896 ddlprintk((MYIOC_s_INFO_FMT
"downloadboot failed! Unable to RESET_ADAPTER diag0val=%x\n",
2897 ioc
->name
, diag0val
));
2901 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
2902 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
2903 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
2904 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
2905 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
2906 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
2908 /* Set the DiagRwEn and Disable ARM bits */
2909 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_RW_ENABLE
| MPI_DIAG_DISABLE_ARM
));
2911 pFwHeader
= (MpiFwHeader_t
*) ioc
->cached_fw
;
2912 fwSize
= (pFwHeader
->ImageSize
+ 3)/4;
2913 ptrFw
= (u32
*) pFwHeader
;
2915 /* Write the LoadStartAddress to the DiagRw Address Register
2916 * using Programmed IO
2918 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->LoadStartAddress
);
2919 ddlprintk((MYIOC_s_INFO_FMT
"LoadStart addr written 0x%x \n",
2920 ioc
->name
, pFwHeader
->LoadStartAddress
));
2922 ddlprintk((MYIOC_s_INFO_FMT
"Write FW Image: 0x%x bytes @ %p\n",
2923 ioc
->name
, fwSize
*4, ptrFw
));
2925 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
2928 nextImage
= pFwHeader
->NextImageHeaderOffset
;
2930 pExtImage
= (MpiExtImageHeader_t
*) ((char *)pFwHeader
+ nextImage
);
2932 load_addr
= pExtImage
->LoadStartAddress
;
2934 fwSize
= (pExtImage
->ImageSize
+ 3) >> 2;
2935 ptrFw
= (u32
*)pExtImage
;
2937 ddlprintk((MYIOC_s_INFO_FMT
"Write Ext Image: 0x%x bytes @ %p load_addr=%x\n",
2938 ioc
->name
, fwSize
*4, ptrFw
, load_addr
));
2939 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, load_addr
);
2942 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
2944 nextImage
= pExtImage
->NextImageHeaderOffset
;
2947 /* Write the IopResetVectorRegAddr */
2948 ddlprintk((MYIOC_s_INFO_FMT
"Write IopResetVector Addr=%x! \n", ioc
->name
, pFwHeader
->IopResetRegAddr
));
2949 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->IopResetRegAddr
);
2951 /* Write the IopResetVectorValue */
2952 ddlprintk((MYIOC_s_INFO_FMT
"Write IopResetVector Value=%x! \n", ioc
->name
, pFwHeader
->IopResetVectorValue
));
2953 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, pFwHeader
->IopResetVectorValue
);
2955 /* Clear the internal flash bad bit - autoincrementing register,
2956 * so must do two writes.
2958 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
2959 diagRwData
= CHIPREG_PIO_READ32(&ioc
->pio_chip
->DiagRwData
);
2960 diagRwData
|= 0x4000000;
2961 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
2962 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, diagRwData
);
2964 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
2965 ddlprintk((MYIOC_s_INFO_FMT
"downloadboot diag0val=%x, turning off PREVENT_IOC_BOOT, DISABLE_ARM\n",
2966 ioc
->name
, diag0val
));
2967 diag0val
&= ~(MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
);
2968 ddlprintk((MYIOC_s_INFO_FMT
"downloadboot now diag0val=%x\n",
2969 ioc
->name
, diag0val
));
2970 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
2972 /* Write 0xFF to reset the sequencer */
2973 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
2975 for (count
=0; count
<HZ
*20; count
++) {
2976 if ((ioc_state
= mpt_GetIocState(ioc
, 0)) & MPI_IOC_STATE_READY
) {
2977 ddlprintk((MYIOC_s_INFO_FMT
"downloadboot successful! (count=%d) IocState=%x\n",
2978 ioc
->name
, count
, ioc_state
));
2979 if ((SendIocInit(ioc
, sleepFlag
)) != 0) {
2980 ddlprintk((MYIOC_s_INFO_FMT
"downloadboot: SendIocInit failed\n",
2984 ddlprintk((MYIOC_s_INFO_FMT
"downloadboot: SendIocInit successful\n",
2988 if (sleepFlag
== CAN_SLEEP
) {
2989 set_current_state(TASK_INTERRUPTIBLE
);
2990 schedule_timeout(10 * HZ
/ 1000);
2995 ddlprintk((MYIOC_s_INFO_FMT
"downloadboot failed! IocState=%x\n",
2996 ioc
->name
, ioc_state
));
3000 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3002 * KickStart - Perform hard reset of MPT adapter.
3003 * @ioc: Pointer to MPT_ADAPTER structure
3004 * @force: Force hard reset
3005 * @sleepFlag: Specifies whether the process can sleep
3007 * This routine places MPT adapter in diagnostic mode via the
3008 * WriteSequence register, and then performs a hard reset of adapter
3009 * via the Diagnostic register.
3011 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3012 * or NO_SLEEP (interrupt thread, use mdelay)
3013 * force - 1 if doorbell active, board fault state
3014 * board operational, IOC_RECOVERY or
3015 * IOC_BRINGUP and there is an alt_ioc.
3019 * 1 - hard reset, READY
3020 * 0 - no reset due to History bit, READY
3021 * -1 - no reset due to History bit but not READY
3022 * OR reset but failed to come READY
3023 * -2 - no reset, could not enter DIAG mode
3024 * -3 - reset but bad FW bit
3027 KickStart(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
3029 int hard_reset_done
= 0;
3033 dinitprintk((KERN_WARNING MYNAM
": KickStarting %s!\n", ioc
->name
));
3034 if ((int)ioc
->chip_type
> (int)FC929
) {
3035 /* Always issue a Msg Unit Reset first. This will clear some
3036 * SCSI bus hang conditions.
3038 SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
);
3040 if (sleepFlag
== CAN_SLEEP
) {
3041 set_current_state(TASK_INTERRUPTIBLE
);
3042 schedule_timeout(1000 * HZ
/ 1000);
3048 hard_reset_done
= mpt_diag_reset(ioc
, force
, sleepFlag
);
3049 if (hard_reset_done
< 0)
3050 return hard_reset_done
;
3052 dinitprintk((MYIOC_s_INFO_FMT
"Diagnostic reset successful!\n",
3055 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 2; /* 2 seconds */
3056 for (cnt
=0; cnt
<cntdn
; cnt
++) {
3057 ioc_state
= mpt_GetIocState(ioc
, 1);
3058 if ((ioc_state
== MPI_IOC_STATE_READY
) || (ioc_state
== MPI_IOC_STATE_OPERATIONAL
)) {
3059 dinitprintk((MYIOC_s_INFO_FMT
"KickStart successful! (cnt=%d)\n",
3061 return hard_reset_done
;
3063 if (sleepFlag
== CAN_SLEEP
) {
3064 set_current_state(TASK_INTERRUPTIBLE
);
3065 schedule_timeout(10 * HZ
/ 1000);
3071 printk(MYIOC_s_ERR_FMT
"Failed to come READY after reset! IocState=%x\n",
3072 ioc
->name
, ioc_state
);
3076 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3078 * mpt_diag_reset - Perform hard reset of the adapter.
3079 * @ioc: Pointer to MPT_ADAPTER structure
3080 * @ignore: Set if to honor and clear to ignore
3081 * the reset history bit
3082 * @sleepflag: CAN_SLEEP if called in a non-interrupt thread,
3083 * else set to NO_SLEEP (use mdelay instead)
3085 * This routine places the adapter in diagnostic mode via the
3086 * WriteSequence register and then performs a hard reset of adapter
3087 * via the Diagnostic register. Adapter should be in ready state
3088 * upon successful completion.
3090 * Returns: 1 hard reset successful
3091 * 0 no reset performed because reset history bit set
3092 * -2 enabling diagnostic mode failed
3093 * -3 diagnostic reset failed
3096 mpt_diag_reset(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
)
3100 int hard_reset_done
= 0;
3106 /* Clear any existing interrupts */
3107 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
3109 /* Use "Diagnostic reset" method! (only thing available!) */
3110 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3114 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3115 dprintk((MYIOC_s_INFO_FMT
"DbG1: diag0=%08x, diag1=%08x\n",
3116 ioc
->name
, diag0val
, diag1val
));
3119 /* Do the reset if we are told to ignore the reset history
3120 * or if the reset history is 0
3122 if (ignore
|| !(diag0val
& MPI_DIAG_RESET_HISTORY
)) {
3123 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
3124 /* Write magic sequence to WriteSequence register
3125 * Loop until in diagnostic mode
3127 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3128 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3129 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3130 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3131 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3132 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3135 if (sleepFlag
== CAN_SLEEP
) {
3136 set_current_state(TASK_INTERRUPTIBLE
);
3137 schedule_timeout(100 * HZ
/ 1000);
3144 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
3145 ioc
->name
, diag0val
);
3150 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3152 dprintk((MYIOC_s_INFO_FMT
"Wrote magic DiagWriteEn sequence (%x)\n",
3153 ioc
->name
, diag0val
));
3158 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3159 dprintk((MYIOC_s_INFO_FMT
"DbG2: diag0=%08x, diag1=%08x\n",
3160 ioc
->name
, diag0val
, diag1val
));
3163 * Disable the ARM (Bug fix)
3166 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_DISABLE_ARM
);
3170 * Now hit the reset bit in the Diagnostic register
3171 * (THE BIG HAMMER!) (Clears DRWE bit).
3173 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
3174 hard_reset_done
= 1;
3175 dprintk((MYIOC_s_INFO_FMT
"Diagnostic reset performed\n",
3179 * Call each currently registered protocol IOC reset handler
3180 * with pre-reset indication.
3181 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3182 * MptResetHandlers[] registered yet.
3188 for (ii
=MPT_MAX_PROTOCOL_DRIVERS
-1; ii
; ii
--) {
3189 if (MptResetHandlers
[ii
]) {
3190 dprintk((MYIOC_s_INFO_FMT
"Calling IOC pre_reset handler #%d\n",
3192 r
+= (*(MptResetHandlers
[ii
]))(ioc
, MPT_IOC_PRE_RESET
);
3194 dprintk((MYIOC_s_INFO_FMT
"Calling alt-%s pre_reset handler #%d\n",
3195 ioc
->name
, ioc
->alt_ioc
->name
, ii
));
3196 r
+= (*(MptResetHandlers
[ii
]))(ioc
->alt_ioc
, MPT_IOC_PRE_RESET
);
3200 /* FIXME? Examine results here? */
3203 if (ioc
->cached_fw
) {
3204 /* If the DownloadBoot operation fails, the
3205 * IOC will be left unusable. This is a fatal error
3206 * case. _diag_reset will return < 0
3208 for (count
= 0; count
< 30; count
++) {
3209 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3210 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
3215 if (sleepFlag
== CAN_SLEEP
) {
3216 set_current_state(TASK_INTERRUPTIBLE
);
3217 schedule_timeout(1000 * HZ
/ 1000);
3222 if ((count
= mpt_downloadboot(ioc
, sleepFlag
)) < 0) {
3223 printk(KERN_WARNING MYNAM
3224 ": firmware downloadboot failure (%d)!\n", count
);
3228 /* Wait for FW to reload and for board
3229 * to go to the READY state.
3230 * Maximum wait is 60 seconds.
3231 * If fail, no error will check again
3232 * with calling program.
3234 for (count
= 0; count
< 60; count
++) {
3235 doorbell
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
3236 doorbell
&= MPI_IOC_STATE_MASK
;
3238 if (doorbell
== MPI_IOC_STATE_READY
) {
3243 if (sleepFlag
== CAN_SLEEP
) {
3244 set_current_state(TASK_INTERRUPTIBLE
);
3245 schedule_timeout(1000 * HZ
/ 1000);
3253 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3256 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3257 dprintk((MYIOC_s_INFO_FMT
"DbG3: diag0=%08x, diag1=%08x\n",
3258 ioc
->name
, diag0val
, diag1val
));
3261 /* Clear RESET_HISTORY bit! Place board in the
3262 * diagnostic mode to update the diag register.
3264 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3266 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
3267 /* Write magic sequence to WriteSequence register
3268 * Loop until in diagnostic mode
3270 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3271 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3272 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3273 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3274 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3275 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3278 if (sleepFlag
== CAN_SLEEP
) {
3279 set_current_state(TASK_INTERRUPTIBLE
);
3280 schedule_timeout(100 * HZ
/ 1000);
3287 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
3288 ioc
->name
, diag0val
);
3291 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3293 diag0val
&= ~MPI_DIAG_RESET_HISTORY
;
3294 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
3295 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3296 if (diag0val
& MPI_DIAG_RESET_HISTORY
) {
3297 printk(MYIOC_s_WARN_FMT
"ResetHistory bit failed to clear!\n",
3301 /* Disable Diagnostic Mode
3303 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFFFFFFFF);
3305 /* Check FW reload status flags.
3307 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3308 if (diag0val
& (MPI_DIAG_FLASH_BAD_SIG
| MPI_DIAG_RESET_ADAPTER
| MPI_DIAG_DISABLE_ARM
)) {
3309 printk(MYIOC_s_ERR_FMT
"Diagnostic reset FAILED! (%02xh)\n",
3310 ioc
->name
, diag0val
);
3316 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3317 dprintk((MYIOC_s_INFO_FMT
"DbG4: diag0=%08x, diag1=%08x\n",
3318 ioc
->name
, diag0val
, diag1val
));
3322 * Reset flag that says we've enabled event notification
3324 ioc
->facts
.EventState
= 0;
3327 ioc
->alt_ioc
->facts
.EventState
= 0;
3329 return hard_reset_done
;
3332 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3334 * SendIocReset - Send IOCReset request to MPT adapter.
3335 * @ioc: Pointer to MPT_ADAPTER structure
3336 * @reset_type: reset type, expected values are
3337 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3339 * Send IOCReset request to the MPT adapter.
3341 * Returns 0 for success, non-zero for failure.
3344 SendIocReset(MPT_ADAPTER
*ioc
, u8 reset_type
, int sleepFlag
)
3350 drsprintk((KERN_WARNING MYNAM
": %s: Sending IOC reset(0x%02x)!\n",
3351 ioc
->name
, reset_type
));
3352 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, reset_type
<<MPI_DOORBELL_FUNCTION_SHIFT
);
3353 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
3356 /* FW ACK'd request, wait for READY state
3359 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 15; /* 15 seconds */
3361 while ((state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
3365 if (sleepFlag
!= CAN_SLEEP
)
3368 printk(KERN_ERR MYNAM
": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3369 ioc
->name
, (int)((count
+5)/HZ
));
3373 if (sleepFlag
== CAN_SLEEP
) {
3374 set_current_state(TASK_INTERRUPTIBLE
);
3375 schedule_timeout(1 * HZ
/ 1000);
3377 mdelay (1); /* 1 msec delay */
3382 * Cleanup all event stuff for this IOC; re-issue EventNotification
3383 * request if needed.
3385 if (ioc
->facts
.Function
)
3386 ioc
->facts
.EventState
= 0;
3391 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3393 * initChainBuffers - Allocate memory for and initialize
3394 * chain buffers, chain buffer control arrays and spinlock.
3395 * @hd: Pointer to MPT_SCSI_HOST structure
3396 * @init: If set, initialize the spin lock.
3399 initChainBuffers(MPT_ADAPTER
*ioc
)
3402 int sz
, ii
, num_chain
;
3403 int scale
, num_sge
, numSGE
;
3405 /* ReqToChain size must equal the req_depth
3408 if (ioc
->ReqToChain
== NULL
) {
3409 sz
= ioc
->req_depth
* sizeof(int);
3410 mem
= kmalloc(sz
, GFP_ATOMIC
);
3414 ioc
->ReqToChain
= (int *) mem
;
3415 dinitprintk((KERN_INFO MYNAM
": %s ReqToChain alloc @ %p, sz=%d bytes\n",
3416 ioc
->name
, mem
, sz
));
3417 mem
= kmalloc(sz
, GFP_ATOMIC
);
3421 ioc
->RequestNB
= (int *) mem
;
3422 dinitprintk((KERN_INFO MYNAM
": %s RequestNB alloc @ %p, sz=%d bytes\n",
3423 ioc
->name
, mem
, sz
));
3425 for (ii
= 0; ii
< ioc
->req_depth
; ii
++) {
3426 ioc
->ReqToChain
[ii
] = MPT_HOST_NO_CHAIN
;
3429 /* ChainToChain size must equal the total number
3430 * of chain buffers to be allocated.
3433 * Calculate the number of chain buffers needed(plus 1) per I/O
3434 * then multiply the the maximum number of simultaneous cmds
3436 * num_sge = num sge in request frame + last chain buffer
3437 * scale = num sge per chain buffer if no chain element
3439 scale
= ioc
->req_sz
/(sizeof(dma_addr_t
) + sizeof(u32
));
3440 if (sizeof(dma_addr_t
) == sizeof(u64
))
3441 num_sge
= scale
+ (ioc
->req_sz
- 60) / (sizeof(dma_addr_t
) + sizeof(u32
));
3443 num_sge
= 1+ scale
+ (ioc
->req_sz
- 64) / (sizeof(dma_addr_t
) + sizeof(u32
));
3445 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
3446 numSGE
= (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) + scale
+
3447 (ioc
->req_sz
- 60) / (sizeof(dma_addr_t
) + sizeof(u32
));
3449 numSGE
= 1 + (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) + scale
+
3450 (ioc
->req_sz
- 64) / (sizeof(dma_addr_t
) + sizeof(u32
));
3452 dinitprintk((KERN_INFO MYNAM
": %s num_sge=%d numSGE=%d\n",
3453 ioc
->name
, num_sge
, numSGE
));
3455 if ( numSGE
> MPT_SCSI_SG_DEPTH
)
3456 numSGE
= MPT_SCSI_SG_DEPTH
;
3459 while (numSGE
- num_sge
> 0) {
3461 num_sge
+= (scale
- 1);
3465 dinitprintk((KERN_INFO MYNAM
": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
3466 ioc
->name
, numSGE
, num_sge
, num_chain
));
3468 if ((int) ioc
->chip_type
> (int) FC929
)
3469 num_chain
*= MPT_SCSI_CAN_QUEUE
;
3471 num_chain
*= MPT_FC_CAN_QUEUE
;
3473 ioc
->num_chain
= num_chain
;
3475 sz
= num_chain
* sizeof(int);
3476 if (ioc
->ChainToChain
== NULL
) {
3477 mem
= kmalloc(sz
, GFP_ATOMIC
);
3481 ioc
->ChainToChain
= (int *) mem
;
3482 dinitprintk((KERN_INFO MYNAM
": %s ChainToChain alloc @ %p, sz=%d bytes\n",
3483 ioc
->name
, mem
, sz
));
3485 mem
= (u8
*) ioc
->ChainToChain
;
3487 memset(mem
, 0xFF, sz
);
3491 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3493 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3494 * @ioc: Pointer to MPT_ADAPTER structure
3496 * This routine allocates memory for the MPT reply and request frame
3497 * pools (if necessary), and primes the IOC reply FIFO with
3500 * Returns 0 for success, non-zero for failure.
3503 PrimeIocFifos(MPT_ADAPTER
*ioc
)
3506 unsigned long flags
;
3507 dma_addr_t alloc_dma
;
3509 int i
, reply_sz
, sz
, total_size
, num_chain
;
3511 /* Prime reply FIFO... */
3513 if (ioc
->reply_frames
== NULL
) {
3514 if ( (num_chain
= initChainBuffers(ioc
)) < 0)
3517 total_size
= reply_sz
= (ioc
->reply_sz
* ioc
->reply_depth
);
3518 dinitprintk((KERN_INFO MYNAM
": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3519 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
3520 dinitprintk((KERN_INFO MYNAM
": %s.ReplyBuffer sz=%d[%x] bytes\n",
3521 ioc
->name
, reply_sz
, reply_sz
));
3523 sz
= (ioc
->req_sz
* ioc
->req_depth
);
3524 dinitprintk((KERN_INFO MYNAM
": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3525 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
3526 dinitprintk((KERN_INFO MYNAM
": %s.RequestBuffer sz=%d[%x] bytes\n",
3527 ioc
->name
, sz
, sz
));
3530 sz
= num_chain
* ioc
->req_sz
; /* chain buffer pool size */
3531 dinitprintk((KERN_INFO MYNAM
": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3532 ioc
->name
, ioc
->req_sz
, num_chain
));
3533 dinitprintk((KERN_INFO MYNAM
": %s.ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3534 ioc
->name
, sz
, sz
, num_chain
));
3537 mem
= pci_alloc_consistent(ioc
->pcidev
, total_size
, &alloc_dma
);
3539 printk(MYIOC_s_ERR_FMT
"Unable to allocate Reply, Request, Chain Buffers!\n",
3544 dinitprintk((KERN_INFO MYNAM
": %s.Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3545 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
, total_size
, total_size
));
3547 memset(mem
, 0, total_size
);
3548 ioc
->alloc_total
+= total_size
;
3550 ioc
->alloc_dma
= alloc_dma
;
3551 ioc
->alloc_sz
= total_size
;
3552 ioc
->reply_frames
= (MPT_FRAME_HDR
*) mem
;
3553 ioc
->reply_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
3555 alloc_dma
+= reply_sz
;
3558 /* Request FIFO - WE manage this! */
3560 ioc
->req_frames
= (MPT_FRAME_HDR
*) mem
;
3561 ioc
->req_frames_dma
= alloc_dma
;
3563 dinitprintk((KERN_INFO MYNAM
": %s.RequestBuffers @ %p[%p]\n",
3564 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
));
3566 ioc
->req_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
3568 #if defined(CONFIG_MTRR) && 0
3570 * Enable Write Combining MTRR for IOC's memory region.
3571 * (at least as much as we can; "size and base must be
3572 * multiples of 4 kiB"
3574 ioc
->mtrr_reg
= mtrr_add(ioc
->req_frames_dma
,
3576 MTRR_TYPE_WRCOMB
, 1);
3577 dprintk((MYIOC_s_INFO_FMT
"MTRR region registered (base:size=%08x:%x)\n",
3578 ioc
->name
, ioc
->req_frames_dma
, sz
));
3581 for (i
= 0; i
< ioc
->req_depth
; i
++) {
3582 alloc_dma
+= ioc
->req_sz
;
3586 ioc
->ChainBuffer
= mem
;
3587 ioc
->ChainBufferDMA
= alloc_dma
;
3589 dinitprintk((KERN_INFO MYNAM
" :%s.ChainBuffers @ %p(%p)\n",
3590 ioc
->name
, ioc
->ChainBuffer
, (void *)(ulong
)ioc
->ChainBufferDMA
));
3592 /* Initialize the free chain Q.
3595 Q_INIT(&ioc
->FreeChainQ
, MPT_FRAME_HDR
);
3597 /* Post the chain buffers to the FreeChainQ.
3599 mem
= (u8
*)ioc
->ChainBuffer
;
3600 for (i
=0; i
< num_chain
; i
++) {
3601 mf
= (MPT_FRAME_HDR
*) mem
;
3602 Q_ADD_TAIL(&ioc
->FreeChainQ
.head
, &mf
->u
.frame
.linkage
, MPT_FRAME_HDR
);
3606 /* Initialize Request frames linked list
3608 alloc_dma
= ioc
->req_frames_dma
;
3609 mem
= (u8
*) ioc
->req_frames
;
3611 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
3612 Q_INIT(&ioc
->FreeQ
, MPT_FRAME_HDR
);
3613 for (i
= 0; i
< ioc
->req_depth
; i
++) {
3614 mf
= (MPT_FRAME_HDR
*) mem
;
3616 /* Queue REQUESTs *internally*! */
3617 Q_ADD_TAIL(&ioc
->FreeQ
.head
, &mf
->u
.frame
.linkage
, MPT_FRAME_HDR
);
3620 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
3622 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
3623 ioc
->sense_buf_pool
=
3624 pci_alloc_consistent(ioc
->pcidev
, sz
, &ioc
->sense_buf_pool_dma
);
3625 if (ioc
->sense_buf_pool
== NULL
) {
3626 printk(MYIOC_s_ERR_FMT
"Unable to allocate Sense Buffers!\n",
3631 ioc
->sense_buf_low_dma
= (u32
) (ioc
->sense_buf_pool_dma
& 0xFFFFFFFF);
3632 ioc
->alloc_total
+= sz
;
3633 dinitprintk((KERN_INFO MYNAM
": %s.SenseBuffers @ %p[%p]\n",
3634 ioc
->name
, ioc
->sense_buf_pool
, (void *)(ulong
)ioc
->sense_buf_pool_dma
));
3638 /* Post Reply frames to FIFO
3640 alloc_dma
= ioc
->alloc_dma
;
3641 dinitprintk((KERN_INFO MYNAM
": %s.ReplyBuffers @ %p[%p]\n",
3642 ioc
->name
, ioc
->reply_frames
, (void *)(ulong
)alloc_dma
));
3644 for (i
= 0; i
< ioc
->reply_depth
; i
++) {
3645 /* Write each address to the IOC! */
3646 CHIPREG_WRITE32(&ioc
->chip
->ReplyFifo
, alloc_dma
);
3647 alloc_dma
+= ioc
->reply_sz
;
3653 if (ioc
->alloc
!= NULL
) {
3655 pci_free_consistent(ioc
->pcidev
,
3657 ioc
->alloc
, ioc
->alloc_dma
);
3658 ioc
->reply_frames
= NULL
;
3659 ioc
->req_frames
= NULL
;
3660 ioc
->alloc_total
-= sz
;
3662 if (ioc
->sense_buf_pool
!= NULL
) {
3663 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
3664 pci_free_consistent(ioc
->pcidev
,
3666 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
3667 ioc
->sense_buf_pool
= NULL
;
3672 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3674 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3675 * from IOC via doorbell handshake method.
3676 * @ioc: Pointer to MPT_ADAPTER structure
3677 * @reqBytes: Size of the request in bytes
3678 * @req: Pointer to MPT request frame
3679 * @replyBytes: Expected size of the reply in bytes
3680 * @u16reply: Pointer to area where reply should be written
3681 * @maxwait: Max wait time for a reply (in seconds)
3682 * @sleepFlag: Specifies whether the process can sleep
3684 * NOTES: It is the callers responsibility to byte-swap fields in the
3685 * request which are greater than 1 byte in size. It is also the
3686 * callers responsibility to byte-swap response fields which are
3687 * greater than 1 byte in size.
3689 * Returns 0 for success, non-zero for failure.
3692 mpt_handshake_req_reply_wait(MPT_ADAPTER
*ioc
, int reqBytes
, u32
*req
,
3693 int replyBytes
, u16
*u16reply
, int maxwait
, int sleepFlag
)
3695 MPIDefaultReply_t
*mptReply
;
3700 * Get ready to cache a handshake reply
3702 ioc
->hs_reply_idx
= 0;
3703 mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
3704 mptReply
->MsgLength
= 0;
3707 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
3708 * then tell IOC that we want to handshake a request of N words.
3709 * (WRITE u32val to Doorbell reg).
3711 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
3712 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
3713 ((MPI_FUNCTION_HANDSHAKE
<<MPI_DOORBELL_FUNCTION_SHIFT
) |
3714 ((reqBytes
/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT
)));
3717 * Wait for IOC's doorbell handshake int
3719 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
3722 dhsprintk((MYIOC_s_INFO_FMT
"HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
3723 ioc
->name
, reqBytes
, t
, failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
3725 /* Read doorbell and check for active bit */
3726 if (!(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & MPI_DOORBELL_ACTIVE
))
3730 * Clear doorbell int (WRITE 0 to IntStatus reg),
3731 * then wait for IOC to ACKnowledge that it's ready for
3732 * our handshake request.
3734 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
3735 if (!failcnt
&& (t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
3740 u8
*req_as_bytes
= (u8
*) req
;
3743 * Stuff request words via doorbell handshake,
3744 * with ACK from IOC for each.
3746 for (ii
= 0; !failcnt
&& ii
< reqBytes
/4; ii
++) {
3747 u32 word
= ((req_as_bytes
[(ii
*4) + 0] << 0) |
3748 (req_as_bytes
[(ii
*4) + 1] << 8) |
3749 (req_as_bytes
[(ii
*4) + 2] << 16) |
3750 (req_as_bytes
[(ii
*4) + 3] << 24));
3752 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, word
);
3753 if ((t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
3757 dhsprintk((KERN_INFO MYNAM
": Handshake request frame (@%p) header\n", req
));
3758 DBG_DUMP_REQUEST_FRAME_HDR(req
)
3760 dhsprintk((MYIOC_s_INFO_FMT
"HandShake request post done, WaitCnt=%d%s\n",
3761 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL ACK!" : ""));
3764 * Wait for completion of doorbell handshake reply from the IOC
3766 if (!failcnt
&& (t
= WaitForDoorbellReply(ioc
, maxwait
, sleepFlag
)) < 0)
3769 dhsprintk((MYIOC_s_INFO_FMT
"HandShake reply count=%d%s\n",
3770 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL REPLY!" : ""));
3773 * Copy out the cached reply...
3775 for (ii
=0; ii
< min(replyBytes
/2,mptReply
->MsgLength
*2); ii
++)
3776 u16reply
[ii
] = ioc
->hs_reply
[ii
];
3784 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3786 * WaitForDoorbellAck - Wait for IOC to clear the IOP_DOORBELL_STATUS bit
3787 * in it's IntStatus register.
3788 * @ioc: Pointer to MPT_ADAPTER structure
3789 * @howlong: How long to wait (in seconds)
3790 * @sleepFlag: Specifies whether the process can sleep
3792 * This routine waits (up to ~2 seconds max) for IOC doorbell
3793 * handshake ACKnowledge.
3795 * Returns a negative value on failure, else wait loop count.
3798 WaitForDoorbellAck(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
3804 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * howlong
;
3806 if (sleepFlag
== CAN_SLEEP
) {
3808 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
3809 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
3811 set_current_state(TASK_INTERRUPTIBLE
);
3812 schedule_timeout(1 * HZ
/ 1000);
3817 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
3818 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
3826 dprintk((MYIOC_s_INFO_FMT
"WaitForDoorbell ACK (count=%d)\n",
3831 printk(MYIOC_s_ERR_FMT
"Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
3832 ioc
->name
, count
, intstat
);
3836 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3838 * WaitForDoorbellInt - Wait for IOC to set the HIS_DOORBELL_INTERRUPT bit
3839 * in it's IntStatus register.
3840 * @ioc: Pointer to MPT_ADAPTER structure
3841 * @howlong: How long to wait (in seconds)
3842 * @sleepFlag: Specifies whether the process can sleep
3844 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt.
3846 * Returns a negative value on failure, else wait loop count.
3849 WaitForDoorbellInt(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
3855 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * howlong
;
3856 if (sleepFlag
== CAN_SLEEP
) {
3858 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
3859 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
3861 set_current_state(TASK_INTERRUPTIBLE
);
3862 schedule_timeout(1 * HZ
/ 1000);
3867 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
3868 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
3876 dprintk((MYIOC_s_INFO_FMT
"WaitForDoorbell INT (cnt=%d) howlong=%d\n",
3877 ioc
->name
, count
, howlong
));
3881 printk(MYIOC_s_ERR_FMT
"Doorbell INT timeout (count=%d), IntStatus=%x!\n",
3882 ioc
->name
, count
, intstat
);
3886 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3888 * WaitForDoorbellReply - Wait for and capture a IOC handshake reply.
3889 * @ioc: Pointer to MPT_ADAPTER structure
3890 * @howlong: How long to wait (in seconds)
3891 * @sleepFlag: Specifies whether the process can sleep
3893 * This routine polls the IOC for a handshake reply, 16 bits at a time.
3894 * Reply is cached to IOC private area large enough to hold a maximum
3895 * of 128 bytes of reply data.
3897 * Returns a negative value on failure, else size of reply in WORDS.
3900 WaitForDoorbellReply(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
3905 u16
*hs_reply
= ioc
->hs_reply
;
3906 volatile MPIDefaultReply_t
*mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
3909 hs_reply
[0] = hs_reply
[1] = hs_reply
[7] = 0;
3912 * Get first two u16's so we can look at IOC's intended reply MsgLength
3915 if ((t
= WaitForDoorbellInt(ioc
, howlong
, sleepFlag
)) < 0) {
3918 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
3919 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
3920 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
3923 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
3924 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
3928 dhsprintk((MYIOC_s_INFO_FMT
"WaitCnt=%d First handshake reply word=%08x%s\n",
3929 ioc
->name
, t
, le32_to_cpu(*(u32
*)hs_reply
),
3930 failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
3933 * If no error (and IOC said MsgLength is > 0), piece together
3934 * reply 16 bits at a time.
3936 for (u16cnt
=2; !failcnt
&& u16cnt
< (2 * mptReply
->MsgLength
); u16cnt
++) {
3937 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
3939 hword
= le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
3940 /* don't overflow our IOC hs_reply[] buffer! */
3941 if (u16cnt
< sizeof(ioc
->hs_reply
) / sizeof(ioc
->hs_reply
[0]))
3942 hs_reply
[u16cnt
] = hword
;
3943 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
3946 if (!failcnt
&& (t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
3948 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
3951 printk(MYIOC_s_ERR_FMT
"Handshake reply failure!\n",
3956 else if (u16cnt
!= (2 * mptReply
->MsgLength
)) {
3959 else if ((mptReply
->IOCStatus
& MPI_IOCSTATUS_MASK
) != MPI_IOCSTATUS_SUCCESS
) {
3964 dhsprintk((MYIOC_s_INFO_FMT
"Got Handshake reply:\n", ioc
->name
));
3965 DBG_DUMP_REPLY_FRAME(mptReply
)
3967 dhsprintk((MYIOC_s_INFO_FMT
"WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
3968 ioc
->name
, t
, u16cnt
/2));
3972 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3974 * GetLanConfigPages - Fetch LANConfig pages.
3975 * @ioc: Pointer to MPT_ADAPTER structure
3977 * Return: 0 for success
3978 * -ENOMEM if no memory available
3979 * -EPERM if not allowed due to ISR context
3980 * -EAGAIN if no msg frames currently available
3981 * -EFAULT for non-successful reply or no reply (timeout)
3984 GetLanConfigPages(MPT_ADAPTER
*ioc
)
3986 ConfigPageHeader_t hdr
;
3988 LANPage0_t
*ppage0_alloc
;
3989 dma_addr_t page0_dma
;
3990 LANPage1_t
*ppage1_alloc
;
3991 dma_addr_t page1_dma
;
3996 /* Get LAN Page 0 header */
3997 hdr
.PageVersion
= 0;
4000 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4003 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4008 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4011 if (hdr
.PageLength
> 0) {
4012 data_sz
= hdr
.PageLength
* 4;
4013 ppage0_alloc
= (LANPage0_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page0_dma
);
4016 memset((u8
*)ppage0_alloc
, 0, data_sz
);
4017 cfg
.physAddr
= page0_dma
;
4018 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4020 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4022 copy_sz
= min_t(int, sizeof(LANPage0_t
), data_sz
);
4023 memcpy(&ioc
->lan_cnfg_page0
, ppage0_alloc
, copy_sz
);
4027 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage0_alloc
, page0_dma
);
4030 * Normalize endianness of structure data,
4031 * by byte-swapping all > 1 byte fields!
4040 /* Get LAN Page 1 header */
4041 hdr
.PageVersion
= 0;
4044 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4047 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4051 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4054 if (hdr
.PageLength
== 0)
4057 data_sz
= hdr
.PageLength
* 4;
4059 ppage1_alloc
= (LANPage1_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page1_dma
);
4061 memset((u8
*)ppage1_alloc
, 0, data_sz
);
4062 cfg
.physAddr
= page1_dma
;
4063 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4065 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4067 copy_sz
= min_t(int, sizeof(LANPage1_t
), data_sz
);
4068 memcpy(&ioc
->lan_cnfg_page1
, ppage1_alloc
, copy_sz
);
4071 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage1_alloc
, page1_dma
);
4074 * Normalize endianness of structure data,
4075 * by byte-swapping all > 1 byte fields!
4083 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4085 * GetFcPortPage0 - Fetch FCPort config Page0.
4086 * @ioc: Pointer to MPT_ADAPTER structure
4087 * @portnum: IOC Port number
4089 * Return: 0 for success
4090 * -ENOMEM if no memory available
4091 * -EPERM if not allowed due to ISR context
4092 * -EAGAIN if no msg frames currently available
4093 * -EFAULT for non-successful reply or no reply (timeout)
4096 GetFcPortPage0(MPT_ADAPTER
*ioc
, int portnum
)
4098 ConfigPageHeader_t hdr
;
4100 FCPortPage0_t
*ppage0_alloc
;
4101 FCPortPage0_t
*pp0dest
;
4102 dma_addr_t page0_dma
;
4107 /* Get FCPort Page 0 header */
4108 hdr
.PageVersion
= 0;
4111 hdr
.PageType
= MPI_CONFIG_PAGETYPE_FC_PORT
;
4114 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4116 cfg
.pageAddr
= portnum
;
4119 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4122 if (hdr
.PageLength
== 0)
4125 data_sz
= hdr
.PageLength
* 4;
4127 ppage0_alloc
= (FCPortPage0_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page0_dma
);
4129 memset((u8
*)ppage0_alloc
, 0, data_sz
);
4130 cfg
.physAddr
= page0_dma
;
4131 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4133 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4135 pp0dest
= &ioc
->fc_port_page0
[portnum
];
4136 copy_sz
= min_t(int, sizeof(FCPortPage0_t
), data_sz
);
4137 memcpy(pp0dest
, ppage0_alloc
, copy_sz
);
4140 * Normalize endianness of structure data,
4141 * by byte-swapping all > 1 byte fields!
4143 pp0dest
->Flags
= le32_to_cpu(pp0dest
->Flags
);
4144 pp0dest
->PortIdentifier
= le32_to_cpu(pp0dest
->PortIdentifier
);
4145 pp0dest
->WWNN
.Low
= le32_to_cpu(pp0dest
->WWNN
.Low
);
4146 pp0dest
->WWNN
.High
= le32_to_cpu(pp0dest
->WWNN
.High
);
4147 pp0dest
->WWPN
.Low
= le32_to_cpu(pp0dest
->WWPN
.Low
);
4148 pp0dest
->WWPN
.High
= le32_to_cpu(pp0dest
->WWPN
.High
);
4149 pp0dest
->SupportedServiceClass
= le32_to_cpu(pp0dest
->SupportedServiceClass
);
4150 pp0dest
->SupportedSpeeds
= le32_to_cpu(pp0dest
->SupportedSpeeds
);
4151 pp0dest
->CurrentSpeed
= le32_to_cpu(pp0dest
->CurrentSpeed
);
4152 pp0dest
->MaxFrameSize
= le32_to_cpu(pp0dest
->MaxFrameSize
);
4153 pp0dest
->FabricWWNN
.Low
= le32_to_cpu(pp0dest
->FabricWWNN
.Low
);
4154 pp0dest
->FabricWWNN
.High
= le32_to_cpu(pp0dest
->FabricWWNN
.High
);
4155 pp0dest
->FabricWWPN
.Low
= le32_to_cpu(pp0dest
->FabricWWPN
.Low
);
4156 pp0dest
->FabricWWPN
.High
= le32_to_cpu(pp0dest
->FabricWWPN
.High
);
4157 pp0dest
->DiscoveredPortsCount
= le32_to_cpu(pp0dest
->DiscoveredPortsCount
);
4158 pp0dest
->MaxInitiators
= le32_to_cpu(pp0dest
->MaxInitiators
);
4162 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage0_alloc
, page0_dma
);
4168 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4170 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4171 * @ioc: Pointer to MPT_ADAPTER structure
4173 * Returns: 0 for success
4174 * -ENOMEM if no memory available
4175 * -EPERM if not allowed due to ISR context
4176 * -EAGAIN if no msg frames currently available
4177 * -EFAULT for non-successful reply or no reply (timeout)
4180 GetIoUnitPage2(MPT_ADAPTER
*ioc
)
4182 ConfigPageHeader_t hdr
;
4184 IOUnitPage2_t
*ppage_alloc
;
4185 dma_addr_t page_dma
;
4189 /* Get the page header */
4190 hdr
.PageVersion
= 0;
4193 hdr
.PageType
= MPI_CONFIG_PAGETYPE_IO_UNIT
;
4196 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4201 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4204 if (hdr
.PageLength
== 0)
4207 /* Read the config page */
4208 data_sz
= hdr
.PageLength
* 4;
4210 ppage_alloc
= (IOUnitPage2_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page_dma
);
4212 memset((u8
*)ppage_alloc
, 0, data_sz
);
4213 cfg
.physAddr
= page_dma
;
4214 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4216 /* If Good, save data */
4217 if ((rc
= mpt_config(ioc
, &cfg
)) == 0)
4218 ioc
->biosVersion
= le32_to_cpu(ppage_alloc
->BiosVersion
);
4220 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage_alloc
, page_dma
);
4226 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4227 /* mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4228 * @ioc: Pointer to a Adapter Strucutre
4229 * @portnum: IOC port number
4231 * Return: -EFAULT if read of config page header fails
4233 * If read of SCSI Port Page 0 fails,
4234 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4235 * Adapter settings: async, narrow
4237 * If read of SCSI Port Page 2 fails,
4238 * Adapter settings valid
4239 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4244 * CHECK - what type of locking mechanisms should be used????
4247 mpt_GetScsiPortSettings(MPT_ADAPTER
*ioc
, int portnum
)
4252 ConfigPageHeader_t header
;
4258 if (!ioc
->spi_data
.nvram
) {
4261 sz
= MPT_MAX_SCSI_DEVICES
* sizeof(int);
4262 mem
= kmalloc(sz
, GFP_ATOMIC
);
4266 ioc
->spi_data
.nvram
= (int *) mem
;
4268 dprintk((MYIOC_s_INFO_FMT
"SCSI device NVRAM settings @ %p, sz=%d\n",
4269 ioc
->name
, ioc
->spi_data
.nvram
, sz
));
4272 /* Invalidate NVRAM information
4274 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
4275 ioc
->spi_data
.nvram
[ii
] = MPT_HOST_NVRAM_INVALID
;
4278 /* Read SPP0 header, allocate memory, then read page.
4280 header
.PageVersion
= 0;
4281 header
.PageLength
= 0;
4282 header
.PageNumber
= 0;
4283 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_PORT
;
4286 cfg
.pageAddr
= portnum
;
4287 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4289 cfg
.timeout
= 0; /* use default */
4290 if (mpt_config(ioc
, &cfg
) != 0)
4293 if (header
.PageLength
> 0) {
4294 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
4296 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4297 cfg
.physAddr
= buf_dma
;
4298 if (mpt_config(ioc
, &cfg
) != 0) {
4299 ioc
->spi_data
.maxBusWidth
= MPT_NARROW
;
4300 ioc
->spi_data
.maxSyncOffset
= 0;
4301 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
4302 ioc
->spi_data
.busType
= MPT_HOST_BUS_UNKNOWN
;
4305 /* Save the Port Page 0 data
4307 SCSIPortPage0_t
*pPP0
= (SCSIPortPage0_t
*) pbuf
;
4308 pPP0
->Capabilities
= le32_to_cpu(pPP0
->Capabilities
);
4309 pPP0
->PhysicalInterface
= le32_to_cpu(pPP0
->PhysicalInterface
);
4311 if ( (pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_QAS
) == 0 ) {
4312 ioc
->spi_data
.noQas
|= MPT_TARGET_NO_NEGO_QAS
;
4313 dinitprintk((KERN_INFO MYNAM
" :%s noQas due to Capabilities=%x\n",
4314 ioc
->name
, pPP0
->Capabilities
));
4316 ioc
->spi_data
.maxBusWidth
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_WIDE
? 1 : 0;
4317 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK
;
4319 ioc
->spi_data
.maxSyncOffset
= (u8
) (data
>> 16);
4320 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK
;
4321 ioc
->spi_data
.minSyncFactor
= (u8
) (data
>> 8);
4323 ioc
->spi_data
.maxSyncOffset
= 0;
4324 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
4327 ioc
->spi_data
.busType
= pPP0
->PhysicalInterface
& MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK
;
4329 /* Update the minSyncFactor based on bus type.
4331 if ((ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD
) ||
4332 (ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE
)) {
4334 if (ioc
->spi_data
.minSyncFactor
< MPT_ULTRA
)
4335 ioc
->spi_data
.minSyncFactor
= MPT_ULTRA
;
4339 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
4344 /* SCSI Port Page 2 - Read the header then the page.
4346 header
.PageVersion
= 0;
4347 header
.PageLength
= 0;
4348 header
.PageNumber
= 2;
4349 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_PORT
;
4352 cfg
.pageAddr
= portnum
;
4353 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4355 if (mpt_config(ioc
, &cfg
) != 0)
4358 if (header
.PageLength
> 0) {
4359 /* Allocate memory and read SCSI Port Page 2
4361 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
4363 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_NVRAM
;
4364 cfg
.physAddr
= buf_dma
;
4365 if (mpt_config(ioc
, &cfg
) != 0) {
4366 /* Nvram data is left with INVALID mark
4370 SCSIPortPage2_t
*pPP2
= (SCSIPortPage2_t
*) pbuf
;
4371 MpiDeviceInfo_t
*pdevice
= NULL
;
4373 /* Save the Port Page 2 data
4374 * (reformat into a 32bit quantity)
4376 data
= le32_to_cpu(pPP2
->PortFlags
) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK
;
4377 ioc
->spi_data
.PortFlags
= data
;
4378 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
4379 pdevice
= &pPP2
->DeviceSettings
[ii
];
4380 data
= (le16_to_cpu(pdevice
->DeviceFlags
) << 16) |
4381 (pdevice
->SyncFactor
<< 8) | pdevice
->Timeout
;
4382 ioc
->spi_data
.nvram
[ii
] = data
;
4386 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
4390 /* Update Adapter limits with those from NVRAM
4391 * Comment: Don't need to do this. Target performance
4392 * parameters will never exceed the adapters limits.
4398 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4399 /* mpt_readScsiDevicePageHeaders - save version and length of SDP1
4400 * @ioc: Pointer to a Adapter Strucutre
4401 * @portnum: IOC port number
4403 * Return: -EFAULT if read of config page header fails
4407 mpt_readScsiDevicePageHeaders(MPT_ADAPTER
*ioc
, int portnum
)
4410 ConfigPageHeader_t header
;
4412 /* Read the SCSI Device Page 1 header
4414 header
.PageVersion
= 0;
4415 header
.PageLength
= 0;
4416 header
.PageNumber
= 1;
4417 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
4420 cfg
.pageAddr
= portnum
;
4421 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4424 if (mpt_config(ioc
, &cfg
) != 0)
4427 ioc
->spi_data
.sdp1version
= cfg
.hdr
->PageVersion
;
4428 ioc
->spi_data
.sdp1length
= cfg
.hdr
->PageLength
;
4430 header
.PageVersion
= 0;
4431 header
.PageLength
= 0;
4432 header
.PageNumber
= 0;
4433 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
4434 if (mpt_config(ioc
, &cfg
) != 0)
4437 ioc
->spi_data
.sdp0version
= cfg
.hdr
->PageVersion
;
4438 ioc
->spi_data
.sdp0length
= cfg
.hdr
->PageLength
;
4440 dcprintk((MYIOC_s_INFO_FMT
"Headers: 0: version %d length %d\n",
4441 ioc
->name
, ioc
->spi_data
.sdp0version
, ioc
->spi_data
.sdp0length
));
4443 dcprintk((MYIOC_s_INFO_FMT
"Headers: 1: version %d length %d\n",
4444 ioc
->name
, ioc
->spi_data
.sdp1version
, ioc
->spi_data
.sdp1length
));
4448 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4450 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4451 * @ioc: Pointer to a Adapter Strucutre
4452 * @portnum: IOC port number
4456 * -EFAULT if read of config page header fails or data pointer not NULL
4457 * -ENOMEM if pci_alloc failed
4460 mpt_findImVolumes(MPT_ADAPTER
*ioc
)
4464 ConfigPageIoc2RaidVol_t
*pIocRv
;
4465 dma_addr_t ioc2_dma
;
4467 ConfigPageHeader_t header
;
4474 /* Read IOCP2 header then the page.
4476 header
.PageVersion
= 0;
4477 header
.PageLength
= 0;
4478 header
.PageNumber
= 2;
4479 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
4483 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4486 if (mpt_config(ioc
, &cfg
) != 0)
4489 if (header
.PageLength
== 0)
4492 iocpage2sz
= header
.PageLength
* 4;
4493 pIoc2
= pci_alloc_consistent(ioc
->pcidev
, iocpage2sz
, &ioc2_dma
);
4497 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4498 cfg
.physAddr
= ioc2_dma
;
4499 if (mpt_config(ioc
, &cfg
) != 0)
4502 if ( (mem
= (u8
*)ioc
->spi_data
.pIocPg2
) == NULL
) {
4503 mem
= kmalloc(iocpage2sz
, GFP_ATOMIC
);
4505 ioc
->spi_data
.pIocPg2
= (IOCPage2_t
*) mem
;
4510 memcpy(mem
, (u8
*)pIoc2
, iocpage2sz
);
4512 /* Identify RAID Volume Id's */
4513 nVols
= pIoc2
->NumActiveVolumes
;
4519 /* At least 1 RAID Volume
4521 pIocRv
= pIoc2
->RaidVolume
;
4522 ioc
->spi_data
.isRaid
= 0;
4523 for (jj
= 0; jj
< nVols
; jj
++, pIocRv
++) {
4524 vid
= pIocRv
->VolumeID
;
4525 vbus
= pIocRv
->VolumeBus
;
4526 vioc
= pIocRv
->VolumeIOC
;
4531 ioc
->spi_data
.isRaid
|= (1 << vid
);
4533 /* Error! Always bus 0
4539 /* Identify Hidden Physical Disk Id's */
4540 nPhys
= pIoc2
->NumActivePhysDisks
;
4542 /* No physical disks.
4545 mpt_read_ioc_pg_3(ioc
);
4549 pci_free_consistent(ioc
->pcidev
, iocpage2sz
, pIoc2
, ioc2_dma
);
4555 mpt_read_ioc_pg_3(MPT_ADAPTER
*ioc
)
4560 ConfigPageHeader_t header
;
4561 dma_addr_t ioc3_dma
;
4564 /* Free the old page
4566 if (ioc
->spi_data
.pIocPg3
) {
4567 kfree(ioc
->spi_data
.pIocPg3
);
4568 ioc
->spi_data
.pIocPg3
= NULL
;
4571 /* There is at least one physical disk.
4572 * Read and save IOC Page 3
4574 header
.PageVersion
= 0;
4575 header
.PageLength
= 0;
4576 header
.PageNumber
= 3;
4577 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
4581 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4584 if (mpt_config(ioc
, &cfg
) != 0)
4587 if (header
.PageLength
== 0)
4590 /* Read Header good, alloc memory
4592 iocpage3sz
= header
.PageLength
* 4;
4593 pIoc3
= pci_alloc_consistent(ioc
->pcidev
, iocpage3sz
, &ioc3_dma
);
4597 /* Read the Page and save the data
4598 * into malloc'd memory.
4600 cfg
.physAddr
= ioc3_dma
;
4601 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4602 if (mpt_config(ioc
, &cfg
) == 0) {
4603 mem
= kmalloc(iocpage3sz
, GFP_ATOMIC
);
4605 memcpy(mem
, (u8
*)pIoc3
, iocpage3sz
);
4606 ioc
->spi_data
.pIocPg3
= (IOCPage3_t
*) mem
;
4610 pci_free_consistent(ioc
->pcidev
, iocpage3sz
, pIoc3
, ioc3_dma
);
4616 mpt_read_ioc_pg_4(MPT_ADAPTER
*ioc
)
4620 ConfigPageHeader_t header
;
4621 dma_addr_t ioc4_dma
;
4624 /* Read and save IOC Page 4
4626 header
.PageVersion
= 0;
4627 header
.PageLength
= 0;
4628 header
.PageNumber
= 4;
4629 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
4633 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4636 if (mpt_config(ioc
, &cfg
) != 0)
4639 if (header
.PageLength
== 0)
4642 if ( (pIoc4
= ioc
->spi_data
.pIocPg4
) == NULL
) {
4643 iocpage4sz
= (header
.PageLength
+ 4) * 4; /* Allow 4 additional SEP's */
4644 pIoc4
= pci_alloc_consistent(ioc
->pcidev
, iocpage4sz
, &ioc4_dma
);
4648 ioc4_dma
= ioc
->spi_data
.IocPg4_dma
;
4649 iocpage4sz
= ioc
->spi_data
.IocPg4Sz
;
4652 /* Read the Page into dma memory.
4654 cfg
.physAddr
= ioc4_dma
;
4655 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4656 if (mpt_config(ioc
, &cfg
) == 0) {
4657 ioc
->spi_data
.pIocPg4
= (IOCPage4_t
*) pIoc4
;
4658 ioc
->spi_data
.IocPg4_dma
= ioc4_dma
;
4659 ioc
->spi_data
.IocPg4Sz
= iocpage4sz
;
4661 pci_free_consistent(ioc
->pcidev
, iocpage4sz
, pIoc4
, ioc4_dma
);
4662 ioc
->spi_data
.pIocPg4
= NULL
;
4667 mpt_read_ioc_pg_1(MPT_ADAPTER
*ioc
)
4671 ConfigPageHeader_t header
;
4672 dma_addr_t ioc1_dma
;
4676 /* Check the Coalescing Timeout in IOC Page 1
4678 header
.PageVersion
= 0;
4679 header
.PageLength
= 0;
4680 header
.PageNumber
= 1;
4681 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
4685 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4688 if (mpt_config(ioc
, &cfg
) != 0)
4691 if (header
.PageLength
== 0)
4694 /* Read Header good, alloc memory
4696 iocpage1sz
= header
.PageLength
* 4;
4697 pIoc1
= pci_alloc_consistent(ioc
->pcidev
, iocpage1sz
, &ioc1_dma
);
4701 /* Read the Page and check coalescing timeout
4703 cfg
.physAddr
= ioc1_dma
;
4704 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4705 if (mpt_config(ioc
, &cfg
) == 0) {
4707 tmp
= le32_to_cpu(pIoc1
->Flags
) & MPI_IOCPAGE1_REPLY_COALESCING
;
4708 if (tmp
== MPI_IOCPAGE1_REPLY_COALESCING
) {
4709 tmp
= le32_to_cpu(pIoc1
->CoalescingTimeout
);
4711 dprintk((MYIOC_s_INFO_FMT
"Coalescing Enabled Timeout = %d\n",
4714 if (tmp
> MPT_COALESCING_TIMEOUT
) {
4715 pIoc1
->CoalescingTimeout
= cpu_to_le32(MPT_COALESCING_TIMEOUT
);
4717 /* Write NVRAM and current
4720 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
4721 if (mpt_config(ioc
, &cfg
) == 0) {
4722 dprintk((MYIOC_s_INFO_FMT
"Reset Current Coalescing Timeout to = %d\n",
4723 ioc
->name
, MPT_COALESCING_TIMEOUT
));
4725 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM
;
4726 if (mpt_config(ioc
, &cfg
) == 0) {
4727 dprintk((MYIOC_s_INFO_FMT
"Reset NVRAM Coalescing Timeout to = %d\n",
4728 ioc
->name
, MPT_COALESCING_TIMEOUT
));
4730 dprintk((MYIOC_s_INFO_FMT
"Reset NVRAM Coalescing Timeout Failed\n",
4735 dprintk((MYIOC_s_WARN_FMT
"Reset of Current Coalescing Timeout Failed!\n",
4741 dprintk((MYIOC_s_WARN_FMT
"Coalescing Disabled\n", ioc
->name
));
4745 pci_free_consistent(ioc
->pcidev
, iocpage1sz
, pIoc1
, ioc1_dma
);
4750 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4752 * SendEventNotification - Send EventNotification (on or off) request
4754 * @ioc: Pointer to MPT_ADAPTER structure
4755 * @EvSwitch: Event switch flags
4758 SendEventNotification(MPT_ADAPTER
*ioc
, u8 EvSwitch
)
4760 EventNotification_t
*evnp
;
4762 evnp
= (EventNotification_t
*) mpt_get_msg_frame(mpt_base_index
, ioc
);
4764 dprintk((MYIOC_s_WARN_FMT
"Unable to allocate event request frame!\n",
4768 memset(evnp
, 0, sizeof(*evnp
));
4770 dprintk((MYIOC_s_INFO_FMT
"Sending EventNotification(%d)\n", ioc
->name
, EvSwitch
));
4772 evnp
->Function
= MPI_FUNCTION_EVENT_NOTIFICATION
;
4773 evnp
->ChainOffset
= 0;
4775 evnp
->Switch
= EvSwitch
;
4777 mpt_put_msg_frame(mpt_base_index
, ioc
, (MPT_FRAME_HDR
*)evnp
);
4782 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4784 * SendEventAck - Send EventAck request to MPT adapter.
4785 * @ioc: Pointer to MPT_ADAPTER structure
4786 * @evnp: Pointer to original EventNotification request
4789 SendEventAck(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*evnp
)
4793 if ((pAck
= (EventAck_t
*) mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
4794 printk(MYIOC_s_WARN_FMT
"Unable to allocate event ACK request frame!\n",
4798 memset(pAck
, 0, sizeof(*pAck
));
4800 dprintk((MYIOC_s_INFO_FMT
"Sending EventAck\n", ioc
->name
));
4802 pAck
->Function
= MPI_FUNCTION_EVENT_ACK
;
4803 pAck
->ChainOffset
= 0;
4805 pAck
->Event
= evnp
->Event
;
4806 pAck
->EventContext
= evnp
->EventContext
;
4808 mpt_put_msg_frame(mpt_base_index
, ioc
, (MPT_FRAME_HDR
*)pAck
);
4813 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4815 * mpt_config - Generic function to issue config message
4816 * @ioc - Pointer to an adapter structure
4817 * @cfg - Pointer to a configuration structure. Struct contains
4818 * action, page address, direction, physical address
4819 * and pointer to a configuration page header
4820 * Page header is updated.
4822 * Returns 0 for success
4823 * -EPERM if not allowed due to ISR context
4824 * -EAGAIN if no msg frames currently available
4825 * -EFAULT for non-successful reply or no reply (timeout)
4828 mpt_config(MPT_ADAPTER
*ioc
, CONFIGPARMS
*pCfg
)
4832 unsigned long flags
;
4837 /* (Bugzilla:fibrebugs, #513)
4838 * Bug fix (part 1)! 20010905 -sralston
4839 * Prevent calling wait_event() (below), if caller happens
4840 * to be in ISR context, because that is fatal!
4842 in_isr
= in_interrupt();
4844 dcprintk((MYIOC_s_WARN_FMT
"Config request not allowed in ISR context!\n",
4849 /* Get and Populate a free Frame
4851 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
4852 dcprintk((MYIOC_s_WARN_FMT
"mpt_config: no msg frames!\n",
4856 pReq
= (Config_t
*)mf
;
4857 pReq
->Action
= pCfg
->action
;
4859 pReq
->ChainOffset
= 0;
4860 pReq
->Function
= MPI_FUNCTION_CONFIG
;
4861 pReq
->ExtPageLength
= 0;
4862 pReq
->ExtPageType
= 0;
4864 for (ii
=0; ii
< 8; ii
++)
4865 pReq
->Reserved2
[ii
] = 0;
4867 pReq
->Header
.PageVersion
= pCfg
->hdr
->PageVersion
;
4868 pReq
->Header
.PageLength
= pCfg
->hdr
->PageLength
;
4869 pReq
->Header
.PageNumber
= pCfg
->hdr
->PageNumber
;
4870 pReq
->Header
.PageType
= (pCfg
->hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
);
4871 pReq
->PageAddress
= cpu_to_le32(pCfg
->pageAddr
);
4873 /* Add a SGE to the config request.
4876 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_WRITE
;
4878 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
;
4880 flagsLength
|= pCfg
->hdr
->PageLength
* 4;
4882 mpt_add_sge((char *)&pReq
->PageBufferSGE
, flagsLength
, pCfg
->physAddr
);
4884 dcprintk((MYIOC_s_INFO_FMT
"Sending Config request type %d, page %d and action %d\n",
4885 ioc
->name
, pReq
->Header
.PageType
, pReq
->Header
.PageNumber
, pReq
->Action
));
4887 /* Append pCfg pointer to end of mf
4889 *((void **) (((u8
*) mf
) + (ioc
->req_sz
- sizeof(void *)))) = (void *) pCfg
;
4891 /* Initalize the timer
4893 init_timer(&pCfg
->timer
);
4894 pCfg
->timer
.data
= (unsigned long) ioc
;
4895 pCfg
->timer
.function
= mpt_timer_expired
;
4896 pCfg
->wait_done
= 0;
4898 /* Set the timer; ensure 10 second minimum */
4899 if (pCfg
->timeout
< 10)
4900 pCfg
->timer
.expires
= jiffies
+ HZ
*10;
4902 pCfg
->timer
.expires
= jiffies
+ HZ
*pCfg
->timeout
;
4904 /* Add to end of Q, set timer and then issue this command */
4905 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
4906 Q_ADD_TAIL(&ioc
->configQ
.head
, &pCfg
->linkage
, Q_ITEM
);
4907 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
4909 add_timer(&pCfg
->timer
);
4910 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
4911 wait_event(mpt_waitq
, pCfg
->wait_done
);
4913 /* mf has been freed - do not access */
4920 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4922 * mpt_toolbox - Generic function to issue toolbox message
4923 * @ioc - Pointer to an adapter structure
4924 * @cfg - Pointer to a toolbox structure. Struct contains
4925 * action, page address, direction, physical address
4926 * and pointer to a configuration page header
4927 * Page header is updated.
4929 * Returns 0 for success
4930 * -EPERM if not allowed due to ISR context
4931 * -EAGAIN if no msg frames currently available
4932 * -EFAULT for non-successful reply or no reply (timeout)
4935 mpt_toolbox(MPT_ADAPTER
*ioc
, CONFIGPARMS
*pCfg
)
4937 ToolboxIstwiReadWriteRequest_t
*pReq
;
4939 struct pci_dev
*pdev
;
4940 unsigned long flags
;
4945 /* (Bugzilla:fibrebugs, #513)
4946 * Bug fix (part 1)! 20010905 -sralston
4947 * Prevent calling wait_event() (below), if caller happens
4948 * to be in ISR context, because that is fatal!
4950 in_isr
= in_interrupt();
4952 dcprintk((MYIOC_s_WARN_FMT
"toobox request not allowed in ISR context!\n",
4957 /* Get and Populate a free Frame
4959 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
4960 dcprintk((MYIOC_s_WARN_FMT
"mpt_toolbox: no msg frames!\n",
4964 pReq
= (ToolboxIstwiReadWriteRequest_t
*)mf
;
4965 pReq
->Tool
= pCfg
->action
;
4967 pReq
->ChainOffset
= 0;
4968 pReq
->Function
= MPI_FUNCTION_TOOLBOX
;
4969 pReq
->Reserved1
= 0;
4970 pReq
->Reserved2
= 0;
4972 pReq
->Flags
= pCfg
->dir
;
4974 pReq
->Reserved3
= 0;
4975 pReq
->NumAddressBytes
= 0x01;
4976 pReq
->Reserved4
= 0;
4977 pReq
->DataLength
= 0x04;
4978 pdev
= (struct pci_dev
*) ioc
->pcidev
;
4979 if (pdev
->devfn
& 1)
4980 pReq
->DeviceAddr
= 0xB2;
4982 pReq
->DeviceAddr
= 0xB0;
4986 pReq
->Reserved5
= 0;
4988 /* Add a SGE to the config request.
4991 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
| 4;
4993 mpt_add_sge((char *)&pReq
->SGL
, flagsLength
, pCfg
->physAddr
);
4995 dcprintk((MYIOC_s_INFO_FMT
"Sending Toolbox request, Tool=%x\n",
4996 ioc
->name
, pReq
->Tool
));
4998 /* Append pCfg pointer to end of mf
5000 *((void **) (((u8
*) mf
) + (ioc
->req_sz
- sizeof(void *)))) = (void *) pCfg
;
5002 /* Initalize the timer
5004 init_timer(&pCfg
->timer
);
5005 pCfg
->timer
.data
= (unsigned long) ioc
;
5006 pCfg
->timer
.function
= mpt_timer_expired
;
5007 pCfg
->wait_done
= 0;
5009 /* Set the timer; ensure 10 second minimum */
5010 if (pCfg
->timeout
< 10)
5011 pCfg
->timer
.expires
= jiffies
+ HZ
*10;
5013 pCfg
->timer
.expires
= jiffies
+ HZ
*pCfg
->timeout
;
5015 /* Add to end of Q, set timer and then issue this command */
5016 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
5017 Q_ADD_TAIL(&ioc
->configQ
.head
, &pCfg
->linkage
, Q_ITEM
);
5018 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
5020 add_timer(&pCfg
->timer
);
5021 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
5022 wait_event(mpt_waitq
, pCfg
->wait_done
);
5024 /* mf has been freed - do not access */
5031 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5033 * mpt_timer_expired - Call back for timer process.
5034 * Used only internal config functionality.
5035 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5038 mpt_timer_expired(unsigned long data
)
5040 MPT_ADAPTER
*ioc
= (MPT_ADAPTER
*) data
;
5042 dcprintk((MYIOC_s_WARN_FMT
"mpt_timer_expired! \n", ioc
->name
));
5044 /* Perform a FW reload */
5045 if (mpt_HardResetHandler(ioc
, NO_SLEEP
) < 0)
5046 printk(MYIOC_s_WARN_FMT
"Firmware Reload FAILED!\n", ioc
->name
);
5048 /* No more processing.
5049 * Hard reset clean-up will wake up
5050 * process and free all resources.
5052 dcprintk((MYIOC_s_WARN_FMT
"mpt_timer_expired complete!\n", ioc
->name
));
5057 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5059 * mpt_ioc_reset - Base cleanup for hard reset
5060 * @ioc: Pointer to the adapter structure
5061 * @reset_phase: Indicates pre- or post-reset functionality
5063 * Remark: Free's resources with internally generated commands.
5066 mpt_ioc_reset(MPT_ADAPTER
*ioc
, int reset_phase
)
5069 unsigned long flags
;
5071 dprintk((KERN_WARNING MYNAM
5072 ": IOC %s_reset routed to MPT base driver!\n",
5073 reset_phase
==MPT_IOC_SETUP_RESET
? "setup" : (
5074 reset_phase
==MPT_IOC_PRE_RESET
? "pre" : "post")));
5076 if (reset_phase
== MPT_IOC_SETUP_RESET
) {
5078 } else if (reset_phase
== MPT_IOC_PRE_RESET
) {
5079 /* If the internal config Q is not empty -
5080 * delete timer. MF resources will be freed when
5081 * the FIFO's are primed.
5083 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
5084 if (! Q_IS_EMPTY(&ioc
->configQ
)){
5085 pCfg
= (CONFIGPARMS
*)ioc
->configQ
.head
;
5087 del_timer(&pCfg
->timer
);
5088 pCfg
= (CONFIGPARMS
*) (pCfg
->linkage
.forw
);
5089 } while (pCfg
!= (CONFIGPARMS
*)&ioc
->configQ
);
5091 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
5096 /* Search the configQ for internal commands.
5097 * Flush the Q, and wake up all suspended threads.
5099 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
5100 if (! Q_IS_EMPTY(&ioc
->configQ
)){
5101 pCfg
= (CONFIGPARMS
*)ioc
->configQ
.head
;
5103 pNext
= (CONFIGPARMS
*) pCfg
->linkage
.forw
;
5105 Q_DEL_ITEM(&pCfg
->linkage
);
5107 pCfg
->status
= MPT_CONFIG_ERROR
;
5108 pCfg
->wait_done
= 1;
5109 wake_up(&mpt_waitq
);
5112 } while (pCfg
!= (CONFIGPARMS
*)&ioc
->configQ
);
5114 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
5117 return 1; /* currently means nothing really */
5121 #ifdef CONFIG_PROC_FS /* { */
5122 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5124 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5126 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5128 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5130 * Returns 0 for success, non-zero for failure.
5133 procmpt_create(void)
5135 struct proc_dir_entry
*ent
;
5137 mpt_proc_root_dir
= proc_mkdir(MPT_PROCFS_MPTBASEDIR
, NULL
);
5138 if (mpt_proc_root_dir
== NULL
)
5141 ent
= create_proc_entry("summary", S_IFREG
|S_IRUGO
, mpt_proc_root_dir
);
5143 ent
->read_proc
= procmpt_summary_read
;
5145 ent
= create_proc_entry("version", S_IFREG
|S_IRUGO
, mpt_proc_root_dir
);
5147 ent
->read_proc
= procmpt_version_read
;
5152 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5154 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5156 * Returns 0 for success, non-zero for failure.
5159 procmpt_destroy(void)
5161 remove_proc_entry("version", mpt_proc_root_dir
);
5162 remove_proc_entry("summary", mpt_proc_root_dir
);
5163 remove_proc_entry(MPT_PROCFS_MPTBASEDIR
, NULL
);
5166 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5168 * procmpt_summary_read - Handle read request from /proc/mpt/summary
5169 * or from /proc/mpt/iocN/summary.
5170 * @buf: Pointer to area to write information
5171 * @start: Pointer to start pointer
5172 * @offset: Offset to start writing
5174 * @eof: Pointer to EOF integer
5177 * Returns number of characters written to process performing the read.
5180 procmpt_summary_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
5190 mpt_print_ioc_summary(ioc
, out
, &more
, 0, 1);
5194 list_for_each_entry(ioc
, &ioc_list
, list
) {
5197 mpt_print_ioc_summary(ioc
, out
, &more
, 0, 1);
5200 if ((out
-buf
) >= request
)
5207 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
5210 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5212 * procmpt_version_read - Handle read request from /proc/mpt/version.
5213 * @buf: Pointer to area to write information
5214 * @start: Pointer to start pointer
5215 * @offset: Offset to start writing
5217 * @eof: Pointer to EOF integer
5220 * Returns number of characters written to process performing the read.
5223 procmpt_version_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
5226 int scsi
, lan
, ctl
, targ
, dmp
;
5230 len
= sprintf(buf
, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON
);
5231 len
+= sprintf(buf
+len
, " Fusion MPT base driver\n");
5233 scsi
= lan
= ctl
= targ
= dmp
= 0;
5234 for (ii
=MPT_MAX_PROTOCOL_DRIVERS
-1; ii
; ii
--) {
5236 if (MptCallbacks
[ii
]) {
5237 switch (MptDriverClass
[ii
]) {
5238 case MPTSCSIH_DRIVER
:
5239 if (!scsi
++) drvname
= "SCSI host";
5242 if (!lan
++) drvname
= "LAN";
5245 if (!targ
++) drvname
= "SCSI target";
5248 if (!ctl
++) drvname
= "ioctl";
5251 if (!dmp
++) drvname
= "DMP";
5256 len
+= sprintf(buf
+len
, " Fusion MPT %s driver\n", drvname
);
5260 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
5263 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5265 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5266 * @buf: Pointer to area to write information
5267 * @start: Pointer to start pointer
5268 * @offset: Offset to start writing
5270 * @eof: Pointer to EOF integer
5273 * Returns number of characters written to process performing the read.
5276 procmpt_iocinfo_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
5278 MPT_ADAPTER
*ioc
= data
;
5284 mpt_get_fw_exp_ver(expVer
, ioc
);
5286 len
= sprintf(buf
, "%s:", ioc
->name
);
5287 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
5288 len
+= sprintf(buf
+len
, " (f/w download boot flag set)");
5289 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5290 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5292 len
+= sprintf(buf
+len
, "\n ProductID = 0x%04x (%s)\n",
5293 ioc
->facts
.ProductID
,
5295 len
+= sprintf(buf
+len
, " FWVersion = 0x%08x%s", ioc
->facts
.FWVersion
.Word
, expVer
);
5296 if (ioc
->facts
.FWImageSize
)
5297 len
+= sprintf(buf
+len
, " (fw_size=%d)", ioc
->facts
.FWImageSize
);
5298 len
+= sprintf(buf
+len
, "\n MsgVersion = 0x%04x\n", ioc
->facts
.MsgVersion
);
5299 len
+= sprintf(buf
+len
, " FirstWhoInit = 0x%02x\n", ioc
->FirstWhoInit
);
5300 len
+= sprintf(buf
+len
, " EventState = 0x%02x\n", ioc
->facts
.EventState
);
5302 len
+= sprintf(buf
+len
, " CurrentHostMfaHighAddr = 0x%08x\n",
5303 ioc
->facts
.CurrentHostMfaHighAddr
);
5304 len
+= sprintf(buf
+len
, " CurrentSenseBufferHighAddr = 0x%08x\n",
5305 ioc
->facts
.CurrentSenseBufferHighAddr
);
5307 len
+= sprintf(buf
+len
, " MaxChainDepth = 0x%02x frames\n", ioc
->facts
.MaxChainDepth
);
5308 len
+= sprintf(buf
+len
, " MinBlockSize = 0x%02x bytes\n", 4*ioc
->facts
.BlockSize
);
5310 len
+= sprintf(buf
+len
, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5311 (void *)ioc
->req_frames
, (void *)(ulong
)ioc
->req_frames_dma
);
5313 * Rounding UP to nearest 4-kB boundary here...
5315 sz
= (ioc
->req_sz
* ioc
->req_depth
) + 128;
5316 sz
= ((sz
+ 0x1000UL
- 1UL) / 0x1000) * 0x1000;
5317 len
+= sprintf(buf
+len
, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5318 ioc
->req_sz
, ioc
->req_depth
, ioc
->req_sz
*ioc
->req_depth
, sz
);
5319 len
+= sprintf(buf
+len
, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
5320 4*ioc
->facts
.RequestFrameSize
,
5321 ioc
->facts
.GlobalCredits
);
5323 len
+= sprintf(buf
+len
, " Frames @ 0x%p (Dma @ 0x%p)\n",
5324 (void *)ioc
->alloc
, (void *)(ulong
)ioc
->alloc_dma
);
5325 sz
= (ioc
->reply_sz
* ioc
->reply_depth
) + 128;
5326 len
+= sprintf(buf
+len
, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5327 ioc
->reply_sz
, ioc
->reply_depth
, ioc
->reply_sz
*ioc
->reply_depth
, sz
);
5328 len
+= sprintf(buf
+len
, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
5329 ioc
->facts
.CurReplyFrameSize
,
5330 ioc
->facts
.ReplyQueueDepth
);
5332 len
+= sprintf(buf
+len
, " MaxDevices = %d\n",
5333 (ioc
->facts
.MaxDevices
==0) ? 255 : ioc
->facts
.MaxDevices
);
5334 len
+= sprintf(buf
+len
, " MaxBuses = %d\n", ioc
->facts
.MaxBuses
);
5337 for (p
=0; p
< ioc
->facts
.NumberOfPorts
; p
++) {
5338 len
+= sprintf(buf
+len
, " PortNumber = %d (of %d)\n",
5340 ioc
->facts
.NumberOfPorts
);
5341 if ((int)ioc
->chip_type
<= (int)FC929
) {
5342 if (ioc
->pfacts
[p
].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
5343 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
5344 len
+= sprintf(buf
+len
, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5345 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
5347 len
+= sprintf(buf
+len
, " WWN = %08X%08X:%08X%08X\n",
5348 ioc
->fc_port_page0
[p
].WWNN
.High
,
5349 ioc
->fc_port_page0
[p
].WWNN
.Low
,
5350 ioc
->fc_port_page0
[p
].WWPN
.High
,
5351 ioc
->fc_port_page0
[p
].WWPN
.Low
);
5355 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
5358 #endif /* CONFIG_PROC_FS } */
5360 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5362 mpt_get_fw_exp_ver(char *buf
, MPT_ADAPTER
*ioc
)
5365 if ((ioc
->facts
.FWVersion
.Word
>> 24) == 0x0E) {
5366 sprintf(buf
, " (Exp %02d%02d)",
5367 (ioc
->facts
.FWVersion
.Word
>> 16) & 0x00FF, /* Month */
5368 (ioc
->facts
.FWVersion
.Word
>> 8) & 0x1F); /* Day */
5371 if ((ioc
->facts
.FWVersion
.Word
>> 8) & 0x80)
5372 strcat(buf
, " [MDBG]");
5376 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5378 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5379 * @ioc: Pointer to MPT_ADAPTER structure
5380 * @buffer: Pointer to buffer where IOC summary info should be written
5381 * @size: Pointer to number of bytes we wrote (set by this routine)
5382 * @len: Offset at which to start writing in buffer
5383 * @showlan: Display LAN stuff?
5385 * This routine writes (english readable) ASCII text, which represents
5386 * a summary of IOC information, to a buffer.
5389 mpt_print_ioc_summary(MPT_ADAPTER
*ioc
, char *buffer
, int *size
, int len
, int showlan
)
5394 mpt_get_fw_exp_ver(expVer
, ioc
);
5397 * Shorter summary of attached ioc's...
5399 y
= sprintf(buffer
+len
, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
5402 MPT_FW_REV_MAGIC_ID_STRING
, /* "FwRev=" or somesuch */
5403 ioc
->facts
.FWVersion
.Word
,
5405 ioc
->facts
.NumberOfPorts
,
5408 if (showlan
&& (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
)) {
5409 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
5410 y
+= sprintf(buffer
+len
+y
, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
5411 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
5415 y
+= sprintf(buffer
+len
+y
, ", IRQ=%d", ioc
->pci_irq
);
5417 y
+= sprintf(buffer
+len
+y
, ", IRQ=%s", __irq_itoa(ioc
->pci_irq
));
5421 y
+= sprintf(buffer
+len
+y
, " (disabled)");
5423 y
+= sprintf(buffer
+len
+y
, "\n");
5428 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5432 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5434 * mpt_HardResetHandler - Generic reset handler, issue SCSI Task
5435 * Management call based on input arg values. If TaskMgmt fails,
5436 * return associated SCSI request.
5437 * @ioc: Pointer to MPT_ADAPTER structure
5438 * @sleepFlag: Indicates if sleep or schedule must be called.
5440 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
5441 * or a non-interrupt thread. In the former, must not call schedule().
5443 * Remark: A return of -1 is a FATAL error case, as it means a
5444 * FW reload/initialization failed.
5446 * Returns 0 for SUCCESS or -1 if FAILED.
5449 mpt_HardResetHandler(MPT_ADAPTER
*ioc
, int sleepFlag
)
5452 unsigned long flags
;
5454 dtmprintk((MYIOC_s_INFO_FMT
"HardResetHandler Entered!\n", ioc
->name
));
5456 printk(MYIOC_s_INFO_FMT
"HardResetHandler Entered!\n", ioc
->name
);
5457 printk("MF count 0x%x !\n", ioc
->mfcnt
);
5460 /* Reset the adapter. Prevent more than 1 call to
5461 * mpt_do_ioc_recovery at any instant in time.
5463 spin_lock_irqsave(&ioc
->diagLock
, flags
);
5464 if ((ioc
->diagPending
) || (ioc
->alt_ioc
&& ioc
->alt_ioc
->diagPending
)){
5465 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
5468 ioc
->diagPending
= 1;
5470 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
5472 /* FIXME: If do_ioc_recovery fails, repeat....
5475 /* The SCSI driver needs to adjust timeouts on all current
5476 * commands prior to the diagnostic reset being issued.
5477 * Prevents timeouts occuring during a diagnostic reset...very bad.
5478 * For all other protocol drivers, this is a no-op.
5484 for (ii
=MPT_MAX_PROTOCOL_DRIVERS
-1; ii
; ii
--) {
5485 if (MptResetHandlers
[ii
]) {
5486 dtmprintk((MYIOC_s_INFO_FMT
"Calling IOC reset_setup handler #%d\n",
5488 r
+= (*(MptResetHandlers
[ii
]))(ioc
, MPT_IOC_SETUP_RESET
);
5490 dtmprintk((MYIOC_s_INFO_FMT
"Calling alt-%s setup reset handler #%d\n",
5491 ioc
->name
, ioc
->alt_ioc
->name
, ii
));
5492 r
+= (*(MptResetHandlers
[ii
]))(ioc
->alt_ioc
, MPT_IOC_SETUP_RESET
);
5498 if ((rc
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_RECOVER
, sleepFlag
)) != 0) {
5499 printk(KERN_WARNING MYNAM
": WARNING - (%d) Cannot recover %s\n",
5504 ioc
->alt_ioc
->reload_fw
= 0;
5506 spin_lock_irqsave(&ioc
->diagLock
, flags
);
5507 ioc
->diagPending
= 0;
5509 ioc
->alt_ioc
->diagPending
= 0;
5510 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
5512 dtmprintk((MYIOC_s_INFO_FMT
"HardResetHandler rc = %d!\n", ioc
->name
, rc
));
5517 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5519 EventDescriptionStr(u8 event
, u32 evData0
)
5524 case MPI_EVENT_NONE
:
5527 case MPI_EVENT_LOG_DATA
:
5530 case MPI_EVENT_STATE_CHANGE
:
5531 ds
= "State Change";
5533 case MPI_EVENT_UNIT_ATTENTION
:
5534 ds
= "Unit Attention";
5536 case MPI_EVENT_IOC_BUS_RESET
:
5537 ds
= "IOC Bus Reset";
5539 case MPI_EVENT_EXT_BUS_RESET
:
5540 ds
= "External Bus Reset";
5542 case MPI_EVENT_RESCAN
:
5543 ds
= "Bus Rescan Event";
5544 /* Ok, do we need to do anything here? As far as
5545 I can tell, this is when a new device gets added
5548 case MPI_EVENT_LINK_STATUS_CHANGE
:
5549 if (evData0
== MPI_EVENT_LINK_STATUS_FAILURE
)
5550 ds
= "Link Status(FAILURE) Change";
5552 ds
= "Link Status(ACTIVE) Change";
5554 case MPI_EVENT_LOOP_STATE_CHANGE
:
5555 if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LIP
)
5556 ds
= "Loop State(LIP) Change";
5557 else if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LPE
)
5558 ds
= "Loop State(LPE) Change"; /* ??? */
5560 ds
= "Loop State(LPB) Change"; /* ??? */
5562 case MPI_EVENT_LOGOUT
:
5565 case MPI_EVENT_EVENT_CHANGE
:
5567 ds
= "Events(ON) Change";
5569 ds
= "Events(OFF) Change";
5571 case MPI_EVENT_INTEGRATED_RAID
:
5572 ds
= "Integrated Raid";
5575 * MPT base "custom" events may be added here...
5584 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5586 * ProcessEventNotification - Route a received EventNotificationReply to
5587 * all currently regeistered event handlers.
5588 * @ioc: Pointer to MPT_ADAPTER structure
5589 * @pEventReply: Pointer to EventNotification reply frame
5590 * @evHandlers: Pointer to integer, number of event handlers
5592 * Returns sum of event handlers return values.
5595 ProcessEventNotification(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEventReply
, int *evHandlers
)
5607 * Do platform normalization of values
5609 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
5610 // evCtx = le32_to_cpu(pEventReply->EventContext);
5611 evDataLen
= le16_to_cpu(pEventReply
->EventDataLength
);
5613 evData0
= le32_to_cpu(pEventReply
->Data
[0]);
5616 evStr
= EventDescriptionStr(event
, evData0
);
5617 devtprintk((MYIOC_s_INFO_FMT
"MPT event (%s=%02Xh) detected!\n",
5622 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_EVENTS)
5623 printk(KERN_INFO MYNAM
": Event data:\n" KERN_INFO
);
5624 for (ii
= 0; ii
< evDataLen
; ii
++)
5625 printk(" %08x", le32_to_cpu(pEventReply
->Data
[ii
]));
5630 * Do general / base driver event processing
5633 case MPI_EVENT_NONE
: /* 00 */
5634 case MPI_EVENT_LOG_DATA
: /* 01 */
5635 case MPI_EVENT_STATE_CHANGE
: /* 02 */
5636 case MPI_EVENT_UNIT_ATTENTION
: /* 03 */
5637 case MPI_EVENT_IOC_BUS_RESET
: /* 04 */
5638 case MPI_EVENT_EXT_BUS_RESET
: /* 05 */
5639 case MPI_EVENT_RESCAN
: /* 06 */
5640 case MPI_EVENT_LINK_STATUS_CHANGE
: /* 07 */
5641 case MPI_EVENT_LOOP_STATE_CHANGE
: /* 08 */
5642 case MPI_EVENT_LOGOUT
: /* 09 */
5643 case MPI_EVENT_INTEGRATED_RAID
: /* 0B */
5644 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE
: /* 0C */
5647 case MPI_EVENT_EVENT_CHANGE
: /* 0A */
5649 u8 evState
= evData0
& 0xFF;
5651 /* CHECKME! What if evState unexpectedly says OFF (0)? */
5653 /* Update EventState field in cached IocFacts */
5654 if (ioc
->facts
.Function
) {
5655 ioc
->facts
.EventState
= evState
;
5662 * Should this event be logged? Events are written sequentially.
5663 * When buffer is full, start again at the top.
5665 if (ioc
->events
&& (ioc
->eventTypes
& ( 1 << event
))) {
5668 idx
= ioc
->eventContext
% ioc
->eventLogSize
;
5670 ioc
->events
[idx
].event
= event
;
5671 ioc
->events
[idx
].eventContext
= ioc
->eventContext
;
5673 for (ii
= 0; ii
< 2; ii
++) {
5675 ioc
->events
[idx
].data
[ii
] = le32_to_cpu(pEventReply
->Data
[ii
]);
5677 ioc
->events
[idx
].data
[ii
] = 0;
5680 ioc
->eventContext
++;
5685 * Call each currently registered protocol event handler.
5687 for (ii
=MPT_MAX_PROTOCOL_DRIVERS
-1; ii
; ii
--) {
5688 if (MptEvHandlers
[ii
]) {
5689 devtprintk((MYIOC_s_INFO_FMT
"Routing Event to event handler #%d\n",
5691 r
+= (*(MptEvHandlers
[ii
]))(ioc
, pEventReply
);
5695 /* FIXME? Examine results here? */
5698 * If needed, send (a single) EventAck.
5700 if (pEventReply
->AckRequired
== MPI_EVENT_NOTIFICATION_ACK_REQUIRED
) {
5701 if ((ii
= SendEventAck(ioc
, pEventReply
)) != 0) {
5702 devtprintk((MYIOC_s_WARN_FMT
"SendEventAck returned %d\n",
5707 *evHandlers
= handlers
;
5711 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5713 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
5714 * @ioc: Pointer to MPT_ADAPTER structure
5715 * @log_info: U32 LogInfo reply word from the IOC
5717 * Refer to lsi/fc_log.h.
5720 mpt_fc_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
5722 static char *subcl_str
[8] = {
5723 "FCP Initiator", "FCP Target", "LAN", "MPI Message Layer",
5724 "FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
5726 u8 subcl
= (log_info
>> 24) & 0x7;
5728 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): SubCl={%s}\n",
5729 ioc
->name
, log_info
, subcl_str
[subcl
]);
5732 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5734 * mpt_sp_log_info - Log information returned from SCSI Parallel IOC.
5735 * @ioc: Pointer to MPT_ADAPTER structure
5736 * @mr: Pointer to MPT reply frame
5737 * @log_info: U32 LogInfo word from the IOC
5739 * Refer to lsi/sp_log.h.
5742 mpt_sp_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
5744 u32 info
= log_info
& 0x00FF0000;
5745 char *desc
= "unknown";
5749 desc
= "bug! MID not found";
5750 if (ioc
->reload_fw
== 0)
5755 desc
= "Parity Error";
5759 desc
= "ASYNC Outbound Overrun";
5763 desc
= "SYNC Offset Error";
5771 desc
= "Msg In Overflow";
5779 desc
= "Outbound DMA Overrun";
5783 desc
= "Task Management";
5787 desc
= "Device Problem";
5791 desc
= "Invalid Phase Change";
5795 desc
= "Untagged Table Size";
5800 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): F/W: %s\n", ioc
->name
, log_info
, desc
);
5803 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5805 * mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
5806 * @ioc: Pointer to MPT_ADAPTER structure
5807 * @ioc_status: U32 IOCStatus word from IOC
5808 * @mf: Pointer to MPT request frame
5810 * Refer to lsi/mpi.h.
5813 mpt_sp_ioc_info(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
)
5815 u32 status
= ioc_status
& MPI_IOCSTATUS_MASK
;
5819 case MPI_IOCSTATUS_INVALID_FUNCTION
: /* 0x0001 */
5820 desc
= "Invalid Function";
5823 case MPI_IOCSTATUS_BUSY
: /* 0x0002 */
5827 case MPI_IOCSTATUS_INVALID_SGL
: /* 0x0003 */
5828 desc
= "Invalid SGL";
5831 case MPI_IOCSTATUS_INTERNAL_ERROR
: /* 0x0004 */
5832 desc
= "Internal Error";
5835 case MPI_IOCSTATUS_RESERVED
: /* 0x0005 */
5839 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES
: /* 0x0006 */
5840 desc
= "Insufficient Resources";
5843 case MPI_IOCSTATUS_INVALID_FIELD
: /* 0x0007 */
5844 desc
= "Invalid Field";
5847 case MPI_IOCSTATUS_INVALID_STATE
: /* 0x0008 */
5848 desc
= "Invalid State";
5851 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION
: /* 0x0020 */
5852 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE
: /* 0x0021 */
5853 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE
: /* 0x0022 */
5854 case MPI_IOCSTATUS_CONFIG_INVALID_DATA
: /* 0x0023 */
5855 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS
: /* 0x0024 */
5856 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT
: /* 0x0025 */
5857 /* No message for Config IOCStatus values */
5860 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR
: /* 0x0040 */
5861 /* No message for recovered error
5862 desc = "SCSI Recovered Error";
5866 case MPI_IOCSTATUS_SCSI_INVALID_BUS
: /* 0x0041 */
5867 desc
= "SCSI Invalid Bus";
5870 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID
: /* 0x0042 */
5871 desc
= "SCSI Invalid TargetID";
5874 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE
: /* 0x0043 */
5876 SCSIIORequest_t
*pScsiReq
= (SCSIIORequest_t
*) mf
;
5877 U8 cdb
= pScsiReq
->CDB
[0];
5878 if (cdb
!= 0x12) { /* Inquiry is issued for device scanning */
5879 desc
= "SCSI Device Not There";
5884 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN
: /* 0x0044 */
5885 desc
= "SCSI Data Overrun";
5888 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
: /* 0x0045 */
5889 /* This error is checked in scsi_io_done(). Skip.
5890 desc = "SCSI Data Underrun";
5894 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR
: /* 0x0046 */
5895 desc
= "SCSI I/O Data Error";
5898 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR
: /* 0x0047 */
5899 desc
= "SCSI Protocol Error";
5902 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED
: /* 0x0048 */
5903 desc
= "SCSI Task Terminated";
5906 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH
: /* 0x0049 */
5907 desc
= "SCSI Residual Mismatch";
5910 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED
: /* 0x004A */
5911 desc
= "SCSI Task Management Failed";
5914 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED
: /* 0x004B */
5915 desc
= "SCSI IOC Terminated";
5918 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED
: /* 0x004C */
5919 desc
= "SCSI Ext Terminated";
5927 printk(MYIOC_s_INFO_FMT
"IOCStatus(0x%04x): %s\n", ioc
->name
, status
, desc
);
5930 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5931 EXPORT_SYMBOL(ioc_list
);
5932 EXPORT_SYMBOL(mpt_proc_root_dir
);
5933 EXPORT_SYMBOL(DmpService
);
5934 EXPORT_SYMBOL(mpt_register
);
5935 EXPORT_SYMBOL(mpt_deregister
);
5936 EXPORT_SYMBOL(mpt_event_register
);
5937 EXPORT_SYMBOL(mpt_event_deregister
);
5938 EXPORT_SYMBOL(mpt_reset_register
);
5939 EXPORT_SYMBOL(mpt_reset_deregister
);
5940 EXPORT_SYMBOL(mpt_device_driver_register
);
5941 EXPORT_SYMBOL(mpt_device_driver_deregister
);
5942 EXPORT_SYMBOL(mpt_get_msg_frame
);
5943 EXPORT_SYMBOL(mpt_put_msg_frame
);
5944 EXPORT_SYMBOL(mpt_free_msg_frame
);
5945 EXPORT_SYMBOL(mpt_add_sge
);
5946 EXPORT_SYMBOL(mpt_add_chain
);
5947 EXPORT_SYMBOL(mpt_send_handshake_request
);
5948 EXPORT_SYMBOL(mpt_handshake_req_reply_wait
);
5949 EXPORT_SYMBOL(mpt_verify_adapter
);
5950 EXPORT_SYMBOL(mpt_GetIocState
);
5951 EXPORT_SYMBOL(mpt_print_ioc_summary
);
5952 EXPORT_SYMBOL(mpt_lan_index
);
5953 EXPORT_SYMBOL(mpt_stm_index
);
5954 EXPORT_SYMBOL(mpt_HardResetHandler
);
5955 EXPORT_SYMBOL(mpt_config
);
5956 EXPORT_SYMBOL(mpt_toolbox
);
5957 EXPORT_SYMBOL(mpt_findImVolumes
);
5958 EXPORT_SYMBOL(mpt_read_ioc_pg_3
);
5959 EXPORT_SYMBOL(mpt_alloc_fw_memory
);
5960 EXPORT_SYMBOL(mpt_free_fw_memory
);
5962 static struct pci_driver mptbase_driver
= {
5964 .id_table
= mptbase_pci_table
,
5965 .probe
= mptbase_probe
,
5966 .remove
= __devexit_p(mptbase_remove
),
5968 .shutdown
= mptbase_shutdown
,
5971 .suspend
= mptbase_suspend
,
5972 .resume
= mptbase_resume
,
5976 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5978 * fusion_init - Fusion MPT base driver initialization routine.
5980 * Returns 0 for success, non-zero for failure.
5988 if (FusionInitCalled
++) {
5989 dprintk((KERN_INFO MYNAM
": INFO - Driver late-init entry point called\n"));
5993 show_mptmod_ver(my_NAME
, my_VERSION
);
5994 printk(KERN_INFO COPYRIGHT
"\n");
5996 for (i
= 0; i
< MPT_MAX_PROTOCOL_DRIVERS
; i
++) {
5997 MptCallbacks
[i
] = NULL
;
5998 MptDriverClass
[i
] = MPTUNKNOWN_DRIVER
;
5999 MptEvHandlers
[i
] = NULL
;
6000 MptResetHandlers
[i
] = NULL
;
6005 /* NEW! 20010120 -sralston
6006 * Register ourselves (mptbase) in order to facilitate
6007 * EventNotification handling.
6009 mpt_base_index
= mpt_register(mpt_base_reply
, MPTBASE_DRIVER
);
6011 /* Register for hard reset handling callbacks.
6013 if (mpt_reset_register(mpt_base_index
, mpt_ioc_reset
) == 0) {
6014 dprintk((KERN_INFO MYNAM
": Register for IOC reset notification\n"));
6019 #ifdef CONFIG_PROC_FS
6020 (void) procmpt_create();
6022 r
= pci_module_init(&mptbase_driver
);
6029 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6031 * fusion_exit - Perform driver unload cleanup.
6033 * This routine frees all resources associated with each MPT adapter
6034 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
6040 dexitprintk((KERN_INFO MYNAM
": fusion_exit() called!\n"));
6042 pci_unregister_driver(&mptbase_driver
);
6043 mpt_reset_deregister(mpt_base_index
);
6045 #ifdef CONFIG_PROC_FS
6051 module_init(fusion_init
);
6052 module_exit(fusion_exit
);