aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkashyap.desai@lsi.com <kashyap.desai@lsi.com>2011-08-05 01:34:37 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-08-27 10:35:53 -0400
commit98cbe371fd373f13806595835b79da07f3a2f934 (patch)
treefee917c26c396b1e8358ec91e3b50bb21e1a2558
parent55a3a35dd4fe616301450c85a77e2d5b5f4bb7bf (diff)
[SCSI] mptfusion: Fix for device offline while doing aggressive HBA reset
[Resend patch as per Bernd Schubert comment ] Issue: Device goes offline while doing aggressive HBA reset along with IO using some utility. Root cause: FW goes into bad state due to aggressive reset. Softreset does not help to recover FW. And also aggressive reset open up the window for Error handling thread to kicked off at the same time HBA will be in constant RESET loop as part of aggressive reset test case can lead Device to goes offline. Changes: 1. Added extra check as below inside eh_timed_out call back as below. if(ioc->ioc_reset_in_progress) Rc = EH_TIMER_RESET 2. Removed " DOORBELL_ACTIVE" check for SAS controller from task management context. Since SAS controller uses high priority queue for task management. This check is not required for SAS controller. 3. Moved SoftReset call to HardReset from Task Mgmt context. Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r--drivers/message/fusion/mptbase.c29
-rw-r--r--drivers/message/fusion/mptbase.h2
-rw-r--r--drivers/message/fusion/mptsas.c9
-rw-r--r--drivers/message/fusion/mptscsih.c12
4 files changed, 47 insertions, 5 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 517621fa8bca..e9c6a6047a00 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -6474,8 +6474,19 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
6474 pReq->Action, ioc->mptbase_cmds.status, timeleft)); 6474 pReq->Action, ioc->mptbase_cmds.status, timeleft));
6475 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) 6475 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
6476 goto out; 6476 goto out;
6477 if (!timeleft) 6477 if (!timeleft) {
6478 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6479 if (ioc->ioc_reset_in_progress) {
6480 spin_unlock_irqrestore(&ioc->taskmgmt_lock,
6481 flags);
6482 printk(MYIOC_s_INFO_FMT "%s: host reset in"
6483 " progress mpt_config timed out.!!\n",
6484 __func__, ioc->name);
6485 return -EFAULT;
6486 }
6487 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6478 issue_hard_reset = 1; 6488 issue_hard_reset = 1;
6489 }
6479 goto out; 6490 goto out;
6480 } 6491 }
6481 6492
@@ -7189,7 +7200,18 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
7189 spin_lock_irqsave(&ioc->taskmgmt_lock, flags); 7200 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7190 if (ioc->ioc_reset_in_progress) { 7201 if (ioc->ioc_reset_in_progress) {
7191 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); 7202 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7192 return 0; 7203 ioc->wait_on_reset_completion = 1;
7204 do {
7205 ssleep(1);
7206 } while (ioc->ioc_reset_in_progress == 1);
7207 ioc->wait_on_reset_completion = 0;
7208 return ioc->reset_status;
7209 }
7210 if (ioc->wait_on_reset_completion) {
7211 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7212 rc = 0;
7213 time_count = jiffies;
7214 goto exit;
7193 } 7215 }
7194 ioc->ioc_reset_in_progress = 1; 7216 ioc->ioc_reset_in_progress = 1;
7195 if (ioc->alt_ioc) 7217 if (ioc->alt_ioc)
@@ -7226,6 +7248,7 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
7226 ioc->ioc_reset_in_progress = 0; 7248 ioc->ioc_reset_in_progress = 0;
7227 ioc->taskmgmt_quiesce_io = 0; 7249 ioc->taskmgmt_quiesce_io = 0;
7228 ioc->taskmgmt_in_progress = 0; 7250 ioc->taskmgmt_in_progress = 0;
7251 ioc->reset_status = rc;
7229 if (ioc->alt_ioc) { 7252 if (ioc->alt_ioc) {
7230 ioc->alt_ioc->ioc_reset_in_progress = 0; 7253 ioc->alt_ioc->ioc_reset_in_progress = 0;
7231 ioc->alt_ioc->taskmgmt_quiesce_io = 0; 7254 ioc->alt_ioc->taskmgmt_quiesce_io = 0;
@@ -7241,7 +7264,7 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
7241 ioc->alt_ioc, MPT_IOC_POST_RESET); 7264 ioc->alt_ioc, MPT_IOC_POST_RESET);
7242 } 7265 }
7243 } 7266 }
7244 7267exit:
7245 dtmprintk(ioc, 7268 dtmprintk(ioc,
7246 printk(MYIOC_s_DEBUG_FMT 7269 printk(MYIOC_s_DEBUG_FMT
7247 "HardResetHandler: completed (%d seconds): %s\n", ioc->name, 7270 "HardResetHandler: completed (%d seconds): %s\n", ioc->name,
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index a4048ea45c92..b4d24dc081ae 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -753,6 +753,8 @@ typedef struct _MPT_ADAPTER
753 int taskmgmt_in_progress; 753 int taskmgmt_in_progress;
754 u8 taskmgmt_quiesce_io; 754 u8 taskmgmt_quiesce_io;
755 u8 ioc_reset_in_progress; 755 u8 ioc_reset_in_progress;
756 u8 reset_status;
757 u8 wait_on_reset_completion;
756 MPT_SCHEDULE_TARGET_RESET schedule_target_reset; 758 MPT_SCHEDULE_TARGET_RESET schedule_target_reset;
757 MPT_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds; 759 MPT_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds;
758 struct work_struct sas_persist_task; 760 struct work_struct sas_persist_task;
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 074e52254fcd..9d9504298549 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -1950,6 +1950,15 @@ static enum blk_eh_timer_return mptsas_eh_timed_out(struct scsi_cmnd *sc)
1950 goto done; 1950 goto done;
1951 } 1951 }
1952 1952
1953 /* In case if IOC is in reset from internal context.
1954 * Do not execute EEH for the same IOC. SML should to reset timer.
1955 */
1956 if (ioc->ioc_reset_in_progress) {
1957 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT ": %s: ioc is in reset,"
1958 "SML need to reset the timer (sc=%p)\n",
1959 ioc->name, __func__, sc));
1960 rc = BLK_EH_RESET_TIMER;
1961 }
1953 vdevice = sc->device->hostdata; 1962 vdevice = sc->device->hostdata;
1954 if (vdevice && vdevice->vtarget && (vdevice->vtarget->inDMD 1963 if (vdevice && vdevice->vtarget && (vdevice->vtarget->inDMD
1955 || vdevice->vtarget->deleted)) { 1964 || vdevice->vtarget->deleted)) {
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index de8cf92d8614..ced6e4dc0847 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -1630,7 +1630,13 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun,
1630 return 0; 1630 return 0;
1631 } 1631 }
1632 1632
1633 if (ioc_raw_state & MPI_DOORBELL_ACTIVE) { 1633 /* DOORBELL ACTIVE check is not required if
1634 * MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q is supported.
1635 */
1636
1637 if (!((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q)
1638 && (ioc->facts.MsgVersion >= MPI_VERSION_01_05)) &&
1639 (ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1634 printk(MYIOC_s_WARN_FMT 1640 printk(MYIOC_s_WARN_FMT
1635 "TaskMgmt type=%x: ioc_state: " 1641 "TaskMgmt type=%x: ioc_state: "
1636 "DOORBELL_ACTIVE (0x%x)!\n", 1642 "DOORBELL_ACTIVE (0x%x)!\n",
@@ -1729,7 +1735,9 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun,
1729 printk(MYIOC_s_WARN_FMT 1735 printk(MYIOC_s_WARN_FMT
1730 "Issuing Reset from %s!! doorbell=0x%08x\n", 1736 "Issuing Reset from %s!! doorbell=0x%08x\n",
1731 ioc->name, __func__, mpt_GetIocState(ioc, 0)); 1737 ioc->name, __func__, mpt_GetIocState(ioc, 0));
1732 retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP); 1738 retval = (ioc->bus_type == SAS) ?
1739 mpt_HardResetHandler(ioc, CAN_SLEEP) :
1740 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
1733 mpt_free_msg_frame(ioc, mf); 1741 mpt_free_msg_frame(ioc, mf);
1734 } 1742 }
1735 1743