OSDN Git Service

scsi: core: Add struct for args to execution functions
authorMike Christie <michael.christie@oracle.com>
Thu, 29 Dec 2022 19:01:40 +0000 (13:01 -0600)
committerMartin K. Petersen <martin.petersen@oracle.com>
Sat, 14 Jan 2023 02:34:08 +0000 (21:34 -0500)
Move the SCSI execution functions to use a struct for passing in optional
args. This commit adds the new struct, temporarily converts scsi_execute()
and scsi_execute_req() ands a new helper, scsi_execute_cmd(), which takes
the scsi_exec_args struct.

There should be no change in behavior. We no longer allow users to pass in
any request->rq_flags value, but they were only passing in RQF_PM which we
do support by allowing users to pass in the BLK_MQ_REQ flags used by
blk_mq_alloc_request().

Subsequent commits 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@oracle.com>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: John Garry <john.g.garry@oracle.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/scsi_lib.c
include/scsi/scsi_device.h

index 9ed1ebc..7d324db 100644 (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);
 
@@ -232,8 +230,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,20 +246,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
index 3642b8e..f6b33c6 100644 (file)
@@ -455,28 +455,51 @@ 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_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);
+
 /* 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);                                          \
+       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(sdev, cmd, data_direction, buffer,
-               bufflen, NULL, sshdr, timeout, retries,  0, 0, 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);