VirtioDevice's DeviceClass::exit code cleaning up bus_name is no longer overwritten by virtio-{blk,serial,net,scsi,balloon,rng} and vhost-scsi.
Note: VirtIOSCSI and VHostSCSI now perform some initializations after VirtIOSCSICommon's realize calls virtio_bus_plug_device(), namely creating the SCSIBus and initializing /dev/vhost-scsi respectively. While at it, drop duplicate VIRTIO_DEVICE() casts and avoid qdev. Signed-off-by: Andreas Färber <afaer...@suse.de> --- hw/9pfs/virtio-9p-device.c | 67 ++++++++++++++++-------------- hw/9pfs/virtio-9p.h | 13 ++++++ hw/block/virtio-blk.c | 52 ++++++++++++++--------- hw/char/virtio-serial-bus.c | 49 ++++++++++++++-------- hw/net/virtio-net.c | 48 ++++++++++++--------- hw/scsi/vhost-scsi.c | 59 +++++++++++++++----------- hw/scsi/virtio-scsi.c | 85 ++++++++++++++++++++++++-------------- hw/virtio/virtio-balloon.c | 50 +++++++++++++--------- hw/virtio/virtio-rng.c | 53 ++++++++++++++---------- hw/virtio/virtio.c | 20 ++++----- include/hw/virtio/vhost-scsi.h | 13 ++++++ include/hw/virtio/virtio-balloon.h | 13 ++++++ include/hw/virtio/virtio-blk.h | 13 ++++++ include/hw/virtio/virtio-net.h | 13 ++++++ include/hw/virtio/virtio-rng.h | 13 ++++++ include/hw/virtio/virtio-scsi.h | 29 +++++++++++-- include/hw/virtio/virtio-serial.h | 13 ++++++ include/hw/virtio/virtio.h | 6 ++- 18 files changed, 406 insertions(+), 203 deletions(-) diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c index dc6f4e4..409d315 100644 --- a/hw/9pfs/virtio-9p-device.c +++ b/hw/9pfs/virtio-9p-device.c @@ -41,15 +41,17 @@ static void virtio_9p_get_config(VirtIODevice *vdev, uint8_t *config) g_free(cfg); } -static int virtio_9p_device_init(VirtIODevice *vdev) +static void virtio_9p_device_realize(DeviceState *dev, Error **errp) { - V9fsState *s = VIRTIO_9P(vdev); + VirtIODevice *vdev = VIRTIO_DEVICE(dev); + V9fsState *s = VIRTIO_9P(dev); + V9fsClass *v9c = VIRTIO_9P_GET_CLASS(dev); int i, len; struct stat stat; FsDriverEntry *fse; V9fsPath path; - virtio_init(VIRTIO_DEVICE(s), "virtio-9p", VIRTIO_ID_9P, + virtio_init(vdev, "virtio-9p", VIRTIO_ID_9P, sizeof(struct virtio_9p_config) + MAX_TAG_LEN); /* initialize pdu allocator */ @@ -65,17 +67,17 @@ static int virtio_9p_device_init(VirtIODevice *vdev) if (!fse) { /* We don't have a fsdev identified by fsdev_id */ - fprintf(stderr, "Virtio-9p device couldn't find fsdev with the " - "id = %s\n", - s->fsconf.fsdev_id ? s->fsconf.fsdev_id : "NULL"); - return -1; + error_setg(errp, "Virtio-9p device couldn't find fsdev with the " + "id = %s", + s->fsconf.fsdev_id ? s->fsconf.fsdev_id : "NULL"); + return; } if (!s->fsconf.tag) { /* we haven't specified a mount_tag */ - fprintf(stderr, "fsdev with id %s needs mount_tag arguments\n", - s->fsconf.fsdev_id); - return -1; + error_setg(errp, "fsdev with id %s needs mount_tag arguments", + s->fsconf.fsdev_id); + return; } s->ctx.export_flags = fse->export_flags; @@ -83,9 +85,9 @@ static int virtio_9p_device_init(VirtIODevice *vdev) s->ctx.exops.get_st_gen = NULL; len = strlen(s->fsconf.tag); if (len > MAX_TAG_LEN - 1) { - fprintf(stderr, "mount tag '%s' (%d bytes) is longer than " - "maximum (%d bytes)", s->fsconf.tag, len, MAX_TAG_LEN - 1); - return -1; + error_setg(errp, "mount tag '%s' (%d bytes) is longer than " + "maximum (%d bytes)", s->fsconf.tag, len, MAX_TAG_LEN - 1); + return; } s->tag = strdup(s->fsconf.tag); @@ -97,13 +99,13 @@ static int virtio_9p_device_init(VirtIODevice *vdev) qemu_co_rwlock_init(&s->rename_lock); if (s->ops->init(&s->ctx) < 0) { - fprintf(stderr, "Virtio-9p Failed to initialize fs-driver with id:%s" - " and export path:%s\n", s->fsconf.fsdev_id, s->ctx.fs_root); - return -1; + error_setg(errp, "Virtio-9p Failed to initialize fs-driver with id:%s" + " and export path:%s", s->fsconf.fsdev_id, s->ctx.fs_root); + return; } if (v9fs_init_worker_threads() < 0) { - fprintf(stderr, "worker thread initialization failed\n"); - return -1; + error_setg(errp, "worker thread initialization failed"); + return; } /* @@ -113,20 +115,20 @@ static int virtio_9p_device_init(VirtIODevice *vdev) */ v9fs_path_init(&path); if (s->ops->name_to_path(&s->ctx, NULL, "/", &path) < 0) { - fprintf(stderr, - "error in converting name to path %s", strerror(errno)); - return -1; + error_setg(errp, + "error in converting name to path %s", strerror(errno)); + return; } if (s->ops->lstat(&s->ctx, &path, &stat)) { - fprintf(stderr, "share path %s does not exist\n", fse->path); - return -1; + error_setg(errp, "share path %s does not exist", fse->path); + return; } else if (!S_ISDIR(stat.st_mode)) { - fprintf(stderr, "share path %s is not a directory\n", fse->path); - return -1; + error_setg(errp, "share path %s is not a directory", fse->path); + return; } v9fs_path_free(&path); - return 0; + v9c->parent_realize(dev, errp); } /* virtio-9p device */ @@ -136,12 +138,16 @@ static Property virtio_9p_properties[] = { DEFINE_PROP_END_OF_LIST(), }; -static void virtio_9p_class_init(ObjectClass *klass, void *data) +static void virtio_9p_class_init(ObjectClass *oc, void *data) { - DeviceClass *dc = DEVICE_CLASS(klass); - VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(oc); + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(oc); + V9fsClass *v9c = VIRTIO_9P_CLASS(oc); + + v9c->parent_realize = dc->realize; + dc->realize = virtio_9p_device_realize; + dc->props = virtio_9p_properties; - vdc->init = virtio_9p_device_init; vdc->get_features = virtio_9p_get_features; vdc->get_config = virtio_9p_get_config; } @@ -151,6 +157,7 @@ static const TypeInfo virtio_device_info = { .parent = TYPE_VIRTIO_DEVICE, .instance_size = sizeof(V9fsState), .class_init = virtio_9p_class_init, + .class_size = sizeof(V9fsClass), }; static void virtio_9p_register_types(void) diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h index 1d6eedb..85699a7 100644 --- a/hw/9pfs/virtio-9p.h +++ b/hw/9pfs/virtio-9p.h @@ -227,6 +227,15 @@ typedef struct V9fsState V9fsConf fsconf; } V9fsState; +typedef struct V9fsClass { + /*< private >*/ + VirtioDeviceClass parent_class; + /*< public >*/ + + DeviceRealize parent_realize; +} V9fsClass; + + typedef struct V9fsStatState { V9fsPDU *pdu; size_t offset; @@ -404,6 +413,10 @@ extern int v9fs_name_to_path(V9fsState *s, V9fsPath *dirpath, #define TYPE_VIRTIO_9P "virtio-9p-device" #define VIRTIO_9P(obj) \ OBJECT_CHECK(V9fsState, (obj), TYPE_VIRTIO_9P) +#define VIRTIO_9P_GET_CLASS(obj) \ + OBJECT_GET_CLASS(V9fsClass, (obj), TYPE_VIRTIO_9P) +#define VIRTIO_9P_CLASS(cls) \ + OBJECT_CLASS_CHECK(V9fsClass, (cls), TYPE_VIRTIO_9P) #define DEFINE_VIRTIO_9P_PROPERTIES(_state, _field) \ DEFINE_PROP_STRING("mount_tag", _state, _field.tag), \ diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index 8ea1f03..88e99a6 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -628,10 +628,11 @@ void virtio_blk_set_conf(DeviceState *dev, VirtIOBlkConf *blk) memcpy(&(s->blk), blk, sizeof(struct VirtIOBlkConf)); } -static int virtio_blk_device_init(VirtIODevice *vdev) +static void virtio_blk_device_realize(DeviceState *dev, Error **errp) { - DeviceState *qdev = DEVICE(vdev); + VirtIODevice *vdev = VIRTIO_DEVICE(dev); VirtIOBlock *s = VIRTIO_BLK(vdev); + VirtIOBlockClass *vbc = VIRTIO_BLK_GET_CLASS(dev); VirtIOBlkConf *blk = &(s->blk); #ifdef CONFIG_VIRTIO_BLK_DATA_PLANE Error *err = NULL; @@ -639,17 +640,18 @@ static int virtio_blk_device_init(VirtIODevice *vdev) static int virtio_blk_id; if (!blk->conf.bs) { - error_report("drive property not set"); - return -1; + error_setg(errp, "drive property not set"); + return; } if (!bdrv_is_inserted(blk->conf.bs)) { - error_report("Device needs media, but drive is empty"); - return -1; + error_setg(errp, "Device needs media, but drive is empty"); + return; } blkconf_serial(&blk->conf, &blk->serial); if (blkconf_geometry(&blk->conf, NULL, 65535, 255, 255) < 0) { - return -1; + error_setg(errp, "Error setting geometry"); + return; } virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK, @@ -665,29 +667,31 @@ static int virtio_blk_device_init(VirtIODevice *vdev) #ifdef CONFIG_VIRTIO_BLK_DATA_PLANE virtio_blk_data_plane_create(vdev, blk, &s->dataplane, &err); if (err != NULL) { - error_report("%s", error_get_pretty(err)); - error_free(err); + error_propagate(errp, err); virtio_cleanup(vdev); - return -1; + return; } #endif s->change = qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s); - register_savevm(qdev, "virtio-blk", virtio_blk_id++, 2, + register_savevm(dev, "virtio-blk", virtio_blk_id++, 2, virtio_blk_save, virtio_blk_load, s); bdrv_set_dev_ops(s->bs, &virtio_block_ops, s); bdrv_set_buffer_alignment(s->bs, s->conf->logical_block_size); bdrv_iostatus_enable(s->bs); - add_boot_device_path(s->conf->bootindex, qdev, "/disk@0,0"); - return 0; + add_boot_device_path(s->conf->bootindex, dev, "/disk@0,0"); + + vbc->parent_realize(dev, errp); } -static int virtio_blk_device_exit(DeviceState *dev) +static void virtio_blk_device_unrealize(DeviceState *dev, Error **errp) { VirtIODevice *vdev = VIRTIO_DEVICE(dev); VirtIOBlock *s = VIRTIO_BLK(dev); + VirtIOBlockClass *vbc = VIRTIO_BLK_GET_CLASS(dev); + #ifdef CONFIG_VIRTIO_BLK_DATA_PLANE virtio_blk_data_plane_destroy(s->dataplane); s->dataplane = NULL; @@ -696,7 +700,8 @@ static int virtio_blk_device_exit(DeviceState *dev) unregister_savevm(dev, "virtio-blk", s); blockdev_mark_auto_del(s->bs); virtio_cleanup(vdev); - return 0; + + vbc->parent_unrealize(dev, errp); } static Property virtio_blk_properties[] = { @@ -704,13 +709,19 @@ static Property virtio_blk_properties[] = { DEFINE_PROP_END_OF_LIST(), }; -static void virtio_blk_class_init(ObjectClass *klass, void *data) +static void virtio_blk_class_init(ObjectClass *oc, void *data) { - DeviceClass *dc = DEVICE_CLASS(klass); - VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); - dc->exit = virtio_blk_device_exit; + DeviceClass *dc = DEVICE_CLASS(oc); + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(oc); + VirtIOBlockClass *vbc = VIRTIO_BLK_CLASS(oc); + + vbc->parent_realize = dc->realize; + dc->realize = virtio_blk_device_realize; + + vbc->parent_unrealize = dc->unrealize; + dc->unrealize = virtio_blk_device_unrealize; + dc->props = virtio_blk_properties; - vdc->init = virtio_blk_device_init; vdc->get_config = virtio_blk_update_config; vdc->set_config = virtio_blk_set_config; vdc->get_features = virtio_blk_get_features; @@ -723,6 +734,7 @@ static const TypeInfo virtio_device_info = { .parent = TYPE_VIRTIO_DEVICE, .instance_size = sizeof(VirtIOBlock), .class_init = virtio_blk_class_init, + .class_size = sizeof(VirtIOBlockClass), }; static void virtio_register_types(void) diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c index cc3d1dd..1cdd659 100644 --- a/hw/char/virtio-serial-bus.c +++ b/hw/char/virtio-serial-bus.c @@ -889,31 +889,35 @@ static int virtser_port_qdev_exit(DeviceState *qdev) return 0; } -static int virtio_serial_device_init(VirtIODevice *vdev) +static void virtio_serial_device_realize(DeviceState *dev, Error **errp) { - DeviceState *qdev = DEVICE(vdev); - VirtIOSerial *vser = VIRTIO_SERIAL(vdev); + VirtIODevice *vdev = VIRTIO_DEVICE(dev); + VirtIOSerial *vser = VIRTIO_SERIAL(dev); + VirtIOSerialClass *vsc = VIRTIO_SERIAL_GET_CLASS(dev); + BusState *bus; uint32_t i, max_supported_ports; if (!vser->serial.max_virtserial_ports) { - return -1; + error_setg(errp, "Maximum number of serial ports not specified"); + return; } /* Each port takes 2 queues, and one pair is for the control queue */ max_supported_ports = VIRTIO_PCI_QUEUE_MAX / 2 - 1; if (vser->serial.max_virtserial_ports > max_supported_ports) { - error_report("maximum ports supported: %u", max_supported_ports); - return -1; + error_setg(errp, "maximum ports supported: %u", max_supported_ports); + return; } virtio_init(vdev, "virtio-serial", VIRTIO_ID_CONSOLE, sizeof(struct virtio_console_config)); /* Spawn a new virtio-serial bus on which the ports will ride as devices */ - qbus_create_inplace(&vser->bus.qbus, TYPE_VIRTIO_SERIAL_BUS, qdev, + qbus_create_inplace(&vser->bus, TYPE_VIRTIO_SERIAL_BUS, dev, vdev->bus_name); - vser->bus.qbus.allow_hotplug = 1; + bus = BUS(&vser->bus); + bus->allow_hotplug = 1; vser->bus.vser = vser; QTAILQ_INIT(&vser->ports); @@ -961,10 +965,10 @@ static int virtio_serial_device_init(VirtIODevice *vdev) * Register for the savevm section with the virtio-console name * to preserve backward compat */ - register_savevm(qdev, "virtio-console", -1, 3, virtio_serial_save, + register_savevm(dev, "virtio-console", -1, 3, virtio_serial_save, virtio_serial_load, vser); - return 0; + vsc->parent_realize(dev, errp); } static void virtio_serial_port_class_init(ObjectClass *klass, void *data) @@ -986,10 +990,11 @@ static const TypeInfo virtio_serial_port_type_info = { .class_init = virtio_serial_port_class_init, }; -static int virtio_serial_device_exit(DeviceState *dev) +static void virtio_serial_device_unrealize(DeviceState *dev, Error **errp) { - VirtIOSerial *vser = VIRTIO_SERIAL(dev); VirtIODevice *vdev = VIRTIO_DEVICE(dev); + VirtIOSerial *vser = VIRTIO_SERIAL(dev); + VirtIOSerialClass *vsc = VIRTIO_SERIAL_GET_CLASS(dev); unregister_savevm(dev, "virtio-console", vser); @@ -1003,7 +1008,8 @@ static int virtio_serial_device_exit(DeviceState *dev) g_free(vser->post_load); } virtio_cleanup(vdev); - return 0; + + vsc->parent_unrealize(dev, errp); } static Property virtio_serial_properties[] = { @@ -1011,13 +1017,19 @@ static Property virtio_serial_properties[] = { DEFINE_PROP_END_OF_LIST(), }; -static void virtio_serial_class_init(ObjectClass *klass, void *data) +static void virtio_serial_class_init(ObjectClass *oc, void *data) { - DeviceClass *dc = DEVICE_CLASS(klass); - VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); - dc->exit = virtio_serial_device_exit; + DeviceClass *dc = DEVICE_CLASS(oc); + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(oc); + VirtIOSerialClass *vsc = VIRTIO_SERIAL_CLASS(oc); + + vsc->parent_realize = dc->realize; + dc->realize = virtio_serial_device_realize; + + vsc->parent_unrealize = dc->unrealize; + dc->unrealize = virtio_serial_device_unrealize; + dc->props = virtio_serial_properties; - vdc->init = virtio_serial_device_init; vdc->get_features = get_features; vdc->get_config = get_config; vdc->set_config = set_config; @@ -1030,6 +1042,7 @@ static const TypeInfo virtio_device_info = { .parent = TYPE_VIRTIO_DEVICE, .instance_size = sizeof(VirtIOSerial), .class_init = virtio_serial_class_init, + .class_size = sizeof(VirtIOSerialClass), }; static void virtio_serial_register_types(void) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 1ea9556..9a3680c 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1367,15 +1367,16 @@ void virtio_net_set_netclient_name(VirtIONet *n, const char *name, n->netclient_type = g_strdup(type); } -static int virtio_net_device_init(VirtIODevice *vdev) +static void virtio_net_device_realize(DeviceState *dev, Error **errp) { int i; - DeviceState *qdev = DEVICE(vdev); - VirtIONet *n = VIRTIO_NET(vdev); + DeviceState *qdev = DEVICE(dev); + VirtIODevice *vdev = VIRTIO_DEVICE(dev); + VirtIONet *n = VIRTIO_NET(dev); + VirtIONetClass *vnc = VIRTIO_NET_GET_CLASS(dev); - virtio_init(VIRTIO_DEVICE(n), "virtio-net", VIRTIO_ID_NET, - n->config_size); + virtio_init(vdev, "virtio-net", VIRTIO_ID_NET, n->config_size); n->max_queues = MAX(n->nic_conf.queues, 1); n->vqs = g_malloc0(sizeof(VirtIONetQueue) * n->max_queues); @@ -1439,24 +1440,26 @@ static int virtio_net_device_init(VirtIODevice *vdev) n->vlans = g_malloc0(MAX_VLAN >> 3); - n->qdev = qdev; - register_savevm(qdev, "virtio-net", -1, VIRTIO_NET_VM_VERSION, + n->qdev = dev; + register_savevm(dev, "virtio-net", -1, VIRTIO_NET_VM_VERSION, virtio_net_save, virtio_net_load, n); - add_boot_device_path(n->nic_conf.bootindex, qdev, "/ethernet-phy@0"); - return 0; + add_boot_device_path(n->nic_conf.bootindex, dev, "/ethernet-phy@0"); + + vnc->parent_realize(dev, errp); } -static int virtio_net_device_exit(DeviceState *qdev) +static void virtio_net_device_unrealize(DeviceState *dev, Error **errp) { - VirtIONet *n = VIRTIO_NET(qdev); - VirtIODevice *vdev = VIRTIO_DEVICE(qdev); + VirtIODevice *vdev = VIRTIO_DEVICE(dev); + VirtIONet *n = VIRTIO_NET(dev); + VirtIONetClass *vnc = VIRTIO_NET_GET_CLASS(dev); int i; /* This will stop vhost backend if appropriate. */ virtio_net_set_status(vdev, 0); - unregister_savevm(qdev, "virtio-net", n); + unregister_savevm(dev, "virtio-net", n); if (n->netclient_name) { g_free(n->netclient_name); @@ -1488,7 +1491,7 @@ static int virtio_net_device_exit(DeviceState *qdev) qemu_del_nic(n->nic); virtio_cleanup(vdev); - return 0; + vnc->parent_unrealize(dev, errp); } static void virtio_net_instance_init(Object *obj) @@ -1511,13 +1514,19 @@ static Property virtio_net_properties[] = { DEFINE_PROP_END_OF_LIST(), }; -static void virtio_net_class_init(ObjectClass *klass, void *data) +static void virtio_net_class_init(ObjectClass *oc, void *data) { - DeviceClass *dc = DEVICE_CLASS(klass); - VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); - dc->exit = virtio_net_device_exit; + DeviceClass *dc = DEVICE_CLASS(oc); + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(oc); + VirtIONetClass *vnc = VIRTIO_NET_CLASS(oc); + + vnc->parent_realize = dc->realize; + dc->realize = virtio_net_device_realize; + + vnc->parent_unrealize = dc->unrealize; + dc->unrealize = virtio_net_device_unrealize; + dc->props = virtio_net_properties; - vdc->init = virtio_net_device_init; vdc->get_config = virtio_net_get_config; vdc->set_config = virtio_net_set_config; vdc->get_features = virtio_net_get_features; @@ -1535,6 +1544,7 @@ static const TypeInfo virtio_net_info = { .instance_size = sizeof(VirtIONet), .instance_init = virtio_net_instance_init, .class_init = virtio_net_class_init, + .class_size = sizeof(VirtIONetClass), }; static void virtio_register_types(void) diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c index d7a1c33..cacaf64 100644 --- a/hw/scsi/vhost-scsi.c +++ b/hw/scsi/vhost-scsi.c @@ -196,29 +196,32 @@ static void vhost_scsi_set_status(VirtIODevice *vdev, uint8_t val) } } -static int vhost_scsi_init(VirtIODevice *vdev) +static void vhost_scsi_realize(DeviceState *dev, Error **errp) { - VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev); - VHostSCSI *s = VHOST_SCSI(vdev); + VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev); + VHostSCSI *s = VHOST_SCSI(dev); + VHostSCSIClass *vsc = VHOST_SCSI_GET_CLASS(dev); + Error *err = NULL; int vhostfd = -1; int ret; if (!vs->conf.wwpn) { - error_report("vhost-scsi: missing wwpn\n"); - return -EINVAL; + error_setg(errp, "vhost-scsi: missing wwpn"); + return; } if (vs->conf.vhostfd) { vhostfd = monitor_handle_fd_param(cur_mon, vs->conf.vhostfd); if (vhostfd == -1) { - error_report("vhost-scsi: unable to parse vhostfd\n"); - return -EINVAL; + error_setg(errp, "vhost-scsi: unable to parse vhostfd"); + return; } } - ret = virtio_scsi_common_init(vs); - if (ret < 0) { - return ret; + vsc->parent_realize(dev, &err); + if (err != NULL) { + error_propagate(errp, err); + return; } s->dev.nvqs = VHOST_SCSI_VQ_NUM_FIXED + vs->conf.num_queues; @@ -227,24 +230,22 @@ static int vhost_scsi_init(VirtIODevice *vdev) ret = vhost_dev_init(&s->dev, vhostfd, "/dev/vhost-scsi", true); if (ret < 0) { - error_report("vhost-scsi: vhost initialization failed: %s\n", - strerror(-ret)); - return ret; + error_setg(errp, "vhost-scsi: vhost initialization failed: %s", + strerror(-ret)); + return; } s->dev.backend_features = 0; error_setg(&s->migration_blocker, "vhost-scsi does not support migration"); migrate_add_blocker(s->migration_blocker); - - return 0; } -static int vhost_scsi_exit(DeviceState *qdev) +static void vhost_scsi_unrealize(DeviceState *dev, Error **errp) { - VirtIODevice *vdev = VIRTIO_DEVICE(qdev); - VHostSCSI *s = VHOST_SCSI(qdev); - VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(qdev); + VirtIODevice *vdev = VIRTIO_DEVICE(dev); + VHostSCSI *s = VHOST_SCSI(dev); + VHostSCSIClass *vsc = VHOST_SCSI_GET_CLASS(dev); migrate_del_blocker(s->migration_blocker); error_free(s->migration_blocker); @@ -253,7 +254,8 @@ static int vhost_scsi_exit(DeviceState *qdev) vhost_scsi_set_status(vdev, 0); g_free(s->dev.vqs); - return virtio_scsi_common_exit(vs); + + vsc->parent_unrealize(dev, errp); } static Property vhost_scsi_properties[] = { @@ -261,13 +263,19 @@ static Property vhost_scsi_properties[] = { DEFINE_PROP_END_OF_LIST(), }; -static void vhost_scsi_class_init(ObjectClass *klass, void *data) +static void vhost_scsi_class_init(ObjectClass *oc, void *data) { - DeviceClass *dc = DEVICE_CLASS(klass); - VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); - dc->exit = vhost_scsi_exit; + DeviceClass *dc = DEVICE_CLASS(oc); + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(oc); + VHostSCSIClass *vsc = VHOST_SCSI_CLASS(oc); + + vsc->parent_realize = dc->realize; + dc->realize = vhost_scsi_realize; + + vsc->parent_unrealize = dc->unrealize; + dc->unrealize = vhost_scsi_unrealize; + dc->props = vhost_scsi_properties; - vdc->init = vhost_scsi_init; vdc->get_features = vhost_scsi_get_features; vdc->set_config = vhost_scsi_set_config; vdc->set_status = vhost_scsi_set_status; @@ -278,6 +286,7 @@ static const TypeInfo vhost_scsi_info = { .parent = TYPE_VIRTIO_SCSI_COMMON, .instance_size = sizeof(VHostSCSI), .class_init = vhost_scsi_class_init, + .class_size = sizeof(VHostSCSIClass), }; static void virtio_register_types(void) diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 08dd3f3..6704f78 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -587,12 +587,14 @@ static struct SCSIBusInfo virtio_scsi_scsi_info = { .load_request = virtio_scsi_load_request, }; -int virtio_scsi_common_init(VirtIOSCSICommon *s) +static void virtio_scsi_common_realize(DeviceState *dev, Error **errp) { - VirtIODevice *vdev = VIRTIO_DEVICE(s); + VirtIODevice *vdev = VIRTIO_DEVICE(dev); + VirtIOSCSICommon *s = VIRTIO_SCSI_COMMON(dev); + VirtIOSCSICommonClass *vscc = VIRTIO_SCSI_COMMON_GET_CLASS(dev); int i; - virtio_init(VIRTIO_DEVICE(s), "virtio-scsi", VIRTIO_ID_SCSI, + virtio_init(vdev, "virtio-scsi", VIRTIO_ID_SCSI, sizeof(VirtIOSCSIConfig)); s->cmd_vqs = g_malloc0(s->conf.num_queues * sizeof(VirtQueue *)); @@ -608,50 +610,53 @@ int virtio_scsi_common_init(VirtIOSCSICommon *s) virtio_scsi_handle_cmd); } - return 0; + vscc->parent_realize(dev, errp); } -static int virtio_scsi_device_init(VirtIODevice *vdev) +static void virtio_scsi_device_realize(DeviceState *dev, Error **errp) { - DeviceState *qdev = DEVICE(vdev); - VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev); - VirtIOSCSI *s = VIRTIO_SCSI(vdev); + VirtIODevice *vdev = VIRTIO_DEVICE(dev); + VirtIOSCSI *s = VIRTIO_SCSI(dev); + VirtIOSCSIClass *vsc = VIRTIO_SCSI_GET_CLASS(dev); static int virtio_scsi_id; - int ret; + Error *err = NULL; - ret = virtio_scsi_common_init(vs); - if (ret < 0) { - return ret; + vsc->parent_realize(dev, &err); + if (err != NULL) { + error_propagate(errp, err); + return; } - scsi_bus_new(&s->bus, qdev, &virtio_scsi_scsi_info, vdev->bus_name); + scsi_bus_new(&s->bus, dev, &virtio_scsi_scsi_info, vdev->bus_name); - if (!qdev->hotplugged) { + if (!dev->hotplugged) { scsi_bus_legacy_handle_cmdline(&s->bus); } - register_savevm(qdev, "virtio-scsi", virtio_scsi_id++, 1, + register_savevm(dev, "virtio-scsi", virtio_scsi_id++, 1, virtio_scsi_save, virtio_scsi_load, s); - - return 0; } -int virtio_scsi_common_exit(VirtIOSCSICommon *vs) +static void virtio_scsi_common_unrealize(DeviceState *dev, Error **errp) { - VirtIODevice *vdev = VIRTIO_DEVICE(vs); + VirtIODevice *vdev = VIRTIO_DEVICE(dev); + VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev); + VirtIOSCSICommonClass *vscc = VIRTIO_SCSI_COMMON_GET_CLASS(dev); g_free(vs->cmd_vqs); virtio_cleanup(vdev); - return 0; + + vscc->parent_unrealize(dev, errp); } -static int virtio_scsi_device_exit(DeviceState *qdev) +static void virtio_scsi_device_unrealize(DeviceState *dev, Error **errp) { - VirtIOSCSI *s = VIRTIO_SCSI(qdev); - VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(qdev); + VirtIOSCSI *s = VIRTIO_SCSI(dev); + VirtIOSCSIClass *vsc = VIRTIO_SCSI_GET_CLASS(dev); - unregister_savevm(qdev, "virtio-scsi", s); - return virtio_scsi_common_exit(vs); + unregister_savevm(dev, "virtio-scsi", s); + + vsc->parent_unrealize(dev, errp); } static Property virtio_scsi_properties[] = { @@ -659,20 +664,34 @@ static Property virtio_scsi_properties[] = { DEFINE_PROP_END_OF_LIST(), }; -static void virtio_scsi_common_class_init(ObjectClass *klass, void *data) +static void virtio_scsi_common_class_init(ObjectClass *oc, void *data) { - VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(oc); + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(oc); + VirtIOSCSICommonClass *vscc = VIRTIO_SCSI_COMMON_CLASS(oc); + + vscc->parent_realize = dc->realize; + dc->realize = virtio_scsi_common_realize; + + vscc->parent_unrealize = dc->unrealize; + dc->unrealize = virtio_scsi_common_unrealize; vdc->get_config = virtio_scsi_get_config; } -static void virtio_scsi_class_init(ObjectClass *klass, void *data) +static void virtio_scsi_class_init(ObjectClass *oc, void *data) { - DeviceClass *dc = DEVICE_CLASS(klass); - VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); - dc->exit = virtio_scsi_device_exit; + DeviceClass *dc = DEVICE_CLASS(oc); + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(oc); + VirtIOSCSIClass *vsc = VIRTIO_SCSI_CLASS(oc); + + vsc->parent_realize = dc->realize; + dc->realize = virtio_scsi_device_realize; + + vsc->parent_unrealize = dc->unrealize; + dc->unrealize = virtio_scsi_device_unrealize; + dc->props = virtio_scsi_properties; - vdc->init = virtio_scsi_device_init; vdc->set_config = virtio_scsi_set_config; vdc->get_features = virtio_scsi_get_features; vdc->reset = virtio_scsi_reset; @@ -683,6 +702,7 @@ static const TypeInfo virtio_scsi_common_info = { .parent = TYPE_VIRTIO_DEVICE, .instance_size = sizeof(VirtIOSCSICommon), .class_init = virtio_scsi_common_class_init, + .class_size = sizeof(VirtIOSCSICommonClass), }; static const TypeInfo virtio_scsi_info = { @@ -690,6 +710,7 @@ static const TypeInfo virtio_scsi_info = { .parent = TYPE_VIRTIO_SCSI_COMMON, .instance_size = sizeof(VirtIOSCSI), .class_init = virtio_scsi_class_init, + .class_size = sizeof(VirtIOSCSIClass), }; static void virtio_register_types(void) diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index d669756..0535062 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -336,10 +336,11 @@ static int virtio_balloon_load(QEMUFile *f, void *opaque, int version_id) return 0; } -static int virtio_balloon_device_init(VirtIODevice *vdev) +static void virtio_balloon_device_realize(DeviceState *dev, Error **errp) { - DeviceState *qdev = DEVICE(vdev); - VirtIOBalloon *s = VIRTIO_BALLOON(vdev); + VirtIODevice *vdev = VIRTIO_DEVICE(dev); + VirtIOBalloon *s = VIRTIO_BALLOON(dev); + VirtIOBalloonClass *vbc = VIRTIO_BALLOON_GET_CLASS(dev); int ret; virtio_init(vdev, "virtio-balloon", VIRTIO_ID_BALLOON, 8); @@ -348,50 +349,60 @@ static int virtio_balloon_device_init(VirtIODevice *vdev) virtio_balloon_stat, s); if (ret < 0) { - virtio_cleanup(VIRTIO_DEVICE(s)); - return -1; + error_setg(errp, "Adding balloon handler failed"); + virtio_cleanup(vdev); + return; } s->ivq = virtio_add_queue(vdev, 128, virtio_balloon_handle_output); s->dvq = virtio_add_queue(vdev, 128, virtio_balloon_handle_output); s->svq = virtio_add_queue(vdev, 128, virtio_balloon_receive_stats); - register_savevm(qdev, "virtio-balloon", -1, 1, + register_savevm(dev, "virtio-balloon", -1, 1, virtio_balloon_save, virtio_balloon_load, s); - object_property_add(OBJECT(qdev), "guest-stats", "guest statistics", + object_property_add(OBJECT(dev), "guest-stats", "guest statistics", balloon_stats_get_all, NULL, NULL, s, NULL); - object_property_add(OBJECT(qdev), "guest-stats-polling-interval", "int", + object_property_add(OBJECT(dev), "guest-stats-polling-interval", "int", balloon_stats_get_poll_interval, balloon_stats_set_poll_interval, NULL, s, NULL); - return 0; + + vbc->parent_realize(dev, errp); } -static int virtio_balloon_device_exit(DeviceState *qdev) +static void virtio_balloon_device_unrealize(DeviceState *dev, Error **errp) { - VirtIOBalloon *s = VIRTIO_BALLOON(qdev); - VirtIODevice *vdev = VIRTIO_DEVICE(qdev); + VirtIODevice *vdev = VIRTIO_DEVICE(dev); + VirtIOBalloon *s = VIRTIO_BALLOON(dev); + VirtIOBalloonClass *vbc = VIRTIO_BALLOON_GET_CLASS(dev); balloon_stats_destroy_timer(s); qemu_remove_balloon_handler(s); - unregister_savevm(qdev, "virtio-balloon", s); + unregister_savevm(dev, "virtio-balloon", s); virtio_cleanup(vdev); - return 0; + + vbc->parent_unrealize(dev, errp); } static Property virtio_balloon_properties[] = { DEFINE_PROP_END_OF_LIST(), }; -static void virtio_balloon_class_init(ObjectClass *klass, void *data) +static void virtio_balloon_class_init(ObjectClass *oc, void *data) { - DeviceClass *dc = DEVICE_CLASS(klass); - VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); - dc->exit = virtio_balloon_device_exit; + DeviceClass *dc = DEVICE_CLASS(oc); + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(oc); + VirtIOBalloonClass *vbc = VIRTIO_BALLOON_CLASS(oc); + + vbc->parent_realize = dc->realize; + dc->realize = virtio_balloon_device_realize; + + vbc->parent_unrealize = dc->unrealize; + dc->unrealize = virtio_balloon_device_unrealize; + dc->props = virtio_balloon_properties; - vdc->init = virtio_balloon_device_init; vdc->get_config = virtio_balloon_get_config; vdc->set_config = virtio_balloon_set_config; vdc->get_features = virtio_balloon_get_features; @@ -402,6 +413,7 @@ static const TypeInfo virtio_balloon_info = { .parent = TYPE_VIRTIO_DEVICE, .instance_size = sizeof(VirtIOBalloon), .class_init = virtio_balloon_class_init, + .class_size = sizeof(VirtIOBalloonClass), }; static void virtio_register_types(void) diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c index cb787c7..108cfc9 100644 --- a/hw/virtio/virtio-rng.c +++ b/hw/virtio/virtio-rng.c @@ -133,21 +133,22 @@ static void check_rate_limit(void *opaque) qemu_get_clock_ms(vm_clock) + vrng->conf.period_ms); } -static int virtio_rng_device_init(VirtIODevice *vdev) +static void virtio_rng_device_realize(DeviceState *dev, Error **errp) { - DeviceState *qdev = DEVICE(vdev); - VirtIORNG *vrng = VIRTIO_RNG(vdev); + VirtIODevice *vdev = VIRTIO_DEVICE(dev); + VirtIORNG *vrng = VIRTIO_RNG(dev); + VirtIORNGClass *vrc = VIRTIO_RNG_GET_CLASS(dev); Error *local_err = NULL; if (vrng->conf.rng == NULL) { vrng->conf.default_backend = RNG_RANDOM(object_new(TYPE_RNG_RANDOM)); - object_property_add_child(OBJECT(qdev), + object_property_add_child(OBJECT(dev), "default-backend", OBJECT(vrng->conf.default_backend), NULL); - object_property_set_link(OBJECT(qdev), + object_property_set_link(OBJECT(dev), OBJECT(vrng->conf.default_backend), "rng", NULL); } @@ -156,15 +157,14 @@ static int virtio_rng_device_init(VirtIODevice *vdev) vrng->rng = vrng->conf.rng; if (vrng->rng == NULL) { - qerror_report(QERR_INVALID_PARAMETER_VALUE, "rng", "a valid object"); - return -1; + error_set(errp, QERR_INVALID_PARAMETER_VALUE, "rng", "a valid object"); + return; } rng_backend_open(vrng->rng, &local_err); if (local_err) { - qerror_report_err(local_err); - error_free(local_err); - return -1; + error_propagate(errp, local_err); + return; } vrng->vq = virtio_add_queue(vdev, 8, handle_input); @@ -178,22 +178,24 @@ static int virtio_rng_device_init(VirtIODevice *vdev) qemu_mod_timer(vrng->rate_limit_timer, qemu_get_clock_ms(vm_clock) + vrng->conf.period_ms); - register_savevm(qdev, "virtio-rng", -1, 1, virtio_rng_save, + register_savevm(dev, "virtio-rng", -1, 1, virtio_rng_save, virtio_rng_load, vrng); - return 0; + vrc->parent_realize(dev, errp); } -static int virtio_rng_device_exit(DeviceState *qdev) +static void virtio_rng_device_unrealize(DeviceState *dev, Error **errp) { - VirtIORNG *vrng = VIRTIO_RNG(qdev); - VirtIODevice *vdev = VIRTIO_DEVICE(qdev); + VirtIODevice *vdev = VIRTIO_DEVICE(dev); + VirtIORNG *vrng = VIRTIO_RNG(dev); + VirtIORNGClass *vrc = VIRTIO_RNG_GET_CLASS(dev); qemu_del_timer(vrng->rate_limit_timer); qemu_free_timer(vrng->rate_limit_timer); - unregister_savevm(qdev, "virtio-rng", vrng); + unregister_savevm(dev, "virtio-rng", vrng); virtio_cleanup(vdev); - return 0; + + vrc->parent_unrealize(dev, errp); } static Property virtio_rng_properties[] = { @@ -201,13 +203,19 @@ static Property virtio_rng_properties[] = { DEFINE_PROP_END_OF_LIST(), }; -static void virtio_rng_class_init(ObjectClass *klass, void *data) +static void virtio_rng_class_init(ObjectClass *oc, void *data) { - DeviceClass *dc = DEVICE_CLASS(klass); - VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); - dc->exit = virtio_rng_device_exit; + DeviceClass *dc = DEVICE_CLASS(oc); + VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(oc); + VirtIORNGClass *vrc = VIRTIO_RNG_CLASS(oc); + + vrc->parent_realize = dc->realize; + dc->realize = virtio_rng_device_realize; + + vrc->parent_unrealize = dc->unrealize; + dc->unrealize = virtio_rng_device_unrealize; + dc->props = virtio_rng_properties; - vdc->init = virtio_rng_device_init; vdc->get_features = get_features; } @@ -225,6 +233,7 @@ static const TypeInfo virtio_rng_info = { .instance_size = sizeof(VirtIORNG), .instance_init = virtio_rng_initfn, .class_init = virtio_rng_class_init, + .class_size = sizeof(VirtIORNGClass), }; static void virtio_register_types(void) diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index 8176c14..d369f9a 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -1105,35 +1105,29 @@ void virtio_device_set_child_bus_name(VirtIODevice *vdev, char *bus_name) } } -static int virtio_device_init(DeviceState *qdev) +static void virtio_device_realize(DeviceState *dev, Error **errp) { - VirtIODevice *vdev = VIRTIO_DEVICE(qdev); - VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(qdev); - assert(k->init != NULL); - if (k->init(vdev) < 0) { - return -1; - } + VirtIODevice *vdev = VIRTIO_DEVICE(dev); + virtio_bus_plug_device(vdev); - return 0; } -static int virtio_device_exit(DeviceState *qdev) +static void virtio_device_unrealize(DeviceState *dev, Error **errp) { - VirtIODevice *vdev = VIRTIO_DEVICE(qdev); + VirtIODevice *vdev = VIRTIO_DEVICE(dev); if (vdev->bus_name) { g_free(vdev->bus_name); vdev->bus_name = NULL; } - return 0; } static void virtio_device_class_init(ObjectClass *klass, void *data) { /* Set the default value here. */ DeviceClass *dc = DEVICE_CLASS(klass); - dc->init = virtio_device_init; - dc->exit = virtio_device_exit; + dc->realize = virtio_device_realize; + dc->unrealize = virtio_device_unrealize; dc->bus_type = TYPE_VIRTIO_BUS; } diff --git a/include/hw/virtio/vhost-scsi.h b/include/hw/virtio/vhost-scsi.h index 85cc031..b0d64e4 100644 --- a/include/hw/virtio/vhost-scsi.h +++ b/include/hw/virtio/vhost-scsi.h @@ -53,6 +53,10 @@ enum vhost_scsi_vq_list { #define TYPE_VHOST_SCSI "vhost-scsi" #define VHOST_SCSI(obj) \ OBJECT_CHECK(VHostSCSI, (obj), TYPE_VHOST_SCSI) +#define VHOST_SCSI_GET_CLASS(obj) \ + OBJECT_GET_CLASS(VHostSCSIClass, (obj), TYPE_VHOST_SCSI) +#define VHOST_SCSI_CLASS(cls) \ + OBJECT_CLASS_CHECK(VHostSCSIClass, (cls), TYPE_VHOST_SCSI) typedef struct VHostSCSI { VirtIOSCSICommon parent_obj; @@ -62,6 +66,15 @@ typedef struct VHostSCSI { struct vhost_dev dev; } VHostSCSI; +typedef struct VHostSCSIClass { + /*< private >*/ + VirtIOSCSICommonClass parent_class; + /*< public >*/ + + DeviceRealize parent_realize; + DeviceUnrealize parent_unrealize; +} VHostSCSIClass; + #define DEFINE_VHOST_SCSI_PROPERTIES(_state, _conf_field) \ DEFINE_PROP_STRING("vhostfd", _state, _conf_field.vhostfd), \ DEFINE_PROP_STRING("wwpn", _state, _conf_field.wwpn), \ diff --git a/include/hw/virtio/virtio-balloon.h b/include/hw/virtio/virtio-balloon.h index f863bfe..146fa04 100644 --- a/include/hw/virtio/virtio-balloon.h +++ b/include/hw/virtio/virtio-balloon.h @@ -21,6 +21,10 @@ #define TYPE_VIRTIO_BALLOON "virtio-balloon-device" #define VIRTIO_BALLOON(obj) \ OBJECT_CHECK(VirtIOBalloon, (obj), TYPE_VIRTIO_BALLOON) +#define VIRTIO_BALLOON_GET_CLASS(obj) \ + OBJECT_GET_CLASS(VirtIOBalloonClass, (obj), TYPE_VIRTIO_BALLOON) +#define VIRTIO_BALLOON_CLASS(cls) \ + OBJECT_CLASS_CHECK(VirtIOBalloonClass, (cls), TYPE_VIRTIO_BALLOON) /* from Linux's linux/virtio_balloon.h */ @@ -69,4 +73,13 @@ typedef struct VirtIOBalloon { int64_t stats_poll_interval; } VirtIOBalloon; +typedef struct VirtIOBalloonClass { + /*< private >*/ + VirtioDeviceClass parent_class; + /*< public >*/ + + DeviceRealize parent_realize; + DeviceUnrealize parent_unrealize; +} VirtIOBalloonClass; + #endif diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h index fc71853..5ed703d 100644 --- a/include/hw/virtio/virtio-blk.h +++ b/include/hw/virtio/virtio-blk.h @@ -20,6 +20,10 @@ #define TYPE_VIRTIO_BLK "virtio-blk-device" #define VIRTIO_BLK(obj) \ OBJECT_CHECK(VirtIOBlock, (obj), TYPE_VIRTIO_BLK) +#define VIRTIO_BLK_GET_CLASS(obj) \ + OBJECT_GET_CLASS(VirtIOBlockClass, (obj), TYPE_VIRTIO_BLK) +#define VIRTIO_BLK_CLASS(cls) \ + OBJECT_CLASS_CHECK(VirtIOBlockClass, (cls), TYPE_VIRTIO_BLK) /* from Linux's linux/virtio_blk.h */ @@ -129,6 +133,15 @@ typedef struct VirtIOBlock { #endif } VirtIOBlock; +typedef struct VirtIOBlockClass { + /*< private >*/ + VirtioDeviceClass parent_class; + /*< public >*/ + + DeviceRealize parent_realize; + DeviceUnrealize parent_unrealize; +} VirtIOBlockClass; + #define DEFINE_VIRTIO_BLK_FEATURES(_state, _field) \ DEFINE_VIRTIO_COMMON_FEATURES(_state, _field) diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h index b315ac9..0b8a06e 100644 --- a/include/hw/virtio/virtio-net.h +++ b/include/hw/virtio/virtio-net.h @@ -20,6 +20,10 @@ #define TYPE_VIRTIO_NET "virtio-net-device" #define VIRTIO_NET(obj) \ OBJECT_CHECK(VirtIONet, (obj), TYPE_VIRTIO_NET) +#define VIRTIO_NET_GET_CLASS(obj) \ + OBJECT_GET_CLASS(VirtIONetClass, (obj), TYPE_VIRTIO_NET) +#define VIRTIO_NET_CLASS(cls) \ + OBJECT_CLASS_CHECK(VirtIONetClass, (cls), TYPE_VIRTIO_NET) #define ETH_ALEN 6 @@ -195,6 +199,15 @@ typedef struct VirtIONet { uint64_t curr_guest_offloads; } VirtIONet; +typedef struct VirtIONetClass { + /*< private >*/ + VirtioDeviceClass parent_class; + /*< public >*/ + + DeviceRealize parent_realize; + DeviceUnrealize parent_unrealize; +} VirtIONetClass; + #define VIRTIO_NET_CTRL_MAC 1 #define VIRTIO_NET_CTRL_MAC_TABLE_SET 0 #define VIRTIO_NET_CTRL_MAC_ADDR_SET 1 diff --git a/include/hw/virtio/virtio-rng.h b/include/hw/virtio/virtio-rng.h index debaa15..528f70c 100644 --- a/include/hw/virtio/virtio-rng.h +++ b/include/hw/virtio/virtio-rng.h @@ -18,6 +18,10 @@ #define TYPE_VIRTIO_RNG "virtio-rng-device" #define VIRTIO_RNG(obj) \ OBJECT_CHECK(VirtIORNG, (obj), TYPE_VIRTIO_RNG) +#define VIRTIO_RNG_GET_CLASS(obj) \ + OBJECT_GET_CLASS(VirtIORNGClass, (obj), TYPE_VIRTIO_RNG) +#define VIRTIO_RNG_CLASS(cls) \ + OBJECT_CLASS_CHECK(VirtIORNGClass, (cls), TYPE_VIRTIO_RNG) /* The Virtio ID for the virtio rng device */ #define VIRTIO_ID_RNG 4 @@ -46,6 +50,15 @@ typedef struct VirtIORNG { int64_t quota_remaining; } VirtIORNG; +typedef struct VirtIORNGClass { + /*< private >*/ + VirtioDeviceClass parent_class; + /*< public >*/ + + DeviceRealize parent_realize; + DeviceUnrealize parent_unrealize; +} VirtIORNGClass; + /* Set a default rate limit of 2^47 bytes per minute or roughly 2TB/s. If you have an entropy source capable of generating more entropy than this and you can pass it through via virtio-rng, then hats off to you. Until diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h index 9a98540..2ce58cd 100644 --- a/include/hw/virtio/virtio-scsi.h +++ b/include/hw/virtio/virtio-scsi.h @@ -21,10 +21,18 @@ #define TYPE_VIRTIO_SCSI_COMMON "virtio-scsi-common" #define VIRTIO_SCSI_COMMON(obj) \ OBJECT_CHECK(VirtIOSCSICommon, (obj), TYPE_VIRTIO_SCSI_COMMON) +#define VIRTIO_SCSI_COMMON_GET_CLASS(obj) \ + OBJECT_GET_CLASS(VirtIOSCSICommonClass, (obj), TYPE_VIRTIO_SCSI_COMMON) +#define VIRTIO_SCSI_COMMON_CLASS(cls) \ + OBJECT_CHECK(VirtIOSCSICommonClass, (cls), TYPE_VIRTIO_SCSI_COMMON) #define TYPE_VIRTIO_SCSI "virtio-scsi-device" #define VIRTIO_SCSI(obj) \ OBJECT_CHECK(VirtIOSCSI, (obj), TYPE_VIRTIO_SCSI) +#define VIRTIO_SCSI_GET_CLASS(obj) \ + OBJECT_GET_CLASS(VirtIOSCSIClass, (obj), TYPE_VIRTIO_SCSI) +#define VIRTIO_SCSI_CLASS(cls) \ + OBJECT_CHECK(VirtIOSCSIClass, (cls), TYPE_VIRTIO_SCSI) /* The ID for virtio_scsi */ @@ -166,6 +174,15 @@ typedef struct VirtIOSCSICommon { VirtQueue **cmd_vqs; } VirtIOSCSICommon; +typedef struct VirtIOSCSICommonClass { + /*< private >*/ + VirtioDeviceClass parent_class; + /*< public >*/ + + DeviceRealize parent_realize; + DeviceUnrealize parent_unrealize; +} VirtIOSCSICommonClass; + typedef struct { VirtIOSCSICommon parent_obj; @@ -174,6 +191,15 @@ typedef struct { bool events_dropped; } VirtIOSCSI; +typedef struct VirtIOSCSIClass { + /*< private >*/ + VirtIOSCSICommonClass parent_class; + /*< public >*/ + + DeviceRealize parent_realize; + DeviceUnrealize parent_unrealize; +} VirtIOSCSIClass; + #define DEFINE_VIRTIO_SCSI_PROPERTIES(_state, _conf_field) \ DEFINE_PROP_UINT32("num_queues", _state, _conf_field.num_queues, 1), \ DEFINE_PROP_UINT32("max_sectors", _state, _conf_field.max_sectors, 0xFFFF),\ @@ -186,7 +212,4 @@ typedef struct { DEFINE_PROP_BIT("param_change", _state, _feature_field, \ VIRTIO_SCSI_F_CHANGE, true) -int virtio_scsi_common_init(VirtIOSCSICommon *vs); -int virtio_scsi_common_exit(VirtIOSCSICommon *vs); - #endif /* _QEMU_VIRTIO_SCSI_H */ diff --git a/include/hw/virtio/virtio-serial.h b/include/hw/virtio/virtio-serial.h index 1d2040b..49af9e3 100644 --- a/include/hw/virtio/virtio-serial.h +++ b/include/hw/virtio/virtio-serial.h @@ -212,6 +212,15 @@ struct VirtIOSerial { virtio_serial_conf serial; }; +typedef struct VirtIOSerialClass { + /*< private >*/ + VirtioDeviceClass parent_class; + /*< public >*/ + + DeviceRealize parent_realize; + DeviceUnrealize parent_unrealize; +} VirtIOSerialClass; + /* Interface to the virtio-serial bus */ /* @@ -247,6 +256,10 @@ void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle); #define TYPE_VIRTIO_SERIAL "virtio-serial-device" #define VIRTIO_SERIAL(obj) \ OBJECT_CHECK(VirtIOSerial, (obj), TYPE_VIRTIO_SERIAL) +#define VIRTIO_SERIAL_GET_CLASS(obj) \ + OBJECT_GET_CLASS(VirtIOSerialClass, (obj), TYPE_VIRTIO_SERIAL) +#define VIRTIO_SERIAL_CLASS(cls) \ + OBJECT_CLASS_CHECK(VirtIOSerialClass, (cls), TYPE_VIRTIO_SERIAL) #define DEFINE_VIRTIO_SERIAL_PROPERTIES(_state, _field) \ DEFINE_PROP_UINT32("max_ports", _state, _field.max_virtserial_ports, 31) diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index a6c5c53..7e1854a 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -122,9 +122,11 @@ struct VirtIODevice }; typedef struct VirtioDeviceClass { - /* This is what a VirtioDevice must implement */ + /*< private >*/ DeviceClass parent; - int (*init)(VirtIODevice *vdev); + /*< public >*/ + + /* This is what a VirtioDevice must implement */ uint32_t (*get_features)(VirtIODevice *vdev, uint32_t requested_features); uint32_t (*bad_features)(VirtIODevice *vdev); void (*set_features)(VirtIODevice *vdev, uint32_t val); -- 1.8.1.4