From patchwork Fri Nov 25 22:05:42 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eduardo Habkost X-Patchwork-Id: 9448153 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 8B69F6071C for ; Fri, 25 Nov 2016 22:12:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 77EAF204C0 for ; Fri, 25 Nov 2016 22:12:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6902C2808F; Fri, 25 Nov 2016 22:12:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 4C957204C0 for ; Fri, 25 Nov 2016 22:12:41 +0000 (UTC) Received: from localhost ([::1]:48112 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cAOjY-0002pj-HN for patchwork-qemu-devel@patchwork.kernel.org; Fri, 25 Nov 2016 17:12:40 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50561) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cAOdT-0006Q4-6Z for qemu-devel@nongnu.org; Fri, 25 Nov 2016 17:06:25 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cAOdR-0008Ll-4F for qemu-devel@nongnu.org; Fri, 25 Nov 2016 17:06:23 -0500 Received: from mx1.redhat.com ([209.132.183.28]:37318) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cAOdQ-0008KU-Qv for qemu-devel@nongnu.org; Fri, 25 Nov 2016 17:06:21 -0500 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 045DF81252 for ; Fri, 25 Nov 2016 22:06:20 +0000 (UTC) Received: from localhost (ovpn-116-207.phx2.redhat.com [10.3.116.207]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id uAPM6IJR016230; Fri, 25 Nov 2016 17:06:19 -0500 From: Eduardo Habkost To: qemu-devel@nongnu.org, Markus Armbruster , Marcel Apfelbaum , "Michael S. Tsirkin" Date: Fri, 25 Nov 2016 20:05:42 -0200 Message-Id: <1480111556-32586-7-git-send-email-ehabkost@redhat.com> In-Reply-To: <1480111556-32586-1-git-send-email-ehabkost@redhat.com> References: <1480111556-32586-1-git-send-email-ehabkost@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Fri, 25 Nov 2016 22:06:20 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC v2 06/20] qdev: Add 'accepted-device-types' property to BusClass X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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; };