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.altman@xxxxxxx> --- 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