From: Jaegeuk Kim <[email protected]>

In order to conduct FFU or RPMB operations, UFS needs to clear UAC. This patch
clears it explicitly, so that we could get no failure given early execution.

Cc: Alim Akhtar <[email protected]>
Cc: Avri Altman <[email protected]>
Signed-off-by: Jaegeuk Kim <[email protected]>
---
 drivers/scsi/ufs/ufshcd.c | 41 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index d929c3d1e58cc..5deba03a61f75 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -7385,6 +7385,45 @@ static int ufshcd_add_lus(struct ufs_hba *hba)
        return ret;
 }
 
+static int
+ufshcd_send_request_sense(struct ufs_hba *hba, struct scsi_device *sdp);
+
+static int ufshcd_clear_uac(struct ufs_hba *hba)
+{
+       struct scsi_device *sdp;
+       unsigned long flags;
+       int ret = 0;
+
+       spin_lock_irqsave(hba->host->host_lock, flags);
+       sdp = hba->sdev_ufs_device;
+       if (sdp) {
+               ret = scsi_device_get(sdp);
+               if (!ret && !scsi_device_online(sdp)) {
+                       ret = -ENODEV;
+                       scsi_device_put(sdp);
+               }
+       } else {
+               ret = -ENODEV;
+       }
+       spin_unlock_irqrestore(hba->host->host_lock, flags);
+       if (ret)
+               goto out_err;
+
+       if (hba->wlun_dev_clr_ua) {
+               ret = ufshcd_send_request_sense(hba, sdp);
+               if (ret)
+                       goto out;
+               /* Unit attention condition is cleared now */
+               hba->wlun_dev_clr_ua = false;
+       }
+out:
+       scsi_device_put(sdp);
+out_err:
+       if (ret)
+               dev_err(hba->dev, "%s: Failed UAC clear ret = %d\n", __func__, 
ret);
+       return ret;
+}
+
 /**
  * ufshcd_probe_hba - probe hba to detect device and initialize
  * @hba: per-adapter instance
@@ -7500,6 +7539,8 @@ static void ufshcd_async_scan(void *data, async_cookie_t 
cookie)
                pm_runtime_put_sync(hba->dev);
                ufshcd_exit_clk_scaling(hba);
                ufshcd_hba_exit(hba);
+       } else {
+               ufshcd_clear_uac(hba);
        }
 }
 
-- 
2.28.0.618.gf4bc123cb7-goog

Reply via email to