Patchwork [1/5] virtio: add type safe API

login
register
mail settings
Submitter Michael S. Tsirkin
Date March 18, 2010, 7:21 a.m.
Message ID <66e86d289a7c8030c713534687f5722f94c2b2b8.1268896694.git.mst@redhat.com>
Download mbox | patch
Permalink /patch/48005/
State New
Headers show

Comments

Michael S. Tsirkin - March 18, 2010, 7:21 a.m.
This adds VIRTIO_COMMON_INIT which is type-safe
and let us get rid of struct layout assumptions.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/virtio-balloon.c    |    5 ++---
 hw/virtio-blk.c        |    6 +++---
 hw/virtio-net.c        |    6 +++---
 hw/virtio-serial-bus.c |    6 +++---
 hw/virtio.c            |    5 +++--
 hw/virtio.h            |    9 ++++++++-
 6 files changed, 22 insertions(+), 15 deletions(-)

Patch

diff --git a/hw/virtio-balloon.c b/hw/virtio-balloon.c
index 6d12024..5a3be22 100644
--- a/hw/virtio-balloon.c
+++ b/hw/virtio-balloon.c
@@ -281,9 +281,8 @@  VirtIODevice *virtio_balloon_init(DeviceState *dev)
 {
     VirtIOBalloon *s;
 
-    s = (VirtIOBalloon *)virtio_common_init("virtio-balloon",
-                                            VIRTIO_ID_BALLOON,
-                                            8, sizeof(VirtIOBalloon));
+    s = VIRTIO_COMMON_INIT("virtio-balloon", VIRTIO_ID_BALLOON, 8,
+                           VirtIOBalloon, vdev);
 
     s->vdev.get_config = virtio_balloon_get_config;
     s->vdev.set_config = virtio_balloon_set_config;
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index 9915840..b89f1f4 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -482,9 +482,9 @@  VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
     int cylinders, heads, secs;
     static int virtio_blk_id;
 
-    s = (VirtIOBlock *)virtio_common_init("virtio-blk", VIRTIO_ID_BLOCK,
-                                          sizeof(struct virtio_blk_config),
-                                          sizeof(VirtIOBlock));
+    s = VIRTIO_COMMON_INIT("virtio-blk", VIRTIO_ID_BLOCK,
+                           sizeof(struct virtio_blk_config),
+                           VirtIOBlock, vdev);
 
     s->vdev.get_config = virtio_blk_update_config;
     s->vdev.get_features = virtio_blk_get_features;
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index be33c68..5edb354 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -836,9 +836,9 @@  VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf)
     VirtIONet *n;
     static int virtio_net_id;
 
-    n = (VirtIONet *)virtio_common_init("virtio-net", VIRTIO_ID_NET,
-                                        sizeof(struct virtio_net_config),
-                                        sizeof(VirtIONet));
+    n = VIRTIO_COMMON_INIT("virtio-net", VIRTIO_ID_NET,
+                           sizeof(struct virtio_net_config),
+                           VirtIONet, vdev);
 
     n->vdev.get_config = virtio_net_get_config;
     n->vdev.set_config = virtio_net_set_config;
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 17c1ec1..72425f3 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -567,11 +567,11 @@  VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports)
     if (!max_nr_ports)
         return NULL;
 
-    vdev = virtio_common_init("virtio-serial", VIRTIO_ID_CONSOLE,
+    vser = VIRTIO_COMMON_INIT("virtio-serial", VIRTIO_ID_CONSOLE,
                               sizeof(struct virtio_console_config),
-                              sizeof(VirtIOSerial));
+                              VirtIOSerial, vdev);
 
-    vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
+    vdev = &vser->vdev;
 
     /* Spawn a new virtio-serial bus on which the ports will ride as devices */
     vser->bus = virtser_bus_new(dev);
diff --git a/hw/virtio.c b/hw/virtio.c
index 7c020a3..67177b0 100644
--- a/hw/virtio.c
+++ b/hw/virtio.c
@@ -701,12 +701,13 @@  void virtio_cleanup(VirtIODevice *vdev)
 }
 
 VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
-                                 size_t config_size, size_t struct_size)
+                                 size_t config_size, size_t struct_size,
+                                 size_t struct_offset)
 {
     VirtIODevice *vdev;
     int i;
 
-    vdev = qemu_mallocz(struct_size);
+    vdev = qemu_mallocz(struct_size) + struct_offset;
 
     vdev->device_id = device_id;
     vdev->status = 0;
diff --git a/hw/virtio.h b/hw/virtio.h
index 3baa2a3..a736b88 100644
--- a/hw/virtio.h
+++ b/hw/virtio.h
@@ -150,7 +150,14 @@  int virtio_queue_empty(VirtQueue *vq);
 /* Host binding interface.  */
 
 VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
-                                 size_t config_size, size_t struct_size);
+                                 size_t config_size, size_t struct_size,
+				 size_t struct_offset);
+#define VIRTIO_COMMON_INIT(_name, _device_id, _config_size, _type, _field) \
+    container_of(virtio_common_init((_name), (_device_id), (_config_size), \
+                                    sizeof(_type), offsetof(_type, _field) + \
+                                    type_check(VirtIODevice, \
+                                               typeof_field(_type, _field)) \
+                                   ), _type, _field)
 uint32_t virtio_config_readb(VirtIODevice *vdev, uint32_t addr);
 uint32_t virtio_config_readw(VirtIODevice *vdev, uint32_t addr);
 uint32_t virtio_config_readl(VirtIODevice *vdev, uint32_t addr);