From: Hannes Reinecke <hare@suse.de>
To: "Martin K. Petersen" <martin.petersen@oracle.com>
Cc: Christoph Hellwig <hch@lst.de>,
James Bottomley <james.bottomley@hansenpartnership.com>,
John Garry <john.garry@huawei.com>,
Ming Lei <ming.lei@redhat.com>,
Bart van Assche <bvanassche@acm.org>,
linux-scsi@vger.kernel.org, Hannes Reinecke <hare@suse.de>
Subject: [PATCH RFC v3 10/41] scsi: make host device a first-class citizen
Date: Thu, 30 Apr 2020 15:18:33 +0200 [thread overview]
Message-ID: <20200430131904.5847-11-hare@suse.de> (raw)
In-Reply-To: <20200430131904.5847-1-hare@suse.de>
Rather than having the device created by scsi_get_host_dev() as
a weird semi-initialized device make it a first class citizen by
implementing a minimal command emulation and provide (static)
inquiry data.
Signed-off-by: Hannes Reinecke <hare@suse.de>
---
drivers/scsi/scsi_lib.c | 24 +++++++++++++++++++
drivers/scsi/scsi_scan.c | 60 +++++++++++++++++++++++++++++++++++-----------
drivers/scsi/scsi_sysfs.c | 3 ++-
include/scsi/scsi_device.h | 1 +
include/scsi/scsi_host.h | 3 +++
5 files changed, 76 insertions(+), 15 deletions(-)
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 30f9ca9fce22..ce9f1d83aaee 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -1528,6 +1528,30 @@ static int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
}
+ if (unlikely(scsi_device_is_virtual(cmd->device))) {
+ unsigned char null_report_luns[16];
+
+ switch (cmd->cmnd[0]) {
+ case TEST_UNIT_READY:
+ cmd->result = (DID_OK << 16);
+ goto done;
+ case INQUIRY:
+ scsi_sg_copy_from_buffer(cmd, cmd->device->inquiry, 36);
+ cmd->result = (DID_OK << 16);
+ goto done;
+ case REPORT_LUNS:
+ memset(null_report_luns, 0, 16);
+ null_report_luns[3] = 0x08;
+ scsi_sg_copy_from_buffer(cmd, null_report_luns, 16);
+ cmd->result = (DID_OK << 16);
+ goto done;
+ default:
+ scsi_build_sense_buffer(0, cmd->sense_buffer,
+ ILLEGAL_REQUEST, 0x20, 0x00);
+ cmd->result = (DID_NO_CONNECT << 16);
+ goto done;
+ }
+ }
trace_scsi_dispatch_cmd_start(cmd);
rtn = host->hostt->queuecommand(host, cmd);
if (rtn) {
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 4648fd3f80d9..fdc291c47b9b 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -1080,6 +1080,9 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
if (!sdev)
goto out;
+ if (sdev->hidden)
+ return SCSI_SCAN_LUN_PRESENT;
+
result = kmalloc(result_len, GFP_KERNEL |
((shost->unchecked_isa_dma) ? __GFP_DMA : 0));
if (!result)
@@ -1325,6 +1328,8 @@ static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflag
sdev = scsi_alloc_sdev(starget, 0, NULL);
if (!sdev)
return 0;
+ if (sdev->hidden)
+ return 0;
if (scsi_device_get(sdev)) {
__scsi_remove_device(sdev);
return 0;
@@ -1698,6 +1703,8 @@ static void scsi_sysfs_add_devices(struct Scsi_Host *shost)
/* If device is already visible, skip adding it to sysfs */
if (sdev->is_visible)
continue;
+ if (sdev->hidden)
+ continue;
if (!scsi_host_scan_allowed(shost) ||
scsi_sysfs_add_sdev(sdev) != 0)
__scsi_remove_device(sdev);
@@ -1861,39 +1868,48 @@ EXPORT_SYMBOL(scsi_scan_host);
void scsi_forget_host(struct Scsi_Host *shost)
{
- struct scsi_device *sdev;
+ struct scsi_device *sdev, *virtual_sdev = NULL;
unsigned long flags;
restart:
spin_lock_irqsave(shost->host_lock, flags);
list_for_each_entry(sdev, &shost->__devices, siblings) {
+ if (scsi_device_is_virtual(sdev)) {
+ virtual_sdev = sdev;
+ continue;
+ }
if (sdev->sdev_state == SDEV_DEL)
continue;
spin_unlock_irqrestore(shost->host_lock, flags);
__scsi_remove_device(sdev);
goto restart;
}
+ /* Remove virtual device last, might be needed to send commands */
+ if (virtual_sdev)
+ __scsi_remove_device(virtual_sdev);
spin_unlock_irqrestore(shost->host_lock, flags);
}
/**
- * scsi_get_host_dev - Create a scsi_device that points to the host adapter itself
+ * scsi_get_virtual_dev - Create a virtual scsi_device to the host adapter
* @shost: Host that needs a scsi_device
+ * @channel: SCSI channel number for the virtual device
+ * @id: SCSI target number for the virtual device
*
* Lock status: None assumed.
*
* Returns: The scsi_device or NULL
*
* Notes:
- * Attach a single scsi_device to the Scsi_Host - this should
- * be made to look like a "pseudo-device" that points to the
- * HA itself.
- *
- * Note - this device is not accessible from any high-level
- * drivers (including generics), which is probably not
- * optimal. We can add hooks later to attach.
+ * Attach a single scsi_device to the Scsi_Host. This device
+ * has a minimal command emulation, but will never submit commands
+ * to the LLDD. The primary aim for this device is to serve as a
+ * container from which command tags can be allocated from; each
+ * scsi command will carry an unused/free command tag, which then
+ * can be used by the LLDD to format internal or passthrough commands.
*/
-struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
+struct scsi_device *scsi_get_virtual_dev(struct Scsi_Host *shost,
+ unsigned int channel, unsigned int id)
{
struct scsi_device *sdev = NULL;
struct scsi_target *starget;
@@ -1901,22 +1917,38 @@ struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
mutex_lock(&shost->scan_mutex);
if (!scsi_host_scan_allowed(shost))
goto out;
- starget = scsi_alloc_target(&shost->shost_gendev, 0, shost->this_id);
+ starget = scsi_alloc_target(&shost->shost_gendev, channel, id);
if (!starget)
goto out;
sdev = scsi_alloc_sdev(starget, 0, NULL);
- if (sdev)
+ if (sdev) {
sdev->borken = 0;
- else
+ sdev->hidden = 1;
+ sdev->inquiry = (unsigned char *)scsi_null_inquiry;
+ sdev->inquiry_len = sizeof(scsi_null_inquiry);
+ scsi_device_set_state(sdev, SDEV_RUNNING);
+ } else
scsi_target_reap(starget);
put_device(&starget->dev);
out:
mutex_unlock(&shost->scan_mutex);
return sdev;
}
+EXPORT_SYMBOL_GPL(scsi_get_virtual_dev);
+
+struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
+{
+ return scsi_get_virtual_dev(shost, 0, shost->this_id);
+}
EXPORT_SYMBOL(scsi_get_host_dev);
+bool scsi_device_is_virtual(struct scsi_device *sdev)
+{
+ return ((const unsigned char *)sdev->inquiry == scsi_null_inquiry);
+}
+EXPORT_SYMBOL_GPL(scsi_device_is_virtual);
+
/**
* scsi_free_host_dev - Free a scsi_device that points to the host adapter itself
* @sdev: Host device to be freed
@@ -1927,7 +1959,7 @@ EXPORT_SYMBOL(scsi_get_host_dev);
*/
void scsi_free_host_dev(struct scsi_device *sdev)
{
- BUG_ON(sdev->id != sdev->host->this_id);
+ BUG_ON(!scsi_device_is_virtual(sdev));
__scsi_remove_device(sdev);
}
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 163dbcb741c1..c54011c2cdda 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -485,7 +485,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_virtual(sdev))
+ kfree(sdev->inquiry);
kfree(sdev);
if (parent)
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index e74c7e671aa0..6039ce7d09d7 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -203,6 +203,7 @@ struct scsi_device {
unsigned unmap_limit_for_ws:1; /* Use the UNMAP limit for WRITE SAME */
unsigned rpm_autosuspend:1; /* Enable runtime autosuspend at device
* creation time */
+ unsigned hidden:1; /* Do not register with sysfs */
bool offline_already; /* Device offline message logged */
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 37bb7d74e4c4..6961cbc3b2c0 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -781,7 +781,10 @@ struct class_container;
* from any high-level drivers.
*/
extern void scsi_free_host_dev(struct scsi_device *);
+extern struct scsi_device *scsi_get_virtual_dev(struct Scsi_Host *,
+ unsigned int, unsigned int);
extern struct scsi_device *scsi_get_host_dev(struct Scsi_Host *);
+extern bool scsi_device_is_virtual(struct scsi_device *);
/*
* DIF defines the exchange of protection information between
--
2.16.4
next prev parent reply other threads:[~2020-04-30 13:20 UTC|newest]
Thread overview: 104+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-30 13:18 [PATCH RFC v3 00/41] scsi: enable reserved commands for LLDDs Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 01/41] scsi: add 'nr_reserved_cmds' field to the SCSI host template Hannes Reinecke
2020-04-30 14:15 ` John Garry
2020-04-30 14:48 ` Hannes Reinecke
2020-05-01 4:36 ` Bart Van Assche
2020-05-01 17:48 ` Christoph Hellwig
2020-05-04 6:13 ` Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 02/41] scsi: add scsi_{get,put}_reserved_cmd() Hannes Reinecke
2020-04-30 17:11 ` Douglas Gilbert
2020-05-01 15:42 ` Hannes Reinecke
2020-05-01 4:35 ` Bart Van Assche
2020-05-01 12:01 ` John Garry
2020-05-02 12:24 ` Hannes Reinecke
2020-05-01 17:39 ` Christoph Hellwig
2020-05-02 8:45 ` Hannes Reinecke
2020-05-02 8:48 ` Christoph Hellwig
2020-04-30 13:18 ` [PATCH RFC v3 03/41] scsi: Implement scsi_cmd_is_reserved() Hannes Reinecke
2020-05-01 4:38 ` Bart Van Assche
2020-05-01 17:43 ` Christoph Hellwig
2020-05-02 8:46 ` Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 04/41] csiostor: use reserved command for LUN reset Hannes Reinecke
2020-04-30 15:15 ` Ming Lei
2020-05-01 13:01 ` Hannes Reinecke
2020-05-01 15:01 ` Ming Lei
2020-05-01 17:45 ` Christoph Hellwig
2020-05-02 3:11 ` Ming Lei
2020-05-04 6:43 ` Hannes Reinecke
2020-05-02 8:49 ` Hannes Reinecke
2020-05-02 14:29 ` Ming Lei
2020-05-04 6:55 ` Hannes Reinecke
2020-05-04 8:47 ` Ming Lei
2020-05-04 10:24 ` Hannes Reinecke
2020-05-04 10:49 ` Ming Lei
2020-05-02 16:10 ` Bart Van Assche
2020-05-04 7:02 ` Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 05/41] scsi: add scsi_cmd_from_priv() Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 06/41] virtio_scsi: use reserved commands for TMF Hannes Reinecke
2020-04-30 15:17 ` Ming Lei
2020-05-04 9:25 ` Ming Lei
2020-05-04 10:21 ` Hannes Reinecke
2020-05-04 10:35 ` Ming Lei
2020-04-30 13:18 ` [PATCH RFC v3 07/41] fnic: use reserved commands Hannes Reinecke
2020-04-30 15:24 ` Ming Lei
2020-04-30 13:18 ` [PATCH RFC v3 08/41] fnic: use scsi_host_busy_iter() to traverse commands Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 09/41] scsi: use real inquiry data when initialising devices Hannes Reinecke
2020-05-01 17:49 ` Christoph Hellwig
2020-05-04 6:26 ` Hannes Reinecke
2020-04-30 13:18 ` Hannes Reinecke [this message]
2020-05-01 4:49 ` [PATCH RFC v3 10/41] scsi: make host device a first-class citizen Bart Van Assche
2020-04-30 13:18 ` [PATCH RFC v3 11/41] hpsa: move hpsa_hba_inquiry after scsi_add_host() Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 12/41] hpsa: use reserved commands Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 13/41] hpsa: use scsi_host_busy_iter() to traverse outstanding commands Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 14/41] hpsa: drop refcount field from CommandList Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 15/41] aacraid: use private commands Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 16/41] aacraid: use scsi_host_busy_iter() to traverse commands Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 17/41] megaraid_sas: kill this_id and init_id Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 18/41] megaraid_sas: use shost_priv() Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 19/41] megaraid_sas: avoid using megaraid_lookup_instance() Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 20/41] megaraid_sas: separate out megasas_set_max_sectors() Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 21/41] megaraid_sas: megaraid_sas: reshuffle SCSI host allocation Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 22/41] block: implement persistent commands Hannes Reinecke
2020-05-01 4:59 ` Bart Van Assche
2020-05-02 12:11 ` Hannes Reinecke
2020-05-02 16:22 ` Bart Van Assche
2020-05-01 8:33 ` Ming Lei
2020-05-02 12:22 ` Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 23/41] scsi: add a 'persistent' argument to scsi_get_reserved_cmd() Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 24/41] megaraid_sas: separate out megasas_prepare_aen() Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 25/41] megaraid_sas: use reserved commands Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 26/41] megaraid_sas_fusion: rearrange mfi and mpt frame pools Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 27/41] megaraid_sas_fusion: sanitize command lookup Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 28/41] megaraid_sas: use scsi_host_busy_iter to traverse outstanding commands Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 29/41] snic: use reserved commands Hannes Reinecke
2020-05-02 3:19 ` Ming Lei
2020-05-04 6:45 ` Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 30/41] snic: use tagset iter for traversing commands Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 31/41] mv_sas: kill mvsas_debug_issue_ssp_tmf() Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 32/41] pm8001: kill pm8001_issue_ssp_tmf() Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 33/41] pm8001: kill 'dev' argument from pm8001_exec_internal_task_abort() Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 34/41] pm8001: use libsas-provided domain devices for SATA Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 35/41] libsas: add SCSI target pointer to struct domain_device Hannes Reinecke
2020-04-30 13:18 ` [PATCH RFC v3 36/41] scsi: libsas,hisi_sas,mvsas,pm8001: Allocate Scsi_cmd for slow task Hannes Reinecke
2020-05-01 10:53 ` John Garry
2020-05-02 16:34 ` [PATCH RFC v3 36/41] scsi: libsas, hisi_sas, mvsas, pm8001: " kbuild test robot
2020-05-05 4:18 ` kbuild test robot
2020-04-30 13:19 ` [PATCH RFC v3 37/41] libsas: add tag to struct sas_task Hannes Reinecke
2020-05-01 10:26 ` John Garry
2020-05-02 12:42 ` Hannes Reinecke
2020-05-04 7:49 ` John Garry
2020-05-04 8:00 ` Hannes Reinecke
2020-05-05 8:38 ` John Garry
2020-04-30 13:19 ` [PATCH RFC v3 38/41] scsi: hisi_sas: Use libsas slow task SCSI command Hannes Reinecke
2020-04-30 13:19 ` [PATCH RFC v3 39/41] hisi_sas: use task tag to reference the slot Hannes Reinecke
2020-04-30 13:19 ` [PATCH RFC v3 40/41] mv_sas: use reserved tags and drop private tag allocation Hannes Reinecke
2020-04-30 13:19 ` [PATCH RFC v3 41/41] pm8001: use block-layer tags for ccb allocation Hannes Reinecke
2020-05-01 10:47 ` John Garry
2020-05-01 12:01 ` [PATCH RFC v3 00/41] scsi: enable reserved commands for LLDDs John Garry
2020-05-02 12:23 ` Hannes Reinecke
2020-05-01 17:46 ` Christoph Hellwig
2020-05-04 6:16 ` Hannes Reinecke
2020-06-05 15:32 ` Don.Brace
2020-06-05 16:50 ` Hannes Reinecke
2020-06-05 17:01 ` Don.Brace
2020-06-08 21:56 ` Don.Brace
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200430131904.5847-11-hare@suse.de \
--to=hare@suse.de \
--cc=bvanassche@acm.org \
--cc=hch@lst.de \
--cc=james.bottomley@hansenpartnership.com \
--cc=john.garry@huawei.com \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
--cc=ming.lei@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.