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