[PATCH 06/18] scsi: Use dummy inquiry data for the host device

Hannes Reinecke
2021-05-03T15:03:57Z

Attach the dummy inquiry data to the scsi host device and use it
to check if any given device is a scsi host device.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
drivers/scsi/scsi_scan.c | 17 +++++++++++++++--
drivers/scsi/scsi_sysfs.c | 3 ++-
include/scsi/scsi_host.h | 7 ++++---
3 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index a50abba41ac1..55fa7f7317a2 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -1940,9 +1940,11 @@ struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
goto out;

sdev = scsi_alloc_sdev(starget, 0, NULL);
- if (sdev)
+ if (sdev) {
sdev->borken = 0;
- else
+ sdev->inquiry = (unsigned char *)scsi_null_inquiry;
+ sdev->inquiry_len = sizeof(scsi_null_inquiry);
+ } else
scsi_target_reap(starget);
put_device(&starget->dev);
out:
@@ -1967,3 +1969,14 @@ void scsi_free_host_dev(struct scsi_device *sdev)
}
EXPORT_SYMBOL(scsi_free_host_dev);

+/**
+ * scsi_device_is_host_dev - Check if a scsi device is a host device
+ * @sdev: SCSI device to test
+ *
+ * Returns: true if @sdev is a host device, false otherwise
+ */
+bool scsi_device_is_host_dev(struct scsi_device *sdev)
+{
+ return ((const unsigned char *)sdev->inquiry == scsi_null_inquiry);
+}
+EXPORT_SYMBOL_GPL(scsi_device_is_host_dev);
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 6d2a28294092..d5260d1b7b38 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -498,7 +498,8 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work)
kfree_rcu(vpd_pg80, rcu);
if (vpd_pg89)
kfree_rcu(vpd_pg89, rcu);
- kfree(sdev->inquiry);
+ if (!scsi_device_is_host_dev(sdev))
+ kfree(sdev->inquiry);
kfree(sdev);

if (parent)
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 3f3ebfdedeb2..f492e9034a62 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -804,14 +804,15 @@ void scsi_host_busy_iter(struct Scsi_Host *,
struct class_container;

/*
- * These two functions are used to allocate and free a pseudo device
- * which will connect to the host adapter itself rather than any
- * physical device. You must deallocate when you are done with the
+ * These three functions are used to allocate, free, and test for
+ * a pseudo device which will connect to the host adapter itself rather
+ * than any physical device. You must deallocate when you are done with the
* thing. This physical pseudo-device isn't real and won't be available
* from any high-level drivers.
*/
extern void scsi_free_host_dev(struct scsi_device *);
extern struct scsi_device *scsi_get_host_dev(struct Scsi_Host *);
+bool scsi_device_is_host_dev(struct scsi_device *);

/*
* DIF defines the exchange of protection information between
--
2.29.2