Blob Blame History Raw
From 37886aeaaf93bdb39f2973afed54208723573df5 Mon Sep 17 00:00:00 2001
From: Hannes Reinecke <hare@suse.de>
Date: Fri, 10 Jan 2020 08:47:03 +0100
Subject: [PATCH] scsi: add 'disable_async_probing' module argument
Patch-Mainline: never, SLE15-SP2 specific
References: jsc#SLE-11117,bsc#1156954

Add a 'disable_async_probing' module argument, which takes a comma-
separated list of drivers on which asynchronous device probing
should be disabled.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/scsi/hosts.c     | 15 +++++++++++++++
 drivers/scsi/scsi_scan.c |  3 +++
 include/scsi/scsi_host.h |  3 +++
 lib/cmdline.c            |  1 +
 4 files changed, 22 insertions(+)

diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -49,8 +49,22 @@ module_param_named(eh_deadline, shost_eh_deadline, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(eh_deadline,
 		 "SCSI EH timeout in seconds (should be between 0 and 2^31-1)");
 
+static char *shost_async_drv_names;
+module_param_named(disable_async_probing, shost_async_drv_names,
+		   charp, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(disable_async_probing,
+		 "Disable asynchronous device probing for drivers");
+
 static DEFINE_IDA(host_index_ida);
 
+static inline bool cmdline_disable_async_probing(struct scsi_host_template *sht)
+{
+	const char *drv_name = sht->proc_name ? sht->proc_name : sht->name;
+
+	if (!shost_async_drv_names || !strlen(shost_async_drv_names))
+		return false;
+	return parse_option_str(shost_async_drv_names, drv_name);
+}
 
 static void scsi_host_cls_release(struct device *dev)
 {
@@ -418,6 +432,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
 	shost->cmd_per_lun = sht->cmd_per_lun;
 	shost->no_write_same = sht->no_write_same;
 	shost->host_tagset = sht->host_tagset;
+	shost->async_device_scan = !cmdline_disable_async_probing(sht);
 
 	if (shost_eh_deadline == -1 || !sht->eh_host_reset_handler)
 		shost->eh_deadline = -1;
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 058079f915f1..b1533140ceed 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -1079,6 +1079,9 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
 	if (!sdev)
 		goto out;
 
+	dev_enable_async_probe(&sdev->sdev_gendev,
+			       shost->async_device_scan);
+
 	result = kmalloc(result_len, GFP_KERNEL);
 	if (!result)
 		goto out_free_sdev;
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 31e0d6ca1eba..2fcc7eb0722a 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -646,6 +646,9 @@ struct Scsi_Host {
 	/* The transport requires the LUN bits NOT to be stored in CDB[1] */
 	unsigned no_scsi2_lun_in_cdb:1;
 
+	/* Allow asynchronous device scan */
+	unsigned async_device_scan:1;
+
 	/*
 	 * Optional work queue to be utilized by the transport
 	 */
diff --git a/lib/cmdline.c b/lib/cmdline.c
index fbb9981a04a4..5e3149238d12 100644
--- a/lib/cmdline.c
+++ b/lib/cmdline.c
@@ -192,6 +192,7 @@ bool parse_option_str(const char *str, const char *option)
 
 	return false;
 }
+EXPORT_SYMBOL_GPL(parse_option_str);
 
 /*
  * Parse a string to get a param value pair.
-- 
2.16.4