This begins to move the SCSI execution functions to use a struct for passing in optional args. This patch adds the new struct, temporarily converts scsi_execute and scsi_execute_req and add two helpers: 1. scsi_execute_args which takes the scsi_exec_args struct. 2. scsi_execute_cmd does not support the scsi_exec_args struct. The next patches will convert scsi_execute and scsi_execute_req users to the new helpers then remove scsi_execute and scsi_execute_req. Signed-off-by: Mike Christie <michael.christie@xxxxxxxxxx> --- drivers/scsi/scsi_lib.c | 40 ++++++++-------------- include/scsi/scsi_device.h | 70 ++++++++++++++++++++++++++++++-------- 2 files changed, 71 insertions(+), 39 deletions(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index a29d87e57430..f76acb468abb 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -185,39 +185,29 @@ void scsi_queue_insert(struct scsi_cmnd *cmd, int reason) __scsi_queue_insert(cmd, reason, true); } - /** * __scsi_execute - insert request and wait for the result - * @sdev: scsi device + * @sdev: scsi_device * @cmd: scsi command - * @data_direction: data direction + * @opf: block layer request cmd_flags * @buffer: data buffer * @bufflen: len of buffer - * @sense: optional sense buffer - * @sshdr: optional decoded sense header * @timeout: request timeout in HZ * @retries: number of times to retry request - * @flags: flags for ->cmd_flags - * @rq_flags: flags for ->rq_flags - * @resid: optional residual length + * @args: Optional args. See struct definition for field descriptions * * Returns the scsi_cmnd result field if a command was executed, or a negative * Linux error code if we didn't get that far. */ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, - int data_direction, void *buffer, unsigned bufflen, - unsigned char *sense, struct scsi_sense_hdr *sshdr, - int timeout, int retries, blk_opf_t flags, - req_flags_t rq_flags, int *resid) + blk_opf_t opf, void *buffer, unsigned int bufflen, + int timeout, int retries, const struct scsi_exec_args args) { struct request *req; struct scsi_cmnd *scmd; int ret; - req = scsi_alloc_request(sdev->request_queue, - data_direction == DMA_TO_DEVICE ? - REQ_OP_DRV_OUT : REQ_OP_DRV_IN, - rq_flags & RQF_PM ? BLK_MQ_REQ_PM : 0); + req = scsi_alloc_request(sdev->request_queue, opf, args.req_flags); if (IS_ERR(req)) return PTR_ERR(req); @@ -232,8 +222,7 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, memcpy(scmd->cmnd, cmd, scmd->cmd_len); scmd->allowed = retries; req->timeout = timeout; - req->cmd_flags |= flags; - req->rq_flags |= rq_flags | RQF_QUIET; + req->rq_flags |= RQF_QUIET; /* * head injection *required* here otherwise quiesce won't work @@ -249,13 +238,14 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, if (unlikely(scmd->resid_len > 0 && scmd->resid_len <= bufflen)) memset(buffer + bufflen - scmd->resid_len, 0, scmd->resid_len); - if (resid) - *resid = scmd->resid_len; - if (sense && scmd->sense_len) - memcpy(sense, scmd->sense_buffer, SCSI_SENSE_BUFFERSIZE); - if (sshdr) - scsi_normalize_sense(scmd->sense_buffer, scmd->sense_len, - sshdr); + if (args.resid) + *args.resid = scmd->resid_len; + if (args.sense && scmd->sense_len) + memcpy(args.sense, scmd->sense_buffer, SCSI_SENSE_BUFFERSIZE); + if (args.sshdr) + scsi_normalize_sense(scmd->sense_buffer, + scmd->sense_len, args.sshdr); + ret = scmd->result; out: blk_mq_free_request(req); diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 3642b8e3928b..eb960aa73b3b 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -455,28 +455,70 @@ extern const char *scsi_device_state_name(enum scsi_device_state); extern int scsi_is_sdev_device(const struct device *); extern int scsi_is_target_device(const struct device *); extern void scsi_sanitize_inquiry_string(unsigned char *s, int len); -extern int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, - int data_direction, void *buffer, unsigned bufflen, - unsigned char *sense, struct scsi_sense_hdr *sshdr, - int timeout, int retries, blk_opf_t flags, - req_flags_t rq_flags, int *resid); + +/* Optional arguments to __scsi_execute */ +struct scsi_exec_args { + unsigned char *sense; /* sense buffer */ + unsigned int sense_len; /* sense buffer len */ + struct scsi_sense_hdr *sshdr; /* decoded sense header */ + blk_mq_req_flags_t req_flags; /* BLK_MQ_REQ flags */ + int *resid; /* residual length */ +}; + +int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, + blk_opf_t opf, void *buffer, unsigned int bufflen, + int timeout, int retries, const struct scsi_exec_args args); + +#define scsi_execute_args(sdev, cmd, opf, buffer, bufflen, timeout, \ + retries, args) \ +({ \ + BUILD_BUG_ON(args.sense && \ + args.sense_len != SCSI_SENSE_BUFFERSIZE); \ + __scsi_execute(sdev, cmd, opf, buffer, bufflen, timeout, \ + retries, args); \ +}) + +#define scsi_execute_cmd(sdev, cmd, opf, buffer, bufflen, timeout, \ + retries) \ +({ \ + struct scsi_exec_args exec_args = {}; \ + \ + __scsi_execute(sdev, cmd, opf, buffer, bufflen, timeout, \ + retries, exec_args); \ +}) + /* Make sure any sense buffer is the correct size. */ -#define scsi_execute(sdev, cmd, data_direction, buffer, bufflen, sense, \ - sshdr, timeout, retries, flags, rq_flags, resid) \ +#define scsi_execute(_sdev, _cmd, _data_dir, _buffer, _bufflen, _sense, \ + _sshdr, _timeout, _retries, _flags, _rq_flags, \ + _resid) \ ({ \ - BUILD_BUG_ON((sense) != NULL && \ - sizeof(sense) != SCSI_SENSE_BUFFERSIZE); \ - __scsi_execute(sdev, cmd, data_direction, buffer, bufflen, \ - sense, sshdr, timeout, retries, flags, rq_flags, \ - resid); \ + BUILD_BUG_ON((_sense) != NULL && \ + sizeof(_sense) != SCSI_SENSE_BUFFERSIZE); \ + __scsi_execute(_sdev, _cmd, (_data_dir == DMA_TO_DEVICE ? \ + REQ_OP_DRV_OUT : REQ_OP_DRV_IN) | _flags, \ + _buffer, _bufflen, _timeout, _retries, \ + (struct scsi_exec_args) { \ + .sense = _sense, \ + .sshdr = _sshdr, \ + .req_flags = _rq_flags & RQF_PM ? \ + BLK_MQ_REQ_PM : 0, \ + .resid = _resid, \ + }); \ }) + static inline int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd, int data_direction, void *buffer, unsigned bufflen, struct scsi_sense_hdr *sshdr, int timeout, int retries, int *resid) { - return scsi_execute(sdev, cmd, data_direction, buffer, - bufflen, NULL, sshdr, timeout, retries, 0, 0, resid); + return __scsi_execute(sdev, cmd, + data_direction == DMA_TO_DEVICE ? + REQ_OP_DRV_OUT : REQ_OP_DRV_IN, buffer, + bufflen, timeout, retries, + (struct scsi_exec_args) { + .sshdr = sshdr, + .resid = resid, + }); } extern void sdev_disable_disk_events(struct scsi_device *sdev); extern void sdev_enable_disk_events(struct scsi_device *sdev); -- 2.25.1