Commit aa53f580 authored by Can Guo's avatar Can Guo Committed by Martin K. Petersen

scsi: ufs: Minor adjustments to error handling

In error handling prepare stage, after SCSI requests are blocked, do a
down/up_write(clk_scaling_lock) to clean up the queuecommand() path.
Meanwhile, stop eeh_work in case it disturbs error recovery. Moreover,
reset ufshcd_state at the entrance of ufshcd_probe_hba(), since it may be
called multiple times during error recovery.

Link: https://lore.kernel.org/r/1614145010-36079-2-git-send-email-cang@codeaurora.orgReviewed-by: default avatarAvri Altman <avri.altman@wdc.com>
Signed-off-by: default avatarCan Guo <cang@codeaurora.org>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent dbdbb81b
...@@ -4987,6 +4987,7 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) ...@@ -4987,6 +4987,7 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
* UFS device needs urgent BKOPs. * UFS device needs urgent BKOPs.
*/ */
if (!hba->pm_op_in_progress && if (!hba->pm_op_in_progress &&
!ufshcd_eh_in_progress(hba) &&
ufshcd_is_exception_event(lrbp->ucd_rsp_ptr) && ufshcd_is_exception_event(lrbp->ucd_rsp_ptr) &&
schedule_work(&hba->eeh_work)) { schedule_work(&hba->eeh_work)) {
/* /*
...@@ -5784,13 +5785,20 @@ static void ufshcd_err_handling_prepare(struct ufs_hba *hba) ...@@ -5784,13 +5785,20 @@ static void ufshcd_err_handling_prepare(struct ufs_hba *hba)
ufshcd_suspend_clkscaling(hba); ufshcd_suspend_clkscaling(hba);
ufshcd_clk_scaling_allow(hba, false); ufshcd_clk_scaling_allow(hba, false);
} }
ufshcd_scsi_block_requests(hba);
/* Drain ufshcd_queuecommand() */
down_write(&hba->clk_scaling_lock);
up_write(&hba->clk_scaling_lock);
cancel_work_sync(&hba->eeh_work);
} }
static void ufshcd_err_handling_unprepare(struct ufs_hba *hba) static void ufshcd_err_handling_unprepare(struct ufs_hba *hba)
{ {
ufshcd_scsi_unblock_requests(hba);
ufshcd_release(hba); ufshcd_release(hba);
if (ufshcd_is_clkscaling_supported(hba)) if (ufshcd_is_clkscaling_supported(hba))
ufshcd_clk_scaling_suspend(hba, false); ufshcd_clk_scaling_suspend(hba, false);
ufshcd_clear_ua_wluns(hba);
pm_runtime_put(hba->dev); pm_runtime_put(hba->dev);
} }
...@@ -5882,7 +5890,7 @@ static void ufshcd_err_handler(struct work_struct *work) ...@@ -5882,7 +5890,7 @@ static void ufshcd_err_handler(struct work_struct *work)
spin_unlock_irqrestore(hba->host->host_lock, flags); spin_unlock_irqrestore(hba->host->host_lock, flags);
ufshcd_err_handling_prepare(hba); ufshcd_err_handling_prepare(hba);
spin_lock_irqsave(hba->host->host_lock, flags); spin_lock_irqsave(hba->host->host_lock, flags);
ufshcd_scsi_block_requests(hba); if (hba->ufshcd_state != UFSHCD_STATE_ERROR)
hba->ufshcd_state = UFSHCD_STATE_RESET; hba->ufshcd_state = UFSHCD_STATE_RESET;
/* Complete requests that have door-bell cleared by h/w */ /* Complete requests that have door-bell cleared by h/w */
...@@ -6042,12 +6050,8 @@ static void ufshcd_err_handler(struct work_struct *work) ...@@ -6042,12 +6050,8 @@ static void ufshcd_err_handler(struct work_struct *work)
} }
ufshcd_clear_eh_in_progress(hba); ufshcd_clear_eh_in_progress(hba);
spin_unlock_irqrestore(hba->host->host_lock, flags); spin_unlock_irqrestore(hba->host->host_lock, flags);
ufshcd_scsi_unblock_requests(hba);
ufshcd_err_handling_unprepare(hba); ufshcd_err_handling_unprepare(hba);
up(&hba->host_sem); up(&hba->host_sem);
if (!err && needs_reset)
ufshcd_clear_ua_wluns(hba);
} }
/** /**
...@@ -7858,6 +7862,8 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool async) ...@@ -7858,6 +7862,8 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool async)
unsigned long flags; unsigned long flags;
ktime_t start = ktime_get(); ktime_t start = ktime_get();
hba->ufshcd_state = UFSHCD_STATE_RESET;
ret = ufshcd_link_startup(hba); ret = ufshcd_link_startup(hba);
if (ret) if (ret)
goto out; goto out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment