Add this functionality, now that job->reply is big enough.
While at it, fix a typo in ufs_bsg_verify_query_params.

Signed-off-by: Avri Altman <avri.alt...@wdc.com>
---
 Documentation/scsi/ufs.txt |  8 ++++++++
 drivers/scsi/ufs/ufs_bsg.c | 25 +++++++++++++++----------
 2 files changed, 23 insertions(+), 10 deletions(-)

diff --git a/Documentation/scsi/ufs.txt b/Documentation/scsi/ufs.txt
index 520b5b0..e90d756 100644
--- a/Documentation/scsi/ufs.txt
+++ b/Documentation/scsi/ufs.txt
@@ -148,6 +148,14 @@ send SG_IO with the applicable sg_io_v4:
        io_hdr_v4.request_len = request_len;
        io_hdr_v4.request = (__u64)request_upiu;
 
+If you wish to write a descriptor, append it right after the bsg request, and
+indicate the total size (sizeof(struct ufs_bsg_request) + sizeof(descriptor))
+in the request_len. Similarly, If you wish to read a descriptor, indicate the
+total size (sizeof(struct ufs_bsg_reply) + sizeof(descriptor)) in the
+max_response_len. Expect to find it in the appropriate offset - right after the
+bsg reply, in the response.
+
+
 UFS Specifications can be found at,
 UFS - http://www.jedec.org/sites/default/files/docs/JESD220.pdf
 UFSHCI - http://www.jedec.org/sites/default/files/docs/JESD223.pdf
diff --git a/drivers/scsi/ufs/ufs_bsg.c b/drivers/scsi/ufs/ufs_bsg.c
index e5f8e54..cc27799 100644
--- a/drivers/scsi/ufs/ufs_bsg.c
+++ b/drivers/scsi/ufs/ufs_bsg.c
@@ -36,6 +36,9 @@ static int ufs_bsg_verify_query_size(struct ufs_hba *hba,
        if (desc_op == UPIU_QUERY_OPCODE_WRITE_DESC)
                min_req_len += desc_len;
 
+       if (desc_op == UPIU_QUERY_OPCODE_READ_DESC)
+               min_rsp_len += desc_len;
+
        if (min_req_len > request_len || min_rsp_len > reply_len) {
                dev_err(hba->dev, "not enough space assigned\n");
                return -EINVAL;
@@ -47,18 +50,15 @@ static int ufs_bsg_verify_query_size(struct ufs_hba *hba,
 static int ufs_bsg_verify_query_params(struct ufs_hba *hba,
                                       struct ufs_bsg_request *bsg_request,
                                       unsigned int request_len,
+                                      struct ufs_bsg_reply *bsg_reply,
                                       unsigned int reply_len,
-                                      uint8_t *desc_buff, int *desc_len,
+                                      uint8_t **desc_buff, int *desc_len,
                                       enum query_opcode desc_op)
 {
        struct utp_upiu_query *qr;
 
-       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,7 +71,8 @@ static int ufs_bsg_verify_query_params(struct ufs_hba *hba,
                                      desc_op))
                return -EINVAL;
 
-       desc_buff = (uint8_t *)(bsg_request + 1);
+       *desc_buff = desc_op == UPIU_QUERY_OPCODE_WRITE_DESC ?
+                   (uint8_t *)(bsg_request + 1) : (uint8_t *)(bsg_reply + 1);
 
 out:
        return 0;
@@ -102,8 +103,9 @@ static int ufs_bsg_request(struct bsg_job *job)
        case UPIU_TRANSACTION_QUERY_REQ:
                desc_op = bsg_request->upiu_req.qr.opcode;
                ret = ufs_bsg_verify_query_params(hba, bsg_request, req_len,
-                                                 reply_len, desc_buff,
-                                                 &desc_len, desc_op);
+                                                 bsg_reply, reply_len,
+                                                 &desc_buff, &desc_len,
+                                                 desc_op);
                if (ret)
                        goto out;
 
@@ -135,6 +137,9 @@ static int ufs_bsg_request(struct bsg_job *job)
                break;
        }
 
+       if (desc_buff)
+               bsg_reply->reply_payload_rcv_len = desc_len;
+
 out:
        bsg_reply->result = ret;
        job->reply_len = sizeof(struct ufs_bsg_reply) +
-- 
1.9.1

Reply via email to