]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
scsi: core: Add scsi_{get,put}_internal_cmd() helpers
authorHannes Reinecke <hare@suse.de>
Fri, 31 Oct 2025 20:39:14 +0000 (13:39 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 12 Nov 2025 22:02:31 +0000 (17:02 -0500)
Add helper functions to allow LLDDs to allocate and free internal commands.

[ bvanassche: changed the 'nowait' argument into a 'flags' argument. See also
  https://lore.kernel.org/linux-scsi/20211125151048.103910-3-hare@suse.de/ ]

Reviewed-by: John Garry <john.g.garry@oracle.com>
Signed-off-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Link: https://patch.msgid.link/20251031204029.2883185-7-bvanassche@acm.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/scsi_lib.c
include/scsi/scsi_device.h

index d4e874bbf2ea0371017789e76bec1c1dec0b48e3..51ad2ad07e4390fec91a915d858b4df7ddb60f61 100644 (file)
@@ -2134,6 +2134,44 @@ void scsi_mq_free_tags(struct kref *kref)
        complete(&shost->tagset_freed);
 }
 
+/**
+ * scsi_get_internal_cmd() - Allocate an internal SCSI command.
+ * @sdev: SCSI device from which to allocate the command
+ * @data_direction: Data direction for the allocated command
+ * @flags: request allocation flags, e.g. BLK_MQ_REQ_RESERVED or
+ *     BLK_MQ_REQ_NOWAIT.
+ *
+ * Allocates a SCSI command for internal LLDD use.
+ */
+struct scsi_cmnd *scsi_get_internal_cmd(struct scsi_device *sdev,
+                                       enum dma_data_direction data_direction,
+                                       blk_mq_req_flags_t flags)
+{
+       enum req_op op = data_direction == DMA_TO_DEVICE ? REQ_OP_DRV_OUT :
+                                                          REQ_OP_DRV_IN;
+       struct scsi_cmnd *scmd;
+       struct request *rq;
+
+       rq = scsi_alloc_request(sdev->request_queue, op, flags);
+       if (IS_ERR(rq))
+               return NULL;
+       scmd = blk_mq_rq_to_pdu(rq);
+       scmd->device = sdev;
+
+       return scmd;
+}
+EXPORT_SYMBOL_GPL(scsi_get_internal_cmd);
+
+/**
+ * scsi_put_internal_cmd() - Free an internal SCSI command.
+ * @scmd: SCSI command to be freed
+ */
+void scsi_put_internal_cmd(struct scsi_cmnd *scmd)
+{
+       blk_mq_free_request(blk_mq_rq_from_pdu(scmd));
+}
+EXPORT_SYMBOL_GPL(scsi_put_internal_cmd);
+
 /**
  * scsi_device_from_queue - return sdev associated with a request_queue
  * @q: The request queue to return the sdev from
index 9186310887114b5a1c0eca1bd95d8245ce047296..1e2e599517e980e5849111b84a49c430e4109bbc 100644 (file)
@@ -558,6 +558,10 @@ int scsi_execute_cmd(struct scsi_device *sdev, const unsigned char *cmd,
                     const struct scsi_exec_args *args);
 void scsi_failures_reset_retries(struct scsi_failures *failures);
 
+struct scsi_cmnd *scsi_get_internal_cmd(struct scsi_device *sdev,
+                                       enum dma_data_direction data_direction,
+                                       blk_mq_req_flags_t flags);
+void scsi_put_internal_cmd(struct scsi_cmnd *scmd);
 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);