aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion/mptbase.c
diff options
context:
space:
mode:
authorKashyap, Desai <kashyap.desai@lsi.com>2009-05-29 07:10:57 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-06-09 18:26:20 -0400
commitf0f09d3b3f06900d64971625d6753dea0623ed45 (patch)
tree896237d53275eeb6b4484c2cb747f0b333157c30 /drivers/message/fusion/mptbase.c
parentfd76175a7d3abf4d14df17f5f4c7e68b466b455d (diff)
[SCSI] mpt fusion: config path optimized, completion queue is used
1) Previously we had mutliple #defines to use same values. Now those #defines are optimized. MPT_IOCTL_STATUS_* is removed and MPT_MGMT_STATUS_* are new #defines. 2.) config path is optimized. Instead of wait Queue and timer, using completion Q. 3.) mpt_timer_expired is not used. [jejb: elide patch to eliminate mpt_timer_expired] Signed-off-by: Kashyap Desai <kadesai@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/message/fusion/mptbase.c')
-rw-r--r--drivers/message/fusion/mptbase.c456
1 files changed, 215 insertions, 241 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 0d2fb0eb34b9..e63a6260b0a0 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -146,7 +146,6 @@ static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
146static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS]; 146static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
147static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS]; 147static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
148 148
149static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
150 149
151/* 150/*
152 * Driver Callback Index's 151 * Driver Callback Index's
@@ -159,7 +158,8 @@ static u8 last_drv_idx;
159 * Forward protos... 158 * Forward protos...
160 */ 159 */
161static irqreturn_t mpt_interrupt(int irq, void *bus_id); 160static irqreturn_t mpt_interrupt(int irq, void *bus_id);
162static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply); 161static int mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
162 MPT_FRAME_HDR *reply);
163static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, 163static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
164 u32 *req, int replyBytes, u16 *u16reply, int maxwait, 164 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
165 int sleepFlag); 165 int sleepFlag);
@@ -190,7 +190,6 @@ static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
190static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum); 190static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
191static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc); 191static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
192static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc); 192static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
193static void mpt_timer_expired(unsigned long data);
194static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc); 193static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
195static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch, 194static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch,
196 int sleepFlag); 195 int sleepFlag);
@@ -559,9 +558,9 @@ mpt_interrupt(int irq, void *bus_id)
559 558
560/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 559/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
561/** 560/**
562 * mpt_base_reply - MPT base driver's callback routine 561 * mptbase_reply - MPT base driver's callback routine
563 * @ioc: Pointer to MPT_ADAPTER structure 562 * @ioc: Pointer to MPT_ADAPTER structure
564 * @mf: Pointer to original MPT request frame 563 * @req: Pointer to original MPT request frame
565 * @reply: Pointer to MPT reply frame (NULL if TurboReply) 564 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
566 * 565 *
567 * MPT base driver's callback routine; all base driver 566 * MPT base driver's callback routine; all base driver
@@ -572,122 +571,49 @@ mpt_interrupt(int irq, void *bus_id)
572 * should be freed, or 0 if it shouldn't. 571 * should be freed, or 0 if it shouldn't.
573 */ 572 */
574static int 573static int
575mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply) 574mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
576{ 575{
576 EventNotificationReply_t *pEventReply;
577 u8 event;
578 int evHandlers;
577 int freereq = 1; 579 int freereq = 1;
578 u8 func;
579
580 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply() called\n", ioc->name));
581#ifdef CONFIG_FUSION_LOGGING
582 if ((ioc->debug_level & MPT_DEBUG_MSG_FRAME) &&
583 !(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
584 dmfprintk(ioc, printk(MYIOC_s_INFO_FMT ": Original request frame (@%p) header\n",
585 ioc->name, mf));
586 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)mf);
587 }
588#endif
589
590 func = reply->u.hdr.Function;
591 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, Function=%02Xh\n",
592 ioc->name, func));
593
594 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
595 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
596 int evHandlers = 0;
597 int results;
598
599 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
600 if (results != evHandlers) {
601 /* CHECKME! Any special handling needed here? */
602 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
603 ioc->name, evHandlers, results));
604 }
605 580
606 /* 581 switch (reply->u.hdr.Function) {
607 * Hmmm... It seems that EventNotificationReply is an exception 582 case MPI_FUNCTION_EVENT_NOTIFICATION:
608 * to the rule of one reply per request. 583 pEventReply = (EventNotificationReply_t *)reply;
609 */ 584 evHandlers = 0;
610 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) { 585 ProcessEventNotification(ioc, pEventReply, &evHandlers);
586 event = le32_to_cpu(pEventReply->Event) & 0xFF;
587 if (pEventReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
611 freereq = 0; 588 freereq = 0;
612 } else { 589 if (event != MPI_EVENT_EVENT_CHANGE)
613 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n", 590 break;
614 ioc->name, pEvReply)); 591 case MPI_FUNCTION_CONFIG:
615 } 592 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
616 593 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
617#ifdef CONFIG_PROC_FS 594 if (reply) {
618// LogEvent(ioc, pEvReply); 595 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
619#endif 596 memcpy(ioc->mptbase_cmds.reply, reply,
620 597 min(MPT_DEFAULT_FRAME_SIZE,
621 } else if (func == MPI_FUNCTION_EVENT_ACK) { 598 4 * reply->u.reply.MsgLength));
622 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, EventAck reply received\n",
623 ioc->name));
624 } else if (func == MPI_FUNCTION_CONFIG) {
625 CONFIGPARMS *pCfg;
626 unsigned long flags;
627
628 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "config_complete (mf=%p,mr=%p)\n",
629 ioc->name, mf, reply));
630
631 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
632
633 if (pCfg) {
634 /* disable timer and remove from linked list */
635 del_timer(&pCfg->timer);
636
637 spin_lock_irqsave(&ioc->FreeQlock, flags);
638 list_del(&pCfg->linkage);
639 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
640
641 /*
642 * If IOC Status is SUCCESS, save the header
643 * and set the status code to GOOD.
644 */
645 pCfg->status = MPT_CONFIG_ERROR;
646 if (reply) {
647 ConfigReply_t *pReply = (ConfigReply_t *)reply;
648 u16 status;
649
650 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
651 dcprintk(ioc, printk(MYIOC_s_NOTE_FMT " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
652 ioc->name, status, le32_to_cpu(pReply->IOCLogInfo)));
653
654 pCfg->status = status;
655 if (status == MPI_IOCSTATUS_SUCCESS) {
656 if ((pReply->Header.PageType &
657 MPI_CONFIG_PAGETYPE_MASK) ==
658 MPI_CONFIG_PAGETYPE_EXTENDED) {
659 pCfg->cfghdr.ehdr->ExtPageLength =
660 le16_to_cpu(pReply->ExtPageLength);
661 pCfg->cfghdr.ehdr->ExtPageType =
662 pReply->ExtPageType;
663 }
664 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
665
666 /* If this is a regular header, save PageLength. */
667 /* LMP Do this better so not using a reserved field! */
668 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
669 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
670 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
671 }
672 }
673
674 /*
675 * Wake up the original calling thread
676 */
677 pCfg->wait_done = 1;
678 wake_up(&mpt_waitq);
679 } 599 }
680 } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) { 600 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
681 /* we should be always getting a reply frame */ 601 ioc->mptbase_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
682 memcpy(ioc->persist_reply_frame, reply, 602 complete(&ioc->mptbase_cmds.done);
683 min(MPT_DEFAULT_FRAME_SIZE, 603 } else
684 4*reply->u.reply.MsgLength)); 604 freereq = 0;
685 del_timer(&ioc->persist_timer); 605 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_FREE_MF)
686 ioc->persist_wait_done = 1; 606 freereq = 1;
687 wake_up(&mpt_waitq); 607 break;
688 } else { 608 case MPI_FUNCTION_EVENT_ACK:
689 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n", 609 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
690 ioc->name, func); 610 "EventAck reply received\n", ioc->name));
611 break;
612 default:
613 printk(MYIOC_s_ERR_FMT
614 "Unexpected msg function (=%02Xh) reply received!\n",
615 ioc->name, reply->u.hdr.Function);
616 break;
691 } 617 }
692 618
693 /* 619 /*
@@ -1849,6 +1775,9 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1849 spin_lock_init(&ioc->diagLock); 1775 spin_lock_init(&ioc->diagLock);
1850 spin_lock_init(&ioc->initializing_hba_lock); 1776 spin_lock_init(&ioc->initializing_hba_lock);
1851 1777
1778 mutex_init(&ioc->mptbase_cmds.mutex);
1779 init_completion(&ioc->mptbase_cmds.done);
1780
1852 /* Initialize the event logging. 1781 /* Initialize the event logging.
1853 */ 1782 */
1854 ioc->eventTypes = 0; /* None */ 1783 ioc->eventTypes = 0; /* None */
@@ -1866,10 +1795,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1866 */ 1795 */
1867 memset(&ioc->spi_data, 0, sizeof(SpiCfgData)); 1796 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1868 1797
1869 /* Initialize the running configQ head.
1870 */
1871 INIT_LIST_HEAD(&ioc->configQ);
1872
1873 /* Initialize the fc rport list head. 1798 /* Initialize the fc rport list head.
1874 */ 1799 */
1875 INIT_LIST_HEAD(&ioc->fc_rports); 1800 INIT_LIST_HEAD(&ioc->fc_rports);
@@ -5013,7 +4938,14 @@ mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
5013 SasIoUnitControlReply_t *sasIoUnitCntrReply; 4938 SasIoUnitControlReply_t *sasIoUnitCntrReply;
5014 MPT_FRAME_HDR *mf = NULL; 4939 MPT_FRAME_HDR *mf = NULL;
5015 MPIHeader_t *mpi_hdr; 4940 MPIHeader_t *mpi_hdr;
4941 int ret = 0;
4942 unsigned long timeleft;
4943
4944 mutex_lock(&ioc->mptbase_cmds.mutex);
5016 4945
4946 /* init the internal cmd struct */
4947 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
4948 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
5017 4949
5018 /* insure garbage is not sent to fw */ 4950 /* insure garbage is not sent to fw */
5019 switch(persist_opcode) { 4951 switch(persist_opcode) {
@@ -5023,17 +4955,19 @@ mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
5023 break; 4955 break;
5024 4956
5025 default: 4957 default:
5026 return -1; 4958 ret = -1;
5027 break; 4959 goto out;
5028 } 4960 }
5029 4961
5030 printk("%s: persist_opcode=%x\n",__func__, persist_opcode); 4962 printk(KERN_DEBUG "%s: persist_opcode=%x\n",
4963 __func__, persist_opcode);
5031 4964
5032 /* Get a MF for this command. 4965 /* Get a MF for this command.
5033 */ 4966 */
5034 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { 4967 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5035 printk("%s: no msg frames!\n",__func__); 4968 printk(KERN_DEBUG "%s: no msg frames!\n", __func__);
5036 return -1; 4969 ret = -1;
4970 goto out;
5037 } 4971 }
5038 4972
5039 mpi_hdr = (MPIHeader_t *) mf; 4973 mpi_hdr = (MPIHeader_t *) mf;
@@ -5043,27 +4977,42 @@ mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
5043 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext; 4977 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
5044 sasIoUnitCntrReq->Operation = persist_opcode; 4978 sasIoUnitCntrReq->Operation = persist_opcode;
5045 4979
5046 init_timer(&ioc->persist_timer);
5047 ioc->persist_timer.data = (unsigned long) ioc;
5048 ioc->persist_timer.function = mpt_timer_expired;
5049 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
5050 ioc->persist_wait_done=0;
5051 add_timer(&ioc->persist_timer);
5052 mpt_put_msg_frame(mpt_base_index, ioc, mf); 4980 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5053 wait_event(mpt_waitq, ioc->persist_wait_done); 4981 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done, 10*HZ);
4982 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
4983 ret = -ETIME;
4984 printk(KERN_DEBUG "%s: failed\n", __func__);
4985 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
4986 goto out;
4987 if (!timeleft) {
4988 printk(KERN_DEBUG "%s: Issuing Reset from %s!!\n",
4989 ioc->name, __func__);
4990 mpt_HardResetHandler(ioc, CAN_SLEEP);
4991 mpt_free_msg_frame(ioc, mf);
4992 }
4993 goto out;
4994 }
4995
4996 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
4997 ret = -1;
4998 goto out;
4999 }
5054 5000
5055 sasIoUnitCntrReply = 5001 sasIoUnitCntrReply =
5056 (SasIoUnitControlReply_t *)ioc->persist_reply_frame; 5002 (SasIoUnitControlReply_t *)ioc->mptbase_cmds.reply;
5057 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) { 5003 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
5058 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n", 5004 printk(KERN_DEBUG "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
5059 __func__, 5005 __func__, sasIoUnitCntrReply->IOCStatus,
5060 sasIoUnitCntrReply->IOCStatus,
5061 sasIoUnitCntrReply->IOCLogInfo); 5006 sasIoUnitCntrReply->IOCLogInfo);
5062 return -1; 5007 printk(KERN_DEBUG "%s: failed\n", __func__);
5063 } 5008 ret = -1;
5009 } else
5010 printk(KERN_DEBUG "%s: success\n", __func__);
5011 out:
5064 5012
5065 printk("%s: success\n",__func__); 5013 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
5066 return 0; 5014 mutex_unlock(&ioc->mptbase_cmds.mutex);
5015 return ret;
5067} 5016}
5068 5017
5069/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5018/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -6066,7 +6015,7 @@ SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
6066 6015
6067 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { 6016 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6068 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n", 6017 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
6069 ioc->name,__func__)); 6018 ioc->name, __func__));
6070 return -1; 6019 return -1;
6071 } 6020 }
6072 6021
@@ -6103,12 +6052,18 @@ int
6103mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) 6052mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
6104{ 6053{
6105 Config_t *pReq; 6054 Config_t *pReq;
6055 ConfigReply_t *pReply;
6106 ConfigExtendedPageHeader_t *pExtHdr = NULL; 6056 ConfigExtendedPageHeader_t *pExtHdr = NULL;
6107 MPT_FRAME_HDR *mf; 6057 MPT_FRAME_HDR *mf;
6108 unsigned long flags; 6058 int ii;
6109 int ii, rc;
6110 int flagsLength; 6059 int flagsLength;
6060 long timeout;
6061 int ret;
6062 u8 page_type = 0, extend_page;
6063 unsigned long timeleft;
6111 int in_isr; 6064 int in_isr;
6065 u8 issue_hard_reset = 0;
6066 u8 retry_count = 0;
6112 6067
6113 /* Prevent calling wait_event() (below), if caller happens 6068 /* Prevent calling wait_event() (below), if caller happens
6114 * to be in ISR context, because that is fatal! 6069 * to be in ISR context, because that is fatal!
@@ -6120,13 +6075,31 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
6120 return -EPERM; 6075 return -EPERM;
6121 } 6076 }
6122 6077
6078 /* don't send if no chance of success */
6079 if (!ioc->active ||
6080 mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_OPERATIONAL) {
6081 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6082 "%s: ioc not operational, %d, %xh\n",
6083 ioc->name, __func__, ioc->active,
6084 mpt_GetIocState(ioc, 0)));
6085 return -EFAULT;
6086 }
6087
6088 retry_config:
6089 mutex_lock(&ioc->mptbase_cmds.mutex);
6090 /* init the internal cmd struct */
6091 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
6092 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
6093
6123 /* Get and Populate a free Frame 6094 /* Get and Populate a free Frame
6124 */ 6095 */
6125 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { 6096 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6126 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n", 6097 dcprintk(ioc, printk(MYIOC_s_WARN_FMT
6127 ioc->name)); 6098 "mpt_config: no msg frames!\n", ioc->name));
6128 return -EAGAIN; 6099 ret = -EAGAIN;
6100 goto out;
6129 } 6101 }
6102
6130 pReq = (Config_t *)mf; 6103 pReq = (Config_t *)mf;
6131 pReq->Action = pCfg->action; 6104 pReq->Action = pCfg->action;
6132 pReq->Reserved = 0; 6105 pReq->Reserved = 0;
@@ -6152,7 +6125,9 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
6152 pReq->ExtPageType = pExtHdr->ExtPageType; 6125 pReq->ExtPageType = pExtHdr->ExtPageType;
6153 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED; 6126 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
6154 6127
6155 /* Page Length must be treated as a reserved field for the extended header. */ 6128 /* Page Length must be treated as a reserved field for the
6129 * extended header.
6130 */
6156 pReq->Header.PageLength = 0; 6131 pReq->Header.PageLength = 0;
6157 } 6132 }
6158 6133
@@ -6165,78 +6140,91 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
6165 else 6140 else
6166 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ; 6141 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
6167 6142
6168 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) { 6143 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) ==
6144 MPI_CONFIG_PAGETYPE_EXTENDED) {
6169 flagsLength |= pExtHdr->ExtPageLength * 4; 6145 flagsLength |= pExtHdr->ExtPageLength * 4;
6170 6146 page_type = pReq->ExtPageType;
6171 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n", 6147 extend_page = 1;
6172 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action)); 6148 } else {
6173 }
6174 else {
6175 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4; 6149 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
6176 6150 page_type = pReq->Header.PageType;
6177 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n", 6151 extend_page = 0;
6178 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
6179 } 6152 }
6180 6153
6181 ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr); 6154 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6182 6155 "Sending Config request type 0x%x, page 0x%x and action %d\n",
6183 /* Append pCfg pointer to end of mf 6156 ioc->name, page_type, pReq->Header.PageNumber, pReq->Action));
6184 */
6185 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
6186
6187 /* Initalize the timer
6188 */
6189 init_timer_on_stack(&pCfg->timer);
6190 pCfg->timer.data = (unsigned long) ioc;
6191 pCfg->timer.function = mpt_timer_expired;
6192 pCfg->wait_done = 0;
6193
6194 /* Set the timer; ensure 10 second minimum */
6195 if (pCfg->timeout < 10)
6196 pCfg->timer.expires = jiffies + HZ*10;
6197 else
6198 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
6199
6200 /* Add to end of Q, set timer and then issue this command */
6201 spin_lock_irqsave(&ioc->FreeQlock, flags);
6202 list_add_tail(&pCfg->linkage, &ioc->configQ);
6203 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
6204 6157
6205 add_timer(&pCfg->timer); 6158 ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
6159 timeout = (pCfg->timeout < 15) ? HZ*15 : HZ*pCfg->timeout;
6206 mpt_put_msg_frame(mpt_base_index, ioc, mf); 6160 mpt_put_msg_frame(mpt_base_index, ioc, mf);
6207 wait_event(mpt_waitq, pCfg->wait_done); 6161 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done,
6208 6162 timeout);
6209 /* mf has been freed - do not access */ 6163 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
6164 ret = -ETIME;
6165 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6166 "Failed Sending Config request type 0x%x, page 0x%x,"
6167 " action %d, status %xh, time left %ld\n\n",
6168 ioc->name, page_type, pReq->Header.PageNumber,
6169 pReq->Action, ioc->mptbase_cmds.status, timeleft));
6170 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
6171 goto out;
6172 if (!timeleft)
6173 issue_hard_reset = 1;
6174 goto out;
6175 }
6210 6176
6211 rc = pCfg->status; 6177 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
6178 ret = -1;
6179 goto out;
6180 }
6181 pReply = (ConfigReply_t *)ioc->mptbase_cmds.reply;
6182 ret = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
6183 if (ret == MPI_IOCSTATUS_SUCCESS) {
6184 if (extend_page) {
6185 pCfg->cfghdr.ehdr->ExtPageLength =
6186 le16_to_cpu(pReply->ExtPageLength);
6187 pCfg->cfghdr.ehdr->ExtPageType =
6188 pReply->ExtPageType;
6189 }
6190 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
6191 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
6192 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
6193 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
6212 6194
6213 return rc; 6195 }
6214}
6215 6196
6216/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6197 if (retry_count)
6217/** 6198 printk(MYIOC_s_INFO_FMT "Retry completed "
6218 * mpt_timer_expired - Callback for timer process. 6199 "ret=0x%x timeleft=%ld\n",
6219 * Used only internal config functionality. 6200 ioc->name, ret, timeleft);
6220 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
6221 */
6222static void
6223mpt_timer_expired(unsigned long data)
6224{
6225 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
6226 6201
6227 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired! \n", ioc->name)); 6202 dcprintk(ioc, printk(KERN_DEBUG "IOCStatus=%04xh, IOCLogInfo=%08xh\n",
6203 ret, le32_to_cpu(pReply->IOCLogInfo)));
6228 6204
6229 /* Perform a FW reload */ 6205out:
6230 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
6231 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
6232 6206
6233 /* No more processing. 6207 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
6234 * Hard reset clean-up will wake up 6208 mutex_unlock(&ioc->mptbase_cmds.mutex);
6235 * process and free all resources. 6209 if (issue_hard_reset) {
6236 */ 6210 issue_hard_reset = 0;
6237 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired complete!\n", ioc->name)); 6211 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
6212 ioc->name, __func__);
6213 mpt_HardResetHandler(ioc, CAN_SLEEP);
6214 mpt_free_msg_frame(ioc, mf);
6215 /* attempt one retry for a timed out command */
6216 if (!retry_count) {
6217 printk(MYIOC_s_INFO_FMT
6218 "Attempting Retry Config request"
6219 " type 0x%x, page 0x%x,"
6220 " action %d\n", ioc->name, page_type,
6221 pCfg->cfghdr.hdr->PageNumber, pCfg->action);
6222 retry_count++;
6223 goto retry_config;
6224 }
6225 }
6226 return ret;
6238 6227
6239 return;
6240} 6228}
6241 6229
6242/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6230/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -6250,41 +6238,27 @@ mpt_timer_expired(unsigned long data)
6250static int 6238static int
6251mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) 6239mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
6252{ 6240{
6253 CONFIGPARMS *pCfg; 6241 switch (reset_phase) {
6254 unsigned long flags; 6242 case MPT_IOC_SETUP_RESET:
6255 6243 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6256 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6244 "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
6257 ": IOC %s_reset routed to MPT base driver!\n", 6245 break;
6258 ioc->name, reset_phase==MPT_IOC_SETUP_RESET ? "setup" : ( 6246 case MPT_IOC_PRE_RESET:
6259 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"))); 6247 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6260 6248 "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
6261 if (reset_phase == MPT_IOC_SETUP_RESET) { 6249 break;
6262 ; 6250 case MPT_IOC_POST_RESET:
6263 } else if (reset_phase == MPT_IOC_PRE_RESET) { 6251 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6264 /* If the internal config Q is not empty - 6252 "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
6265 * delete timer. MF resources will be freed when 6253/* wake up mptbase_cmds */
6266 * the FIFO's are primed. 6254 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
6267 */ 6255 ioc->mptbase_cmds.status |=
6268 spin_lock_irqsave(&ioc->FreeQlock, flags); 6256 MPT_MGMT_STATUS_DID_IOCRESET;
6269 list_for_each_entry(pCfg, &ioc->configQ, linkage) 6257 complete(&ioc->mptbase_cmds.done);
6270 del_timer(&pCfg->timer);
6271 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
6272
6273 } else {
6274 CONFIGPARMS *pNext;
6275
6276 /* Search the configQ for internal commands.
6277 * Flush the Q, and wake up all suspended threads.
6278 */
6279 spin_lock_irqsave(&ioc->FreeQlock, flags);
6280 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
6281 list_del(&pCfg->linkage);
6282
6283 pCfg->status = MPT_CONFIG_ERROR;
6284 pCfg->wait_done = 1;
6285 wake_up(&mpt_waitq);
6286 } 6258 }
6287 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 6259 break;
6260 default:
6261 break;
6288 } 6262 }
6289 6263
6290 return 1; /* currently means nothing really */ 6264 return 1; /* currently means nothing really */
@@ -7901,7 +7875,7 @@ fusion_init(void)
7901 /* Register ourselves (mptbase) in order to facilitate 7875 /* Register ourselves (mptbase) in order to facilitate
7902 * EventNotification handling. 7876 * EventNotification handling.
7903 */ 7877 */
7904 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER); 7878 mpt_base_index = mpt_register(mptbase_reply, MPTBASE_DRIVER);
7905 7879
7906 /* Register for hard reset handling callbacks. 7880 /* Register for hard reset handling callbacks.
7907 */ 7881 */