From patchwork Thu Mar 18 07:21:29 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [1/5] virtio: add type safe API Date: Wed, 17 Mar 2010 21:21:29 -0000 From: "Michael S. Tsirkin" X-Patchwork-Id: 48005 Message-Id: <66e86d289a7c8030c713534687f5722f94c2b2b8.1268896694.git.mst@redhat.com> To: quintela@redhat.com, qemu-devel@nongnu.org Cc: This adds VIRTIO_COMMON_INIT which is type-safe and let us get rid of struct layout assumptions. Signed-off-by: Michael S. Tsirkin --- 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(-) 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);