diff mbox

[RFC,v9,02/27] virtio-blk: Set up host notifier for data plane

Message ID 1342624074-24650-3-git-send-email-stefanha@linux.vnet.ibm.com (mailing list archive)
State New, archived
Headers show

Commit Message

Stefan Hajnoczi July 18, 2012, 3:07 p.m. UTC
Set up the virtqueue notify ioeventfd that the data plane will monitor.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 hw/virtio-blk.c |   37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)
diff mbox

Patch

diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index a627427..0389294 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -26,6 +26,8 @@  typedef struct VirtIOBlock
     char *serial;
     unsigned short sector_mask;
     DeviceState *qdev;
+
+    bool data_plane_started;
 } VirtIOBlock;
 
 static VirtIOBlock *to_virtio_blk(VirtIODevice *vdev)
@@ -33,6 +35,39 @@  static VirtIOBlock *to_virtio_blk(VirtIODevice *vdev)
     return (VirtIOBlock *)vdev;
 }
 
+static void virtio_blk_data_plane_start(VirtIOBlock *s)
+{
+    if (s->vdev.binding->set_host_notifier(s->vdev.binding_opaque, 0, true) != 0) {
+        fprintf(stderr, "virtio-blk failed to set host notifier\n");
+        return;
+    }
+
+    s->data_plane_started = true;
+}
+
+static void virtio_blk_data_plane_stop(VirtIOBlock *s)
+{
+    s->data_plane_started = false;
+
+    s->vdev.binding->set_host_notifier(s->vdev.binding_opaque, 0, false);
+}
+
+static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t val)
+{
+    VirtIOBlock *s = to_virtio_blk(vdev);
+
+    /* Toggle host notifier only on status change */
+    if (s->data_plane_started == !!(val & VIRTIO_CONFIG_S_DRIVER_OK)) {
+        return;
+    }
+
+    if (val & VIRTIO_CONFIG_S_DRIVER_OK) {
+        virtio_blk_data_plane_start(s);
+    } else {
+        virtio_blk_data_plane_stop(s);
+    }
+}
+
 static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
 {
     fprintf(stderr, "virtio_blk_handle_output: should never get here,"
@@ -115,6 +150,7 @@  VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf,
 
     s->vdev.get_config = virtio_blk_update_config;
     s->vdev.get_features = virtio_blk_get_features;
+    s->vdev.set_status = virtio_blk_set_status;
     s->bs = conf->bs;
     s->conf = conf;
     s->serial = *serial;
@@ -122,6 +158,7 @@  VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf,
     bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);
 
     s->vq = virtio_add_queue(&s->vdev, 128, virtio_blk_handle_output);
+    s->data_plane_started = false;
 
     s->qdev = dev;
     bdrv_set_buffer_alignment(s->bs, conf->logical_block_size);