From: Peter Wang <peter.wang@xxxxxxxxxxxx> When uic error (NON_FATAL) happen in runtime pm flow, ufshcd_err_handler stuck in ufshcd_rpm_get_sync, but runtime pm(suspend or resume) stuck in send SSU(sleep or active) which always get SCSI_MLQUEUE_HOST_BUSY. This patch try to solve this deadlock: 1. Return error to break runtime suspend let err handler going, same as UFSHCD_STATE_EH_SCHEDULED_FATAL do. 2. Try do recovery if SSU(active) fail when resume, prevent resume return fail which casue IO hang. Signed-off-by: Peter Wang <peter.wang@xxxxxxxxxxxx> --- drivers/ufs/core/ufshcd.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 129446775796..bc30a0842277 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -2863,6 +2863,14 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) * being issued in that case. */ if (ufshcd_eh_in_progress(hba)) { + /* Same as UFSHCD_STATE_EH_SCHEDULED_FATAL */ + if (hba->pm_op_in_progress) { + hba->force_reset = true; + set_host_byte(cmd, DID_BAD_TARGET); + scsi_done(cmd); + goto out; + } + err = SCSI_MLQUEUE_HOST_BUSY; goto out; } @@ -9784,6 +9792,9 @@ static int __ufshcd_wl_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) if (!ufshcd_is_ufs_dev_active(hba)) { ret = ufshcd_set_dev_pwr_mode(hba, UFS_ACTIVE_PWR_MODE); + /* Try prevent return error, else IO hang */ + if (ret) + ret = ufshcd_link_recovery(hba); if (ret) goto set_old_link_state; ufshcd_set_timestamp_attr(hba); -- 2.18.0