diff options
-rw-r--r-- | drivers/message/fusion/mptbase.c | 29 | ||||
-rw-r--r-- | drivers/message/fusion/mptbase.h | 2 | ||||
-rw-r--r-- | drivers/message/fusion/mptsas.c | 9 | ||||
-rw-r--r-- | drivers/message/fusion/mptscsih.c | 12 |
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 | 7267 | exit: | |
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 | ||