6.1-stable review patch. If anyone has any objections, please let me know. ------------------ From: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> This reverts commit cf33e6ca12d814e1be2263cb76960d0019d7fb94 which is commit d0949565811f0896c1c7e781ab2ad99d34273fdf upstream. It is known to cause problems and has asked to be dropped. Link: https://lore.kernel.org/r/yq1frvvpymp.fsf@xxxxxxxxxxxxxxxxxxxx Cc: Tasos Sahanidis <tasos@xxxxxxxxxxxx> Cc: Ewan D. Milne <emilne@xxxxxxxxxx> Cc: Bart Van Assche <bvanassche@xxxxxxx> Cc: Tasos Sahanidis <tasos@xxxxxxxxxxxx> Cc: Martin K. Petersen <martin.petersen@xxxxxxxxxx> Cc: James Bottomley <jejb@xxxxxxxxxxxxx> Cc: Sasha Levin <sashal@xxxxxxxxxx> Reported-by: John David Anglin <dave.anglin@xxxxxxxx> Reported-by: Cyril Brulebois <kibi@xxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/scsi/scsi_lib.c | 52 +++++++++++++++++++++++---------------------- include/scsi/scsi_device.h | 51 ++++++++++++-------------------------------- 2 files changed, 41 insertions(+), 62 deletions(-) --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -185,37 +185,39 @@ void scsi_queue_insert(struct scsi_cmnd __scsi_queue_insert(cmd, reason, true); } + /** - * scsi_execute_cmd - insert request and wait for the result - * @sdev: scsi_device + * __scsi_execute - insert request and wait for the result + * @sdev: scsi device * @cmd: scsi command - * @opf: block layer request cmd_flags + * @data_direction: data direction * @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 - * @args: Optional args. See struct definition for field descriptions + * @flags: flags for ->cmd_flags + * @rq_flags: flags for ->rq_flags + * @resid: optional residual length * * 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_cmd(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) +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) { - static const struct scsi_exec_args default_args; struct request *req; struct scsi_cmnd *scmd; int ret; - if (!args) - args = &default_args; - else if (WARN_ON_ONCE(args->sense && - args->sense_len != SCSI_SENSE_BUFFERSIZE)) - return -EINVAL; - - req = scsi_alloc_request(sdev->request_queue, opf, args->req_flags); + 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); if (IS_ERR(req)) return PTR_ERR(req); @@ -230,7 +232,8 @@ int scsi_execute_cmd(struct scsi_device memcpy(scmd->cmnd, cmd, scmd->cmd_len); scmd->allowed = retries; req->timeout = timeout; - req->rq_flags |= RQF_QUIET; + req->cmd_flags |= flags; + req->rq_flags |= rq_flags | RQF_QUIET; /* * head injection *required* here otherwise quiesce won't work @@ -246,21 +249,20 @@ int scsi_execute_cmd(struct scsi_device if (unlikely(scmd->resid_len > 0 && scmd->resid_len <= bufflen)) memset(buffer + bufflen - scmd->resid_len, 0, scmd->resid_len); - if (args->resid) - *args->resid = scmd->resid_len; - if (args->sense) - memcpy(args->sense, scmd->sense_buffer, SCSI_SENSE_BUFFERSIZE); - if (args->sshdr) + 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, - args->sshdr); - + sshdr); ret = scmd->result; out: blk_mq_free_request(req); return ret; } -EXPORT_SYMBOL(scsi_execute_cmd); +EXPORT_SYMBOL(__scsi_execute); /* * Wake up the error handler if necessary. Avoid as follows that the error --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -479,51 +479,28 @@ extern const char *scsi_device_state_nam 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); - -/* Optional arguments to scsi_execute_cmd */ -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_cmd(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); - +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); /* Make sure any sense buffer is the correct size. */ -#define scsi_execute(_sdev, _cmd, _data_dir, _buffer, _bufflen, _sense, \ - _sshdr, _timeout, _retries, _flags, _rq_flags, \ - _resid) \ +#define scsi_execute(sdev, cmd, data_direction, buffer, bufflen, sense, \ + sshdr, timeout, retries, flags, rq_flags, resid) \ ({ \ - scsi_execute_cmd(_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, \ - }); \ + 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); \ }) - 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_cmd(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, - }); + return scsi_execute(sdev, cmd, data_direction, buffer, + bufflen, NULL, sshdr, timeout, retries, 0, 0, resid); } extern void sdev_disable_disk_events(struct scsi_device *sdev); extern void sdev_enable_disk_events(struct scsi_device *sdev);