From: Hannes Reinecke Date: Fri, 31 Oct 2025 20:39:14 +0000 (-0700) Subject: scsi: core: Add scsi_{get,put}_internal_cmd() helpers X-Git-Tag: v6.19-rc1~95^2~16^2~22 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a2ab4e33286de37f3fe8f28f86f5f71d6b0ae3b0;p=thirdparty%2Fkernel%2Flinux.git scsi: core: Add scsi_{get,put}_internal_cmd() helpers 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 Signed-off-by: Hannes Reinecke Signed-off-by: Bart Van Assche Link: https://patch.msgid.link/20251031204029.2883185-7-bvanassche@acm.org Signed-off-by: Martin K. Petersen --- diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index d4e874bbf2ea0..51ad2ad07e439 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -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 diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 9186310887114..1e2e599517e98 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -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);