From: Can Guo <c...@codeaurora.org>

[ Upstream commit 35fc4cd34426c242ab015ef280853b7bff101f48 ]

Users can initiate resets to specific SCSI device/target/host through
IOCTL. When this happens, the SCSI cmd passed to eh_device/target/host
_reset_handler() callbacks is initialized with a request whose tag is -1.
In this case it is not right for eh_device_reset_handler() callback to
count on the LUN get from hba->lrb[-1]. Fix it by getting LUN from the SCSI
device associated with the SCSI cmd.

Link: 
https://lore.kernel.org/r/1609157080-26283-1-git-send-email-c...@codeaurora.org
Reviewed-by: Avri Altman <avri.alt...@wdc.com>
Reviewed-by: Stanley Chu <stanley....@mediatek.com>
Signed-off-by: Can Guo <c...@codeaurora.org>
Signed-off-by: Martin K. Petersen <martin.peter...@oracle.com>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 drivers/scsi/ufs/ufshcd.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index b888117f4ecd3..476ef8044ae59 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -5980,19 +5980,16 @@ static int ufshcd_eh_device_reset_handler(struct 
scsi_cmnd *cmd)
 {
        struct Scsi_Host *host;
        struct ufs_hba *hba;
-       unsigned int tag;
        u32 pos;
        int err;
-       u8 resp = 0xF;
-       struct ufshcd_lrb *lrbp;
+       u8 resp = 0xF, lun;
        unsigned long flags;
 
        host = cmd->device->host;
        hba = shost_priv(host);
-       tag = cmd->request->tag;
 
-       lrbp = &hba->lrb[tag];
-       err = ufshcd_issue_tm_cmd(hba, lrbp->lun, 0, UFS_LOGICAL_RESET, &resp);
+       lun = ufshcd_scsi_to_upiu_lun(cmd->device->lun);
+       err = ufshcd_issue_tm_cmd(hba, lun, 0, UFS_LOGICAL_RESET, &resp);
        if (err || resp != UPIU_TASK_MANAGEMENT_FUNC_COMPL) {
                if (!err)
                        err = resp;
@@ -6001,7 +5998,7 @@ static int ufshcd_eh_device_reset_handler(struct 
scsi_cmnd *cmd)
 
        /* clear the commands that were pending for corresponding LUN */
        for_each_set_bit(pos, &hba->outstanding_reqs, hba->nutrs) {
-               if (hba->lrb[pos].lun == lrbp->lun) {
+               if (hba->lrb[pos].lun == lun) {
                        err = ufshcd_clear_cmd(hba, pos);
                        if (err)
                                break;
-- 
2.27.0



Reply via email to