virtio: set virtio-mmio transport features for various backends Hi Peter, i.e others -
This is a second attempt at setting transport backend features, for back-ends that are instantiated separately from transport and dynamically plugged in. virtio-mmio transport is addressed by this patch for virtio-net and virtio-blk back-ends. This patch declares features for all back-ends in the transport file, and based on the type of back-end applies the back-end features. A hook is added in VirtioBusClass that each transport can override to apply specific features for a back-end. The hook is called with the back-end device when it's plugged in. Thanks, Mario. Signed-off-by: Mario Smarduch <m.smard...@samsung.com> --- hw/virtio/virtio-bus.c | 5 +++++ hw/virtio/virtio-mmio.c | 46 ++++++++++++++++++++++++++++++++++++++++ include/hw/virtio/virtio-bus.h | 4 ++++ 3 files changed, 55 insertions(+) diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c index eb77019..5eb9ba1 100644 --- a/hw/virtio/virtio-bus.c +++ b/hw/virtio/virtio-bus.c @@ -44,8 +44,13 @@ int virtio_bus_device_plugged(VirtIODevice *vdev) BusState *qbus = BUS(qdev_get_parent_bus(qdev)); VirtioBusState *bus = VIRTIO_BUS(qbus); VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(bus); + DeviceState *proxy = DEVICE(qbus->parent); DPRINTF("%s: plug device.\n", qbus->name); + if (klass->set_transport_features != NULL) { + klass->set_transport_features(proxy); + } + if (klass->device_plugged != NULL) { klass->device_plugged(qbus->parent); } diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c index 8829eb0..f4e67a2 100644 --- a/hw/virtio/virtio-mmio.c +++ b/hw/virtio/virtio-mmio.c @@ -23,6 +23,8 @@ #include "hw/virtio/virtio.h" #include "qemu/host-utils.h" #include "hw/virtio/virtio-bus.h" +#include "hw/virtio/virtio-net.h" +#include "hw/virtio/virtio-blk.h" /* #define DEBUG_VIRTIO_MMIO */ @@ -89,6 +91,49 @@ typedef struct { VirtioBusState bus; } VirtIOMMIOProxy; +/* supported features for virtio-net backend */ +static Property virtio_net_transport_properties[] = { + DEFINE_VIRTIO_NET_FEATURES(VirtIOMMIOProxy, host_features), + DEFINE_PROP_END_OF_LIST(), +}; + +/* supported features for virtio-blk backend */ +static Property virtio_blk_transport_properties[] = { + DEFINE_VIRTIO_BLK_FEATURES(VirtIOMMIOProxy, host_features), + DEFINE_PROP_END_OF_LIST(), +}; + +static struct { + const char *backend_name; + const Property *props; +} mmio_transport_backends[] = { + { TYPE_VIRTIO_NET, virtio_net_transport_properties }, + { TYPE_VIRTIO_BLK, virtio_blk_transport_properties }, + { NULL, NULL }, +}; + + +static void virtio_mmio_set_transport_features(DeviceState *d) +{ + VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d); + VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus); + int i; + + for (i = 0; mmio_transport_backends[i].backend_name != NULL; i++) { + if (object_dynamic_cast(OBJECT(vdev), + mmio_transport_backends[i].backend_name)) { + const Property *props = mmio_transport_backends[i].props; + for (; props->qtype == QTYPE_QBOOL && props->qtype != QTYPE_NONE; + props++) { + if (props->defval == true) { + proxy->host_features |= (1 << props->bitnr); + } else { + proxy->host_features &= ~(1 << props->bitnr); + } + } + } + } +} static void virtio_mmio_bus_new(VirtioBusState *bus, size_t bus_size, VirtIOMMIOProxy *dev); @@ -408,6 +453,7 @@ static void virtio_mmio_bus_class_init(ObjectClass *klass, void *data) k->load_config = virtio_mmio_load_config; k->get_features = virtio_mmio_get_features; k->device_plugged = virtio_mmio_device_plugged; + k->set_transport_features = virtio_mmio_set_transport_features; k->has_variable_vring_alignment = true; bus_class->max_dev = 1; } diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h index 0756545..3136fc6 100644 --- a/include/hw/virtio/virtio-bus.h +++ b/include/hw/virtio/virtio-bus.h @@ -62,6 +62,10 @@ typedef struct VirtioBusClass { * This is called by virtio-bus just before the device is unplugged. */ void (*device_unplugged)(DeviceState *d); + /* Call before plugging a backend into transport to set features supported + * by the backend. + */ + void (*set_transport_features)(DeviceState *d); /* * Does the transport have variable vring alignment? * (ie can it ever call virtio_queue_set_align()?) -- 1.7.9.5