qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/3] scsi: Implement hotplug support for virtio-scsi
@ 2012-07-02  9:28 Paolo Bonzini
  2012-07-02  9:28 ` [Qemu-devel] [PATCH 1/3] scsi: introduce hotplug() and hot_unplug() interfaces for SCSI bus Paolo Bonzini
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Paolo Bonzini @ 2012-07-02  9:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: mc

Here are Cong Meng's patches, rebased and including support for
missed events.

I'm keeping them out of the next pull request, waiting for test results
from Cong Meng with any updated kernel patches he might have.  Cong,
they are on top of the scsi-next branch on github.

Cong Meng (2):
  scsi: introduce hotplug() and hot_unplug() interfaces for SCSI bus
  virtio-scsi: Implement hotplug support for virtio-scsi

Paolo Bonzini (1):
  virtio-scsi: Report missed events

 hw/scsi-bus.c    |   17 +++++++++-
 hw/scsi.h        |    2 ++
 hw/virtio-scsi.c |   92 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 107 insertions(+), 4 deletions(-)

-- 
1.7.10.2

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Qemu-devel] [PATCH 1/3] scsi: introduce hotplug() and hot_unplug() interfaces for SCSI bus
  2012-07-02  9:28 [Qemu-devel] [PATCH 0/3] scsi: Implement hotplug support for virtio-scsi Paolo Bonzini
@ 2012-07-02  9:28 ` Paolo Bonzini
  2012-07-02  9:28 ` [Qemu-devel] [PATCH 2/3] virtio-scsi: Implement hotplug support for virtio-scsi Paolo Bonzini
  2012-07-02  9:28 ` [Qemu-devel] [PATCH 3/3] virtio-scsi: Report missed events Paolo Bonzini
  2 siblings, 0 replies; 4+ messages in thread
From: Paolo Bonzini @ 2012-07-02  9:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: mc, Sen Wang

From: Cong Meng <mc@linux.vnet.ibm.com>

Add two interfaces hotplug() and hot_unplug() to scsi bus info.
The scsi bus can implement these two interfaces to signal the HBA driver
of guest kernel to add/remove the scsi device in question.

Signed-off-by: Sen Wang <senwang@linux.vnet.ibm.com>
Signed-off-by: Cong Meng <mc@linux.vnet.ibm.com>
[ Fixed braces and indentation - Paolo ]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/scsi-bus.c |   17 ++++++++++++++++-
 hw/scsi.h     |    2 ++
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 14e2f73..a5a5982 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -186,6 +186,10 @@ static int scsi_qdev_init(DeviceState *qdev)
                                                          dev);
     }
 
+    if (bus->info->hotplug) {
+        bus->info->hotplug(bus, dev);
+    }
+
 err:
     return rc;
 }
@@ -1571,6 +1575,17 @@ static int get_scsi_requests(QEMUFile *f, void *pv, size_t size)
     return 0;
 }
 
+static int scsi_qdev_unplug(DeviceState *qdev)
+{
+    SCSIDevice *dev = SCSI_DEVICE(qdev);
+    SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
+
+    if (bus->info->hot_unplug) {
+        bus->info->hot_unplug(bus, dev);
+    }
+    return qdev_simple_unplug_cb(qdev);
+}
+
 static const VMStateInfo vmstate_info_scsi_requests = {
     .name = "scsi-requests",
     .get  = get_scsi_requests,
@@ -1607,7 +1622,7 @@ static void scsi_device_class_init(ObjectClass *klass, void *data)
     DeviceClass *k = DEVICE_CLASS(klass);
     k->bus_type = TYPE_SCSI_BUS;
     k->init     = scsi_qdev_init;
-    k->unplug   = qdev_simple_unplug_cb;
+    k->unplug   = scsi_qdev_unplug;
     k->exit     = scsi_qdev_exit;
     k->props    = scsi_props;
 }
diff --git a/hw/scsi.h b/hw/scsi.h
index 76f06d4..dd1cd45 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -130,6 +130,8 @@ struct SCSIBusInfo {
     void (*transfer_data)(SCSIRequest *req, uint32_t arg);
     void (*complete)(SCSIRequest *req, uint32_t arg, size_t resid);
     void (*cancel)(SCSIRequest *req);
+    void (*hotplug)(SCSIBus *bus, SCSIDevice *dev);
+    void (*hot_unplug)(SCSIBus *bus, SCSIDevice *dev);
     QEMUSGList *(*get_sg_list)(SCSIRequest *req);
 
     void (*save_request)(QEMUFile *f, SCSIRequest *req);
-- 
1.7.10.2

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [Qemu-devel] [PATCH 2/3] virtio-scsi: Implement hotplug support for virtio-scsi
  2012-07-02  9:28 [Qemu-devel] [PATCH 0/3] scsi: Implement hotplug support for virtio-scsi Paolo Bonzini
  2012-07-02  9:28 ` [Qemu-devel] [PATCH 1/3] scsi: introduce hotplug() and hot_unplug() interfaces for SCSI bus Paolo Bonzini
@ 2012-07-02  9:28 ` Paolo Bonzini
  2012-07-02  9:28 ` [Qemu-devel] [PATCH 3/3] virtio-scsi: Report missed events Paolo Bonzini
  2 siblings, 0 replies; 4+ messages in thread
From: Paolo Bonzini @ 2012-07-02  9:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: mc, Sen Wang

From: Cong Meng <mc@linux.vnet.ibm.com>

Implement the hotplug() and hot_unplug() interfaces in virtio-scsi, by signal
the virtio_scsi.ko in guest kernel via event virtual queue.

The counterpart patch of virtio_scsi.ko will be sent soon in another thread.

Signed-off-by: Sen Wang <senwang@linux.vnet.ibm.com>
Signed-off-by: Cong Meng <mc@linux.vnet.ibm.com>
[ Add memset, fix LUN field, placate checkpatch - Paolo ]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/virtio-scsi.c |   68 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 66 insertions(+), 2 deletions(-)

diff --git a/hw/virtio-scsi.c b/hw/virtio-scsi.c
index 0a5ac40..29d5a66 100644
--- a/hw/virtio-scsi.c
+++ b/hw/virtio-scsi.c
@@ -24,6 +24,10 @@
 #define VIRTIO_SCSI_MAX_TARGET  255
 #define VIRTIO_SCSI_MAX_LUN     16383
 
+/* Feature Bits */
+#define VIRTIO_SCSI_F_INOUT                    0
+#define VIRTIO_SCSI_F_HOTPLUG                  1
+
 /* Response codes */
 #define VIRTIO_SCSI_S_OK                       0
 #define VIRTIO_SCSI_S_OVERRUN                  1
@@ -60,6 +64,11 @@
 #define VIRTIO_SCSI_T_TRANSPORT_RESET          1
 #define VIRTIO_SCSI_T_ASYNC_NOTIFY             2
 
+/* Reasons for transport reset event */
+#define VIRTIO_SCSI_EVT_RESET_HARD             0
+#define VIRTIO_SCSI_EVT_RESET_RESCAN           1
+#define VIRTIO_SCSI_EVT_RESET_REMOVED          2
+
 /* SCSI command request, followed by data-out */
 typedef struct {
     uint8_t lun[8];              /* Logical Unit Number */
@@ -206,11 +215,13 @@ static void qemu_sgl_init_external(QEMUSGList *qsgl, struct iovec *sg,
 static void virtio_scsi_parse_req(VirtIOSCSI *s, VirtQueue *vq,
                                   VirtIOSCSIReq *req)
 {
-    assert(req->elem.out_num && req->elem.in_num);
+    assert(req->elem.in_num);
     req->vq = vq;
     req->dev = s;
     req->sreq = NULL;
-    req->req.buf = req->elem.out_sg[0].iov_base;
+    if (req->elem.out_num) {
+        req->req.buf = req->elem.out_sg[0].iov_base;
+    }
     req->resp.buf = req->elem.in_sg[0].iov_base;
 
     if (req->elem.out_num > 1) {
@@ -545,6 +556,7 @@ static void virtio_scsi_set_config(VirtIODevice *vdev,
 static uint32_t virtio_scsi_get_features(VirtIODevice *vdev,
                                          uint32_t requested_features)
 {
+    requested_features |= (1UL << VIRTIO_SCSI_F_HOTPLUG);
     return requested_features;
 }
 
@@ -577,6 +589,56 @@ static int virtio_scsi_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
+static void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
+                                   uint32_t event, uint32_t reason)
+{
+    VirtIOSCSIReq *req = virtio_scsi_pop_req(s, s->event_vq);
+    VirtIOSCSIEvent *evt;
+
+    if (req) {
+        int in_size;
+        if (req->elem.out_num || req->elem.in_num != 1) {
+            virtio_scsi_bad_req();
+        }
+
+        in_size = req->elem.in_sg[0].iov_len;
+        if (in_size < sizeof(VirtIOSCSIEvent)) {
+            virtio_scsi_bad_req();
+        }
+
+        evt = req->resp.event;
+        memset(evt, 0, sizeof(VirtIOSCSIEvent));
+        evt->event = event;
+        evt->reason = reason;
+        evt->lun[0] = 1;
+        evt->lun[1] = dev->id;
+        evt->lun[2] = (dev->lun >> 8) | 0x40;
+        evt->lun[3] = dev->lun & 0xFF;
+        virtio_scsi_complete_req(req);
+    }
+}
+
+static void virtio_scsi_hotplug(SCSIBus *bus, SCSIDevice *dev)
+{
+    VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
+
+    if (((s->vdev.guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) &&
+        (s->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK)) {
+        virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_TRANSPORT_RESET,
+                               VIRTIO_SCSI_EVT_RESET_RESCAN);
+    }
+}
+
+static void virtio_scsi_hot_unplug(SCSIBus *bus, SCSIDevice *dev)
+{
+    VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
+
+    if ((s->vdev.guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
+        virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_TRANSPORT_RESET,
+                               VIRTIO_SCSI_EVT_RESET_REMOVED);
+    }
+}
+
 static struct SCSIBusInfo virtio_scsi_scsi_info = {
     .tcq = true,
     .max_channel = VIRTIO_SCSI_MAX_CHANNEL,
@@ -585,6 +647,8 @@ static struct SCSIBusInfo virtio_scsi_scsi_info = {
 
     .complete = virtio_scsi_command_complete,
     .cancel = virtio_scsi_request_cancelled,
+    .hotplug = virtio_scsi_hotplug,
+    .hot_unplug = virtio_scsi_hot_unplug,
     .get_sg_list = virtio_scsi_get_sg_list,
     .save_request = virtio_scsi_save_request,
     .load_request = virtio_scsi_load_request,
-- 
1.7.10.2

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [Qemu-devel] [PATCH 3/3] virtio-scsi: Report missed events
  2012-07-02  9:28 [Qemu-devel] [PATCH 0/3] scsi: Implement hotplug support for virtio-scsi Paolo Bonzini
  2012-07-02  9:28 ` [Qemu-devel] [PATCH 1/3] scsi: introduce hotplug() and hot_unplug() interfaces for SCSI bus Paolo Bonzini
  2012-07-02  9:28 ` [Qemu-devel] [PATCH 2/3] virtio-scsi: Implement hotplug support for virtio-scsi Paolo Bonzini
@ 2012-07-02  9:28 ` Paolo Bonzini
  2 siblings, 0 replies; 4+ messages in thread
From: Paolo Bonzini @ 2012-07-02  9:28 UTC (permalink / raw)
  To: qemu-devel; +Cc: mc

When an event is reported but no buffers are present in the event vq,
we can set a flag and report a dummy event as soon as one is added.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 hw/virtio-scsi.c |   54 ++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 36 insertions(+), 18 deletions(-)

diff --git a/hw/virtio-scsi.c b/hw/virtio-scsi.c
index 29d5a66..41f10c2 100644
--- a/hw/virtio-scsi.c
+++ b/hw/virtio-scsi.c
@@ -141,6 +141,7 @@ typedef struct {
     uint32_t sense_size;
     uint32_t cdb_size;
     int resetting;
+    bool events_dropped;
     VirtQueue *ctrl_vq;
     VirtQueue *event_vq;
     VirtQueue *cmd_vqs[0];
@@ -416,10 +417,6 @@ static void virtio_scsi_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
     }
 }
 
-static void virtio_scsi_handle_event(VirtIODevice *vdev, VirtQueue *vq)
-{
-}
-
 static void virtio_scsi_command_complete(SCSIRequest *r, uint32_t status,
                                          size_t resid)
 {
@@ -594,27 +591,48 @@ static void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
 {
     VirtIOSCSIReq *req = virtio_scsi_pop_req(s, s->event_vq);
     VirtIOSCSIEvent *evt;
+    int in_size;
 
-    if (req) {
-        int in_size;
-        if (req->elem.out_num || req->elem.in_num != 1) {
-            virtio_scsi_bad_req();
-        }
+    if (!req) {
+        s->events_dropped = true;
+        return;
+    }
 
-        in_size = req->elem.in_sg[0].iov_len;
-        if (in_size < sizeof(VirtIOSCSIEvent)) {
-            virtio_scsi_bad_req();
-        }
+    if (req->elem.out_num || req->elem.in_num != 1) {
+        virtio_scsi_bad_req();
+    }
 
-        evt = req->resp.event;
-        memset(evt, 0, sizeof(VirtIOSCSIEvent));
-        evt->event = event;
-        evt->reason = reason;
+    if (s->events_dropped) {
+        event |= VIRTIO_SCSI_T_EVENTS_MISSED;
+        s->events_dropped = false;
+    }
+
+    in_size = req->elem.in_sg[0].iov_len;
+    if (in_size < sizeof(VirtIOSCSIEvent)) {
+        virtio_scsi_bad_req();
+    }
+
+    evt = req->resp.event;
+    memset(evt, 0, sizeof(VirtIOSCSIEvent));
+    evt->event = event;
+    evt->reason = reason;
+    if (!dev) {
+        assert(event == VIRTIO_SCSI_T_NO_EVENT);
+    } else {
         evt->lun[0] = 1;
         evt->lun[1] = dev->id;
         evt->lun[2] = (dev->lun >> 8) | 0x40;
         evt->lun[3] = dev->lun & 0xFF;
-        virtio_scsi_complete_req(req);
+    }
+    virtio_scsi_complete_req(req);
+}
+
+static void virtio_scsi_handle_event(VirtIODevice *vdev, VirtQueue *vq)
+{
+    VirtIOSCSI *s = (VirtIOSCSI *)vdev;
+
+    if (s->events_dropped) {
+        virtio_scsi_push_event(s, NULL, VIRTIO_SCSI_T_NO_EVENT, 0);
     }
 }
 
-- 
1.7.10.2

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2012-07-02  9:28 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-07-02  9:28 [Qemu-devel] [PATCH 0/3] scsi: Implement hotplug support for virtio-scsi Paolo Bonzini
2012-07-02  9:28 ` [Qemu-devel] [PATCH 1/3] scsi: introduce hotplug() and hot_unplug() interfaces for SCSI bus Paolo Bonzini
2012-07-02  9:28 ` [Qemu-devel] [PATCH 2/3] virtio-scsi: Implement hotplug support for virtio-scsi Paolo Bonzini
2012-07-02  9:28 ` [Qemu-devel] [PATCH 3/3] virtio-scsi: Report missed events Paolo Bonzini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).