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/kernel.h>
51 #include <linux/module.h>
52 #include <linux/errno.h>
53 #include <linux/init.h>
54 #include <linux/slab.h>
55 #include <linux/types.h>
56 #include <linux/pci.h>
57 #include <linux/kdev_t.h>
58 #include <linux/blkdev.h>
59 #include <linux/delay.h>
60 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
61 #include <linux/dma-mapping.h>
67 #include <asm/irq.h> /* needed for __irq_itoa() proto */
72 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
73 #define my_NAME "Fusion MPT base driver"
74 #define my_VERSION MPT_LINUX_VERSION_COMMON
75 #define MYNAM "mptbase"
77 MODULE_AUTHOR(MODULEAUTHOR);
78 MODULE_DESCRIPTION(my_NAME);
79 MODULE_LICENSE("GPL");
84 static int mpt_msi_enable;
85 module_param(mpt_msi_enable, int, 0);
86 MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)");
89 static int mfcounter = 0;
90 #define PRINT_MF_COUNT 20000
93 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
97 int mpt_lan_index = -1;
98 int mpt_stm_index = -1;
100 struct proc_dir_entry *mpt_proc_root_dir;
102 #define WHOINIT_UNKNOWN 0xAA
104 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
108 /* Adapter link list */
110 /* Callback lookup table */
111 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
112 /* Protocol driver class lookup table */
113 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
114 /* Event handler lookup table */
115 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
116 /* Reset handler lookup table */
117 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
118 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
120 static int mpt_base_index = -1;
121 static int last_drv_idx = -1;
123 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
125 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
129 static irqreturn_t mpt_interrupt(int irq, void *bus_id, struct pt_regs *r);
130 static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
131 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
132 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
134 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
135 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
136 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
137 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
139 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
140 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
141 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
142 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
143 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
144 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
145 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
146 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
147 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
148 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
149 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
150 static int PrimeIocFifos(MPT_ADAPTER *ioc);
151 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
152 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
153 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
154 static int GetLanConfigPages(MPT_ADAPTER *ioc);
155 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
156 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
157 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
158 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
159 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
160 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
161 static void mpt_timer_expired(unsigned long data);
162 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
163 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
164 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
165 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
167 #ifdef CONFIG_PROC_FS
168 static int procmpt_summary_read(char *buf, char **start, off_t offset,
169 int request, int *eof, void *data);
170 static int procmpt_version_read(char *buf, char **start, off_t offset,
171 int request, int *eof, void *data);
172 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
173 int request, int *eof, void *data);
175 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
177 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
178 static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
179 static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
180 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
181 static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
182 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
183 static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
185 /* module entry point */
186 static int __init fusion_init (void);
187 static void __exit fusion_exit (void);
189 #define CHIPREG_READ32(addr) readl_relaxed(addr)
190 #define CHIPREG_READ32_dmasync(addr) readl(addr)
191 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
192 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
193 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
196 pci_disable_io_access(struct pci_dev *pdev)
200 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
202 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
206 pci_enable_io_access(struct pci_dev *pdev)
210 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
212 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
216 * Process turbo (context) reply...
219 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
221 MPT_FRAME_HDR *mf = NULL;
222 MPT_FRAME_HDR *mr = NULL;
226 dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n",
229 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
230 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
231 req_idx = pa & 0x0000FFFF;
232 cb_idx = (pa & 0x00FF0000) >> 16;
233 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
235 case MPI_CONTEXT_REPLY_TYPE_LAN:
236 cb_idx = mpt_lan_index;
238 * Blind set of mf to NULL here was fatal
239 * after lan_reply says "freeme"
240 * Fix sort of combined with an optimization here;
241 * added explicit check for case where lan_reply
242 * was just returning 1 and doing nothing else.
243 * For this case skip the callback, but set up
244 * proper mf value first here:-)
246 if ((pa & 0x58000000) == 0x58000000) {
247 req_idx = pa & 0x0000FFFF;
248 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
249 mpt_free_msg_frame(ioc, mf);
254 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
256 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
257 cb_idx = mpt_stm_index;
258 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
265 /* Check for (valid) IO callback! */
266 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
267 MptCallbacks[cb_idx] == NULL) {
268 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
269 __FUNCTION__, ioc->name, cb_idx);
273 if (MptCallbacks[cb_idx](ioc, mf, mr))
274 mpt_free_msg_frame(ioc, mf);
280 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
291 /* non-TURBO reply! Hmmm, something may be up...
292 * Newest turbo reply mechanism; get address
293 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
296 /* Map DMA address of reply header to cpu address.
297 * pa is 32 bits - but the dma address may be 32 or 64 bits
298 * get offset based only only the low addresses
301 reply_dma_low = (pa <<= 1);
302 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
303 (reply_dma_low - ioc->reply_frames_low_dma));
305 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
306 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
307 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
309 dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
310 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
311 DBG_DUMP_REPLY_FRAME(mr)
313 /* Check/log IOC log info
315 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
316 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
317 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
318 if (ioc->bus_type == FC)
319 mpt_fc_log_info(ioc, log_info);
320 else if (ioc->bus_type == SPI)
321 mpt_spi_log_info(ioc, log_info);
322 else if (ioc->bus_type == SAS)
323 mpt_sas_log_info(ioc, log_info);
325 if (ioc_stat & MPI_IOCSTATUS_MASK) {
326 if (ioc->bus_type == SPI &&
327 cb_idx != mpt_stm_index &&
328 cb_idx != mpt_lan_index)
329 mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
333 /* Check for (valid) IO callback! */
334 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
335 MptCallbacks[cb_idx] == NULL) {
336 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
337 __FUNCTION__, ioc->name, cb_idx);
342 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
345 /* Flush (non-TURBO) reply with a WRITE! */
346 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
349 mpt_free_msg_frame(ioc, mf);
353 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
355 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
356 * @irq: irq number (not used)
357 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
358 * @r: pt_regs pointer (not used)
360 * This routine is registered via the request_irq() kernel API call,
361 * and handles all interrupts generated from a specific MPT adapter
362 * (also referred to as a IO Controller or IOC).
363 * This routine must clear the interrupt from the adapter and does
364 * so by reading the reply FIFO. Multiple replies may be processed
365 * per single call to this routine.
367 * This routine handles register-level access of the adapter but
368 * dispatches (calls) a protocol-specific callback routine to handle
369 * the protocol-specific details of the MPT request completion.
372 mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
374 MPT_ADAPTER *ioc = bus_id;
378 * Drain the reply FIFO!
381 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
382 if (pa == 0xFFFFFFFF)
384 else if (pa & MPI_ADDRESS_REPLY_A_BIT)
387 mpt_turbo_reply(ioc, pa);
393 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
395 * mpt_base_reply - MPT base driver's callback routine; all base driver
396 * "internal" request/reply processing is routed here.
397 * Currently used for EventNotification and EventAck handling.
398 * @ioc: Pointer to MPT_ADAPTER structure
399 * @mf: Pointer to original MPT request frame
400 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
402 * Returns 1 indicating original alloc'd request frame ptr
403 * should be freed, or 0 if it shouldn't.
406 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
411 dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name));
413 #if defined(MPT_DEBUG_MSG_FRAME)
414 if (!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
415 dmfprintk((KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf));
416 DBG_DUMP_REQUEST_FRAME_HDR(mf)
420 func = reply->u.hdr.Function;
421 dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n",
424 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
425 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
429 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
430 if (results != evHandlers) {
431 /* CHECKME! Any special handling needed here? */
432 devtverboseprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
433 ioc->name, evHandlers, results));
437 * Hmmm... It seems that EventNotificationReply is an exception
438 * to the rule of one reply per request.
440 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
442 devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n",
443 ioc->name, pEvReply));
445 devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
446 ioc->name, pEvReply));
449 #ifdef CONFIG_PROC_FS
450 // LogEvent(ioc, pEvReply);
453 } else if (func == MPI_FUNCTION_EVENT_ACK) {
454 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
456 } else if (func == MPI_FUNCTION_CONFIG) {
460 dcprintk((MYIOC_s_INFO_FMT "config_complete (mf=%p,mr=%p)\n",
461 ioc->name, mf, reply));
463 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
466 /* disable timer and remove from linked list */
467 del_timer(&pCfg->timer);
469 spin_lock_irqsave(&ioc->FreeQlock, flags);
470 list_del(&pCfg->linkage);
471 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
474 * If IOC Status is SUCCESS, save the header
475 * and set the status code to GOOD.
477 pCfg->status = MPT_CONFIG_ERROR;
479 ConfigReply_t *pReply = (ConfigReply_t *)reply;
482 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
483 dcprintk((KERN_NOTICE " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
484 status, le32_to_cpu(pReply->IOCLogInfo)));
486 pCfg->status = status;
487 if (status == MPI_IOCSTATUS_SUCCESS) {
488 if ((pReply->Header.PageType &
489 MPI_CONFIG_PAGETYPE_MASK) ==
490 MPI_CONFIG_PAGETYPE_EXTENDED) {
491 pCfg->cfghdr.ehdr->ExtPageLength =
492 le16_to_cpu(pReply->ExtPageLength);
493 pCfg->cfghdr.ehdr->ExtPageType =
496 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
498 /* If this is a regular header, save PageLength. */
499 /* LMP Do this better so not using a reserved field! */
500 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
501 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
502 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
507 * Wake up the original calling thread
512 } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
513 /* we should be always getting a reply frame */
514 memcpy(ioc->persist_reply_frame, reply,
515 min(MPT_DEFAULT_FRAME_SIZE,
516 4*reply->u.reply.MsgLength));
517 del_timer(&ioc->persist_timer);
518 ioc->persist_wait_done = 1;
521 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
526 * Conditionally tell caller to free the original
527 * EventNotification/EventAck/unexpected request frame!
532 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
534 * mpt_register - Register protocol-specific main callback handler.
535 * @cbfunc: callback function pointer
536 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
538 * This routine is called by a protocol-specific driver (SCSI host,
539 * LAN, SCSI target) to register it's reply callback routine. Each
540 * protocol-specific driver must do this before it will be able to
541 * use any IOC resources, such as obtaining request frames.
543 * NOTES: The SCSI protocol driver currently calls this routine thrice
544 * in order to register separate callbacks; one for "normal" SCSI IO;
545 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
547 * Returns a positive integer valued "handle" in the
548 * range (and S.O.D. order) {N,...,7,6,5,...,1} if successful.
549 * Any non-positive return value (including zero!) should be considered
550 * an error by the caller.
553 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
560 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
561 * (slot/handle 0 is reserved!)
563 for (i = MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
564 if (MptCallbacks[i] == NULL) {
565 MptCallbacks[i] = cbfunc;
566 MptDriverClass[i] = dclass;
567 MptEvHandlers[i] = NULL;
576 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
578 * mpt_deregister - Deregister a protocol drivers resources.
579 * @cb_idx: previously registered callback handle
581 * Each protocol-specific driver should call this routine when it's
582 * module is unloaded.
585 mpt_deregister(int cb_idx)
587 if ((cb_idx >= 0) && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
588 MptCallbacks[cb_idx] = NULL;
589 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
590 MptEvHandlers[cb_idx] = NULL;
596 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
598 * mpt_event_register - Register protocol-specific event callback
600 * @cb_idx: previously registered (via mpt_register) callback handle
601 * @ev_cbfunc: callback function
603 * This routine can be called by one or more protocol-specific drivers
604 * if/when they choose to be notified of MPT events.
606 * Returns 0 for success.
609 mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc)
611 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
614 MptEvHandlers[cb_idx] = ev_cbfunc;
618 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
620 * mpt_event_deregister - Deregister protocol-specific event callback
622 * @cb_idx: previously registered callback handle
624 * Each protocol-specific driver should call this routine
625 * when it does not (or can no longer) handle events,
626 * or when it's module is unloaded.
629 mpt_event_deregister(int cb_idx)
631 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
634 MptEvHandlers[cb_idx] = NULL;
637 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
639 * mpt_reset_register - Register protocol-specific IOC reset handler.
640 * @cb_idx: previously registered (via mpt_register) callback handle
641 * @reset_func: reset function
643 * This routine can be called by one or more protocol-specific drivers
644 * if/when they choose to be notified of IOC resets.
646 * Returns 0 for success.
649 mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func)
651 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
654 MptResetHandlers[cb_idx] = reset_func;
658 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
660 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
661 * @cb_idx: previously registered callback handle
663 * Each protocol-specific driver should call this routine
664 * when it does not (or can no longer) handle IOC reset handling,
665 * or when it's module is unloaded.
668 mpt_reset_deregister(int cb_idx)
670 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
673 MptResetHandlers[cb_idx] = NULL;
676 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
678 * mpt_device_driver_register - Register device driver hooks
681 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
685 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) {
689 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
691 /* call per pci device probe entry point */
692 list_for_each_entry(ioc, &ioc_list, list) {
693 if(dd_cbfunc->probe) {
694 dd_cbfunc->probe(ioc->pcidev,
695 ioc->pcidev->driver->id_table);
702 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
704 * mpt_device_driver_deregister - DeRegister device driver hooks
707 mpt_device_driver_deregister(int cb_idx)
709 struct mpt_pci_driver *dd_cbfunc;
712 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
715 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
717 list_for_each_entry(ioc, &ioc_list, list) {
718 if (dd_cbfunc->remove)
719 dd_cbfunc->remove(ioc->pcidev);
722 MptDeviceDriverHandlers[cb_idx] = NULL;
726 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
728 * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
729 * allocated per MPT adapter.
730 * @handle: Handle of registered MPT protocol driver
731 * @ioc: Pointer to MPT adapter structure
733 * Returns pointer to a MPT request frame or %NULL if none are available
734 * or IOC is not active.
737 mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc)
741 u16 req_idx; /* Request index */
743 /* validate handle and ioc identifier */
747 printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n");
750 /* If interrupts are not attached, do not return a request frame */
754 spin_lock_irqsave(&ioc->FreeQlock, flags);
755 if (!list_empty(&ioc->FreeQ)) {
758 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
759 u.frame.linkage.list);
760 list_del(&mf->u.frame.linkage.list);
761 mf->u.frame.linkage.arg1 = 0;
762 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
763 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
765 req_idx = req_offset / ioc->req_sz;
766 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
767 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
768 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; /* Default, will be changed if necessary in SG generation */
775 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
779 printk(KERN_WARNING "IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", ioc->mfcnt, ioc->req_depth);
781 if (mfcounter == PRINT_MF_COUNT)
782 printk(KERN_INFO "MF Count 0x%x Max 0x%x \n", ioc->mfcnt, ioc->req_depth);
785 dmfprintk((KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",
786 ioc->name, handle, ioc->id, mf));
790 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
792 * mpt_put_msg_frame - Send a protocol specific MPT request frame
794 * @handle: Handle of registered MPT protocol driver
795 * @ioc: Pointer to MPT adapter structure
796 * @mf: Pointer to MPT request frame
798 * This routine posts a MPT request frame to the request post FIFO of a
799 * specific MPT adapter.
802 mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
806 u16 req_idx; /* Request index */
808 /* ensure values are reset properly! */
809 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
810 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
812 req_idx = req_offset / ioc->req_sz;
813 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
814 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
816 #ifdef MPT_DEBUG_MSG_FRAME
818 u32 *m = mf->u.frame.hwhdr.__hdr;
821 printk(KERN_INFO MYNAM ": %s: About to Put msg frame @ %p:\n" KERN_INFO " ",
823 n = ioc->req_sz/4 - 1;
826 for (ii=0; ii<=n; ii++) {
827 if (ii && ((ii%8)==0))
828 printk("\n" KERN_INFO " ");
829 printk(" %08x", le32_to_cpu(m[ii]));
835 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
836 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]));
837 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
840 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
842 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
843 * @handle: Handle of registered MPT protocol driver
844 * @ioc: Pointer to MPT adapter structure
845 * @mf: Pointer to MPT request frame
847 * This routine places a MPT request frame back on the MPT adapter's
851 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
855 /* Put Request back on FreeQ! */
856 spin_lock_irqsave(&ioc->FreeQlock, flags);
857 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
858 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
862 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
865 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
867 * mpt_add_sge - Place a simple SGE at address pAddr.
868 * @pAddr: virtual address for SGE
869 * @flagslength: SGE flags and data transfer length
870 * @dma_addr: Physical address
872 * This routine places a MPT request frame back on the MPT adapter's
876 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
878 if (sizeof(dma_addr_t) == sizeof(u64)) {
879 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
880 u32 tmp = dma_addr & 0xFFFFFFFF;
882 pSge->FlagsLength = cpu_to_le32(flagslength);
883 pSge->Address.Low = cpu_to_le32(tmp);
884 tmp = (u32) ((u64)dma_addr >> 32);
885 pSge->Address.High = cpu_to_le32(tmp);
888 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
889 pSge->FlagsLength = cpu_to_le32(flagslength);
890 pSge->Address = cpu_to_le32(dma_addr);
894 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
896 * mpt_send_handshake_request - Send MPT request via doorbell
898 * @handle: Handle of registered MPT protocol driver
899 * @ioc: Pointer to MPT adapter structure
900 * @reqBytes: Size of the request in bytes
901 * @req: Pointer to MPT request frame
902 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
904 * This routine is used exclusively to send MptScsiTaskMgmt
905 * requests since they are required to be sent via doorbell handshake.
907 * NOTE: It is the callers responsibility to byte-swap fields in the
908 * request which are greater than 1 byte in size.
910 * Returns 0 for success, non-zero for failure.
913 mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
919 /* State is known to be good upon entering
920 * this function so issue the bus reset
925 * Emulate what mpt_put_msg_frame() does /wrt to sanity
926 * setting cb_idx/req_idx. But ONLY if this request
927 * is in proper (pre-alloc'd) request buffer range...
929 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
930 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
931 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
932 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
933 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
936 /* Make sure there are no doorbells */
937 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
939 CHIPREG_WRITE32(&ioc->chip->Doorbell,
940 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
941 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
943 /* Wait for IOC doorbell int */
944 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
948 /* Read doorbell and check for active bit */
949 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
952 dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
955 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
957 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
961 /* Send request via doorbell handshake */
962 req_as_bytes = (u8 *) req;
963 for (ii = 0; ii < reqBytes/4; ii++) {
966 word = ((req_as_bytes[(ii*4) + 0] << 0) |
967 (req_as_bytes[(ii*4) + 1] << 8) |
968 (req_as_bytes[(ii*4) + 2] << 16) |
969 (req_as_bytes[(ii*4) + 3] << 24));
970 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
971 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
977 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
982 /* Make sure there are no doorbells */
983 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
988 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
990 * mpt_host_page_access_control - provides mechanism for the host
991 * driver to control the IOC's Host Page Buffer access.
992 * @ioc: Pointer to MPT adapter structure
993 * @access_control_value: define bits below
995 * Access Control Value - bits[15:12]
997 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
998 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
999 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1001 * Returns 0 for success, non-zero for failure.
1005 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1009 /* return if in use */
1010 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1011 & MPI_DOORBELL_ACTIVE)
1014 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1016 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1017 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1018 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1019 (access_control_value<<12)));
1021 /* Wait for IOC to clear Doorbell Status bit */
1022 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1028 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1030 * mpt_host_page_alloc - allocate system memory for the fw
1031 * If we already allocated memory in past, then resend the same pointer.
1032 * ioc@: Pointer to pointer to IOC adapter
1033 * ioc_init@: Pointer to ioc init config page
1035 * Returns 0 for success, non-zero for failure.
1038 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1042 u32 host_page_buffer_sz=0;
1044 if(!ioc->HostPageBuffer) {
1046 host_page_buffer_sz =
1047 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1049 if(!host_page_buffer_sz)
1050 return 0; /* fw doesn't need any host buffers */
1052 /* spin till we get enough memory */
1053 while(host_page_buffer_sz > 0) {
1055 if((ioc->HostPageBuffer = pci_alloc_consistent(
1057 host_page_buffer_sz,
1058 &ioc->HostPageBuffer_dma)) != NULL) {
1060 dinitprintk((MYIOC_s_INFO_FMT
1061 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1063 ioc->HostPageBuffer,
1064 ioc->HostPageBuffer_dma,
1065 host_page_buffer_sz));
1066 ioc->alloc_total += host_page_buffer_sz;
1067 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1071 host_page_buffer_sz -= (4*1024);
1075 if(!ioc->HostPageBuffer) {
1076 printk(MYIOC_s_ERR_FMT
1077 "Failed to alloc memory for host_page_buffer!\n",
1082 psge = (char *)&ioc_init->HostPageBufferSGE;
1083 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1084 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1085 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1086 MPI_SGE_FLAGS_HOST_TO_IOC |
1087 MPI_SGE_FLAGS_END_OF_BUFFER;
1088 if (sizeof(dma_addr_t) == sizeof(u64)) {
1089 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1091 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1092 flags_length |= ioc->HostPageBuffer_sz;
1093 mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1094 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1099 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1101 * mpt_verify_adapter - Given a unique IOC identifier, set pointer to
1102 * the associated MPT adapter structure.
1103 * @iocid: IOC unique identifier (integer)
1104 * @iocpp: Pointer to pointer to IOC adapter
1106 * Returns iocid and sets iocpp.
1109 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1113 list_for_each_entry(ioc,&ioc_list,list) {
1114 if (ioc->id == iocid) {
1124 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1126 * mpt_attach - Install a PCI intelligent MPT adapter.
1127 * @pdev: Pointer to pci_dev structure
1129 * This routine performs all the steps necessary to bring the IOC of
1130 * a MPT adapter to a OPERATIONAL state. This includes registering
1131 * memory regions, registering the interrupt, and allocating request
1132 * and reply memory pools.
1134 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1137 * Returns 0 for success, non-zero for failure.
1139 * TODO: Add support for polled controllers
1142 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1146 unsigned long mem_phys;
1154 static int mpt_ids = 0;
1155 #ifdef CONFIG_PROC_FS
1156 struct proc_dir_entry *dent, *ent;
1159 if (pci_enable_device(pdev))
1162 dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1164 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1165 dprintk((KERN_INFO MYNAM
1166 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1167 } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1168 printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1172 if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
1173 dprintk((KERN_INFO MYNAM
1174 ": Using 64 bit consistent mask\n"));
1176 dprintk((KERN_INFO MYNAM
1177 ": Not using 64 bit consistent mask\n"));
1179 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1181 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1184 ioc->alloc_total = sizeof(MPT_ADAPTER);
1185 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1186 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1189 ioc->diagPending = 0;
1190 spin_lock_init(&ioc->diagLock);
1191 spin_lock_init(&ioc->fc_rescan_work_lock);
1192 spin_lock_init(&ioc->fc_rport_lock);
1193 spin_lock_init(&ioc->initializing_hba_lock);
1195 /* Initialize the event logging.
1197 ioc->eventTypes = 0; /* None */
1198 ioc->eventContext = 0;
1199 ioc->eventLogSize = 0;
1206 ioc->cached_fw = NULL;
1208 /* Initilize SCSI Config Data structure
1210 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1212 /* Initialize the running configQ head.
1214 INIT_LIST_HEAD(&ioc->configQ);
1216 /* Initialize the fc rport list head.
1218 INIT_LIST_HEAD(&ioc->fc_rports);
1220 /* Find lookup slot. */
1221 INIT_LIST_HEAD(&ioc->list);
1222 ioc->id = mpt_ids++;
1224 mem_phys = msize = 0;
1226 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1227 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1228 /* Get I/O space! */
1229 port = pci_resource_start(pdev, ii);
1230 psize = pci_resource_len(pdev,ii);
1233 mem_phys = pci_resource_start(pdev, ii);
1234 msize = pci_resource_len(pdev,ii);
1238 ioc->mem_size = msize;
1240 if (ii == DEVICE_COUNT_RESOURCE) {
1241 printk(KERN_ERR MYNAM ": ERROR - MPT adapter has no memory regions defined!\n");
1246 dinitprintk((KERN_INFO MYNAM ": MPT adapter @ %lx, msize=%dd bytes\n", mem_phys, msize));
1247 dinitprintk((KERN_INFO MYNAM ": (port i/o @ %lx, psize=%dd bytes)\n", port, psize));
1250 /* Get logical ptr for PciMem0 space */
1251 /*mem = ioremap(mem_phys, msize);*/
1252 mem = ioremap(mem_phys, 0x100);
1254 printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1259 dinitprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1261 dinitprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1262 &ioc->facts, &ioc->pfacts[0]));
1264 ioc->mem_phys = mem_phys;
1265 ioc->chip = (SYSIF_REGS __iomem *)mem;
1267 /* Save Port IO values in case we need to do downloadboot */
1269 u8 *pmem = (u8*)port;
1270 ioc->pio_mem_phys = port;
1271 ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1274 if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC909) {
1275 ioc->prod_name = "LSIFC909";
1278 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
1279 ioc->prod_name = "LSIFC929";
1282 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) {
1283 ioc->prod_name = "LSIFC919";
1286 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) {
1287 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1289 if (revision < XL_929) {
1290 ioc->prod_name = "LSIFC929X";
1291 /* 929X Chip Fix. Set Split transactions level
1292 * for PCIX. Set MOST bits to zero.
1294 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1296 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1298 ioc->prod_name = "LSIFC929XL";
1299 /* 929XL Chip Fix. Set MMRBC to 0x08.
1301 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1303 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1306 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) {
1307 ioc->prod_name = "LSIFC919X";
1309 /* 919X Chip Fix. Set Split transactions level
1310 * for PCIX. Set MOST bits to zero.
1312 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1314 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1316 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC939X) {
1317 ioc->prod_name = "LSIFC939X";
1319 ioc->errata_flag_1064 = 1;
1321 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949X) {
1322 ioc->prod_name = "LSIFC949X";
1324 ioc->errata_flag_1064 = 1;
1326 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949E) {
1327 ioc->prod_name = "LSIFC949E";
1330 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
1331 ioc->prod_name = "LSI53C1030";
1332 ioc->bus_type = SPI;
1333 /* 1030 Chip Fix. Disable Split transactions
1334 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1336 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1337 if (revision < C0_1030) {
1338 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1340 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1343 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
1344 ioc->prod_name = "LSI53C1035";
1345 ioc->bus_type = SPI;
1347 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064) {
1348 ioc->prod_name = "LSISAS1064";
1349 ioc->bus_type = SAS;
1350 ioc->errata_flag_1064 = 1;
1352 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066) {
1353 ioc->prod_name = "LSISAS1066";
1354 ioc->bus_type = SAS;
1355 ioc->errata_flag_1064 = 1;
1357 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) {
1358 ioc->prod_name = "LSISAS1068";
1359 ioc->bus_type = SAS;
1360 ioc->errata_flag_1064 = 1;
1362 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064E) {
1363 ioc->prod_name = "LSISAS1064E";
1364 ioc->bus_type = SAS;
1366 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066E) {
1367 ioc->prod_name = "LSISAS1066E";
1368 ioc->bus_type = SAS;
1370 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) {
1371 ioc->prod_name = "LSISAS1068E";
1372 ioc->bus_type = SAS;
1375 if (ioc->errata_flag_1064)
1376 pci_disable_io_access(pdev);
1378 sprintf(ioc->name, "ioc%d", ioc->id);
1380 spin_lock_init(&ioc->FreeQlock);
1383 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1385 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1387 /* Set lookup ptr. */
1388 list_add_tail(&ioc->list, &ioc_list);
1390 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1392 mpt_detect_bound_ports(ioc, pdev);
1394 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1396 printk(KERN_WARNING MYNAM
1397 ": WARNING - %s did not initialize properly! (%d)\n",
1399 list_del(&ioc->list);
1401 ioc->alt_ioc->alt_ioc = NULL;
1404 pci_set_drvdata(pdev, NULL);
1408 /* call per device driver probe entry point */
1409 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1410 if(MptDeviceDriverHandlers[ii] &&
1411 MptDeviceDriverHandlers[ii]->probe) {
1412 MptDeviceDriverHandlers[ii]->probe(pdev,id);
1416 #ifdef CONFIG_PROC_FS
1418 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1420 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1422 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1424 ent->read_proc = procmpt_iocinfo_read;
1427 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1429 ent->read_proc = procmpt_summary_read;
1438 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1440 * mpt_detach - Remove a PCI intelligent MPT adapter.
1441 * @pdev: Pointer to pci_dev structure
1446 mpt_detach(struct pci_dev *pdev)
1448 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1452 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1453 remove_proc_entry(pname, NULL);
1454 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1455 remove_proc_entry(pname, NULL);
1456 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1457 remove_proc_entry(pname, NULL);
1459 /* call per device driver remove entry point */
1460 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1461 if(MptDeviceDriverHandlers[ii] &&
1462 MptDeviceDriverHandlers[ii]->remove) {
1463 MptDeviceDriverHandlers[ii]->remove(pdev);
1467 /* Disable interrupts! */
1468 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1471 synchronize_irq(pdev->irq);
1473 /* Clear any lingering interrupt */
1474 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1476 CHIPREG_READ32(&ioc->chip->IntStatus);
1478 mpt_adapter_dispose(ioc);
1480 pci_set_drvdata(pdev, NULL);
1483 /**************************************************************************
1487 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1489 * mpt_suspend - Fusion MPT base driver suspend routine.
1494 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1497 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1499 device_state=pci_choose_state(pdev, state);
1501 printk(MYIOC_s_INFO_FMT
1502 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1503 ioc->name, pdev, pci_name(pdev), device_state);
1505 pci_save_state(pdev);
1507 /* put ioc into READY_STATE */
1508 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1509 printk(MYIOC_s_ERR_FMT
1510 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1513 /* disable interrupts */
1514 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1517 /* Clear any lingering interrupt */
1518 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1520 pci_disable_device(pdev);
1521 pci_set_power_state(pdev, device_state);
1526 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1528 * mpt_resume - Fusion MPT base driver resume routine.
1533 mpt_resume(struct pci_dev *pdev)
1535 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1536 u32 device_state = pdev->current_state;
1539 printk(MYIOC_s_INFO_FMT
1540 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1541 ioc->name, pdev, pci_name(pdev), device_state);
1543 pci_set_power_state(pdev, 0);
1544 pci_restore_state(pdev);
1545 pci_enable_device(pdev);
1547 /* enable interrupts */
1548 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1551 printk(MYIOC_s_INFO_FMT
1552 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1554 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1555 CHIPREG_READ32(&ioc->chip->Doorbell));
1557 /* bring ioc to operational state */
1558 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1559 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1560 printk(MYIOC_s_INFO_FMT
1561 "pci-resume: Cannot recover, error:[%x]\n",
1562 ioc->name, recovery_state);
1564 printk(MYIOC_s_INFO_FMT
1565 "pci-resume: success\n", ioc->name);
1572 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1574 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1575 * @ioc: Pointer to MPT adapter structure
1576 * @reason: Event word / reason
1577 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1579 * This routine performs all the steps necessary to bring the IOC
1580 * to a OPERATIONAL state.
1582 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1587 * -1 if failed to get board READY
1588 * -2 if READY but IOCFacts Failed
1589 * -3 if READY but PrimeIOCFifos Failed
1590 * -4 if READY but IOCInit Failed
1593 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1595 int hard_reset_done = 0;
1596 int alt_ioc_ready = 0;
1602 int reset_alt_ioc_active = 0;
1603 int irq_allocated = 0;
1605 printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1606 ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1608 /* Disable reply interrupts (also blocks FreeQ) */
1609 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1613 if (ioc->alt_ioc->active)
1614 reset_alt_ioc_active = 1;
1616 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1617 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1618 ioc->alt_ioc->active = 0;
1622 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1625 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1626 if (hard_reset_done == -4) {
1627 printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1630 if (reset_alt_ioc_active && ioc->alt_ioc) {
1631 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1632 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1633 ioc->alt_ioc->name));
1634 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1635 ioc->alt_ioc->active = 1;
1639 printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1645 /* hard_reset_done = 0 if a soft reset was performed
1646 * and 1 if a hard reset was performed.
1648 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1649 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1652 printk(KERN_WARNING MYNAM
1653 ": alt-%s: Not ready WARNING!\n",
1654 ioc->alt_ioc->name);
1657 for (ii=0; ii<5; ii++) {
1658 /* Get IOC facts! Allow 5 retries */
1659 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1665 dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1667 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1668 MptDisplayIocCapabilities(ioc);
1671 if (alt_ioc_ready) {
1672 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1673 dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1674 /* Retry - alt IOC was initialized once
1676 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1679 dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1681 reset_alt_ioc_active = 0;
1682 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1683 MptDisplayIocCapabilities(ioc->alt_ioc);
1688 * Device is reset now. It must have de-asserted the interrupt line
1689 * (if it was asserted) and it should be safe to register for the
1692 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1694 if (ioc->pcidev->irq) {
1695 if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev))
1696 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
1698 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
1699 SA_SHIRQ, ioc->name, ioc);
1702 printk(MYIOC_s_ERR_FMT "Unable to allocate "
1703 "interrupt %d!\n", ioc->name,
1706 printk(MYIOC_s_ERR_FMT "Unable to allocate "
1707 "interrupt %s!\n", ioc->name,
1708 __irq_itoa(ioc->pcidev->irq));
1711 pci_disable_msi(ioc->pcidev);
1715 ioc->pci_irq = ioc->pcidev->irq;
1716 pci_set_master(ioc->pcidev); /* ?? */
1717 pci_set_drvdata(ioc->pcidev, ioc);
1719 dprintk((KERN_INFO MYNAM ": %s installed at interrupt "
1720 "%d\n", ioc->name, ioc->pcidev->irq));
1722 dprintk((KERN_INFO MYNAM ": %s installed at interrupt "
1724 __irq_itoa(ioc->pcidev->irq)));
1729 /* Prime reply & request queues!
1730 * (mucho alloc's) Must be done prior to
1731 * init as upper addresses are needed for init.
1732 * If fails, continue with alt-ioc processing
1734 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
1737 /* May need to check/upload firmware & data here!
1738 * If fails, continue with alt-ioc processing
1740 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
1743 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
1744 printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1745 ioc->alt_ioc->name, rc);
1747 reset_alt_ioc_active = 0;
1750 if (alt_ioc_ready) {
1751 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
1753 reset_alt_ioc_active = 0;
1754 printk(KERN_WARNING MYNAM
1755 ": alt-%s: (%d) init failure WARNING!\n",
1756 ioc->alt_ioc->name, rc);
1760 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
1761 if (ioc->upload_fw) {
1762 ddlprintk((MYIOC_s_INFO_FMT
1763 "firmware upload required!\n", ioc->name));
1765 /* Controller is not operational, cannot do upload
1768 rc = mpt_do_upload(ioc, sleepFlag);
1770 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
1772 * Maintain only one pointer to FW memory
1773 * so there will not be two attempt to
1774 * downloadboot onboard dual function
1775 * chips (mpt_adapter_disable,
1778 ioc->cached_fw = NULL;
1779 ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload: alt_%s has cached_fw=%p \n",
1780 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
1783 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
1791 /* Enable! (reply interrupt) */
1792 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1796 if (reset_alt_ioc_active && ioc->alt_ioc) {
1797 /* (re)Enable alt-IOC! (reply interrupt) */
1798 dinitprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1799 ioc->alt_ioc->name));
1800 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1801 ioc->alt_ioc->active = 1;
1804 /* Enable MPT base driver management of EventNotification
1805 * and EventAck handling.
1807 if ((ret == 0) && (!ioc->facts.EventState))
1808 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
1810 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
1811 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
1813 /* Add additional "reason" check before call to GetLanConfigPages
1814 * (combined with GetIoUnitPage2 call). This prevents a somewhat
1815 * recursive scenario; GetLanConfigPages times out, timer expired
1816 * routine calls HardResetHandler, which calls into here again,
1817 * and we try GetLanConfigPages again...
1819 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1820 if (ioc->bus_type == SAS) {
1822 /* clear persistency table */
1823 if(ioc->facts.IOCExceptions &
1824 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
1825 ret = mptbase_sas_persist_operation(ioc,
1826 MPI_SAS_OP_CLEAR_NOT_PRESENT);
1833 mpt_findImVolumes(ioc);
1835 } else if (ioc->bus_type == FC) {
1837 * Pre-fetch FC port WWN and stuff...
1838 * (FCPortPage0_t stuff)
1840 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1841 (void) mptbase_GetFcPortPage0(ioc, ii);
1844 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
1845 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
1847 * Pre-fetch the ports LAN MAC address!
1848 * (LANPage1_t stuff)
1850 (void) GetLanConfigPages(ioc);
1853 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
1854 dprintk((MYIOC_s_INFO_FMT "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
1855 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0] ));
1860 /* Get NVRAM and adapter maximums from SPP 0 and 2
1862 mpt_GetScsiPortSettings(ioc, 0);
1864 /* Get version and length of SDP 1
1866 mpt_readScsiDevicePageHeaders(ioc, 0);
1870 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
1871 mpt_findImVolumes(ioc);
1873 /* Check, and possibly reset, the coalescing value
1875 mpt_read_ioc_pg_1(ioc);
1877 mpt_read_ioc_pg_4(ioc);
1880 GetIoUnitPage2(ioc);
1884 * Call each currently registered protocol IOC reset handler
1885 * with post-reset indication.
1886 * NOTE: If we're doing _IOC_BRINGUP, there can be no
1887 * MptResetHandlers[] registered yet.
1889 if (hard_reset_done) {
1891 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
1892 if ((ret == 0) && MptResetHandlers[ii]) {
1893 dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
1895 rc += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET);
1899 if (alt_ioc_ready && MptResetHandlers[ii]) {
1900 drsprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
1901 ioc->name, ioc->alt_ioc->name, ii));
1902 rc += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
1906 /* FIXME? Examine results here? */
1910 if ((ret != 0) && irq_allocated) {
1911 free_irq(ioc->pci_irq, ioc);
1913 pci_disable_msi(ioc->pcidev);
1918 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1920 * mpt_detect_bound_ports - Search for PCI bus/dev_function
1921 * which matches PCI bus/dev_function (+/-1) for newly discovered 929,
1922 * 929X, 1030 or 1035.
1923 * @ioc: Pointer to MPT adapter structure
1924 * @pdev: Pointer to (struct pci_dev) structure
1926 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
1927 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
1930 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
1932 struct pci_dev *peer=NULL;
1933 unsigned int slot = PCI_SLOT(pdev->devfn);
1934 unsigned int func = PCI_FUNC(pdev->devfn);
1935 MPT_ADAPTER *ioc_srch;
1937 dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x,"
1938 " searching for devfn match on %x or %x\n",
1939 ioc->name, pci_name(pdev), pdev->bus->number,
1940 pdev->devfn, func-1, func+1));
1942 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
1944 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
1949 list_for_each_entry(ioc_srch, &ioc_list, list) {
1950 struct pci_dev *_pcidev = ioc_srch->pcidev;
1951 if (_pcidev == peer) {
1952 /* Paranoia checks */
1953 if (ioc->alt_ioc != NULL) {
1954 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1955 ioc->name, ioc->alt_ioc->name);
1957 } else if (ioc_srch->alt_ioc != NULL) {
1958 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1959 ioc_srch->name, ioc_srch->alt_ioc->name);
1962 dprintk((KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
1963 ioc->name, ioc_srch->name));
1964 ioc_srch->alt_ioc = ioc;
1965 ioc->alt_ioc = ioc_srch;
1971 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1973 * mpt_adapter_disable - Disable misbehaving MPT adapter.
1974 * @this: Pointer to MPT adapter structure
1977 mpt_adapter_disable(MPT_ADAPTER *ioc)
1982 if (ioc->cached_fw != NULL) {
1983 ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
1984 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
1985 printk(KERN_WARNING MYNAM
1986 ": firmware downloadboot failure (%d)!\n", ret);
1990 /* Disable adapter interrupts! */
1991 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1993 /* Clear any lingering interrupt */
1994 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1996 if (ioc->alloc != NULL) {
1998 dexitprintk((KERN_INFO MYNAM ": %s.free @ %p, sz=%d bytes\n",
1999 ioc->name, ioc->alloc, ioc->alloc_sz));
2000 pci_free_consistent(ioc->pcidev, sz,
2001 ioc->alloc, ioc->alloc_dma);
2002 ioc->reply_frames = NULL;
2003 ioc->req_frames = NULL;
2005 ioc->alloc_total -= sz;
2008 if (ioc->sense_buf_pool != NULL) {
2009 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2010 pci_free_consistent(ioc->pcidev, sz,
2011 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2012 ioc->sense_buf_pool = NULL;
2013 ioc->alloc_total -= sz;
2016 if (ioc->events != NULL){
2017 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2020 ioc->alloc_total -= sz;
2023 if (ioc->cached_fw != NULL) {
2024 sz = ioc->facts.FWImageSize;
2025 pci_free_consistent(ioc->pcidev, sz,
2026 ioc->cached_fw, ioc->cached_fw_dma);
2027 ioc->cached_fw = NULL;
2028 ioc->alloc_total -= sz;
2031 kfree(ioc->spi_data.nvram);
2032 kfree(ioc->raid_data.pIocPg3);
2033 ioc->spi_data.nvram = NULL;
2034 ioc->raid_data.pIocPg3 = NULL;
2036 if (ioc->spi_data.pIocPg4 != NULL) {
2037 sz = ioc->spi_data.IocPg4Sz;
2038 pci_free_consistent(ioc->pcidev, sz,
2039 ioc->spi_data.pIocPg4,
2040 ioc->spi_data.IocPg4_dma);
2041 ioc->spi_data.pIocPg4 = NULL;
2042 ioc->alloc_total -= sz;
2045 if (ioc->ReqToChain != NULL) {
2046 kfree(ioc->ReqToChain);
2047 kfree(ioc->RequestNB);
2048 ioc->ReqToChain = NULL;
2051 kfree(ioc->ChainToChain);
2052 ioc->ChainToChain = NULL;
2054 if (ioc->HostPageBuffer != NULL) {
2055 if((ret = mpt_host_page_access_control(ioc,
2056 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2057 printk(KERN_ERR MYNAM
2058 ": %s: host page buffers free failed (%d)!\n",
2061 dexitprintk((KERN_INFO MYNAM ": %s HostPageBuffer free @ %p, sz=%d bytes\n",
2062 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2063 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2064 ioc->HostPageBuffer,
2065 ioc->HostPageBuffer_dma);
2066 ioc->HostPageBuffer = NULL;
2067 ioc->HostPageBuffer_sz = 0;
2068 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2072 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2074 * mpt_adapter_dispose - Free all resources associated with a MPT
2076 * @ioc: Pointer to MPT adapter structure
2078 * This routine unregisters h/w resources and frees all alloc'd memory
2079 * associated with a MPT adapter structure.
2082 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2084 int sz_first, sz_last;
2089 sz_first = ioc->alloc_total;
2091 mpt_adapter_disable(ioc);
2093 if (ioc->pci_irq != -1) {
2094 free_irq(ioc->pci_irq, ioc);
2096 pci_disable_msi(ioc->pcidev);
2100 if (ioc->memmap != NULL) {
2101 iounmap(ioc->memmap);
2105 #if defined(CONFIG_MTRR) && 0
2106 if (ioc->mtrr_reg > 0) {
2107 mtrr_del(ioc->mtrr_reg, 0, 0);
2108 dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
2112 /* Zap the adapter lookup ptr! */
2113 list_del(&ioc->list);
2115 sz_last = ioc->alloc_total;
2116 dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
2117 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2120 ioc->alt_ioc->alt_ioc = NULL;
2125 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2127 * MptDisplayIocCapabilities - Disply IOC's capacilities.
2128 * @ioc: Pointer to MPT adapter structure
2131 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2135 printk(KERN_INFO "%s: ", ioc->name);
2136 if (ioc->prod_name && strlen(ioc->prod_name) > 3)
2137 printk("%s: ", ioc->prod_name+3);
2138 printk("Capabilities={");
2140 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2141 printk("Initiator");
2145 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2146 printk("%sTarget", i ? "," : "");
2150 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2151 printk("%sLAN", i ? "," : "");
2157 * This would probably evoke more questions than it's worth
2159 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2160 printk("%sLogBusAddr", i ? "," : "");
2168 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2170 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2171 * @ioc: Pointer to MPT_ADAPTER structure
2172 * @force: Force hard KickStart of IOC
2173 * @sleepFlag: Specifies whether the process can sleep
2176 * 1 - DIAG reset and READY
2177 * 0 - READY initially OR soft reset and READY
2178 * -1 - Any failure on KickStart
2179 * -2 - Msg Unit Reset Failed
2180 * -3 - IO Unit Reset Failed
2181 * -4 - IOC owned by a PEER
2184 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2189 int hard_reset_done = 0;
2194 /* Get current [raw] IOC state */
2195 ioc_state = mpt_GetIocState(ioc, 0);
2196 dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
2199 * Check to see if IOC got left/stuck in doorbell handshake
2200 * grip of death. If so, hard reset the IOC.
2202 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2204 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2208 /* Is it already READY? */
2209 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2213 * Check to see if IOC is in FAULT state.
2215 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2217 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2219 printk(KERN_WARNING " FAULT code = %04xh\n",
2220 ioc_state & MPI_DOORBELL_DATA_MASK);
2224 * Hmmm... Did it get left operational?
2226 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2227 dinitprintk((MYIOC_s_INFO_FMT "IOC operational unexpected\n",
2231 * If PCI Peer, exit.
2232 * Else, if no fault conditions are present, issue a MessageUnitReset
2233 * Else, fall through to KickStart case
2235 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2236 dinitprintk((KERN_INFO MYNAM
2237 ": whoinit 0x%x statefault %d force %d\n",
2238 whoinit, statefault, force));
2239 if (whoinit == MPI_WHOINIT_PCI_PEER)
2242 if ((statefault == 0 ) && (force == 0)) {
2243 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2250 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2251 if (hard_reset_done < 0)
2255 * Loop here waiting for IOC to come READY.
2258 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2260 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2261 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2263 * BIOS or previous driver load left IOC in OP state.
2264 * Reset messaging FIFOs.
2266 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2267 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2270 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2272 * Something is wrong. Try to get IOC back
2275 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2276 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2283 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2284 ioc->name, (int)((ii+5)/HZ));
2288 if (sleepFlag == CAN_SLEEP) {
2289 msleep_interruptible(1);
2291 mdelay (1); /* 1 msec delay */
2296 if (statefault < 3) {
2297 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2299 statefault==1 ? "stuck handshake" : "IOC FAULT");
2302 return hard_reset_done;
2305 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2307 * mpt_GetIocState - Get the current state of a MPT adapter.
2308 * @ioc: Pointer to MPT_ADAPTER structure
2309 * @cooked: Request raw or cooked IOC state
2311 * Returns all IOC Doorbell register bits if cooked==0, else just the
2312 * Doorbell bits in MPI_IOC_STATE_MASK.
2315 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2320 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2321 // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2322 sc = s & MPI_IOC_STATE_MASK;
2325 ioc->last_state = sc;
2327 return cooked ? sc : s;
2330 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2332 * GetIocFacts - Send IOCFacts request to MPT adapter.
2333 * @ioc: Pointer to MPT_ADAPTER structure
2334 * @sleepFlag: Specifies whether the process can sleep
2335 * @reason: If recovery, only update facts.
2337 * Returns 0 for success, non-zero for failure.
2340 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2342 IOCFacts_t get_facts;
2343 IOCFactsReply_t *facts;
2351 /* IOC *must* NOT be in RESET state! */
2352 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2353 printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2359 facts = &ioc->facts;
2361 /* Destination (reply area)... */
2362 reply_sz = sizeof(*facts);
2363 memset(facts, 0, reply_sz);
2365 /* Request area (get_facts on the stack right now!) */
2366 req_sz = sizeof(get_facts);
2367 memset(&get_facts, 0, req_sz);
2369 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2370 /* Assert: All other get_facts fields are zero! */
2372 dinitprintk((MYIOC_s_INFO_FMT
2373 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2374 ioc->name, req_sz, reply_sz));
2376 /* No non-zero fields in the get_facts request are greater than
2377 * 1 byte in size, so we can just fire it off as is.
2379 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2380 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2385 * Now byte swap (GRRR) the necessary fields before any further
2386 * inspection of reply contents.
2388 * But need to do some sanity checks on MsgLength (byte) field
2389 * to make sure we don't zero IOC's req_sz!
2391 /* Did we get a valid reply? */
2392 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2393 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2395 * If not been here, done that, save off first WhoInit value
2397 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2398 ioc->FirstWhoInit = facts->WhoInit;
2401 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2402 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2403 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2404 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2405 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2406 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2407 /* CHECKME! IOCStatus, IOCLogInfo */
2409 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2410 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2413 * FC f/w version changed between 1.1 and 1.2
2414 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2415 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2417 if (facts->MsgVersion < 0x0102) {
2419 * Handle old FC f/w style, convert to new...
2421 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2422 facts->FWVersion.Word =
2423 ((oldv<<12) & 0xFF000000) |
2424 ((oldv<<8) & 0x000FFF00);
2426 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2428 facts->ProductID = le16_to_cpu(facts->ProductID);
2429 facts->CurrentHostMfaHighAddr =
2430 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2431 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2432 facts->CurrentSenseBufferHighAddr =
2433 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2434 facts->CurReplyFrameSize =
2435 le16_to_cpu(facts->CurReplyFrameSize);
2436 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2439 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2440 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2441 * to 14 in MPI-1.01.0x.
2443 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2444 facts->MsgVersion > 0x0100) {
2445 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2448 sz = facts->FWImageSize;
2453 facts->FWImageSize = sz;
2455 if (!facts->RequestFrameSize) {
2456 /* Something is wrong! */
2457 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2462 r = sz = facts->BlockSize;
2463 vv = ((63 / (sz * 4)) + 1) & 0x03;
2464 ioc->NB_for_64_byte_frame = vv;
2470 ioc->NBShiftFactor = shiftFactor;
2471 dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2472 ioc->name, vv, shiftFactor, r));
2474 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2476 * Set values for this IOC's request & reply frame sizes,
2477 * and request & reply queue depths...
2479 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2480 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2481 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2482 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2484 dinitprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
2485 ioc->name, ioc->reply_sz, ioc->reply_depth));
2486 dinitprintk((MYIOC_s_INFO_FMT "req_sz =%3d, req_depth =%4d\n",
2487 ioc->name, ioc->req_sz, ioc->req_depth));
2489 /* Get port facts! */
2490 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2494 printk(MYIOC_s_ERR_FMT
2495 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2496 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2497 RequestFrameSize)/sizeof(u32)));
2504 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2506 * GetPortFacts - Send PortFacts request to MPT adapter.
2507 * @ioc: Pointer to MPT_ADAPTER structure
2508 * @portnum: Port number
2509 * @sleepFlag: Specifies whether the process can sleep
2511 * Returns 0 for success, non-zero for failure.
2514 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2516 PortFacts_t get_pfacts;
2517 PortFactsReply_t *pfacts;
2522 /* IOC *must* NOT be in RESET state! */
2523 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2524 printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2530 pfacts = &ioc->pfacts[portnum];
2532 /* Destination (reply area)... */
2533 reply_sz = sizeof(*pfacts);
2534 memset(pfacts, 0, reply_sz);
2536 /* Request area (get_pfacts on the stack right now!) */
2537 req_sz = sizeof(get_pfacts);
2538 memset(&get_pfacts, 0, req_sz);
2540 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2541 get_pfacts.PortNumber = portnum;
2542 /* Assert: All other get_pfacts fields are zero! */
2544 dinitprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
2545 ioc->name, portnum));
2547 /* No non-zero fields in the get_pfacts request are greater than
2548 * 1 byte in size, so we can just fire it off as is.
2550 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2551 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2555 /* Did we get a valid reply? */
2557 /* Now byte swap the necessary fields in the response. */
2558 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2559 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2560 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2561 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2562 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2563 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2564 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2565 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2566 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2571 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2573 * SendIocInit - Send IOCInit request to MPT adapter.
2574 * @ioc: Pointer to MPT_ADAPTER structure
2575 * @sleepFlag: Specifies whether the process can sleep
2577 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2579 * Returns 0 for success, non-zero for failure.
2582 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2585 MPIDefaultReply_t init_reply;
2591 memset(&ioc_init, 0, sizeof(ioc_init));
2592 memset(&init_reply, 0, sizeof(init_reply));
2594 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2595 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2597 /* If we are in a recovery mode and we uploaded the FW image,
2598 * then this pointer is not NULL. Skip the upload a second time.
2599 * Set this flag if cached_fw set for either IOC.
2601 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2605 ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
2606 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2608 if(ioc->bus_type == SAS)
2609 ioc_init.MaxDevices = ioc->facts.MaxDevices;
2610 else if(ioc->bus_type == FC)
2611 ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
2613 ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
2614 ioc_init.MaxBuses = MPT_MAX_BUS;
2615 dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n",
2616 ioc->name, ioc->facts.MsgVersion));
2617 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2618 // set MsgVersion and HeaderVersion host driver was built with
2619 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2620 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2622 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2623 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2624 } else if(mpt_host_page_alloc(ioc, &ioc_init))
2627 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2629 if (sizeof(dma_addr_t) == sizeof(u64)) {
2630 /* Save the upper 32-bits of the request
2631 * (reply) and sense buffers.
2633 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2634 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2636 /* Force 32-bit addressing */
2637 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2638 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2641 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2642 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2643 ioc->facts.MaxDevices = ioc_init.MaxDevices;
2644 ioc->facts.MaxBuses = ioc_init.MaxBuses;
2646 dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
2647 ioc->name, &ioc_init));
2649 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2650 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2652 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
2656 /* No need to byte swap the multibyte fields in the reply
2657 * since we don't even look at it's contents.
2660 dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
2661 ioc->name, &ioc_init));
2663 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
2664 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
2668 /* YIKES! SUPER IMPORTANT!!!
2669 * Poll IocState until _OPERATIONAL while IOC is doing
2670 * LoopInit and TargetDiscovery!
2673 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2674 state = mpt_GetIocState(ioc, 1);
2675 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2676 if (sleepFlag == CAN_SLEEP) {
2677 msleep_interruptible(1);
2683 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2684 ioc->name, (int)((count+5)/HZ));
2688 state = mpt_GetIocState(ioc, 1);
2691 dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2697 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2699 * SendPortEnable - Send PortEnable request to MPT adapter port.
2700 * @ioc: Pointer to MPT_ADAPTER structure
2701 * @portnum: Port number to enable
2702 * @sleepFlag: Specifies whether the process can sleep
2704 * Send PortEnable to bring IOC to OPERATIONAL state.
2706 * Returns 0 for success, non-zero for failure.
2709 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2711 PortEnable_t port_enable;
2712 MPIDefaultReply_t reply_buf;
2717 /* Destination... */
2718 reply_sz = sizeof(MPIDefaultReply_t);
2719 memset(&reply_buf, 0, reply_sz);
2721 req_sz = sizeof(PortEnable_t);
2722 memset(&port_enable, 0, req_sz);
2724 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2725 port_enable.PortNumber = portnum;
2726 /* port_enable.ChainOffset = 0; */
2727 /* port_enable.MsgFlags = 0; */
2728 /* port_enable.MsgContext = 0; */
2730 dinitprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
2731 ioc->name, portnum, &port_enable));
2733 /* RAID FW may take a long time to enable
2735 if (((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2736 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) ||
2737 (ioc->bus_type == SAS)) {
2738 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2739 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2740 300 /*seconds*/, sleepFlag);
2742 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2743 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2744 30 /*seconds*/, sleepFlag);
2750 * ioc: Pointer to MPT_ADAPTER structure
2751 * size - total FW bytes
2754 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
2757 return; /* use already allocated memory */
2758 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2759 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
2760 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
2762 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
2763 ioc->alloc_total += size;
2767 * If alt_img is NULL, delete from ioc structure.
2768 * Else, delete a secondary image in same format.
2771 mpt_free_fw_memory(MPT_ADAPTER *ioc)
2775 sz = ioc->facts.FWImageSize;
2776 dinitprintk((KERN_INFO MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
2777 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2778 pci_free_consistent(ioc->pcidev, sz,
2779 ioc->cached_fw, ioc->cached_fw_dma);
2780 ioc->cached_fw = NULL;
2786 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2788 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
2789 * @ioc: Pointer to MPT_ADAPTER structure
2790 * @sleepFlag: Specifies whether the process can sleep
2792 * Returns 0 for success, >0 for handshake failure
2793 * <0 for fw upload failure.
2795 * Remark: If bound IOC and a successful FWUpload was performed
2796 * on the bound IOC, the second image is discarded
2797 * and memory is free'd. Both channels must upload to prevent
2798 * IOC from running in degraded mode.
2801 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2803 u8 request[ioc->req_sz];
2804 u8 reply[sizeof(FWUploadReply_t)];
2805 FWUpload_t *prequest;
2806 FWUploadReply_t *preply;
2807 FWUploadTCSGE_t *ptcsge;
2810 int ii, sz, reply_sz;
2813 /* If the image size is 0, we are done.
2815 if ((sz = ioc->facts.FWImageSize) == 0)
2818 mpt_alloc_fw_memory(ioc, sz);
2820 dinitprintk((KERN_INFO MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
2821 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2823 if (ioc->cached_fw == NULL) {
2829 prequest = (FWUpload_t *)&request;
2830 preply = (FWUploadReply_t *)&reply;
2832 /* Destination... */
2833 memset(prequest, 0, ioc->req_sz);
2835 reply_sz = sizeof(reply);
2836 memset(preply, 0, reply_sz);
2838 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
2839 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
2841 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
2842 ptcsge->DetailsLength = 12;
2843 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
2844 ptcsge->ImageSize = cpu_to_le32(sz);
2846 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
2848 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
2849 mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
2851 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
2852 dinitprintk((KERN_INFO MYNAM ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
2853 prequest, sgeoffset));
2854 DBG_DUMP_FW_REQUEST_FRAME(prequest)
2856 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
2857 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
2859 dinitprintk((KERN_INFO MYNAM ": FW Upload completed rc=%x \n", ii));
2861 cmdStatus = -EFAULT;
2863 /* Handshake transfer was complete and successful.
2864 * Check the Reply Frame.
2866 int status, transfer_sz;
2867 status = le16_to_cpu(preply->IOCStatus);
2868 if (status == MPI_IOCSTATUS_SUCCESS) {
2869 transfer_sz = le32_to_cpu(preply->ActualImageSize);
2870 if (transfer_sz == sz)
2874 dinitprintk((MYIOC_s_INFO_FMT ": do_upload cmdStatus=%d \n",
2875 ioc->name, cmdStatus));
2880 ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
2882 mpt_free_fw_memory(ioc);
2888 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2890 * mpt_downloadboot - DownloadBoot code
2891 * @ioc: Pointer to MPT_ADAPTER structure
2892 * @flag: Specify which part of IOC memory is to be uploaded.
2893 * @sleepFlag: Specifies whether the process can sleep
2895 * FwDownloadBoot requires Programmed IO access.
2897 * Returns 0 for success
2898 * -1 FW Image size is 0
2899 * -2 No valid cached_fw Pointer
2900 * <0 for fw upload failure.
2903 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
2905 MpiExtImageHeader_t *pExtImage;
2915 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
2916 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
2918 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2919 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2920 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2921 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2922 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2923 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2925 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
2928 if (sleepFlag == CAN_SLEEP) {
2929 msleep_interruptible(1);
2934 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2935 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2937 for (count = 0; count < 30; count ++) {
2938 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2939 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
2940 ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
2945 if (sleepFlag == CAN_SLEEP) {
2946 msleep_interruptible (100);
2952 if ( count == 30 ) {
2953 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! "
2954 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
2955 ioc->name, diag0val));
2959 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2960 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2961 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2962 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2963 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2964 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2966 /* Set the DiagRwEn and Disable ARM bits */
2967 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
2969 fwSize = (pFwHeader->ImageSize + 3)/4;
2970 ptrFw = (u32 *) pFwHeader;
2972 /* Write the LoadStartAddress to the DiagRw Address Register
2973 * using Programmed IO
2975 if (ioc->errata_flag_1064)
2976 pci_enable_io_access(ioc->pcidev);
2978 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
2979 ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
2980 ioc->name, pFwHeader->LoadStartAddress));
2982 ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n",
2983 ioc->name, fwSize*4, ptrFw));
2985 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2988 nextImage = pFwHeader->NextImageHeaderOffset;
2990 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
2992 load_addr = pExtImage->LoadStartAddress;
2994 fwSize = (pExtImage->ImageSize + 3) >> 2;
2995 ptrFw = (u32 *)pExtImage;
2997 ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
2998 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
2999 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3002 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3004 nextImage = pExtImage->NextImageHeaderOffset;
3007 /* Write the IopResetVectorRegAddr */
3008 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3009 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3011 /* Write the IopResetVectorValue */
3012 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3013 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3015 /* Clear the internal flash bad bit - autoincrementing register,
3016 * so must do two writes.
3018 if (ioc->bus_type == SPI) {
3020 * 1030 and 1035 H/W errata, workaround to access
3021 * the ClearFlashBadSignatureBit
3023 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3024 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3025 diagRwData |= 0x40000000;
3026 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3027 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3029 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3030 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3031 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3032 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3035 if (sleepFlag == CAN_SLEEP) {
3036 msleep_interruptible (1);
3042 if (ioc->errata_flag_1064)
3043 pci_disable_io_access(ioc->pcidev);
3045 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3046 ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, "
3047 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3048 ioc->name, diag0val));
3049 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3050 ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
3051 ioc->name, diag0val));
3052 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3054 /* Write 0xFF to reset the sequencer */
3055 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3057 if (ioc->bus_type == SAS) {
3058 ioc_state = mpt_GetIocState(ioc, 0);
3059 if ( (GetIocFacts(ioc, sleepFlag,
3060 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3061 ddlprintk((MYIOC_s_INFO_FMT "GetIocFacts failed: IocState=%x\n",
3062 ioc->name, ioc_state));
3067 for (count=0; count<HZ*20; count++) {
3068 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3069 ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
3070 ioc->name, count, ioc_state));
3071 if (ioc->bus_type == SAS) {
3074 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3075 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
3079 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit successful\n",
3083 if (sleepFlag == CAN_SLEEP) {
3084 msleep_interruptible (10);
3089 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! IocState=%x\n",
3090 ioc->name, ioc_state));
3094 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3096 * KickStart - Perform hard reset of MPT adapter.
3097 * @ioc: Pointer to MPT_ADAPTER structure
3098 * @force: Force hard reset
3099 * @sleepFlag: Specifies whether the process can sleep
3101 * This routine places MPT adapter in diagnostic mode via the
3102 * WriteSequence register, and then performs a hard reset of adapter
3103 * via the Diagnostic register.
3105 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3106 * or NO_SLEEP (interrupt thread, use mdelay)
3107 * force - 1 if doorbell active, board fault state
3108 * board operational, IOC_RECOVERY or
3109 * IOC_BRINGUP and there is an alt_ioc.
3113 * 1 - hard reset, READY
3114 * 0 - no reset due to History bit, READY
3115 * -1 - no reset due to History bit but not READY
3116 * OR reset but failed to come READY
3117 * -2 - no reset, could not enter DIAG mode
3118 * -3 - reset but bad FW bit
3121 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3123 int hard_reset_done = 0;
3127 dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
3128 if (ioc->bus_type == SPI) {
3129 /* Always issue a Msg Unit Reset first. This will clear some
3130 * SCSI bus hang conditions.
3132 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3134 if (sleepFlag == CAN_SLEEP) {
3135 msleep_interruptible (1000);
3141 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3142 if (hard_reset_done < 0)
3143 return hard_reset_done;
3145 dinitprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
3148 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3149 for (cnt=0; cnt<cntdn; cnt++) {
3150 ioc_state = mpt_GetIocState(ioc, 1);
3151 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3152 dinitprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
3154 return hard_reset_done;
3156 if (sleepFlag == CAN_SLEEP) {
3157 msleep_interruptible (10);
3163 printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3164 ioc->name, ioc_state);
3168 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3170 * mpt_diag_reset - Perform hard reset of the adapter.
3171 * @ioc: Pointer to MPT_ADAPTER structure
3172 * @ignore: Set if to honor and clear to ignore
3173 * the reset history bit
3174 * @sleepflag: CAN_SLEEP if called in a non-interrupt thread,
3175 * else set to NO_SLEEP (use mdelay instead)
3177 * This routine places the adapter in diagnostic mode via the
3178 * WriteSequence register and then performs a hard reset of adapter
3179 * via the Diagnostic register. Adapter should be in ready state
3180 * upon successful completion.
3182 * Returns: 1 hard reset successful
3183 * 0 no reset performed because reset history bit set
3184 * -2 enabling diagnostic mode failed
3185 * -3 diagnostic reset failed
3188 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3192 int hard_reset_done = 0;
3198 /* Clear any existing interrupts */
3199 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3201 /* Use "Diagnostic reset" method! (only thing available!) */
3202 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3206 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3207 dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3208 ioc->name, diag0val, diag1val));
3211 /* Do the reset if we are told to ignore the reset history
3212 * or if the reset history is 0
3214 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3215 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3216 /* Write magic sequence to WriteSequence register
3217 * Loop until in diagnostic mode
3219 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3220 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3221 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3222 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3223 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3224 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3227 if (sleepFlag == CAN_SLEEP) {
3228 msleep_interruptible (100);
3235 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3236 ioc->name, diag0val);
3241 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3243 dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3244 ioc->name, diag0val));
3249 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3250 dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3251 ioc->name, diag0val, diag1val));
3254 * Disable the ARM (Bug fix)
3257 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3261 * Now hit the reset bit in the Diagnostic register
3262 * (THE BIG HAMMER!) (Clears DRWE bit).
3264 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3265 hard_reset_done = 1;
3266 dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
3270 * Call each currently registered protocol IOC reset handler
3271 * with pre-reset indication.
3272 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3273 * MptResetHandlers[] registered yet.
3279 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
3280 if (MptResetHandlers[ii]) {
3281 dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
3283 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_PRE_RESET);
3285 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3286 ioc->name, ioc->alt_ioc->name, ii));
3287 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_PRE_RESET);
3291 /* FIXME? Examine results here? */
3294 if (ioc->cached_fw) {
3295 /* If the DownloadBoot operation fails, the
3296 * IOC will be left unusable. This is a fatal error
3297 * case. _diag_reset will return < 0
3299 for (count = 0; count < 30; count ++) {
3300 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3301 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3306 if (sleepFlag == CAN_SLEEP) {
3307 msleep_interruptible (1000);
3312 if ((count = mpt_downloadboot(ioc,
3313 (MpiFwHeader_t *)ioc->cached_fw, sleepFlag)) < 0) {
3314 printk(KERN_WARNING MYNAM
3315 ": firmware downloadboot failure (%d)!\n", count);
3319 /* Wait for FW to reload and for board
3320 * to go to the READY state.
3321 * Maximum wait is 60 seconds.
3322 * If fail, no error will check again
3323 * with calling program.
3325 for (count = 0; count < 60; count ++) {
3326 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3327 doorbell &= MPI_IOC_STATE_MASK;
3329 if (doorbell == MPI_IOC_STATE_READY) {
3334 if (sleepFlag == CAN_SLEEP) {
3335 msleep_interruptible (1000);
3343 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3346 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3347 dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3348 ioc->name, diag0val, diag1val));
3351 /* Clear RESET_HISTORY bit! Place board in the
3352 * diagnostic mode to update the diag register.
3354 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3356 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3357 /* Write magic sequence to WriteSequence register
3358 * Loop until in diagnostic mode
3360 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3361 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3362 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3363 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3364 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3365 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3368 if (sleepFlag == CAN_SLEEP) {
3369 msleep_interruptible (100);
3376 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3377 ioc->name, diag0val);
3380 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3382 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3383 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3384 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3385 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3386 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3390 /* Disable Diagnostic Mode
3392 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3394 /* Check FW reload status flags.
3396 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3397 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3398 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3399 ioc->name, diag0val);
3405 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3406 dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3407 ioc->name, diag0val, diag1val));
3411 * Reset flag that says we've enabled event notification
3413 ioc->facts.EventState = 0;
3416 ioc->alt_ioc->facts.EventState = 0;
3418 return hard_reset_done;
3421 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3423 * SendIocReset - Send IOCReset request to MPT adapter.
3424 * @ioc: Pointer to MPT_ADAPTER structure
3425 * @reset_type: reset type, expected values are
3426 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3428 * Send IOCReset request to the MPT adapter.
3430 * Returns 0 for success, non-zero for failure.
3433 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3439 drsprintk((KERN_INFO MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
3440 ioc->name, reset_type));
3441 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3442 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3445 /* FW ACK'd request, wait for READY state
3448 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3450 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3454 if (sleepFlag != CAN_SLEEP)
3457 printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3458 ioc->name, (int)((count+5)/HZ));
3462 if (sleepFlag == CAN_SLEEP) {
3463 msleep_interruptible(1);
3465 mdelay (1); /* 1 msec delay */
3470 * Cleanup all event stuff for this IOC; re-issue EventNotification
3471 * request if needed.
3473 if (ioc->facts.Function)
3474 ioc->facts.EventState = 0;
3479 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3481 * initChainBuffers - Allocate memory for and initialize
3482 * chain buffers, chain buffer control arrays and spinlock.
3483 * @hd: Pointer to MPT_SCSI_HOST structure
3484 * @init: If set, initialize the spin lock.
3487 initChainBuffers(MPT_ADAPTER *ioc)
3490 int sz, ii, num_chain;
3491 int scale, num_sge, numSGE;
3493 /* ReqToChain size must equal the req_depth
3496 if (ioc->ReqToChain == NULL) {
3497 sz = ioc->req_depth * sizeof(int);
3498 mem = kmalloc(sz, GFP_ATOMIC);
3502 ioc->ReqToChain = (int *) mem;
3503 dinitprintk((KERN_INFO MYNAM ": %s ReqToChain alloc @ %p, sz=%d bytes\n",
3504 ioc->name, mem, sz));
3505 mem = kmalloc(sz, GFP_ATOMIC);
3509 ioc->RequestNB = (int *) mem;
3510 dinitprintk((KERN_INFO MYNAM ": %s RequestNB alloc @ %p, sz=%d bytes\n",
3511 ioc->name, mem, sz));
3513 for (ii = 0; ii < ioc->req_depth; ii++) {
3514 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3517 /* ChainToChain size must equal the total number
3518 * of chain buffers to be allocated.
3521 * Calculate the number of chain buffers needed(plus 1) per I/O
3522 * then multiply the the maximum number of simultaneous cmds
3524 * num_sge = num sge in request frame + last chain buffer
3525 * scale = num sge per chain buffer if no chain element
3527 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3528 if (sizeof(dma_addr_t) == sizeof(u64))
3529 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3531 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3533 if (sizeof(dma_addr_t) == sizeof(u64)) {
3534 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3535 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3537 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3538 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3540 dinitprintk((KERN_INFO MYNAM ": %s num_sge=%d numSGE=%d\n",
3541 ioc->name, num_sge, numSGE));
3543 if ( numSGE > MPT_SCSI_SG_DEPTH )
3544 numSGE = MPT_SCSI_SG_DEPTH;
3547 while (numSGE - num_sge > 0) {
3549 num_sge += (scale - 1);
3553 dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
3554 ioc->name, numSGE, num_sge, num_chain));
3556 if (ioc->bus_type == SPI)
3557 num_chain *= MPT_SCSI_CAN_QUEUE;
3559 num_chain *= MPT_FC_CAN_QUEUE;
3561 ioc->num_chain = num_chain;
3563 sz = num_chain * sizeof(int);
3564 if (ioc->ChainToChain == NULL) {
3565 mem = kmalloc(sz, GFP_ATOMIC);
3569 ioc->ChainToChain = (int *) mem;
3570 dinitprintk((KERN_INFO MYNAM ": %s ChainToChain alloc @ %p, sz=%d bytes\n",
3571 ioc->name, mem, sz));
3573 mem = (u8 *) ioc->ChainToChain;
3575 memset(mem, 0xFF, sz);
3579 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3581 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3582 * @ioc: Pointer to MPT_ADAPTER structure
3584 * This routine allocates memory for the MPT reply and request frame
3585 * pools (if necessary), and primes the IOC reply FIFO with
3588 * Returns 0 for success, non-zero for failure.
3591 PrimeIocFifos(MPT_ADAPTER *ioc)
3594 unsigned long flags;
3595 dma_addr_t alloc_dma;
3597 int i, reply_sz, sz, total_size, num_chain;
3599 /* Prime reply FIFO... */
3601 if (ioc->reply_frames == NULL) {
3602 if ( (num_chain = initChainBuffers(ioc)) < 0)
3605 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3606 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3607 ioc->name, ioc->reply_sz, ioc->reply_depth));
3608 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d[%x] bytes\n",
3609 ioc->name, reply_sz, reply_sz));
3611 sz = (ioc->req_sz * ioc->req_depth);
3612 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3613 ioc->name, ioc->req_sz, ioc->req_depth));
3614 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d[%x] bytes\n",
3615 ioc->name, sz, sz));
3618 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3619 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3620 ioc->name, ioc->req_sz, num_chain));
3621 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3622 ioc->name, sz, sz, num_chain));
3625 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3627 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3632 dinitprintk((KERN_INFO MYNAM ": %s.Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3633 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3635 memset(mem, 0, total_size);
3636 ioc->alloc_total += total_size;
3638 ioc->alloc_dma = alloc_dma;
3639 ioc->alloc_sz = total_size;
3640 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3641 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3643 dinitprintk((KERN_INFO MYNAM ": %s ReplyBuffers @ %p[%p]\n",
3644 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3646 alloc_dma += reply_sz;
3649 /* Request FIFO - WE manage this! */
3651 ioc->req_frames = (MPT_FRAME_HDR *) mem;
3652 ioc->req_frames_dma = alloc_dma;
3654 dinitprintk((KERN_INFO MYNAM ": %s RequestBuffers @ %p[%p]\n",
3655 ioc->name, mem, (void *)(ulong)alloc_dma));
3657 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3659 #if defined(CONFIG_MTRR) && 0
3661 * Enable Write Combining MTRR for IOC's memory region.
3662 * (at least as much as we can; "size and base must be
3663 * multiples of 4 kiB"
3665 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
3667 MTRR_TYPE_WRCOMB, 1);
3668 dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
3669 ioc->name, ioc->req_frames_dma, sz));
3672 for (i = 0; i < ioc->req_depth; i++) {
3673 alloc_dma += ioc->req_sz;
3677 ioc->ChainBuffer = mem;
3678 ioc->ChainBufferDMA = alloc_dma;
3680 dinitprintk((KERN_INFO MYNAM " :%s ChainBuffers @ %p(%p)\n",
3681 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
3683 /* Initialize the free chain Q.
3686 INIT_LIST_HEAD(&ioc->FreeChainQ);
3688 /* Post the chain buffers to the FreeChainQ.
3690 mem = (u8 *)ioc->ChainBuffer;
3691 for (i=0; i < num_chain; i++) {
3692 mf = (MPT_FRAME_HDR *) mem;
3693 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
3697 /* Initialize Request frames linked list
3699 alloc_dma = ioc->req_frames_dma;
3700 mem = (u8 *) ioc->req_frames;
3702 spin_lock_irqsave(&ioc->FreeQlock, flags);
3703 INIT_LIST_HEAD(&ioc->FreeQ);
3704 for (i = 0; i < ioc->req_depth; i++) {
3705 mf = (MPT_FRAME_HDR *) mem;
3707 /* Queue REQUESTs *internally*! */
3708 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
3712 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3714 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3715 ioc->sense_buf_pool =
3716 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3717 if (ioc->sense_buf_pool == NULL) {
3718 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
3723 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
3724 ioc->alloc_total += sz;
3725 dinitprintk((KERN_INFO MYNAM ": %s.SenseBuffers @ %p[%p]\n",
3726 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
3730 /* Post Reply frames to FIFO
3732 alloc_dma = ioc->alloc_dma;
3733 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffers @ %p[%p]\n",
3734 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3736 for (i = 0; i < ioc->reply_depth; i++) {
3737 /* Write each address to the IOC! */
3738 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
3739 alloc_dma += ioc->reply_sz;
3745 if (ioc->alloc != NULL) {
3747 pci_free_consistent(ioc->pcidev,
3749 ioc->alloc, ioc->alloc_dma);
3750 ioc->reply_frames = NULL;
3751 ioc->req_frames = NULL;
3752 ioc->alloc_total -= sz;
3754 if (ioc->sense_buf_pool != NULL) {
3755 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3756 pci_free_consistent(ioc->pcidev,
3758 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
3759 ioc->sense_buf_pool = NULL;
3764 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3766 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3767 * from IOC via doorbell handshake method.
3768 * @ioc: Pointer to MPT_ADAPTER structure
3769 * @reqBytes: Size of the request in bytes
3770 * @req: Pointer to MPT request frame
3771 * @replyBytes: Expected size of the reply in bytes
3772 * @u16reply: Pointer to area where reply should be written
3773 * @maxwait: Max wait time for a reply (in seconds)
3774 * @sleepFlag: Specifies whether the process can sleep
3776 * NOTES: It is the callers responsibility to byte-swap fields in the
3777 * request which are greater than 1 byte in size. It is also the
3778 * callers responsibility to byte-swap response fields which are
3779 * greater than 1 byte in size.
3781 * Returns 0 for success, non-zero for failure.
3784 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
3785 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
3787 MPIDefaultReply_t *mptReply;
3792 * Get ready to cache a handshake reply
3794 ioc->hs_reply_idx = 0;
3795 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3796 mptReply->MsgLength = 0;
3799 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
3800 * then tell IOC that we want to handshake a request of N words.
3801 * (WRITE u32val to Doorbell reg).
3803 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3804 CHIPREG_WRITE32(&ioc->chip->Doorbell,
3805 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
3806 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
3809 * Wait for IOC's doorbell handshake int
3811 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3814 dhsprintk((MYIOC_s_INFO_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
3815 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3817 /* Read doorbell and check for active bit */
3818 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
3822 * Clear doorbell int (WRITE 0 to IntStatus reg),
3823 * then wait for IOC to ACKnowledge that it's ready for
3824 * our handshake request.
3826 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3827 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3832 u8 *req_as_bytes = (u8 *) req;
3835 * Stuff request words via doorbell handshake,
3836 * with ACK from IOC for each.
3838 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
3839 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
3840 (req_as_bytes[(ii*4) + 1] << 8) |
3841 (req_as_bytes[(ii*4) + 2] << 16) |
3842 (req_as_bytes[(ii*4) + 3] << 24));
3844 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
3845 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3849 dhsprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
3850 DBG_DUMP_REQUEST_FRAME_HDR(req)
3852 dhsprintk((MYIOC_s_INFO_FMT "HandShake request post done, WaitCnt=%d%s\n",
3853 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
3856 * Wait for completion of doorbell handshake reply from the IOC
3858 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
3861 dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n",
3862 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
3865 * Copy out the cached reply...
3867 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
3868 u16reply[ii] = ioc->hs_reply[ii];
3876 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3878 * WaitForDoorbellAck - Wait for IOC to clear the IOP_DOORBELL_STATUS bit
3879 * in it's IntStatus register.
3880 * @ioc: Pointer to MPT_ADAPTER structure
3881 * @howlong: How long to wait (in seconds)
3882 * @sleepFlag: Specifies whether the process can sleep
3884 * This routine waits (up to ~2 seconds max) for IOC doorbell
3885 * handshake ACKnowledge.
3887 * Returns a negative value on failure, else wait loop count.
3890 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3896 cntdn = 1000 * howlong;
3898 if (sleepFlag == CAN_SLEEP) {
3900 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3901 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3903 msleep_interruptible (1);
3908 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3909 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3917 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (count=%d)\n",
3922 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
3923 ioc->name, count, intstat);
3927 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3929 * WaitForDoorbellInt - Wait for IOC to set the HIS_DOORBELL_INTERRUPT bit
3930 * in it's IntStatus register.
3931 * @ioc: Pointer to MPT_ADAPTER structure
3932 * @howlong: How long to wait (in seconds)
3933 * @sleepFlag: Specifies whether the process can sleep
3935 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt.
3937 * Returns a negative value on failure, else wait loop count.
3940 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3946 cntdn = 1000 * howlong;
3947 if (sleepFlag == CAN_SLEEP) {
3949 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3950 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3952 msleep_interruptible(1);
3957 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3958 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3966 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
3967 ioc->name, count, howlong));
3971 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
3972 ioc->name, count, intstat);
3976 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3978 * WaitForDoorbellReply - Wait for and capture a IOC handshake reply.
3979 * @ioc: Pointer to MPT_ADAPTER structure
3980 * @howlong: How long to wait (in seconds)
3981 * @sleepFlag: Specifies whether the process can sleep
3983 * This routine polls the IOC for a handshake reply, 16 bits at a time.
3984 * Reply is cached to IOC private area large enough to hold a maximum
3985 * of 128 bytes of reply data.
3987 * Returns a negative value on failure, else size of reply in WORDS.
3990 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3995 u16 *hs_reply = ioc->hs_reply;
3996 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3999 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4002 * Get first two u16's so we can look at IOC's intended reply MsgLength
4005 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4008 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4009 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4010 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4013 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4014 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4018 dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4019 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4020 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4023 * If no error (and IOC said MsgLength is > 0), piece together
4024 * reply 16 bits at a time.
4026 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4027 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4029 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4030 /* don't overflow our IOC hs_reply[] buffer! */
4031 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4032 hs_reply[u16cnt] = hword;
4033 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4036 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4038 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4041 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4046 else if (u16cnt != (2 * mptReply->MsgLength)) {
4049 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4054 dhsprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
4055 DBG_DUMP_REPLY_FRAME(mptReply)
4057 dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4058 ioc->name, t, u16cnt/2));
4062 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4064 * GetLanConfigPages - Fetch LANConfig pages.
4065 * @ioc: Pointer to MPT_ADAPTER structure
4067 * Return: 0 for success
4068 * -ENOMEM if no memory available
4069 * -EPERM if not allowed due to ISR context
4070 * -EAGAIN if no msg frames currently available
4071 * -EFAULT for non-successful reply or no reply (timeout)
4074 GetLanConfigPages(MPT_ADAPTER *ioc)
4076 ConfigPageHeader_t hdr;
4078 LANPage0_t *ppage0_alloc;
4079 dma_addr_t page0_dma;
4080 LANPage1_t *ppage1_alloc;
4081 dma_addr_t page1_dma;
4086 /* Get LAN Page 0 header */
4087 hdr.PageVersion = 0;
4090 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4091 cfg.cfghdr.hdr = &hdr;
4093 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4098 if ((rc = mpt_config(ioc, &cfg)) != 0)
4101 if (hdr.PageLength > 0) {
4102 data_sz = hdr.PageLength * 4;
4103 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4106 memset((u8 *)ppage0_alloc, 0, data_sz);
4107 cfg.physAddr = page0_dma;
4108 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4110 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4112 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4113 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4117 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4120 * Normalize endianness of structure data,
4121 * by byte-swapping all > 1 byte fields!
4130 /* Get LAN Page 1 header */
4131 hdr.PageVersion = 0;
4134 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4135 cfg.cfghdr.hdr = &hdr;
4137 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4141 if ((rc = mpt_config(ioc, &cfg)) != 0)
4144 if (hdr.PageLength == 0)
4147 data_sz = hdr.PageLength * 4;
4149 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4151 memset((u8 *)ppage1_alloc, 0, data_sz);
4152 cfg.physAddr = page1_dma;
4153 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4155 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4157 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4158 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4161 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4164 * Normalize endianness of structure data,
4165 * by byte-swapping all > 1 byte fields!
4173 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4175 * mptbase_GetFcPortPage0 - Fetch FCPort config Page0.
4176 * @ioc: Pointer to MPT_ADAPTER structure
4177 * @portnum: IOC Port number
4179 * Return: 0 for success
4180 * -ENOMEM if no memory available
4181 * -EPERM if not allowed due to ISR context
4182 * -EAGAIN if no msg frames currently available
4183 * -EFAULT for non-successful reply or no reply (timeout)
4186 mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
4188 ConfigPageHeader_t hdr;
4190 FCPortPage0_t *ppage0_alloc;
4191 FCPortPage0_t *pp0dest;
4192 dma_addr_t page0_dma;
4199 /* Get FCPort Page 0 header */
4200 hdr.PageVersion = 0;
4203 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
4204 cfg.cfghdr.hdr = &hdr;
4206 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4208 cfg.pageAddr = portnum;
4211 if ((rc = mpt_config(ioc, &cfg)) != 0)
4214 if (hdr.PageLength == 0)
4217 data_sz = hdr.PageLength * 4;
4219 ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4223 memset((u8 *)ppage0_alloc, 0, data_sz);
4224 cfg.physAddr = page0_dma;
4225 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4227 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4229 pp0dest = &ioc->fc_port_page0[portnum];
4230 copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
4231 memcpy(pp0dest, ppage0_alloc, copy_sz);
4234 * Normalize endianness of structure data,
4235 * by byte-swapping all > 1 byte fields!
4237 pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
4238 pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
4239 pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
4240 pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
4241 pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
4242 pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
4243 pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
4244 pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
4245 pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
4246 pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
4247 pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
4248 pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
4249 pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
4250 pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
4251 pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
4252 pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
4255 * if still doing discovery,
4256 * hang loose a while until finished
4258 if (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) {
4260 msleep_interruptible(100);
4263 printk(MYIOC_s_INFO_FMT "Firmware discovery not"
4269 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4275 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4277 * mptbase_sas_persist_operation - Perform operation on SAS Persitent Table
4278 * @ioc: Pointer to MPT_ADAPTER structure
4279 * @sas_address: 64bit SAS Address for operation.
4280 * @target_id: specified target for operation
4281 * @bus: specified bus for operation
4282 * @persist_opcode: see below
4284 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4285 * devices not currently present.
4286 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4288 * NOTE: Don't use not this function during interrupt time.
4290 * Returns: 0 for success, non-zero error
4293 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4295 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4297 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4298 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4299 MPT_FRAME_HDR *mf = NULL;
4300 MPIHeader_t *mpi_hdr;
4303 /* insure garbage is not sent to fw */
4304 switch(persist_opcode) {
4306 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4307 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4315 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4317 /* Get a MF for this command.
4319 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4320 printk("%s: no msg frames!\n",__FUNCTION__);
4324 mpi_hdr = (MPIHeader_t *) mf;
4325 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4326 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4327 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4328 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4329 sasIoUnitCntrReq->Operation = persist_opcode;
4331 init_timer(&ioc->persist_timer);
4332 ioc->persist_timer.data = (unsigned long) ioc;
4333 ioc->persist_timer.function = mpt_timer_expired;
4334 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4335 ioc->persist_wait_done=0;
4336 add_timer(&ioc->persist_timer);
4337 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4338 wait_event(mpt_waitq, ioc->persist_wait_done);
4340 sasIoUnitCntrReply =
4341 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4342 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4343 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4345 sasIoUnitCntrReply->IOCStatus,
4346 sasIoUnitCntrReply->IOCLogInfo);
4350 printk("%s: success\n",__FUNCTION__);
4354 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4357 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4358 MpiEventDataRaid_t * pRaidEventData)
4367 volume = pRaidEventData->VolumeID;
4368 reason = pRaidEventData->ReasonCode;
4369 disk = pRaidEventData->PhysDiskNum;
4370 status = le32_to_cpu(pRaidEventData->SettingsStatus);
4371 flags = (status >> 0) & 0xff;
4372 state = (status >> 8) & 0xff;
4374 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4378 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4379 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4380 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4381 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d\n",
4384 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4389 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4390 printk(MYIOC_s_INFO_FMT " volume has been created\n",
4394 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4396 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
4400 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4401 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
4405 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4406 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
4408 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4410 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4412 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4415 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4417 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4418 ? ", quiesced" : "",
4419 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4420 ? ", resync in progress" : "" );
4423 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4424 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
4428 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4429 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
4433 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4434 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
4438 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4439 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
4443 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4444 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
4446 state == MPI_PHYSDISK0_STATUS_ONLINE
4448 : state == MPI_PHYSDISK0_STATUS_MISSING
4450 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4452 : state == MPI_PHYSDISK0_STATUS_FAILED
4454 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4456 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4457 ? "offline requested"
4458 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4459 ? "failed requested"
4460 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4463 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4464 ? ", out of sync" : "",
4465 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4466 ? ", quiesced" : "" );
4469 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4470 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
4474 case MPI_EVENT_RAID_RC_SMART_DATA:
4475 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4476 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4479 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4480 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
4486 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4488 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4489 * @ioc: Pointer to MPT_ADAPTER structure
4491 * Returns: 0 for success
4492 * -ENOMEM if no memory available
4493 * -EPERM if not allowed due to ISR context
4494 * -EAGAIN if no msg frames currently available
4495 * -EFAULT for non-successful reply or no reply (timeout)
4498 GetIoUnitPage2(MPT_ADAPTER *ioc)
4500 ConfigPageHeader_t hdr;
4502 IOUnitPage2_t *ppage_alloc;
4503 dma_addr_t page_dma;
4507 /* Get the page header */
4508 hdr.PageVersion = 0;
4511 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4512 cfg.cfghdr.hdr = &hdr;
4514 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4519 if ((rc = mpt_config(ioc, &cfg)) != 0)
4522 if (hdr.PageLength == 0)
4525 /* Read the config page */
4526 data_sz = hdr.PageLength * 4;
4528 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4530 memset((u8 *)ppage_alloc, 0, data_sz);
4531 cfg.physAddr = page_dma;
4532 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4534 /* If Good, save data */
4535 if ((rc = mpt_config(ioc, &cfg)) == 0)
4536 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4538 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4544 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4545 /* mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4546 * @ioc: Pointer to a Adapter Strucutre
4547 * @portnum: IOC port number
4549 * Return: -EFAULT if read of config page header fails
4551 * If read of SCSI Port Page 0 fails,
4552 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4553 * Adapter settings: async, narrow
4555 * If read of SCSI Port Page 2 fails,
4556 * Adapter settings valid
4557 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4562 * CHECK - what type of locking mechanisms should be used????
4565 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4570 ConfigPageHeader_t header;
4576 if (!ioc->spi_data.nvram) {
4579 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4580 mem = kmalloc(sz, GFP_ATOMIC);
4584 ioc->spi_data.nvram = (int *) mem;
4586 dprintk((MYIOC_s_INFO_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4587 ioc->name, ioc->spi_data.nvram, sz));
4590 /* Invalidate NVRAM information
4592 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4593 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4596 /* Read SPP0 header, allocate memory, then read page.
4598 header.PageVersion = 0;
4599 header.PageLength = 0;
4600 header.PageNumber = 0;
4601 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4602 cfg.cfghdr.hdr = &header;
4604 cfg.pageAddr = portnum;
4605 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4607 cfg.timeout = 0; /* use default */
4608 if (mpt_config(ioc, &cfg) != 0)
4611 if (header.PageLength > 0) {
4612 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4614 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4615 cfg.physAddr = buf_dma;
4616 if (mpt_config(ioc, &cfg) != 0) {
4617 ioc->spi_data.maxBusWidth = MPT_NARROW;
4618 ioc->spi_data.maxSyncOffset = 0;
4619 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4620 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4622 ddvprintk((MYIOC_s_INFO_FMT "Unable to read PortPage0 minSyncFactor=%x\n",
4623 ioc->name, ioc->spi_data.minSyncFactor));
4625 /* Save the Port Page 0 data
4627 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4628 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4629 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4631 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4632 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4633 ddvprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
4634 ioc->name, pPP0->Capabilities));
4636 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4637 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4639 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4640 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4641 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4642 ddvprintk((MYIOC_s_INFO_FMT "PortPage0 minSyncFactor=%x\n",
4643 ioc->name, ioc->spi_data.minSyncFactor));
4645 ioc->spi_data.maxSyncOffset = 0;
4646 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4649 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4651 /* Update the minSyncFactor based on bus type.
4653 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4654 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4656 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4657 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4658 ddvprintk((MYIOC_s_INFO_FMT "HVD or SE detected, minSyncFactor=%x\n",
4659 ioc->name, ioc->spi_data.minSyncFactor));
4664 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4669 /* SCSI Port Page 2 - Read the header then the page.
4671 header.PageVersion = 0;
4672 header.PageLength = 0;
4673 header.PageNumber = 2;
4674 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4675 cfg.cfghdr.hdr = &header;
4677 cfg.pageAddr = portnum;
4678 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4680 if (mpt_config(ioc, &cfg) != 0)
4683 if (header.PageLength > 0) {
4684 /* Allocate memory and read SCSI Port Page 2
4686 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4688 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4689 cfg.physAddr = buf_dma;
4690 if (mpt_config(ioc, &cfg) != 0) {
4691 /* Nvram data is left with INVALID mark
4695 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4696 MpiDeviceInfo_t *pdevice = NULL;
4699 * Save "Set to Avoid SCSI Bus Resets" flag
4701 ioc->spi_data.bus_reset =
4702 (le32_to_cpu(pPP2->PortFlags) &
4703 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
4706 /* Save the Port Page 2 data
4707 * (reformat into a 32bit quantity)
4709 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4710 ioc->spi_data.PortFlags = data;
4711 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4712 pdevice = &pPP2->DeviceSettings[ii];
4713 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4714 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4715 ioc->spi_data.nvram[ii] = data;
4719 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4723 /* Update Adapter limits with those from NVRAM
4724 * Comment: Don't need to do this. Target performance
4725 * parameters will never exceed the adapters limits.
4731 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4732 /* mpt_readScsiDevicePageHeaders - save version and length of SDP1
4733 * @ioc: Pointer to a Adapter Strucutre
4734 * @portnum: IOC port number
4736 * Return: -EFAULT if read of config page header fails
4740 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4743 ConfigPageHeader_t header;
4745 /* Read the SCSI Device Page 1 header
4747 header.PageVersion = 0;
4748 header.PageLength = 0;
4749 header.PageNumber = 1;
4750 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4751 cfg.cfghdr.hdr = &header;
4753 cfg.pageAddr = portnum;
4754 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4757 if (mpt_config(ioc, &cfg) != 0)
4760 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
4761 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
4763 header.PageVersion = 0;
4764 header.PageLength = 0;
4765 header.PageNumber = 0;
4766 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4767 if (mpt_config(ioc, &cfg) != 0)
4770 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
4771 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
4773 dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
4774 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
4776 dcprintk((MYIOC_s_INFO_FMT "Headers: 1: version %d length %d\n",
4777 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
4781 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4783 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4784 * @ioc: Pointer to a Adapter Strucutre
4785 * @portnum: IOC port number
4789 * -EFAULT if read of config page header fails or data pointer not NULL
4790 * -ENOMEM if pci_alloc failed
4793 mpt_findImVolumes(MPT_ADAPTER *ioc)
4797 ConfigPageIoc2RaidVol_t *pIocRv;
4798 dma_addr_t ioc2_dma;
4800 ConfigPageHeader_t header;
4807 /* Read IOCP2 header then the page.
4809 header.PageVersion = 0;
4810 header.PageLength = 0;
4811 header.PageNumber = 2;
4812 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4813 cfg.cfghdr.hdr = &header;
4816 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4819 if (mpt_config(ioc, &cfg) != 0)
4822 if (header.PageLength == 0)
4825 iocpage2sz = header.PageLength * 4;
4826 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
4830 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4831 cfg.physAddr = ioc2_dma;
4832 if (mpt_config(ioc, &cfg) != 0)
4835 if ( (mem = (u8 *)ioc->raid_data.pIocPg2) == NULL ) {
4836 mem = kmalloc(iocpage2sz, GFP_ATOMIC);
4838 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
4843 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
4845 /* Identify RAID Volume Id's */
4846 nVols = pIoc2->NumActiveVolumes;
4852 /* At least 1 RAID Volume
4854 pIocRv = pIoc2->RaidVolume;
4855 ioc->raid_data.isRaid = 0;
4856 for (jj = 0; jj < nVols; jj++, pIocRv++) {
4857 vid = pIocRv->VolumeID;
4858 vbus = pIocRv->VolumeBus;
4859 vioc = pIocRv->VolumeIOC;
4864 ioc->raid_data.isRaid |= (1 << vid);
4866 /* Error! Always bus 0
4872 /* Identify Hidden Physical Disk Id's */
4873 nPhys = pIoc2->NumActivePhysDisks;
4875 /* No physical disks.
4878 mpt_read_ioc_pg_3(ioc);
4882 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
4888 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
4893 ConfigPageHeader_t header;
4894 dma_addr_t ioc3_dma;
4897 /* Free the old page
4899 kfree(ioc->raid_data.pIocPg3);
4900 ioc->raid_data.pIocPg3 = NULL;
4902 /* There is at least one physical disk.
4903 * Read and save IOC Page 3
4905 header.PageVersion = 0;
4906 header.PageLength = 0;
4907 header.PageNumber = 3;
4908 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4909 cfg.cfghdr.hdr = &header;
4912 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4915 if (mpt_config(ioc, &cfg) != 0)
4918 if (header.PageLength == 0)
4921 /* Read Header good, alloc memory
4923 iocpage3sz = header.PageLength * 4;
4924 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
4928 /* Read the Page and save the data
4929 * into malloc'd memory.
4931 cfg.physAddr = ioc3_dma;
4932 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4933 if (mpt_config(ioc, &cfg) == 0) {
4934 mem = kmalloc(iocpage3sz, GFP_ATOMIC);
4936 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
4937 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
4941 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
4947 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
4951 ConfigPageHeader_t header;
4952 dma_addr_t ioc4_dma;
4955 /* Read and save IOC Page 4
4957 header.PageVersion = 0;
4958 header.PageLength = 0;
4959 header.PageNumber = 4;
4960 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4961 cfg.cfghdr.hdr = &header;
4964 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4967 if (mpt_config(ioc, &cfg) != 0)
4970 if (header.PageLength == 0)
4973 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
4974 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
4975 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
4979 ioc4_dma = ioc->spi_data.IocPg4_dma;
4980 iocpage4sz = ioc->spi_data.IocPg4Sz;
4983 /* Read the Page into dma memory.
4985 cfg.physAddr = ioc4_dma;
4986 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4987 if (mpt_config(ioc, &cfg) == 0) {
4988 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
4989 ioc->spi_data.IocPg4_dma = ioc4_dma;
4990 ioc->spi_data.IocPg4Sz = iocpage4sz;
4992 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
4993 ioc->spi_data.pIocPg4 = NULL;
4998 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5002 ConfigPageHeader_t header;
5003 dma_addr_t ioc1_dma;
5007 /* Check the Coalescing Timeout in IOC Page 1
5009 header.PageVersion = 0;
5010 header.PageLength = 0;
5011 header.PageNumber = 1;
5012 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5013 cfg.cfghdr.hdr = &header;
5016 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5019 if (mpt_config(ioc, &cfg) != 0)
5022 if (header.PageLength == 0)
5025 /* Read Header good, alloc memory
5027 iocpage1sz = header.PageLength * 4;
5028 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5032 /* Read the Page and check coalescing timeout
5034 cfg.physAddr = ioc1_dma;
5035 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5036 if (mpt_config(ioc, &cfg) == 0) {
5038 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5039 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5040 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5042 dprintk((MYIOC_s_INFO_FMT "Coalescing Enabled Timeout = %d\n",
5045 if (tmp > MPT_COALESCING_TIMEOUT) {
5046 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5048 /* Write NVRAM and current
5051 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5052 if (mpt_config(ioc, &cfg) == 0) {
5053 dprintk((MYIOC_s_INFO_FMT "Reset Current Coalescing Timeout to = %d\n",
5054 ioc->name, MPT_COALESCING_TIMEOUT));
5056 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5057 if (mpt_config(ioc, &cfg) == 0) {
5058 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout to = %d\n",
5059 ioc->name, MPT_COALESCING_TIMEOUT));
5061 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout Failed\n",
5066 dprintk((MYIOC_s_WARN_FMT "Reset of Current Coalescing Timeout Failed!\n",
5072 dprintk((MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5076 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5081 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5083 * SendEventNotification - Send EventNotification (on or off) request
5085 * @ioc: Pointer to MPT_ADAPTER structure
5086 * @EvSwitch: Event switch flags
5089 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5091 EventNotification_t *evnp;
5093 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5095 devtverboseprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5099 memset(evnp, 0, sizeof(*evnp));
5101 devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5103 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5104 evnp->ChainOffset = 0;
5106 evnp->Switch = EvSwitch;
5108 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5113 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5115 * SendEventAck - Send EventAck request to MPT adapter.
5116 * @ioc: Pointer to MPT_ADAPTER structure
5117 * @evnp: Pointer to original EventNotification request
5120 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5124 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5125 printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK "
5126 "request frame for Event=%x EventContext=%x EventData=%x!\n",
5127 ioc->name, evnp->Event, le32_to_cpu(evnp->EventContext),
5128 le32_to_cpu(evnp->Data[0]));
5131 memset(pAck, 0, sizeof(*pAck));
5133 dprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
5135 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5136 pAck->ChainOffset = 0;
5138 pAck->Event = evnp->Event;
5139 pAck->EventContext = evnp->EventContext;
5141 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5146 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5148 * mpt_config - Generic function to issue config message
5149 * @ioc - Pointer to an adapter structure
5150 * @cfg - Pointer to a configuration structure. Struct contains
5151 * action, page address, direction, physical address
5152 * and pointer to a configuration page header
5153 * Page header is updated.
5155 * Returns 0 for success
5156 * -EPERM if not allowed due to ISR context
5157 * -EAGAIN if no msg frames currently available
5158 * -EFAULT for non-successful reply or no reply (timeout)
5161 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5164 ConfigExtendedPageHeader_t *pExtHdr = NULL;
5166 unsigned long flags;
5171 /* Prevent calling wait_event() (below), if caller happens
5172 * to be in ISR context, because that is fatal!
5174 in_isr = in_interrupt();
5176 dcprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5181 /* Get and Populate a free Frame
5183 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5184 dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5188 pReq = (Config_t *)mf;
5189 pReq->Action = pCfg->action;
5191 pReq->ChainOffset = 0;
5192 pReq->Function = MPI_FUNCTION_CONFIG;
5194 /* Assume page type is not extended and clear "reserved" fields. */
5195 pReq->ExtPageLength = 0;
5196 pReq->ExtPageType = 0;
5199 for (ii=0; ii < 8; ii++)
5200 pReq->Reserved2[ii] = 0;
5202 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5203 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5204 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5205 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5207 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5208 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5209 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5210 pReq->ExtPageType = pExtHdr->ExtPageType;
5211 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5213 /* Page Length must be treated as a reserved field for the extended header. */
5214 pReq->Header.PageLength = 0;
5217 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5219 /* Add a SGE to the config request.
5222 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5224 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5226 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5227 flagsLength |= pExtHdr->ExtPageLength * 4;
5229 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5230 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5233 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5235 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5236 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5239 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5241 /* Append pCfg pointer to end of mf
5243 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5245 /* Initalize the timer
5247 init_timer(&pCfg->timer);
5248 pCfg->timer.data = (unsigned long) ioc;
5249 pCfg->timer.function = mpt_timer_expired;
5250 pCfg->wait_done = 0;
5252 /* Set the timer; ensure 10 second minimum */
5253 if (pCfg->timeout < 10)
5254 pCfg->timer.expires = jiffies + HZ*10;
5256 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5258 /* Add to end of Q, set timer and then issue this command */
5259 spin_lock_irqsave(&ioc->FreeQlock, flags);
5260 list_add_tail(&pCfg->linkage, &ioc->configQ);
5261 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5263 add_timer(&pCfg->timer);
5264 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5265 wait_event(mpt_waitq, pCfg->wait_done);
5267 /* mf has been freed - do not access */
5274 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5276 * mpt_timer_expired - Call back for timer process.
5277 * Used only internal config functionality.
5278 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5281 mpt_timer_expired(unsigned long data)
5283 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5285 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name));
5287 /* Perform a FW reload */
5288 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5289 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5291 /* No more processing.
5292 * Hard reset clean-up will wake up
5293 * process and free all resources.
5295 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name));
5300 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5302 * mpt_ioc_reset - Base cleanup for hard reset
5303 * @ioc: Pointer to the adapter structure
5304 * @reset_phase: Indicates pre- or post-reset functionality
5306 * Remark: Free's resources with internally generated commands.
5309 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5312 unsigned long flags;
5314 dprintk((KERN_WARNING MYNAM
5315 ": IOC %s_reset routed to MPT base driver!\n",
5316 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5317 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5319 if (reset_phase == MPT_IOC_SETUP_RESET) {
5321 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5322 /* If the internal config Q is not empty -
5323 * delete timer. MF resources will be freed when
5324 * the FIFO's are primed.
5326 spin_lock_irqsave(&ioc->FreeQlock, flags);
5327 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5328 del_timer(&pCfg->timer);
5329 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5334 /* Search the configQ for internal commands.
5335 * Flush the Q, and wake up all suspended threads.
5337 spin_lock_irqsave(&ioc->FreeQlock, flags);
5338 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5339 list_del(&pCfg->linkage);
5341 pCfg->status = MPT_CONFIG_ERROR;
5342 pCfg->wait_done = 1;
5343 wake_up(&mpt_waitq);
5345 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5348 return 1; /* currently means nothing really */
5352 #ifdef CONFIG_PROC_FS /* { */
5353 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5355 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5357 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5359 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5361 * Returns 0 for success, non-zero for failure.
5364 procmpt_create(void)
5366 struct proc_dir_entry *ent;
5368 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5369 if (mpt_proc_root_dir == NULL)
5372 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5374 ent->read_proc = procmpt_summary_read;
5376 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5378 ent->read_proc = procmpt_version_read;
5383 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5385 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5387 * Returns 0 for success, non-zero for failure.
5390 procmpt_destroy(void)
5392 remove_proc_entry("version", mpt_proc_root_dir);
5393 remove_proc_entry("summary", mpt_proc_root_dir);
5394 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5397 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5399 * procmpt_summary_read - Handle read request from /proc/mpt/summary
5400 * or from /proc/mpt/iocN/summary.
5401 * @buf: Pointer to area to write information
5402 * @start: Pointer to start pointer
5403 * @offset: Offset to start writing
5405 * @eof: Pointer to EOF integer
5408 * Returns number of characters written to process performing the read.
5411 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5421 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5425 list_for_each_entry(ioc, &ioc_list, list) {
5428 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5431 if ((out-buf) >= request)
5438 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5441 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5443 * procmpt_version_read - Handle read request from /proc/mpt/version.
5444 * @buf: Pointer to area to write information
5445 * @start: Pointer to start pointer
5446 * @offset: Offset to start writing
5448 * @eof: Pointer to EOF integer
5451 * Returns number of characters written to process performing the read.
5454 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5457 int scsi, fc, sas, lan, ctl, targ, dmp;
5461 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5462 len += sprintf(buf+len, " Fusion MPT base driver\n");
5464 scsi = fc = sas = lan = ctl = targ = dmp = 0;
5465 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5467 if (MptCallbacks[ii]) {
5468 switch (MptDriverClass[ii]) {
5470 if (!scsi++) drvname = "SPI host";
5473 if (!fc++) drvname = "FC host";
5476 if (!sas++) drvname = "SAS host";
5479 if (!lan++) drvname = "LAN";
5482 if (!targ++) drvname = "SCSI target";
5485 if (!ctl++) drvname = "ioctl";
5490 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5494 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5497 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5499 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5500 * @buf: Pointer to area to write information
5501 * @start: Pointer to start pointer
5502 * @offset: Offset to start writing
5504 * @eof: Pointer to EOF integer
5507 * Returns number of characters written to process performing the read.
5510 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5512 MPT_ADAPTER *ioc = data;
5518 mpt_get_fw_exp_ver(expVer, ioc);
5520 len = sprintf(buf, "%s:", ioc->name);
5521 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5522 len += sprintf(buf+len, " (f/w download boot flag set)");
5523 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5524 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5526 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
5527 ioc->facts.ProductID,
5529 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5530 if (ioc->facts.FWImageSize)
5531 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5532 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5533 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5534 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
5536 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
5537 ioc->facts.CurrentHostMfaHighAddr);
5538 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
5539 ioc->facts.CurrentSenseBufferHighAddr);
5541 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5542 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5544 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5545 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
5547 * Rounding UP to nearest 4-kB boundary here...
5549 sz = (ioc->req_sz * ioc->req_depth) + 128;
5550 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5551 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5552 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5553 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
5554 4*ioc->facts.RequestFrameSize,
5555 ioc->facts.GlobalCredits);
5557 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
5558 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
5559 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5560 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5561 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5562 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
5563 ioc->facts.CurReplyFrameSize,
5564 ioc->facts.ReplyQueueDepth);
5566 len += sprintf(buf+len, " MaxDevices = %d\n",
5567 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5568 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
5571 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5572 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
5574 ioc->facts.NumberOfPorts);
5575 if (ioc->bus_type == FC) {
5576 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5577 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5578 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5579 a[5], a[4], a[3], a[2], a[1], a[0]);
5581 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
5582 ioc->fc_port_page0[p].WWNN.High,
5583 ioc->fc_port_page0[p].WWNN.Low,
5584 ioc->fc_port_page0[p].WWPN.High,
5585 ioc->fc_port_page0[p].WWPN.Low);
5589 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5592 #endif /* CONFIG_PROC_FS } */
5594 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5596 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
5599 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
5600 sprintf(buf, " (Exp %02d%02d)",
5601 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
5602 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
5605 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
5606 strcat(buf, " [MDBG]");
5610 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5612 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5613 * @ioc: Pointer to MPT_ADAPTER structure
5614 * @buffer: Pointer to buffer where IOC summary info should be written
5615 * @size: Pointer to number of bytes we wrote (set by this routine)
5616 * @len: Offset at which to start writing in buffer
5617 * @showlan: Display LAN stuff?
5619 * This routine writes (english readable) ASCII text, which represents
5620 * a summary of IOC information, to a buffer.
5623 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
5628 mpt_get_fw_exp_ver(expVer, ioc);
5631 * Shorter summary of attached ioc's...
5633 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
5636 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
5637 ioc->facts.FWVersion.Word,
5639 ioc->facts.NumberOfPorts,
5642 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
5643 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5644 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
5645 a[5], a[4], a[3], a[2], a[1], a[0]);
5649 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
5651 y += sprintf(buffer+len+y, ", IRQ=%s", __irq_itoa(ioc->pci_irq));
5655 y += sprintf(buffer+len+y, " (disabled)");
5657 y += sprintf(buffer+len+y, "\n");
5662 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5666 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5668 * mpt_HardResetHandler - Generic reset handler, issue SCSI Task
5669 * Management call based on input arg values. If TaskMgmt fails,
5670 * return associated SCSI request.
5671 * @ioc: Pointer to MPT_ADAPTER structure
5672 * @sleepFlag: Indicates if sleep or schedule must be called.
5674 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
5675 * or a non-interrupt thread. In the former, must not call schedule().
5677 * Remark: A return of -1 is a FATAL error case, as it means a
5678 * FW reload/initialization failed.
5680 * Returns 0 for SUCCESS or -1 if FAILED.
5683 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5686 unsigned long flags;
5688 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
5690 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
5691 printk("MF count 0x%x !\n", ioc->mfcnt);
5694 /* Reset the adapter. Prevent more than 1 call to
5695 * mpt_do_ioc_recovery at any instant in time.
5697 spin_lock_irqsave(&ioc->diagLock, flags);
5698 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
5699 spin_unlock_irqrestore(&ioc->diagLock, flags);
5702 ioc->diagPending = 1;
5704 spin_unlock_irqrestore(&ioc->diagLock, flags);
5706 /* FIXME: If do_ioc_recovery fails, repeat....
5709 /* The SCSI driver needs to adjust timeouts on all current
5710 * commands prior to the diagnostic reset being issued.
5711 * Prevents timeouts occuring during a diagnostic reset...very bad.
5712 * For all other protocol drivers, this is a no-op.
5718 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5719 if (MptResetHandlers[ii]) {
5720 dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
5722 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_SETUP_RESET);
5724 dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
5725 ioc->name, ioc->alt_ioc->name, ii));
5726 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_SETUP_RESET);
5732 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
5733 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
5738 ioc->alt_ioc->reload_fw = 0;
5740 spin_lock_irqsave(&ioc->diagLock, flags);
5741 ioc->diagPending = 0;
5743 ioc->alt_ioc->diagPending = 0;
5744 spin_unlock_irqrestore(&ioc->diagLock, flags);
5746 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
5751 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5753 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5758 case MPI_EVENT_NONE:
5761 case MPI_EVENT_LOG_DATA:
5764 case MPI_EVENT_STATE_CHANGE:
5765 ds = "State Change";
5767 case MPI_EVENT_UNIT_ATTENTION:
5768 ds = "Unit Attention";
5770 case MPI_EVENT_IOC_BUS_RESET:
5771 ds = "IOC Bus Reset";
5773 case MPI_EVENT_EXT_BUS_RESET:
5774 ds = "External Bus Reset";
5776 case MPI_EVENT_RESCAN:
5777 ds = "Bus Rescan Event";
5778 /* Ok, do we need to do anything here? As far as
5779 I can tell, this is when a new device gets added
5782 case MPI_EVENT_LINK_STATUS_CHANGE:
5783 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
5784 ds = "Link Status(FAILURE) Change";
5786 ds = "Link Status(ACTIVE) Change";
5788 case MPI_EVENT_LOOP_STATE_CHANGE:
5789 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
5790 ds = "Loop State(LIP) Change";
5791 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
5792 ds = "Loop State(LPE) Change"; /* ??? */
5794 ds = "Loop State(LPB) Change"; /* ??? */
5796 case MPI_EVENT_LOGOUT:
5799 case MPI_EVENT_EVENT_CHANGE:
5801 ds = "Events(ON) Change";
5803 ds = "Events(OFF) Change";
5805 case MPI_EVENT_INTEGRATED_RAID:
5807 u8 ReasonCode = (u8)(evData0 >> 16);
5808 switch (ReasonCode) {
5809 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
5810 ds = "Integrated Raid: Volume Created";
5812 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
5813 ds = "Integrated Raid: Volume Deleted";
5815 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
5816 ds = "Integrated Raid: Volume Settings Changed";
5818 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
5819 ds = "Integrated Raid: Volume Status Changed";
5821 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
5822 ds = "Integrated Raid: Volume Physdisk Changed";
5824 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
5825 ds = "Integrated Raid: Physdisk Created";
5827 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
5828 ds = "Integrated Raid: Physdisk Deleted";
5830 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
5831 ds = "Integrated Raid: Physdisk Settings Changed";
5833 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
5834 ds = "Integrated Raid: Physdisk Status Changed";
5836 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
5837 ds = "Integrated Raid: Domain Validation Needed";
5839 case MPI_EVENT_RAID_RC_SMART_DATA :
5840 ds = "Integrated Raid; Smart Data";
5842 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
5843 ds = "Integrated Raid: Replace Action Started";
5846 ds = "Integrated Raid";
5851 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
5852 ds = "SCSI Device Status Change";
5854 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
5857 u8 id = (u8)(evData0);
5858 u8 ReasonCode = (u8)(evData0 >> 16);
5859 switch (ReasonCode) {
5860 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
5861 sprintf(buf,"SAS Device Status Change: Added: id=%d", id);
5863 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
5864 sprintf(buf,"SAS Device Status Change: Deleted: id=%d", id);
5866 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
5867 sprintf(buf,"SAS Device Status Change: SMART Data: id=%d", id);
5869 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
5870 sprintf(buf,"SAS Device Status Change: No Persistancy Added: id=%d", id);
5873 sprintf(buf,"SAS Device Status Change: Unknown: id=%d", id);
5879 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
5880 ds = "Bus Timer Expired";
5882 case MPI_EVENT_QUEUE_FULL:
5885 case MPI_EVENT_SAS_SES:
5886 ds = "SAS SES Event";
5888 case MPI_EVENT_PERSISTENT_TABLE_FULL:
5889 ds = "Persistent Table Full";
5891 case MPI_EVENT_SAS_PHY_LINK_STATUS:
5894 u8 LinkRates = (u8)(evData0 >> 8);
5895 u8 PhyNumber = (u8)(evData0);
5896 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
5897 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
5898 switch (LinkRates) {
5899 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
5900 sprintf(buf,"SAS PHY Link Status: Phy=%d:"
5901 " Rate Unknown",PhyNumber);
5903 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
5904 sprintf(buf,"SAS PHY Link Status: Phy=%d:"
5905 " Phy Disabled",PhyNumber);
5907 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
5908 sprintf(buf,"SAS PHY Link Status: Phy=%d:"
5909 " Failed Speed Nego",PhyNumber);
5911 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
5912 sprintf(buf,"SAS PHY Link Status: Phy=%d:"
5913 " Sata OOB Completed",PhyNumber);
5915 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
5916 sprintf(buf,"SAS PHY Link Status: Phy=%d:"
5917 " Rate 1.5 Gbps",PhyNumber);
5919 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
5920 sprintf(buf,"SAS PHY Link Status: Phy=%d:"
5921 " Rate 3.0 Gpbs",PhyNumber);
5924 sprintf(buf,"SAS PHY Link Status: Phy=%d", PhyNumber);
5930 case MPI_EVENT_SAS_DISCOVERY_ERROR:
5931 ds = "SAS Discovery Error";
5933 case MPI_EVENT_IR_RESYNC_UPDATE:
5935 u8 resync_complete = (u8)(evData0 >> 16);
5937 sprintf(buf,"IR Resync Update: Complete = %d:",resync_complete);
5943 u8 ReasonCode = (u8)(evData0 >> 16);
5944 switch (ReasonCode) {
5945 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
5946 ds = "IR2: LD State Changed";
5948 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
5949 ds = "IR2: PD State Changed";
5951 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
5952 ds = "IR2: Bad Block Table Full";
5954 case MPI_EVENT_IR2_RC_PD_INSERTED:
5955 ds = "IR2: PD Inserted";
5957 case MPI_EVENT_IR2_RC_PD_REMOVED:
5958 ds = "IR2: PD Removed";
5960 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
5961 ds = "IR2: Foreign CFG Detected";
5963 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
5964 ds = "IR2: Rebuild Medium Error";
5972 case MPI_EVENT_SAS_DISCOVERY:
5975 ds = "SAS Discovery: Start";
5977 ds = "SAS Discovery: Stop";
5980 case MPI_EVENT_LOG_ENTRY_ADDED:
5981 ds = "SAS Log Entry Added";
5985 * MPT base "custom" events may be added here...
5994 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5996 * ProcessEventNotification - Route a received EventNotificationReply to
5997 * all currently regeistered event handlers.
5998 * @ioc: Pointer to MPT_ADAPTER structure
5999 * @pEventReply: Pointer to EventNotification reply frame
6000 * @evHandlers: Pointer to integer, number of event handlers
6002 * Returns sum of event handlers return values.
6005 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
6017 * Do platform normalization of values
6019 event = le32_to_cpu(pEventReply->Event) & 0xFF;
6020 // evCtx = le32_to_cpu(pEventReply->EventContext);
6021 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
6023 evData0 = le32_to_cpu(pEventReply->Data[0]);
6026 EventDescriptionStr(event, evData0, evStr);
6027 devtprintk((MYIOC_s_INFO_FMT "MPT event:(%02Xh) : %s\n",
6032 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_VERBOSE_EVENTS)
6033 printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
6034 for (ii = 0; ii < evDataLen; ii++)
6035 printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
6040 * Do general / base driver event processing
6043 case MPI_EVENT_EVENT_CHANGE: /* 0A */
6045 u8 evState = evData0 & 0xFF;
6047 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6049 /* Update EventState field in cached IocFacts */
6050 if (ioc->facts.Function) {
6051 ioc->facts.EventState = evState;
6055 case MPI_EVENT_INTEGRATED_RAID:
6056 mptbase_raid_process_event_data(ioc,
6057 (MpiEventDataRaid_t *)pEventReply->Data);
6064 * Should this event be logged? Events are written sequentially.
6065 * When buffer is full, start again at the top.
6067 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6070 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
6072 ioc->events[idx].event = event;
6073 ioc->events[idx].eventContext = ioc->eventContext;
6075 for (ii = 0; ii < 2; ii++) {
6077 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6079 ioc->events[idx].data[ii] = 0;
6082 ioc->eventContext++;
6087 * Call each currently registered protocol event handler.
6089 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
6090 if (MptEvHandlers[ii]) {
6091 devtverboseprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
6093 r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
6097 /* FIXME? Examine results here? */
6100 * If needed, send (a single) EventAck.
6102 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6103 devtverboseprintk((MYIOC_s_WARN_FMT
6104 "EventAck required\n",ioc->name));
6105 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6106 devtverboseprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
6111 *evHandlers = handlers;
6115 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6117 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6118 * @ioc: Pointer to MPT_ADAPTER structure
6119 * @log_info: U32 LogInfo reply word from the IOC
6121 * Refer to lsi/fc_log.h.
6124 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6126 static char *subcl_str[8] = {
6127 "FCP Initiator", "FCP Target", "LAN", "MPI Message Layer",
6128 "FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
6130 u8 subcl = (log_info >> 24) & 0x7;
6132 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}\n",
6133 ioc->name, log_info, subcl_str[subcl]);
6136 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6138 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6139 * @ioc: Pointer to MPT_ADAPTER structure
6140 * @mr: Pointer to MPT reply frame
6141 * @log_info: U32 LogInfo word from the IOC
6143 * Refer to lsi/sp_log.h.
6146 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6148 u32 info = log_info & 0x00FF0000;
6149 char *desc = "unknown";
6153 desc = "bug! MID not found";
6154 if (ioc->reload_fw == 0)
6159 desc = "Parity Error";
6163 desc = "ASYNC Outbound Overrun";
6167 desc = "SYNC Offset Error";
6175 desc = "Msg In Overflow";
6183 desc = "Outbound DMA Overrun";
6187 desc = "Task Management";
6191 desc = "Device Problem";
6195 desc = "Invalid Phase Change";
6199 desc = "Untagged Table Size";
6204 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6207 /* strings for sas loginfo */
6208 static char *originator_str[] = {
6213 static char *iop_code_str[] = {
6215 "Invalid SAS Address", /* 01h */
6217 "Invalid Page", /* 03h */
6219 "Task Terminated" /* 05h */
6221 static char *pl_code_str[] = {
6223 "Open Failure", /* 01h */
6224 "Invalid Scatter Gather List", /* 02h */
6225 "Wrong Relative Offset or Frame Length", /* 03h */
6226 "Frame Transfer Error", /* 04h */
6227 "Transmit Frame Connected Low", /* 05h */
6228 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6229 "SATA Read Log Receive Data Error", /* 07h */
6230 "SATA NCQ Fail All Commands After Error", /* 08h */
6231 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6232 "Receive Frame Invalid Message", /* 0Ah */
6233 "Receive Context Message Valid Error", /* 0Bh */
6234 "Receive Frame Current Frame Error", /* 0Ch */
6235 "SATA Link Down", /* 0Dh */
6236 "Discovery SATA Init W IOS", /* 0Eh */
6237 "Config Invalid Page", /* 0Fh */
6238 "Discovery SATA Init Timeout", /* 10h */
6241 "IO Not Yet Executed", /* 13h */
6242 "IO Executed", /* 14h */
6243 "Persistant Reservation Out Not Affiliation Owner", /* 15h */
6244 "Open Transmit DMA Abort", /* 16h */
6254 "Enclosure Management" /* 20h */
6257 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6259 * mpt_sas_log_info - Log information returned from SAS IOC.
6260 * @ioc: Pointer to MPT_ADAPTER structure
6261 * @log_info: U32 LogInfo reply word from the IOC
6263 * Refer to lsi/mpi_log_sas.h.
6266 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6268 union loginfo_type {
6277 union loginfo_type sas_loginfo;
6278 char *code_desc = NULL;
6280 sas_loginfo.loginfo = log_info;
6281 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
6282 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
6284 if ((sas_loginfo.dw.originator == 0 /*IOP*/) &&
6285 (sas_loginfo.dw.code < sizeof(iop_code_str)/sizeof(char*))) {
6286 code_desc = iop_code_str[sas_loginfo.dw.code];
6287 }else if ((sas_loginfo.dw.originator == 1 /*PL*/) &&
6288 (sas_loginfo.dw.code < sizeof(pl_code_str)/sizeof(char*) )) {
6289 code_desc = pl_code_str[sas_loginfo.dw.code];
6292 if (code_desc != NULL)
6293 printk(MYIOC_s_INFO_FMT
6294 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
6295 " SubCode(0x%04x)\n",
6298 originator_str[sas_loginfo.dw.originator],
6300 sas_loginfo.dw.subcode);
6302 printk(MYIOC_s_INFO_FMT
6303 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
6304 " SubCode(0x%04x)\n",
6307 originator_str[sas_loginfo.dw.originator],
6308 sas_loginfo.dw.code,
6309 sas_loginfo.dw.subcode);
6312 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6314 * mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
6315 * @ioc: Pointer to MPT_ADAPTER structure
6316 * @ioc_status: U32 IOCStatus word from IOC
6317 * @mf: Pointer to MPT request frame
6319 * Refer to lsi/mpi.h.
6322 mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
6324 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
6328 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
6329 desc = "Invalid Function";
6332 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
6336 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
6337 desc = "Invalid SGL";
6340 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
6341 desc = "Internal Error";
6344 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
6348 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
6349 desc = "Insufficient Resources";
6352 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
6353 desc = "Invalid Field";
6356 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
6357 desc = "Invalid State";
6360 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
6361 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
6362 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
6363 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
6364 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
6365 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
6366 /* No message for Config IOCStatus values */
6369 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
6370 /* No message for recovered error
6371 desc = "SCSI Recovered Error";
6375 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
6376 desc = "SCSI Invalid Bus";
6379 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
6380 desc = "SCSI Invalid TargetID";
6383 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
6385 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
6386 U8 cdb = pScsiReq->CDB[0];
6387 if (cdb != 0x12) { /* Inquiry is issued for device scanning */
6388 desc = "SCSI Device Not There";
6393 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
6394 desc = "SCSI Data Overrun";
6397 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
6398 /* This error is checked in scsi_io_done(). Skip.
6399 desc = "SCSI Data Underrun";
6403 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
6404 desc = "SCSI I/O Data Error";
6407 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
6408 desc = "SCSI Protocol Error";
6411 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
6412 desc = "SCSI Task Terminated";
6415 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
6416 desc = "SCSI Residual Mismatch";
6419 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
6420 desc = "SCSI Task Management Failed";
6423 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
6424 desc = "SCSI IOC Terminated";
6427 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
6428 desc = "SCSI Ext Terminated";
6436 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc);
6439 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6440 EXPORT_SYMBOL(mpt_attach);
6441 EXPORT_SYMBOL(mpt_detach);
6443 EXPORT_SYMBOL(mpt_resume);
6444 EXPORT_SYMBOL(mpt_suspend);
6446 EXPORT_SYMBOL(ioc_list);
6447 EXPORT_SYMBOL(mpt_proc_root_dir);
6448 EXPORT_SYMBOL(mpt_register);
6449 EXPORT_SYMBOL(mpt_deregister);
6450 EXPORT_SYMBOL(mpt_event_register);
6451 EXPORT_SYMBOL(mpt_event_deregister);
6452 EXPORT_SYMBOL(mpt_reset_register);
6453 EXPORT_SYMBOL(mpt_reset_deregister);
6454 EXPORT_SYMBOL(mpt_device_driver_register);
6455 EXPORT_SYMBOL(mpt_device_driver_deregister);
6456 EXPORT_SYMBOL(mpt_get_msg_frame);
6457 EXPORT_SYMBOL(mpt_put_msg_frame);
6458 EXPORT_SYMBOL(mpt_free_msg_frame);
6459 EXPORT_SYMBOL(mpt_add_sge);
6460 EXPORT_SYMBOL(mpt_send_handshake_request);
6461 EXPORT_SYMBOL(mpt_verify_adapter);
6462 EXPORT_SYMBOL(mpt_GetIocState);
6463 EXPORT_SYMBOL(mpt_print_ioc_summary);
6464 EXPORT_SYMBOL(mpt_lan_index);
6465 EXPORT_SYMBOL(mpt_stm_index);
6466 EXPORT_SYMBOL(mpt_HardResetHandler);
6467 EXPORT_SYMBOL(mpt_config);
6468 EXPORT_SYMBOL(mpt_findImVolumes);
6469 EXPORT_SYMBOL(mpt_alloc_fw_memory);
6470 EXPORT_SYMBOL(mpt_free_fw_memory);
6471 EXPORT_SYMBOL(mptbase_sas_persist_operation);
6472 EXPORT_SYMBOL(mptbase_GetFcPortPage0);
6475 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6477 * fusion_init - Fusion MPT base driver initialization routine.
6479 * Returns 0 for success, non-zero for failure.
6486 show_mptmod_ver(my_NAME, my_VERSION);
6487 printk(KERN_INFO COPYRIGHT "\n");
6489 for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
6490 MptCallbacks[i] = NULL;
6491 MptDriverClass[i] = MPTUNKNOWN_DRIVER;
6492 MptEvHandlers[i] = NULL;
6493 MptResetHandlers[i] = NULL;
6496 /* Register ourselves (mptbase) in order to facilitate
6497 * EventNotification handling.
6499 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
6501 /* Register for hard reset handling callbacks.
6503 if (mpt_reset_register(mpt_base_index, mpt_ioc_reset) == 0) {
6504 dprintk((KERN_INFO MYNAM ": Register for IOC reset notification\n"));
6509 #ifdef CONFIG_PROC_FS
6510 (void) procmpt_create();
6515 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6517 * fusion_exit - Perform driver unload cleanup.
6519 * This routine frees all resources associated with each MPT adapter
6520 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
6526 dexitprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
6528 mpt_reset_deregister(mpt_base_index);
6530 #ifdef CONFIG_PROC_FS
6535 module_init(fusion_init);
6536 module_exit(fusion_exit);