[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC v2 06/20] qdev: Add 'accepted-device-types' property t
From: |
Eduardo Habkost |
Subject: |
[Qemu-devel] [RFC v2 06/20] qdev: Add 'accepted-device-types' property to BusClass |
Date: |
Fri, 25 Nov 2016 20:05:42 -0200 |
Each bus class will now be aware of the specific device types
that can be plugged on it. That will be useful for:
* Runtime check for which devices types can be plugged to the
machine;
* Validation of query-machines output by automated tests.
By default, a single type name is used on all bus instances (set
at BusClass::device_type), but bus instances can override it and
return a different type list.
Signed-off-by: Eduardo Habkost <address@hidden>
---
Changes v1 -> v2:
* v1 patch subject was
"qdev: Add device_type field to BusClass"
* Replace 'device-type' with 'accepted-device-types'
property
---
hw/audio/intel-hda.c | 7 +++++++
hw/block/fdc.c | 15 +++++++++++----
hw/char/virtio-serial-bus.c | 1 +
hw/core/bus.c | 21 +++++++++++++++++++++
hw/core/sysbus.c | 1 +
hw/i2c/core.c | 7 +++++++
hw/ide/qdev.c | 1 +
hw/input/adb.c | 7 +++++++
hw/ipack/ipack.c | 7 +++++++
hw/isa/isa-bus.c | 1 +
hw/misc/auxbus.c | 1 +
hw/pci/pci.c | 1 +
hw/ppc/spapr_vio.c | 1 +
hw/s390x/css-bridge.c | 2 ++
hw/s390x/event-facility.c | 1 +
hw/s390x/s390-pci-bus.c | 7 +++++++
hw/scsi/scsi-bus.c | 1 +
hw/sd/core.c | 7 +++++++
hw/ssi/ssi.c | 7 +++++++
hw/usb/bus.c | 1 +
hw/usb/dev-smartcard-reader.c | 7 +++++++
hw/virtio/virtio-bus.c | 1 +
include/hw/qdev-core.h | 8 ++++++++
23 files changed, 109 insertions(+), 4 deletions(-)
diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index 537face..a363993 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -36,9 +36,16 @@ static Property hda_props[] = {
DEFINE_PROP_END_OF_LIST()
};
+static void hda_codec_bus_class_init(ObjectClass *oc, void *opaque)
+{
+ BusClass *bc = BUS_CLASS(oc);
+ bc->device_type = TYPE_HDA_CODEC_DEVICE;
+}
+
static const TypeInfo hda_codec_bus_info = {
.name = TYPE_HDA_BUS,
.parent = TYPE_BUS,
+ .class_init = hda_codec_bus_class_init,
.instance_size = sizeof(HDACodecBus),
};
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 17d29e7..09bfdda 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -60,6 +60,10 @@
#define TYPE_FLOPPY_BUS "floppy-bus"
#define FLOPPY_BUS(obj) OBJECT_CHECK(FloppyBus, (obj), TYPE_FLOPPY_BUS)
+#define TYPE_FLOPPY_DRIVE "floppy"
+#define FLOPPY_DRIVE(obj) \
+ OBJECT_CHECK(FloppyDrive, (obj), TYPE_FLOPPY_DRIVE)
+
typedef struct FDCtrl FDCtrl;
typedef struct FDrive FDrive;
static FDrive *get_drv(FDCtrl *fdctrl, int unit);
@@ -69,9 +73,16 @@ typedef struct FloppyBus {
FDCtrl *fdc;
} FloppyBus;
+static void floppy_bus_class_init(ObjectClass *oc, void *opaque)
+{
+ BusClass *bc = BUS_CLASS(oc);
+ bc->device_type = TYPE_FLOPPY_DRIVE;
+}
+
static const TypeInfo floppy_bus_info = {
.name = TYPE_FLOPPY_BUS,
.parent = TYPE_BUS,
+ .class_init = floppy_bus_class_init,
.instance_size = sizeof(FloppyBus),
};
@@ -483,10 +494,6 @@ static const BlockDevOps fd_block_ops = {
};
-#define TYPE_FLOPPY_DRIVE "floppy"
-#define FLOPPY_DRIVE(obj) \
- OBJECT_CHECK(FloppyDrive, (obj), TYPE_FLOPPY_DRIVE)
-
typedef struct FloppyDrive {
DeviceState qdev;
uint32_t unit;
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index 7975c2c..215e180 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -832,6 +832,7 @@ static void virtser_bus_class_init(ObjectClass *klass, void
*data)
{
BusClass *k = BUS_CLASS(klass);
k->print_dev = virtser_bus_dev_print;
+ k->device_type = TYPE_VIRTIO_SERIAL_PORT;
}
static const TypeInfo virtser_bus_info = {
diff --git a/hw/core/bus.c b/hw/core/bus.c
index cf383fc..d2bf717 100644
--- a/hw/core/bus.c
+++ b/hw/core/bus.c
@@ -21,6 +21,7 @@
#include "qemu-common.h"
#include "hw/qdev.h"
#include "qapi/error.h"
+#include "qapi-visit.h"
static void qbus_set_hotplug_handler_internal(BusState *bus, Object *handler,
Error **errp)
@@ -191,8 +192,15 @@ static void bus_set_realized(Object *obj, bool value,
Error **errp)
static void qbus_initfn(Object *obj)
{
BusState *bus = BUS(obj);
+ BusClass *bc = BUS_GET_CLASS(bus);
QTAILQ_INIT(&bus->children);
+
+ if (bc->device_type) {
+ bus->accepted_device_types = g_new0(strList, 1);
+ bus->accepted_device_types->value = g_strdup(bc->device_type);
+ }
+
object_property_add_link(obj, QDEV_HOTPLUG_HANDLER_PROPERTY,
TYPE_HOTPLUG_HANDLER,
(Object **)&bus->hotplug_handler,
@@ -208,12 +216,25 @@ static char *default_bus_get_fw_dev_path(DeviceState *dev)
return g_strdup(object_get_typename(OBJECT(dev)));
}
+static void bus_get_device_type(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ BusState *bus = BUS(obj);
+
+ visit_type_strList(v, NULL, &bus->accepted_device_types, errp);
+}
+
static void bus_class_init(ObjectClass *class, void *data)
{
BusClass *bc = BUS_CLASS(class);
class->unparent = bus_unparent;
bc->get_fw_dev_path = default_bus_get_fw_dev_path;
+
+ object_class_property_add(class, "accepted-device-types", "strList",
+ bus_get_device_type, NULL, NULL, NULL,
+ &error_abort);
}
static void qbus_finalize(Object *obj)
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
index c0f560b..c065eb8 100644
--- a/hw/core/sysbus.c
+++ b/hw/core/sysbus.c
@@ -76,6 +76,7 @@ static void system_bus_class_init(ObjectClass *klass, void
*data)
k->print_dev = sysbus_dev_print;
k->get_fw_dev_path = sysbus_get_fw_dev_path;
+ k->device_type = TYPE_SYS_BUS_DEVICE;
}
static const TypeInfo system_bus_info = {
diff --git a/hw/i2c/core.c b/hw/i2c/core.c
index abd4c4c..81b6ae4 100644
--- a/hw/i2c/core.c
+++ b/hw/i2c/core.c
@@ -35,9 +35,16 @@ static Property i2c_props[] = {
#define TYPE_I2C_BUS "i2c-bus"
#define I2C_BUS(obj) OBJECT_CHECK(I2CBus, (obj), TYPE_I2C_BUS)
+static void i2c_bus_class_init(ObjectClass *oc, void *opaque)
+{
+ BusClass *bc = BUS_CLASS(oc);
+ bc->device_type = TYPE_I2C_SLAVE;
+}
+
static const TypeInfo i2c_bus_info = {
.name = TYPE_I2C_BUS,
.parent = TYPE_BUS,
+ .class_init = i2c_bus_class_init,
.instance_size = sizeof(I2CBus),
};
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index dbaa75c..b526f85 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -43,6 +43,7 @@ static void ide_bus_class_init(ObjectClass *klass, void *data)
BusClass *k = BUS_CLASS(klass);
k->get_fw_dev_path = idebus_get_fw_dev_path;
+ k->device_type = TYPE_IDE_DEVICE;
}
static void idebus_unrealize(DeviceState *qdev, Error **errp)
diff --git a/hw/input/adb.c b/hw/input/adb.c
index 43d3205..c6a2b31 100644
--- a/hw/input/adb.c
+++ b/hw/input/adb.c
@@ -121,9 +121,16 @@ int adb_poll(ADBBusState *s, uint8_t *obuf, uint16_t
poll_mask)
return olen;
}
+static void adb_bus_class_init(ObjectClass *oc, void *opaque)
+{
+ BusClass *bc = BUS_CLASS(oc);
+ bc->device_type = TYPE_ADB_DEVICE;
+}
+
static const TypeInfo adb_bus_type_info = {
.name = TYPE_ADB_BUS,
.parent = TYPE_BUS,
+ .class_init = adb_bus_class_init,
.instance_size = sizeof(ADBBusState),
};
diff --git a/hw/ipack/ipack.c b/hw/ipack/ipack.c
index 6021e6d..f22c504 100644
--- a/hw/ipack/ipack.c
+++ b/hw/ipack/ipack.c
@@ -106,9 +106,16 @@ static const TypeInfo ipack_device_info = {
.abstract = true,
};
+static void ipack_bus_class_init(ObjectClass *oc, void *opaque)
+{
+ BusClass *bc = BUS_CLASS(oc);
+ bc->device_type = TYPE_IPACK_DEVICE;
+}
+
static const TypeInfo ipack_bus_info = {
.name = TYPE_IPACK_BUS,
.parent = TYPE_BUS,
+ .class_init = ipack_bus_class_init,
.instance_size = sizeof(IPackBus),
};
diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
index 9d07b11..aad7669 100644
--- a/hw/isa/isa-bus.c
+++ b/hw/isa/isa-bus.c
@@ -36,6 +36,7 @@ static void isa_bus_class_init(ObjectClass *klass, void *data)
k->print_dev = isabus_dev_print;
k->get_fw_dev_path = isabus_get_fw_dev_path;
+ k->device_type = TYPE_ISA_DEVICE;
}
static const TypeInfo isa_dma_info = {
diff --git a/hw/misc/auxbus.c b/hw/misc/auxbus.c
index e4a7ba4..4b0d565 100644
--- a/hw/misc/auxbus.c
+++ b/hw/misc/auxbus.c
@@ -57,6 +57,7 @@ static void aux_bus_class_init(ObjectClass *klass, void *data)
* in monitor.
*/
k->print_dev = aux_slave_dev_print;
+ k->device_type = TYPE_AUX_SLAVE;
}
AUXBus *aux_init_bus(DeviceState *parent, const char *name)
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 24fae16..74b8fef 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -152,6 +152,7 @@ static void pci_bus_class_init(ObjectClass *klass, void
*data)
k->realize = pci_bus_realize;
k->unrealize = pci_bus_unrealize;
k->reset = pcibus_reset;
+ k->device_type = TYPE_PCI_DEVICE;
pbc->is_root = pcibus_is_root;
pbc->bus_num = pcibus_num;
diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
index cc1e09c..c70b9b9 100644
--- a/hw/ppc/spapr_vio.c
+++ b/hw/ppc/spapr_vio.c
@@ -61,6 +61,7 @@ static void spapr_vio_bus_class_init(ObjectClass *klass, void
*data)
k->get_dev_path = spapr_vio_get_dev_name;
k->get_fw_dev_path = spapr_vio_get_dev_name;
+ k->device_type = TYPE_VIO_SPAPR_DEVICE;
}
static const TypeInfo spapr_vio_bus_info = {
diff --git a/hw/s390x/css-bridge.c b/hw/s390x/css-bridge.c
index 9a7f7ee..8a6c1ae 100644
--- a/hw/s390x/css-bridge.c
+++ b/hw/s390x/css-bridge.c
@@ -17,6 +17,7 @@
#include "hw/s390x/css.h"
#include "ccw-device.h"
#include "hw/s390x/css-bridge.h"
+#include "hw/s390x/virtio-ccw.h"
/*
* Invoke device-specific unplug handler, disable the subchannel
@@ -81,6 +82,7 @@ static void virtual_css_bus_class_init(ObjectClass *klass,
void *data)
k->reset = virtual_css_bus_reset;
k->get_dev_path = virtual_css_bus_get_dev_path;
+ k->device_type = TYPE_VIRTIO_CCW_DEVICE;
}
static const TypeInfo virtual_css_bus_info = {
diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c
index 34b2faf..f2562ce 100644
--- a/hw/s390x/event-facility.c
+++ b/hw/s390x/event-facility.c
@@ -307,6 +307,7 @@ static void sclp_events_bus_class_init(ObjectClass *klass,
void *data)
BusClass *bc = BUS_CLASS(klass);
bc->realize = sclp_events_bus_realize;
+ bc->device_type = TYPE_SCLP_EVENT;
}
static const TypeInfo sclp_events_bus_info = {
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 63f6248..7470fdd 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -783,10 +783,17 @@ static const TypeInfo s390_pcihost_info = {
}
};
+static void s390_pcibus_class_init(ObjectClass *oc, void *opaque)
+{
+ BusClass *bc = BUS_CLASS(oc);
+ bc->device_type = TYPE_S390_PCI_DEVICE;
+}
+
static const TypeInfo s390_pcibus_info = {
.name = TYPE_S390_PCI_BUS,
.parent = TYPE_BUS,
.instance_size = sizeof(S390PCIBus),
+ .class_init = s390_pcibus_class_init,
};
static uint16_t s390_pci_generate_uid(void)
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 297216d..9faf45f 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -31,6 +31,7 @@ static void scsi_bus_class_init(ObjectClass *klass, void
*data)
k->get_dev_path = scsibus_get_dev_path;
k->get_fw_dev_path = scsibus_get_fw_dev_path;
+ k->device_type = TYPE_SCSI_DEVICE;
hc->unplug = qdev_simple_device_unplug_cb;
}
diff --git a/hw/sd/core.c b/hw/sd/core.c
index 14c2bdf..49b9f59 100644
--- a/hw/sd/core.c
+++ b/hw/sd/core.c
@@ -131,11 +131,18 @@ void sdbus_set_readonly(SDBus *sdbus, bool readonly)
}
}
+static void sd_bus_class_init(ObjectClass *oc, void *opaque)
+{
+ BusClass *bc = BUS_CLASS(oc);
+ bc->device_type = TYPE_SD_CARD;
+}
+
static const TypeInfo sd_bus_info = {
.name = TYPE_SD_BUS,
.parent = TYPE_BUS,
.instance_size = sizeof(SDBus),
.class_size = sizeof(SDBusClass),
+ .class_init = sd_bus_class_init,
};
static void sd_bus_register_types(void)
diff --git a/hw/ssi/ssi.c b/hw/ssi/ssi.c
index 7eaaf56..c48920d 100644
--- a/hw/ssi/ssi.c
+++ b/hw/ssi/ssi.c
@@ -22,10 +22,17 @@ struct SSIBus {
#define TYPE_SSI_BUS "SSI"
#define SSI_BUS(obj) OBJECT_CHECK(SSIBus, (obj), TYPE_SSI_BUS)
+static void ssi_bus_class_init(ObjectClass *oc, void *opaque)
+{
+ BusClass *bc = BUS_CLASS(oc);
+ bc->device_type = TYPE_SSI_SLAVE;
+}
+
static const TypeInfo ssi_bus_info = {
.name = TYPE_SSI_BUS,
.parent = TYPE_BUS,
.instance_size = sizeof(SSIBus),
+ .class_init = ssi_bus_class_init,
};
static void ssi_cs_default(void *opaque, int n, int level)
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 25913ad..2cb7fa4 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -33,6 +33,7 @@ static void usb_bus_class_init(ObjectClass *klass, void *data)
k->print_dev = usb_bus_dev_print;
k->get_dev_path = usb_get_dev_path;
k->get_fw_dev_path = usb_get_fw_dev_path;
+ k->device_type = TYPE_USB_DEVICE;
hc->unplug = qdev_simple_device_unplug_cb;
}
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
index 89e11b6..2721f0c 100644
--- a/hw/usb/dev-smartcard-reader.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -1180,10 +1180,17 @@ static Property ccid_props[] = {
#define TYPE_CCID_BUS "ccid-bus"
#define CCID_BUS(obj) OBJECT_CHECK(CCIDBus, (obj), TYPE_CCID_BUS)
+static void ccid_bus_class_init(ObjectClass *oc, void *opaque)
+{
+ BusClass *bc = BUS_CLASS(oc);
+ bc->device_type = TYPE_CCID_CARD;
+}
+
static const TypeInfo ccid_bus_info = {
.name = TYPE_CCID_BUS,
.parent = TYPE_BUS,
.instance_size = sizeof(CCIDBus),
+ .class_init = ccid_bus_class_init,
};
void ccid_card_send_apdu_to_guest(CCIDCardState *card,
diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
index d6c0c72..815f3dd 100644
--- a/hw/virtio/virtio-bus.c
+++ b/hw/virtio/virtio-bus.c
@@ -293,6 +293,7 @@ static void virtio_bus_class_init(ObjectClass *klass, void
*data)
BusClass *bus_class = BUS_CLASS(klass);
bus_class->get_dev_path = virtio_bus_get_dev_path;
bus_class->get_fw_dev_path = virtio_bus_get_fw_dev_path;
+ bus_class->device_type = TYPE_VIRTIO_DEVICE;
}
static const TypeInfo virtio_bus_info = {
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 2c97347..a7f9ac4 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -207,6 +207,13 @@ struct BusClass {
int max_dev;
/* number of automatically allocated bus ids (e.g. ide.0) */
int automatic_ids;
+
+ /* default device type for 'accepted-device-type' property
+ *
+ * Most buses return only BusClass::device_type on accepted-device-types,
+ * but on some cases bus instances may override it.
+ */
+ const char *device_type;
};
typedef struct BusChild {
@@ -228,6 +235,7 @@ struct BusState {
HotplugHandler *hotplug_handler;
int max_index;
bool realized;
+ strList *accepted_device_types;
QTAILQ_HEAD(ChildrenHead, BusChild) children;
QLIST_ENTRY(BusState) sibling;
};
--
2.7.4
- [Qemu-devel] [RFC v2 00/20] qmp: Report bus information on 'query-machines', Eduardo Habkost, 2016/11/25
- [Qemu-devel] [RFC v2 01/20] qemu.py: Make logging optional, Eduardo Habkost, 2016/11/25
- [Qemu-devel] [RFC v2 02/20] qtest.py: Support QTEST_LOG environment variable, Eduardo Habkost, 2016/11/25
- [Qemu-devel] [RFC v2 03/20] qtest.py: make logging optional, Eduardo Habkost, 2016/11/25
- [Qemu-devel] [RFC v2 04/20] qtest.py: Make 'binary' parameter optional, Eduardo Habkost, 2016/11/25
- [Qemu-devel] [RFC v2 05/20] tests: Add rules to non-gtester qtest test cases, Eduardo Habkost, 2016/11/25
- [Qemu-devel] [RFC v2 06/20] qdev: Add 'accepted-device-types' property to BusClass,
Eduardo Habkost <=
- [Qemu-devel] [RFC v2 08/20] virtio-pci: Set PCIDeviceClass::is_express=1, Eduardo Habkost, 2016/11/25
- [Qemu-devel] [RFC v2 07/20] qmp: Add 'always-available-buses' field to 'query-machines', Eduardo Habkost, 2016/11/25
- [Qemu-devel] [RFC v2 09/20] vmxnet3: Set PCIDeviceClass::is_express=1, Eduardo Habkost, 2016/11/25
- [Qemu-devel] [RFC v2 10/20] pvscsi: Set PCIDeviceClass::is_express=1, Eduardo Habkost, 2016/11/25
- [Qemu-devel] [RFC v2 11/20] pci: INTERFACE_LEGACY_PCI_DEVICE and INTERFACE_PCIE_DEVICE interfaces, Eduardo Habkost, 2016/11/25
- [Qemu-devel] [RFC v2 13/20] [trivial] edu: Move edu_info outside function, Eduardo Habkost, 2016/11/25
- [Qemu-devel] [RFC v2 12/20] pci: Replace is_express with INTERFACE_PCIE_DEVICE, Eduardo Habkost, 2016/11/25
- [Qemu-devel] [RFC v2 15/20] eepro100: Add INTERFACE_LEGACY_PCI_DEVICE, Eduardo Habkost, 2016/11/25