* [Qemu-devel] [PATCH V2 1/7] qdev: add a maximum device allowed field for the bus.
2013-01-09 15:56 [Qemu-devel] [PATCH V2 0/7] Virtio-refactoring part1 fred.konrad
@ 2013-01-09 15:56 ` fred.konrad
2013-01-09 15:56 ` [Qemu-devel] [PATCH V2 2/7] virtio-bus: introduce virtio-bus fred.konrad
` (5 subsequent siblings)
6 siblings, 0 replies; 16+ messages in thread
From: fred.konrad @ 2013-01-09 15:56 UTC (permalink / raw)
To: qemu-devel, aliguori
Cc: kwolf, peter.maydell, e.voevodin, mst, mark.burton, agraf,
amit.shah, aneesh.kumar, stefanha, cornelia.huck, pbonzini,
afaerber, fred.konrad
From: KONRAD Frederic <fred.konrad@greensocs.com>
Add a max_dev field to BusClass to specify the maximum amount of devices allowed
on the bus (has no effect if max_dev=0)
Signed-off-by: KONRAD Frederic <fred.konrad@greensocs.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/qdev-core.h | 2 ++
hw/qdev-monitor.c | 12 ++++++++++++
2 files changed, 14 insertions(+)
diff --git a/hw/qdev-core.h b/hw/qdev-core.h
index fdf14ec..a9b852e 100644
--- a/hw/qdev-core.h
+++ b/hw/qdev-core.h
@@ -87,6 +87,8 @@ struct BusClass {
*/
char *(*get_fw_dev_path)(DeviceState *dev);
int (*reset)(BusState *bus);
+ /* maximum devices allowed on the bus, 0: no limit. */
+ int max_dev;
};
typedef struct BusChild {
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index b739867..2943513 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -283,6 +283,7 @@ static DeviceState *qbus_find_dev(BusState *bus, char *elem)
static BusState *qbus_find_recursive(BusState *bus, const char *name,
const char *bus_typename)
{
+ BusClass *bus_class = BUS_GET_CLASS(bus);
BusChild *kid;
BusState *child, *ret;
int match = 1;
@@ -293,6 +294,17 @@ static BusState *qbus_find_recursive(BusState *bus, const char *name,
if (bus_typename && !object_dynamic_cast(OBJECT(bus), bus_typename)) {
match = 0;
}
+ if ((bus_class->max_dev != 0) && (bus_class->max_dev <= bus->max_index)) {
+ if (name != NULL) {
+ /* bus was explicitly specified: return an error. */
+ qerror_report(ERROR_CLASS_GENERIC_ERROR, "Bus '%s' is full",
+ bus->name);
+ return NULL;
+ } else {
+ /* bus was not specified: try to find another one. */
+ match = 0;
+ }
+ }
if (match) {
return bus;
}
--
1.7.11.7
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [Qemu-devel] [PATCH V2 2/7] virtio-bus: introduce virtio-bus
2013-01-09 15:56 [Qemu-devel] [PATCH V2 0/7] Virtio-refactoring part1 fred.konrad
2013-01-09 15:56 ` [Qemu-devel] [PATCH V2 1/7] qdev: add a maximum device allowed field for the bus fred.konrad
@ 2013-01-09 15:56 ` fred.konrad
2013-01-09 15:56 ` [Qemu-devel] [PATCH V2 3/7] virtio-device: refactor virtio-device fred.konrad
` (4 subsequent siblings)
6 siblings, 0 replies; 16+ messages in thread
From: fred.konrad @ 2013-01-09 15:56 UTC (permalink / raw)
To: qemu-devel, aliguori
Cc: kwolf, peter.maydell, e.voevodin, mst, mark.burton, agraf,
amit.shah, aneesh.kumar, stefanha, cornelia.huck, pbonzini,
afaerber, fred.konrad
From: KONRAD Frederic <fred.konrad@greensocs.com>
Introduce virtio-bus. Refactored transport device will create a bus which
extends virtio-bus.
Signed-off-by: KONRAD Frederic <fred.konrad@greensocs.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/Makefile.objs | 1 +
hw/virtio-bus.c | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
hw/virtio-bus.h | 91 +++++++++++++++++++++++++++++++++++
3 files changed, 235 insertions(+)
create mode 100644 hw/virtio-bus.c
create mode 100644 hw/virtio-bus.h
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index b8bbed3..6011a66 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -3,6 +3,7 @@ common-obj-y += loader.o
common-obj-$(CONFIG_VIRTIO) += virtio-console.o
common-obj-$(CONFIG_VIRTIO) += virtio-rng.o
common-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
+common-obj-$(CONFIG_VIRTIO) += virtio-bus.o
common-obj-y += fw_cfg.o
common-obj-$(CONFIG_PCI) += pci_bridge_dev.o
common-obj-$(CONFIG_PCI) += ioh3420.o xio3130_upstream.o xio3130_downstream.o
diff --git a/hw/virtio-bus.c b/hw/virtio-bus.c
new file mode 100644
index 0000000..7813a89
--- /dev/null
+++ b/hw/virtio-bus.c
@@ -0,0 +1,143 @@
+/*
+ * VirtioBus
+ *
+ * Copyright (C) 2012 : GreenSocs Ltd
+ * http://www.greensocs.com/ , email: info@greensocs.com
+ *
+ * Developed by :
+ * Frederic Konrad <fred.konrad@greensocs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "hw.h"
+#include "qemu/error-report.h"
+#include "qdev.h"
+#include "virtio-bus.h"
+#include "virtio.h"
+
+/* #define DEBUG_VIRTIO_BUS */
+
+#ifdef DEBUG_VIRTIO_BUS
+#define DPRINTF(fmt, ...) \
+do { printf("virtio_bus: " fmt , ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) do { } while (0)
+#endif
+
+/* Plug the VirtIODevice */
+int virtio_bus_plug_device(VirtIODevice *vdev)
+{
+ DeviceState *qdev = DEVICE(vdev);
+ BusState *qbus = BUS(qdev_get_parent_bus(qdev));
+ VirtioBusState *bus = VIRTIO_BUS(qbus);
+ VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(bus);
+ DPRINTF("%s: plug device.\n", qbus->name);
+
+ bus->vdev = vdev;
+
+ /*
+ * The lines below will disappear when we drop VirtIOBindings, at the end
+ * of the series.
+ */
+ bus->bindings.notify = klass->notify;
+ bus->bindings.save_config = klass->save_config;
+ bus->bindings.save_queue = klass->save_queue;
+ bus->bindings.load_config = klass->load_config;
+ bus->bindings.load_queue = klass->load_queue;
+ bus->bindings.load_done = klass->load_done;
+ bus->bindings.get_features = klass->get_features;
+ bus->bindings.query_guest_notifiers = klass->query_guest_notifiers;
+ bus->bindings.set_guest_notifiers = klass->set_guest_notifiers;
+ bus->bindings.set_host_notifier = klass->set_host_notifier;
+ bus->bindings.vmstate_change = klass->vmstate_change;
+ virtio_bind_device(bus->vdev, &bus->bindings, qbus->parent);
+
+ if (klass->device_plugged != NULL) {
+ klass->device_plugged(qbus->parent);
+ }
+
+ return 0;
+}
+
+/* Reset the virtio_bus */
+void virtio_bus_reset(VirtioBusState *bus)
+{
+ DPRINTF("%s: reset device.\n", qbus->name);
+ if (bus->vdev != NULL) {
+ virtio_reset(bus->vdev);
+ }
+}
+
+/* Destroy the VirtIODevice */
+void virtio_bus_destroy_device(VirtioBusState *bus)
+{
+ DeviceState *qdev;
+ BusState *qbus = BUS(bus);
+ VirtioBusClass *klass = VIRTIO_BUS_GET_CLASS(bus);
+ DPRINTF("%s: remove device.\n", qbus->name);
+
+ if (bus->vdev != NULL) {
+ if (klass->device_unplug != NULL) {
+ klass->device_unplug(qbus->parent);
+ }
+ qdev = DEVICE(bus->vdev);
+ qdev_free(qdev);
+ bus->vdev = NULL;
+ }
+}
+
+/* Get the device id of the plugged device. */
+uint16_t virtio_device_get_id(VirtioBusState *bus)
+{
+ assert(bus->vdev != NULL);
+ return bus->vdev->device_id;
+}
+
+/* Get the nvectors field of the plugged device. */
+int virtio_device_get_nvectors(VirtioBusState *bus)
+{
+ assert(bus->vdev != NULL);
+ return bus->vdev->nvectors;
+}
+
+/* Set the nvectors field of the plugged device. */
+void virtio_device_set_nvectors(VirtioBusState *bus, int nvectors)
+{
+ assert(bus->vdev != NULL);
+ bus->vdev->nvectors = nvectors;
+}
+
+/* Get the config_len field of the plugged device. */
+size_t virtio_device_get_config_len(VirtioBusState *bus)
+{
+ assert(bus->vdev != NULL);
+ return bus->vdev->config_len;
+}
+
+static const TypeInfo virtio_bus_info = {
+ .name = TYPE_VIRTIO_BUS,
+ .parent = TYPE_BUS,
+ .instance_size = sizeof(VirtioBusState),
+ .abstract = true,
+ .class_size = sizeof(VirtioBusClass),
+};
+
+static void virtio_register_types(void)
+{
+ type_register_static(&virtio_bus_info);
+}
+
+type_init(virtio_register_types)
diff --git a/hw/virtio-bus.h b/hw/virtio-bus.h
new file mode 100644
index 0000000..8aa71b2
--- /dev/null
+++ b/hw/virtio-bus.h
@@ -0,0 +1,91 @@
+/*
+ * VirtioBus
+ *
+ * Copyright (C) 2012 : GreenSocs Ltd
+ * http://www.greensocs.com/ , email: info@greensocs.com
+ *
+ * Developed by :
+ * Frederic Konrad <fred.konrad@greensocs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef VIRTIO_BUS_H
+#define VIRTIO_BUS_H
+
+#include "qdev.h"
+#include "sysemu/sysemu.h"
+#include "virtio.h"
+
+#define TYPE_VIRTIO_BUS "virtio-bus"
+#define VIRTIO_BUS_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(VirtioBusClass, obj, TYPE_VIRTIO_BUS)
+#define VIRTIO_BUS_CLASS(klass) \
+ OBJECT_CLASS_CHECK(VirtioBusClass, klass, TYPE_VIRTIO_BUS)
+#define VIRTIO_BUS(obj) OBJECT_CHECK(VirtioBusState, (obj), TYPE_VIRTIO_BUS)
+
+typedef struct VirtioBusState VirtioBusState;
+
+typedef struct VirtioBusClass {
+ /* This is what a VirtioBus must implement */
+ BusClass parent;
+ void (*notify)(DeviceState *d, uint16_t vector);
+ void (*save_config)(DeviceState *d, QEMUFile *f);
+ void (*save_queue)(DeviceState *d, int n, QEMUFile *f);
+ int (*load_config)(DeviceState *d, QEMUFile *f);
+ int (*load_queue)(DeviceState *d, int n, QEMUFile *f);
+ int (*load_done)(DeviceState *d, QEMUFile *f);
+ unsigned (*get_features)(DeviceState *d);
+ bool (*query_guest_notifiers)(DeviceState *d);
+ int (*set_guest_notifiers)(DeviceState *d, bool assigned);
+ int (*set_host_notifier)(DeviceState *d, int n, bool assigned);
+ void (*vmstate_change)(DeviceState *d, bool running);
+ /*
+ * transport independent init function.
+ * This is called by virtio-bus just after the device is plugged.
+ */
+ void (*device_plugged)(DeviceState *d);
+ /*
+ * transport independent exit function.
+ * This is called by virtio-bus just before the device is unplugged.
+ */
+ void (*device_unplug)(DeviceState *d);
+} VirtioBusClass;
+
+struct VirtioBusState {
+ BusState parent_obj;
+ /*
+ * Only one VirtIODevice can be plugged on the bus.
+ */
+ VirtIODevice *vdev;
+ /*
+ * This will be removed at the end of the series.
+ */
+ VirtIOBindings bindings;
+};
+
+int virtio_bus_plug_device(VirtIODevice *vdev);
+void virtio_bus_reset(VirtioBusState *bus);
+void virtio_bus_destroy_device(VirtioBusState *bus);
+/* Get the device id of the plugged device. */
+uint16_t virtio_device_get_id(VirtioBusState *bus);
+/* Get the nvectors field of the plugged device. */
+int virtio_device_get_nvectors(VirtioBusState *bus);
+/* Set the nvectors field of the plugged device. */
+void virtio_device_set_nvectors(VirtioBusState *bus, int nvectors);
+/* Get the config_len field of the plugged device. */
+size_t virtio_device_get_config_len(VirtioBusState *bus);
+
+#endif /* VIRTIO_BUS_H */
--
1.7.11.7
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [Qemu-devel] [PATCH V2 3/7] virtio-device: refactor virtio-device.
2013-01-09 15:56 [Qemu-devel] [PATCH V2 0/7] Virtio-refactoring part1 fred.konrad
2013-01-09 15:56 ` [Qemu-devel] [PATCH V2 1/7] qdev: add a maximum device allowed field for the bus fred.konrad
2013-01-09 15:56 ` [Qemu-devel] [PATCH V2 2/7] virtio-bus: introduce virtio-bus fred.konrad
@ 2013-01-09 15:56 ` fred.konrad
2013-01-14 19:06 ` Anthony Liguori
2013-01-09 15:56 ` [Qemu-devel] [PATCH V2 4/7] virtio-pci-bus: introduce virtio-pci-bus fred.konrad
` (3 subsequent siblings)
6 siblings, 1 reply; 16+ messages in thread
From: fred.konrad @ 2013-01-09 15:56 UTC (permalink / raw)
To: qemu-devel, aliguori
Cc: kwolf, peter.maydell, e.voevodin, mst, mark.burton, agraf,
amit.shah, aneesh.kumar, stefanha, cornelia.huck, pbonzini,
afaerber, fred.konrad
From: KONRAD Frederic <fred.konrad@greensocs.com>
Create the virtio-device which is abstract. All the virtio-device can extend
this class. It also add some functions to virtio-bus.
Signed-off-by: KONRAD Frederic <fred.konrad@greensocs.com>
---
hw/virtio-bus.c | 35 +++++++++++++++++++++++++++++
hw/virtio-bus.h | 7 ++++++
hw/virtio.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++----------
hw/virtio.h | 30 +++++++++++++++++++++++++
4 files changed, 130 insertions(+), 12 deletions(-)
diff --git a/hw/virtio-bus.c b/hw/virtio-bus.c
index 7813a89..ec43185 100644
--- a/hw/virtio-bus.c
+++ b/hw/virtio-bus.c
@@ -127,6 +127,41 @@ size_t virtio_device_get_config_len(VirtioBusState *bus)
return bus->vdev->config_len;
}
+/* Get the features of the plugged device. */
+uint32_t virtio_device_get_features(VirtioBusState *bus,
+ uint32_t requested_features)
+{
+ VirtioDeviceClass *k;
+ assert(bus->vdev != NULL);
+ k = VIRTIO_DEVICE_GET_CLASS(bus->vdev);
+ assert(k->get_features != NULL);
+ return k->get_features(bus->vdev, requested_features);
+}
+
+/* Get bad features of the plugged device. */
+uint32_t virtio_device_get_bad_features(VirtioBusState *bus)
+{
+ VirtioDeviceClass *k;
+ assert(bus->vdev != NULL);
+ k = VIRTIO_DEVICE_GET_CLASS(bus->vdev);
+ if (k->bad_features != NULL) {
+ return k->bad_features(bus->vdev);
+ } else {
+ return 0;
+ }
+}
+
+/* Get config of the plugged device. */
+void virtio_device_get_config(VirtioBusState *bus, uint8_t *config)
+{
+ VirtioDeviceClass *k;
+ assert(bus->vdev != NULL);
+ k = VIRTIO_DEVICE_GET_CLASS(bus->vdev);
+ if (k->get_config != NULL) {
+ k->get_config(bus->vdev, config);
+ }
+}
+
static const TypeInfo virtio_bus_info = {
.name = TYPE_VIRTIO_BUS,
.parent = TYPE_BUS,
diff --git a/hw/virtio-bus.h b/hw/virtio-bus.h
index 8aa71b2..7bea64a 100644
--- a/hw/virtio-bus.h
+++ b/hw/virtio-bus.h
@@ -87,5 +87,12 @@ int virtio_device_get_nvectors(VirtioBusState *bus);
void virtio_device_set_nvectors(VirtioBusState *bus, int nvectors);
/* Get the config_len field of the plugged device. */
size_t virtio_device_get_config_len(VirtioBusState *bus);
+/* Get the features of the plugged device. */
+uint32_t virtio_device_get_features(VirtioBusState *bus,
+ uint32_t requested_features);
+/* Get bad features of the plugged device. */
+uint32_t virtio_device_get_bad_features(VirtioBusState *bus);
+/* Get config of the plugged device. */
+void virtio_device_get_config(VirtioBusState *bus, uint8_t *config);
#endif /* VIRTIO_BUS_H */
diff --git a/hw/virtio.c b/hw/virtio.c
index 77b53a9..ca170c3 100644
--- a/hw/virtio.c
+++ b/hw/virtio.c
@@ -17,6 +17,7 @@
#include "qemu/error-report.h"
#include "virtio.h"
#include "qemu/atomic.h"
+#include "virtio-bus.h"
/* The alignment to use between consumer and producer parts of vring.
* x86 pagesize again. */
@@ -875,11 +876,16 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
return 0;
}
-void virtio_cleanup(VirtIODevice *vdev)
+void virtio_common_cleanup(VirtIODevice *vdev)
{
qemu_del_vm_change_state_handler(vdev->vmstate);
g_free(vdev->config);
g_free(vdev->vq);
+}
+
+void virtio_cleanup(VirtIODevice *vdev)
+{
+ virtio_common_cleanup(vdev);
g_free(vdev);
}
@@ -902,14 +908,10 @@ static void virtio_vmstate_change(void *opaque, int running, RunState state)
}
}
-VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
- size_t config_size, size_t struct_size)
+void virtio_init(VirtIODevice *vdev, const char *name,
+ uint16_t device_id, size_t config_size)
{
- VirtIODevice *vdev;
int i;
-
- vdev = g_malloc0(struct_size);
-
vdev->device_id = device_id;
vdev->status = 0;
vdev->isr = 0;
@@ -917,20 +919,28 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
vdev->config_vector = VIRTIO_NO_VECTOR;
vdev->vq = g_malloc0(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX);
vdev->vm_running = runstate_is_running();
- for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
+ for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
vdev->vq[i].vector = VIRTIO_NO_VECTOR;
vdev->vq[i].vdev = vdev;
}
vdev->name = name;
vdev->config_len = config_size;
- if (vdev->config_len)
+ if (vdev->config_len) {
vdev->config = g_malloc0(config_size);
- else
+ } else {
vdev->config = NULL;
+ }
+ vdev->vmstate = qemu_add_vm_change_state_handler(virtio_vmstate_change,
+ vdev);
+}
- vdev->vmstate = qemu_add_vm_change_state_handler(virtio_vmstate_change, vdev);
-
+VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
+ size_t config_size, size_t struct_size)
+{
+ VirtIODevice *vdev;
+ vdev = g_malloc0(struct_size);
+ virtio_init(vdev, name, device_id, config_size);
return vdev;
}
@@ -1056,3 +1066,39 @@ EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq)
{
return &vq->host_notifier;
}
+
+static int virtio_device_init(DeviceState *qdev)
+{
+ VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
+ VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(qdev);
+ assert(k->init != NULL);
+ if (k->init(vdev) < 0) {
+ return -1;
+ }
+ virtio_bus_plug_device(vdev);
+ 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->bus_type = TYPE_VIRTIO_BUS;
+}
+
+static const TypeInfo virtio_device_info = {
+ .name = TYPE_VIRTIO_DEVICE,
+ .parent = TYPE_DEVICE,
+ .instance_size = sizeof(VirtIODevice),
+ .class_init = virtio_device_class_init,
+ .abstract = true,
+ .class_size = sizeof(VirtioDeviceClass),
+};
+
+static void virtio_register_types(void)
+{
+ type_register_static(&virtio_device_info);
+}
+
+type_init(virtio_register_types)
diff --git a/hw/virtio.h b/hw/virtio.h
index 1dec9dc..a321fb2 100644
--- a/hw/virtio.h
+++ b/hw/virtio.h
@@ -108,8 +108,17 @@ typedef struct {
#define VIRTIO_NO_VECTOR 0xffff
+#define TYPE_VIRTIO_DEVICE "virtio-device"
+#define VIRTIO_DEVICE_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(VirtioDeviceClass, obj, TYPE_VIRTIO_DEVICE)
+#define VIRTIO_DEVICE_CLASS(klass) \
+ OBJECT_CLASS_CHECK(VirtioDeviceClass, klass, TYPE_VIRTIO_DEVICE)
+#define VIRTIO_DEVICE(obj) \
+ OBJECT_CHECK(VirtIODevice, (obj), TYPE_VIRTIO_DEVICE)
+
struct VirtIODevice
{
+ DeviceState parent_obj;
const char *name;
uint8_t status;
uint8_t isr;
@@ -119,6 +128,10 @@ struct VirtIODevice
void *config;
uint16_t config_vector;
int nvectors;
+ /*
+ * Function pointers will be removed at the end of the series as they are in
+ * VirtioDeviceClass.
+ */
uint32_t (*get_features)(VirtIODevice *vdev, uint32_t requested_features);
uint32_t (*bad_features)(VirtIODevice *vdev);
void (*set_features)(VirtIODevice *vdev, uint32_t val);
@@ -134,6 +147,23 @@ struct VirtIODevice
VMChangeStateEntry *vmstate;
};
+typedef struct {
+ /* This is what a VirtioDevice must implement */
+ DeviceClass parent;
+ int (*init)(VirtIODevice *vdev);
+ uint32_t (*get_features)(VirtIODevice *vdev, uint32_t requested_features);
+ uint32_t (*bad_features)(VirtIODevice *vdev);
+ void (*set_features)(VirtIODevice *vdev, uint32_t val);
+ void (*get_config)(VirtIODevice *vdev, uint8_t *config);
+ void (*set_config)(VirtIODevice *vdev, const uint8_t *config);
+ void (*reset)(VirtIODevice *vdev);
+ void (*set_status)(VirtIODevice *vdev, uint8_t val);
+} VirtioDeviceClass;
+
+void virtio_init(VirtIODevice *vdev, const char *name,
+ uint16_t device_id, size_t config_size);
+void virtio_common_cleanup(VirtIODevice *vdev);
+
VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
void (*handle_output)(VirtIODevice *,
VirtQueue *));
--
1.7.11.7
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [Qemu-devel] [PATCH V2 3/7] virtio-device: refactor virtio-device.
2013-01-09 15:56 ` [Qemu-devel] [PATCH V2 3/7] virtio-device: refactor virtio-device fred.konrad
@ 2013-01-14 19:06 ` Anthony Liguori
2013-01-14 20:05 ` KONRAD Frédéric
0 siblings, 1 reply; 16+ messages in thread
From: Anthony Liguori @ 2013-01-14 19:06 UTC (permalink / raw)
To: fred.konrad, qemu-devel
Cc: kwolf, peter.maydell, e.voevodin, mst, mark.burton, agraf,
cornelia.huck, aneesh.kumar, stefanha, amit.shah, pbonzini,
afaerber
fred.konrad@greensocs.com writes:
> From: KONRAD Frederic <fred.konrad@greensocs.com>
>
> Create the virtio-device which is abstract. All the virtio-device can extend
> this class. It also add some functions to virtio-bus.
>
> Signed-off-by: KONRAD Frederic <fred.konrad@greensocs.com>
> ---
> hw/virtio-bus.c | 35 +++++++++++++++++++++++++++++
> hw/virtio-bus.h | 7 ++++++
> hw/virtio.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++----------
> hw/virtio.h | 30 +++++++++++++++++++++++++
> 4 files changed, 130 insertions(+), 12 deletions(-)
>
> diff --git a/hw/virtio-bus.c b/hw/virtio-bus.c
> index 7813a89..ec43185 100644
> --- a/hw/virtio-bus.c
> +++ b/hw/virtio-bus.c
> @@ -127,6 +127,41 @@ size_t virtio_device_get_config_len(VirtioBusState *bus)
> return bus->vdev->config_len;
> }
>
> +/* Get the features of the plugged device. */
> +uint32_t virtio_device_get_features(VirtioBusState *bus,
> + uint32_t requested_features)
> +{
> + VirtioDeviceClass *k;
> + assert(bus->vdev != NULL);
> + k = VIRTIO_DEVICE_GET_CLASS(bus->vdev);
> + assert(k->get_features != NULL);
> + return k->get_features(bus->vdev, requested_features);
> +}
> +
> +/* Get bad features of the plugged device. */
> +uint32_t virtio_device_get_bad_features(VirtioBusState *bus)
> +{
> + VirtioDeviceClass *k;
> + assert(bus->vdev != NULL);
> + k = VIRTIO_DEVICE_GET_CLASS(bus->vdev);
> + if (k->bad_features != NULL) {
> + return k->bad_features(bus->vdev);
> + } else {
> + return 0;
> + }
> +}
> +
> +/* Get config of the plugged device. */
> +void virtio_device_get_config(VirtioBusState *bus, uint8_t *config)
> +{
> + VirtioDeviceClass *k;
> + assert(bus->vdev != NULL);
> + k = VIRTIO_DEVICE_GET_CLASS(bus->vdev);
> + if (k->get_config != NULL) {
> + k->get_config(bus->vdev, config);
> + }
> +}
> +
If the prefix is "virtio_device" the first argument should be a
VirtIODevice not a virtio_bus.
You probably should introduce a virtio_bus_get_vdev() and then call
virtio_device(virtio_bus_get_vdev(bus), ...)
Or alternatively, rename these to:
virtio_bus_get_vdev_*
> static const TypeInfo virtio_bus_info = {
> .name = TYPE_VIRTIO_BUS,
> .parent = TYPE_BUS,
> diff --git a/hw/virtio-bus.h b/hw/virtio-bus.h
> index 8aa71b2..7bea64a 100644
> --- a/hw/virtio-bus.h
> +++ b/hw/virtio-bus.h
> @@ -87,5 +87,12 @@ int virtio_device_get_nvectors(VirtioBusState *bus);
> void virtio_device_set_nvectors(VirtioBusState *bus, int nvectors);
> /* Get the config_len field of the plugged device. */
> size_t virtio_device_get_config_len(VirtioBusState *bus);
> +/* Get the features of the plugged device. */
> +uint32_t virtio_device_get_features(VirtioBusState *bus,
> + uint32_t requested_features);
> +/* Get bad features of the plugged device. */
> +uint32_t virtio_device_get_bad_features(VirtioBusState *bus);
> +/* Get config of the plugged device. */
> +void virtio_device_get_config(VirtioBusState *bus, uint8_t *config);
>
> #endif /* VIRTIO_BUS_H */
> diff --git a/hw/virtio.c b/hw/virtio.c
> index 77b53a9..ca170c3 100644
> --- a/hw/virtio.c
> +++ b/hw/virtio.c
> @@ -17,6 +17,7 @@
> #include "qemu/error-report.h"
> #include "virtio.h"
> #include "qemu/atomic.h"
> +#include "virtio-bus.h"
>
> /* The alignment to use between consumer and producer parts of vring.
> * x86 pagesize again. */
> @@ -875,11 +876,16 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
> return 0;
> }
>
> -void virtio_cleanup(VirtIODevice *vdev)
> +void virtio_common_cleanup(VirtIODevice *vdev)
> {
> qemu_del_vm_change_state_handler(vdev->vmstate);
> g_free(vdev->config);
> g_free(vdev->vq);
> +}
> +
> +void virtio_cleanup(VirtIODevice *vdev)
> +{
> + virtio_common_cleanup(vdev);
> g_free(vdev);
> }
>
> @@ -902,14 +908,10 @@ static void virtio_vmstate_change(void *opaque, int running, RunState state)
> }
> }
>
> -VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
> - size_t config_size, size_t struct_size)
> +void virtio_init(VirtIODevice *vdev, const char *name,
> + uint16_t device_id, size_t config_size)
> {
> - VirtIODevice *vdev;
> int i;
> -
> - vdev = g_malloc0(struct_size);
> -
> vdev->device_id = device_id;
> vdev->status = 0;
> vdev->isr = 0;
> @@ -917,20 +919,28 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
> vdev->config_vector = VIRTIO_NO_VECTOR;
> vdev->vq = g_malloc0(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX);
> vdev->vm_running = runstate_is_running();
> - for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
> + for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
> vdev->vq[i].vector = VIRTIO_NO_VECTOR;
> vdev->vq[i].vdev = vdev;
> }
>
> vdev->name = name;
> vdev->config_len = config_size;
> - if (vdev->config_len)
> + if (vdev->config_len) {
> vdev->config = g_malloc0(config_size);
> - else
> + } else {
> vdev->config = NULL;
> + }
> + vdev->vmstate = qemu_add_vm_change_state_handler(virtio_vmstate_change,
> + vdev);
> +}
>
> - vdev->vmstate = qemu_add_vm_change_state_handler(virtio_vmstate_change, vdev);
> -
> +VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
> + size_t config_size, size_t struct_size)
> +{
> + VirtIODevice *vdev;
> + vdev = g_malloc0(struct_size);
> + virtio_init(vdev, name, device_id, config_size);
> return vdev;
> }
>
> @@ -1056,3 +1066,39 @@ EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq)
> {
> return &vq->host_notifier;
> }
> +
> +static int virtio_device_init(DeviceState *qdev)
> +{
> + VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
> + VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(qdev);
> + assert(k->init != NULL);
> + if (k->init(vdev) < 0) {
> + return -1;
> + }
> + virtio_bus_plug_device(vdev);
> + 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->bus_type = TYPE_VIRTIO_BUS;
> +}
> +
> +static const TypeInfo virtio_device_info = {
> + .name = TYPE_VIRTIO_DEVICE,
> + .parent = TYPE_DEVICE,
> + .instance_size = sizeof(VirtIODevice),
> + .class_init = virtio_device_class_init,
> + .abstract = true,
> + .class_size = sizeof(VirtioDeviceClass),
> +};
> +
> +static void virtio_register_types(void)
> +{
> + type_register_static(&virtio_device_info);
> +}
> +
> +type_init(virtio_register_types)
> diff --git a/hw/virtio.h b/hw/virtio.h
> index 1dec9dc..a321fb2 100644
> --- a/hw/virtio.h
> +++ b/hw/virtio.h
> @@ -108,8 +108,17 @@ typedef struct {
>
> #define VIRTIO_NO_VECTOR 0xffff
>
> +#define TYPE_VIRTIO_DEVICE "virtio-device"
> +#define VIRTIO_DEVICE_GET_CLASS(obj) \
> + OBJECT_GET_CLASS(VirtioDeviceClass, obj, TYPE_VIRTIO_DEVICE)
> +#define VIRTIO_DEVICE_CLASS(klass) \
> + OBJECT_CLASS_CHECK(VirtioDeviceClass, klass, TYPE_VIRTIO_DEVICE)
> +#define VIRTIO_DEVICE(obj) \
> + OBJECT_CHECK(VirtIODevice, (obj), TYPE_VIRTIO_DEVICE)
> +
> struct VirtIODevice
> {
> + DeviceState parent_obj;
> const char *name;
> uint8_t status;
> uint8_t isr;
> @@ -119,6 +128,10 @@ struct VirtIODevice
> void *config;
> uint16_t config_vector;
> int nvectors;
> + /*
> + * Function pointers will be removed at the end of the series as they are in
> + * VirtioDeviceClass.
> + */
> uint32_t (*get_features)(VirtIODevice *vdev, uint32_t requested_features);
> uint32_t (*bad_features)(VirtIODevice *vdev);
> void (*set_features)(VirtIODevice *vdev, uint32_t val);
> @@ -134,6 +147,23 @@ struct VirtIODevice
> VMChangeStateEntry *vmstate;
> };
>
> +typedef struct {
It's good form to not make this an anonymous struct.
Regards,
Anthony Liguori
> + /* This is what a VirtioDevice must implement */
> + DeviceClass parent;
> + int (*init)(VirtIODevice *vdev);
> + uint32_t (*get_features)(VirtIODevice *vdev, uint32_t requested_features);
> + uint32_t (*bad_features)(VirtIODevice *vdev);
> + void (*set_features)(VirtIODevice *vdev, uint32_t val);
> + void (*get_config)(VirtIODevice *vdev, uint8_t *config);
> + void (*set_config)(VirtIODevice *vdev, const uint8_t *config);
> + void (*reset)(VirtIODevice *vdev);
> + void (*set_status)(VirtIODevice *vdev, uint8_t val);
> +} VirtioDeviceClass;
> +
> +void virtio_init(VirtIODevice *vdev, const char *name,
> + uint16_t device_id, size_t config_size);
> +void virtio_common_cleanup(VirtIODevice *vdev);
> +
> VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
> void (*handle_output)(VirtIODevice *,
> VirtQueue *));
> --
> 1.7.11.7
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Qemu-devel] [PATCH V2 3/7] virtio-device: refactor virtio-device.
2013-01-14 19:06 ` Anthony Liguori
@ 2013-01-14 20:05 ` KONRAD Frédéric
2013-01-14 20:29 ` Anthony Liguori
0 siblings, 1 reply; 16+ messages in thread
From: KONRAD Frédéric @ 2013-01-14 20:05 UTC (permalink / raw)
To: Anthony Liguori
Cc: kwolf, peter.maydell, e.voevodin, mst, mark.burton, qemu-devel,
agraf, cornelia.huck, aneesh.kumar, stefanha, amit.shah, pbonzini,
afaerber
On 14/01/2013 20:06, Anthony Liguori wrote:
> fred.konrad@greensocs.com writes:
>
>> From: KONRAD Frederic <fred.konrad@greensocs.com>
>>
>> Create the virtio-device which is abstract. All the virtio-device can extend
>> this class. It also add some functions to virtio-bus.
>>
>> Signed-off-by: KONRAD Frederic <fred.konrad@greensocs.com>
>> ---
>> hw/virtio-bus.c | 35 +++++++++++++++++++++++++++++
>> hw/virtio-bus.h | 7 ++++++
>> hw/virtio.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++----------
>> hw/virtio.h | 30 +++++++++++++++++++++++++
>> 4 files changed, 130 insertions(+), 12 deletions(-)
>>
>> diff --git a/hw/virtio-bus.c b/hw/virtio-bus.c
>> index 7813a89..ec43185 100644
>> --- a/hw/virtio-bus.c
>> +++ b/hw/virtio-bus.c
>> @@ -127,6 +127,41 @@ size_t virtio_device_get_config_len(VirtioBusState *bus)
>> return bus->vdev->config_len;
>> }
>>
>> +/* Get the features of the plugged device. */
>> +uint32_t virtio_device_get_features(VirtioBusState *bus,
>> + uint32_t requested_features)
>> +{
>> + VirtioDeviceClass *k;
>> + assert(bus->vdev != NULL);
>> + k = VIRTIO_DEVICE_GET_CLASS(bus->vdev);
>> + assert(k->get_features != NULL);
>> + return k->get_features(bus->vdev, requested_features);
>> +}
>> +
>> +/* Get bad features of the plugged device. */
>> +uint32_t virtio_device_get_bad_features(VirtioBusState *bus)
>> +{
>> + VirtioDeviceClass *k;
>> + assert(bus->vdev != NULL);
>> + k = VIRTIO_DEVICE_GET_CLASS(bus->vdev);
>> + if (k->bad_features != NULL) {
>> + return k->bad_features(bus->vdev);
>> + } else {
>> + return 0;
>> + }
>> +}
>> +
>> +/* Get config of the plugged device. */
>> +void virtio_device_get_config(VirtioBusState *bus, uint8_t *config)
>> +{
>> + VirtioDeviceClass *k;
>> + assert(bus->vdev != NULL);
>> + k = VIRTIO_DEVICE_GET_CLASS(bus->vdev);
>> + if (k->get_config != NULL) {
>> + k->get_config(bus->vdev, config);
>> + }
>> +}
>> +
> If the prefix is "virtio_device" the first argument should be a
> VirtIODevice not a virtio_bus.
>
> You probably should introduce a virtio_bus_get_vdev() and then call
> virtio_device(virtio_bus_get_vdev(bus), ...)
>
> Or alternatively, rename these to:
>
> virtio_bus_get_vdev_*
You suggest prefix this function with virtio_device last time.
But I can remove this function and use
virtio_device(virtio_bus_get_vdev(...))
>
>> static const TypeInfo virtio_bus_info = {
>> .name = TYPE_VIRTIO_BUS,
>> .parent = TYPE_BUS,
>> diff --git a/hw/virtio-bus.h b/hw/virtio-bus.h
>> index 8aa71b2..7bea64a 100644
>> --- a/hw/virtio-bus.h
>> +++ b/hw/virtio-bus.h
>> @@ -87,5 +87,12 @@ int virtio_device_get_nvectors(VirtioBusState *bus);
>> void virtio_device_set_nvectors(VirtioBusState *bus, int nvectors);
>> /* Get the config_len field of the plugged device. */
>> size_t virtio_device_get_config_len(VirtioBusState *bus);
>> +/* Get the features of the plugged device. */
>> +uint32_t virtio_device_get_features(VirtioBusState *bus,
>> + uint32_t requested_features);
>> +/* Get bad features of the plugged device. */
>> +uint32_t virtio_device_get_bad_features(VirtioBusState *bus);
>> +/* Get config of the plugged device. */
>> +void virtio_device_get_config(VirtioBusState *bus, uint8_t *config);
>>
>> #endif /* VIRTIO_BUS_H */
>> diff --git a/hw/virtio.c b/hw/virtio.c
>> index 77b53a9..ca170c3 100644
>> --- a/hw/virtio.c
>> +++ b/hw/virtio.c
>> @@ -17,6 +17,7 @@
>> #include "qemu/error-report.h"
>> #include "virtio.h"
>> #include "qemu/atomic.h"
>> +#include "virtio-bus.h"
>>
>> /* The alignment to use between consumer and producer parts of vring.
>> * x86 pagesize again. */
>> @@ -875,11 +876,16 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
>> return 0;
>> }
>>
>> -void virtio_cleanup(VirtIODevice *vdev)
>> +void virtio_common_cleanup(VirtIODevice *vdev)
>> {
>> qemu_del_vm_change_state_handler(vdev->vmstate);
>> g_free(vdev->config);
>> g_free(vdev->vq);
>> +}
>> +
>> +void virtio_cleanup(VirtIODevice *vdev)
>> +{
>> + virtio_common_cleanup(vdev);
>> g_free(vdev);
>> }
>>
>> @@ -902,14 +908,10 @@ static void virtio_vmstate_change(void *opaque, int running, RunState state)
>> }
>> }
>>
>> -VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
>> - size_t config_size, size_t struct_size)
>> +void virtio_init(VirtIODevice *vdev, const char *name,
>> + uint16_t device_id, size_t config_size)
>> {
>> - VirtIODevice *vdev;
>> int i;
>> -
>> - vdev = g_malloc0(struct_size);
>> -
>> vdev->device_id = device_id;
>> vdev->status = 0;
>> vdev->isr = 0;
>> @@ -917,20 +919,28 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
>> vdev->config_vector = VIRTIO_NO_VECTOR;
>> vdev->vq = g_malloc0(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX);
>> vdev->vm_running = runstate_is_running();
>> - for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
>> + for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
>> vdev->vq[i].vector = VIRTIO_NO_VECTOR;
>> vdev->vq[i].vdev = vdev;
>> }
>>
>> vdev->name = name;
>> vdev->config_len = config_size;
>> - if (vdev->config_len)
>> + if (vdev->config_len) {
>> vdev->config = g_malloc0(config_size);
>> - else
>> + } else {
>> vdev->config = NULL;
>> + }
>> + vdev->vmstate = qemu_add_vm_change_state_handler(virtio_vmstate_change,
>> + vdev);
>> +}
>>
>> - vdev->vmstate = qemu_add_vm_change_state_handler(virtio_vmstate_change, vdev);
>> -
>> +VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
>> + size_t config_size, size_t struct_size)
>> +{
>> + VirtIODevice *vdev;
>> + vdev = g_malloc0(struct_size);
>> + virtio_init(vdev, name, device_id, config_size);
>> return vdev;
>> }
>>
>> @@ -1056,3 +1066,39 @@ EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq)
>> {
>> return &vq->host_notifier;
>> }
>> +
>> +static int virtio_device_init(DeviceState *qdev)
>> +{
>> + VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
>> + VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(qdev);
>> + assert(k->init != NULL);
>> + if (k->init(vdev) < 0) {
>> + return -1;
>> + }
>> + virtio_bus_plug_device(vdev);
>> + 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->bus_type = TYPE_VIRTIO_BUS;
>> +}
>> +
>> +static const TypeInfo virtio_device_info = {
>> + .name = TYPE_VIRTIO_DEVICE,
>> + .parent = TYPE_DEVICE,
>> + .instance_size = sizeof(VirtIODevice),
>> + .class_init = virtio_device_class_init,
>> + .abstract = true,
>> + .class_size = sizeof(VirtioDeviceClass),
>> +};
>> +
>> +static void virtio_register_types(void)
>> +{
>> + type_register_static(&virtio_device_info);
>> +}
>> +
>> +type_init(virtio_register_types)
>> diff --git a/hw/virtio.h b/hw/virtio.h
>> index 1dec9dc..a321fb2 100644
>> --- a/hw/virtio.h
>> +++ b/hw/virtio.h
>> @@ -108,8 +108,17 @@ typedef struct {
>>
>> #define VIRTIO_NO_VECTOR 0xffff
>>
>> +#define TYPE_VIRTIO_DEVICE "virtio-device"
>> +#define VIRTIO_DEVICE_GET_CLASS(obj) \
>> + OBJECT_GET_CLASS(VirtioDeviceClass, obj, TYPE_VIRTIO_DEVICE)
>> +#define VIRTIO_DEVICE_CLASS(klass) \
>> + OBJECT_CLASS_CHECK(VirtioDeviceClass, klass, TYPE_VIRTIO_DEVICE)
>> +#define VIRTIO_DEVICE(obj) \
>> + OBJECT_CHECK(VirtIODevice, (obj), TYPE_VIRTIO_DEVICE)
>> +
>> struct VirtIODevice
>> {
>> + DeviceState parent_obj;
>> const char *name;
>> uint8_t status;
>> uint8_t isr;
>> @@ -119,6 +128,10 @@ struct VirtIODevice
>> void *config;
>> uint16_t config_vector;
>> int nvectors;
>> + /*
>> + * Function pointers will be removed at the end of the series as they are in
>> + * VirtioDeviceClass.
>> + */
>> uint32_t (*get_features)(VirtIODevice *vdev, uint32_t requested_features);
>> uint32_t (*bad_features)(VirtIODevice *vdev);
>> void (*set_features)(VirtIODevice *vdev, uint32_t val);
>> @@ -134,6 +147,23 @@ struct VirtIODevice
>> VMChangeStateEntry *vmstate;
>> };
>>
>> +typedef struct {
> It's good form to not make this an anonymous struct.
>
> Regards,
>
> Anthony Liguori
>
>> + /* This is what a VirtioDevice must implement */
>> + DeviceClass parent;
>> + int (*init)(VirtIODevice *vdev);
>> + uint32_t (*get_features)(VirtIODevice *vdev, uint32_t requested_features);
>> + uint32_t (*bad_features)(VirtIODevice *vdev);
>> + void (*set_features)(VirtIODevice *vdev, uint32_t val);
>> + void (*get_config)(VirtIODevice *vdev, uint8_t *config);
>> + void (*set_config)(VirtIODevice *vdev, const uint8_t *config);
>> + void (*reset)(VirtIODevice *vdev);
>> + void (*set_status)(VirtIODevice *vdev, uint8_t val);
>> +} VirtioDeviceClass;
>> +
>> +void virtio_init(VirtIODevice *vdev, const char *name,
>> + uint16_t device_id, size_t config_size);
>> +void virtio_common_cleanup(VirtIODevice *vdev);
>> +
>> VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
>> void (*handle_output)(VirtIODevice *,
>> VirtQueue *));
>> --
>> 1.7.11.7
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Qemu-devel] [PATCH V2 3/7] virtio-device: refactor virtio-device.
2013-01-14 20:05 ` KONRAD Frédéric
@ 2013-01-14 20:29 ` Anthony Liguori
0 siblings, 0 replies; 16+ messages in thread
From: Anthony Liguori @ 2013-01-14 20:29 UTC (permalink / raw)
To: KONRAD Frédéric
Cc: kwolf, peter.maydell, e.voevodin, mst, mark.burton, qemu-devel,
agraf, cornelia.huck, aneesh.kumar, stefanha, amit.shah, pbonzini,
afaerber
KONRAD Frédéric <fred.konrad@greensocs.com> writes:
> On 14/01/2013 20:06, Anthony Liguori wrote:
>> fred.konrad@greensocs.com writes:
>>
>>> From: KONRAD Frederic <fred.konrad@greensocs.com>
>>>
>>> Create the virtio-device which is abstract. All the virtio-device can extend
>>> this class. It also add some functions to virtio-bus.
>>>
>>> Signed-off-by: KONRAD Frederic <fred.konrad@greensocs.com>
>>> ---
>>> hw/virtio-bus.c | 35 +++++++++++++++++++++++++++++
>>> hw/virtio-bus.h | 7 ++++++
>>> hw/virtio.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++----------
>>> hw/virtio.h | 30 +++++++++++++++++++++++++
>>> 4 files changed, 130 insertions(+), 12 deletions(-)
>>>
>>> diff --git a/hw/virtio-bus.c b/hw/virtio-bus.c
>>> index 7813a89..ec43185 100644
>>> --- a/hw/virtio-bus.c
>>> +++ b/hw/virtio-bus.c
>>> @@ -127,6 +127,41 @@ size_t virtio_device_get_config_len(VirtioBusState *bus)
>>> return bus->vdev->config_len;
>>> }
>>>
>>> +/* Get the features of the plugged device. */
>>> +uint32_t virtio_device_get_features(VirtioBusState *bus,
>>> + uint32_t requested_features)
>>> +{
>>> + VirtioDeviceClass *k;
>>> + assert(bus->vdev != NULL);
>>> + k = VIRTIO_DEVICE_GET_CLASS(bus->vdev);
>>> + assert(k->get_features != NULL);
>>> + return k->get_features(bus->vdev, requested_features);
>>> +}
>>> +
>>> +/* Get bad features of the plugged device. */
>>> +uint32_t virtio_device_get_bad_features(VirtioBusState *bus)
>>> +{
>>> + VirtioDeviceClass *k;
>>> + assert(bus->vdev != NULL);
>>> + k = VIRTIO_DEVICE_GET_CLASS(bus->vdev);
>>> + if (k->bad_features != NULL) {
>>> + return k->bad_features(bus->vdev);
>>> + } else {
>>> + return 0;
>>> + }
>>> +}
>>> +
>>> +/* Get config of the plugged device. */
>>> +void virtio_device_get_config(VirtioBusState *bus, uint8_t *config)
>>> +{
>>> + VirtioDeviceClass *k;
>>> + assert(bus->vdev != NULL);
>>> + k = VIRTIO_DEVICE_GET_CLASS(bus->vdev);
>>> + if (k->get_config != NULL) {
>>> + k->get_config(bus->vdev, config);
>>> + }
>>> +}
>>> +
>> If the prefix is "virtio_device" the first argument should be a
>> VirtIODevice not a virtio_bus.
>>
>> You probably should introduce a virtio_bus_get_vdev() and then call
>> virtio_device(virtio_bus_get_vdev(bus), ...)
>>
>> Or alternatively, rename these to:
>>
>> virtio_bus_get_vdev_*
> You suggest prefix this function with virtio_device last time.
Can you refer me to the mail? I searched and I can't find it...
Regards,
Anthony Liguori
>
> But I can remove this function and use
> virtio_device(virtio_bus_get_vdev(...))
>>
>>> static const TypeInfo virtio_bus_info = {
>>> .name = TYPE_VIRTIO_BUS,
>>> .parent = TYPE_BUS,
>>> diff --git a/hw/virtio-bus.h b/hw/virtio-bus.h
>>> index 8aa71b2..7bea64a 100644
>>> --- a/hw/virtio-bus.h
>>> +++ b/hw/virtio-bus.h
>>> @@ -87,5 +87,12 @@ int virtio_device_get_nvectors(VirtioBusState *bus);
>>> void virtio_device_set_nvectors(VirtioBusState *bus, int nvectors);
>>> /* Get the config_len field of the plugged device. */
>>> size_t virtio_device_get_config_len(VirtioBusState *bus);
>>> +/* Get the features of the plugged device. */
>>> +uint32_t virtio_device_get_features(VirtioBusState *bus,
>>> + uint32_t requested_features);
>>> +/* Get bad features of the plugged device. */
>>> +uint32_t virtio_device_get_bad_features(VirtioBusState *bus);
>>> +/* Get config of the plugged device. */
>>> +void virtio_device_get_config(VirtioBusState *bus, uint8_t *config);
>>>
>>> #endif /* VIRTIO_BUS_H */
>>> diff --git a/hw/virtio.c b/hw/virtio.c
>>> index 77b53a9..ca170c3 100644
>>> --- a/hw/virtio.c
>>> +++ b/hw/virtio.c
>>> @@ -17,6 +17,7 @@
>>> #include "qemu/error-report.h"
>>> #include "virtio.h"
>>> #include "qemu/atomic.h"
>>> +#include "virtio-bus.h"
>>>
>>> /* The alignment to use between consumer and producer parts of vring.
>>> * x86 pagesize again. */
>>> @@ -875,11 +876,16 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
>>> return 0;
>>> }
>>>
>>> -void virtio_cleanup(VirtIODevice *vdev)
>>> +void virtio_common_cleanup(VirtIODevice *vdev)
>>> {
>>> qemu_del_vm_change_state_handler(vdev->vmstate);
>>> g_free(vdev->config);
>>> g_free(vdev->vq);
>>> +}
>>> +
>>> +void virtio_cleanup(VirtIODevice *vdev)
>>> +{
>>> + virtio_common_cleanup(vdev);
>>> g_free(vdev);
>>> }
>>>
>>> @@ -902,14 +908,10 @@ static void virtio_vmstate_change(void *opaque, int running, RunState state)
>>> }
>>> }
>>>
>>> -VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
>>> - size_t config_size, size_t struct_size)
>>> +void virtio_init(VirtIODevice *vdev, const char *name,
>>> + uint16_t device_id, size_t config_size)
>>> {
>>> - VirtIODevice *vdev;
>>> int i;
>>> -
>>> - vdev = g_malloc0(struct_size);
>>> -
>>> vdev->device_id = device_id;
>>> vdev->status = 0;
>>> vdev->isr = 0;
>>> @@ -917,20 +919,28 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
>>> vdev->config_vector = VIRTIO_NO_VECTOR;
>>> vdev->vq = g_malloc0(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX);
>>> vdev->vm_running = runstate_is_running();
>>> - for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
>>> + for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
>>> vdev->vq[i].vector = VIRTIO_NO_VECTOR;
>>> vdev->vq[i].vdev = vdev;
>>> }
>>>
>>> vdev->name = name;
>>> vdev->config_len = config_size;
>>> - if (vdev->config_len)
>>> + if (vdev->config_len) {
>>> vdev->config = g_malloc0(config_size);
>>> - else
>>> + } else {
>>> vdev->config = NULL;
>>> + }
>>> + vdev->vmstate = qemu_add_vm_change_state_handler(virtio_vmstate_change,
>>> + vdev);
>>> +}
>>>
>>> - vdev->vmstate = qemu_add_vm_change_state_handler(virtio_vmstate_change, vdev);
>>> -
>>> +VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
>>> + size_t config_size, size_t struct_size)
>>> +{
>>> + VirtIODevice *vdev;
>>> + vdev = g_malloc0(struct_size);
>>> + virtio_init(vdev, name, device_id, config_size);
>>> return vdev;
>>> }
>>>
>>> @@ -1056,3 +1066,39 @@ EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq)
>>> {
>>> return &vq->host_notifier;
>>> }
>>> +
>>> +static int virtio_device_init(DeviceState *qdev)
>>> +{
>>> + VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
>>> + VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(qdev);
>>> + assert(k->init != NULL);
>>> + if (k->init(vdev) < 0) {
>>> + return -1;
>>> + }
>>> + virtio_bus_plug_device(vdev);
>>> + 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->bus_type = TYPE_VIRTIO_BUS;
>>> +}
>>> +
>>> +static const TypeInfo virtio_device_info = {
>>> + .name = TYPE_VIRTIO_DEVICE,
>>> + .parent = TYPE_DEVICE,
>>> + .instance_size = sizeof(VirtIODevice),
>>> + .class_init = virtio_device_class_init,
>>> + .abstract = true,
>>> + .class_size = sizeof(VirtioDeviceClass),
>>> +};
>>> +
>>> +static void virtio_register_types(void)
>>> +{
>>> + type_register_static(&virtio_device_info);
>>> +}
>>> +
>>> +type_init(virtio_register_types)
>>> diff --git a/hw/virtio.h b/hw/virtio.h
>>> index 1dec9dc..a321fb2 100644
>>> --- a/hw/virtio.h
>>> +++ b/hw/virtio.h
>>> @@ -108,8 +108,17 @@ typedef struct {
>>>
>>> #define VIRTIO_NO_VECTOR 0xffff
>>>
>>> +#define TYPE_VIRTIO_DEVICE "virtio-device"
>>> +#define VIRTIO_DEVICE_GET_CLASS(obj) \
>>> + OBJECT_GET_CLASS(VirtioDeviceClass, obj, TYPE_VIRTIO_DEVICE)
>>> +#define VIRTIO_DEVICE_CLASS(klass) \
>>> + OBJECT_CLASS_CHECK(VirtioDeviceClass, klass, TYPE_VIRTIO_DEVICE)
>>> +#define VIRTIO_DEVICE(obj) \
>>> + OBJECT_CHECK(VirtIODevice, (obj), TYPE_VIRTIO_DEVICE)
>>> +
>>> struct VirtIODevice
>>> {
>>> + DeviceState parent_obj;
>>> const char *name;
>>> uint8_t status;
>>> uint8_t isr;
>>> @@ -119,6 +128,10 @@ struct VirtIODevice
>>> void *config;
>>> uint16_t config_vector;
>>> int nvectors;
>>> + /*
>>> + * Function pointers will be removed at the end of the series as they are in
>>> + * VirtioDeviceClass.
>>> + */
>>> uint32_t (*get_features)(VirtIODevice *vdev, uint32_t requested_features);
>>> uint32_t (*bad_features)(VirtIODevice *vdev);
>>> void (*set_features)(VirtIODevice *vdev, uint32_t val);
>>> @@ -134,6 +147,23 @@ struct VirtIODevice
>>> VMChangeStateEntry *vmstate;
>>> };
>>>
>>> +typedef struct {
>> It's good form to not make this an anonymous struct.
>>
>> Regards,
>>
>> Anthony Liguori
>>
>>> + /* This is what a VirtioDevice must implement */
>>> + DeviceClass parent;
>>> + int (*init)(VirtIODevice *vdev);
>>> + uint32_t (*get_features)(VirtIODevice *vdev, uint32_t requested_features);
>>> + uint32_t (*bad_features)(VirtIODevice *vdev);
>>> + void (*set_features)(VirtIODevice *vdev, uint32_t val);
>>> + void (*get_config)(VirtIODevice *vdev, uint8_t *config);
>>> + void (*set_config)(VirtIODevice *vdev, const uint8_t *config);
>>> + void (*reset)(VirtIODevice *vdev);
>>> + void (*set_status)(VirtIODevice *vdev, uint8_t val);
>>> +} VirtioDeviceClass;
>>> +
>>> +void virtio_init(VirtIODevice *vdev, const char *name,
>>> + uint16_t device_id, size_t config_size);
>>> +void virtio_common_cleanup(VirtIODevice *vdev);
>>> +
>>> VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
>>> void (*handle_output)(VirtIODevice *,
>>> VirtQueue *));
>>> --
>>> 1.7.11.7
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Qemu-devel] [PATCH V2 4/7] virtio-pci-bus: introduce virtio-pci-bus.
2013-01-09 15:56 [Qemu-devel] [PATCH V2 0/7] Virtio-refactoring part1 fred.konrad
` (2 preceding siblings ...)
2013-01-09 15:56 ` [Qemu-devel] [PATCH V2 3/7] virtio-device: refactor virtio-device fred.konrad
@ 2013-01-09 15:56 ` fred.konrad
2013-01-14 19:08 ` Anthony Liguori
2013-01-09 15:56 ` [Qemu-devel] [PATCH V2 5/7] virtio-pci: refactor virtio-pci device fred.konrad
` (2 subsequent siblings)
6 siblings, 1 reply; 16+ messages in thread
From: fred.konrad @ 2013-01-09 15:56 UTC (permalink / raw)
To: qemu-devel, aliguori
Cc: kwolf, peter.maydell, e.voevodin, mst, mark.burton, agraf,
amit.shah, aneesh.kumar, stefanha, cornelia.huck, pbonzini,
afaerber, fred.konrad
From: KONRAD Frederic <fred.konrad@greensocs.com>
Introduce virtio-pci-bus, which extends virtio-bus. It is used with virtio-pci
transport device.
Signed-off-by: KONRAD Frederic <fred.konrad@greensocs.com>
---
hw/virtio-pci.c | 37 +++++++++++++++++++++++++++++++++++++
hw/virtio-pci.h | 23 +++++++++++++++++++++--
2 files changed, 58 insertions(+), 2 deletions(-)
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index c7f0c4d..090dc41 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -31,6 +31,7 @@
#include "sysemu/blockdev.h"
#include "virtio-pci.h"
#include "qemu/range.h"
+#include "virtio-bus.h"
/* from Linux's linux/virtio_pci.h */
@@ -1162,6 +1163,41 @@ static TypeInfo virtio_scsi_info = {
.class_init = virtio_scsi_class_init,
};
+/* virtio-pci-bus */
+
+VirtioBusState *virtio_pci_bus_new(VirtIOPCIProxy *dev)
+{
+ DeviceState *qdev = DEVICE(dev);
+ BusState *qbus = qbus_create(TYPE_VIRTIO_PCI_BUS, qdev, NULL);
+ VirtioBusState *bus = VIRTIO_BUS(qbus);
+ qbus->allow_hotplug = 0;
+ return bus;
+}
+
+static void virtio_pci_bus_class_init(ObjectClass *klass, void *data)
+{
+ BusClass *bus_class = BUS_CLASS(klass);
+ VirtioBusClass *k = VIRTIO_BUS_CLASS(klass);
+ bus_class->max_dev = 1;
+ k->notify = virtio_pci_notify;
+ k->save_config = virtio_pci_save_config;
+ k->load_config = virtio_pci_load_config;
+ k->save_queue = virtio_pci_save_queue;
+ k->load_queue = virtio_pci_load_queue;
+ k->get_features = virtio_pci_get_features;
+ k->query_guest_notifiers = virtio_pci_query_guest_notifiers;
+ k->set_host_notifier = virtio_pci_set_host_notifier;
+ k->set_guest_notifiers = virtio_pci_set_guest_notifiers;
+ k->vmstate_change = virtio_pci_vmstate_change;
+}
+
+static const TypeInfo virtio_pci_bus_info = {
+ .name = TYPE_VIRTIO_PCI_BUS,
+ .parent = TYPE_VIRTIO_BUS,
+ .instance_size = sizeof(VirtioPCIBusState),
+ .class_init = virtio_pci_bus_class_init,
+};
+
static void virtio_pci_register_types(void)
{
type_register_static(&virtio_blk_info);
@@ -1170,6 +1206,7 @@ static void virtio_pci_register_types(void)
type_register_static(&virtio_balloon_info);
type_register_static(&virtio_scsi_info);
type_register_static(&virtio_rng_info);
+ type_register_static(&virtio_pci_bus_info);
}
type_init(virtio_pci_register_types)
diff --git a/hw/virtio-pci.h b/hw/virtio-pci.h
index b58d9a2..ed0097f 100644
--- a/hw/virtio-pci.h
+++ b/hw/virtio-pci.h
@@ -20,6 +20,25 @@
#include "virtio-rng.h"
#include "virtio-serial.h"
#include "virtio-scsi.h"
+#include "virtio-bus.h"
+
+typedef struct VirtIOPCIProxy VirtIOPCIProxy;
+
+/* virtio-pci-bus */
+
+typedef struct VirtioBusState VirtioPCIBusState;
+typedef struct VirtioBusClass VirtioPCIBusClass;
+
+#define TYPE_VIRTIO_PCI_BUS "virtio-pci-bus"
+#define VIRTIO_PCI_BUS(obj) \
+ OBJECT_CHECK(VirtioPCIBusState, (obj), TYPE_VIRTIO_PCI_BUS)
+#define VIRTIO_PCI_BUS_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(VirtioPCIBusClass, obj, TYPE_VIRTIO_PCI_BUS)
+#define VIRTIO_PCI_BUS_CLASS(klass) \
+ OBJECT_CLASS_CHECK(VirtioPCIBusClass, klass, TYPE_VIRTIO_PCI_BUS)
+
+
+VirtioBusState *virtio_pci_bus_new(VirtIOPCIProxy *dev);
/* Performance improves when virtqueue kick processing is decoupled from the
* vcpu thread using ioeventfd for some devices. */
@@ -31,7 +50,7 @@ typedef struct {
unsigned int users;
} VirtIOIRQFD;
-typedef struct {
+struct VirtIOPCIProxy {
PCIDevice pci_dev;
VirtIODevice *vdev;
MemoryRegion bar;
@@ -51,7 +70,7 @@ typedef struct {
bool ioeventfd_disabled;
bool ioeventfd_started;
VirtIOIRQFD *vector_irqfd;
-} VirtIOPCIProxy;
+};
void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev);
void virtio_pci_reset(DeviceState *d);
--
1.7.11.7
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [Qemu-devel] [PATCH V2 4/7] virtio-pci-bus: introduce virtio-pci-bus.
2013-01-09 15:56 ` [Qemu-devel] [PATCH V2 4/7] virtio-pci-bus: introduce virtio-pci-bus fred.konrad
@ 2013-01-14 19:08 ` Anthony Liguori
2013-01-14 20:36 ` KONRAD Frédéric
0 siblings, 1 reply; 16+ messages in thread
From: Anthony Liguori @ 2013-01-14 19:08 UTC (permalink / raw)
To: fred.konrad, qemu-devel
Cc: kwolf, peter.maydell, e.voevodin, mst, mark.burton, agraf,
amit.shah, aneesh.kumar, stefanha, cornelia.huck, pbonzini,
afaerber
fred.konrad@greensocs.com writes:
> From: KONRAD Frederic <fred.konrad@greensocs.com>
>
> Introduce virtio-pci-bus, which extends virtio-bus. It is used with virtio-pci
> transport device.
>
> Signed-off-by: KONRAD Frederic <fred.konrad@greensocs.com>
> ---
> hw/virtio-pci.c | 37 +++++++++++++++++++++++++++++++++++++
> hw/virtio-pci.h | 23 +++++++++++++++++++++--
> 2 files changed, 58 insertions(+), 2 deletions(-)
>
> diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
> index c7f0c4d..090dc41 100644
> --- a/hw/virtio-pci.c
> +++ b/hw/virtio-pci.c
> @@ -31,6 +31,7 @@
> #include "sysemu/blockdev.h"
> #include "virtio-pci.h"
> #include "qemu/range.h"
> +#include "virtio-bus.h"
>
> /* from Linux's linux/virtio_pci.h */
>
> @@ -1162,6 +1163,41 @@ static TypeInfo virtio_scsi_info = {
> .class_init = virtio_scsi_class_init,
> };
>
> +/* virtio-pci-bus */
> +
> +VirtioBusState *virtio_pci_bus_new(VirtIOPCIProxy *dev)
> +{
> + DeviceState *qdev = DEVICE(dev);
> + BusState *qbus = qbus_create(TYPE_VIRTIO_PCI_BUS, qdev, NULL);
> + VirtioBusState *bus = VIRTIO_BUS(qbus);
> + qbus->allow_hotplug = 0;
Any reason to not use a qbus_create_inplace()?
Regards,
Anthony Liguori
> + return bus;
> +}
> +
> +static void virtio_pci_bus_class_init(ObjectClass *klass, void *data)
> +{
> + BusClass *bus_class = BUS_CLASS(klass);
> + VirtioBusClass *k = VIRTIO_BUS_CLASS(klass);
> + bus_class->max_dev = 1;
> + k->notify = virtio_pci_notify;
> + k->save_config = virtio_pci_save_config;
> + k->load_config = virtio_pci_load_config;
> + k->save_queue = virtio_pci_save_queue;
> + k->load_queue = virtio_pci_load_queue;
> + k->get_features = virtio_pci_get_features;
> + k->query_guest_notifiers = virtio_pci_query_guest_notifiers;
> + k->set_host_notifier = virtio_pci_set_host_notifier;
> + k->set_guest_notifiers = virtio_pci_set_guest_notifiers;
> + k->vmstate_change = virtio_pci_vmstate_change;
> +}
> +
> +static const TypeInfo virtio_pci_bus_info = {
> + .name = TYPE_VIRTIO_PCI_BUS,
> + .parent = TYPE_VIRTIO_BUS,
> + .instance_size = sizeof(VirtioPCIBusState),
> + .class_init = virtio_pci_bus_class_init,
> +};
> +
> static void virtio_pci_register_types(void)
> {
> type_register_static(&virtio_blk_info);
> @@ -1170,6 +1206,7 @@ static void virtio_pci_register_types(void)
> type_register_static(&virtio_balloon_info);
> type_register_static(&virtio_scsi_info);
> type_register_static(&virtio_rng_info);
> + type_register_static(&virtio_pci_bus_info);
> }
>
> type_init(virtio_pci_register_types)
> diff --git a/hw/virtio-pci.h b/hw/virtio-pci.h
> index b58d9a2..ed0097f 100644
> --- a/hw/virtio-pci.h
> +++ b/hw/virtio-pci.h
> @@ -20,6 +20,25 @@
> #include "virtio-rng.h"
> #include "virtio-serial.h"
> #include "virtio-scsi.h"
> +#include "virtio-bus.h"
> +
> +typedef struct VirtIOPCIProxy VirtIOPCIProxy;
> +
> +/* virtio-pci-bus */
> +
> +typedef struct VirtioBusState VirtioPCIBusState;
> +typedef struct VirtioBusClass VirtioPCIBusClass;
> +
> +#define TYPE_VIRTIO_PCI_BUS "virtio-pci-bus"
> +#define VIRTIO_PCI_BUS(obj) \
> + OBJECT_CHECK(VirtioPCIBusState, (obj), TYPE_VIRTIO_PCI_BUS)
> +#define VIRTIO_PCI_BUS_GET_CLASS(obj) \
> + OBJECT_GET_CLASS(VirtioPCIBusClass, obj, TYPE_VIRTIO_PCI_BUS)
> +#define VIRTIO_PCI_BUS_CLASS(klass) \
> + OBJECT_CLASS_CHECK(VirtioPCIBusClass, klass, TYPE_VIRTIO_PCI_BUS)
> +
> +
> +VirtioBusState *virtio_pci_bus_new(VirtIOPCIProxy *dev);
>
> /* Performance improves when virtqueue kick processing is decoupled from the
> * vcpu thread using ioeventfd for some devices. */
> @@ -31,7 +50,7 @@ typedef struct {
> unsigned int users;
> } VirtIOIRQFD;
>
> -typedef struct {
> +struct VirtIOPCIProxy {
> PCIDevice pci_dev;
> VirtIODevice *vdev;
> MemoryRegion bar;
> @@ -51,7 +70,7 @@ typedef struct {
> bool ioeventfd_disabled;
> bool ioeventfd_started;
> VirtIOIRQFD *vector_irqfd;
> -} VirtIOPCIProxy;
> +};
>
> void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev);
> void virtio_pci_reset(DeviceState *d);
> --
> 1.7.11.7
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Qemu-devel] [PATCH V2 4/7] virtio-pci-bus: introduce virtio-pci-bus.
2013-01-14 19:08 ` Anthony Liguori
@ 2013-01-14 20:36 ` KONRAD Frédéric
2013-01-14 21:39 ` Andreas Färber
0 siblings, 1 reply; 16+ messages in thread
From: KONRAD Frédéric @ 2013-01-14 20:36 UTC (permalink / raw)
To: Anthony Liguori
Cc: kwolf, peter.maydell, e.voevodin, mst, mark.burton, qemu-devel,
agraf, amit.shah, aneesh.kumar, stefanha, cornelia.huck, pbonzini,
afaerber
On 14/01/2013 20:08, Anthony Liguori wrote:
> fred.konrad@greensocs.com writes:
>
>> From: KONRAD Frederic <fred.konrad@greensocs.com>
>>
>> Introduce virtio-pci-bus, which extends virtio-bus. It is used with virtio-pci
>> transport device.
>>
>> Signed-off-by: KONRAD Frederic <fred.konrad@greensocs.com>
>> ---
>> hw/virtio-pci.c | 37 +++++++++++++++++++++++++++++++++++++
>> hw/virtio-pci.h | 23 +++++++++++++++++++++--
>> 2 files changed, 58 insertions(+), 2 deletions(-)
>>
>> diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
>> index c7f0c4d..090dc41 100644
>> --- a/hw/virtio-pci.c
>> +++ b/hw/virtio-pci.c
>> @@ -31,6 +31,7 @@
>> #include "sysemu/blockdev.h"
>> #include "virtio-pci.h"
>> #include "qemu/range.h"
>> +#include "virtio-bus.h"
>>
>> /* from Linux's linux/virtio_pci.h */
>>
>> @@ -1162,6 +1163,41 @@ static TypeInfo virtio_scsi_info = {
>> .class_init = virtio_scsi_class_init,
>> };
>>
>> +/* virtio-pci-bus */
>> +
>> +VirtioBusState *virtio_pci_bus_new(VirtIOPCIProxy *dev)
>> +{
>> + DeviceState *qdev = DEVICE(dev);
>> + BusState *qbus = qbus_create(TYPE_VIRTIO_PCI_BUS, qdev, NULL);
>> + VirtioBusState *bus = VIRTIO_BUS(qbus);
>> + qbus->allow_hotplug = 0;
> Any reason to not use a qbus_create_inplace()?
>
> Regards,
>
> Anthony Liguori
If I change the bus field of VirtIOPCIProxy from VirtioBus* to VirtioBus
and I use qbus_create_inplace
I can't use qbus_create_inplace(BUS(&dev->bus),...) as the object is not
initialised yet right?
>
>> + return bus;
>> +}
>> +
>> +static void virtio_pci_bus_class_init(ObjectClass *klass, void *data)
>> +{
>> + BusClass *bus_class = BUS_CLASS(klass);
>> + VirtioBusClass *k = VIRTIO_BUS_CLASS(klass);
>> + bus_class->max_dev = 1;
>> + k->notify = virtio_pci_notify;
>> + k->save_config = virtio_pci_save_config;
>> + k->load_config = virtio_pci_load_config;
>> + k->save_queue = virtio_pci_save_queue;
>> + k->load_queue = virtio_pci_load_queue;
>> + k->get_features = virtio_pci_get_features;
>> + k->query_guest_notifiers = virtio_pci_query_guest_notifiers;
>> + k->set_host_notifier = virtio_pci_set_host_notifier;
>> + k->set_guest_notifiers = virtio_pci_set_guest_notifiers;
>> + k->vmstate_change = virtio_pci_vmstate_change;
>> +}
>> +
>> +static const TypeInfo virtio_pci_bus_info = {
>> + .name = TYPE_VIRTIO_PCI_BUS,
>> + .parent = TYPE_VIRTIO_BUS,
>> + .instance_size = sizeof(VirtioPCIBusState),
>> + .class_init = virtio_pci_bus_class_init,
>> +};
>> +
>> static void virtio_pci_register_types(void)
>> {
>> type_register_static(&virtio_blk_info);
>> @@ -1170,6 +1206,7 @@ static void virtio_pci_register_types(void)
>> type_register_static(&virtio_balloon_info);
>> type_register_static(&virtio_scsi_info);
>> type_register_static(&virtio_rng_info);
>> + type_register_static(&virtio_pci_bus_info);
>> }
>>
>> type_init(virtio_pci_register_types)
>> diff --git a/hw/virtio-pci.h b/hw/virtio-pci.h
>> index b58d9a2..ed0097f 100644
>> --- a/hw/virtio-pci.h
>> +++ b/hw/virtio-pci.h
>> @@ -20,6 +20,25 @@
>> #include "virtio-rng.h"
>> #include "virtio-serial.h"
>> #include "virtio-scsi.h"
>> +#include "virtio-bus.h"
>> +
>> +typedef struct VirtIOPCIProxy VirtIOPCIProxy;
>> +
>> +/* virtio-pci-bus */
>> +
>> +typedef struct VirtioBusState VirtioPCIBusState;
>> +typedef struct VirtioBusClass VirtioPCIBusClass;
>> +
>> +#define TYPE_VIRTIO_PCI_BUS "virtio-pci-bus"
>> +#define VIRTIO_PCI_BUS(obj) \
>> + OBJECT_CHECK(VirtioPCIBusState, (obj), TYPE_VIRTIO_PCI_BUS)
>> +#define VIRTIO_PCI_BUS_GET_CLASS(obj) \
>> + OBJECT_GET_CLASS(VirtioPCIBusClass, obj, TYPE_VIRTIO_PCI_BUS)
>> +#define VIRTIO_PCI_BUS_CLASS(klass) \
>> + OBJECT_CLASS_CHECK(VirtioPCIBusClass, klass, TYPE_VIRTIO_PCI_BUS)
>> +
>> +
>> +VirtioBusState *virtio_pci_bus_new(VirtIOPCIProxy *dev);
>>
>> /* Performance improves when virtqueue kick processing is decoupled from the
>> * vcpu thread using ioeventfd for some devices. */
>> @@ -31,7 +50,7 @@ typedef struct {
>> unsigned int users;
>> } VirtIOIRQFD;
>>
>> -typedef struct {
>> +struct VirtIOPCIProxy {
>> PCIDevice pci_dev;
>> VirtIODevice *vdev;
>> MemoryRegion bar;
>> @@ -51,7 +70,7 @@ typedef struct {
>> bool ioeventfd_disabled;
>> bool ioeventfd_started;
>> VirtIOIRQFD *vector_irqfd;
>> -} VirtIOPCIProxy;
>> +};
>>
>> void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev);
>> void virtio_pci_reset(DeviceState *d);
>> --
>> 1.7.11.7
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Qemu-devel] [PATCH V2 4/7] virtio-pci-bus: introduce virtio-pci-bus.
2013-01-14 20:36 ` KONRAD Frédéric
@ 2013-01-14 21:39 ` Andreas Färber
2013-01-14 21:41 ` KONRAD Frédéric
0 siblings, 1 reply; 16+ messages in thread
From: Andreas Färber @ 2013-01-14 21:39 UTC (permalink / raw)
To: KONRAD Frédéric
Cc: kwolf, peter.maydell, Anthony Liguori, e.voevodin, mst,
mark.burton, qemu-devel, agraf, amit.shah, aneesh.kumar, stefanha,
cornelia.huck, pbonzini
Am 14.01.2013 21:36, schrieb KONRAD Frédéric:
> On 14/01/2013 20:08, Anthony Liguori wrote:
>> fred.konrad@greensocs.com writes:
>>
>>> +VirtioBusState *virtio_pci_bus_new(VirtIOPCIProxy *dev)
>>> +{
>>> + DeviceState *qdev = DEVICE(dev);
>>> + BusState *qbus = qbus_create(TYPE_VIRTIO_PCI_BUS, qdev, NULL);
>>> + VirtioBusState *bus = VIRTIO_BUS(qbus);
>>> + qbus->allow_hotplug = 0;
>> Any reason to not use a qbus_create_inplace()?
>>
>> Regards,
>>
>> Anthony Liguori
> If I change the bus field of VirtIOPCIProxy from VirtioBus* to VirtioBus
> and I use qbus_create_inplace
> I can't use qbus_create_inplace(BUS(&dev->bus),...) as the object is not
> initialised yet right?
Correct, you need to use qbus_create_inplace((BusState *)&dev->bus,...).
I ran into the same trap for ADB last night. ;)
Andreas
--
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Qemu-devel] [PATCH V2 4/7] virtio-pci-bus: introduce virtio-pci-bus.
2013-01-14 21:39 ` Andreas Färber
@ 2013-01-14 21:41 ` KONRAD Frédéric
0 siblings, 0 replies; 16+ messages in thread
From: KONRAD Frédéric @ 2013-01-14 21:41 UTC (permalink / raw)
To: Andreas Färber
Cc: kwolf, peter.maydell, Anthony Liguori, e.voevodin, mst,
mark.burton, qemu-devel, agraf, amit.shah, aneesh.kumar, stefanha,
cornelia.huck, pbonzini
On 14/01/2013 22:39, Andreas Färber wrote:
> Am 14.01.2013 21:36, schrieb KONRAD Frédéric:
>> On 14/01/2013 20:08, Anthony Liguori wrote:
>>> fred.konrad@greensocs.com writes:
>>>
>>>> +VirtioBusState *virtio_pci_bus_new(VirtIOPCIProxy *dev)
>>>> +{
>>>> + DeviceState *qdev = DEVICE(dev);
>>>> + BusState *qbus = qbus_create(TYPE_VIRTIO_PCI_BUS, qdev, NULL);
>>>> + VirtioBusState *bus = VIRTIO_BUS(qbus);
>>>> + qbus->allow_hotplug = 0;
>>> Any reason to not use a qbus_create_inplace()?
>>>
>>> Regards,
>>>
>>> Anthony Liguori
>> If I change the bus field of VirtIOPCIProxy from VirtioBus* to VirtioBus
>> and I use qbus_create_inplace
>> I can't use qbus_create_inplace(BUS(&dev->bus),...) as the object is not
>> initialised yet right?
> Correct, you need to use qbus_create_inplace((BusState *)&dev->bus,...).
> I ran into the same trap for ADB last night. ;)
>
> Andreas
>
ok, so I'll use the cast.
I suppose it is the same for the s390.
Thanks Andreas!
Fred
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Qemu-devel] [PATCH V2 5/7] virtio-pci: refactor virtio-pci device.
2013-01-09 15:56 [Qemu-devel] [PATCH V2 0/7] Virtio-refactoring part1 fred.konrad
` (3 preceding siblings ...)
2013-01-09 15:56 ` [Qemu-devel] [PATCH V2 4/7] virtio-pci-bus: introduce virtio-pci-bus fred.konrad
@ 2013-01-09 15:56 ` fred.konrad
2013-01-14 19:13 ` Anthony Liguori
2013-01-09 15:56 ` [Qemu-devel] [PATCH V2 6/7] virtio-s390-bus: add virtio-s390-bus fred.konrad
2013-01-09 15:56 ` [Qemu-devel] [PATCH V2 7/7] virtio-s390-device: create a virtio-s390-bus during init fred.konrad
6 siblings, 1 reply; 16+ messages in thread
From: fred.konrad @ 2013-01-09 15:56 UTC (permalink / raw)
To: qemu-devel, aliguori
Cc: kwolf, peter.maydell, e.voevodin, mst, mark.burton, agraf,
amit.shah, aneesh.kumar, stefanha, cornelia.huck, pbonzini,
afaerber, fred.konrad
From: KONRAD Frederic <fred.konrad@greensocs.com>
Create the virtio-pci device. This transport device will create a
virtio-pci-bus, so one VirtIODevice can be connected.
Signed-off-by: KONRAD Frederic <fred.konrad@greensocs.com>
---
hw/virtio-pci.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
hw/virtio-pci.h | 18 ++++++++
2 files changed, 145 insertions(+)
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 090dc41..8598aee 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -1163,6 +1163,130 @@ static TypeInfo virtio_scsi_info = {
.class_init = virtio_scsi_class_init,
};
+/*
+ * virtio-pci: This is the PCIDevice which has a virtio-pci-bus.
+ */
+
+/* This is called by virtio-bus just after the device is plugged. */
+static void virtio_pci_device_plugged(DeviceState *d)
+{
+ VirtIOPCIProxy *proxy = VIRTIO_PCI(d);
+ VirtioBusState *bus = proxy->bus;
+ uint8_t *config;
+ uint32_t size;
+ uint16_t device_id = 0;
+ uint16_t class_id = 0;
+
+ switch (virtio_device_get_id(proxy->bus)) {
+ default:
+ error_report("unknown device id\n");
+ break;
+ }
+ pci_config_set_device_id(proxy->pci_dev.config, device_id);
+ pci_config_set_class(proxy->pci_dev.config, class_id);
+
+ proxy->vdev = proxy->bus->vdev;
+
+ config = proxy->pci_dev.config;
+ if (proxy->class_code) {
+ pci_config_set_class(config, proxy->class_code);
+ }
+ pci_set_word(config + PCI_SUBSYSTEM_VENDOR_ID,
+ pci_get_word(config + PCI_VENDOR_ID));
+ pci_set_word(config + PCI_SUBSYSTEM_ID, virtio_device_get_id(proxy->bus));
+ config[PCI_INTERRUPT_PIN] = 1;
+
+ if (proxy->nvectors &&
+ msix_init_exclusive_bar(&proxy->pci_dev, proxy->nvectors, 1)) {
+ proxy->nvectors = 0;
+ }
+
+ proxy->pci_dev.config_write = virtio_write_config;
+
+ size = VIRTIO_PCI_REGION_SIZE(&proxy->pci_dev)
+ + virtio_device_get_config_len(bus);
+ if (size & (size - 1)) {
+ size = 1 << qemu_fls(size);
+ }
+
+ memory_region_init_io(&proxy->bar, &virtio_pci_config_ops, proxy,
+ "virtio-pci", size);
+ pci_register_bar(&proxy->pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
+ &proxy->bar);
+
+ if (!kvm_has_many_ioeventfds()) {
+ proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
+ }
+
+ proxy->host_features |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
+ proxy->host_features |= 0x1 << VIRTIO_F_BAD_FEATURE;
+ proxy->host_features = virtio_device_get_features(bus,
+ proxy->host_features);
+}
+
+/* This is called by virtio-bus just before the device is unplugged. */
+static void virtio_pci_device_unplug(DeviceState *d)
+{
+ VirtIOPCIProxy *dev = VIRTIO_PCI(d);
+ virtio_pci_stop_ioeventfd(dev);
+}
+
+static int virtio_pci_init(PCIDevice *pci_dev)
+{
+ VirtIOPCIProxy *dev = VIRTIO_PCI(pci_dev);
+ VirtioPCIClass *k = VIRTIO_PCI_GET_CLASS(pci_dev);
+ dev->bus = virtio_pci_bus_new(dev);
+ if (k->init != NULL) {
+ return k->init(dev);
+ }
+ return 0;
+}
+
+static void virtio_pci_exit(PCIDevice *pci_dev)
+{
+ VirtIOPCIProxy *proxy = VIRTIO_PCI(pci_dev);
+ VirtioBusState *bus = VIRTIO_BUS(proxy->bus);
+ BusState *qbus = BUS(proxy->bus);
+ virtio_bus_destroy_device(bus);
+ qbus_free(qbus);
+ virtio_exit_pci(pci_dev);
+}
+
+/*
+ * This will be renamed virtio_pci_reset at the end of the series.
+ * virtio_pci_reset is still in use at this moment.
+ */
+static void virtio_pci_rst(DeviceState *qdev)
+{
+ VirtIOPCIProxy *proxy = VIRTIO_PCI(qdev);
+ VirtioBusState *bus = VIRTIO_BUS(proxy->bus);
+ virtio_pci_stop_ioeventfd(proxy);
+ virtio_bus_reset(bus);
+ msix_unuse_all_vectors(&proxy->pci_dev);
+ proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
+}
+
+static void virtio_pci_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+ k->init = virtio_pci_init;
+ k->exit = virtio_pci_exit;
+ k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+ k->revision = VIRTIO_PCI_ABI_VERSION;
+ k->class_id = PCI_CLASS_OTHERS;
+ dc->reset = virtio_pci_rst;
+}
+
+static const TypeInfo virtio_pci_info = {
+ .name = TYPE_VIRTIO_PCI,
+ .parent = TYPE_PCI_DEVICE,
+ .instance_size = sizeof(VirtIOPCIProxy),
+ .class_init = virtio_pci_class_init,
+ .class_size = sizeof(VirtioPCIClass),
+};
+
/* virtio-pci-bus */
VirtioBusState *virtio_pci_bus_new(VirtIOPCIProxy *dev)
@@ -1189,6 +1313,8 @@ static void virtio_pci_bus_class_init(ObjectClass *klass, void *data)
k->set_host_notifier = virtio_pci_set_host_notifier;
k->set_guest_notifiers = virtio_pci_set_guest_notifiers;
k->vmstate_change = virtio_pci_vmstate_change;
+ k->device_plugged = virtio_pci_device_plugged;
+ k->device_unplug = virtio_pci_device_unplug;
}
static const TypeInfo virtio_pci_bus_info = {
@@ -1207,6 +1333,7 @@ static void virtio_pci_register_types(void)
type_register_static(&virtio_scsi_info);
type_register_static(&virtio_rng_info);
type_register_static(&virtio_pci_bus_info);
+ type_register_static(&virtio_pci_info);
}
type_init(virtio_pci_register_types)
diff --git a/hw/virtio-pci.h b/hw/virtio-pci.h
index ed0097f..f05f63c 100644
--- a/hw/virtio-pci.h
+++ b/hw/virtio-pci.h
@@ -50,6 +50,22 @@ typedef struct {
unsigned int users;
} VirtIOIRQFD;
+/*
+ * virtio-pci: This is the PCIDevice which has a virtio-pci-bus.
+ */
+#define TYPE_VIRTIO_PCI "virtio-pci"
+#define VIRTIO_PCI_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(VirtioPCIClass, obj, TYPE_VIRTIO_PCI)
+#define VIRTIO_PCI_CLASS(klass) \
+ OBJECT_CLASS_CHECK(VirtioPCIClass, klass, TYPE_VIRTIO_PCI)
+#define VIRTIO_PCI(obj) \
+ OBJECT_CHECK(VirtIOPCIProxy, (obj), TYPE_VIRTIO_PCI)
+
+typedef struct VirtioPCIClass {
+ PCIDeviceClass parent_class;
+ int (*init)(VirtIOPCIProxy *vpci_dev);
+} VirtioPCIClass;
+
struct VirtIOPCIProxy {
PCIDevice pci_dev;
VirtIODevice *vdev;
@@ -70,6 +86,8 @@ struct VirtIOPCIProxy {
bool ioeventfd_disabled;
bool ioeventfd_started;
VirtIOIRQFD *vector_irqfd;
+ /* That's the virtio-bus on which VirtioDevice will be connected. */
+ VirtioBusState *bus;
};
void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev);
--
1.7.11.7
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [Qemu-devel] [PATCH V2 5/7] virtio-pci: refactor virtio-pci device.
2013-01-09 15:56 ` [Qemu-devel] [PATCH V2 5/7] virtio-pci: refactor virtio-pci device fred.konrad
@ 2013-01-14 19:13 ` Anthony Liguori
0 siblings, 0 replies; 16+ messages in thread
From: Anthony Liguori @ 2013-01-14 19:13 UTC (permalink / raw)
To: fred.konrad, qemu-devel
Cc: kwolf, peter.maydell, e.voevodin, mst, mark.burton, agraf,
cornelia.huck, aneesh.kumar, stefanha, amit.shah, pbonzini,
afaerber
fred.konrad@greensocs.com writes:
> From: KONRAD Frederic <fred.konrad@greensocs.com>
>
> Create the virtio-pci device. This transport device will create a
> virtio-pci-bus, so one VirtIODevice can be connected.
>
> Signed-off-by: KONRAD Frederic <fred.konrad@greensocs.com>
virtio-pci should be abstract...
> ---
> hw/virtio-pci.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> hw/virtio-pci.h | 18 ++++++++
> 2 files changed, 145 insertions(+)
>
> diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
> index 090dc41..8598aee 100644
> --- a/hw/virtio-pci.c
> +++ b/hw/virtio-pci.c
> @@ -1163,6 +1163,130 @@ static TypeInfo virtio_scsi_info = {
> .class_init = virtio_scsi_class_init,
> };
>
> +/*
> + * virtio-pci: This is the PCIDevice which has a virtio-pci-bus.
> + */
> +
> +/* This is called by virtio-bus just after the device is plugged. */
> +static void virtio_pci_device_plugged(DeviceState *d)
> +{
> + VirtIOPCIProxy *proxy = VIRTIO_PCI(d);
> + VirtioBusState *bus = proxy->bus;
> + uint8_t *config;
> + uint32_t size;
> + uint16_t device_id = 0;
> + uint16_t class_id = 0;
> +
> + switch (virtio_device_get_id(proxy->bus)) {
> + default:
> + error_report("unknown device id\n");
> + break;
> + }
And this chunk should die. Let's avoid having two ways of specifying
virtio-pci devices.
Regards,
Anthony Liguori
> + pci_config_set_device_id(proxy->pci_dev.config, device_id);
> + pci_config_set_class(proxy->pci_dev.config, class_id);
> +
> + proxy->vdev = proxy->bus->vdev;
> +
> + config = proxy->pci_dev.config;
> + if (proxy->class_code) {
> + pci_config_set_class(config, proxy->class_code);
> + }
> + pci_set_word(config + PCI_SUBSYSTEM_VENDOR_ID,
> + pci_get_word(config + PCI_VENDOR_ID));
> + pci_set_word(config + PCI_SUBSYSTEM_ID, virtio_device_get_id(proxy->bus));
> + config[PCI_INTERRUPT_PIN] = 1;
> +
> + if (proxy->nvectors &&
> + msix_init_exclusive_bar(&proxy->pci_dev, proxy->nvectors, 1)) {
> + proxy->nvectors = 0;
> + }
> +
> + proxy->pci_dev.config_write = virtio_write_config;
> +
> + size = VIRTIO_PCI_REGION_SIZE(&proxy->pci_dev)
> + + virtio_device_get_config_len(bus);
> + if (size & (size - 1)) {
> + size = 1 << qemu_fls(size);
> + }
> +
> + memory_region_init_io(&proxy->bar, &virtio_pci_config_ops, proxy,
> + "virtio-pci", size);
> + pci_register_bar(&proxy->pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
> + &proxy->bar);
> +
> + if (!kvm_has_many_ioeventfds()) {
> + proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
> + }
> +
> + proxy->host_features |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
> + proxy->host_features |= 0x1 << VIRTIO_F_BAD_FEATURE;
> + proxy->host_features = virtio_device_get_features(bus,
> + proxy->host_features);
> +}
> +
> +/* This is called by virtio-bus just before the device is unplugged. */
> +static void virtio_pci_device_unplug(DeviceState *d)
> +{
> + VirtIOPCIProxy *dev = VIRTIO_PCI(d);
> + virtio_pci_stop_ioeventfd(dev);
> +}
> +
> +static int virtio_pci_init(PCIDevice *pci_dev)
> +{
> + VirtIOPCIProxy *dev = VIRTIO_PCI(pci_dev);
> + VirtioPCIClass *k = VIRTIO_PCI_GET_CLASS(pci_dev);
> + dev->bus = virtio_pci_bus_new(dev);
> + if (k->init != NULL) {
> + return k->init(dev);
> + }
> + return 0;
> +}
> +
> +static void virtio_pci_exit(PCIDevice *pci_dev)
> +{
> + VirtIOPCIProxy *proxy = VIRTIO_PCI(pci_dev);
> + VirtioBusState *bus = VIRTIO_BUS(proxy->bus);
> + BusState *qbus = BUS(proxy->bus);
> + virtio_bus_destroy_device(bus);
> + qbus_free(qbus);
> + virtio_exit_pci(pci_dev);
> +}
> +
> +/*
> + * This will be renamed virtio_pci_reset at the end of the series.
> + * virtio_pci_reset is still in use at this moment.
> + */
> +static void virtio_pci_rst(DeviceState *qdev)
> +{
> + VirtIOPCIProxy *proxy = VIRTIO_PCI(qdev);
> + VirtioBusState *bus = VIRTIO_BUS(proxy->bus);
> + virtio_pci_stop_ioeventfd(proxy);
> + virtio_bus_reset(bus);
> + msix_unuse_all_vectors(&proxy->pci_dev);
> + proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
> +}
> +
> +static void virtio_pci_class_init(ObjectClass *klass, void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
> +
> + k->init = virtio_pci_init;
> + k->exit = virtio_pci_exit;
> + k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
> + k->revision = VIRTIO_PCI_ABI_VERSION;
> + k->class_id = PCI_CLASS_OTHERS;
> + dc->reset = virtio_pci_rst;
> +}
> +
> +static const TypeInfo virtio_pci_info = {
> + .name = TYPE_VIRTIO_PCI,
> + .parent = TYPE_PCI_DEVICE,
> + .instance_size = sizeof(VirtIOPCIProxy),
> + .class_init = virtio_pci_class_init,
> + .class_size = sizeof(VirtioPCIClass),
> +};
> +
> /* virtio-pci-bus */
>
> VirtioBusState *virtio_pci_bus_new(VirtIOPCIProxy *dev)
> @@ -1189,6 +1313,8 @@ static void virtio_pci_bus_class_init(ObjectClass *klass, void *data)
> k->set_host_notifier = virtio_pci_set_host_notifier;
> k->set_guest_notifiers = virtio_pci_set_guest_notifiers;
> k->vmstate_change = virtio_pci_vmstate_change;
> + k->device_plugged = virtio_pci_device_plugged;
> + k->device_unplug = virtio_pci_device_unplug;
> }
>
> static const TypeInfo virtio_pci_bus_info = {
> @@ -1207,6 +1333,7 @@ static void virtio_pci_register_types(void)
> type_register_static(&virtio_scsi_info);
> type_register_static(&virtio_rng_info);
> type_register_static(&virtio_pci_bus_info);
> + type_register_static(&virtio_pci_info);
> }
>
> type_init(virtio_pci_register_types)
> diff --git a/hw/virtio-pci.h b/hw/virtio-pci.h
> index ed0097f..f05f63c 100644
> --- a/hw/virtio-pci.h
> +++ b/hw/virtio-pci.h
> @@ -50,6 +50,22 @@ typedef struct {
> unsigned int users;
> } VirtIOIRQFD;
>
> +/*
> + * virtio-pci: This is the PCIDevice which has a virtio-pci-bus.
> + */
> +#define TYPE_VIRTIO_PCI "virtio-pci"
> +#define VIRTIO_PCI_GET_CLASS(obj) \
> + OBJECT_GET_CLASS(VirtioPCIClass, obj, TYPE_VIRTIO_PCI)
> +#define VIRTIO_PCI_CLASS(klass) \
> + OBJECT_CLASS_CHECK(VirtioPCIClass, klass, TYPE_VIRTIO_PCI)
> +#define VIRTIO_PCI(obj) \
> + OBJECT_CHECK(VirtIOPCIProxy, (obj), TYPE_VIRTIO_PCI)
> +
> +typedef struct VirtioPCIClass {
> + PCIDeviceClass parent_class;
> + int (*init)(VirtIOPCIProxy *vpci_dev);
> +} VirtioPCIClass;
> +
> struct VirtIOPCIProxy {
> PCIDevice pci_dev;
> VirtIODevice *vdev;
> @@ -70,6 +86,8 @@ struct VirtIOPCIProxy {
> bool ioeventfd_disabled;
> bool ioeventfd_started;
> VirtIOIRQFD *vector_irqfd;
> + /* That's the virtio-bus on which VirtioDevice will be connected. */
> + VirtioBusState *bus;
> };
>
> void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev);
> --
> 1.7.11.7
^ permalink raw reply [flat|nested] 16+ messages in thread
* [Qemu-devel] [PATCH V2 6/7] virtio-s390-bus: add virtio-s390-bus.
2013-01-09 15:56 [Qemu-devel] [PATCH V2 0/7] Virtio-refactoring part1 fred.konrad
` (4 preceding siblings ...)
2013-01-09 15:56 ` [Qemu-devel] [PATCH V2 5/7] virtio-pci: refactor virtio-pci device fred.konrad
@ 2013-01-09 15:56 ` fred.konrad
2013-01-09 15:56 ` [Qemu-devel] [PATCH V2 7/7] virtio-s390-device: create a virtio-s390-bus during init fred.konrad
6 siblings, 0 replies; 16+ messages in thread
From: fred.konrad @ 2013-01-09 15:56 UTC (permalink / raw)
To: qemu-devel, aliguori
Cc: kwolf, peter.maydell, e.voevodin, mst, mark.burton, agraf,
amit.shah, aneesh.kumar, stefanha, cornelia.huck, pbonzini,
afaerber, fred.konrad
From: KONRAD Frederic <fred.konrad@greensocs.com>
This add the virtio-s390-bus which extends virtio-bus. So one VirtIODevice can
be connected on this bus.
Signed-off-by: KONRAD Frederic <fred.konrad@greensocs.com>
---
hw/s390-virtio-bus.c | 29 +++++++++++++++++++++++++++++
hw/s390-virtio-bus.h | 17 +++++++++++++++++
2 files changed, 46 insertions(+)
diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index 7e99175..ad0f21d 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -32,6 +32,7 @@
#include "sysemu/kvm.h"
#include "hw/s390-virtio-bus.h"
+#include "hw/virtio-bus.h"
/* #define DEBUG_S390 */
@@ -569,8 +570,36 @@ static TypeInfo s390_virtio_bridge_info = {
.class_init = s390_virtio_bridge_class_init,
};
+/* virtio-s390-bus */
+
+VirtioBusState *virtio_s390_bus_new(VirtIOS390Device *dev)
+{
+ DeviceState *qdev = DEVICE(dev);
+ BusState *qbus = qbus_create(TYPE_VIRTIO_S390_BUS, qdev, NULL);
+ VirtioBusState *bus = VIRTIO_BUS(qbus);
+ qbus->allow_hotplug = 0;
+ return bus;
+}
+
+static void virtio_s390_bus_class_init(ObjectClass *klass, void *data)
+{
+ VirtioBusClass *k = VIRTIO_BUS_CLASS(klass);
+ BusClass *bus_class = BUS_CLASS(klass);
+ bus_class->max_dev = 1;
+ k->notify = virtio_s390_notify;
+ k->get_features = virtio_s390_get_features;
+}
+
+static const TypeInfo virtio_s390_bus_info = {
+ .name = TYPE_VIRTIO_S390_BUS,
+ .parent = TYPE_VIRTIO_BUS,
+ .instance_size = sizeof(VirtioS390BusState),
+ .class_init = virtio_s390_bus_class_init,
+};
+
static void s390_virtio_register_types(void)
{
+ type_register_static(&virtio_s390_bus_info);
type_register_static(&s390_virtio_bus_info);
type_register_static(&virtio_s390_device_info);
type_register_static(&s390_virtio_serial);
diff --git a/hw/s390-virtio-bus.h b/hw/s390-virtio-bus.h
index 23fedd5..d6260a2 100644
--- a/hw/s390-virtio-bus.h
+++ b/hw/s390-virtio-bus.h
@@ -24,6 +24,7 @@
#include "virtio-rng.h"
#include "virtio-serial.h"
#include "virtio-scsi.h"
+#include "virtio-bus.h"
#define VIRTIO_DEV_OFFS_TYPE 0 /* 8 bits */
#define VIRTIO_DEV_OFFS_NUM_VQ 1 /* 8 bits */
@@ -59,8 +60,24 @@
#define S390_VIRTIO_BUS(obj) \
OBJECT_CHECK(VirtIOS390Bus, (obj), TYPE_S390_VIRTIO_BUS)
+/* virtio-s390-bus */
+
+typedef struct VirtioBusState VirtioS390BusState;
+typedef struct VirtioBusClass VirtioS390BusClass;
+
+#define TYPE_VIRTIO_S390_BUS "virtio-s390-bus"
+#define VIRTIO_S390_BUS(obj) \
+ OBJECT_CHECK(VirtioS390BusState, (obj), TYPE_VIRTIO_S390_BUS)
+#define VIRTIO_S390_BUS_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(VirtioS390BusClass, obj, TYPE_VIRTIO_S390_BUS)
+#define VIRTIO_S390_BUS_CLASS(klass) \
+ OBJECT_CLASS_CHECK(VirtioS390BusClass, klass, TYPE_VIRTIO_S390_BUS)
+
+
typedef struct VirtIOS390Device VirtIOS390Device;
+VirtioBusState *virtio_s390_bus_new(VirtIOS390Device *dev);
+
typedef struct VirtIOS390DeviceClass {
DeviceClass qdev;
int (*init)(VirtIOS390Device *dev);
--
1.7.11.7
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [Qemu-devel] [PATCH V2 7/7] virtio-s390-device: create a virtio-s390-bus during init.
2013-01-09 15:56 [Qemu-devel] [PATCH V2 0/7] Virtio-refactoring part1 fred.konrad
` (5 preceding siblings ...)
2013-01-09 15:56 ` [Qemu-devel] [PATCH V2 6/7] virtio-s390-bus: add virtio-s390-bus fred.konrad
@ 2013-01-09 15:56 ` fred.konrad
6 siblings, 0 replies; 16+ messages in thread
From: fred.konrad @ 2013-01-09 15:56 UTC (permalink / raw)
To: qemu-devel, aliguori
Cc: kwolf, peter.maydell, e.voevodin, mst, mark.burton, agraf,
amit.shah, aneesh.kumar, stefanha, cornelia.huck, pbonzini,
afaerber, fred.konrad
From: KONRAD Frederic <fred.konrad@greensocs.com>
A virtio-s390-bus is created during the init. So one VirtIODevice can be
connected on the virtio-s390-device through this bus.
Signed-off-by: KONRAD Frederic <fred.konrad@greensocs.com>
---
hw/s390-virtio-bus.c | 2 ++
hw/s390-virtio-bus.h | 1 +
2 files changed, 3 insertions(+)
diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c
index ad0f21d..88dfbc9 100644
--- a/hw/s390-virtio-bus.c
+++ b/hw/s390-virtio-bus.c
@@ -503,6 +503,8 @@ static int s390_virtio_busdev_init(DeviceState *dev)
VirtIOS390Device *_dev = (VirtIOS390Device *)dev;
VirtIOS390DeviceClass *_info = VIRTIO_S390_DEVICE_GET_CLASS(dev);
+ _dev->bus = virtio_s390_bus_new(_dev);
+
return _info->init(_dev);
}
diff --git a/hw/s390-virtio-bus.h b/hw/s390-virtio-bus.h
index d6260a2..1430f66 100644
--- a/hw/s390-virtio-bus.h
+++ b/hw/s390-virtio-bus.h
@@ -96,6 +96,7 @@ struct VirtIOS390Device {
virtio_net_conf net;
VirtIOSCSIConf scsi;
VirtIORNGConf rng;
+ VirtioBusState *bus;
};
typedef struct VirtIOS390Bus {
--
1.7.11.7
^ permalink raw reply related [flat|nested] 16+ messages in thread