diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 93849c8d369fddf0eeb07ae087699b5395c7847f..9e8a89c2332b049d107345347bd238c701e887c7 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -544,9 +544,13 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data) k->revision = 0x03; k->class_id = PCI_CLASS_BRIDGE_OTHER; dc->desc = "PM"; - dc->no_user = 1; dc->vmsd = &vmstate_acpi; dc->props = piix4_pm_properties; + /* + * Reason: part of PIIX4 southbridge, needs to be wired up, + * e.g. by mips_malta_init() + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo piix4_pm_info = { diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c index 59e1bb83883161bef191eb20f719416efb97d05c..71a5a37fdc95ce39487272562f344002621e00a0 100644 --- a/hw/alpha/typhoon.c +++ b/hw/alpha/typhoon.c @@ -934,11 +934,9 @@ static int typhoon_pcihost_init(SysBusDevice *dev) static void typhoon_pcihost_class_init(ObjectClass *klass, void *data) { - DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); k->init = typhoon_pcihost_init; - dc->no_user = 1; } static const TypeInfo typhoon_pcihost_info = { diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c index f7e8b7e8fa73da8d158a3e4c32352bd44ef05ba7..aef2bde0c445dc66292bba3a237187a59b1513a4 100644 --- a/hw/arm/versatilepb.c +++ b/hw/arm/versatilepb.c @@ -390,7 +390,6 @@ static void vpb_sic_class_init(ObjectClass *klass, void *data) SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); k->init = vpb_sic_init; - dc->no_user = 1; dc->vmsd = &vmstate_vpb_sic; } diff --git a/hw/audio/marvell_88w8618.c b/hw/audio/marvell_88w8618.c index 97194ce7adc4d0bb3e28b9d7c5e432c765ff2091..cdce238f55a481309c189d0e98828dd4c5fd8393 100644 --- a/hw/audio/marvell_88w8618.c +++ b/hw/audio/marvell_88w8618.c @@ -288,6 +288,8 @@ static void mv88w8618_audio_class_init(ObjectClass *klass, void *data) dc->reset = mv88w8618_audio_reset; dc->vmsd = &mv88w8618_audio_vmsd; dc->props = mv88w8618_audio_properties; + /* Reason: pointer property "wm8750" */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo mv88w8618_audio_info = { diff --git a/hw/audio/pcspk.c b/hw/audio/pcspk.c index 9004ce3d1fab6961c50741c5b962046d0a4694ef..f980d66b2f786395de4c08f8ca20ca15b6570876 100644 --- a/hw/audio/pcspk.c +++ b/hw/audio/pcspk.c @@ -192,8 +192,9 @@ static void pcspk_class_initfn(ObjectClass *klass, void *data) dc->realize = pcspk_realizefn; set_bit(DEVICE_CATEGORY_SOUND, dc->categories); - dc->no_user = 1; dc->props = pcspk_properties; + /* Reason: pointer property "pit", realize sets global pcspk_state */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo pcspk_info = { diff --git a/hw/audio/pl041.c b/hw/audio/pl041.c index 5393b520b775f5876e023b3ce40aad43078f2acb..ed82be54e867eb02140bab26a90253cf4badf14e 100644 --- a/hw/audio/pl041.c +++ b/hw/audio/pl041.c @@ -632,7 +632,6 @@ static void pl041_device_class_init(ObjectClass *klass, void *data) k->init = pl041_init; set_bit(DEVICE_CATEGORY_SOUND, dc->categories); - dc->no_user = 1; dc->reset = pl041_device_reset; dc->vmsd = &vmstate_pl041; dc->props = pl041_device_properties; diff --git a/hw/block/fdc.c b/hw/block/fdc.c index c5a6c212155a3cf8070b6183ec52b2bc8a259824..592b58f9b5dadd4167db3b96ba82230a8a2b95d6 100644 --- a/hw/block/fdc.c +++ b/hw/block/fdc.c @@ -2234,7 +2234,6 @@ static void isabus_fdc_class_init(ObjectClass *klass, void *data) dc->realize = isabus_fdc_realize; dc->fw_name = "fdc"; - dc->no_user = 1; dc->reset = fdctrl_external_reset_isa; dc->vmsd = &vmstate_isa_fdc; dc->props = isa_fdc_properties; diff --git a/hw/core/qdev.c b/hw/core/qdev.c index e374a9399fc687f328b6ae9a40991cc58d6c77e3..bbd780aad100cc8674cb1eadf983492893b70238 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -481,11 +481,6 @@ BusState *qbus_create(const char *typename, DeviceState *parent, const char *nam return bus; } -void qbus_free(BusState *bus) -{ - object_unparent(OBJECT(bus)); -} - static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev) { BusClass *bc = BUS_GET_CLASS(bus); @@ -794,7 +789,7 @@ static void device_unparent(Object *obj) while (dev->num_child_bus) { bus = QLIST_FIRST(&dev->child_bus); - qbus_free(bus); + object_unparent(OBJECT(bus)); } if (dev->realized) { object_property_set_bool(obj, false, "realized", NULL); diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c index 146f50aa157ac5047c30664adeb4673b74ca907f..f4e760d6ebb6862c36dd234b1ec778409ac03b05 100644 --- a/hw/core/sysbus.c +++ b/hw/core/sysbus.c @@ -257,6 +257,13 @@ static void sysbus_device_class_init(ObjectClass *klass, void *data) DeviceClass *k = DEVICE_CLASS(klass); k->init = sysbus_device_init; k->bus_type = TYPE_SYSTEM_BUS; + /* + * device_add plugs devices into suitable bus. For "real" buses, + * that actually connects the device. For sysbus, the connections + * need to be made separately, and device_add can't do that. The + * device would be left unconnected, and could not possibly work. + */ + k->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo sysbus_device_type_info = { diff --git a/hw/cpu/icc_bus.c b/hw/cpu/icc_bus.c index 9a4ea7e2df590a66b040fcd7f4ac5a6fc2d987c8..7f44c59b25af4f3cbe38d3c1e6959dc58ce26fef 100644 --- a/hw/cpu/icc_bus.c +++ b/hw/cpu/icc_bus.c @@ -43,15 +43,13 @@ static const TypeInfo icc_bus_info = { static void icc_device_realize(DeviceState *dev, Error **errp) { - ICCDevice *id = ICC_DEVICE(dev); - ICCDeviceClass *idc = ICC_DEVICE_GET_CLASS(id); - - if (idc->init) { - if (idc->init(id) < 0) { - error_setg(errp, "%s initialization failed.", - object_get_typename(OBJECT(dev))); - } + ICCDeviceClass *idc = ICC_DEVICE_GET_CLASS(dev); + + /* convert to QOM */ + if (idc->realize) { + idc->realize(dev, errp); } + } static void icc_device_class_init(ObjectClass *oc, void *data) diff --git a/hw/display/pl110.c b/hw/display/pl110.c index 790e5108ed602f0423773dfd5bede37e939e8cf5..ab689e9aae69d469d80092821d944c480ddc9687 100644 --- a/hw/display/pl110.c +++ b/hw/display/pl110.c @@ -496,7 +496,6 @@ static void pl110_class_init(ObjectClass *klass, void *data) k->init = pl110_initfn; set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories); - dc->no_user = 1; dc->vmsd = &vmstate_pl110; } diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c index 35b90155a2d37a50884ea0da97db4527419981a5..cb7bda98032ffaae0387bf17487b256ce72330b8 100644 --- a/hw/dma/pl080.c +++ b/hw/dma/pl080.c @@ -381,7 +381,6 @@ static void pl080_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); - dc->no_user = 1; dc->vmsd = &vmstate_pl080; } diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c index 2a92ffb82eea22cfd3044d73503e446c9114d6d5..eac338f1bc8cd243f1b1e8c2a30459c6b6498606 100644 --- a/hw/dma/sparc32_dma.c +++ b/hw/dma/sparc32_dma.c @@ -304,6 +304,8 @@ static void sparc32_dma_class_init(ObjectClass *klass, void *data) dc->reset = dma_reset; dc->vmsd = &vmstate_dma; dc->props = sparc32_dma_properties; + /* Reason: pointer property "iommu_opaque" */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo sparc32_dma_info = { diff --git a/hw/gpio/omap_gpio.c b/hw/gpio/omap_gpio.c index b8f572bb704b7ca9297ada0e61a780077e7ec3a2..938782a45da1171306da7e71858b5e19ee74f902 100644 --- a/hw/gpio/omap_gpio.c +++ b/hw/gpio/omap_gpio.c @@ -759,6 +759,8 @@ static void omap_gpio_class_init(ObjectClass *klass, void *data) k->init = omap_gpio_init; dc->reset = omap_gpif_reset; dc->props = omap_gpio_properties; + /* Reason: pointer property "clk" */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo omap_gpio_info = { @@ -788,6 +790,8 @@ static void omap2_gpio_class_init(ObjectClass *klass, void *data) k->init = omap2_gpio_init; dc->reset = omap2_gpif_reset; dc->props = omap2_gpio_properties; + /* Reason: pointer properties "iclk", "fclk0", ..., "fclk5" */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo omap2_gpio_info = { diff --git a/hw/i2c/omap_i2c.c b/hw/i2c/omap_i2c.c index f528b2b38e24ded9189b8d511f460c8f80681b3b..2d8e2b7839f9f5096eb59adbb224d9f903d64ac6 100644 --- a/hw/i2c/omap_i2c.c +++ b/hw/i2c/omap_i2c.c @@ -475,6 +475,8 @@ static void omap_i2c_class_init(ObjectClass *klass, void *data) k->init = omap_i2c_init; dc->props = omap_i2c_properties; dc->reset = omap_i2c_reset; + /* Reason: pointer properties "iclk", "fclk" */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo omap_i2c_info = { diff --git a/hw/i2c/smbus_eeprom.c b/hw/i2c/smbus_eeprom.c index 0154283762e680abf16c3c0b90ad0a09103a5e9e..0218f8a0ebb9feacc4448534c3b04d60975d3384 100644 --- a/hw/i2c/smbus_eeprom.c +++ b/hw/i2c/smbus_eeprom.c @@ -121,6 +121,8 @@ static void smbus_eeprom_class_initfn(ObjectClass *klass, void *data) sc->write_data = eeprom_write_data; sc->read_data = eeprom_read_data; dc->props = smbus_eeprom_properties; + /* Reason: pointer property "data" */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo smbus_eeprom_info = { diff --git a/hw/i2c/smbus_ich9.c b/hw/i2c/smbus_ich9.c index ca229789f4dc49ab47ca933beef404114a5a471b..8d47eaffc8abec5039ce840296d8750b950bb563 100644 --- a/hw/i2c/smbus_ich9.c +++ b/hw/i2c/smbus_ich9.c @@ -97,11 +97,15 @@ static void ich9_smb_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_INTEL_ICH9_6; k->revision = ICH9_A2_SMB_REVISION; k->class_id = PCI_CLASS_SERIAL_SMBUS; - dc->no_user = 1; dc->vmsd = &vmstate_ich9_smbus; dc->desc = "ICH9 SMBUS Bridge"; k->init = ich9_smbus_initfn; k->config_write = ich9_smbus_write_config; + /* + * Reason: part of ICH9 southbridge, needs to be wired up by + * pc_q35_init() + */ + dc->cannot_instantiate_with_device_add_yet = true; } i2c_bus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base) diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c index 5609063120205cff196c84d6c99ee241bc929022..e873b509a569ed74ca947b75cb5a791ae52932bb 100644 --- a/hw/i386/kvm/apic.c +++ b/hw/i386/kvm/apic.c @@ -25,9 +25,9 @@ static inline uint32_t kvm_apic_get_reg(struct kvm_lapic_state *kapic, return *((uint32_t *)(kapic->regs + (reg_id << 4))); } -void kvm_put_apic_state(DeviceState *d, struct kvm_lapic_state *kapic) +void kvm_put_apic_state(DeviceState *dev, struct kvm_lapic_state *kapic) { - APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); + APICCommonState *s = APIC_COMMON(dev); int i; memset(kapic, 0, sizeof(*kapic)); @@ -51,9 +51,9 @@ void kvm_put_apic_state(DeviceState *d, struct kvm_lapic_state *kapic) kvm_apic_set_reg(kapic, 0x3e, s->divide_conf); } -void kvm_get_apic_state(DeviceState *d, struct kvm_lapic_state *kapic) +void kvm_get_apic_state(DeviceState *dev, struct kvm_lapic_state *kapic) { - APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); + APICCommonState *s = APIC_COMMON(dev); int i, v; s->id = kvm_apic_get_reg(kapic, 0x2) >> 24; @@ -171,8 +171,10 @@ static const MemoryRegionOps kvm_apic_io_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static void kvm_apic_init(APICCommonState *s) +static void kvm_apic_realize(DeviceState *dev, Error **errp) { + APICCommonState *s = APIC_COMMON(dev); + memory_region_init_io(&s->io_memory, NULL, &kvm_apic_io_ops, s, "kvm-apic-msi", APIC_SPACE_SIZE); @@ -185,7 +187,7 @@ static void kvm_apic_class_init(ObjectClass *klass, void *data) { APICCommonClass *k = APIC_COMMON_CLASS(klass); - k->init = kvm_apic_init; + k->realize = kvm_apic_realize; k->set_base = kvm_apic_set_base; k->set_tpr = kvm_apic_set_tpr; k->get_tpr = kvm_apic_get_tpr; diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c index 383938d1bc3058be9925e942b519b4aa231c232a..892aa025f4f3df4c5e54e0c5734cc4e34c98cf8e 100644 --- a/hw/i386/kvm/clock.c +++ b/hw/i386/kvm/clock.c @@ -114,7 +114,6 @@ static void kvmclock_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = kvmclock_realize; - dc->no_user = 1; dc->vmsd = &kvmclock_vmsd; } diff --git a/hw/i386/kvm/ioapic.c b/hw/i386/kvm/ioapic.c index f11a5408255daca7f8fe8cc9d963f575e1e69804..d2a6c4cf60cfad99b73d96ccf5b8f2fd39200cc2 100644 --- a/hw/i386/kvm/ioapic.c +++ b/hw/i386/kvm/ioapic.c @@ -127,11 +127,13 @@ static void kvm_ioapic_set_irq(void *opaque, int irq, int level) apic_report_irq_delivered(delivered); } -static void kvm_ioapic_init(IOAPICCommonState *s, int instance_no) +static void kvm_ioapic_realize(DeviceState *dev, Error **errp) { + IOAPICCommonState *s = IOAPIC_COMMON(dev); + memory_region_init_reservation(&s->io_memory, NULL, "kvm-ioapic", 0x1000); - qdev_init_gpio_in(DEVICE(s), kvm_ioapic_set_irq, IOAPIC_NUM_PINS); + qdev_init_gpio_in(dev, kvm_ioapic_set_irq, IOAPIC_NUM_PINS); } static Property kvm_ioapic_properties[] = { @@ -144,7 +146,7 @@ static void kvm_ioapic_class_init(ObjectClass *klass, void *data) IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); - k->init = kvm_ioapic_init; + k->realize = kvm_ioapic_realize; k->pre_save = kvm_ioapic_get; k->post_load = kvm_ioapic_put; dc->reset = kvm_ioapic_reset; diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c index 2d876009fc1022662435041894cbe3451a51a197..44ee62a233e7d6e7cee8baac9263525e7acd1d5f 100644 --- a/hw/i386/kvmvapic.c +++ b/hw/i386/kvmvapic.c @@ -827,7 +827,6 @@ static void vapic_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - dc->no_user = 1; dc->reset = vapic_reset; dc->vmsd = &vmstate_vapic; dc->realize = vapic_realize; diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 3cd8f383f350e44dcfa10bfd4fd6349ef7ed34b9..e9831ca411f6a8b323d9382ffb5ea55eca1677bc 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -547,10 +547,15 @@ static void port92_class_initfn(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - dc->no_user = 1; dc->realize = port92_realizefn; dc->reset = port92_reset; dc->vmsd = &vmstate_port92_isa; + /* + * Reason: unlike ordinary ISA devices, this one needs additional + * wiring: its A20 output line needs to be wired up by + * port92_init(). + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo port92_info = { diff --git a/hw/ide/piix.c b/hw/ide/piix.c index ab36749417246e72ac95e4445097862df8d93181..9b5960b44e9e5cf53338c2fb607f10287e17be27 100644 --- a/hw/ide/piix.c +++ b/hw/ide/piix.c @@ -248,7 +248,6 @@ static void piix3_ide_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1; k->class_id = PCI_CLASS_STORAGE_IDE; set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); - dc->no_user = 1; } static const TypeInfo piix3_ide_info = { @@ -267,7 +266,6 @@ static void piix3_ide_xen_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_INTEL_82371SB_1; k->class_id = PCI_CLASS_STORAGE_IDE; set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); - dc->no_user = 1; dc->unplug = pci_piix3_xen_ide_unplug; } @@ -289,7 +287,6 @@ static void piix4_ide_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_INTEL_82371AB; k->class_id = PCI_CLASS_STORAGE_IDE; set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); - dc->no_user = 1; } static const TypeInfo piix4_ide_info = { diff --git a/hw/ide/via.c b/hw/ide/via.c index 99468c773e4fb555935ba2904795197c8d82ff65..198123b026b2ccc9f3dfcb1bc3e28dcbcdf9b81c 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -225,7 +225,6 @@ static void via_ide_class_init(ObjectClass *klass, void *data) k->revision = 0x06; k->class_id = PCI_CLASS_STORAGE_IDE; set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); - dc->no_user = 1; } static const TypeInfo via_ide_info = { diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index ce86237cf32fc8081cdd22aca01f558c3a9a1474..655b8c50114795a7dd100af8932a841b7c9d6ab1 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -522,7 +522,6 @@ static void i8042_class_initfn(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = i8042_realizefn; - dc->no_user = 1; dc->vmsd = &vmstate_kbd_isa; } diff --git a/hw/input/vmmouse.c b/hw/input/vmmouse.c index abd032b794c1055a42a7f44c6d844d70a6cb46c9..6a5053352a34100164f0fe14a255586165cb053b 100644 --- a/hw/input/vmmouse.c +++ b/hw/input/vmmouse.c @@ -282,10 +282,11 @@ static void vmmouse_class_initfn(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = vmmouse_realizefn; - dc->no_user = 1; dc->reset = vmmouse_reset; dc->vmsd = &vmstate_vmmouse; dc->props = vmmouse_properties; + /* Reason: pointer property "ps2_mouse" */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo vmmouse_info = { diff --git a/hw/intc/apic.c b/hw/intc/apic.c index a913186ed0443e72e54f6ca9669b3cc993f2b5c3..3d3deb6298d94a283d1532d079a7b0a32dc19cc0 100644 --- a/hw/intc/apic.c +++ b/hw/intc/apic.c @@ -171,9 +171,9 @@ static void apic_local_deliver(APICCommonState *s, int vector) } } -void apic_deliver_pic_intr(DeviceState *d, int level) +void apic_deliver_pic_intr(DeviceState *dev, int level) { - APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); + APICCommonState *s = APIC_COMMON(dev); if (level) { apic_local_deliver(s, APIC_LVT_LINT0); @@ -376,9 +376,9 @@ static void apic_update_irq(APICCommonState *s) } } -void apic_poll_irq(DeviceState *d) +void apic_poll_irq(DeviceState *dev) { - APICCommonState *s = APIC_COMMON(d); + APICCommonState *s = APIC_COMMON(dev); apic_sync_vapic(s, SYNC_FROM_VAPIC); apic_update_irq(s); @@ -482,9 +482,9 @@ static void apic_startup(APICCommonState *s, int vector_num) cpu_interrupt(CPU(s->cpu), CPU_INTERRUPT_SIPI); } -void apic_sipi(DeviceState *d) +void apic_sipi(DeviceState *dev) { - APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); + APICCommonState *s = APIC_COMMON(dev); cpu_reset_interrupt(CPU(s->cpu), CPU_INTERRUPT_SIPI); @@ -494,11 +494,11 @@ void apic_sipi(DeviceState *d) s->wait_for_sipi = 0; } -static void apic_deliver(DeviceState *d, uint8_t dest, uint8_t dest_mode, +static void apic_deliver(DeviceState *dev, uint8_t dest, uint8_t dest_mode, uint8_t delivery_mode, uint8_t vector_num, uint8_t trigger_mode) { - APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); + APICCommonState *s = APIC_COMMON(dev); uint32_t deliver_bitmask[MAX_APIC_WORDS]; int dest_shorthand = (s->icr[0] >> 18) & 3; APICCommonState *apic_iter; @@ -551,9 +551,9 @@ static bool apic_check_pic(APICCommonState *s) return true; } -int apic_get_interrupt(DeviceState *d) +int apic_get_interrupt(DeviceState *dev) { - APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); + APICCommonState *s = APIC_COMMON(dev); int intno; /* if the APIC is installed or enabled, we let the 8259 handle the @@ -585,9 +585,9 @@ int apic_get_interrupt(DeviceState *d) return intno; } -int apic_accept_pic_intr(DeviceState *d) +int apic_accept_pic_intr(DeviceState *dev) { - APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); + APICCommonState *s = APIC_COMMON(dev); uint32_t lvt0; if (!s) @@ -657,16 +657,16 @@ static void apic_mem_writew(void *opaque, hwaddr addr, uint32_t val) static uint32_t apic_mem_readl(void *opaque, hwaddr addr) { - DeviceState *d; + DeviceState *dev; APICCommonState *s; uint32_t val; int index; - d = cpu_get_current_apic(); - if (!d) { + dev = cpu_get_current_apic(); + if (!dev) { return 0; } - s = DO_UPCAST(APICCommonState, busdev.qdev, d); + s = APIC_COMMON(dev); index = (addr >> 4) & 0xff; switch(index) { @@ -752,7 +752,7 @@ static void apic_send_msi(hwaddr addr, uint32_t data) static void apic_mem_writel(void *opaque, hwaddr addr, uint32_t val) { - DeviceState *d; + DeviceState *dev; APICCommonState *s; int index = (addr >> 4) & 0xff; if (addr > 0xfff || !index) { @@ -765,11 +765,11 @@ static void apic_mem_writel(void *opaque, hwaddr addr, uint32_t val) return; } - d = cpu_get_current_apic(); - if (!d) { + dev = cpu_get_current_apic(); + if (!dev) { return; } - s = DO_UPCAST(APICCommonState, busdev.qdev, d); + s = APIC_COMMON(dev); trace_apic_mem_writel(addr, val); @@ -810,7 +810,7 @@ static void apic_mem_writel(void *opaque, hwaddr addr, uint32_t val) break; case 0x30: s->icr[0] = val; - apic_deliver(d, (s->icr[1] >> 24) & 0xff, (s->icr[0] >> 11) & 1, + apic_deliver(dev, (s->icr[1] >> 24) & 0xff, (s->icr[0] >> 11) & 1, (s->icr[0] >> 8) & 7, (s->icr[0] & 0xff), (s->icr[0] >> 15) & 1); break; @@ -871,8 +871,10 @@ static const MemoryRegionOps apic_io_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static void apic_init(APICCommonState *s) +static void apic_realize(DeviceState *dev, Error **errp) { + APICCommonState *s = APIC_COMMON(dev); + memory_region_init_io(&s->io_memory, OBJECT(s), &apic_io_ops, s, "apic-msi", APIC_SPACE_SIZE); @@ -886,7 +888,7 @@ static void apic_class_init(ObjectClass *klass, void *data) { APICCommonClass *k = APIC_COMMON_CLASS(klass); - k->init = apic_init; + k->realize = apic_realize; k->set_base = apic_set_base; k->set_tpr = apic_set_tpr; k->get_tpr = apic_get_tpr; diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c index a0beb1086315d0ca5e4dd448df03823ffc709989..c623fcc6d813d0c84ac3e27d9f974e4fcd8b20e9 100644 --- a/hw/intc/apic_common.c +++ b/hw/intc/apic_common.c @@ -27,21 +27,21 @@ static int apic_irq_delivered; bool apic_report_tpr_access; -void cpu_set_apic_base(DeviceState *d, uint64_t val) +void cpu_set_apic_base(DeviceState *dev, uint64_t val) { trace_cpu_set_apic_base(val); - if (d) { - APICCommonState *s = APIC_COMMON(d); + if (dev) { + APICCommonState *s = APIC_COMMON(dev); APICCommonClass *info = APIC_COMMON_GET_CLASS(s); info->set_base(s, val); } } -uint64_t cpu_get_apic_base(DeviceState *d) +uint64_t cpu_get_apic_base(DeviceState *dev) { - if (d) { - APICCommonState *s = APIC_COMMON(d); + if (dev) { + APICCommonState *s = APIC_COMMON(dev); trace_cpu_get_apic_base((uint64_t)s->apicbase); return s->apicbase; } else { @@ -50,39 +50,39 @@ uint64_t cpu_get_apic_base(DeviceState *d) } } -void cpu_set_apic_tpr(DeviceState *d, uint8_t val) +void cpu_set_apic_tpr(DeviceState *dev, uint8_t val) { APICCommonState *s; APICCommonClass *info; - if (!d) { + if (!dev) { return; } - s = APIC_COMMON(d); + s = APIC_COMMON(dev); info = APIC_COMMON_GET_CLASS(s); info->set_tpr(s, val); } -uint8_t cpu_get_apic_tpr(DeviceState *d) +uint8_t cpu_get_apic_tpr(DeviceState *dev) { APICCommonState *s; APICCommonClass *info; - if (!d) { + if (!dev) { return 0; } - s = APIC_COMMON(d); + s = APIC_COMMON(dev); info = APIC_COMMON_GET_CLASS(s); return info->get_tpr(s); } -void apic_enable_tpr_access_reporting(DeviceState *d, bool enable) +void apic_enable_tpr_access_reporting(DeviceState *dev, bool enable) { - APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); + APICCommonState *s = APIC_COMMON(dev); APICCommonClass *info = APIC_COMMON_GET_CLASS(s); apic_report_tpr_access = enable; @@ -91,19 +91,19 @@ void apic_enable_tpr_access_reporting(DeviceState *d, bool enable) } } -void apic_enable_vapic(DeviceState *d, hwaddr paddr) +void apic_enable_vapic(DeviceState *dev, hwaddr paddr) { - APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); + APICCommonState *s = APIC_COMMON(dev); APICCommonClass *info = APIC_COMMON_GET_CLASS(s); s->vapic_paddr = paddr; info->vapic_base_update(s); } -void apic_handle_tpr_access_report(DeviceState *d, target_ulong ip, +void apic_handle_tpr_access_report(DeviceState *dev, target_ulong ip, TPRAccess access) { - APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); + APICCommonState *s = APIC_COMMON(dev); vapic_report_tpr_access(s->vapic, CPU(s->cpu), ip, access); } @@ -129,9 +129,9 @@ int apic_get_irq_delivered(void) return apic_irq_delivered; } -void apic_deliver_nmi(DeviceState *d) +void apic_deliver_nmi(DeviceState *dev) { - APICCommonState *s = APIC_COMMON(d); + APICCommonState *s = APIC_COMMON(dev); APICCommonClass *info = APIC_COMMON_GET_CLASS(s); info->external_nmi(s); @@ -170,9 +170,9 @@ bool apic_next_timer(APICCommonState *s, int64_t current_time) return true; } -void apic_init_reset(DeviceState *d) +void apic_init_reset(DeviceState *dev) { - APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); + APICCommonState *s = APIC_COMMON(dev); int i; if (!s) { @@ -203,19 +203,19 @@ void apic_init_reset(DeviceState *d) s->timer_expiry = -1; } -void apic_designate_bsp(DeviceState *d) +void apic_designate_bsp(DeviceState *dev) { - if (d == NULL) { + if (dev == NULL) { return; } - APICCommonState *s = APIC_COMMON(d); + APICCommonState *s = APIC_COMMON(dev); s->apicbase |= MSR_IA32_APICBASE_BSP; } -static void apic_reset_common(DeviceState *d) +static void apic_reset_common(DeviceState *dev) { - APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d); + APICCommonState *s = APIC_COMMON(dev); APICCommonClass *info = APIC_COMMON_GET_CLASS(s); bool bsp; @@ -226,7 +226,7 @@ static void apic_reset_common(DeviceState *d) s->vapic_paddr = 0; info->vapic_base_update(s); - apic_init_reset(d); + apic_init_reset(dev); if (bsp) { /* @@ -284,7 +284,7 @@ static int apic_load_old(QEMUFile *f, void *opaque, int version_id) return 0; } -static int apic_init_common(ICCDevice *dev) +static void apic_common_realize(DeviceState *dev, Error **errp) { APICCommonState *s = APIC_COMMON(dev); APICCommonClass *info; @@ -293,14 +293,16 @@ static int apic_init_common(ICCDevice *dev) static bool mmio_registered; if (apic_no >= MAX_APICS) { - return -1; + error_setg(errp, "%s initialization failed.", + object_get_typename(OBJECT(dev))); + return; } s->idx = apic_no++; info = APIC_COMMON_GET_CLASS(s); - info->init(s); + info->realize(dev, errp); if (!mmio_registered) { - ICCBus *b = ICC_BUS(qdev_get_parent_bus(DEVICE(dev))); + ICCBus *b = ICC_BUS(qdev_get_parent_bus(dev)); memory_region_add_subregion(b->apic_address_space, 0, &s->io_memory); mmio_registered = true; } @@ -315,7 +317,6 @@ static int apic_init_common(ICCDevice *dev) info->enable_tpr_reporting(s, true); } - return 0; } static void apic_dispatch_pre_save(void *opaque) @@ -386,9 +387,13 @@ static void apic_common_class_init(ObjectClass *klass, void *data) dc->vmsd = &vmstate_apic_common; dc->reset = apic_reset_common; - dc->no_user = 1; dc->props = apic_properties_common; - idc->init = apic_init_common; + idc->realize = apic_common_realize; + /* + * Reason: APIC and CPU need to be wired up by + * x86_cpu_apic_create() + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo apic_common_type = { @@ -400,9 +405,9 @@ static const TypeInfo apic_common_type = { .abstract = true, }; -static void register_types(void) +static void apic_common_register_types(void) { type_register_static(&apic_common_type); } -type_init(register_types) +type_init(apic_common_register_types) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 6c5965093e29ecb3cc2d0fda82462dfed5a51c3d..9409684ce82307208e1ea5c36d51e78049ccaefd 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -709,7 +709,6 @@ static void arm_gic_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); ARMGICClass *agc = ARM_GIC_CLASS(klass); - dc->no_user = 1; agc->parent_realize = dc->realize; dc->realize = arm_gic_realize; } diff --git a/hw/intc/arm_gic_common.c b/hw/intc/arm_gic_common.c index 710607b044cb61fe5a2e5d5d6a1d9a52ab4448ee..e4fc65028ac38258bcd332a9c696cf66cf1b87ba 100644 --- a/hw/intc/arm_gic_common.c +++ b/hw/intc/arm_gic_common.c @@ -156,7 +156,6 @@ static void arm_gic_common_class_init(ObjectClass *klass, void *data) dc->realize = arm_gic_common_realize; dc->props = arm_gic_common_properties; dc->vmsd = &vmstate_gic; - dc->no_user = 1; } static const TypeInfo arm_gic_common_type = { diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c index f71397542a64b69646eafe84ad4de2ac445f8ee7..59a3da5a6b7290e4c09e9398c12a3db5ddf2a64b 100644 --- a/hw/intc/arm_gic_kvm.c +++ b/hw/intc/arm_gic_kvm.c @@ -150,7 +150,6 @@ static void kvm_arm_gic_class_init(ObjectClass *klass, void *data) kgc->parent_reset = dc->reset; dc->realize = kvm_arm_gic_realize; dc->reset = kvm_arm_gic_reset; - dc->no_user = 1; } static const TypeInfo kvm_arm_gic_info = { diff --git a/hw/intc/etraxfs_pic.c b/hw/intc/etraxfs_pic.c index e02da533cbed93d526b82dde9e935049f80a83b9..636262b49fd63d3d8e266fae4674d5af598c0646 100644 --- a/hw/intc/etraxfs_pic.c +++ b/hw/intc/etraxfs_pic.c @@ -170,6 +170,10 @@ static void etraxfs_pic_class_init(ObjectClass *klass, void *data) k->init = etraxfs_pic_init; dc->props = etraxfs_pic_properties; + /* + * Note: pointer property "interrupt_vector" may remain null, thus + * no need for dc->cannot_instantiate_with_device_add_yet = true; + */ } static const TypeInfo etraxfs_pic_info = { diff --git a/hw/intc/grlib_irqmp.c b/hw/intc/grlib_irqmp.c index 42e00bc4b8a7c8aa3b1f6c590f7f4ceef391c733..d1813f76b61c7583f0e7cd70b0ffe40fce4e68c2 100644 --- a/hw/intc/grlib_irqmp.c +++ b/hw/intc/grlib_irqmp.c @@ -355,6 +355,8 @@ static void grlib_irqmp_class_init(ObjectClass *klass, void *data) k->init = grlib_irqmp_init; dc->reset = grlib_irqmp_reset; dc->props = grlib_irqmp_properties; + /* Reason: pointer properties "set_pil_in", "set_pil_in_opaque" */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo grlib_irqmp_info = { diff --git a/hw/intc/i8259_common.c b/hw/intc/i8259_common.c index 803d037f68be9899161b09f79a455b45560dfc18..9d293999bebddabd66c80d75f13d22b0253c2eae 100644 --- a/hw/intc/i8259_common.c +++ b/hw/intc/i8259_common.c @@ -135,9 +135,15 @@ static void pic_common_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); dc->vmsd = &vmstate_pic_common; - dc->no_user = 1; dc->props = pic_properties_common; dc->realize = pic_common_realize; + /* + * Reason: unlike ordinary ISA devices, the PICs need additional + * wiring: its IRQ input lines are set up by board code, and the + * wiring of the slave to the master is hard-coded in device model + * code. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo pic_common_type = { diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c index d866e00297ddab4efc3c187f0f21fe9bca181017..652dd47a1c1ec2658f5783274dcc30acff985799 100644 --- a/hw/intc/ioapic.c +++ b/hw/intc/ioapic.c @@ -36,6 +36,9 @@ static IOAPICCommonState *ioapics[MAX_IOAPICS]; +/* global variable from ioapic_common.c */ +extern int ioapic_no; + static void ioapic_service(IOAPICCommonState *s) { uint8_t i; @@ -225,14 +228,16 @@ static const MemoryRegionOps ioapic_io_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static void ioapic_init(IOAPICCommonState *s, int instance_no) +static void ioapic_realize(DeviceState *dev, Error **errp) { + IOAPICCommonState *s = IOAPIC_COMMON(dev); + memory_region_init_io(&s->io_memory, OBJECT(s), &ioapic_io_ops, s, "ioapic", 0x1000); - qdev_init_gpio_in(DEVICE(s), ioapic_set_irq, IOAPIC_NUM_PINS); + qdev_init_gpio_in(dev, ioapic_set_irq, IOAPIC_NUM_PINS); - ioapics[instance_no] = s; + ioapics[ioapic_no] = s; } static void ioapic_class_init(ObjectClass *klass, void *data) @@ -240,7 +245,7 @@ static void ioapic_class_init(ObjectClass *klass, void *data) IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); - k->init = ioapic_init; + k->realize = ioapic_realize; dc->reset = ioapic_reset_common; } diff --git a/hw/intc/ioapic_common.c b/hw/intc/ioapic_common.c index 6b705c15467d0da20fa18130f9bd75904dbff71a..4d3d309b62888d40df8ad66926e42c826ff15377 100644 --- a/hw/intc/ioapic_common.c +++ b/hw/intc/ioapic_common.c @@ -23,6 +23,14 @@ #include "hw/i386/ioapic_internal.h" #include "hw/sysbus.h" +/* ioapic_no count start from 0 to MAX_IOAPICS, + * remove as static variable from ioapic_common_init. + * now as a global variable, let child to increase the counter + * then we can drop the 'instance_no' argument + * and convert to our QOM's realize function + */ +int ioapic_no; + void ioapic_reset_common(DeviceState *dev) { IOAPICCommonState *s = IOAPIC_COMMON(dev); @@ -61,7 +69,6 @@ static void ioapic_common_realize(DeviceState *dev, Error **errp) { IOAPICCommonState *s = IOAPIC_COMMON(dev); IOAPICCommonClass *info; - static int ioapic_no; if (ioapic_no >= MAX_IOAPICS) { error_setg(errp, "Only %d ioapics allowed", MAX_IOAPICS); @@ -69,7 +76,7 @@ static void ioapic_common_realize(DeviceState *dev, Error **errp) } info = IOAPIC_COMMON_GET_CLASS(s); - info->init(s, ioapic_no); + info->realize(dev, errp); sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->io_memory); ioapic_no++; @@ -98,7 +105,6 @@ static void ioapic_common_class_init(ObjectClass *klass, void *data) dc->realize = ioapic_common_realize; dc->vmsd = &vmstate_ioapic_common; - dc->no_user = 1; } static const TypeInfo ioapic_common_type = { @@ -110,9 +116,9 @@ static const TypeInfo ioapic_common_type = { .abstract = true, }; -static void register_types(void) +static void ioapic_common_register_types(void) { type_register_static(&ioapic_common_type); } -type_init(register_types) +type_init(ioapic_common_register_types) diff --git a/hw/intc/omap_intc.c b/hw/intc/omap_intc.c index 7dd63da802920cb0e4a1796f4bfd4d9c86a99393..ad3931c1125ee966d6f02cabadf8089932f56069 100644 --- a/hw/intc/omap_intc.c +++ b/hw/intc/omap_intc.c @@ -392,6 +392,8 @@ static void omap_intc_class_init(ObjectClass *klass, void *data) k->init = omap_intc_init; dc->reset = omap_inth_reset; dc->props = omap_intc_properties; + /* Reason: pointer property "clk" */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo omap_intc_info = { @@ -637,6 +639,8 @@ static void omap2_intc_class_init(ObjectClass *klass, void *data) k->init = omap2_intc_init; dc->reset = omap_inth_reset; dc->props = omap2_intc_properties; + /* Reason: pointer property "iclk", "fclk" */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo omap2_intc_info = { diff --git a/hw/intc/pl190.c b/hw/intc/pl190.c index 329680da3a9fdba360d0a1102ed6b609a71a5349..2bf359a76b05d92cab2e3ca40017a33677582a62 100644 --- a/hw/intc/pl190.c +++ b/hw/intc/pl190.c @@ -273,7 +273,6 @@ static void pl190_class_init(ObjectClass *klass, void *data) SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); k->init = pl190_init; - dc->no_user = 1; dc->reset = pl190_reset; dc->vmsd = &vmstate_pl190; } diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c index 9e104eb9a7ca804b4301497cac8b8dccb50979ad..55d01008d3827fafed2d71266b34e4273b3a9b09 100644 --- a/hw/isa/isa-bus.c +++ b/hw/isa/isa-bus.c @@ -197,7 +197,6 @@ static void isabus_bridge_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); dc->fw_name = "isa"; - dc->no_user = 1; } static const TypeInfo isabus_bridge_info = { diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index 19b2198fa681eca6ec814ce09384fc8bd859ecda..51ce12dad64495ab1ba58ac46c5e1378ca6128eb 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -644,14 +644,17 @@ static void ich9_lpc_class_init(ObjectClass *klass, void *data) dc->reset = ich9_lpc_reset; k->init = ich9_lpc_initfn; dc->vmsd = &vmstate_ich9_lpc; - dc->no_user = 1; k->config_write = ich9_lpc_config_write; dc->desc = "ICH9 LPC bridge"; k->vendor_id = PCI_VENDOR_ID_INTEL; k->device_id = PCI_DEVICE_ID_INTEL_ICH9_8; k->revision = ICH9_A2_LPC_REVISION; k->class_id = PCI_CLASS_BRIDGE_ISA; - + /* + * Reason: part of ICH9 southbridge, needs to be wired up by + * pc_q35_init() + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo ich9_lpc_info = { diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c index 1a1d4518ceeaec5d7c15d5e81675e7c8f7e80bd0..def6fe3a0f3d9afd2e4b3289a1a6887c96c887cb 100644 --- a/hw/isa/piix4.c +++ b/hw/isa/piix4.c @@ -113,8 +113,12 @@ static void piix4_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_INTEL_82371AB_0; k->class_id = PCI_CLASS_BRIDGE_ISA; dc->desc = "ISA bridge"; - dc->no_user = 1; dc->vmsd = &vmstate_piix4; + /* + * Reason: part of PIIX4 southbridge, needs to be wired up, + * e.g. by mips_malta_init() + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo piix4_info = { diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 5fb808630fff91f3880e06b8ad688c88a24d4143..e639357db3607772c0ca57ffe66ab9c9cdd2d9c3 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -480,8 +480,12 @@ static void via_class_init(ObjectClass *klass, void *data) k->class_id = PCI_CLASS_BRIDGE_ISA; k->revision = 0x40; dc->desc = "ISA bridge"; - dc->no_user = 1; dc->vmsd = &vmstate_via; + /* + * Reason: part of VIA VT82C686 southbridge, needs to be wired up, + * e.g. by mips_fulong2e_init() + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo via_info = { diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c index 3da2e67098f28033f4d5b5af5ad57ed34238cc03..6398514c99d2b15cd047149c8457717e352e9347 100644 --- a/hw/mips/gt64xxx_pci.c +++ b/hw/mips/gt64xxx_pci.c @@ -1151,12 +1151,18 @@ static int gt64120_pci_init(PCIDevice *d) static void gt64120_pci_class_init(ObjectClass *klass, void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); k->init = gt64120_pci_init; k->vendor_id = PCI_VENDOR_ID_MARVELL; k->device_id = PCI_DEVICE_ID_MARVELL_GT6412X; k->revision = 0x10; k->class_id = PCI_CLASS_BRIDGE_HOST; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo gt64120_pci_info = { diff --git a/hw/misc/arm_l2x0.c b/hw/misc/arm_l2x0.c index 8e192cdf83bec1193d5880074279ce1269e2cad9..9e220c9a56a966b64457b4e1b3af84ebb6b45f73 100644 --- a/hw/misc/arm_l2x0.c +++ b/hw/misc/arm_l2x0.c @@ -179,7 +179,6 @@ static void l2x0_class_init(ObjectClass *klass, void *data) k->init = l2x0_priv_init; dc->vmsd = &vmstate_l2x0; - dc->no_user = 1; dc->props = l2x0_properties; dc->reset = l2x0_priv_reset; } diff --git a/hw/misc/vmport.c b/hw/misc/vmport.c index 0b5a5644e44765089b0c3e3dac37bc32be986c7b..cd5716a46d4fdc0754a66445d10a8b1cfed7873b 100644 --- a/hw/misc/vmport.c +++ b/hw/misc/vmport.c @@ -162,7 +162,8 @@ static void vmport_class_initfn(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = vmport_realizefn; - dc->no_user = 1; + /* Reason: realize sets global port_state */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo vmport_info = { diff --git a/hw/net/etraxfs_eth.c b/hw/net/etraxfs_eth.c index 78ebbbca72d7ecf7eea9038e652f476bde3edc19..6a3c86db487eb9a6c4a74e0c27df9631b4d08a77 100644 --- a/hw/net/etraxfs_eth.c +++ b/hw/net/etraxfs_eth.c @@ -646,6 +646,8 @@ static void etraxfs_eth_class_init(ObjectClass *klass, void *data) k->init = fs_eth_init; dc->props = etraxfs_eth_properties; + /* Reason: pointer properties "dma_out", "dma_in" */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo etraxfs_eth_info = { diff --git a/hw/net/lance.c b/hw/net/lance.c index e339f029b7d0321d06b7b3b2be9e6c755d412230..fe18564e1ea6f7bd8e66904b8b3ff9c87ceadd54 100644 --- a/hw/net/lance.c +++ b/hw/net/lance.c @@ -161,6 +161,8 @@ static void lance_class_init(ObjectClass *klass, void *data) dc->reset = lance_reset; dc->vmsd = &vmstate_lance; dc->props = lance_properties; + /* Reason: pointer property "dma" */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo lance_info = { diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index f5dc3ea8459d31f2a36d97ec0bfa82e951ede25d..ee96c1681b068bb3898e11d5b1366bc77b5e07d8 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -599,7 +599,6 @@ static void fw_cfg_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = fw_cfg_realize; - dc->no_user = 1; dc->reset = fw_cfg_reset; dc->vmsd = &vmstate_fw_cfg; dc->props = fw_cfg_properties; diff --git a/hw/pci-bridge/dec.c b/hw/pci-bridge/dec.c index e5e3be829ffa3856add21cbbebad592b71676ac3..a6ca940d553124c971180053a6e0a467d19e4ad5 100644 --- a/hw/pci-bridge/dec.c +++ b/hw/pci-bridge/dec.c @@ -116,6 +116,7 @@ static int dec_21154_pci_host_init(PCIDevice *d) static void dec_21154_pci_host_class_init(ObjectClass *klass, void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); k->init = dec_21154_pci_host_init; k->vendor_id = PCI_VENDOR_ID_DEC; @@ -123,6 +124,11 @@ static void dec_21154_pci_host_class_init(ObjectClass *klass, void *data) k->revision = 0x02; k->class_id = PCI_CLASS_BRIDGE_PCI; k->is_bridge = 1; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo dec_21154_pci_host_info = { diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c index 92f289f8f9b9e66493b08ac3fdf0ae2eb0ff0f4b..1b399ddbc3e50eee680e6171a6d1138f59d895e3 100644 --- a/hw/pci-host/apb.c +++ b/hw/pci-host/apb.c @@ -516,11 +516,17 @@ static int pbm_pci_host_init(PCIDevice *d) static void pbm_pci_host_class_init(ObjectClass *klass, void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); k->init = pbm_pci_host_init; k->vendor_id = PCI_VENDOR_ID_SUN; k->device_id = PCI_DEVICE_ID_SUN_SABRE; k->class_id = PCI_CLASS_BRIDGE_HOST; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo pbm_pci_host_info = { diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c index 5086d42c13d57cf448769d9c981d287adab606bd..902441f10b2fe5bb9d35e0cbdeab285aeee0c6ca 100644 --- a/hw/pci-host/bonito.c +++ b/hw/pci-host/bonito.c @@ -806,8 +806,12 @@ static void bonito_class_init(ObjectClass *klass, void *data) k->revision = 0x01; k->class_id = PCI_CLASS_BRIDGE_HOST; dc->desc = "Host bridge"; - dc->no_user = 1; dc->vmsd = &vmstate_bonito; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo bonito_info = { @@ -819,11 +823,9 @@ static const TypeInfo bonito_info = { static void bonito_pcihost_class_init(ObjectClass *klass, void *data) { - DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); k->init = bonito_pcihost_initfn; - dc->no_user = 1; } static const TypeInfo bonito_pcihost_info = { diff --git a/hw/pci-host/grackle.c b/hw/pci-host/grackle.c index 75b60d36acef60034a51936e3b331bde9a1360a8..6c7cfdbeb26d1943e6e0d3bfd3221831926f7f64 100644 --- a/hw/pci-host/grackle.c +++ b/hw/pci-host/grackle.c @@ -130,7 +130,11 @@ static void grackle_pci_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_MOTOROLA_MPC106; k->revision = 0x00; k->class_id = PCI_CLASS_BRIDGE_HOST; - dc->no_user = 1; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo grackle_pci_info = { @@ -143,10 +147,8 @@ static const TypeInfo grackle_pci_info = { static void pci_grackle_class_init(ObjectClass *klass, void *data) { SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - DeviceClass *dc = DEVICE_CLASS(klass); k->init = pci_grackle_init_device; - dc->no_user = 1; } static const TypeInfo grackle_pci_host_info = { diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c index 63be7f6cee42000f5a397410c1ec4b42d1500faa..cc97150a90a66e8e0c9f4fa3c081a3a2d56bd64a 100644 --- a/hw/pci-host/piix.c +++ b/hw/pci-host/piix.c @@ -635,7 +635,6 @@ static void piix3_class_init(ObjectClass *klass, void *data) dc->desc = "ISA bridge"; dc->vmsd = &vmstate_piix3; - dc->no_user = 1, k->no_hotplug = 1; k->init = piix3_initfn; k->config_write = piix3_write_config; @@ -643,6 +642,11 @@ static void piix3_class_init(ObjectClass *klass, void *data) /* 82371SB PIIX3 PCI-to-ISA bridge (Step A1) */ k->device_id = PCI_DEVICE_ID_INTEL_82371SB_0; k->class_id = PCI_CLASS_BRIDGE_ISA; + /* + * Reason: part of PIIX3 southbridge, needs to be wired up by + * pc_piix.c's pc_init1() + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo piix3_info = { @@ -659,7 +663,6 @@ static void piix3_xen_class_init(ObjectClass *klass, void *data) dc->desc = "ISA bridge"; dc->vmsd = &vmstate_piix3; - dc->no_user = 1; k->no_hotplug = 1; k->init = piix3_initfn; k->config_write = piix3_write_config_xen; @@ -667,6 +670,11 @@ static void piix3_xen_class_init(ObjectClass *klass, void *data) /* 82371SB PIIX3 PCI-to-ISA bridge (Step A1) */ k->device_id = PCI_DEVICE_ID_INTEL_82371SB_0; k->class_id = PCI_CLASS_BRIDGE_ISA; + /* + * Reason: part of PIIX3 southbridge, needs to be wired up by + * pc_piix.c's pc_init1() + */ + dc->cannot_instantiate_with_device_add_yet = true; }; static const TypeInfo piix3_xen_info = { @@ -689,8 +697,12 @@ static void i440fx_class_init(ObjectClass *klass, void *data) k->revision = 0x02; k->class_id = PCI_CLASS_BRIDGE_HOST; dc->desc = "Host bridge"; - dc->no_user = 1; dc->vmsd = &vmstate_i440fx; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo i440fx_info = { @@ -727,7 +739,6 @@ static void i440fx_pcihost_class_init(ObjectClass *klass, void *data) hc->root_bus_path = i440fx_pcihost_root_bus_path; dc->realize = i440fx_pcihost_realize; dc->fw_name = "pci"; - dc->no_user = 1; dc->props = i440fx_props; } diff --git a/hw/pci-host/ppce500.c b/hw/pci-host/ppce500.c index f00793d819e2c6b60195d3ce676a8401a026bbad..c80b7cb2f55220fbca2ac9579f0f86565cda65e5 100644 --- a/hw/pci-host/ppce500.c +++ b/hw/pci-host/ppce500.c @@ -387,6 +387,11 @@ static void e500_host_bridge_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_MPC8533E; k->class_id = PCI_CLASS_PROCESSOR_POWERPC; dc->desc = "Host bridge"; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo e500_host_bridge_info = { diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c index 0e71fdbfb110fe1a5d06dcc6348216eeca365d63..042dc8f225cf36839ecff3917f4ad70245352274 100644 --- a/hw/pci-host/prep.c +++ b/hw/pci-host/prep.c @@ -198,7 +198,11 @@ static void raven_class_init(ObjectClass *klass, void *data) k->class_id = PCI_CLASS_BRIDGE_HOST; dc->desc = "PReP Host Bridge - Motorola Raven"; dc->vmsd = &vmstate_raven; - dc->no_user = 1; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo raven_info = { @@ -215,7 +219,6 @@ static void raven_pcihost_class_init(ObjectClass *klass, void *data) set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); dc->realize = raven_pcihost_realizefn; dc->fw_name = "pci"; - dc->no_user = 1; } static const TypeInfo raven_pcihost_info = { diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c index 81c82404d6a99ff671cfdb3ed3d1cdabeac0c334..4bc2e0118ee70fcf057db63d76ed2b6a785d1b3d 100644 --- a/hw/pci-host/q35.c +++ b/hw/pci-host/q35.c @@ -403,6 +403,11 @@ static void mch_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_INTEL_Q35_MCH; k->revision = MCH_HOST_BRIDGE_REVISION_DEFAULT; k->class_id = PCI_CLASS_BRIDGE_HOST; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo mch_info = { diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c index adc1d89010c93f3bde4aeb3c91364abd869256a9..e72fe2a70b954bf5675ad0c8735fea6bad665be6 100644 --- a/hw/pci-host/uninorth.c +++ b/hw/pci-host/uninorth.c @@ -351,12 +351,18 @@ static int unin_internal_pci_host_init(PCIDevice *d) static void unin_main_pci_host_class_init(ObjectClass *klass, void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); k->init = unin_main_pci_host_init; k->vendor_id = PCI_VENDOR_ID_APPLE; k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_PCI; k->revision = 0x00; k->class_id = PCI_CLASS_BRIDGE_HOST; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo unin_main_pci_host_info = { @@ -369,12 +375,18 @@ static const TypeInfo unin_main_pci_host_info = { static void u3_agp_pci_host_class_init(ObjectClass *klass, void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); k->init = u3_agp_pci_host_init; k->vendor_id = PCI_VENDOR_ID_APPLE; k->device_id = PCI_DEVICE_ID_APPLE_U3_AGP; k->revision = 0x00; k->class_id = PCI_CLASS_BRIDGE_HOST; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo u3_agp_pci_host_info = { @@ -387,12 +399,18 @@ static const TypeInfo u3_agp_pci_host_info = { static void unin_agp_pci_host_class_init(ObjectClass *klass, void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); k->init = unin_agp_pci_host_init; k->vendor_id = PCI_VENDOR_ID_APPLE; k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP; k->revision = 0x00; k->class_id = PCI_CLASS_BRIDGE_HOST; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo unin_agp_pci_host_info = { @@ -405,12 +423,18 @@ static const TypeInfo unin_agp_pci_host_info = { static void unin_internal_pci_host_class_init(ObjectClass *klass, void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); k->init = unin_internal_pci_host_init; k->vendor_id = PCI_VENDOR_ID_APPLE; k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_I_PCI; k->revision = 0x00; k->class_id = PCI_CLASS_BRIDGE_HOST; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo unin_internal_pci_host_info = { diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c index 6b28929d26a523c9f80db8cc396cedcb52ddd1c4..71ff0de303c86a36a5caa33d9cb36adeac737830 100644 --- a/hw/pci-host/versatile.c +++ b/hw/pci-host/versatile.c @@ -467,11 +467,17 @@ static int versatile_pci_host_init(PCIDevice *d) static void versatile_pci_host_class_init(ObjectClass *klass, void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); k->init = versatile_pci_host_init; k->vendor_id = PCI_VENDOR_ID_XILINX; k->device_id = PCI_DEVICE_ID_XILINX_XC2VP30; k->class_id = PCI_CLASS_PROCESSOR_CO; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo versatile_pci_host_info = { diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c index f72872ebcf1cd4c9a6284771e9a4fe757431f92b..355c3e1b068fd439fff0dc91b4f5dd127694716b 100644 --- a/hw/pci/pci_bridge.c +++ b/hw/pci/pci_bridge.c @@ -391,7 +391,7 @@ void pci_bridge_exitfn(PCIDevice *pci_dev) pci_bridge_region_cleanup(s, s->windows); memory_region_destroy(&s->address_space_mem); memory_region_destroy(&s->address_space_io); - /* qbus_free() is called automatically during device deletion */ + /* object_unparent() is called automatically during device deletion */ } /* diff --git a/hw/ppc/ppc4xx_pci.c b/hw/ppc/ppc4xx_pci.c index d2d6f65e6ce0d45c1b06963717834920644ebf43..4cb78518a38c20e5e72863370daac95220203c98 100644 --- a/hw/ppc/ppc4xx_pci.c +++ b/hw/ppc/ppc4xx_pci.c @@ -380,6 +380,11 @@ static void ppc4xx_host_bridge_class_init(ObjectClass *klass, void *data) k->vendor_id = PCI_VENDOR_ID_IBM; k->device_id = PCI_DEVICE_ID_IBM_440GX; k->class_id = PCI_CLASS_BRIDGE_OTHER; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo ppc4xx_host_bridge_info = { diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c index fee6195f95716d015d32974b33297a5426b99f53..4e33f462d9aa71fd81f8c1ff4ab11d9c244fd69e 100644 --- a/hw/ppc/spapr_vio.c +++ b/hw/ppc/spapr_vio.c @@ -528,11 +528,9 @@ static int spapr_vio_bridge_init(SysBusDevice *dev) static void spapr_vio_bridge_class_init(ObjectClass *klass, void *data) { - DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); k->init = spapr_vio_bridge_init; - dc->no_user = 1; } static const TypeInfo spapr_vio_bridge_info = { diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c index 65d39da314fc1ca31315f011b57362ffa8c629d2..1a6397b88e8173eef1f833e3782ebe808f3e8cb9 100644 --- a/hw/s390x/ipl.c +++ b/hw/s390x/ipl.c @@ -182,7 +182,6 @@ static void s390_ipl_class_init(ObjectClass *klass, void *data) k->init = s390_ipl_init; dc->props = s390_ipl_properties; dc->reset = s390_ipl_reset; - dc->no_user = 1; } static const TypeInfo s390_ipl_info = { diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c index 6a831114da4666cbaa4c2a237a00ff0d606cdba7..46c5ff1898719a21b04b8c495a09943e72b4b097 100644 --- a/hw/s390x/s390-virtio-bus.c +++ b/hw/s390x/s390-virtio-bus.c @@ -676,11 +676,9 @@ static int s390_virtio_bridge_init(SysBusDevice *dev) static void s390_virtio_bridge_class_init(ObjectClass *klass, void *data) { - DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); k->init = s390_virtio_bridge_init; - dc->no_user = 1; } static const TypeInfo s390_virtio_bridge_info = { diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index ecc80ecaf72c9665d005180651648df8120f6260..4b6250dda99da38c686a2372779fe89f229fa5c5 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -1283,11 +1283,9 @@ static int virtual_css_bridge_init(SysBusDevice *dev) static void virtual_css_bridge_class_init(ObjectClass *klass, void *data) { - DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); k->init = virtual_css_bridge_init; - dc->no_user = 1; } static const TypeInfo virtual_css_bridge_info = { diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c index c35896d28c786563378d49a3565a244ffcf8bccb..462558b76daaa88f73ad136eaaa504b6b3e88105 100644 --- a/hw/sd/pl181.c +++ b/hw/sd/pl181.c @@ -506,7 +506,6 @@ static void pl181_class_init(ObjectClass *klass, void *data) sdc->init = pl181_init; k->vmsd = &vmstate_pl181; k->reset = pl181_reset; - k->no_user = 1; } static const TypeInfo pl181_info = { diff --git a/hw/sh4/sh_pci.c b/hw/sh4/sh_pci.c index e81176a11ea7b8411342295749d8f986609781a5..a2f6d9e0b62ca397cb0de16972221008338c7345 100644 --- a/hw/sh4/sh_pci.c +++ b/hw/sh4/sh_pci.c @@ -162,10 +162,16 @@ static int sh_pci_host_init(PCIDevice *d) static void sh_pci_host_class_init(ObjectClass *klass, void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); k->init = sh_pci_host_init; k->vendor_id = PCI_VENDOR_ID_HITACHI; k->device_id = PCI_DEVICE_ID_HITACHI_SH7751R; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo sh_pci_host_info = { diff --git a/hw/timer/arm_mptimer.c b/hw/timer/arm_mptimer.c index d9f9494f269bc53c670932289b39b59a98a00c1d..35a0a2356f012e54baec1cc2f5e7d7d136855e33 100644 --- a/hw/timer/arm_mptimer.c +++ b/hw/timer/arm_mptimer.c @@ -274,7 +274,6 @@ static void arm_mptimer_class_init(ObjectClass *klass, void *data) dc->realize = arm_mptimer_realize; dc->vmsd = &vmstate_arm_mptimer; dc->reset = arm_mptimer_reset; - dc->no_user = 1; dc->props = arm_mptimer_properties; } diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c index bb3bf98745612904dbdefada702298fdd1e9d0ef..2fbbeb1735b74a11b1569857565309039672a3b5 100644 --- a/hw/timer/hpet.c +++ b/hw/timer/hpet.c @@ -765,7 +765,6 @@ static void hpet_device_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = hpet_realize; - dc->no_user = 1; dc->reset = hpet_reset; dc->vmsd = &vmstate_hpet; dc->props = hpet_device_properties; diff --git a/hw/timer/i8254_common.c b/hw/timer/i8254_common.c index e8fb971488b014bc592cd306536583816ca88bb3..9db5c9d12989917c615f228adfc50c50943fcf67 100644 --- a/hw/timer/i8254_common.c +++ b/hw/timer/i8254_common.c @@ -282,7 +282,12 @@ static void pit_common_class_init(ObjectClass *klass, void *data) dc->realize = pit_common_realize; dc->vmsd = &vmstate_pit_common; - dc->no_user = 1; + /* + * Reason: unlike ordinary ISA devices, the PIT may need to be + * wired to the HPET, and because of that, some wiring is always + * done by board code. + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo pit_common_type = { diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c index be0592b53dcb8d4f0cb4bb18092faa262e66aa19..3cfb18a8b33b58ff3044084fd27a4df7b200d0b4 100644 --- a/hw/timer/m48t59.c +++ b/hw/timer/m48t59.c @@ -750,9 +750,10 @@ static void m48t59_isa_class_init(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = m48t59_isa_realize; - dc->no_user = 1; dc->reset = m48t59_reset_isa; dc->props = m48t59_isa_properties; + /* Reason: needs to be wired up by m48t59_init_isa() */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo m48t59_isa_info = { diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c index b0116381c0e1ab7610b0fd6ad0343030ec5ef4ac..6fb124feadb90412d95aa3e3ea3b011961b1336e 100644 --- a/hw/timer/mc146818rtc.c +++ b/hw/timer/mc146818rtc.c @@ -899,9 +899,10 @@ static void rtc_class_initfn(ObjectClass *klass, void *data) DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = rtc_realizefn; - dc->no_user = 1; dc->vmsd = &vmstate_rtc; dc->props = mc146818rtc_properties; + /* Reason: needs to be wired up by rtc_init() */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo mc146818rtc_info = { diff --git a/hw/timer/pl031.c b/hw/timer/pl031.c index 65928a48191fade1efa5b114db9eeaf052010b99..34d9b44e7e3664def811717fa2e3c305e7005f14 100644 --- a/hw/timer/pl031.c +++ b/hw/timer/pl031.c @@ -251,7 +251,6 @@ static void pl031_class_init(ObjectClass *klass, void *data) SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); k->init = pl031_init; - dc->no_user = 1; dc->vmsd = &vmstate_pl031; } diff --git a/hw/xen/xen_apic.c b/hw/xen/xen_apic.c index 9f91e0f0c9625e2926e90309cd2d6c8360c085d6..63bb7f77c6002104b1b387c7dcb6e5d2eb3d8714 100644 --- a/hw/xen/xen_apic.c +++ b/hw/xen/xen_apic.c @@ -36,8 +36,10 @@ static const MemoryRegionOps xen_apic_io_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static void xen_apic_init(APICCommonState *s) +static void xen_apic_realize(DeviceState *dev, Error **errp) { + APICCommonState *s = APIC_COMMON(dev); + memory_region_init_io(&s->io_memory, OBJECT(s), &xen_apic_io_ops, s, "xen-apic-msi", APIC_SPACE_SIZE); @@ -72,7 +74,7 @@ static void xen_apic_class_init(ObjectClass *klass, void *data) { APICCommonClass *k = APIC_COMMON_CLASS(klass); - k->init = xen_apic_init; + k->realize = xen_apic_realize; k->set_base = xen_apic_set_base; k->set_tpr = xen_apic_set_tpr; k->get_tpr = xen_apic_get_tpr; diff --git a/include/hw/cpu/icc_bus.h b/include/hw/cpu/icc_bus.h index b5500708dca7e34b3ad6feb9e8a824b747215b15..98a979fa1cdf1672b90470825ba35d960813f02e 100644 --- a/include/hw/cpu/icc_bus.h +++ b/include/hw/cpu/icc_bus.h @@ -66,7 +66,7 @@ typedef struct ICCDeviceClass { DeviceClass parent_class; /*< public >*/ - int (*init)(ICCDevice *dev); /* TODO replace with QOM realize */ + DeviceRealize realize; } ICCDeviceClass; #define TYPE_ICC_DEVICE "icc-device" diff --git a/include/hw/i386/apic_internal.h b/include/hw/i386/apic_internal.h index 1b0a7fbfad80ec59239b4805c09d91cfd9400829..70542a6f43c6c6839639a512197ee4157fa61bde 100644 --- a/include/hw/i386/apic_internal.h +++ b/include/hw/i386/apic_internal.h @@ -80,7 +80,7 @@ typedef struct APICCommonClass { ICCDeviceClass parent_class; - void (*init)(APICCommonState *s); + DeviceRealize realize; void (*set_base)(APICCommonState *s, uint64_t val); void (*set_tpr)(APICCommonState *s, uint8_t val); uint8_t (*get_tpr)(APICCommonState *s); diff --git a/include/hw/i386/ioapic_internal.h b/include/hw/i386/ioapic_internal.h index 25576c819e5bb7b63f6f17c2f91954fc05000760..3be33521851cc545387281ea33d192b6da43f3a0 100644 --- a/include/hw/i386/ioapic_internal.h +++ b/include/hw/i386/ioapic_internal.h @@ -83,7 +83,8 @@ typedef struct IOAPICCommonState IOAPICCommonState; typedef struct IOAPICCommonClass { SysBusDeviceClass parent_class; - void (*init)(IOAPICCommonState *s, int instance_no); + + DeviceRealize realize; void (*pre_save)(IOAPICCommonState *s); void (*post_load)(IOAPICCommonState *s); } IOAPICCommonClass; diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index f2043a69c2c982a2cd8239cd3c898af4c10002d3..651c3e54eea492dea70decdd916c2cb3103227e7 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -97,7 +97,18 @@ typedef struct DeviceClass { const char *fw_name; const char *desc; Property *props; - int no_user; + + /* + * Shall we hide this device model from -device / device_add? + * All devices should support instantiation with device_add, and + * this flag should not exist. But we're not there, yet. Some + * devices fail to instantiate with cryptic error messages. + * Others instantiate, but don't work. Exposing users to such + * behavior would be cruel; this flag serves to protect them. It + * should never be set without a comment explaining why it is set. + * TODO remove once we're there + */ + bool cannot_instantiate_with_device_add_yet; /* callbacks */ void (*reset)(DeviceState *dev); @@ -272,8 +283,6 @@ void qdev_reset_all(DeviceState *dev); void qbus_reset_all(BusState *bus); void qbus_reset_all_fn(void *opaque); -void qbus_free(BusState *bus); - /* This should go away once we get rid of the NULL bus hack */ BusState *sysbus_get_default(void); diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index 692f82e9355dbb6d70f697bd39656379ba61bb3f..77c6f7c03799f390a90fb1d5685f233078cd1ca8 100644 --- a/include/hw/qdev-properties.h +++ b/include/hw/qdev-properties.h @@ -122,8 +122,25 @@ extern PropertyInfo qdev_prop_arraylen; #define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d) \ DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t) +/* + * Please avoid pointer properties. If you must use them, you must + * cover them in their device's class init function as follows: + * + * - If the property must be set, the device cannot be used with + * device_add, so add code like this: + * |* Reason: pointer property "NAME-OF-YOUR-PROP" *| + * DeviceClass *dc = DEVICE_CLASS(class); + * dc->cannot_instantiate_with_device_add_yet = true; + * + * - If the property may safely remain null, document it like this: + * |* + * * Note: pointer property "interrupt_vector" may remain null, thus + * * no need for dc->cannot_instantiate_with_device_add_yet = true; + * *| + */ #define DEFINE_PROP_PTR(_n, _s, _f) \ DEFINE_PROP(_n, _s, _f, qdev_prop_ptr, void*) + #define DEFINE_PROP_CHR(_n, _s, _f) \ DEFINE_PROP(_n, _s, _f, qdev_prop_chr, CharDriverState*) #define DEFINE_PROP_STRING(_n, _s, _f) \ diff --git a/include/qom/object.h b/include/qom/object.h index a275db2092d125e9b62a66b62fd07076263f2c2a..e0ff212cb699492d76e4b1235272d4cc156d75ef 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -358,7 +358,8 @@ struct ObjectClass Type type; GSList *interfaces; - const char *cast_cache[OBJECT_CLASS_CAST_CACHE]; + const char *object_cast_cache[OBJECT_CLASS_CAST_CACHE]; + const char *class_cast_cache[OBJECT_CLASS_CAST_CACHE]; ObjectUnparent *unparent; }; @@ -535,6 +536,7 @@ struct InterfaceClass ObjectClass parent_class; /*< private >*/ ObjectClass *concrete_class; + Type interface_type; }; #define TYPE_INTERFACE "interface" diff --git a/qdev-monitor.c b/qdev-monitor.c index dc37a43dd96715380f5d1a2dcd40eb9279049dc9..ef63cbd7bbb04dc8658f859e4a0f4c267898dca4 100644 --- a/qdev-monitor.c +++ b/qdev-monitor.c @@ -87,7 +87,7 @@ static void qdev_print_devinfo(DeviceClass *dc) if (dc->desc) { error_printf(", desc \"%s\"", dc->desc); } - if (dc->no_user) { + if (dc->cannot_instantiate_with_device_add_yet) { error_printf(", no-user"); } error_printf("\n"); @@ -127,7 +127,8 @@ static void qdev_print_devinfos(bool show_no_user) if ((i < DEVICE_CATEGORY_MAX ? !test_bit(i, dc->categories) : !bitmap_empty(dc->categories, DEVICE_CATEGORY_MAX)) - || (!show_no_user && dc->no_user)) { + || (!show_no_user + && dc->cannot_instantiate_with_device_add_yet)) { continue; } if (!cat_printed) { @@ -477,8 +478,9 @@ DeviceState *qdev_device_add(QemuOpts *opts) } } - if (!oc) { - qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", "device type"); + if (!object_class_dynamic_cast(oc, TYPE_DEVICE)) { + qerror_report(ERROR_CLASS_GENERIC_ERROR, + "'%s' is not a valid device model name", driver); return NULL; } @@ -489,6 +491,11 @@ DeviceState *qdev_device_add(QemuOpts *opts) } dc = DEVICE_CLASS(oc); + if (dc->cannot_instantiate_with_device_add_yet) { + qerror_report(QERR_INVALID_PARAMETER_VALUE, "driver", + "pluggable device type"); + return NULL; + } /* find bus */ path = qemu_opt_get(opts, "bus"); diff --git a/qom/cpu.c b/qom/cpu.c index 818fb26dd48f4913301653ba9ff1a33f81b9d729..9d624795461071bca72e6ea551fc71d298f846e4 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -254,7 +254,11 @@ static void cpu_class_init(ObjectClass *klass, void *data) k->gdb_read_register = cpu_common_gdb_read_register; k->gdb_write_register = cpu_common_gdb_write_register; dc->realize = cpu_common_realizefn; - dc->no_user = 1; + /* + * Reason: CPUs still need special care by board code: wiring up + * IRQs, adding reset handlers, halting non-first CPUs, ... + */ + dc->cannot_instantiate_with_device_add_yet = true; } static const TypeInfo cpu_type_info = { diff --git a/qom/object.c b/qom/object.c index fc19cf676a69027fc7978cf32521c0cc45d852aa..2aab30b32fd7e441c7fc19b6ee21d482b5a747b6 100644 --- a/qom/object.c +++ b/qom/object.c @@ -78,8 +78,11 @@ static GHashTable *type_table_get(void) return type_table; } +static bool enumerating_types; + static void type_table_add(TypeImpl *ti) { + assert(!enumerating_types); g_hash_table_insert(type_table_get(), (void *)ti->name, ti); } @@ -88,7 +91,7 @@ static TypeImpl *type_table_lookup(const char *name) return g_hash_table_lookup(type_table_get(), name); } -static TypeImpl *type_register_internal(const TypeInfo *info) +static TypeImpl *type_new(const TypeInfo *info) { TypeImpl *ti = g_malloc0(sizeof(*ti)); int i; @@ -122,8 +125,15 @@ static TypeImpl *type_register_internal(const TypeInfo *info) } ti->num_interfaces = i; - type_table_add(ti); + return ti; +} + +static TypeImpl *type_register_internal(const TypeInfo *info) +{ + TypeImpl *ti; + ti = type_new(info); + type_table_add(ti); return ti; } @@ -206,22 +216,25 @@ static bool type_is_ancestor(TypeImpl *type, TypeImpl *target_type) static void type_initialize(TypeImpl *ti); -static void type_initialize_interface(TypeImpl *ti, const char *parent) +static void type_initialize_interface(TypeImpl *ti, TypeImpl *interface_type, + TypeImpl *parent_type) { InterfaceClass *new_iface; TypeInfo info = { }; TypeImpl *iface_impl; - info.parent = parent; - info.name = g_strdup_printf("%s::%s", ti->name, info.parent); + info.parent = parent_type->name; + info.name = g_strdup_printf("%s::%s", ti->name, interface_type->name); info.abstract = true; - iface_impl = type_register(&info); + iface_impl = type_new(&info); + iface_impl->parent_type = parent_type; type_initialize(iface_impl); g_free((char *)info.name); new_iface = (InterfaceClass *)iface_impl->class; new_iface->concrete_class = ti->class; + new_iface->interface_type = interface_type; ti->class->interfaces = g_slist_append(ti->class->interfaces, iface_impl->class); @@ -251,8 +264,10 @@ static void type_initialize(TypeImpl *ti) ti->class->interfaces = NULL; for (e = parent->class->interfaces; e; e = e->next) { - ObjectClass *iface = e->data; - type_initialize_interface(ti, object_class_get_name(iface)); + InterfaceClass *iface = e->data; + ObjectClass *klass = OBJECT_CLASS(iface); + + type_initialize_interface(ti, iface->interface_type, klass->type); } for (i = 0; i < ti->num_interfaces; i++) { @@ -269,7 +284,7 @@ static void type_initialize(TypeImpl *ti) continue; } - type_initialize_interface(ti, ti->interfaces[i].typename); + type_initialize_interface(ti, t, t); } } @@ -285,8 +300,6 @@ static void type_initialize(TypeImpl *ti) if (ti->class_init) { ti->class_init(ti->class, ti->class_data); } - - } static void object_init_with_type(Object *obj, TypeImpl *ti) @@ -458,7 +471,7 @@ Object *object_dynamic_cast_assert(Object *obj, const char *typename, Object *inst; for (i = 0; obj && i < OBJECT_CLASS_CAST_CACHE; i++) { - if (obj->class->cast_cache[i] == typename) { + if (obj->class->object_cast_cache[i] == typename) { goto out; } } @@ -475,9 +488,10 @@ Object *object_dynamic_cast_assert(Object *obj, const char *typename, if (obj && obj == inst) { for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) { - obj->class->cast_cache[i - 1] = obj->class->cast_cache[i]; + obj->class->object_cast_cache[i - 1] = + obj->class->object_cast_cache[i]; } - obj->class->cast_cache[i - 1] = typename; + obj->class->object_cast_cache[i - 1] = typename; } out: @@ -547,7 +561,7 @@ ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class, int i; for (i = 0; class && i < OBJECT_CLASS_CAST_CACHE; i++) { - if (class->cast_cache[i] == typename) { + if (class->class_cast_cache[i] == typename) { ret = class; goto out; } @@ -568,9 +582,9 @@ ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class, #ifdef CONFIG_QOM_CAST_DEBUG if (class && ret == class) { for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) { - class->cast_cache[i - 1] = class->cast_cache[i]; + class->class_cast_cache[i - 1] = class->class_cast_cache[i]; } - class->cast_cache[i - 1] = typename; + class->class_cast_cache[i - 1] = typename; } out: #endif @@ -659,7 +673,9 @@ void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque), { OCFData data = { fn, implements_type, include_abstract, opaque }; + enumerating_types = true; g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data); + enumerating_types = false; } int object_child_foreach(Object *obj, int (*fn)(Object *child, void *opaque), diff --git a/tests/Makefile b/tests/Makefile index 8d258781b749c480f82b3f293104178390200873..0b85a341476eaa3c6c43c216bd9b5a6124278bfa 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -52,6 +52,8 @@ check-unit-y += tests/test-int128$(EXESUF) gcov-files-test-int128-y = check-unit-y += tests/test-bitops$(EXESUF) check-unit-y += tests/test-qdev-global-props$(EXESUF) +check-unit-y += tests/check-qom-interface$(EXESUF) +gcov-files-check-qom-interface-y = qom/object.c check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh @@ -138,6 +140,7 @@ test-qapi-obj-y = tests/test-qapi-visit.o tests/test-qapi-types.o $(test-obj-y): QEMU_INCLUDES += -Itests QEMU_CFLAGS += -I$(SRC_PATH)/tests +qom-core-obj = qom/object.o qom/qom-qobject.o qom/container.o tests/test-x86-cpuid.o: QEMU_INCLUDES += -I$(SRC_PATH)/target-i386 @@ -147,6 +150,7 @@ tests/check-qdict$(EXESUF): tests/check-qdict.o libqemuutil.a tests/check-qlist$(EXESUF): tests/check-qlist.o libqemuutil.a tests/check-qfloat$(EXESUF): tests/check-qfloat.o libqemuutil.a tests/check-qjson$(EXESUF): tests/check-qjson.o libqemuutil.a libqemustub.a +tests/check-qom-interface$(EXESUF): tests/check-qom-interface.o $(qom-core-obj) libqemuutil.a tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(block-obj-y) libqemuutil.a libqemustub.a tests/test-aio$(EXESUF): tests/test-aio.o $(block-obj-y) libqemuutil.a libqemustub.a tests/test-throttle$(EXESUF): tests/test-throttle.o $(block-obj-y) libqemuutil.a libqemustub.a @@ -160,7 +164,7 @@ tests/test-int128$(EXESUF): tests/test-int128.o tests/test-qdev-global-props$(EXESUF): tests/test-qdev-global-props.o \ hw/core/qdev.o hw/core/qdev-properties.o \ hw/core/irq.o \ - qom/object.o qom/container.o qom/qom-qobject.o \ + $(qom-core-obj) \ $(test-qapi-obj-y) \ libqemuutil.a libqemustub.a diff --git a/tests/check-qom-interface.c b/tests/check-qom-interface.c new file mode 100644 index 0000000000000000000000000000000000000000..f06380ef14d810c3743fc7ca8c1b7bb9acc97ed4 --- /dev/null +++ b/tests/check-qom-interface.c @@ -0,0 +1,105 @@ +/* + * QOM interface test. + * + * Copyright (C) 2013 Red Hat Inc. + * + * Authors: + * Igor Mammedov + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + */ +#include + +#include "qom/object.h" +#include "qemu/module.h" + + +#define TYPE_TEST_IF "test-interface" +#define TEST_IF_CLASS(klass) \ + OBJECT_CLASS_CHECK(TestIfClass, (klass), TYPE_TEST_IF) +#define TEST_IF_GET_CLASS(obj) \ + OBJECT_GET_CLASS(TestIfClass, (obj), TYPE_TEST_IF) +#define TEST_IF(obj) \ + INTERFACE_CHECK(TestIf, (obj), TYPE_TEST_IF) + +typedef struct TestIf { + Object parent_obj; +} TestIf; + +typedef struct TestIfClass { + InterfaceClass parent_class; + + uint32_t test; +} TestIfClass; + +static const TypeInfo test_if_info = { + .name = TYPE_TEST_IF, + .parent = TYPE_INTERFACE, + .class_size = sizeof(TestIfClass), +}; + +#define PATTERN 0xFAFBFCFD + +static void test_class_init(ObjectClass *oc, void *data) +{ + TestIfClass *tc = TEST_IF_CLASS(oc); + + g_assert(tc); + tc->test = PATTERN; +} + +#define TYPE_DIRECT_IMPL "direct-impl" + +static const TypeInfo direct_impl_info = { + .name = TYPE_DIRECT_IMPL, + .parent = TYPE_OBJECT, + .class_init = test_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_TEST_IF }, + { } + } +}; + +#define TYPE_INTERMEDIATE_IMPL "intermediate-impl" + +static const TypeInfo intermediate_impl_info = { + .name = TYPE_INTERMEDIATE_IMPL, + .parent = TYPE_DIRECT_IMPL, +}; + +static void test_interface_impl(const char *type) +{ + Object *obj = object_new(type); + TestIf *iobj = TEST_IF(obj); + TestIfClass *ioc = TEST_IF_GET_CLASS(iobj); + + g_assert(iobj); + g_assert(ioc->test == PATTERN); +} + +static void interface_direct_test(void) +{ + test_interface_impl(TYPE_DIRECT_IMPL); +} + +static void interface_intermediate_test(void) +{ + test_interface_impl(TYPE_INTERMEDIATE_IMPL); +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + module_call_init(MODULE_INIT_QOM); + type_register_static(&test_if_info); + type_register_static(&direct_impl_info); + type_register_static(&intermediate_impl_info); + + g_test_add_func("/qom/interface/direct_impl", interface_direct_test); + g_test_add_func("/qom/interface/intermediate_impl", + interface_intermediate_test); + + return g_test_run(); +}