diff options
| author | Hannes Reinecke <hare@suse.de> | 2020-05-06 11:19:09 +0200 |
|---|---|---|
| committer | Hannes Reinecke <hare@suse.de> | 2021-11-06 16:34:33 +0100 |
| commit | ab62e1bf357cb49bc1202b317666790b4eb1fc12 (patch) | |
| tree | 1e2b191111c4a3c61cf8ad0344ddf3326fa14307 | |
| parent | 9a80dd7e8fb2130ebd274fbe7ab438d0493e8ba2 (diff) | |
| download | scsi-devel-ab62e1bf357cb49bc1202b317666790b4eb1fc12.tar.gz | |
scsi: add scsi_{get,put}_internal_cmd() helper
Add helper functions to allow LLDDs to allocate and free
internal commands.
Signed-off-by: Hannes Reinecke <hare@suse.de>
| -rw-r--r-- | drivers/scsi/scsi_lib.c | 41 | ||||
| -rw-r--r-- | include/scsi/scsi_device.h | 3 |
2 files changed, 44 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 702afc7523fda..ff6c9f876078e 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1953,6 +1953,47 @@ void scsi_mq_destroy_tags(struct Scsi_Host *shost) } /** + * scsi_get_internal_cmd - allocate an intenral SCSI command + * @sdev: SCSI device from which to allocate the command + * @data_direction: Data direction for the allocated command + * @op_flags: request allocation flags + * + * Allocates a SCSI command for internal LLDD use. + */ +struct scsi_cmnd *scsi_get_internal_cmd(struct scsi_device *sdev, + int data_direction, int op_flags) +{ + struct request *rq; + struct scsi_cmnd *scmd; + blk_mq_req_flags_t flags = 0; + unsigned int op = REQ_INTERNAL | op_flags; + + op |= (data_direction == DMA_TO_DEVICE) ? + REQ_OP_DRV_OUT : REQ_OP_DRV_IN; + rq = blk_mq_alloc_request(sdev->request_queue, op, flags); + if (IS_ERR(rq)) + return NULL; + scmd = blk_mq_rq_to_pdu(rq); + scmd->request = 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) +{ + struct request *rq = blk_mq_rq_from_pdu(scmd); + + if (blk_rq_is_internal(rq)) + blk_mq_free_request(rq); +} +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 b97e142a7ca92..03bf5eb9b4a9a 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -469,6 +469,9 @@ static inline int scsi_execute_req(struct scsi_device *sdev, return scsi_execute(sdev, cmd, data_direction, buffer, bufflen, NULL, sshdr, timeout, retries, 0, 0, resid); } +struct scsi_cmnd *scsi_get_internal_cmd(struct scsi_device *sdev, + int data_direction, int op_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); |
