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);
365 /* Put Request back on FreeQ! */
366 spin_lock_irqsave(&ioc->FreeQlock, flags);
367 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
371 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
375 } /* drain reply FIFO */
380 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
382 * mpt_base_reply - MPT base driver's callback routine; all base driver
383 * "internal" request/reply processing is routed here.
384 * Currently used for EventNotification and EventAck handling.
385 * @ioc: Pointer to MPT_ADAPTER structure
386 * @mf: Pointer to original MPT request frame
387 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
389 * Returns 1 indicating original alloc'd request frame ptr
390 * should be freed, or 0 if it shouldn't.
393 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
398 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name));
401 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
402 printk(MYIOC_s_ERR_FMT "NULL or BAD request frame ptr! (=%p)\n",
403 ioc->name, (void *)mf);
408 dprintk((MYIOC_s_ERR_FMT "Unexpected NULL Event (turbo?) reply!\n",
413 if (!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
414 dmfprintk((KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf));
415 DBG_DUMP_REQUEST_FRAME_HDR(mf)
418 func = reply->u.hdr.Function;
419 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n",
422 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
423 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
427 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
428 if (results != evHandlers) {
429 /* CHECKME! Any special handling needed here? */
430 devtprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
431 ioc->name, evHandlers, results));
435 * Hmmm... It seems that EventNotificationReply is an exception
436 * to the rule of one reply per request.
438 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
441 #ifdef CONFIG_PROC_FS
442 // LogEvent(ioc, pEvReply);
445 } else if (func == MPI_FUNCTION_EVENT_ACK) {
446 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
448 } else if (func == MPI_FUNCTION_CONFIG ||
449 func == MPI_FUNCTION_TOOLBOX) {
453 dcprintk((MYIOC_s_INFO_FMT "config_complete (mf=%p,mr=%p)\n",
454 ioc->name, mf, reply));
456 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
459 /* disable timer and remove from linked list */
460 del_timer(&pCfg->timer);
462 spin_lock_irqsave(&ioc->FreeQlock, flags);
463 list_del(&pCfg->linkage);
464 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
467 * If IOC Status is SUCCESS, save the header
468 * and set the status code to GOOD.
470 pCfg->status = MPT_CONFIG_ERROR;
472 ConfigReply_t *pReply = (ConfigReply_t *)reply;
475 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
476 dcprintk((KERN_NOTICE " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
477 status, le32_to_cpu(pReply->IOCLogInfo)));
479 pCfg->status = status;
480 if (status == MPI_IOCSTATUS_SUCCESS) {
481 pCfg->hdr->PageVersion = pReply->Header.PageVersion;
482 pCfg->hdr->PageLength = pReply->Header.PageLength;
483 pCfg->hdr->PageNumber = pReply->Header.PageNumber;
484 pCfg->hdr->PageType = pReply->Header.PageType;
489 * Wake up the original calling thread
495 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
500 * Conditionally tell caller to free the original
501 * EventNotification/EventAck/unexpected request frame!
506 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
508 * mpt_register - Register protocol-specific main callback handler.
509 * @cbfunc: callback function pointer
510 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
512 * This routine is called by a protocol-specific driver (SCSI host,
513 * LAN, SCSI target) to register it's reply callback routine. Each
514 * protocol-specific driver must do this before it will be able to
515 * use any IOC resources, such as obtaining request frames.
517 * NOTES: The SCSI protocol driver currently calls this routine thrice
518 * in order to register separate callbacks; one for "normal" SCSI IO;
519 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
521 * Returns a positive integer valued "handle" in the
522 * range (and S.O.D. order) {N,...,7,6,5,...,1} if successful.
523 * Any non-positive return value (including zero!) should be considered
524 * an error by the caller.
527 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
534 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
535 * (slot/handle 0 is reserved!)
537 for (i = MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
538 if (MptCallbacks[i] == NULL) {
539 MptCallbacks[i] = cbfunc;
540 MptDriverClass[i] = dclass;
541 MptEvHandlers[i] = NULL;
550 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
552 * mpt_deregister - Deregister a protocol drivers resources.
553 * @cb_idx: previously registered callback handle
555 * Each protocol-specific driver should call this routine when it's
556 * module is unloaded.
559 mpt_deregister(int cb_idx)
561 if ((cb_idx >= 0) && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
562 MptCallbacks[cb_idx] = NULL;
563 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
564 MptEvHandlers[cb_idx] = NULL;
570 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
572 * mpt_event_register - Register protocol-specific event callback
574 * @cb_idx: previously registered (via mpt_register) callback handle
575 * @ev_cbfunc: callback function
577 * This routine can be called by one or more protocol-specific drivers
578 * if/when they choose to be notified of MPT events.
580 * Returns 0 for success.
583 mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc)
585 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
588 MptEvHandlers[cb_idx] = ev_cbfunc;
592 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
594 * mpt_event_deregister - Deregister protocol-specific event callback
596 * @cb_idx: previously registered callback handle
598 * Each protocol-specific driver should call this routine
599 * when it does not (or can no longer) handle events,
600 * or when it's module is unloaded.
603 mpt_event_deregister(int cb_idx)
605 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
608 MptEvHandlers[cb_idx] = NULL;
611 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
613 * mpt_reset_register - Register protocol-specific IOC reset handler.
614 * @cb_idx: previously registered (via mpt_register) callback handle
615 * @reset_func: reset function
617 * This routine can be called by one or more protocol-specific drivers
618 * if/when they choose to be notified of IOC resets.
620 * Returns 0 for success.
623 mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func)
625 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
628 MptResetHandlers[cb_idx] = reset_func;
632 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
634 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
635 * @cb_idx: previously registered callback handle
637 * Each protocol-specific driver should call this routine
638 * when it does not (or can no longer) handle IOC reset handling,
639 * or when it's module is unloaded.
642 mpt_reset_deregister(int cb_idx)
644 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
647 MptResetHandlers[cb_idx] = NULL;
650 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
652 * mpt_device_driver_register - Register device driver hooks
655 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
659 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) {
663 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
665 /* call per pci device probe entry point */
666 list_for_each_entry(ioc, &ioc_list, list) {
667 if(dd_cbfunc->probe) {
668 dd_cbfunc->probe(ioc->pcidev,
669 ioc->pcidev->driver->id_table);
676 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
678 * mpt_device_driver_deregister - DeRegister device driver hooks
681 mpt_device_driver_deregister(int cb_idx)
683 struct mpt_pci_driver *dd_cbfunc;
686 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
689 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
691 list_for_each_entry(ioc, &ioc_list, list) {
692 if (dd_cbfunc->remove)
693 dd_cbfunc->remove(ioc->pcidev);
696 MptDeviceDriverHandlers[cb_idx] = NULL;
700 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
702 * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
703 * allocated per MPT adapter.
704 * @handle: Handle of registered MPT protocol driver
705 * @ioc: Pointer to MPT adapter structure
707 * Returns pointer to a MPT request frame or %NULL if none are available
708 * or IOC is not active.
711 mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc)
715 u16 req_idx; /* Request index */
717 /* validate handle and ioc identifier */
721 printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n");
724 /* If interrupts are not attached, do not return a request frame */
728 spin_lock_irqsave(&ioc->FreeQlock, flags);
729 if (!list_empty(&ioc->FreeQ)) {
732 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
733 u.frame.linkage.list);
734 list_del(&mf->u.frame.linkage.list);
735 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
736 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
738 req_idx = cpu_to_le16(req_offset / ioc->req_sz);
739 mf->u.frame.hwhdr.msgctxu.fld.req_idx = req_idx;
740 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
741 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; /* Default, will be changed if necessary in SG generation */
748 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
752 printk(KERN_WARNING "IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", ioc->mfcnt, ioc->req_depth);
754 if (mfcounter == PRINT_MF_COUNT)
755 printk(KERN_INFO "MF Count 0x%x Max 0x%x \n", ioc->mfcnt, ioc->req_depth);
758 dmfprintk((KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",
759 ioc->name, handle, ioc->id, mf));
763 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
765 * mpt_put_msg_frame - Send a protocol specific MPT request frame
767 * @handle: Handle of registered MPT protocol driver
768 * @ioc: Pointer to MPT adapter structure
769 * @mf: Pointer to MPT request frame
771 * This routine posts a MPT request frame to the request post FIFO of a
772 * specific MPT adapter.
775 mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
779 u16 req_idx; /* Request index */
781 /* ensure values are reset properly! */
782 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
783 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
785 req_idx = cpu_to_le16(req_offset / ioc->req_sz);
786 mf->u.frame.hwhdr.msgctxu.fld.req_idx = req_idx;
787 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
789 #ifdef MPT_DEBUG_MSG_FRAME
791 u32 *m = mf->u.frame.hwhdr.__hdr;
794 printk(KERN_INFO MYNAM ": %s: About to Put msg frame @ %p:\n" KERN_INFO " ",
796 n = ioc->req_sz/4 - 1;
799 for (ii=0; ii<=n; ii++) {
800 if (ii && ((ii%8)==0))
801 printk("\n" KERN_INFO " ");
802 printk(" %08x", le32_to_cpu(m[ii]));
808 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
809 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]));
810 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
813 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
815 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
816 * @handle: Handle of registered MPT protocol driver
817 * @ioc: Pointer to MPT adapter structure
818 * @mf: Pointer to MPT request frame
820 * This routine places a MPT request frame back on the MPT adapter's
824 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
828 /* Put Request back on FreeQ! */
829 spin_lock_irqsave(&ioc->FreeQlock, flags);
830 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
834 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
837 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
839 * mpt_add_sge - Place a simple SGE at address pAddr.
840 * @pAddr: virtual address for SGE
841 * @flagslength: SGE flags and data transfer length
842 * @dma_addr: Physical address
844 * This routine places a MPT request frame back on the MPT adapter's
848 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
850 if (sizeof(dma_addr_t) == sizeof(u64)) {
851 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
852 u32 tmp = dma_addr & 0xFFFFFFFF;
854 pSge->FlagsLength = cpu_to_le32(flagslength);
855 pSge->Address.Low = cpu_to_le32(tmp);
856 tmp = (u32) ((u64)dma_addr >> 32);
857 pSge->Address.High = cpu_to_le32(tmp);
860 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
861 pSge->FlagsLength = cpu_to_le32(flagslength);
862 pSge->Address = cpu_to_le32(dma_addr);
866 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
868 * mpt_send_handshake_request - Send MPT request via doorbell
870 * @handle: Handle of registered MPT protocol driver
871 * @ioc: Pointer to MPT adapter structure
872 * @reqBytes: Size of the request in bytes
873 * @req: Pointer to MPT request frame
874 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
876 * This routine is used exclusively to send MptScsiTaskMgmt
877 * requests since they are required to be sent via doorbell handshake.
879 * NOTE: It is the callers responsibility to byte-swap fields in the
880 * request which are greater than 1 byte in size.
882 * Returns 0 for success, non-zero for failure.
885 mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
891 /* State is known to be good upon entering
892 * this function so issue the bus reset
897 * Emulate what mpt_put_msg_frame() does /wrt to sanity
898 * setting cb_idx/req_idx. But ONLY if this request
899 * is in proper (pre-alloc'd) request buffer range...
901 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
902 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
903 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
904 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
905 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
908 /* Make sure there are no doorbells */
909 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
911 CHIPREG_WRITE32(&ioc->chip->Doorbell,
912 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
913 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
915 /* Wait for IOC doorbell int */
916 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
920 /* Read doorbell and check for active bit */
921 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
924 dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
927 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
929 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
933 /* Send request via doorbell handshake */
934 req_as_bytes = (u8 *) req;
935 for (ii = 0; ii < reqBytes/4; ii++) {
938 word = ((req_as_bytes[(ii*4) + 0] << 0) |
939 (req_as_bytes[(ii*4) + 1] << 8) |
940 (req_as_bytes[(ii*4) + 2] << 16) |
941 (req_as_bytes[(ii*4) + 3] << 24));
942 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
943 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
949 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
954 /* Make sure there are no doorbells */
955 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
960 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
962 * mpt_verify_adapter - Given a unique IOC identifier, set pointer to
963 * the associated MPT adapter structure.
964 * @iocid: IOC unique identifier (integer)
965 * @iocpp: Pointer to pointer to IOC adapter
967 * Returns iocid and sets iocpp.
970 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
974 list_for_each_entry(ioc,&ioc_list,list) {
975 if (ioc->id == iocid) {
985 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
987 * mpt_attach - Install a PCI intelligent MPT adapter.
988 * @pdev: Pointer to pci_dev structure
990 * This routine performs all the steps necessary to bring the IOC of
991 * a MPT adapter to a OPERATIONAL state. This includes registering
992 * memory regions, registering the interrupt, and allocating request
993 * and reply memory pools.
995 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
998 * Returns 0 for success, non-zero for failure.
1000 * TODO: Add support for polled controllers
1003 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1007 unsigned long mem_phys;
1015 static int mpt_ids = 0;
1016 #ifdef CONFIG_PROC_FS
1017 struct proc_dir_entry *dent, *ent;
1020 if (pci_enable_device(pdev))
1023 dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1025 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1026 dprintk((KERN_INFO MYNAM
1027 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1028 } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1029 printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1033 if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
1034 dprintk((KERN_INFO MYNAM
1035 ": Using 64 bit consistent mask\n"));
1037 dprintk((KERN_INFO MYNAM
1038 ": Not using 64 bit consistent mask\n"));
1040 ioc = kmalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1042 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1045 memset(ioc, 0, sizeof(MPT_ADAPTER));
1046 ioc->alloc_total = sizeof(MPT_ADAPTER);
1047 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1048 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1051 ioc->diagPending = 0;
1052 spin_lock_init(&ioc->diagLock);
1054 /* Initialize the event logging.
1056 ioc->eventTypes = 0; /* None */
1057 ioc->eventContext = 0;
1058 ioc->eventLogSize = 0;
1065 ioc->cached_fw = NULL;
1067 /* Initilize SCSI Config Data structure
1069 memset(&ioc->spi_data, 0, sizeof(ScsiCfgData));
1071 /* Initialize the running configQ head.
1073 INIT_LIST_HEAD(&ioc->configQ);
1075 /* Find lookup slot. */
1076 INIT_LIST_HEAD(&ioc->list);
1077 ioc->id = mpt_ids++;
1079 mem_phys = msize = 0;
1081 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1082 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1083 /* Get I/O space! */
1084 port = pci_resource_start(pdev, ii);
1085 psize = pci_resource_len(pdev,ii);
1088 mem_phys = pci_resource_start(pdev, ii);
1089 msize = pci_resource_len(pdev,ii);
1093 ioc->mem_size = msize;
1095 if (ii == DEVICE_COUNT_RESOURCE) {
1096 printk(KERN_ERR MYNAM ": ERROR - MPT adapter has no memory regions defined!\n");
1101 dinitprintk((KERN_INFO MYNAM ": MPT adapter @ %lx, msize=%dd bytes\n", mem_phys, msize));
1102 dinitprintk((KERN_INFO MYNAM ": (port i/o @ %lx, psize=%dd bytes)\n", port, psize));
1105 /* Get logical ptr for PciMem0 space */
1106 /*mem = ioremap(mem_phys, msize);*/
1107 mem = ioremap(mem_phys, 0x100);
1109 printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1114 dinitprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1116 dinitprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1117 &ioc->facts, &ioc->pfacts[0]));
1119 ioc->mem_phys = mem_phys;
1120 ioc->chip = (SYSIF_REGS __iomem *)mem;
1122 /* Save Port IO values in case we need to do downloadboot */
1124 u8 *pmem = (u8*)port;
1125 ioc->pio_mem_phys = port;
1126 ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1129 if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC909) {
1130 ioc->prod_name = "LSIFC909";
1133 if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
1134 ioc->prod_name = "LSIFC929";
1137 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) {
1138 ioc->prod_name = "LSIFC919";
1141 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) {
1142 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1144 if (revision < XL_929) {
1145 ioc->prod_name = "LSIFC929X";
1146 /* 929X Chip Fix. Set Split transactions level
1147 * for PCIX. Set MOST bits to zero.
1149 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1151 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1153 ioc->prod_name = "LSIFC929XL";
1154 /* 929XL Chip Fix. Set MMRBC to 0x08.
1156 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1158 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1161 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) {
1162 ioc->prod_name = "LSIFC919X";
1164 /* 919X Chip Fix. Set Split transactions level
1165 * for PCIX. Set MOST bits to zero.
1167 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1169 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1171 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
1172 ioc->prod_name = "LSI53C1030";
1173 ioc->bus_type = SCSI;
1174 /* 1030 Chip Fix. Disable Split transactions
1175 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1177 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1178 if (revision < C0_1030) {
1179 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1181 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1184 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
1185 ioc->prod_name = "LSI53C1035";
1186 ioc->bus_type = SCSI;
1189 sprintf(ioc->name, "ioc%d", ioc->id);
1191 spin_lock_init(&ioc->FreeQlock);
1194 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1196 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1198 /* Set lookup ptr. */
1199 list_add_tail(&ioc->list, &ioc_list);
1203 r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc);
1207 printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %d!\n",
1208 ioc->name, pdev->irq);
1210 printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %s!\n",
1211 ioc->name, __irq_itoa(pdev->irq));
1213 list_del(&ioc->list);
1219 ioc->pci_irq = pdev->irq;
1221 pci_set_master(pdev); /* ?? */
1222 pci_set_drvdata(pdev, ioc);
1225 dprintk((KERN_INFO MYNAM ": %s installed at interrupt %d\n", ioc->name, pdev->irq));
1227 dprintk((KERN_INFO MYNAM ": %s installed at interrupt %s\n", ioc->name, __irq_itoa(pdev->irq)));
1231 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1233 mpt_detect_bound_ports(ioc, pdev);
1235 if ((r = mpt_do_ioc_recovery(ioc,
1236 MPT_HOSTEVENT_IOC_BRINGUP, CAN_SLEEP)) != 0) {
1237 printk(KERN_WARNING MYNAM
1238 ": WARNING - %s did not initialize properly! (%d)\n",
1241 list_del(&ioc->list);
1242 free_irq(ioc->pci_irq, ioc);
1245 pci_set_drvdata(pdev, NULL);
1249 /* call per device driver probe entry point */
1250 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1251 if(MptDeviceDriverHandlers[ii] &&
1252 MptDeviceDriverHandlers[ii]->probe) {
1253 MptDeviceDriverHandlers[ii]->probe(pdev,id);
1257 #ifdef CONFIG_PROC_FS
1259 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1261 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1263 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1265 ent->read_proc = procmpt_iocinfo_read;
1268 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1270 ent->read_proc = procmpt_summary_read;
1279 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1281 * mpt_detach - Remove a PCI intelligent MPT adapter.
1282 * @pdev: Pointer to pci_dev structure
1287 mpt_detach(struct pci_dev *pdev)
1289 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1293 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1294 remove_proc_entry(pname, NULL);
1295 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1296 remove_proc_entry(pname, NULL);
1297 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1298 remove_proc_entry(pname, NULL);
1300 /* call per device driver remove entry point */
1301 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1302 if(MptDeviceDriverHandlers[ii] &&
1303 MptDeviceDriverHandlers[ii]->remove) {
1304 MptDeviceDriverHandlers[ii]->remove(pdev);
1308 /* Disable interrupts! */
1309 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1312 synchronize_irq(pdev->irq);
1314 /* Clear any lingering interrupt */
1315 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1317 CHIPREG_READ32(&ioc->chip->IntStatus);
1319 mpt_adapter_dispose(ioc);
1321 pci_set_drvdata(pdev, NULL);
1324 /**************************************************************************
1328 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1330 * mpt_suspend - Fusion MPT base driver suspend routine.
1335 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1338 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1343 device_state=1; /* D1 */;
1347 device_state=3; /* D3 */;
1350 return -EAGAIN /*FIXME*/;
1354 printk(MYIOC_s_INFO_FMT
1355 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1356 ioc->name, pdev, pci_name(pdev), device_state);
1358 pci_save_state(pdev);
1360 /* put ioc into READY_STATE */
1361 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1362 printk(MYIOC_s_ERR_FMT
1363 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1366 /* disable interrupts */
1367 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1370 /* Clear any lingering interrupt */
1371 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1373 pci_disable_device(pdev);
1374 pci_set_power_state(pdev, device_state);
1379 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1381 * mpt_resume - Fusion MPT base driver resume routine.
1386 mpt_resume(struct pci_dev *pdev)
1388 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1389 u32 device_state = pdev->current_state;
1393 printk(MYIOC_s_INFO_FMT
1394 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1395 ioc->name, pdev, pci_name(pdev), device_state);
1397 pci_set_power_state(pdev, 0);
1398 pci_restore_state(pdev);
1399 pci_enable_device(pdev);
1401 /* enable interrupts */
1402 CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
1405 /* F/W not running */
1406 if(!CHIPREG_READ32(&ioc->chip->Doorbell)) {
1407 /* enable domain validation flags */
1408 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
1409 ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_NEED_DV;
1413 printk(MYIOC_s_INFO_FMT
1414 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1416 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1417 CHIPREG_READ32(&ioc->chip->Doorbell));
1419 /* bring ioc to operational state */
1420 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1421 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1422 printk(MYIOC_s_INFO_FMT
1423 "pci-resume: Cannot recover, error:[%x]\n",
1424 ioc->name, recovery_state);
1426 printk(MYIOC_s_INFO_FMT
1427 "pci-resume: success\n", ioc->name);
1434 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1436 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1437 * @ioc: Pointer to MPT adapter structure
1438 * @reason: Event word / reason
1439 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1441 * This routine performs all the steps necessary to bring the IOC
1442 * to a OPERATIONAL state.
1444 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1449 * -1 if failed to get board READY
1450 * -2 if READY but IOCFacts Failed
1451 * -3 if READY but PrimeIOCFifos Failed
1452 * -4 if READY but IOCInit Failed
1455 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1457 int hard_reset_done = 0;
1458 int alt_ioc_ready = 0;
1464 int reset_alt_ioc_active = 0;
1466 printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1467 ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1469 /* Disable reply interrupts (also blocks FreeQ) */
1470 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1474 if (ioc->alt_ioc->active)
1475 reset_alt_ioc_active = 1;
1477 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1478 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1479 ioc->alt_ioc->active = 0;
1483 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1486 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1487 if (hard_reset_done == -4) {
1488 printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1491 if (reset_alt_ioc_active && ioc->alt_ioc) {
1492 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1493 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1494 ioc->alt_ioc->name));
1495 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
1496 ioc->alt_ioc->active = 1;
1500 printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1506 /* hard_reset_done = 0 if a soft reset was performed
1507 * and 1 if a hard reset was performed.
1509 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1510 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1513 printk(KERN_WARNING MYNAM
1514 ": alt-%s: Not ready WARNING!\n",
1515 ioc->alt_ioc->name);
1518 for (ii=0; ii<5; ii++) {
1519 /* Get IOC facts! Allow 5 retries */
1520 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1526 dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1528 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1529 MptDisplayIocCapabilities(ioc);
1532 if (alt_ioc_ready) {
1533 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1534 dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1535 /* Retry - alt IOC was initialized once
1537 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1540 dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1542 reset_alt_ioc_active = 0;
1543 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1544 MptDisplayIocCapabilities(ioc->alt_ioc);
1548 /* Prime reply & request queues!
1549 * (mucho alloc's) Must be done prior to
1550 * init as upper addresses are needed for init.
1551 * If fails, continue with alt-ioc processing
1553 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
1556 /* May need to check/upload firmware & data here!
1557 * If fails, continue with alt-ioc processing
1559 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
1562 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
1563 printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1564 ioc->alt_ioc->name, rc);
1566 reset_alt_ioc_active = 0;
1569 if (alt_ioc_ready) {
1570 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
1572 reset_alt_ioc_active = 0;
1573 printk(KERN_WARNING MYNAM
1574 ": alt-%s: (%d) init failure WARNING!\n",
1575 ioc->alt_ioc->name, rc);
1579 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
1580 if (ioc->upload_fw) {
1581 ddlprintk((MYIOC_s_INFO_FMT
1582 "firmware upload required!\n", ioc->name));
1584 /* Controller is not operational, cannot do upload
1587 rc = mpt_do_upload(ioc, sleepFlag);
1589 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
1595 /* Enable! (reply interrupt) */
1596 CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
1600 if (reset_alt_ioc_active && ioc->alt_ioc) {
1601 /* (re)Enable alt-IOC! (reply interrupt) */
1602 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1603 ioc->alt_ioc->name));
1604 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
1605 ioc->alt_ioc->active = 1;
1608 /* Enable MPT base driver management of EventNotification
1609 * and EventAck handling.
1611 if ((ret == 0) && (!ioc->facts.EventState))
1612 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
1614 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
1615 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
1617 /* Add additional "reason" check before call to GetLanConfigPages
1618 * (combined with GetIoUnitPage2 call). This prevents a somewhat
1619 * recursive scenario; GetLanConfigPages times out, timer expired
1620 * routine calls HardResetHandler, which calls into here again,
1621 * and we try GetLanConfigPages again...
1623 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1624 if (ioc->bus_type == FC) {
1626 * Pre-fetch FC port WWN and stuff...
1627 * (FCPortPage0_t stuff)
1629 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1630 (void) GetFcPortPage0(ioc, ii);
1633 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
1634 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
1636 * Pre-fetch the ports LAN MAC address!
1637 * (LANPage1_t stuff)
1639 (void) GetLanConfigPages(ioc);
1642 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
1643 dprintk((MYIOC_s_INFO_FMT "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
1644 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0] ));
1649 /* Get NVRAM and adapter maximums from SPP 0 and 2
1651 mpt_GetScsiPortSettings(ioc, 0);
1653 /* Get version and length of SDP 1
1655 mpt_readScsiDevicePageHeaders(ioc, 0);
1659 if (ioc->facts.MsgVersion >= 0x0102)
1660 mpt_findImVolumes(ioc);
1662 /* Check, and possibly reset, the coalescing value
1664 mpt_read_ioc_pg_1(ioc);
1666 mpt_read_ioc_pg_4(ioc);
1669 GetIoUnitPage2(ioc);
1673 * Call each currently registered protocol IOC reset handler
1674 * with post-reset indication.
1675 * NOTE: If we're doing _IOC_BRINGUP, there can be no
1676 * MptResetHandlers[] registered yet.
1678 if (hard_reset_done) {
1680 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
1681 if ((ret == 0) && MptResetHandlers[ii]) {
1682 dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
1684 rc += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET);
1688 if (alt_ioc_ready && MptResetHandlers[ii]) {
1689 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
1690 ioc->name, ioc->alt_ioc->name, ii));
1691 rc += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
1695 /* FIXME? Examine results here? */
1701 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1703 * mpt_detect_bound_ports - Search for PCI bus/dev_function
1704 * which matches PCI bus/dev_function (+/-1) for newly discovered 929,
1705 * 929X, 1030 or 1035.
1706 * @ioc: Pointer to MPT adapter structure
1707 * @pdev: Pointer to (struct pci_dev) structure
1709 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
1710 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
1713 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
1715 struct pci_dev *peer=NULL;
1716 unsigned int slot = PCI_SLOT(pdev->devfn);
1717 unsigned int func = PCI_FUNC(pdev->devfn);
1718 MPT_ADAPTER *ioc_srch;
1720 dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x,"
1721 " searching for devfn match on %x or %x\n",
1722 ioc->name, pci_name(pdev), pdev->devfn,
1725 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
1727 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
1732 list_for_each_entry(ioc_srch, &ioc_list, list) {
1733 struct pci_dev *_pcidev = ioc_srch->pcidev;
1734 if (_pcidev == peer) {
1735 /* Paranoia checks */
1736 if (ioc->alt_ioc != NULL) {
1737 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1738 ioc->name, ioc->alt_ioc->name);
1740 } else if (ioc_srch->alt_ioc != NULL) {
1741 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1742 ioc_srch->name, ioc_srch->alt_ioc->name);
1745 dprintk((KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
1746 ioc->name, ioc_srch->name));
1747 ioc_srch->alt_ioc = ioc;
1748 ioc->alt_ioc = ioc_srch;
1754 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1756 * mpt_adapter_disable - Disable misbehaving MPT adapter.
1757 * @this: Pointer to MPT adapter structure
1760 mpt_adapter_disable(MPT_ADAPTER *ioc)
1765 if (ioc->cached_fw != NULL) {
1766 ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
1767 if ((ret = mpt_downloadboot(ioc, NO_SLEEP)) < 0) {
1768 printk(KERN_WARNING MYNAM
1769 ": firmware downloadboot failure (%d)!\n", ret);
1773 /* Disable adapter interrupts! */
1774 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1776 /* Clear any lingering interrupt */
1777 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1779 if (ioc->alloc != NULL) {
1781 dexitprintk((KERN_INFO MYNAM ": %s.free @ %p, sz=%d bytes\n",
1782 ioc->name, ioc->alloc, ioc->alloc_sz));
1783 pci_free_consistent(ioc->pcidev, sz,
1784 ioc->alloc, ioc->alloc_dma);
1785 ioc->reply_frames = NULL;
1786 ioc->req_frames = NULL;
1788 ioc->alloc_total -= sz;
1791 if (ioc->sense_buf_pool != NULL) {
1792 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
1793 pci_free_consistent(ioc->pcidev, sz,
1794 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
1795 ioc->sense_buf_pool = NULL;
1796 ioc->alloc_total -= sz;
1799 if (ioc->events != NULL){
1800 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
1803 ioc->alloc_total -= sz;
1806 if (ioc->cached_fw != NULL) {
1807 sz = ioc->facts.FWImageSize;
1808 pci_free_consistent(ioc->pcidev, sz,
1809 ioc->cached_fw, ioc->cached_fw_dma);
1810 ioc->cached_fw = NULL;
1811 ioc->alloc_total -= sz;
1814 if (ioc->spi_data.nvram != NULL) {
1815 kfree(ioc->spi_data.nvram);
1816 ioc->spi_data.nvram = NULL;
1819 if (ioc->spi_data.pIocPg3 != NULL) {
1820 kfree(ioc->spi_data.pIocPg3);
1821 ioc->spi_data.pIocPg3 = NULL;
1824 if (ioc->spi_data.pIocPg4 != NULL) {
1825 sz = ioc->spi_data.IocPg4Sz;
1826 pci_free_consistent(ioc->pcidev, sz,
1827 ioc->spi_data.pIocPg4,
1828 ioc->spi_data.IocPg4_dma);
1829 ioc->spi_data.pIocPg4 = NULL;
1830 ioc->alloc_total -= sz;
1833 if (ioc->ReqToChain != NULL) {
1834 kfree(ioc->ReqToChain);
1835 kfree(ioc->RequestNB);
1836 ioc->ReqToChain = NULL;
1839 if (ioc->ChainToChain != NULL) {
1840 kfree(ioc->ChainToChain);
1841 ioc->ChainToChain = NULL;
1845 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1847 * mpt_adapter_dispose - Free all resources associated with a MPT
1849 * @ioc: Pointer to MPT adapter structure
1851 * This routine unregisters h/w resources and frees all alloc'd memory
1852 * associated with a MPT adapter structure.
1855 mpt_adapter_dispose(MPT_ADAPTER *ioc)
1858 int sz_first, sz_last;
1860 sz_first = ioc->alloc_total;
1862 mpt_adapter_disable(ioc);
1864 if (ioc->pci_irq != -1) {
1865 free_irq(ioc->pci_irq, ioc);
1869 if (ioc->memmap != NULL)
1870 iounmap(ioc->memmap);
1872 #if defined(CONFIG_MTRR) && 0
1873 if (ioc->mtrr_reg > 0) {
1874 mtrr_del(ioc->mtrr_reg, 0, 0);
1875 dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
1879 /* Zap the adapter lookup ptr! */
1880 list_del(&ioc->list);
1882 sz_last = ioc->alloc_total;
1883 dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
1884 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
1889 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1891 * MptDisplayIocCapabilities - Disply IOC's capacilities.
1892 * @ioc: Pointer to MPT adapter structure
1895 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
1899 printk(KERN_INFO "%s: ", ioc->name);
1900 if (ioc->prod_name && strlen(ioc->prod_name) > 3)
1901 printk("%s: ", ioc->prod_name+3);
1902 printk("Capabilities={");
1904 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
1905 printk("Initiator");
1909 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
1910 printk("%sTarget", i ? "," : "");
1914 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
1915 printk("%sLAN", i ? "," : "");
1921 * This would probably evoke more questions than it's worth
1923 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
1924 printk("%sLogBusAddr", i ? "," : "");
1932 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1934 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
1935 * @ioc: Pointer to MPT_ADAPTER structure
1936 * @force: Force hard KickStart of IOC
1937 * @sleepFlag: Specifies whether the process can sleep
1940 * 1 - DIAG reset and READY
1941 * 0 - READY initially OR soft reset and READY
1942 * -1 - Any failure on KickStart
1943 * -2 - Msg Unit Reset Failed
1944 * -3 - IO Unit Reset Failed
1945 * -4 - IOC owned by a PEER
1948 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
1953 int hard_reset_done = 0;
1958 /* Get current [raw] IOC state */
1959 ioc_state = mpt_GetIocState(ioc, 0);
1960 dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
1963 * Check to see if IOC got left/stuck in doorbell handshake
1964 * grip of death. If so, hard reset the IOC.
1966 if (ioc_state & MPI_DOORBELL_ACTIVE) {
1968 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
1972 /* Is it already READY? */
1973 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
1977 * Check to see if IOC is in FAULT state.
1979 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
1981 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
1983 printk(KERN_WARNING " FAULT code = %04xh\n",
1984 ioc_state & MPI_DOORBELL_DATA_MASK);
1988 * Hmmm... Did it get left operational?
1990 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
1991 dinitprintk((MYIOC_s_WARN_FMT "IOC operational unexpected\n",
1995 * If PCI Peer, exit.
1996 * Else, if no fault conditions are present, issue a MessageUnitReset
1997 * Else, fall through to KickStart case
1999 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2000 dprintk((KERN_WARNING MYNAM
2001 ": whoinit 0x%x\n statefault %d force %d\n",
2002 whoinit, statefault, force));
2003 if (whoinit == MPI_WHOINIT_PCI_PEER)
2006 if ((statefault == 0 ) && (force == 0)) {
2007 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2014 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2015 if (hard_reset_done < 0)
2019 * Loop here waiting for IOC to come READY.
2022 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
2024 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2025 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2027 * BIOS or previous driver load left IOC in OP state.
2028 * Reset messaging FIFOs.
2030 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2031 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2034 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2036 * Something is wrong. Try to get IOC back
2039 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2040 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2047 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2048 ioc->name, (int)((ii+5)/HZ));
2052 if (sleepFlag == CAN_SLEEP) {
2053 msleep_interruptible(1);
2055 mdelay (1); /* 1 msec delay */
2060 if (statefault < 3) {
2061 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2063 statefault==1 ? "stuck handshake" : "IOC FAULT");
2066 return hard_reset_done;
2069 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2071 * mpt_GetIocState - Get the current state of a MPT adapter.
2072 * @ioc: Pointer to MPT_ADAPTER structure
2073 * @cooked: Request raw or cooked IOC state
2075 * Returns all IOC Doorbell register bits if cooked==0, else just the
2076 * Doorbell bits in MPI_IOC_STATE_MASK.
2079 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2084 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2085 // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2086 sc = s & MPI_IOC_STATE_MASK;
2089 ioc->last_state = sc;
2091 return cooked ? sc : s;
2094 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2096 * GetIocFacts - Send IOCFacts request to MPT adapter.
2097 * @ioc: Pointer to MPT_ADAPTER structure
2098 * @sleepFlag: Specifies whether the process can sleep
2099 * @reason: If recovery, only update facts.
2101 * Returns 0 for success, non-zero for failure.
2104 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2106 IOCFacts_t get_facts;
2107 IOCFactsReply_t *facts;
2115 /* IOC *must* NOT be in RESET state! */
2116 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2117 printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2123 facts = &ioc->facts;
2125 /* Destination (reply area)... */
2126 reply_sz = sizeof(*facts);
2127 memset(facts, 0, reply_sz);
2129 /* Request area (get_facts on the stack right now!) */
2130 req_sz = sizeof(get_facts);
2131 memset(&get_facts, 0, req_sz);
2133 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2134 /* Assert: All other get_facts fields are zero! */
2136 dinitprintk((MYIOC_s_INFO_FMT
2137 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2138 ioc->name, req_sz, reply_sz));
2140 /* No non-zero fields in the get_facts request are greater than
2141 * 1 byte in size, so we can just fire it off as is.
2143 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2144 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2149 * Now byte swap (GRRR) the necessary fields before any further
2150 * inspection of reply contents.
2152 * But need to do some sanity checks on MsgLength (byte) field
2153 * to make sure we don't zero IOC's req_sz!
2155 /* Did we get a valid reply? */
2156 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2157 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2159 * If not been here, done that, save off first WhoInit value
2161 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2162 ioc->FirstWhoInit = facts->WhoInit;
2165 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2166 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2167 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2168 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2169 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2170 status = facts->IOCStatus & MPI_IOCSTATUS_MASK;
2171 /* CHECKME! IOCStatus, IOCLogInfo */
2173 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2174 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2177 * FC f/w version changed between 1.1 and 1.2
2178 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2179 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2181 if (facts->MsgVersion < 0x0102) {
2183 * Handle old FC f/w style, convert to new...
2185 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2186 facts->FWVersion.Word =
2187 ((oldv<<12) & 0xFF000000) |
2188 ((oldv<<8) & 0x000FFF00);
2190 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2192 facts->ProductID = le16_to_cpu(facts->ProductID);
2193 facts->CurrentHostMfaHighAddr =
2194 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2195 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2196 facts->CurrentSenseBufferHighAddr =
2197 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2198 facts->CurReplyFrameSize =
2199 le16_to_cpu(facts->CurReplyFrameSize);
2202 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2203 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2204 * to 14 in MPI-1.01.0x.
2206 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2207 facts->MsgVersion > 0x0100) {
2208 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2211 sz = facts->FWImageSize;
2216 facts->FWImageSize = sz;
2218 if (!facts->RequestFrameSize) {
2219 /* Something is wrong! */
2220 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2225 r = sz = facts->BlockSize;
2226 vv = ((63 / (sz * 4)) + 1) & 0x03;
2227 ioc->NB_for_64_byte_frame = vv;
2233 ioc->NBShiftFactor = shiftFactor;
2234 dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2235 ioc->name, vv, shiftFactor, r));
2237 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2239 * Set values for this IOC's request & reply frame sizes,
2240 * and request & reply queue depths...
2242 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2243 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2244 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2245 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2247 dinitprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
2248 ioc->name, ioc->reply_sz, ioc->reply_depth));
2249 dinitprintk((MYIOC_s_INFO_FMT "req_sz =%3d, req_depth =%4d\n",
2250 ioc->name, ioc->req_sz, ioc->req_depth));
2252 /* Get port facts! */
2253 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2257 printk(MYIOC_s_ERR_FMT
2258 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2259 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2260 RequestFrameSize)/sizeof(u32)));
2267 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2269 * GetPortFacts - Send PortFacts request to MPT adapter.
2270 * @ioc: Pointer to MPT_ADAPTER structure
2271 * @portnum: Port number
2272 * @sleepFlag: Specifies whether the process can sleep
2274 * Returns 0 for success, non-zero for failure.
2277 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2279 PortFacts_t get_pfacts;
2280 PortFactsReply_t *pfacts;
2285 /* IOC *must* NOT be in RESET state! */
2286 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2287 printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2293 pfacts = &ioc->pfacts[portnum];
2295 /* Destination (reply area)... */
2296 reply_sz = sizeof(*pfacts);
2297 memset(pfacts, 0, reply_sz);
2299 /* Request area (get_pfacts on the stack right now!) */
2300 req_sz = sizeof(get_pfacts);
2301 memset(&get_pfacts, 0, req_sz);
2303 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2304 get_pfacts.PortNumber = portnum;
2305 /* Assert: All other get_pfacts fields are zero! */
2307 dinitprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
2308 ioc->name, portnum));
2310 /* No non-zero fields in the get_pfacts request are greater than
2311 * 1 byte in size, so we can just fire it off as is.
2313 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2314 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2318 /* Did we get a valid reply? */
2320 /* Now byte swap the necessary fields in the response. */
2321 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2322 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2323 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2324 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2325 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2326 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2327 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2328 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2329 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2334 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2336 * SendIocInit - Send IOCInit request to MPT adapter.
2337 * @ioc: Pointer to MPT_ADAPTER structure
2338 * @sleepFlag: Specifies whether the process can sleep
2340 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2342 * Returns 0 for success, non-zero for failure.
2345 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2348 MPIDefaultReply_t init_reply;
2354 memset(&ioc_init, 0, sizeof(ioc_init));
2355 memset(&init_reply, 0, sizeof(init_reply));
2357 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2358 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2360 /* If we are in a recovery mode and we uploaded the FW image,
2361 * then this pointer is not NULL. Skip the upload a second time.
2362 * Set this flag if cached_fw set for either IOC.
2364 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2368 ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
2369 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2371 if (ioc->bus_type == FC)
2372 ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
2374 ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
2376 ioc_init.MaxBuses = MPT_MAX_BUS;
2378 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2380 if (sizeof(dma_addr_t) == sizeof(u64)) {
2381 /* Save the upper 32-bits of the request
2382 * (reply) and sense buffers.
2384 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2385 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2387 /* Force 32-bit addressing */
2388 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2389 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2392 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2393 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2395 dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
2396 ioc->name, &ioc_init));
2398 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2399 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2403 /* No need to byte swap the multibyte fields in the reply
2404 * since we don't even look at it's contents.
2407 dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
2408 ioc->name, &ioc_init));
2410 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0)
2413 /* YIKES! SUPER IMPORTANT!!!
2414 * Poll IocState until _OPERATIONAL while IOC is doing
2415 * LoopInit and TargetDiscovery!
2418 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2419 state = mpt_GetIocState(ioc, 1);
2420 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2421 if (sleepFlag == CAN_SLEEP) {
2422 msleep_interruptible(1);
2428 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2429 ioc->name, (int)((count+5)/HZ));
2433 state = mpt_GetIocState(ioc, 1);
2436 dhsprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2442 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2444 * SendPortEnable - Send PortEnable request to MPT adapter port.
2445 * @ioc: Pointer to MPT_ADAPTER structure
2446 * @portnum: Port number to enable
2447 * @sleepFlag: Specifies whether the process can sleep
2449 * Send PortEnable to bring IOC to OPERATIONAL state.
2451 * Returns 0 for success, non-zero for failure.
2454 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2456 PortEnable_t port_enable;
2457 MPIDefaultReply_t reply_buf;
2462 /* Destination... */
2463 reply_sz = sizeof(MPIDefaultReply_t);
2464 memset(&reply_buf, 0, reply_sz);
2466 req_sz = sizeof(PortEnable_t);
2467 memset(&port_enable, 0, req_sz);
2469 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2470 port_enable.PortNumber = portnum;
2471 /* port_enable.ChainOffset = 0; */
2472 /* port_enable.MsgFlags = 0; */
2473 /* port_enable.MsgContext = 0; */
2475 dinitprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
2476 ioc->name, portnum, &port_enable));
2478 /* RAID FW may take a long time to enable
2480 if (ioc->bus_type == FC) {
2481 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2482 reply_sz, (u16*)&reply_buf, 65 /*seconds*/, sleepFlag);
2484 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
2485 reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag);
2491 /* We do not even look at the reply, so we need not
2492 * swap the multi-byte fields.
2499 * ioc: Pointer to MPT_ADAPTER structure
2500 * size - total FW bytes
2503 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
2506 return; /* use already allocated memory */
2507 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2508 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
2509 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
2511 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
2512 ioc->alloc_total += size;
2516 * If alt_img is NULL, delete from ioc structure.
2517 * Else, delete a secondary image in same format.
2520 mpt_free_fw_memory(MPT_ADAPTER *ioc)
2524 sz = ioc->facts.FWImageSize;
2525 dinitprintk((KERN_WARNING MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
2526 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2527 pci_free_consistent(ioc->pcidev, sz,
2528 ioc->cached_fw, ioc->cached_fw_dma);
2529 ioc->cached_fw = NULL;
2535 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2537 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
2538 * @ioc: Pointer to MPT_ADAPTER structure
2539 * @sleepFlag: Specifies whether the process can sleep
2541 * Returns 0 for success, >0 for handshake failure
2542 * <0 for fw upload failure.
2544 * Remark: If bound IOC and a successful FWUpload was performed
2545 * on the bound IOC, the second image is discarded
2546 * and memory is free'd. Both channels must upload to prevent
2547 * IOC from running in degraded mode.
2550 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2552 u8 request[ioc->req_sz];
2553 u8 reply[sizeof(FWUploadReply_t)];
2554 FWUpload_t *prequest;
2555 FWUploadReply_t *preply;
2556 FWUploadTCSGE_t *ptcsge;
2559 int ii, sz, reply_sz;
2562 /* If the image size is 0, we are done.
2564 if ((sz = ioc->facts.FWImageSize) == 0)
2567 mpt_alloc_fw_memory(ioc, sz);
2569 dinitprintk((KERN_WARNING MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
2570 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2572 if (ioc->cached_fw == NULL) {
2578 prequest = (FWUpload_t *)&request;
2579 preply = (FWUploadReply_t *)&reply;
2581 /* Destination... */
2582 memset(prequest, 0, ioc->req_sz);
2584 reply_sz = sizeof(reply);
2585 memset(preply, 0, reply_sz);
2587 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
2588 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
2590 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
2591 ptcsge->DetailsLength = 12;
2592 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
2593 ptcsge->ImageSize = cpu_to_le32(sz);
2595 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
2597 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
2598 mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
2600 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
2601 dinitprintk((KERN_WARNING MYNAM "Sending FW Upload (req @ %p) sgeoffset=%d \n",
2602 prequest, sgeoffset));
2603 DBG_DUMP_FW_REQUEST_FRAME(prequest)
2605 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
2606 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
2608 dinitprintk((KERN_WARNING MYNAM "FW Upload completed rc=%x \n", ii));
2610 cmdStatus = -EFAULT;
2612 /* Handshake transfer was complete and successful.
2613 * Check the Reply Frame.
2615 int status, transfer_sz;
2616 status = le16_to_cpu(preply->IOCStatus);
2617 if (status == MPI_IOCSTATUS_SUCCESS) {
2618 transfer_sz = le32_to_cpu(preply->ActualImageSize);
2619 if (transfer_sz == sz)
2623 dinitprintk((MYIOC_s_INFO_FMT ": do_upload status %d \n",
2624 ioc->name, cmdStatus));
2629 ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
2631 mpt_free_fw_memory(ioc);
2637 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2639 * mpt_downloadboot - DownloadBoot code
2640 * @ioc: Pointer to MPT_ADAPTER structure
2641 * @flag: Specify which part of IOC memory is to be uploaded.
2642 * @sleepFlag: Specifies whether the process can sleep
2644 * FwDownloadBoot requires Programmed IO access.
2646 * Returns 0 for success
2647 * -1 FW Image size is 0
2648 * -2 No valid cached_fw Pointer
2649 * <0 for fw upload failure.
2652 mpt_downloadboot(MPT_ADAPTER *ioc, int sleepFlag)
2654 MpiFwHeader_t *pFwHeader;
2655 MpiExtImageHeader_t *pExtImage;
2665 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x, ioc FW Ptr %p\n",
2666 ioc->name, ioc->facts.FWImageSize, ioc->cached_fw));
2668 if ( ioc->facts.FWImageSize == 0 )
2671 if (ioc->cached_fw == NULL)
2674 /* prevent a second downloadboot and memory free with alt_ioc */
2675 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
2676 ioc->alt_ioc->cached_fw = NULL;
2678 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2679 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2680 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2681 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2682 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2683 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2685 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
2688 if (sleepFlag == CAN_SLEEP) {
2689 msleep_interruptible(1);
2694 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2695 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2697 for (count = 0; count < 30; count ++) {
2698 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2699 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
2700 ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
2705 if (sleepFlag == CAN_SLEEP) {
2706 msleep_interruptible (1000);
2712 if ( count == 30 ) {
2713 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! Unable to RESET_ADAPTER diag0val=%x\n",
2714 ioc->name, diag0val));
2718 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2719 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2720 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2721 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2722 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2723 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2725 /* Set the DiagRwEn and Disable ARM bits */
2726 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
2728 pFwHeader = (MpiFwHeader_t *) ioc->cached_fw;
2729 fwSize = (pFwHeader->ImageSize + 3)/4;
2730 ptrFw = (u32 *) pFwHeader;
2732 /* Write the LoadStartAddress to the DiagRw Address Register
2733 * using Programmed IO
2735 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
2736 ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
2737 ioc->name, pFwHeader->LoadStartAddress));
2739 ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n",
2740 ioc->name, fwSize*4, ptrFw));
2742 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2745 nextImage = pFwHeader->NextImageHeaderOffset;
2747 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
2749 load_addr = pExtImage->LoadStartAddress;
2751 fwSize = (pExtImage->ImageSize + 3) >> 2;
2752 ptrFw = (u32 *)pExtImage;
2754 ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x bytes @ %p load_addr=%x\n",
2755 ioc->name, fwSize*4, ptrFw, load_addr));
2756 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
2759 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2761 nextImage = pExtImage->NextImageHeaderOffset;
2764 /* Write the IopResetVectorRegAddr */
2765 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
2766 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
2768 /* Write the IopResetVectorValue */
2769 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
2770 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
2772 /* Clear the internal flash bad bit - autoincrementing register,
2773 * so must do two writes.
2775 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
2776 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
2777 diagRwData |= 0x4000000;
2778 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
2779 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
2781 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2782 ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, turning off PREVENT_IOC_BOOT, DISABLE_ARM\n",
2783 ioc->name, diag0val));
2784 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM);
2785 ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
2786 ioc->name, diag0val));
2787 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
2789 /* Write 0xFF to reset the sequencer */
2790 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2792 for (count=0; count<HZ*20; count++) {
2793 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
2794 ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
2795 ioc->name, count, ioc_state));
2796 if ((SendIocInit(ioc, sleepFlag)) != 0) {
2797 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
2801 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit successful\n",
2805 if (sleepFlag == CAN_SLEEP) {
2806 msleep_interruptible (10);
2811 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! IocState=%x\n",
2812 ioc->name, ioc_state));
2816 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2818 * KickStart - Perform hard reset of MPT adapter.
2819 * @ioc: Pointer to MPT_ADAPTER structure
2820 * @force: Force hard reset
2821 * @sleepFlag: Specifies whether the process can sleep
2823 * This routine places MPT adapter in diagnostic mode via the
2824 * WriteSequence register, and then performs a hard reset of adapter
2825 * via the Diagnostic register.
2827 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
2828 * or NO_SLEEP (interrupt thread, use mdelay)
2829 * force - 1 if doorbell active, board fault state
2830 * board operational, IOC_RECOVERY or
2831 * IOC_BRINGUP and there is an alt_ioc.
2835 * 1 - hard reset, READY
2836 * 0 - no reset due to History bit, READY
2837 * -1 - no reset due to History bit but not READY
2838 * OR reset but failed to come READY
2839 * -2 - no reset, could not enter DIAG mode
2840 * -3 - reset but bad FW bit
2843 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
2845 int hard_reset_done = 0;
2849 dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
2850 if (ioc->bus_type == SCSI) {
2851 /* Always issue a Msg Unit Reset first. This will clear some
2852 * SCSI bus hang conditions.
2854 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
2856 if (sleepFlag == CAN_SLEEP) {
2857 msleep_interruptible (1000);
2863 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
2864 if (hard_reset_done < 0)
2865 return hard_reset_done;
2867 dinitprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
2870 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
2871 for (cnt=0; cnt<cntdn; cnt++) {
2872 ioc_state = mpt_GetIocState(ioc, 1);
2873 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
2874 dinitprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
2876 return hard_reset_done;
2878 if (sleepFlag == CAN_SLEEP) {
2879 msleep_interruptible (10);
2885 printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
2886 ioc->name, ioc_state);
2890 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2892 * mpt_diag_reset - Perform hard reset of the adapter.
2893 * @ioc: Pointer to MPT_ADAPTER structure
2894 * @ignore: Set if to honor and clear to ignore
2895 * the reset history bit
2896 * @sleepflag: CAN_SLEEP if called in a non-interrupt thread,
2897 * else set to NO_SLEEP (use mdelay instead)
2899 * This routine places the adapter in diagnostic mode via the
2900 * WriteSequence register and then performs a hard reset of adapter
2901 * via the Diagnostic register. Adapter should be in ready state
2902 * upon successful completion.
2904 * Returns: 1 hard reset successful
2905 * 0 no reset performed because reset history bit set
2906 * -2 enabling diagnostic mode failed
2907 * -3 diagnostic reset failed
2910 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
2914 int hard_reset_done = 0;
2920 /* Clear any existing interrupts */
2921 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2923 /* Use "Diagnostic reset" method! (only thing available!) */
2924 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2928 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
2929 dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
2930 ioc->name, diag0val, diag1val));
2933 /* Do the reset if we are told to ignore the reset history
2934 * or if the reset history is 0
2936 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
2937 while ((diag0val & MPI_DIAG_DRWE) == 0) {
2938 /* Write magic sequence to WriteSequence register
2939 * Loop until in diagnostic mode
2941 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2942 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2943 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2944 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2945 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2946 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2949 if (sleepFlag == CAN_SLEEP) {
2950 msleep_interruptible (100);
2957 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
2958 ioc->name, diag0val);
2963 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2965 dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
2966 ioc->name, diag0val));
2971 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
2972 dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
2973 ioc->name, diag0val, diag1val));
2976 * Disable the ARM (Bug fix)
2979 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
2983 * Now hit the reset bit in the Diagnostic register
2984 * (THE BIG HAMMER!) (Clears DRWE bit).
2986 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2987 hard_reset_done = 1;
2988 dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
2992 * Call each currently registered protocol IOC reset handler
2993 * with pre-reset indication.
2994 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2995 * MptResetHandlers[] registered yet.
3001 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
3002 if (MptResetHandlers[ii]) {
3003 dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
3005 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_PRE_RESET);
3007 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3008 ioc->name, ioc->alt_ioc->name, ii));
3009 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_PRE_RESET);
3013 /* FIXME? Examine results here? */
3016 if (ioc->cached_fw) {
3017 /* If the DownloadBoot operation fails, the
3018 * IOC will be left unusable. This is a fatal error
3019 * case. _diag_reset will return < 0
3021 for (count = 0; count < 30; count ++) {
3022 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3023 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3028 if (sleepFlag == CAN_SLEEP) {
3034 if ((count = mpt_downloadboot(ioc, sleepFlag)) < 0) {
3035 printk(KERN_WARNING MYNAM
3036 ": firmware downloadboot failure (%d)!\n", count);
3040 /* Wait for FW to reload and for board
3041 * to go to the READY state.
3042 * Maximum wait is 60 seconds.
3043 * If fail, no error will check again
3044 * with calling program.
3046 for (count = 0; count < 60; count ++) {
3047 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3048 doorbell &= MPI_IOC_STATE_MASK;
3050 if (doorbell == MPI_IOC_STATE_READY) {
3055 if (sleepFlag == CAN_SLEEP) {
3056 msleep_interruptible (1000);
3064 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3067 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3068 dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3069 ioc->name, diag0val, diag1val));
3072 /* Clear RESET_HISTORY bit! Place board in the
3073 * diagnostic mode to update the diag register.
3075 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3077 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3078 /* Write magic sequence to WriteSequence register
3079 * Loop until in diagnostic mode
3081 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3082 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3083 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3084 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3085 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3086 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3089 if (sleepFlag == CAN_SLEEP) {
3090 msleep_interruptible (100);
3097 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3098 ioc->name, diag0val);
3101 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3103 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3104 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3105 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3106 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3107 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3111 /* Disable Diagnostic Mode
3113 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3115 /* Check FW reload status flags.
3117 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3118 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3119 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3120 ioc->name, diag0val);
3126 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3127 dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3128 ioc->name, diag0val, diag1val));
3132 * Reset flag that says we've enabled event notification
3134 ioc->facts.EventState = 0;
3137 ioc->alt_ioc->facts.EventState = 0;
3139 return hard_reset_done;
3142 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3144 * SendIocReset - Send IOCReset request to MPT adapter.
3145 * @ioc: Pointer to MPT_ADAPTER structure
3146 * @reset_type: reset type, expected values are
3147 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3149 * Send IOCReset request to the MPT adapter.
3151 * Returns 0 for success, non-zero for failure.
3154 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3160 drsprintk((KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
3161 ioc->name, reset_type));
3162 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3163 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3166 /* FW ACK'd request, wait for READY state
3169 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3171 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3175 if (sleepFlag != CAN_SLEEP)
3178 printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3179 ioc->name, (int)((count+5)/HZ));
3183 if (sleepFlag == CAN_SLEEP) {
3184 msleep_interruptible(1);
3186 mdelay (1); /* 1 msec delay */
3191 * Cleanup all event stuff for this IOC; re-issue EventNotification
3192 * request if needed.
3194 if (ioc->facts.Function)
3195 ioc->facts.EventState = 0;
3200 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3202 * initChainBuffers - Allocate memory for and initialize
3203 * chain buffers, chain buffer control arrays and spinlock.
3204 * @hd: Pointer to MPT_SCSI_HOST structure
3205 * @init: If set, initialize the spin lock.
3208 initChainBuffers(MPT_ADAPTER *ioc)
3211 int sz, ii, num_chain;
3212 int scale, num_sge, numSGE;
3214 /* ReqToChain size must equal the req_depth
3217 if (ioc->ReqToChain == NULL) {
3218 sz = ioc->req_depth * sizeof(int);
3219 mem = kmalloc(sz, GFP_ATOMIC);
3223 ioc->ReqToChain = (int *) mem;
3224 dinitprintk((KERN_INFO MYNAM ": %s ReqToChain alloc @ %p, sz=%d bytes\n",
3225 ioc->name, mem, sz));
3226 mem = kmalloc(sz, GFP_ATOMIC);
3230 ioc->RequestNB = (int *) mem;
3231 dinitprintk((KERN_INFO MYNAM ": %s RequestNB alloc @ %p, sz=%d bytes\n",
3232 ioc->name, mem, sz));
3234 for (ii = 0; ii < ioc->req_depth; ii++) {
3235 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3238 /* ChainToChain size must equal the total number
3239 * of chain buffers to be allocated.
3242 * Calculate the number of chain buffers needed(plus 1) per I/O
3243 * then multiply the the maximum number of simultaneous cmds
3245 * num_sge = num sge in request frame + last chain buffer
3246 * scale = num sge per chain buffer if no chain element
3248 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3249 if (sizeof(dma_addr_t) == sizeof(u64))
3250 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3252 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3254 if (sizeof(dma_addr_t) == sizeof(u64)) {
3255 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3256 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3258 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3259 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3261 dinitprintk((KERN_INFO MYNAM ": %s num_sge=%d numSGE=%d\n",
3262 ioc->name, num_sge, numSGE));
3264 if ( numSGE > MPT_SCSI_SG_DEPTH )
3265 numSGE = MPT_SCSI_SG_DEPTH;
3268 while (numSGE - num_sge > 0) {
3270 num_sge += (scale - 1);
3274 dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
3275 ioc->name, numSGE, num_sge, num_chain));
3277 if (ioc->bus_type == SCSI)
3278 num_chain *= MPT_SCSI_CAN_QUEUE;
3280 num_chain *= MPT_FC_CAN_QUEUE;
3282 ioc->num_chain = num_chain;
3284 sz = num_chain * sizeof(int);
3285 if (ioc->ChainToChain == NULL) {
3286 mem = kmalloc(sz, GFP_ATOMIC);
3290 ioc->ChainToChain = (int *) mem;
3291 dinitprintk((KERN_INFO MYNAM ": %s ChainToChain alloc @ %p, sz=%d bytes\n",
3292 ioc->name, mem, sz));
3294 mem = (u8 *) ioc->ChainToChain;
3296 memset(mem, 0xFF, sz);
3300 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3302 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3303 * @ioc: Pointer to MPT_ADAPTER structure
3305 * This routine allocates memory for the MPT reply and request frame
3306 * pools (if necessary), and primes the IOC reply FIFO with
3309 * Returns 0 for success, non-zero for failure.
3312 PrimeIocFifos(MPT_ADAPTER *ioc)
3315 unsigned long flags;
3316 dma_addr_t alloc_dma;
3318 int i, reply_sz, sz, total_size, num_chain;
3320 /* Prime reply FIFO... */
3322 if (ioc->reply_frames == NULL) {
3323 if ( (num_chain = initChainBuffers(ioc)) < 0)
3326 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3327 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3328 ioc->name, ioc->reply_sz, ioc->reply_depth));
3329 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d[%x] bytes\n",
3330 ioc->name, reply_sz, reply_sz));
3332 sz = (ioc->req_sz * ioc->req_depth);
3333 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3334 ioc->name, ioc->req_sz, ioc->req_depth));
3335 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d[%x] bytes\n",
3336 ioc->name, sz, sz));
3339 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3340 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3341 ioc->name, ioc->req_sz, num_chain));
3342 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3343 ioc->name, sz, sz, num_chain));
3346 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3348 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3353 dinitprintk((KERN_INFO MYNAM ": %s.Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3354 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3356 memset(mem, 0, total_size);
3357 ioc->alloc_total += total_size;
3359 ioc->alloc_dma = alloc_dma;
3360 ioc->alloc_sz = total_size;
3361 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3362 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3364 alloc_dma += reply_sz;
3367 /* Request FIFO - WE manage this! */
3369 ioc->req_frames = (MPT_FRAME_HDR *) mem;
3370 ioc->req_frames_dma = alloc_dma;
3372 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffers @ %p[%p]\n",
3373 ioc->name, mem, (void *)(ulong)alloc_dma));
3375 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3377 #if defined(CONFIG_MTRR) && 0
3379 * Enable Write Combining MTRR for IOC's memory region.
3380 * (at least as much as we can; "size and base must be
3381 * multiples of 4 kiB"
3383 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
3385 MTRR_TYPE_WRCOMB, 1);
3386 dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
3387 ioc->name, ioc->req_frames_dma, sz));
3390 for (i = 0; i < ioc->req_depth; i++) {
3391 alloc_dma += ioc->req_sz;
3395 ioc->ChainBuffer = mem;
3396 ioc->ChainBufferDMA = alloc_dma;
3398 dinitprintk((KERN_INFO MYNAM " :%s.ChainBuffers @ %p(%p)\n",
3399 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
3401 /* Initialize the free chain Q.
3404 INIT_LIST_HEAD(&ioc->FreeChainQ);
3406 /* Post the chain buffers to the FreeChainQ.
3408 mem = (u8 *)ioc->ChainBuffer;
3409 for (i=0; i < num_chain; i++) {
3410 mf = (MPT_FRAME_HDR *) mem;
3411 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
3415 /* Initialize Request frames linked list
3417 alloc_dma = ioc->req_frames_dma;
3418 mem = (u8 *) ioc->req_frames;
3420 spin_lock_irqsave(&ioc->FreeQlock, flags);
3421 INIT_LIST_HEAD(&ioc->FreeQ);
3422 for (i = 0; i < ioc->req_depth; i++) {
3423 mf = (MPT_FRAME_HDR *) mem;
3425 /* Queue REQUESTs *internally*! */
3426 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
3430 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3432 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3433 ioc->sense_buf_pool =
3434 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3435 if (ioc->sense_buf_pool == NULL) {
3436 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
3441 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
3442 ioc->alloc_total += sz;
3443 dinitprintk((KERN_INFO MYNAM ": %s.SenseBuffers @ %p[%p]\n",
3444 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
3448 /* Post Reply frames to FIFO
3450 alloc_dma = ioc->alloc_dma;
3451 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffers @ %p[%p]\n",
3452 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3454 for (i = 0; i < ioc->reply_depth; i++) {
3455 /* Write each address to the IOC! */
3456 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
3457 alloc_dma += ioc->reply_sz;
3463 if (ioc->alloc != NULL) {
3465 pci_free_consistent(ioc->pcidev,
3467 ioc->alloc, ioc->alloc_dma);
3468 ioc->reply_frames = NULL;
3469 ioc->req_frames = NULL;
3470 ioc->alloc_total -= sz;
3472 if (ioc->sense_buf_pool != NULL) {
3473 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3474 pci_free_consistent(ioc->pcidev,
3476 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
3477 ioc->sense_buf_pool = NULL;
3482 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3484 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3485 * from IOC via doorbell handshake method.
3486 * @ioc: Pointer to MPT_ADAPTER structure
3487 * @reqBytes: Size of the request in bytes
3488 * @req: Pointer to MPT request frame
3489 * @replyBytes: Expected size of the reply in bytes
3490 * @u16reply: Pointer to area where reply should be written
3491 * @maxwait: Max wait time for a reply (in seconds)
3492 * @sleepFlag: Specifies whether the process can sleep
3494 * NOTES: It is the callers responsibility to byte-swap fields in the
3495 * request which are greater than 1 byte in size. It is also the
3496 * callers responsibility to byte-swap response fields which are
3497 * greater than 1 byte in size.
3499 * Returns 0 for success, non-zero for failure.
3502 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
3503 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
3505 MPIDefaultReply_t *mptReply;
3510 * Get ready to cache a handshake reply
3512 ioc->hs_reply_idx = 0;
3513 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3514 mptReply->MsgLength = 0;
3517 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
3518 * then tell IOC that we want to handshake a request of N words.
3519 * (WRITE u32val to Doorbell reg).
3521 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3522 CHIPREG_WRITE32(&ioc->chip->Doorbell,
3523 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
3524 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
3527 * Wait for IOC's doorbell handshake int
3529 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3532 dhsprintk((MYIOC_s_INFO_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
3533 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3535 /* Read doorbell and check for active bit */
3536 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
3540 * Clear doorbell int (WRITE 0 to IntStatus reg),
3541 * then wait for IOC to ACKnowledge that it's ready for
3542 * our handshake request.
3544 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3545 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3550 u8 *req_as_bytes = (u8 *) req;
3553 * Stuff request words via doorbell handshake,
3554 * with ACK from IOC for each.
3556 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
3557 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
3558 (req_as_bytes[(ii*4) + 1] << 8) |
3559 (req_as_bytes[(ii*4) + 2] << 16) |
3560 (req_as_bytes[(ii*4) + 3] << 24));
3562 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
3563 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3567 dhsprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
3568 DBG_DUMP_REQUEST_FRAME_HDR(req)
3570 dhsprintk((MYIOC_s_INFO_FMT "HandShake request post done, WaitCnt=%d%s\n",
3571 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
3574 * Wait for completion of doorbell handshake reply from the IOC
3576 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
3579 dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n",
3580 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
3583 * Copy out the cached reply...
3585 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
3586 u16reply[ii] = ioc->hs_reply[ii];
3594 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3596 * WaitForDoorbellAck - Wait for IOC to clear the IOP_DOORBELL_STATUS bit
3597 * in it's IntStatus register.
3598 * @ioc: Pointer to MPT_ADAPTER structure
3599 * @howlong: How long to wait (in seconds)
3600 * @sleepFlag: Specifies whether the process can sleep
3602 * This routine waits (up to ~2 seconds max) for IOC doorbell
3603 * handshake ACKnowledge.
3605 * Returns a negative value on failure, else wait loop count.
3608 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3614 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
3616 if (sleepFlag == CAN_SLEEP) {
3618 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3619 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3621 msleep_interruptible (1);
3626 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3627 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3635 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (count=%d)\n",
3640 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
3641 ioc->name, count, intstat);
3645 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3647 * WaitForDoorbellInt - Wait for IOC to set the HIS_DOORBELL_INTERRUPT bit
3648 * in it's IntStatus register.
3649 * @ioc: Pointer to MPT_ADAPTER structure
3650 * @howlong: How long to wait (in seconds)
3651 * @sleepFlag: Specifies whether the process can sleep
3653 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt.
3655 * Returns a negative value on failure, else wait loop count.
3658 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3664 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * howlong;
3665 if (sleepFlag == CAN_SLEEP) {
3667 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3668 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3670 msleep_interruptible(1);
3675 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3676 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3684 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
3685 ioc->name, count, howlong));
3689 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
3690 ioc->name, count, intstat);
3694 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3696 * WaitForDoorbellReply - Wait for and capture a IOC handshake reply.
3697 * @ioc: Pointer to MPT_ADAPTER structure
3698 * @howlong: How long to wait (in seconds)
3699 * @sleepFlag: Specifies whether the process can sleep
3701 * This routine polls the IOC for a handshake reply, 16 bits at a time.
3702 * Reply is cached to IOC private area large enough to hold a maximum
3703 * of 128 bytes of reply data.
3705 * Returns a negative value on failure, else size of reply in WORDS.
3708 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3713 u16 *hs_reply = ioc->hs_reply;
3714 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3717 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
3720 * Get first two u16's so we can look at IOC's intended reply MsgLength
3723 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
3726 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3727 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3728 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3731 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3732 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3736 dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
3737 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
3738 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3741 * If no error (and IOC said MsgLength is > 0), piece together
3742 * reply 16 bits at a time.
3744 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
3745 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3747 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3748 /* don't overflow our IOC hs_reply[] buffer! */
3749 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
3750 hs_reply[u16cnt] = hword;
3751 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3754 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3756 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3759 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
3764 else if (u16cnt != (2 * mptReply->MsgLength)) {
3767 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
3772 dhsprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
3773 DBG_DUMP_REPLY_FRAME(mptReply)
3775 dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
3776 ioc->name, t, u16cnt/2));
3780 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3782 * GetLanConfigPages - Fetch LANConfig pages.
3783 * @ioc: Pointer to MPT_ADAPTER structure
3785 * Return: 0 for success
3786 * -ENOMEM if no memory available
3787 * -EPERM if not allowed due to ISR context
3788 * -EAGAIN if no msg frames currently available
3789 * -EFAULT for non-successful reply or no reply (timeout)
3792 GetLanConfigPages(MPT_ADAPTER *ioc)
3794 ConfigPageHeader_t hdr;
3796 LANPage0_t *ppage0_alloc;
3797 dma_addr_t page0_dma;
3798 LANPage1_t *ppage1_alloc;
3799 dma_addr_t page1_dma;
3804 /* Get LAN Page 0 header */
3805 hdr.PageVersion = 0;
3808 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
3811 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
3816 if ((rc = mpt_config(ioc, &cfg)) != 0)
3819 if (hdr.PageLength > 0) {
3820 data_sz = hdr.PageLength * 4;
3821 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
3824 memset((u8 *)ppage0_alloc, 0, data_sz);
3825 cfg.physAddr = page0_dma;
3826 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
3828 if ((rc = mpt_config(ioc, &cfg)) == 0) {
3830 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
3831 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
3835 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
3838 * Normalize endianness of structure data,
3839 * by byte-swapping all > 1 byte fields!
3848 /* Get LAN Page 1 header */
3849 hdr.PageVersion = 0;
3852 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
3855 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
3859 if ((rc = mpt_config(ioc, &cfg)) != 0)
3862 if (hdr.PageLength == 0)
3865 data_sz = hdr.PageLength * 4;
3867 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
3869 memset((u8 *)ppage1_alloc, 0, data_sz);
3870 cfg.physAddr = page1_dma;
3871 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
3873 if ((rc = mpt_config(ioc, &cfg)) == 0) {
3875 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
3876 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
3879 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
3882 * Normalize endianness of structure data,
3883 * by byte-swapping all > 1 byte fields!
3891 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3893 * GetFcPortPage0 - Fetch FCPort config Page0.
3894 * @ioc: Pointer to MPT_ADAPTER structure
3895 * @portnum: IOC Port number
3897 * Return: 0 for success
3898 * -ENOMEM if no memory available
3899 * -EPERM if not allowed due to ISR context
3900 * -EAGAIN if no msg frames currently available
3901 * -EFAULT for non-successful reply or no reply (timeout)
3904 GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
3906 ConfigPageHeader_t hdr;
3908 FCPortPage0_t *ppage0_alloc;
3909 FCPortPage0_t *pp0dest;
3910 dma_addr_t page0_dma;
3915 /* Get FCPort Page 0 header */
3916 hdr.PageVersion = 0;
3919 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
3922 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
3924 cfg.pageAddr = portnum;
3927 if ((rc = mpt_config(ioc, &cfg)) != 0)
3930 if (hdr.PageLength == 0)
3933 data_sz = hdr.PageLength * 4;
3935 ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
3937 memset((u8 *)ppage0_alloc, 0, data_sz);
3938 cfg.physAddr = page0_dma;
3939 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
3941 if ((rc = mpt_config(ioc, &cfg)) == 0) {
3943 pp0dest = &ioc->fc_port_page0[portnum];
3944 copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
3945 memcpy(pp0dest, ppage0_alloc, copy_sz);
3948 * Normalize endianness of structure data,
3949 * by byte-swapping all > 1 byte fields!
3951 pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
3952 pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
3953 pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
3954 pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
3955 pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
3956 pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
3957 pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
3958 pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
3959 pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
3960 pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
3961 pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
3962 pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
3963 pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
3964 pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
3965 pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
3966 pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
3970 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
3976 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3978 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
3979 * @ioc: Pointer to MPT_ADAPTER structure
3981 * Returns: 0 for success
3982 * -ENOMEM if no memory available
3983 * -EPERM if not allowed due to ISR context
3984 * -EAGAIN if no msg frames currently available
3985 * -EFAULT for non-successful reply or no reply (timeout)
3988 GetIoUnitPage2(MPT_ADAPTER *ioc)
3990 ConfigPageHeader_t hdr;
3992 IOUnitPage2_t *ppage_alloc;
3993 dma_addr_t page_dma;
3997 /* Get the page header */
3998 hdr.PageVersion = 0;
4001 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4004 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4009 if ((rc = mpt_config(ioc, &cfg)) != 0)
4012 if (hdr.PageLength == 0)
4015 /* Read the config page */
4016 data_sz = hdr.PageLength * 4;
4018 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4020 memset((u8 *)ppage_alloc, 0, data_sz);
4021 cfg.physAddr = page_dma;
4022 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4024 /* If Good, save data */
4025 if ((rc = mpt_config(ioc, &cfg)) == 0)
4026 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4028 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4034 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4035 /* mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4036 * @ioc: Pointer to a Adapter Strucutre
4037 * @portnum: IOC port number
4039 * Return: -EFAULT if read of config page header fails
4041 * If read of SCSI Port Page 0 fails,
4042 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4043 * Adapter settings: async, narrow
4045 * If read of SCSI Port Page 2 fails,
4046 * Adapter settings valid
4047 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4052 * CHECK - what type of locking mechanisms should be used????
4055 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4060 ConfigPageHeader_t header;
4066 if (!ioc->spi_data.nvram) {
4069 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4070 mem = kmalloc(sz, GFP_ATOMIC);
4074 ioc->spi_data.nvram = (int *) mem;
4076 dprintk((MYIOC_s_INFO_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4077 ioc->name, ioc->spi_data.nvram, sz));
4080 /* Invalidate NVRAM information
4082 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4083 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4086 /* Read SPP0 header, allocate memory, then read page.
4088 header.PageVersion = 0;
4089 header.PageLength = 0;
4090 header.PageNumber = 0;
4091 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4094 cfg.pageAddr = portnum;
4095 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4097 cfg.timeout = 0; /* use default */
4098 if (mpt_config(ioc, &cfg) != 0)
4101 if (header.PageLength > 0) {
4102 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4104 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4105 cfg.physAddr = buf_dma;
4106 if (mpt_config(ioc, &cfg) != 0) {
4107 ioc->spi_data.maxBusWidth = MPT_NARROW;
4108 ioc->spi_data.maxSyncOffset = 0;
4109 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4110 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4113 /* Save the Port Page 0 data
4115 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4116 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4117 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4119 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4120 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4121 dinitprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
4122 ioc->name, pPP0->Capabilities));
4124 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4125 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4127 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4128 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4129 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4131 ioc->spi_data.maxSyncOffset = 0;
4132 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4135 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4137 /* Update the minSyncFactor based on bus type.
4139 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4140 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4142 if (ioc->spi_data.minSyncFactor < MPT_ULTRA)
4143 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4147 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4152 /* SCSI Port Page 2 - Read the header then the page.
4154 header.PageVersion = 0;
4155 header.PageLength = 0;
4156 header.PageNumber = 2;
4157 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4160 cfg.pageAddr = portnum;
4161 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4163 if (mpt_config(ioc, &cfg) != 0)
4166 if (header.PageLength > 0) {
4167 /* Allocate memory and read SCSI Port Page 2
4169 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4171 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4172 cfg.physAddr = buf_dma;
4173 if (mpt_config(ioc, &cfg) != 0) {
4174 /* Nvram data is left with INVALID mark
4178 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4179 MpiDeviceInfo_t *pdevice = NULL;
4181 /* Save the Port Page 2 data
4182 * (reformat into a 32bit quantity)
4184 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4185 ioc->spi_data.PortFlags = data;
4186 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4187 pdevice = &pPP2->DeviceSettings[ii];
4188 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4189 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4190 ioc->spi_data.nvram[ii] = data;
4194 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4198 /* Update Adapter limits with those from NVRAM
4199 * Comment: Don't need to do this. Target performance
4200 * parameters will never exceed the adapters limits.
4206 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4207 /* mpt_readScsiDevicePageHeaders - save version and length of SDP1
4208 * @ioc: Pointer to a Adapter Strucutre
4209 * @portnum: IOC port number
4211 * Return: -EFAULT if read of config page header fails
4215 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4218 ConfigPageHeader_t header;
4220 /* Read the SCSI Device Page 1 header
4222 header.PageVersion = 0;
4223 header.PageLength = 0;
4224 header.PageNumber = 1;
4225 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4228 cfg.pageAddr = portnum;
4229 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4232 if (mpt_config(ioc, &cfg) != 0)
4235 ioc->spi_data.sdp1version = cfg.hdr->PageVersion;
4236 ioc->spi_data.sdp1length = cfg.hdr->PageLength;
4238 header.PageVersion = 0;
4239 header.PageLength = 0;
4240 header.PageNumber = 0;
4241 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4242 if (mpt_config(ioc, &cfg) != 0)
4245 ioc->spi_data.sdp0version = cfg.hdr->PageVersion;
4246 ioc->spi_data.sdp0length = cfg.hdr->PageLength;
4248 dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
4249 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
4251 dcprintk((MYIOC_s_INFO_FMT "Headers: 1: version %d length %d\n",
4252 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
4256 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4258 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4259 * @ioc: Pointer to a Adapter Strucutre
4260 * @portnum: IOC port number
4264 * -EFAULT if read of config page header fails or data pointer not NULL
4265 * -ENOMEM if pci_alloc failed
4268 mpt_findImVolumes(MPT_ADAPTER *ioc)
4272 ConfigPageIoc2RaidVol_t *pIocRv;
4273 dma_addr_t ioc2_dma;
4275 ConfigPageHeader_t header;
4282 /* Read IOCP2 header then the page.
4284 header.PageVersion = 0;
4285 header.PageLength = 0;
4286 header.PageNumber = 2;
4287 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4291 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4294 if (mpt_config(ioc, &cfg) != 0)
4297 if (header.PageLength == 0)
4300 iocpage2sz = header.PageLength * 4;
4301 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
4305 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4306 cfg.physAddr = ioc2_dma;
4307 if (mpt_config(ioc, &cfg) != 0)
4310 if ( (mem = (u8 *)ioc->spi_data.pIocPg2) == NULL ) {
4311 mem = kmalloc(iocpage2sz, GFP_ATOMIC);
4313 ioc->spi_data.pIocPg2 = (IOCPage2_t *) mem;
4318 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
4320 /* Identify RAID Volume Id's */
4321 nVols = pIoc2->NumActiveVolumes;
4327 /* At least 1 RAID Volume
4329 pIocRv = pIoc2->RaidVolume;
4330 ioc->spi_data.isRaid = 0;
4331 for (jj = 0; jj < nVols; jj++, pIocRv++) {
4332 vid = pIocRv->VolumeID;
4333 vbus = pIocRv->VolumeBus;
4334 vioc = pIocRv->VolumeIOC;
4339 ioc->spi_data.isRaid |= (1 << vid);
4341 /* Error! Always bus 0
4347 /* Identify Hidden Physical Disk Id's */
4348 nPhys = pIoc2->NumActivePhysDisks;
4350 /* No physical disks.
4353 mpt_read_ioc_pg_3(ioc);
4357 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
4363 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
4368 ConfigPageHeader_t header;
4369 dma_addr_t ioc3_dma;
4372 /* Free the old page
4374 if (ioc->spi_data.pIocPg3) {
4375 kfree(ioc->spi_data.pIocPg3);
4376 ioc->spi_data.pIocPg3 = NULL;
4379 /* There is at least one physical disk.
4380 * Read and save IOC Page 3
4382 header.PageVersion = 0;
4383 header.PageLength = 0;
4384 header.PageNumber = 3;
4385 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4389 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4392 if (mpt_config(ioc, &cfg) != 0)
4395 if (header.PageLength == 0)
4398 /* Read Header good, alloc memory
4400 iocpage3sz = header.PageLength * 4;
4401 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
4405 /* Read the Page and save the data
4406 * into malloc'd memory.
4408 cfg.physAddr = ioc3_dma;
4409 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4410 if (mpt_config(ioc, &cfg) == 0) {
4411 mem = kmalloc(iocpage3sz, GFP_ATOMIC);
4413 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
4414 ioc->spi_data.pIocPg3 = (IOCPage3_t *) mem;
4418 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
4424 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
4428 ConfigPageHeader_t header;
4429 dma_addr_t ioc4_dma;
4432 /* Read and save IOC Page 4
4434 header.PageVersion = 0;
4435 header.PageLength = 0;
4436 header.PageNumber = 4;
4437 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4441 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4444 if (mpt_config(ioc, &cfg) != 0)
4447 if (header.PageLength == 0)
4450 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
4451 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
4452 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
4456 ioc4_dma = ioc->spi_data.IocPg4_dma;
4457 iocpage4sz = ioc->spi_data.IocPg4Sz;
4460 /* Read the Page into dma memory.
4462 cfg.physAddr = ioc4_dma;
4463 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4464 if (mpt_config(ioc, &cfg) == 0) {
4465 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
4466 ioc->spi_data.IocPg4_dma = ioc4_dma;
4467 ioc->spi_data.IocPg4Sz = iocpage4sz;
4469 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
4470 ioc->spi_data.pIocPg4 = NULL;
4475 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
4479 ConfigPageHeader_t header;
4480 dma_addr_t ioc1_dma;
4484 /* Check the Coalescing Timeout in IOC Page 1
4486 header.PageVersion = 0;
4487 header.PageLength = 0;
4488 header.PageNumber = 1;
4489 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4493 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4496 if (mpt_config(ioc, &cfg) != 0)
4499 if (header.PageLength == 0)
4502 /* Read Header good, alloc memory
4504 iocpage1sz = header.PageLength * 4;
4505 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
4509 /* Read the Page and check coalescing timeout
4511 cfg.physAddr = ioc1_dma;
4512 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4513 if (mpt_config(ioc, &cfg) == 0) {
4515 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
4516 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
4517 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
4519 dprintk((MYIOC_s_INFO_FMT "Coalescing Enabled Timeout = %d\n",
4522 if (tmp > MPT_COALESCING_TIMEOUT) {
4523 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
4525 /* Write NVRAM and current
4528 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4529 if (mpt_config(ioc, &cfg) == 0) {
4530 dprintk((MYIOC_s_INFO_FMT "Reset Current Coalescing Timeout to = %d\n",
4531 ioc->name, MPT_COALESCING_TIMEOUT));
4533 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
4534 if (mpt_config(ioc, &cfg) == 0) {
4535 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout to = %d\n",
4536 ioc->name, MPT_COALESCING_TIMEOUT));
4538 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout Failed\n",
4543 dprintk((MYIOC_s_WARN_FMT "Reset of Current Coalescing Timeout Failed!\n",
4549 dprintk((MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
4553 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
4558 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4560 * SendEventNotification - Send EventNotification (on or off) request
4562 * @ioc: Pointer to MPT_ADAPTER structure
4563 * @EvSwitch: Event switch flags
4566 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
4568 EventNotification_t *evnp;
4570 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
4572 dprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
4576 memset(evnp, 0, sizeof(*evnp));
4578 dprintk((MYIOC_s_INFO_FMT "Sending EventNotification(%d)\n", ioc->name, EvSwitch));
4580 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
4581 evnp->ChainOffset = 0;
4583 evnp->Switch = EvSwitch;
4585 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
4590 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4592 * SendEventAck - Send EventAck request to MPT adapter.
4593 * @ioc: Pointer to MPT_ADAPTER structure
4594 * @evnp: Pointer to original EventNotification request
4597 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
4601 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4602 printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK request frame!\n",
4606 memset(pAck, 0, sizeof(*pAck));
4608 dprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
4610 pAck->Function = MPI_FUNCTION_EVENT_ACK;
4611 pAck->ChainOffset = 0;
4613 pAck->Event = evnp->Event;
4614 pAck->EventContext = evnp->EventContext;
4616 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
4621 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4623 * mpt_config - Generic function to issue config message
4624 * @ioc - Pointer to an adapter structure
4625 * @cfg - Pointer to a configuration structure. Struct contains
4626 * action, page address, direction, physical address
4627 * and pointer to a configuration page header
4628 * Page header is updated.
4630 * Returns 0 for success
4631 * -EPERM if not allowed due to ISR context
4632 * -EAGAIN if no msg frames currently available
4633 * -EFAULT for non-successful reply or no reply (timeout)
4636 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
4640 unsigned long flags;
4645 /* Prevent calling wait_event() (below), if caller happens
4646 * to be in ISR context, because that is fatal!
4648 in_isr = in_interrupt();
4650 dcprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
4655 /* Get and Populate a free Frame
4657 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4658 dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
4662 pReq = (Config_t *)mf;
4663 pReq->Action = pCfg->action;
4665 pReq->ChainOffset = 0;
4666 pReq->Function = MPI_FUNCTION_CONFIG;
4667 pReq->ExtPageLength = 0;
4668 pReq->ExtPageType = 0;
4670 for (ii=0; ii < 8; ii++)
4671 pReq->Reserved2[ii] = 0;
4673 pReq->Header.PageVersion = pCfg->hdr->PageVersion;
4674 pReq->Header.PageLength = pCfg->hdr->PageLength;
4675 pReq->Header.PageNumber = pCfg->hdr->PageNumber;
4676 pReq->Header.PageType = (pCfg->hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
4677 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
4679 /* Add a SGE to the config request.
4682 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
4684 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
4686 flagsLength |= pCfg->hdr->PageLength * 4;
4688 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
4690 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
4691 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
4693 /* Append pCfg pointer to end of mf
4695 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
4697 /* Initalize the timer
4699 init_timer(&pCfg->timer);
4700 pCfg->timer.data = (unsigned long) ioc;
4701 pCfg->timer.function = mpt_timer_expired;
4702 pCfg->wait_done = 0;
4704 /* Set the timer; ensure 10 second minimum */
4705 if (pCfg->timeout < 10)
4706 pCfg->timer.expires = jiffies + HZ*10;
4708 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
4710 /* Add to end of Q, set timer and then issue this command */
4711 spin_lock_irqsave(&ioc->FreeQlock, flags);
4712 list_add_tail(&pCfg->linkage, &ioc->configQ);
4713 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4715 add_timer(&pCfg->timer);
4716 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4717 wait_event(mpt_waitq, pCfg->wait_done);
4719 /* mf has been freed - do not access */
4726 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4728 * mpt_toolbox - Generic function to issue toolbox message
4729 * @ioc - Pointer to an adapter structure
4730 * @cfg - Pointer to a toolbox structure. Struct contains
4731 * action, page address, direction, physical address
4732 * and pointer to a configuration page header
4733 * Page header is updated.
4735 * Returns 0 for success
4736 * -EPERM if not allowed due to ISR context
4737 * -EAGAIN if no msg frames currently available
4738 * -EFAULT for non-successful reply or no reply (timeout)
4741 mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
4743 ToolboxIstwiReadWriteRequest_t *pReq;
4745 struct pci_dev *pdev;
4746 unsigned long flags;
4751 /* Prevent calling wait_event() (below), if caller happens
4752 * to be in ISR context, because that is fatal!
4754 in_isr = in_interrupt();
4756 dcprintk((MYIOC_s_WARN_FMT "toobox request not allowed in ISR context!\n",
4761 /* Get and Populate a free Frame
4763 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4764 dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n",
4768 pReq = (ToolboxIstwiReadWriteRequest_t *)mf;
4769 pReq->Tool = pCfg->action;
4771 pReq->ChainOffset = 0;
4772 pReq->Function = MPI_FUNCTION_TOOLBOX;
4773 pReq->Reserved1 = 0;
4774 pReq->Reserved2 = 0;
4776 pReq->Flags = pCfg->dir;
4778 pReq->Reserved3 = 0;
4779 pReq->NumAddressBytes = 0x01;
4780 pReq->Reserved4 = 0;
4781 pReq->DataLength = 0x04;
4782 pdev = (struct pci_dev *) ioc->pcidev;
4783 if (pdev->devfn & 1)
4784 pReq->DeviceAddr = 0xB2;
4786 pReq->DeviceAddr = 0xB0;
4790 pReq->Reserved5 = 0;
4792 /* Add a SGE to the config request.
4795 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | 4;
4797 mpt_add_sge((char *)&pReq->SGL, flagsLength, pCfg->physAddr);
4799 dcprintk((MYIOC_s_INFO_FMT "Sending Toolbox request, Tool=%x\n",
4800 ioc->name, pReq->Tool));
4802 /* Append pCfg pointer to end of mf
4804 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
4806 /* Initalize the timer
4808 init_timer(&pCfg->timer);
4809 pCfg->timer.data = (unsigned long) ioc;
4810 pCfg->timer.function = mpt_timer_expired;
4811 pCfg->wait_done = 0;
4813 /* Set the timer; ensure 10 second minimum */
4814 if (pCfg->timeout < 10)
4815 pCfg->timer.expires = jiffies + HZ*10;
4817 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
4819 /* Add to end of Q, set timer and then issue this command */
4820 spin_lock_irqsave(&ioc->FreeQlock, flags);
4821 list_add_tail(&pCfg->linkage, &ioc->configQ);
4822 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4824 add_timer(&pCfg->timer);
4825 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4826 wait_event(mpt_waitq, pCfg->wait_done);
4828 /* mf has been freed - do not access */
4835 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4837 * mpt_timer_expired - Call back for timer process.
4838 * Used only internal config functionality.
4839 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
4842 mpt_timer_expired(unsigned long data)
4844 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
4846 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name));
4848 /* Perform a FW reload */
4849 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
4850 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
4852 /* No more processing.
4853 * Hard reset clean-up will wake up
4854 * process and free all resources.
4856 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name));
4861 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4863 * mpt_ioc_reset - Base cleanup for hard reset
4864 * @ioc: Pointer to the adapter structure
4865 * @reset_phase: Indicates pre- or post-reset functionality
4867 * Remark: Free's resources with internally generated commands.
4870 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
4873 unsigned long flags;
4875 dprintk((KERN_WARNING MYNAM
4876 ": IOC %s_reset routed to MPT base driver!\n",
4877 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
4878 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
4880 if (reset_phase == MPT_IOC_SETUP_RESET) {
4882 } else if (reset_phase == MPT_IOC_PRE_RESET) {
4883 /* If the internal config Q is not empty -
4884 * delete timer. MF resources will be freed when
4885 * the FIFO's are primed.
4887 spin_lock_irqsave(&ioc->FreeQlock, flags);
4888 list_for_each_entry(pCfg, &ioc->configQ, linkage)
4889 del_timer(&pCfg->timer);
4890 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4895 /* Search the configQ for internal commands.
4896 * Flush the Q, and wake up all suspended threads.
4898 spin_lock_irqsave(&ioc->FreeQlock, flags);
4899 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
4900 list_del(&pCfg->linkage);
4902 pCfg->status = MPT_CONFIG_ERROR;
4903 pCfg->wait_done = 1;
4904 wake_up(&mpt_waitq);
4906 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4909 return 1; /* currently means nothing really */
4913 #ifdef CONFIG_PROC_FS /* { */
4914 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4916 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
4918 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4920 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
4922 * Returns 0 for success, non-zero for failure.
4925 procmpt_create(void)
4927 struct proc_dir_entry *ent;
4929 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
4930 if (mpt_proc_root_dir == NULL)
4933 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
4935 ent->read_proc = procmpt_summary_read;
4937 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
4939 ent->read_proc = procmpt_version_read;
4944 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4946 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
4948 * Returns 0 for success, non-zero for failure.
4951 procmpt_destroy(void)
4953 remove_proc_entry("version", mpt_proc_root_dir);
4954 remove_proc_entry("summary", mpt_proc_root_dir);
4955 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
4958 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4960 * procmpt_summary_read - Handle read request from /proc/mpt/summary
4961 * or from /proc/mpt/iocN/summary.
4962 * @buf: Pointer to area to write information
4963 * @start: Pointer to start pointer
4964 * @offset: Offset to start writing
4966 * @eof: Pointer to EOF integer
4969 * Returns number of characters written to process performing the read.
4972 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
4982 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
4986 list_for_each_entry(ioc, &ioc_list, list) {
4989 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
4992 if ((out-buf) >= request)
4999 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5002 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5004 * procmpt_version_read - Handle read request from /proc/mpt/version.
5005 * @buf: Pointer to area to write information
5006 * @start: Pointer to start pointer
5007 * @offset: Offset to start writing
5009 * @eof: Pointer to EOF integer
5012 * Returns number of characters written to process performing the read.
5015 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5018 int scsi, fc, sas, lan, ctl, targ, dmp;
5022 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5023 len += sprintf(buf+len, " Fusion MPT base driver\n");
5025 scsi = fc = sas = lan = ctl = targ = dmp = 0;
5026 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5028 if (MptCallbacks[ii]) {
5029 switch (MptDriverClass[ii]) {
5031 if (!scsi++) drvname = "SPI host";
5034 if (!fc++) drvname = "FC host";
5037 if (!sas++) drvname = "SAS host";
5040 if (!lan++) drvname = "LAN";
5043 if (!targ++) drvname = "SCSI target";
5046 if (!ctl++) drvname = "ioctl";
5051 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5055 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5058 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5060 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5061 * @buf: Pointer to area to write information
5062 * @start: Pointer to start pointer
5063 * @offset: Offset to start writing
5065 * @eof: Pointer to EOF integer
5068 * Returns number of characters written to process performing the read.
5071 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5073 MPT_ADAPTER *ioc = data;
5079 mpt_get_fw_exp_ver(expVer, ioc);
5081 len = sprintf(buf, "%s:", ioc->name);
5082 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5083 len += sprintf(buf+len, " (f/w download boot flag set)");
5084 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5085 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5087 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
5088 ioc->facts.ProductID,
5090 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5091 if (ioc->facts.FWImageSize)
5092 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5093 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5094 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5095 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
5097 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
5098 ioc->facts.CurrentHostMfaHighAddr);
5099 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
5100 ioc->facts.CurrentSenseBufferHighAddr);
5102 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5103 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5105 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5106 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
5108 * Rounding UP to nearest 4-kB boundary here...
5110 sz = (ioc->req_sz * ioc->req_depth) + 128;
5111 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5112 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5113 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5114 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
5115 4*ioc->facts.RequestFrameSize,
5116 ioc->facts.GlobalCredits);
5118 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
5119 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
5120 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5121 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5122 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5123 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
5124 ioc->facts.CurReplyFrameSize,
5125 ioc->facts.ReplyQueueDepth);
5127 len += sprintf(buf+len, " MaxDevices = %d\n",
5128 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5129 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
5132 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5133 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
5135 ioc->facts.NumberOfPorts);
5136 if (ioc->bus_type == FC) {
5137 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5138 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5139 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5140 a[5], a[4], a[3], a[2], a[1], a[0]);
5142 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
5143 ioc->fc_port_page0[p].WWNN.High,
5144 ioc->fc_port_page0[p].WWNN.Low,
5145 ioc->fc_port_page0[p].WWPN.High,
5146 ioc->fc_port_page0[p].WWPN.Low);
5150 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5153 #endif /* CONFIG_PROC_FS } */
5155 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5157 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
5160 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
5161 sprintf(buf, " (Exp %02d%02d)",
5162 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
5163 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
5166 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
5167 strcat(buf, " [MDBG]");
5171 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5173 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5174 * @ioc: Pointer to MPT_ADAPTER structure
5175 * @buffer: Pointer to buffer where IOC summary info should be written
5176 * @size: Pointer to number of bytes we wrote (set by this routine)
5177 * @len: Offset at which to start writing in buffer
5178 * @showlan: Display LAN stuff?
5180 * This routine writes (english readable) ASCII text, which represents
5181 * a summary of IOC information, to a buffer.
5184 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
5189 mpt_get_fw_exp_ver(expVer, ioc);
5192 * Shorter summary of attached ioc's...
5194 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
5197 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
5198 ioc->facts.FWVersion.Word,
5200 ioc->facts.NumberOfPorts,
5203 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
5204 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5205 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
5206 a[5], a[4], a[3], a[2], a[1], a[0]);
5210 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
5212 y += sprintf(buffer+len+y, ", IRQ=%s", __irq_itoa(ioc->pci_irq));
5216 y += sprintf(buffer+len+y, " (disabled)");
5218 y += sprintf(buffer+len+y, "\n");
5223 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5227 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5229 * mpt_HardResetHandler - Generic reset handler, issue SCSI Task
5230 * Management call based on input arg values. If TaskMgmt fails,
5231 * return associated SCSI request.
5232 * @ioc: Pointer to MPT_ADAPTER structure
5233 * @sleepFlag: Indicates if sleep or schedule must be called.
5235 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
5236 * or a non-interrupt thread. In the former, must not call schedule().
5238 * Remark: A return of -1 is a FATAL error case, as it means a
5239 * FW reload/initialization failed.
5241 * Returns 0 for SUCCESS or -1 if FAILED.
5244 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5247 unsigned long flags;
5249 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
5251 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
5252 printk("MF count 0x%x !\n", ioc->mfcnt);
5255 /* Reset the adapter. Prevent more than 1 call to
5256 * mpt_do_ioc_recovery at any instant in time.
5258 spin_lock_irqsave(&ioc->diagLock, flags);
5259 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
5260 spin_unlock_irqrestore(&ioc->diagLock, flags);
5263 ioc->diagPending = 1;
5265 spin_unlock_irqrestore(&ioc->diagLock, flags);
5267 /* FIXME: If do_ioc_recovery fails, repeat....
5270 /* The SCSI driver needs to adjust timeouts on all current
5271 * commands prior to the diagnostic reset being issued.
5272 * Prevents timeouts occuring during a diagnostic reset...very bad.
5273 * For all other protocol drivers, this is a no-op.
5279 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5280 if (MptResetHandlers[ii]) {
5281 dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
5283 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_SETUP_RESET);
5285 dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
5286 ioc->name, ioc->alt_ioc->name, ii));
5287 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_SETUP_RESET);
5293 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
5294 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
5299 ioc->alt_ioc->reload_fw = 0;
5301 spin_lock_irqsave(&ioc->diagLock, flags);
5302 ioc->diagPending = 0;
5304 ioc->alt_ioc->diagPending = 0;
5305 spin_unlock_irqrestore(&ioc->diagLock, flags);
5307 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
5312 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5314 EventDescriptionStr(u8 event, u32 evData0)
5319 case MPI_EVENT_NONE:
5322 case MPI_EVENT_LOG_DATA:
5325 case MPI_EVENT_STATE_CHANGE:
5326 ds = "State Change";
5328 case MPI_EVENT_UNIT_ATTENTION:
5329 ds = "Unit Attention";
5331 case MPI_EVENT_IOC_BUS_RESET:
5332 ds = "IOC Bus Reset";
5334 case MPI_EVENT_EXT_BUS_RESET:
5335 ds = "External Bus Reset";
5337 case MPI_EVENT_RESCAN:
5338 ds = "Bus Rescan Event";
5339 /* Ok, do we need to do anything here? As far as
5340 I can tell, this is when a new device gets added
5343 case MPI_EVENT_LINK_STATUS_CHANGE:
5344 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
5345 ds = "Link Status(FAILURE) Change";
5347 ds = "Link Status(ACTIVE) Change";
5349 case MPI_EVENT_LOOP_STATE_CHANGE:
5350 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
5351 ds = "Loop State(LIP) Change";
5352 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
5353 ds = "Loop State(LPE) Change"; /* ??? */
5355 ds = "Loop State(LPB) Change"; /* ??? */
5357 case MPI_EVENT_LOGOUT:
5360 case MPI_EVENT_EVENT_CHANGE:
5362 ds = "Events(ON) Change";
5364 ds = "Events(OFF) Change";
5366 case MPI_EVENT_INTEGRATED_RAID:
5367 ds = "Integrated Raid";
5370 * MPT base "custom" events may be added here...
5379 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5381 * ProcessEventNotification - Route a received EventNotificationReply to
5382 * all currently regeistered event handlers.
5383 * @ioc: Pointer to MPT_ADAPTER structure
5384 * @pEventReply: Pointer to EventNotification reply frame
5385 * @evHandlers: Pointer to integer, number of event handlers
5387 * Returns sum of event handlers return values.
5390 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
5402 * Do platform normalization of values
5404 event = le32_to_cpu(pEventReply->Event) & 0xFF;
5405 // evCtx = le32_to_cpu(pEventReply->EventContext);
5406 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
5408 evData0 = le32_to_cpu(pEventReply->Data[0]);
5411 evStr = EventDescriptionStr(event, evData0);
5412 devtprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n",
5417 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_EVENTS)
5418 printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
5419 for (ii = 0; ii < evDataLen; ii++)
5420 printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
5425 * Do general / base driver event processing
5428 case MPI_EVENT_NONE: /* 00 */
5429 case MPI_EVENT_LOG_DATA: /* 01 */
5430 case MPI_EVENT_STATE_CHANGE: /* 02 */
5431 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
5432 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
5433 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
5434 case MPI_EVENT_RESCAN: /* 06 */
5435 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
5436 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
5437 case MPI_EVENT_LOGOUT: /* 09 */
5438 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
5439 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE: /* 0C */
5442 case MPI_EVENT_EVENT_CHANGE: /* 0A */
5444 u8 evState = evData0 & 0xFF;
5446 /* CHECKME! What if evState unexpectedly says OFF (0)? */
5448 /* Update EventState field in cached IocFacts */
5449 if (ioc->facts.Function) {
5450 ioc->facts.EventState = evState;
5457 * Should this event be logged? Events are written sequentially.
5458 * When buffer is full, start again at the top.
5460 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
5463 idx = ioc->eventContext % ioc->eventLogSize;
5465 ioc->events[idx].event = event;
5466 ioc->events[idx].eventContext = ioc->eventContext;
5468 for (ii = 0; ii < 2; ii++) {
5470 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
5472 ioc->events[idx].data[ii] = 0;
5475 ioc->eventContext++;
5480 * Call each currently registered protocol event handler.
5482 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5483 if (MptEvHandlers[ii]) {
5484 devtprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
5486 r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
5490 /* FIXME? Examine results here? */
5493 * If needed, send (a single) EventAck.
5495 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
5496 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
5497 devtprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
5502 *evHandlers = handlers;
5506 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5508 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
5509 * @ioc: Pointer to MPT_ADAPTER structure
5510 * @log_info: U32 LogInfo reply word from the IOC
5512 * Refer to lsi/fc_log.h.
5515 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
5517 static char *subcl_str[8] = {
5518 "FCP Initiator", "FCP Target", "LAN", "MPI Message Layer",
5519 "FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
5521 u8 subcl = (log_info >> 24) & 0x7;
5523 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}\n",
5524 ioc->name, log_info, subcl_str[subcl]);
5527 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5529 * mpt_sp_log_info - Log information returned from SCSI Parallel IOC.
5530 * @ioc: Pointer to MPT_ADAPTER structure
5531 * @mr: Pointer to MPT reply frame
5532 * @log_info: U32 LogInfo word from the IOC
5534 * Refer to lsi/sp_log.h.
5537 mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
5539 u32 info = log_info & 0x00FF0000;
5540 char *desc = "unknown";
5544 desc = "bug! MID not found";
5545 if (ioc->reload_fw == 0)
5550 desc = "Parity Error";
5554 desc = "ASYNC Outbound Overrun";
5558 desc = "SYNC Offset Error";
5566 desc = "Msg In Overflow";
5574 desc = "Outbound DMA Overrun";
5578 desc = "Task Management";
5582 desc = "Device Problem";
5586 desc = "Invalid Phase Change";
5590 desc = "Untagged Table Size";
5595 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
5598 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5600 * mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
5601 * @ioc: Pointer to MPT_ADAPTER structure
5602 * @ioc_status: U32 IOCStatus word from IOC
5603 * @mf: Pointer to MPT request frame
5605 * Refer to lsi/mpi.h.
5608 mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
5610 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
5614 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
5615 desc = "Invalid Function";
5618 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
5622 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
5623 desc = "Invalid SGL";
5626 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
5627 desc = "Internal Error";
5630 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
5634 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
5635 desc = "Insufficient Resources";
5638 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
5639 desc = "Invalid Field";
5642 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
5643 desc = "Invalid State";
5646 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
5647 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
5648 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
5649 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
5650 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
5651 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
5652 /* No message for Config IOCStatus values */
5655 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
5656 /* No message for recovered error
5657 desc = "SCSI Recovered Error";
5661 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
5662 desc = "SCSI Invalid Bus";
5665 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
5666 desc = "SCSI Invalid TargetID";
5669 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
5671 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
5672 U8 cdb = pScsiReq->CDB[0];
5673 if (cdb != 0x12) { /* Inquiry is issued for device scanning */
5674 desc = "SCSI Device Not There";
5679 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
5680 desc = "SCSI Data Overrun";
5683 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
5684 /* This error is checked in scsi_io_done(). Skip.
5685 desc = "SCSI Data Underrun";
5689 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
5690 desc = "SCSI I/O Data Error";
5693 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
5694 desc = "SCSI Protocol Error";
5697 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
5698 desc = "SCSI Task Terminated";
5701 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
5702 desc = "SCSI Residual Mismatch";
5705 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
5706 desc = "SCSI Task Management Failed";
5709 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
5710 desc = "SCSI IOC Terminated";
5713 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
5714 desc = "SCSI Ext Terminated";
5722 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc);
5725 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5726 EXPORT_SYMBOL(mpt_attach);
5727 EXPORT_SYMBOL(mpt_detach);
5729 EXPORT_SYMBOL(mpt_resume);
5730 EXPORT_SYMBOL(mpt_suspend);
5732 EXPORT_SYMBOL(ioc_list);
5733 EXPORT_SYMBOL(mpt_proc_root_dir);
5734 EXPORT_SYMBOL(mpt_register);
5735 EXPORT_SYMBOL(mpt_deregister);
5736 EXPORT_SYMBOL(mpt_event_register);
5737 EXPORT_SYMBOL(mpt_event_deregister);
5738 EXPORT_SYMBOL(mpt_reset_register);
5739 EXPORT_SYMBOL(mpt_reset_deregister);
5740 EXPORT_SYMBOL(mpt_device_driver_register);
5741 EXPORT_SYMBOL(mpt_device_driver_deregister);
5742 EXPORT_SYMBOL(mpt_get_msg_frame);
5743 EXPORT_SYMBOL(mpt_put_msg_frame);
5744 EXPORT_SYMBOL(mpt_free_msg_frame);
5745 EXPORT_SYMBOL(mpt_add_sge);
5746 EXPORT_SYMBOL(mpt_send_handshake_request);
5747 EXPORT_SYMBOL(mpt_verify_adapter);
5748 EXPORT_SYMBOL(mpt_GetIocState);
5749 EXPORT_SYMBOL(mpt_print_ioc_summary);
5750 EXPORT_SYMBOL(mpt_lan_index);
5751 EXPORT_SYMBOL(mpt_stm_index);
5752 EXPORT_SYMBOL(mpt_HardResetHandler);
5753 EXPORT_SYMBOL(mpt_config);
5754 EXPORT_SYMBOL(mpt_toolbox);
5755 EXPORT_SYMBOL(mpt_findImVolumes);
5756 EXPORT_SYMBOL(mpt_read_ioc_pg_3);
5757 EXPORT_SYMBOL(mpt_alloc_fw_memory);
5758 EXPORT_SYMBOL(mpt_free_fw_memory);
5761 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5763 * fusion_init - Fusion MPT base driver initialization routine.
5765 * Returns 0 for success, non-zero for failure.
5772 show_mptmod_ver(my_NAME, my_VERSION);
5773 printk(KERN_INFO COPYRIGHT "\n");
5775 for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
5776 MptCallbacks[i] = NULL;
5777 MptDriverClass[i] = MPTUNKNOWN_DRIVER;
5778 MptEvHandlers[i] = NULL;
5779 MptResetHandlers[i] = NULL;
5782 /* Register ourselves (mptbase) in order to facilitate
5783 * EventNotification handling.
5785 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
5787 /* Register for hard reset handling callbacks.
5789 if (mpt_reset_register(mpt_base_index, mpt_ioc_reset) == 0) {
5790 dprintk((KERN_INFO MYNAM ": Register for IOC reset notification\n"));
5795 #ifdef CONFIG_PROC_FS
5796 (void) procmpt_create();
5801 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5803 * fusion_exit - Perform driver unload cleanup.
5805 * This routine frees all resources associated with each MPT adapter
5806 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
5812 dexitprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
5814 mpt_reset_deregister(mpt_base_index);
5816 #ifdef CONFIG_PROC_FS
5821 module_init(fusion_init);
5822 module_exit(fusion_exit);