Reapply "scsi: core: Add struct for args to execution functions"

This reverts commit 345b6b8319 which is
commit d094956581 upstream.

Reverts of a revert, fun Android API stuff...

It breaks the Android kernel abi and can be brought back in the future
in an abi-safe way if it is really needed.

Bug: 161946584
Change-Id: I9f3f79916a434ecc00c5be57c56c2731760b4f2d
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman
2024-05-15 13:59:41 +00:00
parent faf34a67eb
commit 37db5a6cac
2 changed files with 57 additions and 27 deletions

View File

@@ -185,39 +185,37 @@ 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
* scsi_execute_cmd - insert request and wait for the result
* @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)
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)
{
static const struct scsi_exec_args default_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);
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);
if (IS_ERR(req))
return PTR_ERR(req);
@@ -233,8 +231,7 @@ int __scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
scmd->allowed = retries;
scmd->flags |= args->scmd_flags;
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
@@ -250,20 +247,21 @@ 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)
if (args->resid)
*args->resid = scmd->resid_len;
if (args->sense)
memcpy(args->sense, scmd->sense_buffer, SCSI_SENSE_BUFFERSIZE);
if (args->sshdr)
scsi_normalize_sense(scmd->sense_buffer, scmd->sense_len,
sshdr);
args->sshdr);
ret = scmd->result;
out:
blk_mq_free_request(req);
return ret;
}
EXPORT_SYMBOL(__scsi_execute);
EXPORT_SYMBOL(scsi_execute_cmd);
/*
* Wake up the error handler if necessary. Avoid as follows that the error

View File

@@ -476,6 +476,38 @@ int scsi_execute_cmd(struct scsi_device *sdev, const unsigned char *cmd,
int timeout, int retries,
const struct scsi_exec_args *args);
/* 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) \
({ \
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, \
}); \
})
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,
});
}
extern void sdev_disable_disk_events(struct scsi_device *sdev);
extern void sdev_enable_disk_events(struct scsi_device *sdev);
extern int scsi_vpd_lun_id(struct scsi_device *, char *, size_t);