Skip to content

Commit 9b5ac8a

Browse files
ahunter6martinkpetersen
authored andcommitted
scsi: ufs: Fix ufshcd_request_sense_async() for Samsung KLUFG8RHDA-B2D1
Samsung KLUFG8RHDA-B2D1 does not clear the unit attention condition if the length is zero. So go back to requesting all the sense data, as it was before patch "scsi: ufs: Request sense data asynchronously". That is simpler than creating and maintaining a quirk for affected devices. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Adrian Hunter <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 313bf28 commit 9b5ac8a

File tree

1 file changed

+29
-7
lines changed

1 file changed

+29
-7
lines changed

drivers/scsi/ufs/ufshcd.c

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7937,35 +7937,57 @@ static int ufshcd_add_lus(struct ufs_hba *hba)
79377937
static void ufshcd_request_sense_done(struct request *rq, blk_status_t error)
79387938
{
79397939
if (error != BLK_STS_OK)
7940-
pr_err("%s: REQUEST SENSE failed (%d)", __func__, error);
7940+
pr_err("%s: REQUEST SENSE failed (%d)\n", __func__, error);
7941+
kfree(rq->end_io_data);
79417942
blk_put_request(rq);
79427943
}
79437944

79447945
static int
79457946
ufshcd_request_sense_async(struct ufs_hba *hba, struct scsi_device *sdev)
79467947
{
79477948
/*
7948-
* From SPC-6: the REQUEST SENSE command with any allocation length
7949-
* clears the sense data.
7949+
* Some UFS devices clear unit attention condition only if the sense
7950+
* size used (UFS_SENSE_SIZE in this case) is non-zero.
79507951
*/
7951-
static const u8 cmd[6] = {REQUEST_SENSE, 0, 0, 0, 0, 0};
7952+
static const u8 cmd[6] = {REQUEST_SENSE, 0, 0, 0, UFS_SENSE_SIZE, 0};
79527953
struct scsi_request *rq;
79537954
struct request *req;
7955+
char *buffer;
7956+
int ret;
79547957

7955-
req = blk_get_request(sdev->request_queue, REQ_OP_DRV_IN, /*flags=*/0);
7956-
if (IS_ERR(req))
7957-
return PTR_ERR(req);
7958+
buffer = kzalloc(UFS_SENSE_SIZE, GFP_KERNEL);
7959+
if (!buffer)
7960+
return -ENOMEM;
7961+
7962+
req = blk_get_request(sdev->request_queue, REQ_OP_DRV_IN,
7963+
/*flags=*/BLK_MQ_REQ_PM);
7964+
if (IS_ERR(req)) {
7965+
ret = PTR_ERR(req);
7966+
goto out_free;
7967+
}
7968+
7969+
ret = blk_rq_map_kern(sdev->request_queue, req,
7970+
buffer, UFS_SENSE_SIZE, GFP_NOIO);
7971+
if (ret)
7972+
goto out_put;
79587973

79597974
rq = scsi_req(req);
79607975
rq->cmd_len = ARRAY_SIZE(cmd);
79617976
memcpy(rq->cmd, cmd, rq->cmd_len);
79627977
rq->retries = 3;
79637978
req->timeout = 1 * HZ;
79647979
req->rq_flags |= RQF_PM | RQF_QUIET;
7980+
req->end_io_data = buffer;
79657981

79667982
blk_execute_rq_nowait(/*bd_disk=*/NULL, req, /*at_head=*/true,
79677983
ufshcd_request_sense_done);
79687984
return 0;
7985+
7986+
out_put:
7987+
blk_put_request(req);
7988+
out_free:
7989+
kfree(buffer);
7990+
return ret;
79697991
}
79707992

79717993
static int ufshcd_clear_ua_wlun(struct ufs_hba *hba, u8 wlun)

0 commit comments

Comments
 (0)