Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Avri Altman and committed by
Martin K. Petersen
5c17f87a 4bbbe242

+18 -9
+6 -1
Documentation/scsi/ufs.txt
··· 150 150 if (dir == SG_DXFER_TO_DEV) { 151 151 io_hdr_v4.dout_xfer_len = (uint32_t)byte_cnt; 152 152 io_hdr_v4.dout_xferp = (uintptr_t)(__u64)buff; 153 + } else { 154 + io_hdr_v4.din_xfer_len = (uint32_t)byte_cnt; 155 + io_hdr_v4.din_xferp = (uintptr_t)(__u64)buff; 153 156 } 154 157 155 - If you wish to write a descriptor, use the dout_xferp sg_io_v4. 158 + If you wish to read or write a descriptor, use the appropriate xferp of 159 + sg_io_v4. 160 + 156 161 157 162 UFS Specifications can be found at, 158 163 UFS - http://www.jedec.org/sites/default/files/docs/JESD220.pdf
+12 -8
drivers/scsi/ufs/ufs_bsg.c
··· 48 48 struct utp_upiu_query *qr; 49 49 u8 *descp; 50 50 51 - if (desc_op == UPIU_QUERY_OPCODE_READ_DESC) { 52 - dev_err(hba->dev, "unsupported opcode %d\n", desc_op); 53 - return -ENOTSUPP; 54 - } 55 - 56 - if (desc_op != UPIU_QUERY_OPCODE_WRITE_DESC) 51 + if (desc_op != UPIU_QUERY_OPCODE_WRITE_DESC && 52 + desc_op != UPIU_QUERY_OPCODE_READ_DESC) 57 53 goto out; 58 54 59 55 qr = &bsg_request->upiu_req.qr; ··· 67 71 if (!descp) 68 72 return -ENOMEM; 69 73 70 - sg_copy_to_buffer(job->request_payload.sg_list, 71 - job->request_payload.sg_cnt, descp, *desc_len); 74 + if (desc_op == UPIU_QUERY_OPCODE_WRITE_DESC) 75 + sg_copy_to_buffer(job->request_payload.sg_list, 76 + job->request_payload.sg_cnt, descp, 77 + *desc_len); 72 78 73 79 *desc_buff = descp; 74 80 ··· 137 139 138 140 if (!desc_buff) 139 141 goto out; 142 + 143 + if (desc_op == UPIU_QUERY_OPCODE_READ_DESC && desc_len) 144 + bsg_reply->reply_payload_rcv_len = 145 + sg_copy_from_buffer(job->request_payload.sg_list, 146 + job->request_payload.sg_cnt, 147 + desc_buff, desc_len); 140 148 141 149 kfree(desc_buff); 142 150