All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hannes Reinecke <hare@suse.de>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: qemu-devel@nongnu.org, Hannes Reinecke <hare@suse.de>,
	Hannes Reinecke <hare@suse.com>
Subject: [Qemu-devel] [PATCH 2/4] virtio-scsi: implement target rescan
Date: Thu, 14 Dec 2017 11:14:33 +0100	[thread overview]
Message-ID: <20171214101435.26265-3-hare@suse.de> (raw)
In-Reply-To: <20171214101435.26265-1-hare@suse.de>

Implement a new virtio-scsi command 'rescan' to return a list of
attached targets. The guest is required to set the 'next_id' field
to the next expected target id; the host will return either that
or the next higher target id (if present), or -1 if no additional
targets are found.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 hw/scsi/scsi-bus.c                           | 10 +++++
 hw/scsi/scsi-disk.c                          | 16 +++++++-
 hw/scsi/virtio-scsi.c                        | 55 ++++++++++++++++++++++++++++
 include/hw/scsi/scsi.h                       |  6 ++-
 include/hw/virtio/virtio-scsi.h              |  7 +++-
 include/scsi/constants.h                     | 11 ++++++
 include/standard-headers/linux/virtio_scsi.h | 15 ++++++++
 7 files changed, 115 insertions(+), 5 deletions(-)

diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index a0e66d0e01..83497ac916 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -21,6 +21,7 @@ static Property scsi_props[] = {
     DEFINE_PROP_UINT32("channel", SCSIDevice, channel, 0),
     DEFINE_PROP_UINT32("scsi-id", SCSIDevice, id, -1),
     DEFINE_PROP_UINT64("lun", SCSIDevice, lun, -1),
+    DEFINE_PROP_UINT8("protocol", SCSIDevice, protocol, SCSI_PROTOCOL_SAS),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -189,6 +190,15 @@ static void scsi_qdev_realize(DeviceState *qdev, Error **errp)
         }
     }
 
+    if (dev->protocol != SCSI_PROTOCOL_FCP &&
+        dev->protocol != SCSI_PROTOCOL_SPI &&
+        dev->protocol != SCSI_PROTOCOL_SRP &&
+        dev->protocol != SCSI_PROTOCOL_ISCSI &&
+        dev->protocol != SCSI_PROTOCOL_SAS &&
+        dev->protocol != SCSI_PROTOCOL_UAS) {
+        error_setg(errp, "invalid scsi protocol id: %d", dev->protocol);
+        return;
+    }
     if (dev->id == -1) {
         int id = -1;
         if (dev->lun == -1) {
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index cbee840601..1313aafae3 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -668,7 +668,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
             }
 
             if (s->qdev.port_wwn) {
-                outbuf[buflen++] = 0x61; // SAS / Binary
+                outbuf[buflen++] = s->qdev.protocol << 8 | 0x1; // Binary
                 outbuf[buflen++] = 0x93; // PIV / Target port / NAA
                 outbuf[buflen++] = 0;    // reserved
                 outbuf[buflen++] = 8;
@@ -677,7 +677,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
             }
 
             if (s->port_index) {
-                outbuf[buflen++] = 0x61; // SAS / Binary
+                outbuf[buflen++] = s->qdev.protocol << 8 | 0x1; // Binary
                 outbuf[buflen++] = 0x94; // PIV / Target port / relative target port
                 outbuf[buflen++] = 0;    // reserved
                 outbuf[buflen++] = 4;
@@ -2355,6 +2355,18 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
         return;
     }
 
+    if (dev->protocol == SCSI_PROTOCOL_FCP) {
+        if (!s->qdev.port_wwn) {
+            error_setg(errp,
+                       "Missing port_wwn for FCP protocol");
+            return;
+        }
+        if (!s->qdev.node_wwn && (s->qdev.port_wwn >> 60) != 0x02) {
+            error_setg(errp,
+                       "port_wwn is not a IEEE Extended identifier");
+            return;
+        }
+    }
     if (dev->type == TYPE_DISK) {
         blkconf_geometry(&dev->conf, NULL, 65535, 255, 255, &err);
         if (err) {
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index f98bfb3db5..fa2031f636 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -19,6 +19,7 @@
 #include "hw/virtio/virtio-scsi.h"
 #include "qemu/error-report.h"
 #include "qemu/iov.h"
+#include "qemu/cutils.h"
 #include "sysemu/block-backend.h"
 #include "hw/scsi/scsi.h"
 #include "scsi/constants.h"
@@ -386,6 +387,7 @@ fail:
 static void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req)
 {
     VirtIODevice *vdev = (VirtIODevice *)s;
+    VirtIOSCSICommon *c = VIRTIO_SCSI_COMMON(vdev);
     uint32_t type;
     int r = 0;
 
@@ -415,6 +417,55 @@ static void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req)
             req->resp.an.event_actual = 0;
             req->resp.an.response = VIRTIO_SCSI_S_OK;
         }
+    } else if (type == VIRTIO_SCSI_T_RESCAN) {
+        if (virtio_scsi_parse_req(req, sizeof(VirtIOSCSIRescanReq),
+                                  sizeof(VirtIOSCSIRescanResp)) < 0) {
+            virtio_scsi_bad_req(req);
+            return;
+        } else {
+            BusChild *kid;
+            SCSIDevice *dev = NULL;
+
+            if (req->req.rescan.next_id != -1) {
+                QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {
+                    DeviceState *qdev = kid->child;
+                    SCSIDevice *d = SCSI_DEVICE(qdev);
+
+                    if (d->id >= req->req.rescan.next_id) {
+                        dev = d;
+                        break;
+                    }
+                }
+            }
+            if (dev) {
+                req->resp.rescan.id = dev->id;
+                req->resp.rescan.transport = dev->protocol;
+                if (dev->protocol == SCSI_PROTOCOL_FCP &&
+                    dev->port_wwn && !dev->node_wwn) {
+                    dev->node_wwn = ((uint64_t)1 << 56) |
+                        (dev->port_wwn & ~((uint64_t)0xff << 56));
+                }
+                stq_be_p(req->resp.rescan.node_wwn, dev->node_wwn);
+                stq_be_p(req->resp.rescan.port_wwn, dev->port_wwn);
+            } else {
+                req->resp.rescan.id = -1;
+                if (c->conf.wwnn && c->conf.wwpn) {
+                    req->resp.rescan.transport = SCSI_PROTOCOL_FCP;
+                } else {
+                    req->resp.rescan.transport = SCSI_PROTOCOL_SAS;
+                }
+                if (c->conf.wwnn) {
+                    uint64_t wwnn;
+                    qemu_strtou64(c->conf.wwnn, NULL, 16, &wwnn);
+                    stq_be_p(req->resp.rescan.node_wwn, wwnn);
+                }
+                if (c->conf.wwpn) {
+                    uint64_t wwpn;
+                    qemu_strtou64(c->conf.wwpn, NULL, 16, &wwpn);
+                    stq_be_p(req->resp.rescan.port_wwn, wwpn);
+                }
+            }
+        }
     }
     if (r == 0) {
         virtio_scsi_complete_req(req);
@@ -927,8 +978,12 @@ static Property virtio_scsi_properties[] = {
                                            VIRTIO_SCSI_F_HOTPLUG, true),
     DEFINE_PROP_BIT("param_change", VirtIOSCSI, host_features,
                                                 VIRTIO_SCSI_F_CHANGE, true),
+    DEFINE_PROP_BIT("rescan", VirtIOSCSI, host_features,
+                                          VIRTIO_SCSI_F_RESCAN, true),
     DEFINE_PROP_LINK("iothread", VirtIOSCSI, parent_obj.conf.iothread,
                      TYPE_IOTHREAD, IOThread *),
+    DEFINE_PROP_STRING("wwpn", VirtIOSCSI, parent_obj.conf.wwpn),
+    DEFINE_PROP_STRING("wwnn", VirtIOSCSI, parent_obj.conf.wwnn),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
index f1b4a759de..cb2b2bddcd 100644
--- a/include/hw/scsi/scsi.h
+++ b/include/hw/scsi/scsi.h
@@ -71,19 +71,21 @@ struct SCSIDevice
     DeviceState qdev;
     VMChangeStateEntry *vmsentry;
     QEMUBH *bh;
-    uint32_t id;
     BlockConf conf;
     SCSISense unit_attention;
     bool sense_is_ua;
     uint8_t sense[SCSI_SENSE_BUF_SIZE];
     uint32_t sense_len;
     QTAILQ_HEAD(, SCSIRequest) requests;
+    uint32_t id;
     uint32_t channel;
     uint64_t lun;
     int blocksize;
-    int type;
+    uint8_t type;
+    uint8_t protocol;
     uint64_t max_lba;
     uint64_t wwn;
+    uint64_t node_wwn;
     uint64_t port_wwn;
 };
 
diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h
index 4c0bcdb788..2503680d0c 100644
--- a/include/hw/virtio/virtio-scsi.h
+++ b/include/hw/virtio/virtio-scsi.h
@@ -42,6 +42,8 @@ typedef struct virtio_scsi_ctrl_tmf_req VirtIOSCSICtrlTMFReq;
 typedef struct virtio_scsi_ctrl_tmf_resp VirtIOSCSICtrlTMFResp;
 typedef struct virtio_scsi_ctrl_an_req VirtIOSCSICtrlANReq;
 typedef struct virtio_scsi_ctrl_an_resp VirtIOSCSICtrlANResp;
+typedef struct virtio_scsi_rescan_req VirtIOSCSIRescanReq;
+typedef struct virtio_scsi_rescan_resp VirtIOSCSIRescanResp;
 typedef struct virtio_scsi_event VirtIOSCSIEvent;
 typedef struct virtio_scsi_config VirtIOSCSIConfig;
 
@@ -52,8 +54,9 @@ struct VirtIOSCSIConf {
     uint32_t cmd_per_lun;
 #ifdef CONFIG_VHOST_SCSI
     char *vhostfd;
-    char *wwpn;
 #endif
+    char *wwpn;
+    char *wwnn;
     CharBackend chardev;
     uint32_t boot_tpgt;
     IOThread *iothread;
@@ -116,12 +119,14 @@ typedef struct VirtIOSCSIReq {
         VirtIOSCSICmdResp     cmd;
         VirtIOSCSICtrlTMFResp tmf;
         VirtIOSCSICtrlANResp  an;
+        VirtIOSCSIRescanResp  rescan;
         VirtIOSCSIEvent       event;
     } resp;
     union {
         VirtIOSCSICmdReq      cmd;
         VirtIOSCSICtrlTMFReq  tmf;
         VirtIOSCSICtrlANReq   an;
+        VirtIOSCSIRescanReq   rescan;
     } req;
 } VirtIOSCSIReq;
 
diff --git a/include/scsi/constants.h b/include/scsi/constants.h
index a141dd71f8..ee93727052 100644
--- a/include/scsi/constants.h
+++ b/include/scsi/constants.h
@@ -223,6 +223,17 @@
 #define TYPE_INACTIVE       0x20
 #define TYPE_NO_LUN         0x7f
 
+/*
+ * Protocol identifiers
+ */
+
+#define SCSI_PROTOCOL_FCP    0x00
+#define SCSI_PROTOCOL_SPI    0x01
+#define SCSI_PROTOCOL_SRP    0x04
+#define SCSI_PROTOCOL_ISCSI  0x05
+#define SCSI_PROTOCOL_SAS    0x06
+#define SCSI_PROTOCOL_UAS    0x09
+#define SCSI_PROTOCOL_UNSPEC 0x0f
 /* Mode page codes for mode sense/set */
 #define MODE_PAGE_R_W_ERROR                   0x01
 #define MODE_PAGE_HD_GEOMETRY                 0x04
diff --git a/include/standard-headers/linux/virtio_scsi.h b/include/standard-headers/linux/virtio_scsi.h
index ab66166b6a..5b3a930569 100644
--- a/include/standard-headers/linux/virtio_scsi.h
+++ b/include/standard-headers/linux/virtio_scsi.h
@@ -96,6 +96,19 @@ struct virtio_scsi_ctrl_an_resp {
 	uint8_t response;
 } QEMU_PACKED;
 
+/* Target rescan */
+struct virtio_scsi_rescan_req {
+	__virtio32 type;
+	__virtio32 next_id;
+} QEMU_PACKED;
+
+struct virtio_scsi_rescan_resp {
+	__virtio32 id;
+	__virtio32 transport;
+	uint8_t node_wwn[8];
+	uint8_t port_wwn[8];
+} QEMU_PACKED;
+
 struct virtio_scsi_event {
 	__virtio32 event;
 	uint8_t lun[8];
@@ -120,6 +133,7 @@ struct virtio_scsi_config {
 #define VIRTIO_SCSI_F_HOTPLUG                  1
 #define VIRTIO_SCSI_F_CHANGE                   2
 #define VIRTIO_SCSI_F_T10_PI                   3
+#define VIRTIO_SCSI_F_RESCAN                   4
 
 /* Response codes */
 #define VIRTIO_SCSI_S_OK                       0
@@ -140,6 +154,7 @@ struct virtio_scsi_config {
 #define VIRTIO_SCSI_T_TMF                      0
 #define VIRTIO_SCSI_T_AN_QUERY                 1
 #define VIRTIO_SCSI_T_AN_SUBSCRIBE             2
+#define VIRTIO_SCSI_T_RESCAN                   3
 
 /* Valid TMF subtypes.  */
 #define VIRTIO_SCSI_T_TMF_ABORT_TASK           0
-- 
2.12.3

  parent reply	other threads:[~2017-12-14 10:15 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-12-14 10:14 [Qemu-devel] [PATCH 0/4] virtio-vfc implementation Hannes Reinecke
2017-12-14 10:14 ` [Qemu-devel] [PATCH 1/4] scsi: use 64-bit LUN Hannes Reinecke
2017-12-14 10:14 ` Hannes Reinecke [this message]
2017-12-14 10:14 ` [Qemu-devel] [PATCH 3/4] virtio-scsi: Implement 'native LUN' feature Hannes Reinecke
2017-12-14 10:14 ` [Qemu-devel] [PATCH 4/4] scsi: support REPORT_LUNS for LUNs != 0 Hannes Reinecke
2017-12-14 10:25 ` [Qemu-devel] [PATCH 0/4] virtio-vfc implementation no-reply
2017-12-14 13:49 ` no-reply
2017-12-14 17:25 ` no-reply

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=20171214101435.26265-3-hare@suse.de \
    --to=hare@suse.de \
    --cc=hare@suse.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /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.