2 * linux/drivers/message/fusion/mptbase.c
3 * This is the Fusion MPT base driver which supports multiple
4 * (SCSI + LAN) specialized protocol drivers.
5 * For use with LSI Logic PCI chip/adapter(s)
6 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
8 * Copyright (c) 1999-2005 LSI Logic Corporation
9 * (mailto:mpt_linux_developer@lsil.com)
12 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; version 2 of the License.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
24 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
25 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
26 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
27 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
28 solely responsible for determining the appropriateness of using and
29 distributing the Program and assumes all risks associated with its
30 exercise of rights under this Agreement, including but not limited to
31 the risks and costs of program errors, damage to or loss of data,
32 programs or equipment, and unavailability or interruption of operations.
34 DISCLAIMER OF LIABILITY
35 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
36 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
38 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
39 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
40 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
41 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
43 You should have received a copy of the GNU General Public License
44 along with this program; if not, write to the Free Software
45 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
47 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
49 #include <linux/config.h>
50 #include <linux/version.h>
51 #include <linux/kernel.h>
52 #include <linux/module.h>
53 #include <linux/errno.h>
54 #include <linux/init.h>
55 #include <linux/slab.h>
56 #include <linux/types.h>
57 #include <linux/pci.h>
58 #include <linux/kdev_t.h>
59 #include <linux/blkdev.h>
60 #include <linux/delay.h>
61 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
62 #include <linux/dma-mapping.h>
68 #include <asm/irq.h> /* needed for __irq_itoa() proto */
73 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
74 #define my_NAME "Fusion MPT base driver"
75 #define my_VERSION MPT_LINUX_VERSION_COMMON
76 #define MYNAM "mptbase"
78 MODULE_AUTHOR(MODULEAUTHOR);
79 MODULE_DESCRIPTION(my_NAME);
80 MODULE_LICENSE("GPL");
86 static int mfcounter = 0;
87 #define PRINT_MF_COUNT 20000
90 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
94 int mpt_lan_index = -1;
95 int mpt_stm_index = -1;
97 struct proc_dir_entry *mpt_proc_root_dir;
99 #define WHOINIT_UNKNOWN 0xAA
101 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
105 /* Adapter link list */
107 /* Callback lookup table */
108 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
109 /* Protocol driver class lookup table */
110 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
111 /* Event handler lookup table */
112 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
113 /* Reset handler lookup table */
114 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
115 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
117 static int mpt_base_index = -1;
118 static int last_drv_idx = -1;
120 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
122 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
126 static irqreturn_t mpt_interrupt(int irq, void *bus_id, struct pt_regs *r);
127 static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
128 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
129 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
131 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
132 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
133 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
134 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
136 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
137 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
138 //static u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
139 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
140 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
141 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
142 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
143 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
144 static int mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag);
145 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
146 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
147 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
148 static int PrimeIocFifos(MPT_ADAPTER *ioc);
149 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
150 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
151 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
152 static int GetLanConfigPages(MPT_ADAPTER *ioc);
153 static int GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
154 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
155 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
156 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
157 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
158 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
159 static void mpt_timer_expired(unsigned long data);
160 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
161 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
163 #ifdef CONFIG_PROC_FS
164 static int procmpt_summary_read(char *buf, char **start, off_t offset,
165 int request, int *eof, void *data);
166 static int procmpt_version_read(char *buf, char **start, off_t offset,
167 int request, int *eof, void *data);
168 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
169 int request, int *eof, void *data);
171 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
173 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
174 static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
175 static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
176 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
177 static void mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info);
179 /* module entry point */
180 static int __init fusion_init (void);
181 static void __exit fusion_exit (void);
183 #define CHIPREG_READ32(addr) readl_relaxed(addr)
184 #define CHIPREG_READ32_dmasync(addr) readl(addr)
185 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
186 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
187 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
189 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
191 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
192 * @irq: irq number (not used)
193 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
194 * @r: pt_regs pointer (not used)
196 * This routine is registered via the request_irq() kernel API call,
197 * and handles all interrupts generated from a specific MPT adapter
198 * (also referred to as a IO Controller or IOC).
199 * This routine must clear the interrupt from the adapter and does
200 * so by reading the reply FIFO. Multiple replies may be processed
201 * per single call to this routine; up to MPT_MAX_REPLIES_PER_ISR
202 * which is currently set to 32 in mptbase.h.
204 * This routine handles register-level access of the adapter but
205 * dispatches (calls) a protocol-specific callback routine to handle
206 * the protocol-specific details of the MPT request completion.
209 mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
220 ioc = (MPT_ADAPTER *)bus_id;
223 * Drain the reply FIFO!
225 * NOTES: I've seen up to 10 replies processed in this loop, so far...
226 * Update: I've seen up to 9182 replies processed in this loop! ??
227 * Update: Limit ourselves to processing max of N replies
232 if ((pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo)) == 0xFFFFFFFF)
239 * Check for non-TURBO reply!
241 if (pa & MPI_ADDRESS_REPLY_A_BIT) {
245 /* non-TURBO reply! Hmmm, something may be up...
246 * Newest turbo reply mechanism; get address
247 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
250 /* Map DMA address of reply header to cpu address.
251 * pa is 32 bits - but the dma address may be 32 or 64 bits
252 * get offset based only only the low addresses
254 reply_dma_low = (pa = (pa << 1));
255 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
256 (reply_dma_low - ioc->reply_frames_low_dma));
258 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
259 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
260 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
262 dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x\n",
263 ioc->name, mr, req_idx));
264 DBG_DUMP_REPLY_FRAME(mr)
266 /* Check/log IOC log info
268 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
269 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
270 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
271 if (ioc->bus_type == FC)
272 mpt_fc_log_info(ioc, log_info);
273 else if (ioc->bus_type == SCSI)
274 mpt_sp_log_info(ioc, log_info);
276 if (ioc_stat & MPI_IOCSTATUS_MASK) {
277 if (ioc->bus_type == SCSI)
278 mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
282 * Process turbo (context) reply...
284 dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n", ioc->name, pa));
285 type = (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT);
286 if (type == MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET) {
287 cb_idx = mpt_stm_index;
289 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
290 } else if (type == MPI_CONTEXT_REPLY_TYPE_LAN) {
291 cb_idx = mpt_lan_index;
292 /* Blind set of mf to NULL here was fatal
293 * after lan_reply says "freeme"
294 * Fix sort of combined with an optimization here;
295 * added explicit check for case where lan_reply
296 * was just returning 1 and doing nothing else.
297 * For this case skip the callback, but set up
298 * proper mf value first here:-)
300 if ((pa & 0x58000000) == 0x58000000) {
301 req_idx = pa & 0x0000FFFF;
302 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
305 * IMPORTANT! Invalidate the callback!
311 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
313 req_idx = pa & 0x0000FFFF;
314 cb_idx = (pa & 0x00FF0000) >> 16;
315 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
318 pa = 0; /* No reply flush! */
322 if (ioc->bus_type == SCSI) {
323 /* Verify mf, mr are reasonable.
325 if ((mf) && ((mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))
326 || (mf < ioc->req_frames)) ) {
327 printk(MYIOC_s_WARN_FMT
328 "mpt_interrupt: Invalid mf (%p) req_idx (%d)!\n", ioc->name, (void *)mf, req_idx);
333 if ((pa) && (mr) && ((mr >= MPT_INDEX_2_RFPTR(ioc, ioc->req_depth))
334 || (mr < ioc->reply_frames)) ) {
335 printk(MYIOC_s_WARN_FMT
336 "mpt_interrupt: Invalid rf (%p)!\n", ioc->name, (void *)mr);
341 if (cb_idx > (MPT_MAX_PROTOCOL_DRIVERS-1)) {
342 printk(MYIOC_s_WARN_FMT
343 "mpt_interrupt: Invalid cb_idx (%d)!\n", ioc->name, cb_idx);
351 /* Check for (valid) IO callback! */
353 /* Do the callback! */
354 freeme = (*(MptCallbacks[cb_idx]))(ioc, mf, mr);
358 /* Flush (non-TURBO) reply with a WRITE! */
359 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
363 /* Put Request back on FreeQ! */
364 mpt_free_msg_frame(ioc, mf);
368 } /* drain reply FIFO */
373 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
375 * mpt_base_reply - MPT base driver's callback routine; all base driver
376 * "internal" request/reply processing is routed here.
377 * Currently used for EventNotification and EventAck handling.
378 * @ioc: Pointer to MPT_ADAPTER structure
379 * @mf: Pointer to original MPT request frame
380 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
382 * Returns 1 indicating original alloc'd request frame ptr
383 * should be freed, or 0 if it shouldn't.
386 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
391 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name));
394 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
395 printk(MYIOC_s_ERR_FMT "NULL or BAD request frame ptr! (=%p)\n",
396 ioc->name, (void *)mf);
401 dprintk((MYIOC_s_ERR_FMT "Unexpected NULL Event (turbo?) reply!\n",
406 if (!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
407 dmfprintk((KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf));
408 DBG_DUMP_REQUEST_FRAME_HDR(mf)
411 func = reply->u.hdr.Function;
412 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n",
415 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
416 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
420 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
421 if (results != evHandlers) {
422 /* CHECKME! Any special handling needed here? */
423 devtprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
424 ioc->name, evHandlers, results));
428 * Hmmm... It seems that EventNotificationReply is an exception
429 * to the rule of one reply per request.
431 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
434 #ifdef CONFIG_PROC_FS
435 // LogEvent(ioc, pEvReply);
438 } else if (func == MPI_FUNCTION_EVENT_ACK) {
439 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
441 } else if (func == MPI_FUNCTION_CONFIG ||
442 func == MPI_FUNCTION_TOOLBOX) {
446 dcprintk((MYIOC_s_INFO_FMT "config_complete (mf=%p,mr=%p)\n",
447 ioc->name, mf, reply));
449 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
452 /* disable timer and remove from linked list */
453 del_timer(&pCfg->timer);
455 spin_lock_irqsave(&ioc->FreeQlock, flags);
456 list_del(&pCfg->linkage);
457 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
460 * If IOC Status is SUCCESS, save the header
461 * and set the status code to GOOD.
463 pCfg->status = MPT_CONFIG_ERROR;
465 ConfigReply_t *pReply = (ConfigReply_t *)reply;
468 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
469 dcprintk((KERN_NOTICE " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
470 status, le32_to_cpu(pReply->IOCLogInfo)));
472 pCfg->status = status;
473 if (status == MPI_IOCSTATUS_SUCCESS) {
474 pCfg->hdr->PageVersion = pReply->Header.PageVersion;
475 pCfg->hdr->PageLength = pReply->Header.PageLength;
476 pCfg->hdr->PageNumber = pReply->Header.PageNumber;
477 pCfg->hdr->PageType = pReply->Header.PageType;
482 * Wake up the original calling thread
488 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
493 * Conditionally tell caller to free the original
494 * EventNotification/EventAck/unexpected request frame!
499 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
501 * mpt_register - Register protocol-specific main callback handler.
502 * @cbfunc: callback function pointer
503 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
505 * This routine is called by a protocol-specific driver (SCSI host,
506 * LAN, SCSI target) to register it's reply callback routine. Each
507 * protocol-specific driver must do this before it will be able to
508 * use any IOC resources, such as obtaining request frames.
510 * NOTES: The SCSI protocol driver currently calls this routine thrice
511 * in order to register separate callbacks; one for "normal" SCSI IO;
512 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
514 * Returns a positive integer valued "handle" in the
515 * range (and S.O.D. order) {N,...,7,6,5,...,1} if successful.
516 * Any non-positive return value (including zero!) should be considered
517 * an error by the caller.
520 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
527 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
528 * (slot/handle 0 is reserved!)
530 for (i = MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
531 if (MptCallbacks[i] == NULL) {
532 MptCallbacks[i] = cbfunc;
533 MptDriverClass[i] = dclass;
534 MptEvHandlers[i] = NULL;
543 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
545 * mpt_deregister - Deregister a protocol drivers resources.
546 * @cb_idx: previously registered callback handle
548 * Each protocol-specific driver should call this routine when it's
549 * module is unloaded.
552 mpt_deregister(int cb_idx)
554 if ((cb_idx >= 0) && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
555 MptCallbacks[cb_idx] = NULL;
556 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
557 MptEvHandlers[cb_idx] = NULL;
563 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
565 * mpt_event_register - Register protocol-specific event callback
567 * @cb_idx: previously registered (via mpt_register) callback handle
568 * @ev_cbfunc: callback function
570 * This routine can be called by one or more protocol-specific drivers
571 * if/when they choose to be notified of MPT events.
573 * Returns 0 for success.
576 mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc)
578 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
581 MptEvHandlers[cb_idx] = ev_cbfunc;
585 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
587 * mpt_event_deregister - Deregister protocol-specific event callback
589 * @cb_idx: previously registered callback handle
591 * Each protocol-specific driver should call this routine
592 * when it does not (or can no longer) handle events,
593 * or when it's module is unloaded.
596 mpt_event_deregister(int cb_idx)
598 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
601 MptEvHandlers[cb_idx] = NULL;
604 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
606 * mpt_reset_register - Register protocol-specific IOC reset handler.
607 * @cb_idx: previously registered (via mpt_register) callback handle
608 * @reset_func: reset function
610 * This routine can be called by one or more protocol-specific drivers
611 * if/when they choose to be notified of IOC resets.
613 * Returns 0 for success.
616 mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func)
618 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
621 MptResetHandlers[cb_idx] = reset_func;
625 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
627 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
628 * @cb_idx: previously registered callback handle
630 * Each protocol-specific driver should call this routine
631 * when it does not (or can no longer) handle IOC reset handling,
632 * or when it's module is unloaded.
635 mpt_reset_deregister(int cb_idx)
637 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
640 MptResetHandlers[cb_idx] = NULL;
643 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
645 * mpt_device_driver_register - Register device driver hooks
648 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
652 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) {
656 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
658 /* call per pci device probe entry point */
659 list_for_each_entry(ioc, &ioc_list, list) {
660 if(dd_cbfunc->probe) {
661 dd_cbfunc->probe(ioc->pcidev,
662 ioc->pcidev->driver->id_table);
669 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
671 * mpt_device_driver_deregister - DeRegister device driver hooks
674 mpt_device_driver_deregister(int cb_idx)
676 struct mpt_pci_driver *dd_cbfunc;
679 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
682 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
684 list_for_each_entry(ioc, &ioc_list, list) {
685 if (dd_cbfunc->remove)
686 dd_cbfunc->remove(ioc->pcidev);
689 MptDeviceDriverHandlers[cb_idx] = NULL;
693 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
695 * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
696 * allocated per MPT adapter.
697 * @handle: Handle of registered MPT protocol driver
698 * @ioc: Pointer to MPT adapter structure
700 * Returns pointer to a MPT request frame or %NULL if none are available
701 * or IOC is not active.
704 mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc)
708 u16 req_idx; /* Request index */
710 /* validate handle and ioc identifier */
714 printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n");
717 /* If interrupts are not attached, do not return a request frame */
721 spin_lock_irqsave(&ioc->FreeQlock, flags);
722 if (!list_empty(&ioc->FreeQ)) {
725 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
726 u.frame.linkage.list);
727 list_del(&mf->u.frame.linkage.list);
728 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
729 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
731 req_idx = req_offset / ioc->req_sz;
732 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
733 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
734 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; /* Default, will be changed if necessary in SG generation */
741 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
745 printk(KERN_WARNING "IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", ioc->mfcnt, ioc->req_depth);
747 if (mfcounter == PRINT_MF_COUNT)
748 printk(KERN_INFO "MF Count 0x%x Max 0x%x \n", ioc->mfcnt, ioc->req_depth);
751 dmfprintk((KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",
752 ioc->name, handle, ioc->id, mf));
756 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
758 * mpt_put_msg_frame - Send a protocol specific MPT request frame
760 * @handle: Handle of registered MPT protocol driver
761 * @ioc: Pointer to MPT adapter structure
762 * @mf: Pointer to MPT request frame
764 * This routine posts a MPT request frame to the request post FIFO of a
765 * specific MPT adapter.
768 mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
772 u16 req_idx; /* Request index */
774 /* ensure values are reset properly! */
775 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
776 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
778 req_idx = req_offset / ioc->req_sz;
779 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
780 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
782 #ifdef MPT_DEBUG_MSG_FRAME
784 u32 *m = mf->u.frame.hwhdr.__hdr;
787 printk(KERN_INFO MYNAM ": %s: About to Put msg frame @ %p:\n" KERN_INFO " ",
789 n = ioc->req_sz/4 - 1;
792 for (ii=0; ii<=n; ii++) {
793 if (ii && ((ii%8)==0))
794 printk("\n" KERN_INFO " ");
795 printk(" %08x", le32_to_cpu(m[ii]));
801 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
802 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]));
803 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
806 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
808 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
809 * @handle: Handle of registered MPT protocol driver
810 * @ioc: Pointer to MPT adapter structure
811 * @mf: Pointer to MPT request frame
813 * This routine places a MPT request frame back on the MPT adapter's
817 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
821 /* Put Request back on FreeQ! */
822 spin_lock_irqsave(&ioc->FreeQlock, flags);
823 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
827 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
830 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
832 * mpt_add_sge - Place a simple SGE at address pAddr.
833 * @pAddr: virtual address for SGE
834 * @flagslength: SGE flags and data transfer length
835 * @dma_addr: Physical address
837 * This routine places a MPT request frame back on the MPT adapter's
841 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
843 if (sizeof(dma_addr_t) == sizeof(u64)) {
844 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
845 u32 tmp = dma_addr & 0xFFFFFFFF;
847 pSge->FlagsLength = cpu_to_le32(flagslength);
848 pSge->Address.Low = cpu_to_le32(tmp);
849 tmp = (u32) ((u64)dma_addr >> 32);
850 pSge->Address.High = cpu_to_le32(tmp);
853 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
854 pSge->FlagsLength = cpu_to_le32(flagslength);
855 pSge->Address = cpu_to_le32(dma_addr);
859 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
861 * mpt_send_handshake_request - Send MPT request via doorbell
863 * @handle: Handle of registered MPT protocol driver
864 * @ioc: Pointer to MPT adapter structure
865 * @reqBytes: Size of the request in bytes
866 * @req: Pointer to MPT request frame
867 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
869 * This routine is used exclusively to send MptScsiTaskMgmt
870 * requests since they are required to be sent via doorbell handshake.
872 * NOTE: It is the callers responsibility to byte-swap fields in the
873 * request which are greater than 1 byte in size.
875 * Returns 0 for success, non-zero for failure.
878 mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
884 /* State is known to be good upon entering
885 * this function so issue the bus reset
890 * Emulate what mpt_put_msg_frame() does /wrt to sanity
891 * setting cb_idx/req_idx. But ONLY if this request
892 * is in proper (pre-alloc'd) request buffer range...
894 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
895 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
896 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
897 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
898 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
901 /* Make sure there are no doorbells */
902 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
904 CHIPREG_WRITE32(&ioc->chip->Doorbell,
905 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
906 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
908 /* Wait for IOC doorbell int */
909 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
913 /* Read doorbell and check for active bit */
914 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
917 dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
920 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
922 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
926 /* Send request via doorbell handshake */
927 req_as_bytes = (u8 *) req;
928 for (ii = 0; ii < reqBytes/4; ii++) {
931 word = ((req_as_bytes[(ii*4) + 0] << 0) |
932 (req_as_bytes[(ii*4) + 1] << 8) |
933 (req_as_bytes[(ii*4) + 2] << 16) |
934 (req_as_bytes[(ii*4) + 3] << 24));
935 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
936 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
942 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
947 /* Make sure there are no doorbells */
948 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
953 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
955 * mpt_verify_adapter - Given a unique IOC identifier, set pointer to
956 * the associated MPT adapter structure.
957 * @iocid: IOC unique identifier (integer)
958 * @iocpp: Pointer to pointer to IOC adapter
960 * Returns iocid and sets iocpp.
963 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
967 list_for_each_entry(ioc,&ioc_list,list) {
968 if (ioc->id == iocid) {
978 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
980 * mpt_attach - Install a PCI intelligent MPT adapter.
981 * @pdev: Pointer to pci_dev structure
983 * This routine performs all the steps necessary to bring the IOC of
984 * a MPT adapter to a OPERATIONAL state. This includes registering
985 * memory regions, registering the interrupt, and allocating request
986 * and reply memory pools.
988 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
991 * Returns 0 for success, non-zero for failure.
993 * TODO: Add support for polled controllers
996 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1000 unsigned long mem_phys;
1008 static int mpt_ids = 0;
1009 #ifdef CONFIG_PROC_FS
1010 struct proc_dir_entry *dent, *ent;
1013 if (pci_enable_device(pdev))
1016 dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1018 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1019 dprintk((KERN_INFO MYNAM
1020 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1021 } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1022 printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1026 if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
1027 dprintk((KERN_INFO MYNAM
1028 ": Using 64 bit consistent mask\n"));
1030 dprintk((KERN_INFO MYNAM
1031 ": Not using 64 bit consistent mask\n"));
1033 ioc = kmalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1035 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1038 memset(ioc, 0, sizeof(MPT_ADAPTER));
1039 ioc->alloc_total = sizeof(MPT_ADAPTER);
1040 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1041 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1044 ioc->diagPending = 0;
1045 spin_lock_init(&ioc->diagLock);
1047 /* Initialize the event logging.
1049 ioc->eventTypes = 0; /* None */
1050 ioc->eventContext = 0;
1051 ioc->eventLogSize = 0;
1058 ioc->cached_fw = NULL;
1060 /* Initilize SCSI Config Data structure
1062 memset(&ioc->spi_data, 0, sizeof(ScsiCfgData));
1064 /* Initialize the running configQ head.
1066 INIT_LIST_HEAD(&ioc->configQ);
1068 /* Find lookup slot. */
1069 INIT_LIST_HEAD(&ioc->list);
1070 ioc->id = mpt_ids++;
1072 mem_phys = msize = 0;
1074 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1075 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1076 /* Get I/O space! */
1077 port = pci_resource_start(pdev, ii);
1078 psize = pci_resource_len(pdev,ii);
1081 mem_phys = pci_resource_start(pdev, ii);
1082 msize = pci_resource_len(pdev,ii);
1086 ioc->mem_size = msize;
1088 if (ii == DEVICE_COUNT_RESOURCE) {
1089 printk(KERN_ERR MYNAM ": ERROR - MPT adapter has no memory regions defined!\n");
1094 dinitprintk((KERN_INFO MYNAM ": MPT adapter @ %lx, msize=%dd bytes\n", mem_phys, msize));
1095 dinitprintk((KERN_INFO MYNAM ": (port i/o @ %lx, psize=%dd bytes)\n", port, psize));
1098 /* Get logical ptr for PciMem0 space */
1099 /*mem = ioremap(mem_phys, msize);*/
1100 mem = ioremap(mem_phys, 0x100);
1102 printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1107 dinitprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1109 dinitprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1110 &ioc->facts, &ioc->pfacts[0]));
1112 ioc->mem_phys = mem_phys;
1113 ioc->chip = (SYSIF_REGS __iomem *)mem;
1115 /* Save Port IO values in case we need to do downloadboot */
1117 u8 *pmem = (u8*)port;
1118 ioc->pio_mem_phys = port;
1119 ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1122 if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC909) {
1123 ioc->prod_name = "LSIFC909";
1126 if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
1127 ioc->prod_name = "LSIFC929";
1130 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) {
1131 ioc->prod_name = "LSIFC919";
1134 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) {
1135 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1137 if (revision < XL_929) {
1138 ioc->prod_name = "LSIFC929X";
1139 /* 929X Chip Fix. Set Split transactions level
1140 * for PCIX. Set MOST bits to zero.
1142 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1144 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1146 ioc->prod_name = "LSIFC929XL";
1147 /* 929XL Chip Fix. Set MMRBC to 0x08.
1149 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1151 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1154 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) {
1155 ioc->prod_name = "LSIFC919X";
1157 /* 919X Chip Fix. Set Split transactions level
1158 * for PCIX. Set MOST bits to zero.
1160 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1162 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1164 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
1165 ioc->prod_name = "LSI53C1030";
1166 ioc->bus_type = SCSI;
1167 /* 1030 Chip Fix. Disable Split transactions
1168 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1170 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1171 if (revision < C0_1030) {
1172 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1174 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1177 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
1178 ioc->prod_name = "LSI53C1035";
1179 ioc->bus_type = SCSI;
1182 sprintf(ioc->name, "ioc%d", ioc->id);
1184 spin_lock_init(&ioc->FreeQlock);
1187 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1189 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1191 /* Set lookup ptr. */
1192 list_add_tail(&ioc->list, &ioc_list);
1196 r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc);
1200 printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %d!\n",
1201 ioc->name, pdev->irq);
1203 printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %s!\n",
1204 ioc->name, __irq_itoa(pdev->irq));
1206 list_del(&ioc->list);
1212 ioc->pci_irq = pdev->irq;
1214 pci_set_master(pdev); /* ?? */
1215 pci_set_drvdata(pdev, ioc);
1218 dprintk((KERN_INFO MYNAM ": %s installed at interrupt %d\n", ioc->name, pdev->irq));
1220 dprintk((KERN_INFO MYNAM ": %s installed at interrupt %s\n", ioc->name, __irq_itoa(pdev->irq)));
1224 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1226 mpt_detect_bound_ports(ioc, pdev);
1228 if ((r = mpt_do_ioc_recovery(ioc,
1229 MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0) {
1230 printk(KERN_WARNING MYNAM
1231 ": WARNING - %s did not initialize properly! (%d)\n",
1234 list_del(&ioc->list);
1235 free_irq(ioc->pci_irq, ioc);
1238 pci_set_drvdata(pdev, NULL);
1242 /* call per device driver probe entry point */
1243 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1244 if(MptDeviceDriverHandlers[ii] &&
1245 MptDeviceDriverHandlers[ii]->probe) {
1246 MptDeviceDriverHandlers[ii]->probe(pdev,id);
1250 #ifdef CONFIG_PROC_FS
1252 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1254 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1256 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1258 ent->read_proc = procmpt_iocinfo_read;
1261 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1263 ent->read_proc = procmpt_summary_read;
1272 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1274 * mpt_detach - Remove a PCI intelligent MPT adapter.
1275 * @pdev: Pointer to pci_dev structure
1280 mpt_detach(struct pci_dev *pdev)
1282 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1286 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1287 remove_proc_entry(pname, NULL);
1288 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1289 remove_proc_entry(pname, NULL);
1290 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1291 remove_proc_entry(pname, NULL);
1293 /* call per device driver remove entry point */
1294 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1295 if(MptDeviceDriverHandlers[ii] &&
1296 MptDeviceDriverHandlers[ii]->remove) {
1297 MptDeviceDriverHandlers[ii]->remove(pdev);
1301 /* Disable interrupts! */
1302 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1305 synchronize_irq(pdev->irq);
1307 /* Clear any lingering interrupt */
1308 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1310 CHIPREG_READ32(&ioc->chip->IntStatus);
1312 mpt_adapter_dispose(ioc);
1314 pci_set_drvdata(pdev, NULL);
1317 /**************************************************************************
1321 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1323 * mpt_suspend - Fusion MPT base driver suspend routine.
1328 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1331 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1336 device_state=1; /* D1 */;
1340 device_state=3; /* D3 */;
1343 return -EAGAIN /*FIXME*/;
1347 printk(MYIOC_s_INFO_FMT
1348 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1349 ioc->name, pdev, pci_name(pdev), device_state);
1351 pci_save_state(pdev);
1353 /* put ioc into READY_STATE */
1354 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1355 printk(MYIOC_s_ERR_FMT
1356 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1359 /* disable interrupts */
1360 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1363 /* Clear any lingering interrupt */
1364 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1366 pci_disable_device(pdev);
1367 pci_set_power_state(pdev, device_state);
1372 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1374 * mpt_resume - Fusion MPT base driver resume routine.
1379 mpt_resume(struct pci_dev *pdev)
1381 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1382 u32 device_state = pdev->current_state;
1386 printk(MYIOC_s_INFO_FMT
1387 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1388 ioc->name, pdev, pci_name(pdev), device_state);
1390 pci_set_power_state(pdev, 0);
1391 pci_restore_state(pdev);
1392 pci_enable_device(pdev);
1394 /* enable interrupts */
1395 CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
1398 /* F/W not running */
1399 if(!CHIPREG_READ32(&ioc->chip->Doorbell)) {
1400 /* enable domain validation flags */
1401 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
1402 ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_NEED_DV;
1406 printk(MYIOC_s_INFO_FMT
1407 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1409 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1410 CHIPREG_READ32(&ioc->chip->Doorbell));
1412 /* bring ioc to operational state */
1413 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1414 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1415 printk(MYIOC_s_INFO_FMT
1416 "pci-resume: Cannot recover, error:[%x]\n",
1417 ioc->name, recovery_state);
1419 printk(MYIOC_s_INFO_FMT
1420 "pci-resume: success\n", ioc->name);
1427 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1429 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1430 * @ioc: Pointer to MPT adapter structure
1431 * @reason: Event word / reason
1432 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1434 * This routine performs all the steps necessary to bring the IOC
1435 * to a OPERATIONAL state.
1437 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1442 * -1 if failed to get board READY
1443 * -2 if READY but IOCFacts Failed
1444 * -3 if READY but PrimeIOCFifos Failed
1445 * -4 if READY but IOCInit Failed
1448 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1450 int hard_reset_done = 0;
1451 int alt_ioc_ready = 0;
1457 int reset_alt_ioc_active = 0;
1459 printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1460 ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1462 /* Disable reply interrupts (also blocks FreeQ) */
1463 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1467 if (ioc->alt_ioc->active)
1468 reset_alt_ioc_active = 1;
1470 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1471 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1472 ioc->alt_ioc->active = 0;
1476 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1479 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1480 if (hard_reset_done == -4) {
1481 printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1484 if (reset_alt_ioc_active && ioc->alt_ioc) {
1485 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1486 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1487 ioc->alt_ioc->name));
1488 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
1489 ioc->alt_ioc->active = 1;
1493 printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1499 /* hard_reset_done = 0 if a soft reset was performed
1500 * and 1 if a hard reset was performed.
1502 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1503 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1506 printk(KERN_WARNING MYNAM
1507 ": alt-%s: Not ready WARNING!\n",
1508 ioc->alt_ioc->name);
1511 for (ii=0; ii<5; ii++) {
1512 /* Get IOC facts! Allow 5 retries */
1513 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1519 dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1521 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1522 MptDisplayIocCapabilities(ioc);
1525 if (alt_ioc_ready) {
1526 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1527 dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1528 /* Retry - alt IOC was initialized once
1530 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1533 dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1535 reset_alt_ioc_active = 0;
1536 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1537 MptDisplayIocCapabilities(ioc->alt_ioc);
1541 /* Prime reply & request queues!
1542 * (mucho alloc's) Must be done prior to
1543 * init as upper addresses are needed for init.
1544 * If fails, continue with alt-ioc processing
1546 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
1549 /* May need to check/upload firmware & data here!
1550 * If fails, continue with alt-ioc processing
1552 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
1555 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
1556 printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1557 ioc->alt_ioc->name, rc);
1559 reset_alt_ioc_active = 0;
1562 if (alt_ioc_ready) {
1563 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
1565 reset_alt_ioc_active = 0;
1566 printk(KERN_WARNING MYNAM
1567 ": alt-%s: (%d) init failure WARNING!\n",
1568 ioc->alt_ioc->name, rc);
1572 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
1573 if (ioc->upload_fw) {
1574 ddlprintk((MYIOC_s_INFO_FMT
1575 "firmware upload required!\n", ioc->name));
1577 /* Controller is not operational, cannot do upload
1580 rc = mpt_do_upload(ioc, sleepFlag);
1582 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
1588 /* Enable! (reply interrupt) */
1589 CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
1593 if (reset_alt_ioc_active && ioc->alt_ioc) {
1594 /* (re)Enable alt-IOC! (reply interrupt) */
1595 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1596 ioc->alt_ioc->name));
1597 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
1598 ioc->alt_ioc->active = 1;
1601 /* Enable MPT base driver management of EventNotification
1602 * and EventAck handling.
1604 if ((ret == 0) && (!ioc->facts.EventState))
1605 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
1607 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
1608 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
1610 /* Add additional "reason" check before call to GetLanConfigPages
1611 * (combined with GetIoUnitPage2 call). This prevents a somewhat
1612 * recursive scenario; GetLanConfigPages times out, timer expired
1613 * routine calls HardResetHandler, which calls into here again,
1614 * and we try GetLanConfigPages again...
1616 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1617 if (ioc->bus_type == FC) {
1619 * Pre-fetch FC port WWN and stuff...
1620 * (FCPortPage0_t stuff)
1622 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1623 (void) GetFcPortPage0(ioc, ii);
1626 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
1627 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
1629 * Pre-fetch the ports LAN MAC address!
1630 * (LANPage1_t stuff)
1632 (void) GetLanConfigPages(ioc);
1635 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
1636 dprintk((MYIOC_s_INFO_FMT "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
1637 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0] ));
1642 /* Get NVRAM and adapter maximums from SPP 0 and 2
1644 mpt_GetScsiPortSettings(ioc, 0);
1646 /* Get version and length of SDP 1
1648 mpt_readScsiDevicePageHeaders(ioc, 0);
1652 if (ioc->facts.MsgVersion >= 0x0102)
1653 mpt_findImVolumes(ioc);
1655 /* Check, and possibly reset, the coalescing value
1657 mpt_read_ioc_pg_1(ioc);
1659 mpt_read_ioc_pg_4(ioc);
1662 GetIoUnitPage2(ioc);
1666 * Call each currently registered protocol IOC reset handler
1667 * with post-reset indication.
1668 * NOTE: If we're doing _IOC_BRINGUP, there can be no
1669 * MptResetHandlers[] registered yet.
1671 if (hard_reset_done) {
1673 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
1674 if ((ret == 0) && MptResetHandlers[ii]) {
1675 dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
1677 rc += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET);
1681 if (alt_ioc_ready && MptResetHandlers[ii]) {
1682 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
1683 ioc->name, ioc->alt_ioc->name, ii));
1684 rc += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
1688 /* FIXME? Examine results here? */
1694 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1696 * mpt_detect_bound_ports - Search for PCI bus/dev_function
1697 * which matches PCI bus/dev_function (+/-1) for newly discovered 929,
1698 * 929X, 1030 or 1035.
1699 * @ioc: Pointer to MPT adapter structure
1700 * @pdev: Pointer to (struct pci_dev) structure
1702 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
1703 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
1706 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
1708 struct pci_dev *peer=NULL;
1709 unsigned int slot = PCI_SLOT(pdev->devfn);
1710 unsigned int func = PCI_FUNC(pdev->devfn);
1711 MPT_ADAPTER *ioc_srch;
1713 dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x,"
1714 " searching for devfn match on %x or %x\n",
1715 ioc->name, pci_name(pdev), pdev->devfn,
1718 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
1720 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
1725 list_for_each_entry(ioc_srch, &ioc_list, list) {
1726 struct pci_dev *_pcidev = ioc_srch->pcidev;
1727 if (_pcidev == peer) {
1728 /* Paranoia checks */
1729 if (ioc->alt_ioc != NULL) {
1730 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1731 ioc->name, ioc->alt_ioc->name);
1733 } else if (ioc_srch->alt_ioc != NULL) {
1734 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1735 ioc_srch->name, ioc_srch->alt_ioc->name);
1738 dprintk((KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
1739 ioc->name, ioc_srch->name));
1740 ioc_srch->alt_ioc = ioc;
1741 ioc->alt_ioc = ioc_srch;
1747 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1749 * mpt_adapter_disable - Disable misbehaving MPT adapter.
1750 * @this: Pointer to MPT adapter structure
1753 mpt_adapter_disable(MPT_ADAPTER *ioc)
1758 if (ioc->cached_fw != NULL) {
1759 ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
1760 if ((ret = mpt_downloadboot(ioc, NO_SLEEP)) < 0) {
1761 printk(KERN_WARNING MYNAM
1762 ": firmware downloadboot failure (%d)!\n", ret);
1766 /* Disable adapter interrupts! */
1767 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1769 /* Clear any lingering interrupt */
1770 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1772 if (ioc->alloc != NULL) {
1774 dexitprintk((KERN_INFO MYNAM ": %s.free @ %p, sz=%d bytes\n",
1775 ioc->name, ioc->alloc, ioc->alloc_sz));
1776 pci_free_consistent(ioc->pcidev, sz,
1777 ioc->alloc, ioc->alloc_dma);
1778 ioc->reply_frames = NULL;
1779 ioc->req_frames = NULL;
1781 ioc->alloc_total -= sz;
1784 if (ioc->sense_buf_pool != NULL) {
1785 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
1786 pci_free_consistent(ioc->pcidev, sz,
1787 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
1788 ioc->sense_buf_pool = NULL;
1789 ioc->alloc_total -= sz;
1792 if (ioc->events != NULL){
1793 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
1796 ioc->alloc_total -= sz;
1799 if (ioc->cached_fw != NULL) {
1800 sz = ioc->facts.FWImageSize;
1801 pci_free_consistent(ioc->pcidev, sz,
1802 ioc->cached_fw, ioc->cached_fw_dma);
1803 ioc->cached_fw = NULL;
1804 ioc->alloc_total -= sz;
1807 if (ioc->spi_data.nvram != NULL) {
1808 kfree(ioc->spi_data.nvram);
1809 ioc->spi_data.nvram = NULL;
1812 if (ioc->spi_data.pIocPg3 != NULL) {
1813 kfree(ioc->spi_data.pIocPg3);
1814 ioc->spi_data.pIocPg3 = NULL;
1817 if (ioc->spi_data.pIocPg4 != NULL) {
1818 sz = ioc->spi_data.IocPg4Sz;
1819 pci_free_consistent(ioc->pcidev, sz,
1820 ioc->spi_data.pIocPg4,
1821 ioc->spi_data.IocPg4_dma);
1822 ioc->spi_data.pIocPg4 = NULL;
1823 ioc->alloc_total -= sz;
1826 if (ioc->ReqToChain != NULL) {
1827 kfree(ioc->ReqToChain);
1828 kfree(ioc->RequestNB);
1829 ioc->ReqToChain = NULL;
1832 if (ioc->ChainToChain != NULL) {
1833 kfree(ioc->ChainToChain);
1834 ioc->ChainToChain = NULL;
1838 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1840 * mpt_adapter_dispose - Free all resources associated with a MPT
1842 * @ioc: Pointer to MPT adapter structure
1844 * This routine unregisters h/w resources and frees all alloc'd memory
1845 * associated with a MPT adapter structure.
1848 mpt_adapter_dispose(MPT_ADAPTER *ioc)
1851 int sz_first, sz_last;
1853 sz_first = ioc->alloc_total;
1855 mpt_adapter_disable(ioc);
1857 if (ioc->pci_irq != -1) {
1858 free_irq(ioc->pci_irq, ioc);
1862 if (ioc->memmap != NULL)
1863 iounmap(ioc->memmap);
1865 #if defined(CONFIG_MTRR) && 0
1866 if (ioc->mtrr_reg > 0) {
1867 mtrr_del(ioc->mtrr_reg, 0, 0);
1868 dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
1872 /* Zap the adapter lookup ptr! */
1873 list_del(&ioc->list);
1875 sz_last = ioc->alloc_total;
1876 dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
1877 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
1882 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1884 * MptDisplayIocCapabilities - Disply IOC's capacilities.
1885 * @ioc: Pointer to MPT adapter structure
1888 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
1892 printk(KERN_INFO "%s: ", ioc->name);
1893 if (ioc->prod_name && strlen(ioc->prod_name) > 3)
1894 printk("%s: ", ioc->prod_name+3);
1895 printk("Capabilities={");
1897 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
1898 printk("Initiator");
1902 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
1903 printk("%sTarget", i ? "," : "");
1907 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
1908 printk("%sLAN", i ? "," : "");
1914 * This would probably evoke more questions than it's worth
1916 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
1917 printk("%sLogBusAddr", i ? "," : "");
1925 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1927 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
1928 * @ioc: Pointer to MPT_ADAPTER structure
1929 * @force: Force hard KickStart of IOC
1930 * @sleepFlag: Specifies whether the process can sleep
1933 * 1 - DIAG reset and READY
1934 * 0 - READY initially OR soft reset and READY
1935 * -1 - Any failure on KickStart
1936 * -2 - Msg Unit Reset Failed
1937 * -3 - IO Unit Reset Failed
1938 * -4 - IOC owned by a PEER
1941 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
1946 int hard_reset_done = 0;
1951 /* Get current [raw] IOC state */
1952 ioc_state = mpt_GetIocState(ioc, 0);
1953 dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
1956 * Check to see if IOC got left/stuck in doorbell handshake
1957 * grip of death. If so, hard reset the IOC.
1959 if (ioc_state & MPI_DOORBELL_ACTIVE) {
1961 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
1965 /* Is it already READY? */
1966 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
1970 * Check to see if IOC is in FAULT state.
1972 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
1974 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
1976 printk(KERN_WARNING " FAULT code = %04xh\n",
1977 ioc_state & MPI_DOORBELL_DATA_MASK);
1981 * Hmmm... Did it get left operational?
1983 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
1984 dinitprintk((MYIOC_s_WARN_FMT "IOC operational unexpected\n",
1988 * If PCI Peer, exit.
1989 * Else, if no fault conditions are present, issue a MessageUnitReset
1990 * Else, fall through to KickStart case
1992 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
1993 dprintk((KERN_WARNING MYNAM
1994 ": whoinit 0x%x\n statefault %d force %d\n",
1995 whoinit, statefault, force));
1996 if (whoinit == MPI_WHOINIT_PCI_PEER)
1999 if ((statefault == 0 ) && (force == 0)) {
2000 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2007 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2008 if (hard_reset_done < 0)
2012 * Loop here waiting for IOC to come READY.
2015 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
2017 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2018 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2020 * BIOS or previous driver load left IOC in OP state.
2021 * Reset messaging FIFOs.
2023 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2024 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2027 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2029 * Something is wrong. Try to get IOC back
2032 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2033 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2040 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2041 ioc->name, (int)((ii+5)/HZ));
2045 if (sleepFlag == CAN_SLEEP) {
2046 msleep_interruptible(1);
2048 mdelay (1); /* 1 msec delay */
2053 if (statefault < 3) {
2054 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2056 statefault==1 ? "stuck handshake" : "IOC FAULT");
2059 return hard_reset_done;
2062 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2064 * mpt_GetIocState - Get the current state of a MPT adapter.
2065 * @ioc: Pointer to MPT_ADAPTER structure
2066 * @cooked: Request raw or cooked IOC state
2068 * Returns all IOC Doorbell register bits if cooked==0, else just the
2069 * Doorbell bits in MPI_IOC_STATE_MASK.
2072 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2077 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2078 // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2079 sc = s & MPI_IOC_STATE_MASK;
2082 ioc->last_state = sc;
2084 return cooked ? sc : s;
2087 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2089 * GetIocFacts - Send IOCFacts request to MPT adapter.
2090 * @ioc: Pointer to MPT_ADAPTER structure
2091 * @sleepFlag: Specifies whether the process can sleep
2092 * @reason: If recovery, only update facts.
2094 * Returns 0 for success, non-zero for failure.
2097 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2099 IOCFacts_t get_facts;
2100 IOCFactsReply_t *facts;
2108 /* IOC *must* NOT be in RESET state! */
2109 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2110 printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2116 facts = &ioc->facts;
2118 /* Destination (reply area)... */
2119 reply_sz = sizeof(*facts);
2120 memset(facts, 0, reply_sz);
2122 /* Request area (get_facts on the stack right now!) */
2123 req_sz = sizeof(get_facts);
2124 memset(&get_facts, 0, req_sz);
2126 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2127 /* Assert: All other get_facts fields are zero! */
2129 dinitprintk((MYIOC_s_INFO_FMT
2130 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2131 ioc->name, req_sz, reply_sz));
2133 /* No non-zero fields in the get_facts request are greater than
2134 * 1 byte in size, so we can just fire it off as is.
2136 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2137 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2142 * Now byte swap (GRRR) the necessary fields before any further
2143 * inspection of reply contents.
2145 * But need to do some sanity checks on MsgLength (byte) field
2146 * to make sure we don't zero IOC's req_sz!
2148 /* Did we get a valid reply? */
2149 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2150 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2152 * If not been here, done that, save off first WhoInit value
2154 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2155 ioc->FirstWhoInit = facts->WhoInit;
2158 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2159 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2160 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2161 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2162 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2163 status = facts->IOCStatus & MPI_IOCSTATUS_MASK;
2164 /* CHECKME! IOCStatus, IOCLogInfo */
2166 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2167 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2170 * FC f/w version changed between 1.1 and 1.2
2171 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2172 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2174 if (facts->MsgVersion < 0x0102) {
2176 * Handle old FC f/w style, convert to new...
2178 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2179 facts->FWVersion.Word =
2180 ((oldv<<12) & 0xFF000000) |
2181 ((oldv<<8) & 0x000FFF00);
2183 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2185 facts->ProductID = le16_to_cpu(facts->ProductID);
2186 facts->CurrentHostMfaHighAddr =
2187 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2188 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2189 facts->CurrentSenseBufferHighAddr =
2190 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2191 facts->CurReplyFrameSize =
2192 le16_to_cpu(facts->CurReplyFrameSize);
2195 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2196 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2197 * to 14 in MPI-1.01.0x.
2199 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2200 facts->MsgVersion > 0x0100) {
2201 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2204 sz = facts->FWImageSize;
2209 facts->FWImageSize = sz;
2211 if (!facts->RequestFrameSize) {
2212 /* Something is wrong! */
2213 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2218 r = sz = facts->BlockSize;
2219 vv = ((63 / (sz * 4)) + 1) & 0x03;
2220 ioc->NB_for_64_byte_frame = vv;
2226 ioc->NBShiftFactor = shiftFactor;
2227 dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2228 ioc->name, vv, shiftFactor, r));
2230 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2232 * Set values for this IOC's request & reply frame sizes,
2233 * and request & reply queue depths...
2235 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2236 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2237 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2238 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2240 dinitprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
2241 ioc->name, ioc->reply_sz, ioc->reply_depth));
2242 dinitprintk((MYIOC_s_INFO_FMT "req_sz =%3d, req_depth =%4d\n",
2243 ioc->name, ioc->req_sz, ioc->req_depth));
2245 /* Get port facts! */
2246 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2250 printk(MYIOC_s_ERR_FMT
2251 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2252 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2253 RequestFrameSize)/sizeof(u32)));
2260 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2262 * GetPortFacts - Send PortFacts request to MPT adapter.
2263 * @ioc: Pointer to MPT_ADAPTER structure
2264 * @portnum: Port number
2265 * @sleepFlag: Specifies whether the process can sleep
2267 * Returns 0 for success, non-zero for failure.
2270 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2272 PortFacts_t get_pfacts;
2273 PortFactsReply_t *pfacts;
2278 /* IOC *must* NOT be in RESET state! */
2279 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2280 printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2286 pfacts = &ioc->pfacts[portnum];
2288 /* Destination (reply area)... */
2289 reply_sz = sizeof(*pfacts);
2290 memset(pfacts, 0, reply_sz);
2292 /* Request area (get_pfacts on the stack right now!) */
2293 req_sz = sizeof(get_pfacts);
2294 memset(&get_pfacts, 0, req_sz);
2296 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2297 get_pfacts.PortNumber = portnum;
2298 /* Assert: All other get_pfacts fields are zero! */
2300 dinitprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
2301 ioc->name, portnum));
2303 /* No non-zero fields in the get_pfacts request are greater than
2304 * 1 byte in size, so we can just fire it off as is.
2306 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2307 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2311 /* Did we get a valid reply? */
2313 /* Now byte swap the necessary fields in the response. */
2314 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2315 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2316 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2317 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2318 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2319 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2320 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2321 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2322 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2327 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2329 * SendIocInit - Send IOCInit request to MPT adapter.
2330 * @ioc: Pointer to MPT_ADAPTER structure
2331 * @sleepFlag: Specifies whether the process can sleep
2333 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2335 * Returns 0 for success, non-zero for failure.
2338 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2341 MPIDefaultReply_t init_reply;
2347 memset(&ioc_init, 0, sizeof(ioc_init));
2348 memset(&init_reply, 0, sizeof(init_reply));
2350 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2351 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2353 /* If we are in a recovery mode and we uploaded the FW image,
2354 * then this pointer is not NULL. Skip the upload a second time.
2355 * Set this flag if cached_fw set for either IOC.
2357 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2361 ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
2362 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2364 if (ioc->bus_type == FC)
2365 ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
2367 ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
2369 ioc_init.MaxBuses = MPT_MAX_BUS;
2371 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2373 if (sizeof(dma_addr_t) == sizeof(u64)) {
2374 /* Save the upper 32-bits of the request
2375 * (reply) and sense buffers.
2377 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2378 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2380 /* Force 32-bit addressing */
2381 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2382 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2385 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2386 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2388 dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
2389 ioc->name, &ioc_init));
2391 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2392 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2396 /* No need to byte swap the multibyte fields in the reply
2397 * since we don't even look at it's contents.
2400 dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
2401 ioc->name, &ioc_init));
2403 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0)
2406 /* YIKES! SUPER IMPORTANT!!!
2407 * Poll IocState until _OPERATIONAL while IOC is doing
2408 * LoopInit and TargetDiscovery!
2411 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2412 state = mpt_GetIocState(ioc, 1);
2413 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2414 if (sleepFlag == CAN_SLEEP) {
2415 msleep_interruptible(1);
2421 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2422 ioc->name, (int)((count+5)/HZ));
2426 state = mpt_GetIocState(ioc, 1);
2429 dhsprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2435 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2437 * SendPortEnable - Send PortEnable request to MPT adapter port.
2438 * @ioc: Pointer to MPT_ADAPTER structure
2439 * @portnum: Port number to enable
2440 * @sleepFlag: Specifies whether the process can sleep
2442 * Send PortEnable to bring IOC to OPERATIONAL state.
2444 * Returns 0 for success, non-zero for failure.
2447 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2449 PortEnable_t port_enable;
2450 MPIDefaultReply_t reply_buf;
2455 /* Destination... */
2456 reply_sz = sizeof(MPIDefaultReply_t);
2457 memset(&reply_buf, 0, reply_sz);
2459 req_sz = sizeof(PortEnable_t);
2460 memset(&port_enable, 0, req_sz);
2462 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2463 port_enable.PortNumber = portnum;
2464 /* port_enable.ChainOffset = 0; */
2465 /* port_enable.MsgFlags = 0; */
2466 /* port_enable.MsgContext = 0; */
2468 dinitprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
2469 ioc->name, portnum, &port_enable));
2471 /* RAID FW may take a long time to enable
2473 if (ioc->bus_type == FC) {
2474 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2475 reply_sz, (u16*)&reply_buf, 65 /*seconds*/, sleepFlag);
2477 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2478 reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag);
2484 /* We do not even look at the reply, so we need not
2485 * swap the multi-byte fields.
2492 * ioc: Pointer to MPT_ADAPTER structure
2493 * size - total FW bytes
2496 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
2499 return; /* use already allocated memory */
2500 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2501 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
2502 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
2504 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
2505 ioc->alloc_total += size;
2509 * If alt_img is NULL, delete from ioc structure.
2510 * Else, delete a secondary image in same format.
2513 mpt_free_fw_memory(MPT_ADAPTER *ioc)
2517 sz = ioc->facts.FWImageSize;
2518 dinitprintk((KERN_WARNING MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
2519 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2520 pci_free_consistent(ioc->pcidev, sz,
2521 ioc->cached_fw, ioc->cached_fw_dma);
2522 ioc->cached_fw = NULL;
2528 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2530 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
2531 * @ioc: Pointer to MPT_ADAPTER structure
2532 * @sleepFlag: Specifies whether the process can sleep
2534 * Returns 0 for success, >0 for handshake failure
2535 * <0 for fw upload failure.
2537 * Remark: If bound IOC and a successful FWUpload was performed
2538 * on the bound IOC, the second image is discarded
2539 * and memory is free'd. Both channels must upload to prevent
2540 * IOC from running in degraded mode.
2543 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2545 u8 request[ioc->req_sz];
2546 u8 reply[sizeof(FWUploadReply_t)];
2547 FWUpload_t *prequest;
2548 FWUploadReply_t *preply;
2549 FWUploadTCSGE_t *ptcsge;
2552 int ii, sz, reply_sz;
2555 /* If the image size is 0, we are done.
2557 if ((sz = ioc->facts.FWImageSize) == 0)
2560 mpt_alloc_fw_memory(ioc, sz);
2562 dinitprintk((KERN_WARNING MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
2563 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2565 if (ioc->cached_fw == NULL) {
2571 prequest = (FWUpload_t *)&request;
2572 preply = (FWUploadReply_t *)&reply;
2574 /* Destination... */
2575 memset(prequest, 0, ioc->req_sz);
2577 reply_sz = sizeof(reply);
2578 memset(preply, 0, reply_sz);
2580 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
2581 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
2583 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
2584 ptcsge->DetailsLength = 12;
2585 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
2586 ptcsge->ImageSize = cpu_to_le32(sz);
2588 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
2590 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
2591 mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
2593 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
2594 dinitprintk((KERN_WARNING MYNAM "Sending FW Upload (req @ %p) sgeoffset=%d \n",
2595 prequest, sgeoffset));
2596 DBG_DUMP_FW_REQUEST_FRAME(prequest)
2598 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
2599 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
2601 dinitprintk((KERN_WARNING MYNAM "FW Upload completed rc=%x \n", ii));
2603 cmdStatus = -EFAULT;
2605 /* Handshake transfer was complete and successful.
2606 * Check the Reply Frame.
2608 int status, transfer_sz;
2609 status = le16_to_cpu(preply->IOCStatus);
2610 if (status == MPI_IOCSTATUS_SUCCESS) {
2611 transfer_sz = le32_to_cpu(preply->ActualImageSize);
2612 if (transfer_sz == sz)
2616 dinitprintk((MYIOC_s_INFO_FMT ": do_upload status %d \n",
2617 ioc->name, cmdStatus));
2622 ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
2624 mpt_free_fw_memory(ioc);
2630 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2632 * mpt_downloadboot - DownloadBoot code
2633 * @ioc: Pointer to MPT_ADAPTER structure
2634 * @flag: Specify which part of IOC memory is to be uploaded.
2635 * @sleepFlag: Specifies whether the process can sleep
2637 * FwDownloadBoot requires Programmed IO access.
2639 * Returns 0 for success
2640 * -1 FW Image size is 0
2641 * -2 No valid cached_fw Pointer
2642 * <0 for fw upload failure.
2645 mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
2647 MpiFwHeader_t *pFwHeader;
2648 MpiExtImageHeader_t *pExtImage;
2658 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x, ioc FW Ptr %p\n",
2659 ioc->name, ioc->facts.FWImageSize, ioc->cached_fw));
2661 if ( ioc->facts.FWImageSize == 0 )
2664 if (ioc->cached_fw == NULL)
2667 /* prevent a second downloadboot and memory free with alt_ioc */
2668 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
2669 ioc->alt_ioc->cached_fw = NULL;
2671 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2672 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2673 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2674 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2675 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2676 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2678 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
2681 if (sleepFlag == CAN_SLEEP) {
2682 msleep_interruptible(1);
2687 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2688 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2690 for (count = 0; count < 30; count ++) {
2691 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2692 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
2693 ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
2698 if (sleepFlag == CAN_SLEEP) {
2699 msleep_interruptible (1000);
2705 if ( count == 30 ) {
2706 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! Unable to RESET_ADAPTER diag0val=%x\n",
2707 ioc->name, diag0val));
2711 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2712 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2713 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2714 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2715 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2716 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2718 /* Set the DiagRwEn and Disable ARM bits */
2719 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
2721 pFwHeader = (MpiFwHeader_t *) ioc->cached_fw;
2722 fwSize = (pFwHeader->ImageSize + 3)/4;
2723 ptrFw = (u32 *) pFwHeader;
2725 /* Write the LoadStartAddress to the DiagRw Address Register
2726 * using Programmed IO
2728 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
2729 ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
2730 ioc->name, pFwHeader->LoadStartAddress));
2732 ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n",
2733 ioc->name, fwSize*4, ptrFw));
2735 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2738 nextImage = pFwHeader->NextImageHeaderOffset;
2740 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
2742 load_addr = pExtImage->LoadStartAddress;
2744 fwSize = (pExtImage->ImageSize + 3) >> 2;
2745 ptrFw = (u32 *)pExtImage;
2747 ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x bytes @ %p load_addr=%x\n",
2748 ioc->name, fwSize*4, ptrFw, load_addr));
2749 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
2752 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2754 nextImage = pExtImage->NextImageHeaderOffset;
2757 /* Write the IopResetVectorRegAddr */
2758 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
2759 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
2761 /* Write the IopResetVectorValue */
2762 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
2763 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
2765 /* Clear the internal flash bad bit - autoincrementing register,
2766 * so must do two writes.
2768 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
2769 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
2770 diagRwData |= 0x4000000;
2771 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
2772 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
2774 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2775 ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, turning off PREVENT_IOC_BOOT, DISABLE_ARM\n",
2776 ioc->name, diag0val));
2777 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM);
2778 ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
2779 ioc->name, diag0val));
2780 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
2782 /* Write 0xFF to reset the sequencer */
2783 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2785 for (count=0; count<HZ*20; count++) {
2786 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
2787 ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
2788 ioc->name, count, ioc_state));
2789 if ((SendIocInit(ioc, sleepFlag)) != 0) {
2790 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
2794 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit successful\n",
2798 if (sleepFlag == CAN_SLEEP) {
2799 msleep_interruptible (10);
2804 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! IocState=%x\n",
2805 ioc->name, ioc_state));
2809 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2811 * KickStart - Perform hard reset of MPT adapter.
2812 * @ioc: Pointer to MPT_ADAPTER structure
2813 * @force: Force hard reset
2814 * @sleepFlag: Specifies whether the process can sleep
2816 * This routine places MPT adapter in diagnostic mode via the
2817 * WriteSequence register, and then performs a hard reset of adapter
2818 * via the Diagnostic register.
2820 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
2821 * or NO_SLEEP (interrupt thread, use mdelay)
2822 * force - 1 if doorbell active, board fault state
2823 * board operational, IOC_RECOVERY or
2824 * IOC_BRINGUP and there is an alt_ioc.
2828 * 1 - hard reset, READY
2829 * 0 - no reset due to History bit, READY
2830 * -1 - no reset due to History bit but not READY
2831 * OR reset but failed to come READY
2832 * -2 - no reset, could not enter DIAG mode
2833 * -3 - reset but bad FW bit
2836 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
2838 int hard_reset_done = 0;
2842 dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
2843 if (ioc->bus_type == SCSI) {
2844 /* Always issue a Msg Unit Reset first. This will clear some
2845 * SCSI bus hang conditions.
2847 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
2849 if (sleepFlag == CAN_SLEEP) {
2850 msleep_interruptible (1000);
2856 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
2857 if (hard_reset_done < 0)
2858 return hard_reset_done;
2860 dinitprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
2863 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
2864 for (cnt=0; cnt<cntdn; cnt++) {
2865 ioc_state = mpt_GetIocState(ioc, 1);
2866 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
2867 dinitprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
2869 return hard_reset_done;
2871 if (sleepFlag == CAN_SLEEP) {
2872 msleep_interruptible (10);
2878 printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
2879 ioc->name, ioc_state);
2883 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2885 * mpt_diag_reset - Perform hard reset of the adapter.
2886 * @ioc: Pointer to MPT_ADAPTER structure
2887 * @ignore: Set if to honor and clear to ignore
2888 * the reset history bit
2889 * @sleepflag: CAN_SLEEP if called in a non-interrupt thread,
2890 * else set to NO_SLEEP (use mdelay instead)
2892 * This routine places the adapter in diagnostic mode via the
2893 * WriteSequence register and then performs a hard reset of adapter
2894 * via the Diagnostic register. Adapter should be in ready state
2895 * upon successful completion.
2897 * Returns: 1 hard reset successful
2898 * 0 no reset performed because reset history bit set
2899 * -2 enabling diagnostic mode failed
2900 * -3 diagnostic reset failed
2903 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
2907 int hard_reset_done = 0;
2913 /* Clear any existing interrupts */
2914 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2916 /* Use "Diagnostic reset" method! (only thing available!) */
2917 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2921 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
2922 dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
2923 ioc->name, diag0val, diag1val));
2926 /* Do the reset if we are told to ignore the reset history
2927 * or if the reset history is 0
2929 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
2930 while ((diag0val & MPI_DIAG_DRWE) == 0) {
2931 /* Write magic sequence to WriteSequence register
2932 * Loop until in diagnostic mode
2934 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2935 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2936 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2937 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2938 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2939 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2942 if (sleepFlag == CAN_SLEEP) {
2943 msleep_interruptible (100);
2950 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
2951 ioc->name, diag0val);
2956 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2958 dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
2959 ioc->name, diag0val));
2964 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
2965 dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
2966 ioc->name, diag0val, diag1val));
2969 * Disable the ARM (Bug fix)
2972 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
2976 * Now hit the reset bit in the Diagnostic register
2977 * (THE BIG HAMMER!) (Clears DRWE bit).
2979 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2980 hard_reset_done = 1;
2981 dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
2985 * Call each currently registered protocol IOC reset handler
2986 * with pre-reset indication.
2987 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2988 * MptResetHandlers[] registered yet.
2994 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
2995 if (MptResetHandlers[ii]) {
2996 dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
2998 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_PRE_RESET);
3000 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3001 ioc->name, ioc->alt_ioc->name, ii));
3002 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_PRE_RESET);
3006 /* FIXME? Examine results here? */
3009 if (ioc->cached_fw) {
3010 /* If the DownloadBoot operation fails, the
3011 * IOC will be left unusable. This is a fatal error
3012 * case. _diag_reset will return < 0
3014 for (count = 0; count < 30; count ++) {
3015 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3016 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3021 if (sleepFlag == CAN_SLEEP) {
3027 if ((count = mpt_downloadboot(ioc, sleepFlag)) < 0) {
3028 printk(KERN_WARNING MYNAM
3029 ": firmware downloadboot failure (%d)!\n", count);
3033 /* Wait for FW to reload and for board
3034 * to go to the READY state.
3035 * Maximum wait is 60 seconds.
3036 * If fail, no error will check again
3037 * with calling program.
3039 for (count = 0; count < 60; count ++) {
3040 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3041 doorbell &= MPI_IOC_STATE_MASK;
3043 if (doorbell == MPI_IOC_STATE_READY) {
3048 if (sleepFlag == CAN_SLEEP) {
3049 msleep_interruptible (1000);
3057 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3060 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3061 dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3062 ioc->name, diag0val, diag1val));
3065 /* Clear RESET_HISTORY bit! Place board in the
3066 * diagnostic mode to update the diag register.
3068 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3070 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3071 /* Write magic sequence to WriteSequence register
3072 * Loop until in diagnostic mode
3074 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3075 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3076 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3077 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3078 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3079 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3082 if (sleepFlag == CAN_SLEEP) {
3083 msleep_interruptible (100);
3090 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3091 ioc->name, diag0val);
3094 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3096 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3097 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3098 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3099 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3100 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3104 /* Disable Diagnostic Mode
3106 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3108 /* Check FW reload status flags.
3110 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3111 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3112 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3113 ioc->name, diag0val);
3119 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3120 dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3121 ioc->name, diag0val, diag1val));
3125 * Reset flag that says we've enabled event notification
3127 ioc->facts.EventState = 0;
3130 ioc->alt_ioc->facts.EventState = 0;
3132 return hard_reset_done;
3135 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3137 * SendIocReset - Send IOCReset request to MPT adapter.
3138 * @ioc: Pointer to MPT_ADAPTER structure
3139 * @reset_type: reset type, expected values are
3140 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3142 * Send IOCReset request to the MPT adapter.
3144 * Returns 0 for success, non-zero for failure.
3147 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3153 drsprintk((KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
3154 ioc->name, reset_type));
3155 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3156 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3159 /* FW ACK'd request, wait for READY state
3162 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3164 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3168 if (sleepFlag != CAN_SLEEP)
3171 printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3172 ioc->name, (int)((count+5)/HZ));
3176 if (sleepFlag == CAN_SLEEP) {
3177 msleep_interruptible(1);
3179 mdelay (1); /* 1 msec delay */
3184 * Cleanup all event stuff for this IOC; re-issue EventNotification
3185 * request if needed.
3187 if (ioc->facts.Function)
3188 ioc->facts.EventState = 0;
3193 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3195 * initChainBuffers - Allocate memory for and initialize
3196 * chain buffers, chain buffer control arrays and spinlock.
3197 * @hd: Pointer to MPT_SCSI_HOST structure
3198 * @init: If set, initialize the spin lock.
3201 initChainBuffers(MPT_ADAPTER *ioc)
3204 int sz, ii, num_chain;
3205 int scale, num_sge, numSGE;
3207 /* ReqToChain size must equal the req_depth
3210 if (ioc->ReqToChain == NULL) {
3211 sz = ioc->req_depth * sizeof(int);
3212 mem = kmalloc(sz, GFP_ATOMIC);
3216 ioc->ReqToChain = (int *) mem;
3217 dinitprintk((KERN_INFO MYNAM ": %s ReqToChain alloc @ %p, sz=%d bytes\n",
3218 ioc->name, mem, sz));
3219 mem = kmalloc(sz, GFP_ATOMIC);
3223 ioc->RequestNB = (int *) mem;
3224 dinitprintk((KERN_INFO MYNAM ": %s RequestNB alloc @ %p, sz=%d bytes\n",
3225 ioc->name, mem, sz));
3227 for (ii = 0; ii < ioc->req_depth; ii++) {
3228 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3231 /* ChainToChain size must equal the total number
3232 * of chain buffers to be allocated.
3235 * Calculate the number of chain buffers needed(plus 1) per I/O
3236 * then multiply the the maximum number of simultaneous cmds
3238 * num_sge = num sge in request frame + last chain buffer
3239 * scale = num sge per chain buffer if no chain element
3241 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3242 if (sizeof(dma_addr_t) == sizeof(u64))
3243 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3245 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3247 if (sizeof(dma_addr_t) == sizeof(u64)) {
3248 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3249 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3251 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3252 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3254 dinitprintk((KERN_INFO MYNAM ": %s num_sge=%d numSGE=%d\n",
3255 ioc->name, num_sge, numSGE));
3257 if ( numSGE > MPT_SCSI_SG_DEPTH )
3258 numSGE = MPT_SCSI_SG_DEPTH;
3261 while (numSGE - num_sge > 0) {
3263 num_sge += (scale - 1);
3267 dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
3268 ioc->name, numSGE, num_sge, num_chain));
3270 if (ioc->bus_type == SCSI)
3271 num_chain *= MPT_SCSI_CAN_QUEUE;
3273 num_chain *= MPT_FC_CAN_QUEUE;
3275 ioc->num_chain = num_chain;
3277 sz = num_chain * sizeof(int);
3278 if (ioc->ChainToChain == NULL) {
3279 mem = kmalloc(sz, GFP_ATOMIC);
3283 ioc->ChainToChain = (int *) mem;
3284 dinitprintk((KERN_INFO MYNAM ": %s ChainToChain alloc @ %p, sz=%d bytes\n",
3285 ioc->name, mem, sz));
3287 mem = (u8 *) ioc->ChainToChain;
3289 memset(mem, 0xFF, sz);
3293 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3295 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3296 * @ioc: Pointer to MPT_ADAPTER structure
3298 * This routine allocates memory for the MPT reply and request frame
3299 * pools (if necessary), and primes the IOC reply FIFO with
3302 * Returns 0 for success, non-zero for failure.
3305 PrimeIocFifos(MPT_ADAPTER *ioc)
3308 unsigned long flags;
3309 dma_addr_t alloc_dma;
3311 int i, reply_sz, sz, total_size, num_chain;
3313 /* Prime reply FIFO... */
3315 if (ioc->reply_frames == NULL) {
3316 if ( (num_chain = initChainBuffers(ioc)) < 0)
3319 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3320 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3321 ioc->name, ioc->reply_sz, ioc->reply_depth));
3322 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d[%x] bytes\n",
3323 ioc->name, reply_sz, reply_sz));
3325 sz = (ioc->req_sz * ioc->req_depth);
3326 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3327 ioc->name, ioc->req_sz, ioc->req_depth));
3328 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d[%x] bytes\n",
3329 ioc->name, sz, sz));
3332 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3333 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3334 ioc->name, ioc->req_sz, num_chain));
3335 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3336 ioc->name, sz, sz, num_chain));
3339 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3341 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3346 dinitprintk((KERN_INFO MYNAM ": %s.Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3347 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3349 memset(mem, 0, total_size);
3350 ioc->alloc_total += total_size;
3352 ioc->alloc_dma = alloc_dma;
3353 ioc->alloc_sz = total_size;
3354 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3355 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3357 alloc_dma += reply_sz;
3360 /* Request FIFO - WE manage this! */
3362 ioc->req_frames = (MPT_FRAME_HDR *) mem;
3363 ioc->req_frames_dma = alloc_dma;
3365 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffers @ %p[%p]\n",
3366 ioc->name, mem, (void *)(ulong)alloc_dma));
3368 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3370 #if defined(CONFIG_MTRR) && 0
3372 * Enable Write Combining MTRR for IOC's memory region.
3373 * (at least as much as we can; "size and base must be
3374 * multiples of 4 kiB"
3376 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
3378 MTRR_TYPE_WRCOMB, 1);
3379 dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
3380 ioc->name, ioc->req_frames_dma, sz));
3383 for (i = 0; i < ioc->req_depth; i++) {
3384 alloc_dma += ioc->req_sz;
3388 ioc->ChainBuffer = mem;
3389 ioc->ChainBufferDMA = alloc_dma;
3391 dinitprintk((KERN_INFO MYNAM " :%s.ChainBuffers @ %p(%p)\n",
3392 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
3394 /* Initialize the free chain Q.
3397 INIT_LIST_HEAD(&ioc->FreeChainQ);
3399 /* Post the chain buffers to the FreeChainQ.
3401 mem = (u8 *)ioc->ChainBuffer;
3402 for (i=0; i < num_chain; i++) {
3403 mf = (MPT_FRAME_HDR *) mem;
3404 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
3408 /* Initialize Request frames linked list
3410 alloc_dma = ioc->req_frames_dma;
3411 mem = (u8 *) ioc->req_frames;
3413 spin_lock_irqsave(&ioc->FreeQlock, flags);
3414 INIT_LIST_HEAD(&ioc->FreeQ);
3415 for (i = 0; i < ioc->req_depth; i++) {
3416 mf = (MPT_FRAME_HDR *) mem;
3418 /* Queue REQUESTs *internally*! */
3419 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
3423 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3425 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3426 ioc->sense_buf_pool =
3427 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3428 if (ioc->sense_buf_pool == NULL) {
3429 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
3434 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
3435 ioc->alloc_total += sz;
3436 dinitprintk((KERN_INFO MYNAM ": %s.SenseBuffers @ %p[%p]\n",
3437 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
3441 /* Post Reply frames to FIFO
3443 alloc_dma = ioc->alloc_dma;
3444 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffers @ %p[%p]\n",
3445 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3447 for (i = 0; i < ioc->reply_depth; i++) {
3448 /* Write each address to the IOC! */
3449 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
3450 alloc_dma += ioc->reply_sz;
3456 if (ioc->alloc != NULL) {
3458 pci_free_consistent(ioc->pcidev,
3460 ioc->alloc, ioc->alloc_dma);
3461 ioc->reply_frames = NULL;
3462 ioc->req_frames = NULL;
3463 ioc->alloc_total -= sz;
3465 if (ioc->sense_buf_pool != NULL) {
3466 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3467 pci_free_consistent(ioc->pcidev,
3469 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
3470 ioc->sense_buf_pool = NULL;
3475 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3477 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3478 * from IOC via doorbell handshake method.
3479 * @ioc: Pointer to MPT_ADAPTER structure
3480 * @reqBytes: Size of the request in bytes
3481 * @req: Pointer to MPT request frame
3482 * @replyBytes: Expected size of the reply in bytes
3483 * @u16reply: Pointer to area where reply should be written
3484 * @maxwait: Max wait time for a reply (in seconds)
3485 * @sleepFlag: Specifies whether the process can sleep
3487 * NOTES: It is the callers responsibility to byte-swap fields in the
3488 * request which are greater than 1 byte in size. It is also the
3489 * callers responsibility to byte-swap response fields which are
3490 * greater than 1 byte in size.
3492 * Returns 0 for success, non-zero for failure.
3495 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
3496 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
3498 MPIDefaultReply_t *mptReply;
3503 * Get ready to cache a handshake reply
3505 ioc->hs_reply_idx = 0;
3506 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3507 mptReply->MsgLength = 0;
3510 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
3511 * then tell IOC that we want to handshake a request of N words.
3512 * (WRITE u32val to Doorbell reg).
3514 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3515 CHIPREG_WRITE32(&ioc->chip->Doorbell,
3516 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
3517 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
3520 * Wait for IOC's doorbell handshake int
3522 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3525 dhsprintk((MYIOC_s_INFO_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
3526 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3528 /* Read doorbell and check for active bit */
3529 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
3533 * Clear doorbell int (WRITE 0 to IntStatus reg),
3534 * then wait for IOC to ACKnowledge that it's ready for
3535 * our handshake request.
3537 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3538 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3543 u8 *req_as_bytes = (u8 *) req;
3546 * Stuff request words via doorbell handshake,
3547 * with ACK from IOC for each.
3549 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
3550 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
3551 (req_as_bytes[(ii*4) + 1] << 8) |
3552 (req_as_bytes[(ii*4) + 2] << 16) |
3553 (req_as_bytes[(ii*4) + 3] << 24));
3555 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
3556 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3560 dhsprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
3561 DBG_DUMP_REQUEST_FRAME_HDR(req)
3563 dhsprintk((MYIOC_s_INFO_FMT "HandShake request post done, WaitCnt=%d%s\n",
3564 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
3567 * Wait for completion of doorbell handshake reply from the IOC
3569 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
3572 dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n",
3573 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
3576 * Copy out the cached reply...
3578 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
3579 u16reply[ii] = ioc->hs_reply[ii];
3587 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3589 * WaitForDoorbellAck - Wait for IOC to clear the IOP_DOORBELL_STATUS bit
3590 * in it's IntStatus register.
3591 * @ioc: Pointer to MPT_ADAPTER structure
3592 * @howlong: How long to wait (in seconds)
3593 * @sleepFlag: Specifies whether the process can sleep
3595 * This routine waits (up to ~2 seconds max) for IOC doorbell
3596 * handshake ACKnowledge.
3598 * Returns a negative value on failure, else wait loop count.
3601 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3607 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
3609 if (sleepFlag == CAN_SLEEP) {
3611 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3612 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3614 msleep_interruptible (1);
3619 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3620 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3628 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (count=%d)\n",
3633 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
3634 ioc->name, count, intstat);
3638 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3640 * WaitForDoorbellInt - Wait for IOC to set the HIS_DOORBELL_INTERRUPT bit
3641 * in it's IntStatus register.
3642 * @ioc: Pointer to MPT_ADAPTER structure
3643 * @howlong: How long to wait (in seconds)
3644 * @sleepFlag: Specifies whether the process can sleep
3646 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt.
3648 * Returns a negative value on failure, else wait loop count.
3651 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3657 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
3658 if (sleepFlag == CAN_SLEEP) {
3660 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3661 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3663 msleep_interruptible(1);
3668 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3669 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3677 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
3678 ioc->name, count, howlong));
3682 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
3683 ioc->name, count, intstat);
3687 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3689 * WaitForDoorbellReply - Wait for and capture a IOC handshake reply.
3690 * @ioc: Pointer to MPT_ADAPTER structure
3691 * @howlong: How long to wait (in seconds)
3692 * @sleepFlag: Specifies whether the process can sleep
3694 * This routine polls the IOC for a handshake reply, 16 bits at a time.
3695 * Reply is cached to IOC private area large enough to hold a maximum
3696 * of 128 bytes of reply data.
3698 * Returns a negative value on failure, else size of reply in WORDS.
3701 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3706 u16 *hs_reply = ioc->hs_reply;
3707 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3710 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
3713 * Get first two u16's so we can look at IOC's intended reply MsgLength
3716 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
3719 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3720 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3721 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3724 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3725 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3729 dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
3730 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
3731 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3734 * If no error (and IOC said MsgLength is > 0), piece together
3735 * reply 16 bits at a time.
3737 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
3738 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3740 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3741 /* don't overflow our IOC hs_reply[] buffer! */
3742 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
3743 hs_reply[u16cnt] = hword;
3744 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3747 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3749 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3752 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
3757 else if (u16cnt != (2 * mptReply->MsgLength)) {
3760 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
3765 dhsprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
3766 DBG_DUMP_REPLY_FRAME(mptReply)
3768 dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
3769 ioc->name, t, u16cnt/2));
3773 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3775 * GetLanConfigPages - Fetch LANConfig pages.
3776 * @ioc: Pointer to MPT_ADAPTER structure
3778 * Return: 0 for success
3779 * -ENOMEM if no memory available
3780 * -EPERM if not allowed due to ISR context
3781 * -EAGAIN if no msg frames currently available
3782 * -EFAULT for non-successful reply or no reply (timeout)
3785 GetLanConfigPages(MPT_ADAPTER *ioc)
3787 ConfigPageHeader_t hdr;
3789 LANPage0_t *ppage0_alloc;
3790 dma_addr_t page0_dma;
3791 LANPage1_t *ppage1_alloc;
3792 dma_addr_t page1_dma;
3797 /* Get LAN Page 0 header */
3798 hdr.PageVersion = 0;
3801 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
3804 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
3809 if ((rc = mpt_config(ioc, &cfg)) != 0)
3812 if (hdr.PageLength > 0) {
3813 data_sz = hdr.PageLength * 4;
3814 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
3817 memset((u8 *)ppage0_alloc, 0, data_sz);
3818 cfg.physAddr = page0_dma;
3819 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
3821 if ((rc = mpt_config(ioc, &cfg)) == 0) {
3823 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
3824 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
3828 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
3831 * Normalize endianness of structure data,
3832 * by byte-swapping all > 1 byte fields!
3841 /* Get LAN Page 1 header */
3842 hdr.PageVersion = 0;
3845 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
3848 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
3852 if ((rc = mpt_config(ioc, &cfg)) != 0)
3855 if (hdr.PageLength == 0)
3858 data_sz = hdr.PageLength * 4;
3860 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
3862 memset((u8 *)ppage1_alloc, 0, data_sz);
3863 cfg.physAddr = page1_dma;
3864 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
3866 if ((rc = mpt_config(ioc, &cfg)) == 0) {
3868 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
3869 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
3872 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
3875 * Normalize endianness of structure data,
3876 * by byte-swapping all > 1 byte fields!
3884 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3886 * GetFcPortPage0 - Fetch FCPort config Page0.
3887 * @ioc: Pointer to MPT_ADAPTER structure
3888 * @portnum: IOC Port number
3890 * Return: 0 for success
3891 * -ENOMEM if no memory available
3892 * -EPERM if not allowed due to ISR context
3893 * -EAGAIN if no msg frames currently available
3894 * -EFAULT for non-successful reply or no reply (timeout)
3897 GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
3899 ConfigPageHeader_t hdr;
3901 FCPortPage0_t *ppage0_alloc;
3902 FCPortPage0_t *pp0dest;
3903 dma_addr_t page0_dma;
3908 /* Get FCPort Page 0 header */
3909 hdr.PageVersion = 0;
3912 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
3915 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
3917 cfg.pageAddr = portnum;
3920 if ((rc = mpt_config(ioc, &cfg)) != 0)
3923 if (hdr.PageLength == 0)
3926 data_sz = hdr.PageLength * 4;
3928 ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
3930 memset((u8 *)ppage0_alloc, 0, data_sz);
3931 cfg.physAddr = page0_dma;
3932 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
3934 if ((rc = mpt_config(ioc, &cfg)) == 0) {
3936 pp0dest = &ioc->fc_port_page0[portnum];
3937 copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
3938 memcpy(pp0dest, ppage0_alloc, copy_sz);
3941 * Normalize endianness of structure data,
3942 * by byte-swapping all > 1 byte fields!
3944 pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
3945 pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
3946 pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
3947 pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
3948 pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
3949 pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
3950 pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
3951 pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
3952 pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
3953 pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
3954 pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
3955 pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
3956 pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
3957 pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
3958 pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
3959 pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
3963 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
3969 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3971 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
3972 * @ioc: Pointer to MPT_ADAPTER structure
3974 * Returns: 0 for success
3975 * -ENOMEM if no memory available
3976 * -EPERM if not allowed due to ISR context
3977 * -EAGAIN if no msg frames currently available
3978 * -EFAULT for non-successful reply or no reply (timeout)
3981 GetIoUnitPage2(MPT_ADAPTER *ioc)
3983 ConfigPageHeader_t hdr;
3985 IOUnitPage2_t *ppage_alloc;
3986 dma_addr_t page_dma;
3990 /* Get the page header */
3991 hdr.PageVersion = 0;
3994 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
3997 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4002 if ((rc = mpt_config(ioc, &cfg)) != 0)
4005 if (hdr.PageLength == 0)
4008 /* Read the config page */
4009 data_sz = hdr.PageLength * 4;
4011 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4013 memset((u8 *)ppage_alloc, 0, data_sz);
4014 cfg.physAddr = page_dma;
4015 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4017 /* If Good, save data */
4018 if ((rc = mpt_config(ioc, &cfg)) == 0)
4019 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4021 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4027 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4028 /* mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4029 * @ioc: Pointer to a Adapter Strucutre
4030 * @portnum: IOC port number
4032 * Return: -EFAULT if read of config page header fails
4034 * If read of SCSI Port Page 0 fails,
4035 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4036 * Adapter settings: async, narrow
4038 * If read of SCSI Port Page 2 fails,
4039 * Adapter settings valid
4040 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4045 * CHECK - what type of locking mechanisms should be used????
4048 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4053 ConfigPageHeader_t header;
4059 if (!ioc->spi_data.nvram) {
4062 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4063 mem = kmalloc(sz, GFP_ATOMIC);
4067 ioc->spi_data.nvram = (int *) mem;
4069 dprintk((MYIOC_s_INFO_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4070 ioc->name, ioc->spi_data.nvram, sz));
4073 /* Invalidate NVRAM information
4075 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4076 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4079 /* Read SPP0 header, allocate memory, then read page.
4081 header.PageVersion = 0;
4082 header.PageLength = 0;
4083 header.PageNumber = 0;
4084 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4087 cfg.pageAddr = portnum;
4088 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4090 cfg.timeout = 0; /* use default */
4091 if (mpt_config(ioc, &cfg) != 0)
4094 if (header.PageLength > 0) {
4095 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4097 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4098 cfg.physAddr = buf_dma;
4099 if (mpt_config(ioc, &cfg) != 0) {
4100 ioc->spi_data.maxBusWidth = MPT_NARROW;
4101 ioc->spi_data.maxSyncOffset = 0;
4102 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4103 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4106 /* Save the Port Page 0 data
4108 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4109 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4110 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4112 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4113 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4114 dinitprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
4115 ioc->name, pPP0->Capabilities));
4117 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4118 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4120 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4121 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4122 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4124 ioc->spi_data.maxSyncOffset = 0;
4125 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4128 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4130 /* Update the minSyncFactor based on bus type.
4132 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4133 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4135 if (ioc->spi_data.minSyncFactor < MPT_ULTRA)
4136 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4140 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4145 /* SCSI Port Page 2 - Read the header then the page.
4147 header.PageVersion = 0;
4148 header.PageLength = 0;
4149 header.PageNumber = 2;
4150 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4153 cfg.pageAddr = portnum;
4154 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4156 if (mpt_config(ioc, &cfg) != 0)
4159 if (header.PageLength > 0) {
4160 /* Allocate memory and read SCSI Port Page 2
4162 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4164 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4165 cfg.physAddr = buf_dma;
4166 if (mpt_config(ioc, &cfg) != 0) {
4167 /* Nvram data is left with INVALID mark
4171 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4172 MpiDeviceInfo_t *pdevice = NULL;
4174 /* Save the Port Page 2 data
4175 * (reformat into a 32bit quantity)
4177 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4178 ioc->spi_data.PortFlags = data;
4179 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4180 pdevice = &pPP2->DeviceSettings[ii];
4181 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4182 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4183 ioc->spi_data.nvram[ii] = data;
4187 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4191 /* Update Adapter limits with those from NVRAM
4192 * Comment: Don't need to do this. Target performance
4193 * parameters will never exceed the adapters limits.
4199 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4200 /* mpt_readScsiDevicePageHeaders - save version and length of SDP1
4201 * @ioc: Pointer to a Adapter Strucutre
4202 * @portnum: IOC port number
4204 * Return: -EFAULT if read of config page header fails
4208 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4211 ConfigPageHeader_t header;
4213 /* Read the SCSI Device Page 1 header
4215 header.PageVersion = 0;
4216 header.PageLength = 0;
4217 header.PageNumber = 1;
4218 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4221 cfg.pageAddr = portnum;
4222 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4225 if (mpt_config(ioc, &cfg) != 0)
4228 ioc->spi_data.sdp1version = cfg.hdr->PageVersion;
4229 ioc->spi_data.sdp1length = cfg.hdr->PageLength;
4231 header.PageVersion = 0;
4232 header.PageLength = 0;
4233 header.PageNumber = 0;
4234 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4235 if (mpt_config(ioc, &cfg) != 0)
4238 ioc->spi_data.sdp0version = cfg.hdr->PageVersion;
4239 ioc->spi_data.sdp0length = cfg.hdr->PageLength;
4241 dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
4242 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
4244 dcprintk((MYIOC_s_INFO_FMT "Headers: 1: version %d length %d\n",
4245 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
4249 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4251 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4252 * @ioc: Pointer to a Adapter Strucutre
4253 * @portnum: IOC port number
4257 * -EFAULT if read of config page header fails or data pointer not NULL
4258 * -ENOMEM if pci_alloc failed
4261 mpt_findImVolumes(MPT_ADAPTER *ioc)
4265 ConfigPageIoc2RaidVol_t *pIocRv;
4266 dma_addr_t ioc2_dma;
4268 ConfigPageHeader_t header;
4275 /* Read IOCP2 header then the page.
4277 header.PageVersion = 0;
4278 header.PageLength = 0;
4279 header.PageNumber = 2;
4280 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4284 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4287 if (mpt_config(ioc, &cfg) != 0)
4290 if (header.PageLength == 0)
4293 iocpage2sz = header.PageLength * 4;
4294 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
4298 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4299 cfg.physAddr = ioc2_dma;
4300 if (mpt_config(ioc, &cfg) != 0)
4303 if ( (mem = (u8 *)ioc->spi_data.pIocPg2) == NULL ) {
4304 mem = kmalloc(iocpage2sz, GFP_ATOMIC);
4306 ioc->spi_data.pIocPg2 = (IOCPage2_t *) mem;
4311 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
4313 /* Identify RAID Volume Id's */
4314 nVols = pIoc2->NumActiveVolumes;
4320 /* At least 1 RAID Volume
4322 pIocRv = pIoc2->RaidVolume;
4323 ioc->spi_data.isRaid = 0;
4324 for (jj = 0; jj < nVols; jj++, pIocRv++) {
4325 vid = pIocRv->VolumeID;
4326 vbus = pIocRv->VolumeBus;
4327 vioc = pIocRv->VolumeIOC;
4332 ioc->spi_data.isRaid |= (1 << vid);
4334 /* Error! Always bus 0
4340 /* Identify Hidden Physical Disk Id's */
4341 nPhys = pIoc2->NumActivePhysDisks;
4343 /* No physical disks.
4346 mpt_read_ioc_pg_3(ioc);
4350 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
4356 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
4361 ConfigPageHeader_t header;
4362 dma_addr_t ioc3_dma;
4365 /* Free the old page
4367 if (ioc->spi_data.pIocPg3) {
4368 kfree(ioc->spi_data.pIocPg3);
4369 ioc->spi_data.pIocPg3 = NULL;
4372 /* There is at least one physical disk.
4373 * Read and save IOC Page 3
4375 header.PageVersion = 0;
4376 header.PageLength = 0;
4377 header.PageNumber = 3;
4378 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4382 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4385 if (mpt_config(ioc, &cfg) != 0)
4388 if (header.PageLength == 0)
4391 /* Read Header good, alloc memory
4393 iocpage3sz = header.PageLength * 4;
4394 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
4398 /* Read the Page and save the data
4399 * into malloc'd memory.
4401 cfg.physAddr = ioc3_dma;
4402 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4403 if (mpt_config(ioc, &cfg) == 0) {
4404 mem = kmalloc(iocpage3sz, GFP_ATOMIC);
4406 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
4407 ioc->spi_data.pIocPg3 = (IOCPage3_t *) mem;
4411 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
4417 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
4421 ConfigPageHeader_t header;
4422 dma_addr_t ioc4_dma;
4425 /* Read and save IOC Page 4
4427 header.PageVersion = 0;
4428 header.PageLength = 0;
4429 header.PageNumber = 4;
4430 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4434 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4437 if (mpt_config(ioc, &cfg) != 0)
4440 if (header.PageLength == 0)
4443 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
4444 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
4445 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
4449 ioc4_dma = ioc->spi_data.IocPg4_dma;
4450 iocpage4sz = ioc->spi_data.IocPg4Sz;
4453 /* Read the Page into dma memory.
4455 cfg.physAddr = ioc4_dma;
4456 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4457 if (mpt_config(ioc, &cfg) == 0) {
4458 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
4459 ioc->spi_data.IocPg4_dma = ioc4_dma;
4460 ioc->spi_data.IocPg4Sz = iocpage4sz;
4462 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
4463 ioc->spi_data.pIocPg4 = NULL;
4468 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
4472 ConfigPageHeader_t header;
4473 dma_addr_t ioc1_dma;
4477 /* Check the Coalescing Timeout in IOC Page 1
4479 header.PageVersion = 0;
4480 header.PageLength = 0;
4481 header.PageNumber = 1;
4482 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4486 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4489 if (mpt_config(ioc, &cfg) != 0)
4492 if (header.PageLength == 0)
4495 /* Read Header good, alloc memory
4497 iocpage1sz = header.PageLength * 4;
4498 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
4502 /* Read the Page and check coalescing timeout
4504 cfg.physAddr = ioc1_dma;
4505 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4506 if (mpt_config(ioc, &cfg) == 0) {
4508 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
4509 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
4510 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
4512 dprintk((MYIOC_s_INFO_FMT "Coalescing Enabled Timeout = %d\n",
4515 if (tmp > MPT_COALESCING_TIMEOUT) {
4516 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
4518 /* Write NVRAM and current
4521 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4522 if (mpt_config(ioc, &cfg) == 0) {
4523 dprintk((MYIOC_s_INFO_FMT "Reset Current Coalescing Timeout to = %d\n",
4524 ioc->name, MPT_COALESCING_TIMEOUT));
4526 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
4527 if (mpt_config(ioc, &cfg) == 0) {
4528 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout to = %d\n",
4529 ioc->name, MPT_COALESCING_TIMEOUT));
4531 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout Failed\n",
4536 dprintk((MYIOC_s_WARN_FMT "Reset of Current Coalescing Timeout Failed!\n",
4542 dprintk((MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
4546 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
4551 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4553 * SendEventNotification - Send EventNotification (on or off) request
4555 * @ioc: Pointer to MPT_ADAPTER structure
4556 * @EvSwitch: Event switch flags
4559 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
4561 EventNotification_t *evnp;
4563 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
4565 dprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
4569 memset(evnp, 0, sizeof(*evnp));
4571 dprintk((MYIOC_s_INFO_FMT "Sending EventNotification(%d)\n", ioc->name, EvSwitch));
4573 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
4574 evnp->ChainOffset = 0;
4576 evnp->Switch = EvSwitch;
4578 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
4583 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4585 * SendEventAck - Send EventAck request to MPT adapter.
4586 * @ioc: Pointer to MPT_ADAPTER structure
4587 * @evnp: Pointer to original EventNotification request
4590 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
4594 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4595 printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK request frame!\n",
4599 memset(pAck, 0, sizeof(*pAck));
4601 dprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
4603 pAck->Function = MPI_FUNCTION_EVENT_ACK;
4604 pAck->ChainOffset = 0;
4606 pAck->Event = evnp->Event;
4607 pAck->EventContext = evnp->EventContext;
4609 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
4614 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4616 * mpt_config - Generic function to issue config message
4617 * @ioc - Pointer to an adapter structure
4618 * @cfg - Pointer to a configuration structure. Struct contains
4619 * action, page address, direction, physical address
4620 * and pointer to a configuration page header
4621 * Page header is updated.
4623 * Returns 0 for success
4624 * -EPERM if not allowed due to ISR context
4625 * -EAGAIN if no msg frames currently available
4626 * -EFAULT for non-successful reply or no reply (timeout)
4629 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
4633 unsigned long flags;
4638 /* Prevent calling wait_event() (below), if caller happens
4639 * to be in ISR context, because that is fatal!
4641 in_isr = in_interrupt();
4643 dcprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
4648 /* Get and Populate a free Frame
4650 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4651 dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
4655 pReq = (Config_t *)mf;
4656 pReq->Action = pCfg->action;
4658 pReq->ChainOffset = 0;
4659 pReq->Function = MPI_FUNCTION_CONFIG;
4660 pReq->ExtPageLength = 0;
4661 pReq->ExtPageType = 0;
4663 for (ii=0; ii < 8; ii++)
4664 pReq->Reserved2[ii] = 0;
4666 pReq->Header.PageVersion = pCfg->hdr->PageVersion;
4667 pReq->Header.PageLength = pCfg->hdr->PageLength;
4668 pReq->Header.PageNumber = pCfg->hdr->PageNumber;
4669 pReq->Header.PageType = (pCfg->hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
4670 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
4672 /* Add a SGE to the config request.
4675 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
4677 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
4679 flagsLength |= pCfg->hdr->PageLength * 4;
4681 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
4683 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
4684 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
4686 /* Append pCfg pointer to end of mf
4688 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
4690 /* Initalize the timer
4692 init_timer(&pCfg->timer);
4693 pCfg->timer.data = (unsigned long) ioc;
4694 pCfg->timer.function = mpt_timer_expired;
4695 pCfg->wait_done = 0;
4697 /* Set the timer; ensure 10 second minimum */
4698 if (pCfg->timeout < 10)
4699 pCfg->timer.expires = jiffies + HZ*10;
4701 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
4703 /* Add to end of Q, set timer and then issue this command */
4704 spin_lock_irqsave(&ioc->FreeQlock, flags);
4705 list_add_tail(&pCfg->linkage, &ioc->configQ);
4706 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4708 add_timer(&pCfg->timer);
4709 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4710 wait_event(mpt_waitq, pCfg->wait_done);
4712 /* mf has been freed - do not access */
4719 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4721 * mpt_toolbox - Generic function to issue toolbox message
4722 * @ioc - Pointer to an adapter structure
4723 * @cfg - Pointer to a toolbox structure. Struct contains
4724 * action, page address, direction, physical address
4725 * and pointer to a configuration page header
4726 * Page header is updated.
4728 * Returns 0 for success
4729 * -EPERM if not allowed due to ISR context
4730 * -EAGAIN if no msg frames currently available
4731 * -EFAULT for non-successful reply or no reply (timeout)
4734 mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
4736 ToolboxIstwiReadWriteRequest_t *pReq;
4738 struct pci_dev *pdev;
4739 unsigned long flags;
4744 /* Prevent calling wait_event() (below), if caller happens
4745 * to be in ISR context, because that is fatal!
4747 in_isr = in_interrupt();
4749 dcprintk((MYIOC_s_WARN_FMT "toobox request not allowed in ISR context!\n",
4754 /* Get and Populate a free Frame
4756 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4757 dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n",
4761 pReq = (ToolboxIstwiReadWriteRequest_t *)mf;
4762 pReq->Tool = pCfg->action;
4764 pReq->ChainOffset = 0;
4765 pReq->Function = MPI_FUNCTION_TOOLBOX;
4766 pReq->Reserved1 = 0;
4767 pReq->Reserved2 = 0;
4769 pReq->Flags = pCfg->dir;
4771 pReq->Reserved3 = 0;
4772 pReq->NumAddressBytes = 0x01;
4773 pReq->Reserved4 = 0;
4774 pReq->DataLength = 0x04;
4775 pdev = (struct pci_dev *) ioc->pcidev;
4776 if (pdev->devfn & 1)
4777 pReq->DeviceAddr = 0xB2;
4779 pReq->DeviceAddr = 0xB0;
4783 pReq->Reserved5 = 0;
4785 /* Add a SGE to the config request.
4788 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | 4;
4790 mpt_add_sge((char *)&pReq->SGL, flagsLength, pCfg->physAddr);
4792 dcprintk((MYIOC_s_INFO_FMT "Sending Toolbox request, Tool=%x\n",
4793 ioc->name, pReq->Tool));
4795 /* Append pCfg pointer to end of mf
4797 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
4799 /* Initalize the timer
4801 init_timer(&pCfg->timer);
4802 pCfg->timer.data = (unsigned long) ioc;
4803 pCfg->timer.function = mpt_timer_expired;
4804 pCfg->wait_done = 0;
4806 /* Set the timer; ensure 10 second minimum */
4807 if (pCfg->timeout < 10)
4808 pCfg->timer.expires = jiffies + HZ*10;
4810 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
4812 /* Add to end of Q, set timer and then issue this command */
4813 spin_lock_irqsave(&ioc->FreeQlock, flags);
4814 list_add_tail(&pCfg->linkage, &ioc->configQ);
4815 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4817 add_timer(&pCfg->timer);
4818 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4819 wait_event(mpt_waitq, pCfg->wait_done);
4821 /* mf has been freed - do not access */
4828 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4830 * mpt_timer_expired - Call back for timer process.
4831 * Used only internal config functionality.
4832 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
4835 mpt_timer_expired(unsigned long data)
4837 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
4839 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name));
4841 /* Perform a FW reload */
4842 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
4843 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
4845 /* No more processing.
4846 * Hard reset clean-up will wake up
4847 * process and free all resources.
4849 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name));
4854 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4856 * mpt_ioc_reset - Base cleanup for hard reset
4857 * @ioc: Pointer to the adapter structure
4858 * @reset_phase: Indicates pre- or post-reset functionality
4860 * Remark: Free's resources with internally generated commands.
4863 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
4866 unsigned long flags;
4868 dprintk((KERN_WARNING MYNAM
4869 ": IOC %s_reset routed to MPT base driver!\n",
4870 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
4871 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
4873 if (reset_phase == MPT_IOC_SETUP_RESET) {
4875 } else if (reset_phase == MPT_IOC_PRE_RESET) {
4876 /* If the internal config Q is not empty -
4877 * delete timer. MF resources will be freed when
4878 * the FIFO's are primed.
4880 spin_lock_irqsave(&ioc->FreeQlock, flags);
4881 list_for_each_entry(pCfg, &ioc->configQ, linkage)
4882 del_timer(&pCfg->timer);
4883 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4888 /* Search the configQ for internal commands.
4889 * Flush the Q, and wake up all suspended threads.
4891 spin_lock_irqsave(&ioc->FreeQlock, flags);
4892 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
4893 list_del(&pCfg->linkage);
4895 pCfg->status = MPT_CONFIG_ERROR;
4896 pCfg->wait_done = 1;
4897 wake_up(&mpt_waitq);
4899 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4902 return 1; /* currently means nothing really */
4906 #ifdef CONFIG_PROC_FS /* { */
4907 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4909 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
4911 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4913 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
4915 * Returns 0 for success, non-zero for failure.
4918 procmpt_create(void)
4920 struct proc_dir_entry *ent;
4922 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
4923 if (mpt_proc_root_dir == NULL)
4926 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
4928 ent->read_proc = procmpt_summary_read;
4930 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
4932 ent->read_proc = procmpt_version_read;
4937 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4939 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
4941 * Returns 0 for success, non-zero for failure.
4944 procmpt_destroy(void)
4946 remove_proc_entry("version", mpt_proc_root_dir);
4947 remove_proc_entry("summary", mpt_proc_root_dir);
4948 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
4951 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4953 * procmpt_summary_read - Handle read request from /proc/mpt/summary
4954 * or from /proc/mpt/iocN/summary.
4955 * @buf: Pointer to area to write information
4956 * @start: Pointer to start pointer
4957 * @offset: Offset to start writing
4959 * @eof: Pointer to EOF integer
4962 * Returns number of characters written to process performing the read.
4965 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
4975 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
4979 list_for_each_entry(ioc, &ioc_list, list) {
4982 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
4985 if ((out-buf) >= request)
4992 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
4995 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4997 * procmpt_version_read - Handle read request from /proc/mpt/version.
4998 * @buf: Pointer to area to write information
4999 * @start: Pointer to start pointer
5000 * @offset: Offset to start writing
5002 * @eof: Pointer to EOF integer
5005 * Returns number of characters written to process performing the read.
5008 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5011 int scsi, fc, sas, lan, ctl, targ, dmp;
5015 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5016 len += sprintf(buf+len, " Fusion MPT base driver\n");
5018 scsi = fc = sas = lan = ctl = targ = dmp = 0;
5019 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5021 if (MptCallbacks[ii]) {
5022 switch (MptDriverClass[ii]) {
5024 if (!scsi++) drvname = "SPI host";
5027 if (!fc++) drvname = "FC host";
5030 if (!sas++) drvname = "SAS host";
5033 if (!lan++) drvname = "LAN";
5036 if (!targ++) drvname = "SCSI target";
5039 if (!ctl++) drvname = "ioctl";
5044 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5048 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5051 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5053 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5054 * @buf: Pointer to area to write information
5055 * @start: Pointer to start pointer
5056 * @offset: Offset to start writing
5058 * @eof: Pointer to EOF integer
5061 * Returns number of characters written to process performing the read.
5064 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5066 MPT_ADAPTER *ioc = data;
5072 mpt_get_fw_exp_ver(expVer, ioc);
5074 len = sprintf(buf, "%s:", ioc->name);
5075 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5076 len += sprintf(buf+len, " (f/w download boot flag set)");
5077 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5078 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5080 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
5081 ioc->facts.ProductID,
5083 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5084 if (ioc->facts.FWImageSize)
5085 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5086 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5087 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5088 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
5090 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
5091 ioc->facts.CurrentHostMfaHighAddr);
5092 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
5093 ioc->facts.CurrentSenseBufferHighAddr);
5095 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5096 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5098 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5099 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
5101 * Rounding UP to nearest 4-kB boundary here...
5103 sz = (ioc->req_sz * ioc->req_depth) + 128;
5104 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5105 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5106 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5107 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
5108 4*ioc->facts.RequestFrameSize,
5109 ioc->facts.GlobalCredits);
5111 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
5112 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
5113 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5114 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5115 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5116 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
5117 ioc->facts.CurReplyFrameSize,
5118 ioc->facts.ReplyQueueDepth);
5120 len += sprintf(buf+len, " MaxDevices = %d\n",
5121 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5122 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
5125 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5126 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
5128 ioc->facts.NumberOfPorts);
5129 if (ioc->bus_type == FC) {
5130 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5131 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5132 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5133 a[5], a[4], a[3], a[2], a[1], a[0]);
5135 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
5136 ioc->fc_port_page0[p].WWNN.High,
5137 ioc->fc_port_page0[p].WWNN.Low,
5138 ioc->fc_port_page0[p].WWPN.High,
5139 ioc->fc_port_page0[p].WWPN.Low);
5143 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5146 #endif /* CONFIG_PROC_FS } */
5148 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5150 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
5153 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
5154 sprintf(buf, " (Exp %02d%02d)",
5155 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
5156 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
5159 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
5160 strcat(buf, " [MDBG]");
5164 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5166 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5167 * @ioc: Pointer to MPT_ADAPTER structure
5168 * @buffer: Pointer to buffer where IOC summary info should be written
5169 * @size: Pointer to number of bytes we wrote (set by this routine)
5170 * @len: Offset at which to start writing in buffer
5171 * @showlan: Display LAN stuff?
5173 * This routine writes (english readable) ASCII text, which represents
5174 * a summary of IOC information, to a buffer.
5177 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
5182 mpt_get_fw_exp_ver(expVer, ioc);
5185 * Shorter summary of attached ioc's...
5187 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
5190 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
5191 ioc->facts.FWVersion.Word,
5193 ioc->facts.NumberOfPorts,
5196 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
5197 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5198 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
5199 a[5], a[4], a[3], a[2], a[1], a[0]);
5203 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
5205 y += sprintf(buffer+len+y, ", IRQ=%s", __irq_itoa(ioc->pci_irq));
5209 y += sprintf(buffer+len+y, " (disabled)");
5211 y += sprintf(buffer+len+y, "\n");
5216 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5220 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5222 * mpt_HardResetHandler - Generic reset handler, issue SCSI Task
5223 * Management call based on input arg values. If TaskMgmt fails,
5224 * return associated SCSI request.
5225 * @ioc: Pointer to MPT_ADAPTER structure
5226 * @sleepFlag: Indicates if sleep or schedule must be called.
5228 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
5229 * or a non-interrupt thread. In the former, must not call schedule().
5231 * Remark: A return of -1 is a FATAL error case, as it means a
5232 * FW reload/initialization failed.
5234 * Returns 0 for SUCCESS or -1 if FAILED.
5237 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5240 unsigned long flags;
5242 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
5244 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
5245 printk("MF count 0x%x !\n", ioc->mfcnt);
5248 /* Reset the adapter. Prevent more than 1 call to
5249 * mpt_do_ioc_recovery at any instant in time.
5251 spin_lock_irqsave(&ioc->diagLock, flags);
5252 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
5253 spin_unlock_irqrestore(&ioc->diagLock, flags);
5256 ioc->diagPending = 1;
5258 spin_unlock_irqrestore(&ioc->diagLock, flags);
5260 /* FIXME: If do_ioc_recovery fails, repeat....
5263 /* The SCSI driver needs to adjust timeouts on all current
5264 * commands prior to the diagnostic reset being issued.
5265 * Prevents timeouts occuring during a diagnostic reset...very bad.
5266 * For all other protocol drivers, this is a no-op.
5272 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5273 if (MptResetHandlers[ii]) {
5274 dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
5276 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_SETUP_RESET);
5278 dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
5279 ioc->name, ioc->alt_ioc->name, ii));
5280 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_SETUP_RESET);
5286 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
5287 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
5292 ioc->alt_ioc->reload_fw = 0;
5294 spin_lock_irqsave(&ioc->diagLock, flags);
5295 ioc->diagPending = 0;
5297 ioc->alt_ioc->diagPending = 0;
5298 spin_unlock_irqrestore(&ioc->diagLock, flags);
5300 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
5305 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5307 EventDescriptionStr(u8 event, u32 evData0)
5312 case MPI_EVENT_NONE:
5315 case MPI_EVENT_LOG_DATA:
5318 case MPI_EVENT_STATE_CHANGE:
5319 ds = "State Change";
5321 case MPI_EVENT_UNIT_ATTENTION:
5322 ds = "Unit Attention";
5324 case MPI_EVENT_IOC_BUS_RESET:
5325 ds = "IOC Bus Reset";
5327 case MPI_EVENT_EXT_BUS_RESET:
5328 ds = "External Bus Reset";
5330 case MPI_EVENT_RESCAN:
5331 ds = "Bus Rescan Event";
5332 /* Ok, do we need to do anything here? As far as
5333 I can tell, this is when a new device gets added
5336 case MPI_EVENT_LINK_STATUS_CHANGE:
5337 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
5338 ds = "Link Status(FAILURE) Change";
5340 ds = "Link Status(ACTIVE) Change";
5342 case MPI_EVENT_LOOP_STATE_CHANGE:
5343 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
5344 ds = "Loop State(LIP) Change";
5345 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
5346 ds = "Loop State(LPE) Change"; /* ??? */
5348 ds = "Loop State(LPB) Change"; /* ??? */
5350 case MPI_EVENT_LOGOUT:
5353 case MPI_EVENT_EVENT_CHANGE:
5355 ds = "Events(ON) Change";
5357 ds = "Events(OFF) Change";
5359 case MPI_EVENT_INTEGRATED_RAID:
5360 ds = "Integrated Raid";
5363 * MPT base "custom" events may be added here...
5372 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5374 * ProcessEventNotification - Route a received EventNotificationReply to
5375 * all currently regeistered event handlers.
5376 * @ioc: Pointer to MPT_ADAPTER structure
5377 * @pEventReply: Pointer to EventNotification reply frame
5378 * @evHandlers: Pointer to integer, number of event handlers
5380 * Returns sum of event handlers return values.
5383 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
5395 * Do platform normalization of values
5397 event = le32_to_cpu(pEventReply->Event) & 0xFF;
5398 // evCtx = le32_to_cpu(pEventReply->EventContext);
5399 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
5401 evData0 = le32_to_cpu(pEventReply->Data[0]);
5404 evStr = EventDescriptionStr(event, evData0);
5405 devtprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n",
5410 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_EVENTS)
5411 printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
5412 for (ii = 0; ii < evDataLen; ii++)
5413 printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
5418 * Do general / base driver event processing
5421 case MPI_EVENT_NONE: /* 00 */
5422 case MPI_EVENT_LOG_DATA: /* 01 */
5423 case MPI_EVENT_STATE_CHANGE: /* 02 */
5424 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
5425 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
5426 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
5427 case MPI_EVENT_RESCAN: /* 06 */
5428 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
5429 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
5430 case MPI_EVENT_LOGOUT: /* 09 */
5431 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
5432 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE: /* 0C */
5435 case MPI_EVENT_EVENT_CHANGE: /* 0A */
5437 u8 evState = evData0 & 0xFF;
5439 /* CHECKME! What if evState unexpectedly says OFF (0)? */
5441 /* Update EventState field in cached IocFacts */
5442 if (ioc->facts.Function) {
5443 ioc->facts.EventState = evState;
5450 * Should this event be logged? Events are written sequentially.
5451 * When buffer is full, start again at the top.
5453 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
5456 idx = ioc->eventContext % ioc->eventLogSize;
5458 ioc->events[idx].event = event;
5459 ioc->events[idx].eventContext = ioc->eventContext;
5461 for (ii = 0; ii < 2; ii++) {
5463 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
5465 ioc->events[idx].data[ii] = 0;
5468 ioc->eventContext++;
5473 * Call each currently registered protocol event handler.
5475 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5476 if (MptEvHandlers[ii]) {
5477 devtprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
5479 r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
5483 /* FIXME? Examine results here? */
5486 * If needed, send (a single) EventAck.
5488 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
5489 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
5490 devtprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
5495 *evHandlers = handlers;
5499 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5501 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
5502 * @ioc: Pointer to MPT_ADAPTER structure
5503 * @log_info: U32 LogInfo reply word from the IOC
5505 * Refer to lsi/fc_log.h.
5508 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
5510 static char *subcl_str[8] = {
5511 "FCP Initiator", "FCP Target", "LAN", "MPI Message Layer",
5512 "FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
5514 u8 subcl = (log_info >> 24) & 0x7;
5516 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}\n",
5517 ioc->name, log_info, subcl_str[subcl]);
5520 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5522 * mpt_sp_log_info - Log information returned from SCSI Parallel IOC.
5523 * @ioc: Pointer to MPT_ADAPTER structure
5524 * @mr: Pointer to MPT reply frame
5525 * @log_info: U32 LogInfo word from the IOC
5527 * Refer to lsi/sp_log.h.
5530 mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
5532 u32 info = log_info & 0x00FF0000;
5533 char *desc = "unknown";
5537 desc = "bug! MID not found";
5538 if (ioc->reload_fw == 0)
5543 desc = "Parity Error";
5547 desc = "ASYNC Outbound Overrun";
5551 desc = "SYNC Offset Error";
5559 desc = "Msg In Overflow";
5567 desc = "Outbound DMA Overrun";
5571 desc = "Task Management";
5575 desc = "Device Problem";
5579 desc = "Invalid Phase Change";
5583 desc = "Untagged Table Size";
5588 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
5591 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5593 * mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
5594 * @ioc: Pointer to MPT_ADAPTER structure
5595 * @ioc_status: U32 IOCStatus word from IOC
5596 * @mf: Pointer to MPT request frame
5598 * Refer to lsi/mpi.h.
5601 mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
5603 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
5607 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
5608 desc = "Invalid Function";
5611 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
5615 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
5616 desc = "Invalid SGL";
5619 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
5620 desc = "Internal Error";
5623 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
5627 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
5628 desc = "Insufficient Resources";
5631 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
5632 desc = "Invalid Field";
5635 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
5636 desc = "Invalid State";
5639 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
5640 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
5641 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
5642 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
5643 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
5644 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
5645 /* No message for Config IOCStatus values */
5648 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
5649 /* No message for recovered error
5650 desc = "SCSI Recovered Error";
5654 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
5655 desc = "SCSI Invalid Bus";
5658 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
5659 desc = "SCSI Invalid TargetID";
5662 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
5664 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
5665 U8 cdb = pScsiReq->CDB[0];
5666 if (cdb != 0x12) { /* Inquiry is issued for device scanning */
5667 desc = "SCSI Device Not There";
5672 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
5673 desc = "SCSI Data Overrun";
5676 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
5677 /* This error is checked in scsi_io_done(). Skip.
5678 desc = "SCSI Data Underrun";
5682 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
5683 desc = "SCSI I/O Data Error";
5686 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
5687 desc = "SCSI Protocol Error";
5690 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
5691 desc = "SCSI Task Terminated";
5694 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
5695 desc = "SCSI Residual Mismatch";
5698 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
5699 desc = "SCSI Task Management Failed";
5702 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
5703 desc = "SCSI IOC Terminated";
5706 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
5707 desc = "SCSI Ext Terminated";
5715 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc);
5718 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5719 EXPORT_SYMBOL(mpt_attach);
5720 EXPORT_SYMBOL(mpt_detach);
5722 EXPORT_SYMBOL(mpt_resume);
5723 EXPORT_SYMBOL(mpt_suspend);
5725 EXPORT_SYMBOL(ioc_list);
5726 EXPORT_SYMBOL(mpt_proc_root_dir);
5727 EXPORT_SYMBOL(mpt_register);
5728 EXPORT_SYMBOL(mpt_deregister);
5729 EXPORT_SYMBOL(mpt_event_register);
5730 EXPORT_SYMBOL(mpt_event_deregister);
5731 EXPORT_SYMBOL(mpt_reset_register);
5732 EXPORT_SYMBOL(mpt_reset_deregister);
5733 EXPORT_SYMBOL(mpt_device_driver_register);
5734 EXPORT_SYMBOL(mpt_device_driver_deregister);
5735 EXPORT_SYMBOL(mpt_get_msg_frame);
5736 EXPORT_SYMBOL(mpt_put_msg_frame);
5737 EXPORT_SYMBOL(mpt_free_msg_frame);
5738 EXPORT_SYMBOL(mpt_add_sge);
5739 EXPORT_SYMBOL(mpt_send_handshake_request);
5740 EXPORT_SYMBOL(mpt_verify_adapter);
5741 EXPORT_SYMBOL(mpt_GetIocState);
5742 EXPORT_SYMBOL(mpt_print_ioc_summary);
5743 EXPORT_SYMBOL(mpt_lan_index);
5744 EXPORT_SYMBOL(mpt_stm_index);
5745 EXPORT_SYMBOL(mpt_HardResetHandler);
5746 EXPORT_SYMBOL(mpt_config);
5747 EXPORT_SYMBOL(mpt_toolbox);
5748 EXPORT_SYMBOL(mpt_findImVolumes);
5749 EXPORT_SYMBOL(mpt_read_ioc_pg_3);
5750 EXPORT_SYMBOL(mpt_alloc_fw_memory);
5751 EXPORT_SYMBOL(mpt_free_fw_memory);
5754 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5756 * fusion_init - Fusion MPT base driver initialization routine.
5758 * Returns 0 for success, non-zero for failure.
5765 show_mptmod_ver(my_NAME, my_VERSION);
5766 printk(KERN_INFO COPYRIGHT "\n");
5768 for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
5769 MptCallbacks[i] = NULL;
5770 MptDriverClass[i] = MPTUNKNOWN_DRIVER;
5771 MptEvHandlers[i] = NULL;
5772 MptResetHandlers[i] = NULL;
5775 /* Register ourselves (mptbase) in order to facilitate
5776 * EventNotification handling.
5778 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
5780 /* Register for hard reset handling callbacks.
5782 if (mpt_reset_register(mpt_base_index, mpt_ioc_reset) == 0) {
5783 dprintk((KERN_INFO MYNAM ": Register for IOC reset notification\n"));
5788 #ifdef CONFIG_PROC_FS
5789 (void) procmpt_create();
5794 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5796 * fusion_exit - Perform driver unload cleanup.
5798 * This routine frees all resources associated with each MPT adapter
5799 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
5805 dexitprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
5807 mpt_reset_deregister(mpt_base_index);
5809 #ifdef CONFIG_PROC_FS
5814 module_init(fusion_init);
5815 module_exit(fusion_exit);