diff options
author | Avri Altman <avri.altman@wdc.com> | 2019-02-20 08:11:14 +0100 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2019-02-27 15:00:02 +0100 |
commit | 5c17f87abb1a86eb4d2a108477e56389622cf195 (patch) | |
tree | 05d55c07b59ec5ef06a3ae3e52b3e8ab2f091163 /drivers/scsi/ufs | |
parent | scsi: ufs: Allow reading descriptor via raw upiu (diff) | |
download | linux-5c17f87abb1a86eb4d2a108477e56389622cf195.tar.xz linux-5c17f87abb1a86eb4d2a108477e56389622cf195.zip |
scsi: ufs-bsg: Allow reading descriptors
Add this functionality, placing the descriptor being read in the actual
data buffer in the bio.
That is, for both read and write descriptors query upiu, we are using the
job's request_payload. This in turn, is mapped back in user land to the
applicable sg_io_v4 xferp: dout_xferp for write descriptor, and din_xferp
for read descriptor.
Signed-off-by: Avri Altman <avri.altman@wdc.com>
Reviewed-by: Evan Green <evgreen@chromium.org>
Reviewed-by: Bean Huo <beanhuo@micron.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/ufs')
-rw-r--r-- | drivers/scsi/ufs/ufs_bsg.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/drivers/scsi/ufs/ufs_bsg.c b/drivers/scsi/ufs/ufs_bsg.c index 2fd0769efafe..869e71f861d6 100644 --- a/drivers/scsi/ufs/ufs_bsg.c +++ b/drivers/scsi/ufs/ufs_bsg.c @@ -48,12 +48,8 @@ static int ufs_bsg_alloc_desc_buffer(struct ufs_hba *hba, struct bsg_job *job, struct utp_upiu_query *qr; u8 *descp; - if (desc_op == UPIU_QUERY_OPCODE_READ_DESC) { - dev_err(hba->dev, "unsupported opcode %d\n", desc_op); - return -ENOTSUPP; - } - - if (desc_op != UPIU_QUERY_OPCODE_WRITE_DESC) + if (desc_op != UPIU_QUERY_OPCODE_WRITE_DESC && + desc_op != UPIU_QUERY_OPCODE_READ_DESC) goto out; qr = &bsg_request->upiu_req.qr; @@ -71,8 +67,10 @@ static int ufs_bsg_alloc_desc_buffer(struct ufs_hba *hba, struct bsg_job *job, if (!descp) return -ENOMEM; - sg_copy_to_buffer(job->request_payload.sg_list, - job->request_payload.sg_cnt, descp, *desc_len); + if (desc_op == UPIU_QUERY_OPCODE_WRITE_DESC) + sg_copy_to_buffer(job->request_payload.sg_list, + job->request_payload.sg_cnt, descp, + *desc_len); *desc_buff = descp; @@ -140,6 +138,12 @@ static int ufs_bsg_request(struct bsg_job *job) if (!desc_buff) goto out; + if (desc_op == UPIU_QUERY_OPCODE_READ_DESC && desc_len) + bsg_reply->reply_payload_rcv_len = + sg_copy_from_buffer(job->request_payload.sg_list, + job->request_payload.sg_cnt, + desc_buff, desc_len); + kfree(desc_buff); out: |