]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
scsi: core: add scsi_host_complete_all_commands() helper
authorHannes Reinecke <hare@suse.de>
Fri, 28 Feb 2020 07:53:07 +0000 (08:53 +0100)
committerMartin K. Petersen <martin.petersen@oracle.com>
Sat, 29 Feb 2020 01:54:47 +0000 (20:54 -0500)
Add a helper scsi_host_complete_all_commands() to terminate all outstanding
commands on a SCSI host.

Link: https://lore.kernel.org/r/20200228075318.91255-3-hare@suse.de
Signed-off-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/hosts.c
include/scsi/scsi_host.h

index 1d669e47b692ea45b1d9be7e5b8e4888de6dc27d..00ae9d43ce9f543cd8066e1408b5878e6be2386e 100644 (file)
@@ -650,3 +650,31 @@ void scsi_flush_work(struct Scsi_Host *shost)
        flush_workqueue(shost->work_q);
 }
 EXPORT_SYMBOL_GPL(scsi_flush_work);
+
+static bool complete_all_cmds_iter(struct request *rq, void *data, bool rsvd)
+{
+       struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(rq);
+       int status = *(int *)data;
+
+       scsi_dma_unmap(scmd);
+       scmd->result = status << 16;
+       scmd->scsi_done(scmd);
+       return true;
+}
+
+/**
+ * scsi_host_complete_all_commands - Terminate all running commands
+ * @shost:     Scsi Host on which commands should be terminated
+ * @status:    Status to be set for the terminated commands
+ *
+ * There is no protection against modification of the number
+ * of outstanding commands. It is the responsibility of the
+ * caller to ensure that concurrent I/O submission and/or
+ * completion is stopped when calling this function.
+ */
+void scsi_host_complete_all_commands(struct Scsi_Host *shost, int status)
+{
+       blk_mq_tagset_busy_iter(&shost->tag_set, complete_all_cmds_iter,
+                               &status);
+}
+EXPORT_SYMBOL_GPL(scsi_host_complete_all_commands);
index 7a97fb8104cfa57f496590d05ae15d4833ced239..25bef781cbe14ba105199378f84d022985b12345 100644 (file)
@@ -732,6 +732,8 @@ extern int scsi_host_busy(struct Scsi_Host *shost);
 extern void scsi_host_put(struct Scsi_Host *t);
 extern struct Scsi_Host *scsi_host_lookup(unsigned short);
 extern const char *scsi_host_state_name(enum scsi_host_state);
+extern void scsi_host_complete_all_commands(struct Scsi_Host *shost,
+                                           int status);
 
 static inline int __must_check scsi_add_host(struct Scsi_Host *host,
                                             struct device *dev)