Skip to content

Commit

Permalink
scsi: ufs: Minor adjustments to error handling
Browse files Browse the repository at this point in the history
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.org
Reviewed-by: Avri Altman <avri.altman@wdc.com>
Signed-off-by: Can Guo <cang@codeaurora.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
  • Loading branch information
Can Guo authored and Martin K. Petersen committed Mar 4, 2021
1 parent dbdbb81 commit aa53f58
Showing 1 changed file with 12 additions and 6 deletions.
18 changes: 12 additions & 6 deletions drivers/scsi/ufs/ufshcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -4987,6 +4987,7 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
* UFS device needs urgent BKOPs.
*/
if (!hba->pm_op_in_progress &&
!ufshcd_eh_in_progress(hba) &&
ufshcd_is_exception_event(lrbp->ucd_rsp_ptr) &&
schedule_work(&hba->eeh_work)) {
/*
Expand Down Expand Up @@ -5784,13 +5785,20 @@ static void ufshcd_err_handling_prepare(struct ufs_hba *hba)
ufshcd_suspend_clkscaling(hba);
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)
{
ufshcd_scsi_unblock_requests(hba);
ufshcd_release(hba);
if (ufshcd_is_clkscaling_supported(hba))
ufshcd_clk_scaling_suspend(hba, false);
ufshcd_clear_ua_wluns(hba);
pm_runtime_put(hba->dev);
}

Expand Down Expand Up @@ -5882,8 +5890,8 @@ static void ufshcd_err_handler(struct work_struct *work)
spin_unlock_irqrestore(hba->host->host_lock, flags);
ufshcd_err_handling_prepare(hba);
spin_lock_irqsave(hba->host->host_lock, flags);
ufshcd_scsi_block_requests(hba);
hba->ufshcd_state = UFSHCD_STATE_RESET;
if (hba->ufshcd_state != UFSHCD_STATE_ERROR)
hba->ufshcd_state = UFSHCD_STATE_RESET;

/* Complete requests that have door-bell cleared by h/w */
ufshcd_complete_requests(hba);
Expand Down Expand Up @@ -6042,12 +6050,8 @@ static void ufshcd_err_handler(struct work_struct *work)
}
ufshcd_clear_eh_in_progress(hba);
spin_unlock_irqrestore(hba->host->host_lock, flags);
ufshcd_scsi_unblock_requests(hba);
ufshcd_err_handling_unprepare(hba);
up(&hba->host_sem);

if (!err && needs_reset)
ufshcd_clear_ua_wluns(hba);
}

/**
Expand Down Expand Up @@ -7858,6 +7862,8 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool async)
unsigned long flags;
ktime_t start = ktime_get();

hba->ufshcd_state = UFSHCD_STATE_RESET;

ret = ufshcd_link_startup(hba);
if (ret)
goto out;
Expand Down

0 comments on commit aa53f58

Please sign in to comment.