aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/acpi/piix4.c6
-rw-r--r--hw/block/fdc.c18
-rw-r--r--hw/block/nvme.c44
-rw-r--r--hw/block/virtio-blk.c5
-rw-r--r--hw/char/virtio-serial-bus.c20
-rw-r--r--hw/core/hotplug.c11
-rw-r--r--hw/core/qdev-properties-system.c8
-rw-r--r--hw/core/qdev-properties.c14
-rw-r--r--hw/core/qdev.c113
-rw-r--r--hw/cpu/icc_bus.c8
-rw-r--r--hw/display/vga-pci.c70
-rw-r--r--hw/display/vga.c26
-rw-r--r--hw/i386/acpi-build.c2
-rw-r--r--hw/i386/kvm/pci-assign.c14
-rw-r--r--hw/i386/pc_q35.c2
-rw-r--r--hw/ide/qdev.c47
-rw-r--r--hw/isa/lpc_ich9.c6
-rw-r--r--hw/mips/mips_malta.c10
-rw-r--r--hw/misc/vfio.c13
-rw-r--r--hw/net/e1000.c12
-rw-r--r--hw/net/eepro100.c13
-rw-r--r--hw/net/lance.c12
-rw-r--r--hw/net/ne2000-isa.c44
-rw-r--r--hw/net/ne2000.c14
-rw-r--r--hw/net/pcnet-pci.c12
-rw-r--r--hw/net/pcnet.c2
-rw-r--r--hw/net/pcnet.h1
-rw-r--r--hw/net/rtl8139.c12
-rw-r--r--hw/net/spapr_llan.c12
-rw-r--r--hw/net/virtio-net.c5
-rw-r--r--hw/net/vmxnet3.c10
-rw-r--r--hw/nvram/fw_cfg.c55
-rw-r--r--hw/pci-bridge/pci_bridge_dev.c2
-rw-r--r--hw/pci/pci-hotplug-old.c4
-rw-r--r--hw/pci/pcie.c4
-rw-r--r--hw/pci/pcie_port.c2
-rw-r--r--hw/pci/shpc.c4
-rw-r--r--hw/s390x/event-facility.c2
-rw-r--r--hw/s390x/s390-virtio-bus.c14
-rw-r--r--hw/s390x/virtio-ccw.c21
-rw-r--r--hw/scsi/scsi-bus.c38
-rw-r--r--hw/scsi/scsi-disk.c2
-rw-r--r--hw/scsi/scsi-generic.c4
-rw-r--r--hw/scsi/virtio-scsi.c30
-rw-r--r--hw/scsi/vmw_pvscsi.c26
-rw-r--r--hw/usb/bus.c9
-rw-r--r--hw/usb/dev-network.c11
-rw-r--r--hw/usb/dev-smartcard-reader.c8
-rw-r--r--hw/usb/dev-storage.c56
-rw-r--r--hw/usb/host-libusb.c13
-rw-r--r--hw/usb/redirect.c13
-rw-r--r--hw/virtio/virtio-mmio.c17
-rw-r--r--hw/virtio/virtio-pci.c7
53 files changed, 711 insertions, 217 deletions
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index b72b34e5c9..0bfa814f71 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -354,8 +354,8 @@ static void piix4_device_plug_cb(HotplugHandler *hotplug_dev,
}
}
-static void piix4_device_unplug_cb(HotplugHandler *hotplug_dev,
- DeviceState *dev, Error **errp)
+static void piix4_device_unplug_request_cb(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
{
PIIX4PMState *s = PIIX4_PM(hotplug_dev);
@@ -615,7 +615,7 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data)
dc->cannot_instantiate_with_device_add_yet = true;
dc->hotpluggable = false;
hc->plug = piix4_device_plug_cb;
- hc->unplug = piix4_device_unplug_cb;
+ hc->unplug_request = piix4_device_unplug_request_cb;
adevc->ospm_status = piix4_ospm_status;
}
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 6c86a6b59e..34c1d8f1c9 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -2216,9 +2216,6 @@ static void isabus_fdc_realize(DeviceState *dev, Error **errp)
error_propagate(errp, err);
return;
}
-
- add_boot_device_path(isa->bootindexA, dev, "/floppy@0");
- add_boot_device_path(isa->bootindexB, dev, "/floppy@1");
}
static void sysbus_fdc_initfn(Object *obj)
@@ -2291,8 +2288,6 @@ static Property isa_fdc_properties[] = {
DEFINE_PROP_UINT32("dma", FDCtrlISABus, dma, 2),
DEFINE_PROP_DRIVE("driveA", FDCtrlISABus, state.drives[0].bs),
DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.drives[1].bs),
- DEFINE_PROP_INT32("bootindexA", FDCtrlISABus, bootindexA, -1),
- DEFINE_PROP_INT32("bootindexB", FDCtrlISABus, bootindexB, -1),
DEFINE_PROP_BIT("check_media_rate", FDCtrlISABus, state.check_media_rate,
0, true),
DEFINE_PROP_END_OF_LIST(),
@@ -2310,11 +2305,24 @@ static void isabus_fdc_class_init(ObjectClass *klass, void *data)
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
+static void isabus_fdc_instance_init(Object *obj)
+{
+ FDCtrlISABus *isa = ISA_FDC(obj);
+
+ device_add_bootindex_property(obj, &isa->bootindexA,
+ "bootindexA", "/floppy@0",
+ DEVICE(obj), NULL);
+ device_add_bootindex_property(obj, &isa->bootindexB,
+ "bootindexB", "/floppy@1",
+ DEVICE(obj), NULL);
+}
+
static const TypeInfo isa_fdc_info = {
.name = TYPE_ISA_FDC,
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(FDCtrlISABus),
.class_init = isabus_fdc_class_init,
+ .instance_init = isabus_fdc_instance_init,
};
static const VMStateDescription vmstate_sysbus_fdc ={
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index b010c9b00f..9a95f7530b 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -24,6 +24,8 @@
#include <hw/hw.h>
#include <hw/pci/msix.h>
#include <hw/pci/pci.h>
+#include "sysemu/sysemu.h"
+#include "qapi/visitor.h"
#include "nvme.h"
@@ -871,11 +873,53 @@ static void nvme_class_init(ObjectClass *oc, void *data)
dc->vmsd = &nvme_vmstate;
}
+static void nvme_get_bootindex(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ NvmeCtrl *s = NVME(obj);
+
+ visit_type_int32(v, &s->conf.bootindex, name, errp);
+}
+
+static void nvme_set_bootindex(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ NvmeCtrl *s = NVME(obj);
+ int32_t boot_index;
+ Error *local_err = NULL;
+
+ visit_type_int32(v, &boot_index, name, &local_err);
+ if (local_err) {
+ goto out;
+ }
+ /* check whether bootindex is present in fw_boot_order list */
+ check_boot_index(boot_index, &local_err);
+ if (local_err) {
+ goto out;
+ }
+ /* change bootindex to a new one */
+ s->conf.bootindex = boot_index;
+
+out:
+ if (local_err) {
+ error_propagate(errp, local_err);
+ }
+}
+
+static void nvme_instance_init(Object *obj)
+{
+ object_property_add(obj, "bootindex", "int32",
+ nvme_get_bootindex,
+ nvme_set_bootindex, NULL, NULL, NULL);
+ object_property_set_int(obj, -1, "bootindex", NULL);
+}
+
static const TypeInfo nvme_info = {
.name = "nvme",
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(NvmeCtrl),
.class_init = nvme_class_init,
+ .instance_init = nvme_instance_init,
};
static void nvme_register_types(void)
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 45e0c8f6e9..1fa97709c8 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -768,8 +768,6 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
bdrv_set_guest_block_size(s->bs, s->conf->logical_block_size);
bdrv_iostatus_enable(s->bs);
-
- add_boot_device_path(s->conf->bootindex, dev, "/disk@0,0");
}
static void virtio_blk_device_unrealize(DeviceState *dev, Error **errp)
@@ -794,6 +792,9 @@ static void virtio_blk_instance_init(Object *obj)
(Object **)&s->blk.iothread,
qdev_prop_allow_set_link_before_realize,
OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL);
+ device_add_bootindex_property(obj, &s->blk.conf.bootindex,
+ "bootindex", "/disk@0,0",
+ DEVICE(obj), NULL);
}
static Property virtio_blk_properties[] = {
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index 3931085983..c6870f19e1 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -904,6 +904,12 @@ static void virtser_port_device_realize(DeviceState *dev, Error **errp)
}
port->elem.out_num = 0;
+}
+
+static void virtser_port_device_plug(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
QTAILQ_INSERT_TAIL(&port->vser->ports, port, next);
port->ivq = port->vser->ivqs[port->id];
@@ -912,7 +918,7 @@ static void virtser_port_device_realize(DeviceState *dev, Error **errp)
add_port(port->vser, port->id);
/* Send an update to the guest about this new port added */
- virtio_notify_config(vdev);
+ virtio_notify_config(VIRTIO_DEVICE(hotplug_dev));
}
static void virtser_port_device_unrealize(DeviceState *dev, Error **errp)
@@ -935,7 +941,6 @@ static void virtio_serial_device_realize(DeviceState *dev, Error **errp)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VirtIOSerial *vser = VIRTIO_SERIAL(dev);
- BusState *bus;
uint32_t i, max_supported_ports;
if (!vser->serial.max_virtserial_ports) {
@@ -957,8 +962,7 @@ static void virtio_serial_device_realize(DeviceState *dev, Error **errp)
/* Spawn a new virtio-serial bus on which the ports will ride as devices */
qbus_create_inplace(&vser->bus, sizeof(vser->bus), TYPE_VIRTIO_SERIAL_BUS,
dev, vdev->bus_name);
- bus = BUS(&vser->bus);
- bus->allow_hotplug = 1;
+ qbus_set_hotplug_handler(BUS(&vser->bus), DEVICE(vser), errp);
vser->bus.vser = vser;
QTAILQ_INIT(&vser->ports);
@@ -1021,7 +1025,6 @@ static void virtio_serial_port_class_init(ObjectClass *klass, void *data)
k->bus_type = TYPE_VIRTIO_SERIAL_BUS;
k->realize = virtser_port_device_realize;
k->unrealize = virtser_port_device_unrealize;
- k->unplug = qdev_simple_unplug_cb;
k->props = virtser_props;
}
@@ -1064,6 +1067,7 @@ static void virtio_serial_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
QLIST_INIT(&vserdevices.devices);
@@ -1077,6 +1081,8 @@ static void virtio_serial_class_init(ObjectClass *klass, void *data)
vdc->reset = vser_reset;
vdc->save = virtio_serial_save_device;
vdc->load = virtio_serial_load_device;
+ hc->plug = virtser_port_device_plug;
+ hc->unplug = qdev_simple_device_unplug_cb;
}
static const TypeInfo virtio_device_info = {
@@ -1084,6 +1090,10 @@ static const TypeInfo virtio_device_info = {
.parent = TYPE_VIRTIO_DEVICE,
.instance_size = sizeof(VirtIOSerial),
.class_init = virtio_serial_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_HOTPLUG_HANDLER },
+ { }
+ }
};
static void virtio_serial_register_types(void)
diff --git a/hw/core/hotplug.c b/hw/core/hotplug.c
index 5573d9d2d9..4e01074557 100644
--- a/hw/core/hotplug.c
+++ b/hw/core/hotplug.c
@@ -23,6 +23,17 @@ void hotplug_handler_plug(HotplugHandler *plug_handler,
}
}
+void hotplug_handler_unplug_request(HotplugHandler *plug_handler,
+ DeviceState *plugged_dev,
+ Error **errp)
+{
+ HotplugHandlerClass *hdc = HOTPLUG_HANDLER_GET_CLASS(plug_handler);
+
+ if (hdc->unplug_request) {
+ hdc->unplug_request(plug_handler, plugged_dev, errp);
+ }
+}
+
void hotplug_handler_unplug(HotplugHandler *plug_handler,
DeviceState *plugged_dev,
Error **errp)
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 84caa1d694..f2bd954be5 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -112,7 +112,7 @@ static void set_drive(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_drive = {
.name = "str",
- .legacy_name = "drive",
+ .description = "ID of a drive to use as a backend",
.get = get_drive,
.set = set_drive,
.release = release_drive,
@@ -169,7 +169,7 @@ static void set_chr(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_chr = {
.name = "str",
- .legacy_name = "chr",
+ .description = "ID of a chardev to use as a backend",
.get = get_chr,
.set = set_chr,
.release = release_chr,
@@ -248,7 +248,7 @@ static void set_netdev(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_netdev = {
.name = "str",
- .legacy_name = "netdev",
+ .description = "ID of a netdev to use as a backend",
.get = get_netdev,
.set = set_netdev,
};
@@ -328,7 +328,7 @@ static void set_vlan(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_vlan = {
.name = "int32",
- .legacy_name = "vlan",
+ .description = "Integer VLAN id to connect to",
.print = print_vlan,
.get = get_vlan,
.set = set_vlan,
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 66556d3bf9..2ed995f2b7 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -120,7 +120,7 @@ static void prop_set_bit(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_bit = {
.name = "bool",
- .legacy_name = "on/off",
+ .description = "on/off",
.get = prop_get_bit,
.set = prop_set_bit,
};
@@ -455,7 +455,7 @@ inval:
PropertyInfo qdev_prop_macaddr = {
.name = "str",
- .legacy_name = "macaddr",
+ .description = "Ethernet 6-byte MAC Address, example: 52:54:00:12:34:56",
.get = get_mac,
.set = set_mac,
};
@@ -477,7 +477,8 @@ QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int));
PropertyInfo qdev_prop_bios_chs_trans = {
.name = "BiosAtaTranslation",
- .legacy_name = "bios-chs-trans",
+ .description = "Logical CHS translation algorithm, "
+ "auto/none/lba/large/rechs",
.enum_table = BiosAtaTranslation_lookup,
.get = get_enum,
.set = set_enum,
@@ -551,7 +552,7 @@ static int print_pci_devfn(DeviceState *dev, Property *prop, char *dest,
PropertyInfo qdev_prop_pci_devfn = {
.name = "int32",
- .legacy_name = "pci-devfn",
+ .description = "Slot and optional function number, example: 06.0 or 06",
.print = print_pci_devfn,
.get = get_int32,
.set = set_pci_devfn,
@@ -598,7 +599,7 @@ static void set_blocksize(Object *obj, Visitor *v, void *opaque,
PropertyInfo qdev_prop_blocksize = {
.name = "uint16",
- .legacy_name = "blocksize",
+ .description = "A power of two between 512 and 32768",
.get = get_uint16,
.set = set_blocksize,
};
@@ -706,7 +707,8 @@ inval:
PropertyInfo qdev_prop_pci_host_devaddr = {
.name = "str",
- .legacy_name = "pci-host-devaddr",
+ .description = "Address (bus/device/function) of "
+ "the host device, example: 04:10.0",
.get = get_pci_host_devaddr,
.set = set_pci_host_devaddr,
};
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index fcb16383a1..a1e9247772 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -85,10 +85,6 @@ static void bus_add_child(BusState *bus, DeviceState *child)
char name[32];
BusChild *kid = g_malloc0(sizeof(*kid));
- if (qdev_hotplug) {
- assert(bus->allow_hotplug);
- }
-
kid->index = bus->max_index++;
kid->child = child;
object_ref(OBJECT(kid->child));
@@ -112,6 +108,24 @@ void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
bus_add_child(bus, dev);
}
+static void qbus_set_hotplug_handler_internal(BusState *bus, Object *handler,
+ Error **errp)
+{
+
+ object_property_set_link(OBJECT(bus), OBJECT(handler),
+ QDEV_HOTPLUG_HANDLER_PROPERTY, errp);
+}
+
+void qbus_set_hotplug_handler(BusState *bus, DeviceState *handler, Error **errp)
+{
+ qbus_set_hotplug_handler_internal(bus, OBJECT(handler), errp);
+}
+
+void qbus_set_bus_hotplug_handler(BusState *bus, Error **errp)
+{
+ qbus_set_hotplug_handler_internal(bus, OBJECT(bus), errp);
+}
+
/* Create a new device. This only initializes the device state structure
and allows properties to be set. qdev_init should be called to
initialize the actual device emulation. */
@@ -209,11 +223,30 @@ void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
dev->alias_required_for_version = required_for_version;
}
+static HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev)
+{
+ HotplugHandler *hotplug_ctrl = NULL;
+
+ if (dev->parent_bus && dev->parent_bus->hotplug_handler) {
+ hotplug_ctrl = dev->parent_bus->hotplug_handler;
+ } else if (object_dynamic_cast(qdev_get_machine(), TYPE_MACHINE)) {
+ MachineState *machine = MACHINE(qdev_get_machine());
+ MachineClass *mc = MACHINE_GET_CLASS(machine);
+
+ if (mc->get_hotplug_handler) {
+ hotplug_ctrl = mc->get_hotplug_handler(machine, dev);
+ }
+ }
+ return hotplug_ctrl;
+}
+
void qdev_unplug(DeviceState *dev, Error **errp)
{
DeviceClass *dc = DEVICE_GET_CLASS(dev);
+ HotplugHandler *hotplug_ctrl;
+ HotplugHandlerClass *hdc;
- if (dev->parent_bus && !dev->parent_bus->allow_hotplug) {
+ if (dev->parent_bus && !qbus_is_hotpluggable(dev->parent_bus)) {
error_set(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
return;
}
@@ -226,13 +259,18 @@ void qdev_unplug(DeviceState *dev, Error **errp)
qdev_hot_removed = true;
- if (dev->parent_bus && dev->parent_bus->hotplug_handler) {
- hotplug_handler_unplug(dev->parent_bus->hotplug_handler, dev, errp);
+ hotplug_ctrl = qdev_get_hotplug_handler(dev);
+ /* hotpluggable device MUST have HotplugHandler, if it doesn't
+ * then something is very wrong with it */
+ g_assert(hotplug_ctrl);
+
+ /* If device supports async unplug just request it to be done,
+ * otherwise just remove it synchronously */
+ hdc = HOTPLUG_HANDLER_GET_CLASS(hotplug_ctrl);
+ if (hdc->unplug_request) {
+ hotplug_handler_unplug_request(hotplug_ctrl, dev, errp);
} else {
- assert(dc->unplug != NULL);
- if (dc->unplug(dev) < 0) { /* legacy handler */
- error_set(errp, QERR_UNDEFINED_ERROR);
- }
+ hotplug_handler_unplug(hotplug_ctrl, dev, errp);
}
}
@@ -269,14 +307,13 @@ void qbus_reset_all_fn(void *opaque)
}
/* can be used as ->unplug() callback for the simple cases */
-int qdev_simple_unplug_cb(DeviceState *dev)
+void qdev_simple_device_unplug_cb(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
{
/* just zap it */
object_unparent(OBJECT(dev));
- return 0;
}
-
/* Like qdev_init(), but terminate program via error_report() instead of
returning an error value. This is okay during machine creation.
Don't use for hotplug, because there callers need to recover from
@@ -337,10 +374,20 @@ static NamedGPIOList *qdev_get_named_gpio_list(DeviceState *dev,
void qdev_init_gpio_in_named(DeviceState *dev, qemu_irq_handler handler,
const char *name, int n)
{
+ int i;
NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
+ char *propname = g_strdup_printf("%s[*]", name ? name : "unnamed-gpio-in");
+ assert(gpio_list->num_out == 0 || !name);
gpio_list->in = qemu_extend_irqs(gpio_list->in, gpio_list->num_in, handler,
dev, n);
+
+ for (i = gpio_list->num_in; i < gpio_list->num_in + n; i++) {
+ object_property_add_child(OBJECT(dev), propname,
+ OBJECT(gpio_list->in[i]), &error_abort);
+ }
+ g_free(propname);
+
gpio_list->num_in += n;
}
@@ -352,11 +399,24 @@ void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)
void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins,
const char *name, int n)
{
+ int i;
NamedGPIOList *gpio_list = qdev_get_named_gpio_list(dev, name);
+ char *propname = g_strdup_printf("%s[*]", name ? name : "unnamed-gpio-out");
+ assert(gpio_list->num_in == 0 || !name);
assert(gpio_list->num_out == 0);
gpio_list->num_out = n;
gpio_list->out = pins;
+
+ for (i = 0; i < n; ++i) {
+ memset(&pins[i], 0, sizeof(*pins));
+ object_property_add_link(OBJECT(dev), propname, TYPE_IRQ,
+ (Object **)&pins[i],
+ object_property_allow_set_link,
+ OBJ_PROP_LINK_UNREF_ON_RELEASE,
+ &error_abort);
+ }
+ g_free(propname);
}
void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)
@@ -766,6 +826,11 @@ void qdev_property_add_static(DeviceState *dev, Property *prop,
error_propagate(errp, local_err);
return;
}
+
+ object_property_set_description(obj, prop->name,
+ prop->info->description,
+ &error_abort);
+
if (prop->qtype == QTYPE_NONE) {
return;
}
@@ -811,6 +876,7 @@ static void device_set_realized(Object *obj, bool value, Error **errp)
{
DeviceState *dev = DEVICE(obj);
DeviceClass *dc = DEVICE_GET_CLASS(dev);
+ HotplugHandler *hotplug_ctrl;
BusState *bus;
Error *local_err = NULL;
@@ -838,20 +904,9 @@ static void device_set_realized(Object *obj, bool value, Error **errp)
goto fail;
}
- if (dev->parent_bus && dev->parent_bus->hotplug_handler) {
- hotplug_handler_plug(dev->parent_bus->hotplug_handler,
- dev, &local_err);
- } else if (object_dynamic_cast(qdev_get_machine(), TYPE_MACHINE)) {
- HotplugHandler *hotplug_ctrl;
- MachineState *machine = MACHINE(qdev_get_machine());
- MachineClass *mc = MACHINE_GET_CLASS(machine);
-
- if (mc->get_hotplug_handler) {
- hotplug_ctrl = mc->get_hotplug_handler(machine, dev);
- if (hotplug_ctrl) {
- hotplug_handler_plug(hotplug_ctrl, dev, &local_err);
- }
- }
+ hotplug_ctrl = qdev_get_hotplug_handler(dev);
+ if (hotplug_ctrl) {
+ hotplug_handler_plug(hotplug_ctrl, dev, &local_err);
}
if (local_err != NULL) {
@@ -925,7 +980,7 @@ static bool device_get_hotpluggable(Object *obj, Error **errp)
DeviceState *dev = DEVICE(obj);
return dc->hotpluggable && (dev->parent_bus == NULL ||
- dev->parent_bus->allow_hotplug);
+ qbus_is_hotpluggable(dev->parent_bus));
}
static bool device_get_hotplugged(Object *obj, Error **err)
diff --git a/hw/cpu/icc_bus.c b/hw/cpu/icc_bus.c
index 7f44c59b25..9575fd6a42 100644
--- a/hw/cpu/icc_bus.c
+++ b/hw/cpu/icc_bus.c
@@ -24,18 +24,10 @@
/* icc-bridge implementation */
-static void icc_bus_init(Object *obj)
-{
- BusState *b = BUS(obj);
-
- b->allow_hotplug = true;
-}
-
static const TypeInfo icc_bus_info = {
.name = TYPE_ICC_BUS,
.parent = TYPE_BUS,
.instance_size = sizeof(ICCBus),
- .instance_init = icc_bus_init,
};
diff --git a/hw/display/vga-pci.c b/hw/display/vga-pci.c
index 0351d94707..db922f1843 100644
--- a/hw/display/vga-pci.c
+++ b/hw/display/vga-pci.c
@@ -35,10 +35,18 @@
#define PCI_VGA_IOPORT_SIZE (0x3e0 - 0x3c0)
#define PCI_VGA_BOCHS_OFFSET 0x500
#define PCI_VGA_BOCHS_SIZE (0x0b * 2)
+#define PCI_VGA_QEXT_OFFSET 0x600
+#define PCI_VGA_QEXT_SIZE (2 * 4)
#define PCI_VGA_MMIO_SIZE 0x1000
+#define PCI_VGA_QEXT_REG_SIZE (0 * 4)
+#define PCI_VGA_QEXT_REG_BYTEORDER (1 * 4)
+#define PCI_VGA_QEXT_LITTLE_ENDIAN 0x1e1e1e1e
+#define PCI_VGA_QEXT_BIG_ENDIAN 0xbebebebe
+
enum vga_pci_flags {
PCI_VGA_FLAG_ENABLE_MMIO = 1,
+ PCI_VGA_FLAG_ENABLE_QEXT = 2,
};
typedef struct PCIVGAState {
@@ -48,6 +56,7 @@ typedef struct PCIVGAState {
MemoryRegion mmio;
MemoryRegion ioport;
MemoryRegion bochs;
+ MemoryRegion qext;
} PCIVGAState;
static const VMStateDescription vmstate_vga_pci = {
@@ -140,6 +149,46 @@ static const MemoryRegionOps pci_vga_bochs_ops = {
.endianness = DEVICE_LITTLE_ENDIAN,
};
+static uint64_t pci_vga_qext_read(void *ptr, hwaddr addr, unsigned size)
+{
+ PCIVGAState *d = ptr;
+
+ switch (addr) {
+ case PCI_VGA_QEXT_REG_SIZE:
+ return PCI_VGA_QEXT_SIZE;
+ case PCI_VGA_QEXT_REG_BYTEORDER:
+ return d->vga.big_endian_fb ?
+ PCI_VGA_QEXT_BIG_ENDIAN : PCI_VGA_QEXT_LITTLE_ENDIAN;
+ default:
+ return 0;
+ }
+}
+
+static void pci_vga_qext_write(void *ptr, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+ PCIVGAState *d = ptr;
+
+ switch (addr) {
+ case PCI_VGA_QEXT_REG_BYTEORDER:
+ if (val == PCI_VGA_QEXT_BIG_ENDIAN) {
+ d->vga.big_endian_fb = true;
+ }
+ if (val == PCI_VGA_QEXT_LITTLE_ENDIAN) {
+ d->vga.big_endian_fb = false;
+ }
+ break;
+ }
+}
+
+static const MemoryRegionOps pci_vga_qext_ops = {
+ .read = pci_vga_qext_read,
+ .write = pci_vga_qext_write,
+ .valid.min_access_size = 4,
+ .valid.max_access_size = 4,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
static int pci_std_vga_initfn(PCIDevice *dev)
{
PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev);
@@ -167,6 +216,15 @@ static int pci_std_vga_initfn(PCIDevice *dev)
&d->ioport);
memory_region_add_subregion(&d->mmio, PCI_VGA_BOCHS_OFFSET,
&d->bochs);
+
+ if (d->flags & (1 << PCI_VGA_FLAG_ENABLE_QEXT)) {
+ memory_region_init_io(&d->qext, NULL, &pci_vga_qext_ops, d,
+ "qemu extended regs", PCI_VGA_QEXT_SIZE);
+ memory_region_add_subregion(&d->mmio, PCI_VGA_QEXT_OFFSET,
+ &d->qext);
+ pci_set_byte(&d->dev.config[PCI_REVISION_ID], 2);
+ }
+
pci_register_bar(&d->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio);
}
@@ -199,6 +257,14 @@ static int pci_secondary_vga_initfn(PCIDevice *dev)
memory_region_add_subregion(&d->mmio, PCI_VGA_BOCHS_OFFSET,
&d->bochs);
+ if (d->flags & (1 << PCI_VGA_FLAG_ENABLE_QEXT)) {
+ memory_region_init_io(&d->qext, NULL, &pci_vga_qext_ops, d,
+ "qemu extended regs", PCI_VGA_QEXT_SIZE);
+ memory_region_add_subregion(&d->mmio, PCI_VGA_QEXT_OFFSET,
+ &d->qext);
+ pci_set_byte(&d->dev.config[PCI_REVISION_ID], 2);
+ }
+
pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
pci_register_bar(&d->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio);
@@ -215,11 +281,15 @@ static void pci_secondary_vga_reset(DeviceState *dev)
static Property vga_pci_properties[] = {
DEFINE_PROP_UINT32("vgamem_mb", PCIVGAState, vga.vram_size_mb, 16),
DEFINE_PROP_BIT("mmio", PCIVGAState, flags, PCI_VGA_FLAG_ENABLE_MMIO, true),
+ DEFINE_PROP_BIT("qemu-extended-regs",
+ PCIVGAState, flags, PCI_VGA_FLAG_ENABLE_QEXT, true),
DEFINE_PROP_END_OF_LIST(),
};
static Property secondary_pci_properties[] = {
DEFINE_PROP_UINT32("vgamem_mb", PCIVGAState, vga.vram_size_mb, 16),
+ DEFINE_PROP_BIT("qemu-extended-regs",
+ PCIVGAState, flags, PCI_VGA_FLAG_ENABLE_QEXT, true),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/display/vga.c b/hw/display/vga.c
index 19e7f23bd3..52eaf05659 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -136,32 +136,6 @@ static const uint32_t mask16[16] = {
#define PAT(x) cbswap_32(x)
#endif
-static const uint32_t dmask16[16] = {
- PAT(0x00000000),
- PAT(0x000000ff),
- PAT(0x0000ff00),
- PAT(0x0000ffff),
- PAT(0x00ff0000),
- PAT(0x00ff00ff),
- PAT(0x00ffff00),
- PAT(0x00ffffff),
- PAT(0xff000000),
- PAT(0xff0000ff),
- PAT(0xff00ff00),
- PAT(0xff00ffff),
- PAT(0xffff0000),
- PAT(0xffff00ff),
- PAT(0xffffff00),
- PAT(0xffffffff),
-};
-
-static const uint32_t dmask4[4] = {
- PAT(0x00000000),
- PAT(0x0000ffff),
- PAT(0xffff0000),
- PAT(0xffffffff),
-};
-
static uint32_t expand4[256];
static uint16_t expand2[256];
static uint8_t expand4to8[16];
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index a3133211a8..00be4bb12a 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -774,7 +774,7 @@ static void *acpi_set_bsel(PCIBus *bus, void *opaque)
unsigned *bsel_alloc = opaque;
unsigned *bus_bsel;
- if (bus->qbus.allow_hotplug) {
+ if (qbus_is_hotpluggable(BUS(bus))) {
bus_bsel = g_malloc(sizeof *bus_bsel);
*bus_bsel = (*bsel_alloc)++;
diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c
index 13b9de08f1..bb206da05f 100644
--- a/hw/i386/kvm/pci-assign.c
+++ b/hw/i386/kvm/pci-assign.c
@@ -1825,8 +1825,6 @@ static int assigned_initfn(struct PCIDevice *pci_dev)
assigned_dev_load_option_rom(dev);
- add_boot_device_path(dev->bootindex, &pci_dev->qdev, NULL);
-
return 0;
assigned_out:
@@ -1850,13 +1848,22 @@ static void assigned_exitfn(struct PCIDevice *pci_dev)
free_assigned_device(dev);
}
+static void assigned_dev_instance_init(Object *obj)
+{
+ PCIDevice *pci_dev = PCI_DEVICE(obj);
+ AssignedDevice *d = DO_UPCAST(AssignedDevice, dev, PCI_DEVICE(obj));
+
+ device_add_bootindex_property(obj, &d->bootindex,
+ "bootindex", NULL,
+ &pci_dev->qdev, NULL);
+}
+
static Property assigned_dev_properties[] = {
DEFINE_PROP_PCI_HOST_DEVADDR("host", AssignedDevice, host),
DEFINE_PROP_BIT("prefer_msi", AssignedDevice, features,
ASSIGNED_DEVICE_PREFER_MSI_BIT, false),
DEFINE_PROP_BIT("share_intx", AssignedDevice, features,
ASSIGNED_DEVICE_SHARE_INTX_BIT, true),
- DEFINE_PROP_INT32("bootindex", AssignedDevice, bootindex, -1),
DEFINE_PROP_STRING("configfd", AssignedDevice, configfd_name),
DEFINE_PROP_END_OF_LIST(),
};
@@ -1882,6 +1889,7 @@ static const TypeInfo assign_info = {
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(AssignedDevice),
.class_init = assign_class_init,
+ .instance_init = assigned_dev_instance_init,
};
static void assign_register_types(void)
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index bb0dc8e08a..e225c6d110 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -254,7 +254,7 @@ static void pc_q35_init(MachineState *machine)
true, "ich9-ahci");
idebus[0] = qdev_get_child_bus(&ahci->qdev, "ide.0");
idebus[1] = qdev_get_child_bus(&ahci->qdev, "ide.1");
- g_assert_cmpint(MAX_SATA_PORTS, ==, ICH_AHCI(ahci)->ahci.ports);
+ g_assert(MAX_SATA_PORTS == ICH_AHCI(ahci)->ahci.ports);
ide_drive_get(hd, ICH_AHCI(ahci)->ahci.ports);
ahci_ide_create_devs(ahci, hd);
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index efab95b320..9814ef0d24 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -23,6 +23,7 @@
#include "sysemu/blockdev.h"
#include "hw/block/block.h"
#include "sysemu/sysemu.h"
+#include "qapi/visitor.h"
/* --------------------------------- */
@@ -191,6 +192,51 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind)
return 0;
}
+static void ide_dev_get_bootindex(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ IDEDevice *d = IDE_DEVICE(obj);
+
+ visit_type_int32(v, &d->conf.bootindex, name, errp);
+}
+
+static void ide_dev_set_bootindex(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ IDEDevice *d = IDE_DEVICE(obj);
+ int32_t boot_index;
+ Error *local_err = NULL;
+
+ visit_type_int32(v, &boot_index, name, &local_err);
+ if (local_err) {
+ goto out;
+ }
+ /* check whether bootindex is present in fw_boot_order list */
+ check_boot_index(boot_index, &local_err);
+ if (local_err) {
+ goto out;
+ }
+ /* change bootindex to a new one */
+ d->conf.bootindex = boot_index;
+
+ if (d->unit != -1) {
+ add_boot_device_path(d->conf.bootindex, &d->qdev,
+ d->unit ? "/disk@1" : "/disk@0");
+ }
+out:
+ if (local_err) {
+ error_propagate(errp, local_err);
+ }
+}
+
+static void ide_dev_instance_init(Object *obj)
+{
+ object_property_add(obj, "bootindex", "int32",
+ ide_dev_get_bootindex,
+ ide_dev_set_bootindex, NULL, NULL, NULL);
+ object_property_set_int(obj, -1, "bootindex", NULL);
+}
+
static int ide_hd_initfn(IDEDevice *dev)
{
return ide_dev_initfn(dev, IDE_HD);
@@ -300,6 +346,7 @@ static const TypeInfo ide_device_type_info = {
.abstract = true,
.class_size = sizeof(IDEDeviceClass),
.class_init = ide_device_class_init,
+ .instance_init = ide_dev_instance_init,
};
static void ide_register_types(void)
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index 177023bcaf..530b074551 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -607,8 +607,8 @@ static void ich9_device_plug_cb(HotplugHandler *hotplug_dev,
ich9_pm_device_plug_cb(&lpc->pm, dev, errp);
}
-static void ich9_device_unplug_cb(HotplugHandler *hotplug_dev,
- DeviceState *dev, Error **errp)
+static void ich9_device_unplug_request_cb(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
{
error_setg(errp, "acpi: device unplug request for not supported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -676,7 +676,7 @@ static void ich9_lpc_class_init(ObjectClass *klass, void *data)
*/
dc->cannot_instantiate_with_device_add_yet = true;
hc->plug = ich9_device_plug_cb;
- hc->unplug = ich9_device_unplug_cb;
+ hc->unplug_request = ich9_device_unplug_request_cb;
adevc->ospm_status = ich9_pm_ospm_status;
}
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index b20807c4e4..e8e075c600 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -697,12 +697,12 @@ static void write_bootloader (CPUMIPSState *env, uint8_t *base,
/* Jump to kernel code */
stl_p(p++, 0x3c1f0000 | ((kernel_entry >> 16) & 0xffff)); /* lui ra, high(kernel_entry) */
stl_p(p++, 0x37ff0000 | (kernel_entry & 0xffff)); /* ori ra, ra, low(kernel_entry) */
- stl_p(p++, 0x03e00008); /* jr ra */
+ stl_p(p++, 0x03e00009); /* jalr ra */
stl_p(p++, 0x00000000); /* nop */
/* YAMON subroutines */
p = (uint32_t *) (base + 0x800);
- stl_p(p++, 0x03e00008); /* jr ra */
+ stl_p(p++, 0x03e00009); /* jalr ra */
stl_p(p++, 0x24020000); /* li v0,0 */
/* 808 YAMON print */
stl_p(p++, 0x03e06821); /* move t5,ra */
@@ -716,7 +716,7 @@ static void write_bootloader (CPUMIPSState *env, uint8_t *base,
stl_p(p++, 0x00000000); /* nop */
stl_p(p++, 0x08000205); /* j 814 */
stl_p(p++, 0x00000000); /* nop */
- stl_p(p++, 0x01a00008); /* jr t5 */
+ stl_p(p++, 0x01a00009); /* jalr t5 */
stl_p(p++, 0x01602021); /* move a0,t3 */
/* 0x83c YAMON print_count */
stl_p(p++, 0x03e06821); /* move t5,ra */
@@ -730,7 +730,7 @@ static void write_bootloader (CPUMIPSState *env, uint8_t *base,
stl_p(p++, 0x258cffff); /* addiu t4,t4,-1 */
stl_p(p++, 0x1580fffa); /* bnez t4,84c */
stl_p(p++, 0x00000000); /* nop */
- stl_p(p++, 0x01a00008); /* jr t5 */
+ stl_p(p++, 0x01a00009); /* jalr t5 */
stl_p(p++, 0x01602021); /* move a0,t3 */
/* 0x870 */
stl_p(p++, 0x3c08b800); /* lui t0,0xb400 */
@@ -740,7 +740,7 @@ static void write_bootloader (CPUMIPSState *env, uint8_t *base,
stl_p(p++, 0x31290040); /* andi t1,t1,0x40 */
stl_p(p++, 0x1120fffc); /* beqz t1,878 <outch+0x8> */
stl_p(p++, 0x00000000); /* nop */
- stl_p(p++, 0x03e00008); /* jr ra */
+ stl_p(p++, 0x03e00009); /* jalr ra */
stl_p(p++, 0xa1040000); /* sb a0,0(t0) */
}
diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
index d66f3d2425..b5e798173b 100644
--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -4296,7 +4296,6 @@ static int vfio_initfn(PCIDevice *pdev)
}
}
- add_boot_device_path(vdev->bootindex, &pdev->qdev, NULL);
vfio_register_err_notifier(vdev);
return 0;
@@ -4365,13 +4364,22 @@ post_reset:
vfio_pci_post_reset(vdev);
}
+static void vfio_instance_init(Object *obj)
+{
+ PCIDevice *pci_dev = PCI_DEVICE(obj);
+ VFIODevice *vdev = DO_UPCAST(VFIODevice, pdev, PCI_DEVICE(obj));
+
+ device_add_bootindex_property(obj, &vdev->bootindex,
+ "bootindex", NULL,
+ &pci_dev->qdev, NULL);
+}
+
static Property vfio_pci_dev_properties[] = {
DEFINE_PROP_PCI_HOST_DEVADDR("host", VFIODevice, host),
DEFINE_PROP_UINT32("x-intx-mmap-timeout-ms", VFIODevice,
intx.mmap_timeout, 1100),
DEFINE_PROP_BIT("x-vga", VFIODevice, features,
VFIO_FEATURE_ENABLE_VGA_BIT, false),
- DEFINE_PROP_INT32("bootindex", VFIODevice, bootindex, -1),
/*
* TODO - support passed fds... is this necessary?
* DEFINE_PROP_STRING("vfiofd", VFIODevice, vfiofd_name),
@@ -4407,6 +4415,7 @@ static const TypeInfo vfio_pci_dev_info = {
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(VFIODevice),
.class_init = vfio_pci_dev_class_init,
+ .instance_init = vfio_instance_init,
};
static void register_vfio_pci_dev_type(void)
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 272df00f4a..e33a4da9fa 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -1569,8 +1569,6 @@ static int pci_e1000_init(PCIDevice *pci_dev)
qemu_format_nic_info_str(qemu_get_queue(d->nic), macaddr);
- add_boot_device_path(d->conf.bootindex, dev, "/ethernet-phy@0");
-
d->autoneg_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, e1000_autoneg_timer, d);
d->mit_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, e1000_mit_timer, d);
@@ -1621,10 +1619,19 @@ static void e1000_class_init(ObjectClass *klass, void *data)
dc->props = e1000_properties;
}
+static void e1000_instance_init(Object *obj)
+{
+ E1000State *n = E1000(obj);
+ device_add_bootindex_property(obj, &n->conf.bootindex,
+ "bootindex", "/ethernet-phy@0",
+ DEVICE(n), NULL);
+}
+
static const TypeInfo e1000_base_info = {
.name = TYPE_E1000_BASE,
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(E1000State),
+ .instance_init = e1000_instance_init,
.class_size = sizeof(E1000BaseClass),
.abstract = true,
};
@@ -1668,6 +1675,7 @@ static void e1000_register_types(void)
type_info.parent = TYPE_E1000_BASE;
type_info.class_data = (void *)info;
type_info.class_init = e1000_class_init;
+ type_info.instance_init = e1000_instance_init;
type_register(&type_info);
}
diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
index 3cd826accc..4877bfd4d3 100644
--- a/hw/net/eepro100.c
+++ b/hw/net/eepro100.c
@@ -1901,11 +1901,17 @@ static int e100_nic_init(PCIDevice *pci_dev)
s->vmstate->name = qemu_get_queue(s->nic)->model;
vmstate_register(&pci_dev->qdev, -1, s->vmstate, s);
- add_boot_device_path(s->conf.bootindex, &pci_dev->qdev, "/ethernet-phy@0");
-
return 0;
}
+static void eepro100_instance_init(Object *obj)
+{
+ EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, PCI_DEVICE(obj));
+ device_add_bootindex_property(obj, &s->conf.bootindex,
+ "bootindex", "/ethernet-phy@0",
+ DEVICE(s), NULL);
+}
+
static E100PCIDeviceInfo e100_devices[] = {
{
.name = "i82550",
@@ -2104,7 +2110,8 @@ static void eepro100_register_types(void)
type_info.parent = TYPE_PCI_DEVICE;
type_info.class_init = eepro100_class_init;
type_info.instance_size = sizeof(EEPRO100State);
-
+ type_info.instance_init = eepro100_instance_init;
+
type_register(&type_info);
}
}
diff --git a/hw/net/lance.c b/hw/net/lance.c
index 7811a9edc2..a1c49f1b97 100644
--- a/hw/net/lance.c
+++ b/hw/net/lance.c
@@ -42,6 +42,7 @@
#include "hw/sparc/sun4m.h"
#include "pcnet.h"
#include "trace.h"
+#include "sysemu/sysemu.h"
#define TYPE_LANCE "lance"
#define SYSBUS_PCNET(obj) \
@@ -143,6 +144,16 @@ static void lance_reset(DeviceState *dev)
pcnet_h_reset(&d->state);
}
+static void lance_instance_init(Object *obj)
+{
+ SysBusPCNetState *d = SYSBUS_PCNET(obj);
+ PCNetState *s = &d->state;
+
+ device_add_bootindex_property(obj, &s->conf.bootindex,
+ "bootindex", "/ethernet-phy@0",
+ DEVICE(obj), NULL);
+}
+
static Property lance_properties[] = {
DEFINE_PROP_PTR("dma", SysBusPCNetState, state.dma_opaque),
DEFINE_NIC_PROPERTIES(SysBusPCNetState, state.conf),
@@ -169,6 +180,7 @@ static const TypeInfo lance_info = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SysBusPCNetState),
.class_init = lance_class_init,
+ .instance_init = lance_instance_init,
};
static void lance_register_types(void)
diff --git a/hw/net/ne2000-isa.c b/hw/net/ne2000-isa.c
index 6eb1dac8dc..82e2ba17c1 100644
--- a/hw/net/ne2000-isa.c
+++ b/hw/net/ne2000-isa.c
@@ -28,6 +28,7 @@
#include "net/net.h"
#include "ne2000.h"
#include "exec/address-spaces.h"
+#include "qapi/visitor.h"
#define TYPE_ISA_NE2000 "ne2k_isa"
#define ISA_NE2000(obj) OBJECT_CHECK(ISANE2000State, (obj), TYPE_ISA_NE2000)
@@ -101,11 +102,54 @@ static void isa_ne2000_class_initfn(ObjectClass *klass, void *data)
set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
}
+static void isa_ne2000_get_bootindex(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ ISANE2000State *isa = ISA_NE2000(obj);
+ NE2000State *s = &isa->ne2000;
+
+ visit_type_int32(v, &s->c.bootindex, name, errp);
+}
+
+static void isa_ne2000_set_bootindex(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ ISANE2000State *isa = ISA_NE2000(obj);
+ NE2000State *s = &isa->ne2000;
+ int32_t boot_index;
+ Error *local_err = NULL;
+
+ visit_type_int32(v, &boot_index, name, &local_err);
+ if (local_err) {
+ goto out;
+ }
+ /* check whether bootindex is present in fw_boot_order list */
+ check_boot_index(boot_index, &local_err);
+ if (local_err) {
+ goto out;
+ }
+ /* change bootindex to a new one */
+ s->c.bootindex = boot_index;
+
+out:
+ if (local_err) {
+ error_propagate(errp, local_err);
+ }
+}
+
+static void isa_ne2000_instance_init(Object *obj)
+{
+ object_property_add(obj, "bootindex", "int32",
+ isa_ne2000_get_bootindex,
+ isa_ne2000_set_bootindex, NULL, NULL, NULL);
+ object_property_set_int(obj, -1, "bootindex", NULL);
+}
static const TypeInfo ne2000_isa_info = {
.name = TYPE_ISA_NE2000,
.parent = TYPE_ISA_DEVICE,
.instance_size = sizeof(ISANE2000State),
.class_init = isa_ne2000_class_initfn,
+ .instance_init = isa_ne2000_instance_init,
};
static void ne2000_isa_register_types(void)
diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
index a62d12d92d..3ab2d03696 100644
--- a/hw/net/ne2000.c
+++ b/hw/net/ne2000.c
@@ -738,8 +738,6 @@ static int pci_ne2000_init(PCIDevice *pci_dev)
object_get_typename(OBJECT(pci_dev)), pci_dev->qdev.id, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->c.macaddr.a);
- add_boot_device_path(s->c.bootindex, &pci_dev->qdev, "/ethernet-phy@0");
-
return 0;
}
@@ -752,6 +750,17 @@ static void pci_ne2000_exit(PCIDevice *pci_dev)
qemu_free_irq(s->irq);
}
+static void ne2000_instance_init(Object *obj)
+{
+ PCIDevice *pci_dev = PCI_DEVICE(obj);
+ PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
+ NE2000State *s = &d->ne2000;
+
+ device_add_bootindex_property(obj, &s->c.bootindex,
+ "bootindex", "/ethernet-phy@0",
+ &pci_dev->qdev, NULL);
+}
+
static Property ne2000_properties[] = {
DEFINE_NIC_PROPERTIES(PCINE2000State, ne2000.c),
DEFINE_PROP_END_OF_LIST(),
@@ -778,6 +787,7 @@ static const TypeInfo ne2000_info = {
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCINE2000State),
.class_init = ne2000_class_init,
+ .instance_init = ne2000_instance_init,
};
static void ne2000_register_types(void)
diff --git a/hw/net/pcnet-pci.c b/hw/net/pcnet-pci.c
index 50ffe914e0..fb5f5d6237 100644
--- a/hw/net/pcnet-pci.c
+++ b/hw/net/pcnet-pci.c
@@ -32,6 +32,7 @@
#include "hw/loader.h"
#include "qemu/timer.h"
#include "sysemu/dma.h"
+#include "sysemu/sysemu.h"
#include "pcnet.h"
@@ -344,6 +345,16 @@ static void pci_reset(DeviceState *dev)
pcnet_h_reset(&d->state);
}
+static void pcnet_instance_init(Object *obj)
+{
+ PCIPCNetState *d = PCI_PCNET(obj);
+ PCNetState *s = &d->state;
+
+ device_add_bootindex_property(obj, &s->conf.bootindex,
+ "bootindex", "/ethernet-phy@0",
+ DEVICE(obj), NULL);
+}
+
static Property pcnet_properties[] = {
DEFINE_NIC_PROPERTIES(PCIPCNetState, state.conf),
DEFINE_PROP_END_OF_LIST(),
@@ -372,6 +383,7 @@ static const TypeInfo pcnet_info = {
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIPCNetState),
.class_init = pcnet_class_init,
+ .instance_init = pcnet_instance_init,
};
static void pci_pcnet_register_types(void)
diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c
index 5299d52a8f..d344c15da0 100644
--- a/hw/net/pcnet.c
+++ b/hw/net/pcnet.c
@@ -1735,8 +1735,6 @@ int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info)
s->nic = qemu_new_nic(info, &s->conf, object_get_typename(OBJECT(dev)), dev->id, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
- add_boot_device_path(s->conf.bootindex, dev, "/ethernet-phy@0");
-
/* Initialize the PROM */
/*
diff --git a/hw/net/pcnet.h b/hw/net/pcnet.h
index 9dee6f3e2c..f8e8a6f6ba 100644
--- a/hw/net/pcnet.h
+++ b/hw/net/pcnet.h
@@ -66,5 +66,4 @@ void pcnet_set_link_status(NetClientState *nc);
void pcnet_common_cleanup(PCNetState *d);
int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info);
extern const VMStateDescription vmstate_pcnet;
-
#endif
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index 6e59f3819b..8b8a1b18af 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -3538,11 +3538,18 @@ static int pci_rtl8139_init(PCIDevice *dev)
s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, rtl8139_timer, s);
rtl8139_set_next_tctr_time(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
- add_boot_device_path(s->conf.bootindex, d, "/ethernet-phy@0");
-
return 0;
}
+static void rtl8139_instance_init(Object *obj)
+{
+ RTL8139State *s = RTL8139(obj);
+
+ device_add_bootindex_property(obj, &s->conf.bootindex,
+ "bootindex", "/ethernet-phy@0",
+ DEVICE(obj), NULL);
+}
+
static Property rtl8139_properties[] = {
DEFINE_NIC_PROPERTIES(RTL8139State, conf),
DEFINE_PROP_END_OF_LIST(),
@@ -3571,6 +3578,7 @@ static const TypeInfo rtl8139_info = {
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(RTL8139State),
.class_init = rtl8139_class_init,
+ .instance_init = rtl8139_instance_init,
};
static void rtl8139_register_types(void)
diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c
index 23c47d397c..2c8b038227 100644
--- a/hw/net/spapr_llan.c
+++ b/hw/net/spapr_llan.c
@@ -221,11 +221,18 @@ static int spapr_vlan_init(VIOsPAPRDevice *sdev)
object_get_typename(OBJECT(sdev)), sdev->qdev.id, dev);
qemu_format_nic_info_str(qemu_get_queue(dev->nic), dev->nicconf.macaddr.a);
- add_boot_device_path(dev->nicconf.bootindex, DEVICE(dev), "");
-
return 0;
}
+static void spapr_vlan_instance_init(Object *obj)
+{
+ VIOsPAPRVLANDevice *dev = VIO_SPAPR_VLAN_DEVICE(obj);
+
+ device_add_bootindex_property(obj, &dev->nicconf.bootindex,
+ "bootindex", "",
+ DEVICE(dev), NULL);
+}
+
void spapr_vlan_create(VIOsPAPRBus *bus, NICInfo *nd)
{
DeviceState *dev;
@@ -553,6 +560,7 @@ static const TypeInfo spapr_vlan_info = {
.parent = TYPE_VIO_SPAPR_DEVICE,
.instance_size = sizeof(VIOsPAPRVLANDevice),
.class_init = spapr_vlan_class_init,
+ .instance_init = spapr_vlan_instance_init,
};
static void spapr_vlan_register_types(void)
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 2040eac9a1..9b88775fac 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1661,8 +1661,6 @@ static void virtio_net_device_realize(DeviceState *dev, Error **errp)
n->qdev = dev;
register_savevm(dev, "virtio-net", -1, VIRTIO_NET_VM_VERSION,
virtio_net_save, virtio_net_load, n);
-
- add_boot_device_path(n->nic_conf.bootindex, dev, "/ethernet-phy@0");
}
static void virtio_net_device_unrealize(DeviceState *dev, Error **errp)
@@ -1714,6 +1712,9 @@ static void virtio_net_instance_init(Object *obj)
* Can be overriden with virtio_net_set_config_size.
*/
n->config_size = sizeof(struct virtio_net_config);
+ device_add_bootindex_property(obj, &n->nic_conf.bootindex,
+ "bootindex", "/ethernet-phy@0",
+ DEVICE(n), NULL);
}
static Property virtio_net_properties[] = {
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index f246fa1c45..8eea58989b 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -2172,11 +2172,16 @@ static int vmxnet3_pci_init(PCIDevice *pci_dev)
register_savevm(dev, "vmxnet3-msix", -1, 1,
vmxnet3_msix_save, vmxnet3_msix_load, s);
- add_boot_device_path(s->conf.bootindex, dev, "/ethernet-phy@0");
-
return 0;
}
+static void vmxnet3_instance_init(Object *obj)
+{
+ VMXNET3State *s = VMXNET3(obj);
+ device_add_bootindex_property(obj, &s->conf.bootindex,
+ "bootindex", "/ethernet-phy@0",
+ DEVICE(obj), NULL);
+}
static void vmxnet3_pci_uninit(PCIDevice *pci_dev)
{
@@ -2524,6 +2529,7 @@ static const TypeInfo vmxnet3_info = {
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(VMXNET3State),
.class_init = vmxnet3_class_init,
+ .instance_init = vmxnet3_instance_init,
};
static void vmxnet3_register_types(void)
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index b71d251568..e7ed27e242 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -402,6 +402,26 @@ static void fw_cfg_add_bytes_read_callback(FWCfgState *s, uint16_t key,
s->entries[arch][key].callback_opaque = callback_opaque;
}
+static void *fw_cfg_modify_bytes_read(FWCfgState *s, uint16_t key,
+ void *data, size_t len)
+{
+ void *ptr;
+ int arch = !!(key & FW_CFG_ARCH_LOCAL);
+
+ key &= FW_CFG_ENTRY_MASK;
+
+ assert(key < FW_CFG_MAX_ENTRY && len < UINT32_MAX);
+
+ /* return the old data to the function caller, avoid memory leak */
+ ptr = s->entries[arch][key].data;
+ s->entries[arch][key].data = data;
+ s->entries[arch][key].len = len;
+ s->entries[arch][key].callback_opaque = NULL;
+ s->entries[arch][key].callback = NULL;
+
+ return ptr;
+}
+
void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len)
{
fw_cfg_add_bytes_read_callback(s, key, NULL, NULL, data, len);
@@ -499,13 +519,42 @@ void fw_cfg_add_file(FWCfgState *s, const char *filename,
fw_cfg_add_file_callback(s, filename, NULL, NULL, data, len);
}
-static void fw_cfg_machine_ready(struct Notifier *n, void *data)
+void *fw_cfg_modify_file(FWCfgState *s, const char *filename,
+ void *data, size_t len)
+{
+ int i, index;
+
+ assert(s->files);
+
+ index = be32_to_cpu(s->files->count);
+ assert(index < FW_CFG_FILE_SLOTS);
+
+ for (i = 0; i < index; i++) {
+ if (strcmp(filename, s->files->f[i].name) == 0) {
+ return fw_cfg_modify_bytes_read(s, FW_CFG_FILE_FIRST + i,
+ data, len);
+ }
+ }
+ /* add new one */
+ fw_cfg_add_file_callback(s, filename, NULL, NULL, data, len);
+ return NULL;
+}
+
+static void fw_cfg_machine_reset(void *opaque)
{
+ void *ptr;
size_t len;
- FWCfgState *s = container_of(n, FWCfgState, machine_ready);
+ FWCfgState *s = opaque;
char *bootindex = get_boot_devices_list(&len, false);
- fw_cfg_add_file(s, "bootorder", (uint8_t*)bootindex, len);
+ ptr = fw_cfg_modify_file(s, "bootorder", (uint8_t *)bootindex, len);
+ g_free(ptr);
+}
+
+static void fw_cfg_machine_ready(struct Notifier *n, void *data)
+{
+ FWCfgState *s = container_of(n, FWCfgState, machine_ready);
+ qemu_register_reset(fw_cfg_machine_reset, s);
}
FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
diff --git a/hw/pci-bridge/pci_bridge_dev.c b/hw/pci-bridge/pci_bridge_dev.c
index 92799d08ef..252ea5eb53 100644
--- a/hw/pci-bridge/pci_bridge_dev.c
+++ b/hw/pci-bridge/pci_bridge_dev.c
@@ -150,7 +150,7 @@ static void pci_bridge_dev_class_init(ObjectClass *klass, void *data)
dc->vmsd = &pci_bridge_dev_vmstate;
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
hc->plug = shpc_device_hotplug_cb;
- hc->unplug = shpc_device_hot_unplug_cb;
+ hc->unplug_request = shpc_device_hot_unplug_request_cb;
}
static const TypeInfo pci_bridge_dev_info = {
diff --git a/hw/pci/pci-hotplug-old.c b/hw/pci/pci-hotplug-old.c
index d87c469096..6ab28b703c 100644
--- a/hw/pci/pci-hotplug-old.c
+++ b/hw/pci/pci-hotplug-old.c
@@ -77,7 +77,7 @@ static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon,
monitor_printf(mon, "Invalid PCI device address %s\n", devaddr);
return NULL;
}
- if (!((BusState*)bus)->allow_hotplug) {
+ if (!qbus_is_hotpluggable(BUS(bus))) {
monitor_printf(mon, "PCI bus doesn't support hotplug\n");
return NULL;
}
@@ -227,7 +227,7 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
monitor_printf(mon, "Invalid PCI device address %s\n", devaddr);
return NULL;
}
- if (!((BusState*)bus)->allow_hotplug) {
+ if (!qbus_is_hotpluggable(BUS(bus))) {
monitor_printf(mon, "PCI bus doesn't support hotplug\n");
return NULL;
}
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 1babddff4d..b64a004631 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -262,8 +262,8 @@ void pcie_cap_slot_hotplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
PCI_EXP_HP_EV_PDC | PCI_EXP_HP_EV_ABP);
}
-void pcie_cap_slot_hot_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
- Error **errp)
+void pcie_cap_slot_hot_unplug_request_cb(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
{
uint8_t *exp_cap;
diff --git a/hw/pci/pcie_port.c b/hw/pci/pcie_port.c
index fa24877955..40ca8d5d17 100644
--- a/hw/pci/pcie_port.c
+++ b/hw/pci/pcie_port.c
@@ -154,7 +154,7 @@ static void pcie_slot_class_init(ObjectClass *oc, void *data)
dc->props = pcie_slot_props;
hc->plug = pcie_cap_slot_hotplug_cb;
- hc->unplug = pcie_cap_slot_hot_unplug_cb;
+ hc->unplug_request = pcie_cap_slot_hot_unplug_request_cb;
}
static const TypeInfo pcie_slot_type_info = {
diff --git a/hw/pci/shpc.c b/hw/pci/shpc.c
index 1fcb8c4d85..65b2f5103f 100644
--- a/hw/pci/shpc.c
+++ b/hw/pci/shpc.c
@@ -549,8 +549,8 @@ void shpc_device_hotplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
shpc_interrupt_update(pci_hotplug_dev);
}
-void shpc_device_hot_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
- Error **errp)
+void shpc_device_hot_unplug_request_cb(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
{
Error *local_err = NULL;
PCIDevice *pci_hotplug_dev = PCI_DEVICE(hotplug_dev);
diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c
index 597db34019..78da718362 100644
--- a/hw/s390x/event-facility.c
+++ b/hw/s390x/event-facility.c
@@ -333,7 +333,6 @@ static int init_event_facility(SCLPEventFacility *event_facility)
/* Spawn a new bus for SCLP events */
qbus_create_inplace(&event_facility->sbus, sizeof(event_facility->sbus),
TYPE_SCLP_EVENTS_BUS, sdev, NULL);
- event_facility->sbus.qbus.allow_hotplug = 0;
quiesce = qdev_create(&event_facility->sbus.qbus, "sclpquiesce");
if (!quiesce) {
@@ -408,7 +407,6 @@ static void event_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
dc->bus_type = TYPE_SCLP_EVENTS_BUS;
- dc->unplug = qdev_simple_unplug_cb;
dc->realize = event_realize;
dc->unrealize = event_unrealize;
}
diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c
index f451ca1ed3..29ecdb4194 100644
--- a/hw/s390x/s390-virtio-bus.c
+++ b/hw/s390x/s390-virtio-bus.c
@@ -102,7 +102,7 @@ VirtIOS390Bus *s390_virtio_bus_init(ram_addr_t *ram_size)
bus->next_ring = bus->dev_page + TARGET_PAGE_SIZE;
/* Enable hotplugging */
- _bus->allow_hotplug = 1;
+ qbus_set_hotplug_handler(_bus, dev, &error_abort);
/* Allocate RAM for VirtIO device pages (descriptors, queues, rings) */
*ram_size += S390_DEVICE_PAGES * TARGET_PAGE_SIZE;
@@ -162,6 +162,8 @@ static void s390_virtio_net_instance_init(Object *obj)
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_NET);
+ object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
+ "bootindex", &error_abort);
}
static int s390_virtio_blk_init(VirtIOS390Device *s390_dev)
@@ -183,6 +185,8 @@ static void s390_virtio_blk_instance_init(Object *obj)
TYPE_VIRTIO_BLK);
object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread",
&error_abort);
+ object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
+ "bootindex", &error_abort);
}
static int s390_virtio_serial_init(VirtIOS390Device *s390_dev)
@@ -600,7 +604,6 @@ static void virtio_s390_device_class_init(ObjectClass *klass, void *data)
dc->init = s390_virtio_busdev_init;
dc->bus_type = TYPE_S390_VIRTIO_BUS;
- dc->unplug = qdev_simple_unplug_cb;
dc->reset = s390_virtio_busdev_reset;
}
@@ -681,6 +684,10 @@ static const TypeInfo s390_virtio_bridge_info = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SysBusDevice),
.class_init = s390_virtio_bridge_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_HOTPLUG_HANDLER },
+ { }
+ }
};
/* virtio-s390-bus */
@@ -689,13 +696,10 @@ static void virtio_s390_bus_new(VirtioBusState *bus, size_t bus_size,
VirtIOS390Device *dev)
{
DeviceState *qdev = DEVICE(dev);
- BusState *qbus;
char virtio_bus_name[] = "virtio-bus";
qbus_create_inplace(bus, bus_size, TYPE_VIRTIO_S390_BUS,
qdev, virtio_bus_name);
- qbus = BUS(bus);
- qbus->allow_hotplug = 1;
}
static void virtio_s390_bus_class_init(ObjectClass *klass, void *data)
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 18ba29fa14..f5ec94657f 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -230,7 +230,7 @@ VirtualCssBus *virtual_css_bus_init(void)
cbus = VIRTUAL_CSS_BUS(bus);
/* Enable hotplugging */
- bus->allow_hotplug = 1;
+ qbus_set_hotplug_handler(bus, dev, &error_abort);
return cbus;
}
@@ -795,6 +795,8 @@ static void virtio_ccw_net_instance_init(Object *obj)
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_NET);
+ object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
+ "bootindex", &error_abort);
}
static int virtio_ccw_blk_init(VirtioCcwDevice *ccw_dev)
@@ -817,6 +819,8 @@ static void virtio_ccw_blk_instance_init(Object *obj)
TYPE_VIRTIO_BLK);
object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread",
&error_abort);
+ object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
+ "bootindex", &error_abort);
}
static int virtio_ccw_serial_init(VirtioCcwDevice *ccw_dev)
@@ -1590,7 +1594,8 @@ static int virtio_ccw_busdev_exit(DeviceState *dev)
return _info->exit(_dev);
}
-static int virtio_ccw_busdev_unplug(DeviceState *dev)
+static void virtio_ccw_busdev_unplug(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
{
VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
SubchDev *sch = _dev->sch;
@@ -1609,7 +1614,6 @@ static int virtio_ccw_busdev_unplug(DeviceState *dev)
css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid, 1, 0);
object_unparent(OBJECT(dev));
- return 0;
}
static Property virtio_ccw_properties[] = {
@@ -1624,9 +1628,7 @@ static void virtio_ccw_device_class_init(ObjectClass *klass, void *data)
dc->props = virtio_ccw_properties;
dc->init = virtio_ccw_busdev_init;
dc->exit = virtio_ccw_busdev_exit;
- dc->unplug = virtio_ccw_busdev_unplug;
dc->bus_type = TYPE_VIRTUAL_CSS_BUS;
-
}
static const TypeInfo virtio_ccw_device_info = {
@@ -1650,8 +1652,10 @@ static int virtual_css_bridge_init(SysBusDevice *dev)
static void virtual_css_bridge_class_init(ObjectClass *klass, void *data)
{
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
k->init = virtual_css_bridge_init;
+ hc->unplug = virtio_ccw_busdev_unplug;
}
static const TypeInfo virtual_css_bridge_info = {
@@ -1659,6 +1663,10 @@ static const TypeInfo virtual_css_bridge_info = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SysBusDevice),
.class_init = virtual_css_bridge_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_HOTPLUG_HANDLER },
+ { }
+ }
};
/* virtio-ccw-bus */
@@ -1667,13 +1675,10 @@ static void virtio_ccw_bus_new(VirtioBusState *bus, size_t bus_size,
VirtioCcwDevice *dev)
{
DeviceState *qdev = DEVICE(dev);
- BusState *qbus;
char virtio_bus_name[] = "virtio-bus";
qbus_create_inplace(bus, bus_size, TYPE_VIRTIO_CCW_BUS,
qdev, virtio_bus_name);
- qbus = BUS(bus);
- qbus->allow_hotplug = 1;
}
static void virtio_ccw_bus_class_init(ObjectClass *klass, void *data)
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 0f3e0395f5..022a524074 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -23,9 +23,11 @@ static Property scsi_props[] = {
static void scsi_bus_class_init(ObjectClass *klass, void *data)
{
BusClass *k = BUS_CLASS(klass);
+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
k->get_dev_path = scsibus_get_dev_path;
k->get_fw_dev_path = scsibus_get_fw_dev_path;
+ hc->unplug = qdev_simple_device_unplug_cb;
}
static const TypeInfo scsi_bus_info = {
@@ -33,6 +35,10 @@ static const TypeInfo scsi_bus_info = {
.parent = TYPE_BUS,
.instance_size = sizeof(SCSIBus),
.class_init = scsi_bus_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_HOTPLUG_HANDLER },
+ { }
+ }
};
static int next_scsi_bus;
@@ -92,7 +98,7 @@ void scsi_bus_new(SCSIBus *bus, size_t bus_size, DeviceState *host,
qbus_create_inplace(bus, bus_size, TYPE_SCSI_BUS, host, bus_name);
bus->busnr = next_scsi_bus++;
bus->info = info;
- bus->qbus.allow_hotplug = 1;
+ qbus_set_bus_hotplug_handler(BUS(bus), &error_abort);
}
static void scsi_dma_restart_bh(void *opaque)
@@ -202,10 +208,6 @@ static void scsi_qdev_realize(DeviceState *qdev, Error **errp)
}
dev->vmsentry = qemu_add_vm_change_state_handler(scsi_dma_restart_cb,
dev);
-
- if (bus->info->hotplug) {
- bus->info->hotplug(bus, dev);
- }
}
static void scsi_qdev_unrealize(DeviceState *qdev, Error **errp)
@@ -231,7 +233,8 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv,
dev = qdev_create(&bus->qbus, driver);
qdev_prop_set_uint32(dev, "scsi-id", unit);
if (bootindex >= 0) {
- qdev_prop_set_int32(dev, "bootindex", bootindex);
+ object_property_set_int(OBJECT(dev), bootindex, "bootindex",
+ &error_abort);
}
if (object_property_find(OBJECT(dev), "removable", NULL)) {
qdev_prop_set_bit(dev, "removable", removable);
@@ -1937,17 +1940,6 @@ static int get_scsi_requests(QEMUFile *f, void *pv, size_t size)
return 0;
}
-static int scsi_qdev_unplug(DeviceState *qdev)
-{
- SCSIDevice *dev = SCSI_DEVICE(qdev);
- SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
-
- if (bus->info->hot_unplug) {
- bus->info->hot_unplug(bus, dev);
- }
- return qdev_simple_unplug_cb(qdev);
-}
-
static const VMStateInfo vmstate_info_scsi_requests = {
.name = "scsi-requests",
.get = get_scsi_requests,
@@ -2011,11 +2003,20 @@ static void scsi_device_class_init(ObjectClass *klass, void *data)
set_bit(DEVICE_CATEGORY_STORAGE, k->categories);
k->bus_type = TYPE_SCSI_BUS;
k->realize = scsi_qdev_realize;
- k->unplug = scsi_qdev_unplug;
k->unrealize = scsi_qdev_unrealize;
k->props = scsi_props;
}
+static void scsi_dev_instance_init(Object *obj)
+{
+ DeviceState *dev = DEVICE(obj);
+ SCSIDevice *s = DO_UPCAST(SCSIDevice, qdev, dev);
+
+ device_add_bootindex_property(obj, &s->conf.bootindex,
+ "bootindex", NULL,
+ &s->qdev, NULL);
+}
+
static const TypeInfo scsi_device_type_info = {
.name = TYPE_SCSI_DEVICE,
.parent = TYPE_DEVICE,
@@ -2023,6 +2024,7 @@ static const TypeInfo scsi_device_type_info = {
.abstract = true,
.class_size = sizeof(SCSIDeviceClass),
.class_init = scsi_device_class_init,
+ .instance_init = scsi_dev_instance_init,
};
static void scsi_register_types(void)
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 7a7938a5bf..ae9e08dd13 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -2269,7 +2269,6 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
bdrv_set_guest_block_size(s->qdev.conf.bs, s->qdev.blocksize);
bdrv_iostatus_enable(s->qdev.conf.bs);
- add_boot_device_path(s->qdev.conf.bootindex, &dev->qdev, NULL);
}
static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
@@ -2662,7 +2661,6 @@ static const TypeInfo scsi_cd_info = {
#ifdef __linux__
static Property scsi_block_properties[] = {
DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.bs),
- DEFINE_PROP_INT32("bootindex", SCSIDiskState, qdev.conf.bootindex, -1),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index 01bca084e6..84a1d5bfe3 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -413,9 +413,6 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp)
/* define device state */
s->type = scsiid.scsi_type;
DPRINTF("device type %d\n", s->type);
- if (s->type == TYPE_DISK || s->type == TYPE_ROM) {
- add_boot_device_path(s->conf.bootindex, &s->qdev, NULL);
- }
switch (s->type) {
case TYPE_TAPE:
@@ -463,7 +460,6 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
static Property scsi_generic_properties[] = {
DEFINE_PROP_DRIVE("drive", SCSIDevice, conf.bs),
- DEFINE_PROP_INT32("bootindex", SCSIDevice, conf.bootindex, -1),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 6c02fe2b9a..8547ea0475 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -737,26 +737,29 @@ static void virtio_scsi_change(SCSIBus *bus, SCSIDevice *dev, SCSISense sense)
}
}
-static void virtio_scsi_hotplug(SCSIBus *bus, SCSIDevice *dev)
+static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev,
+ Error **errp)
{
- VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
- VirtIODevice *vdev = VIRTIO_DEVICE(s);
+ VirtIODevice *vdev = VIRTIO_DEVICE(hotplug_dev);
if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
- virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_TRANSPORT_RESET,
+ virtio_scsi_push_event(VIRTIO_SCSI(hotplug_dev), SCSI_DEVICE(dev),
+ VIRTIO_SCSI_T_TRANSPORT_RESET,
VIRTIO_SCSI_EVT_RESET_RESCAN);
}
}
-static void virtio_scsi_hot_unplug(SCSIBus *bus, SCSIDevice *dev)
+static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev,
+ Error **errp)
{
- VirtIOSCSI *s = container_of(bus, VirtIOSCSI, bus);
- VirtIODevice *vdev = VIRTIO_DEVICE(s);
+ VirtIODevice *vdev = VIRTIO_DEVICE(hotplug_dev);
if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {
- virtio_scsi_push_event(s, dev, VIRTIO_SCSI_T_TRANSPORT_RESET,
+ virtio_scsi_push_event(VIRTIO_SCSI(hotplug_dev), SCSI_DEVICE(dev),
+ VIRTIO_SCSI_T_TRANSPORT_RESET,
VIRTIO_SCSI_EVT_RESET_REMOVED);
}
+ qdev_simple_device_unplug_cb(hotplug_dev, dev, errp);
}
static struct SCSIBusInfo virtio_scsi_scsi_info = {
@@ -768,8 +771,6 @@ static struct SCSIBusInfo virtio_scsi_scsi_info = {
.complete = virtio_scsi_command_complete,
.cancel = virtio_scsi_request_cancelled,
.change = virtio_scsi_change,
- .hotplug = virtio_scsi_hotplug,
- .hot_unplug = virtio_scsi_hot_unplug,
.parse_cdb = virtio_scsi_parse_cdb,
.get_sg_list = virtio_scsi_get_sg_list,
.save_request = virtio_scsi_save_request,
@@ -853,6 +854,8 @@ static void virtio_scsi_device_realize(DeviceState *dev, Error **errp)
scsi_bus_new(&s->bus, sizeof(s->bus), dev,
&virtio_scsi_scsi_info, vdev->bus_name);
+ /* override default SCSI bus hotplug-handler, with virtio-scsi's one */
+ qbus_set_hotplug_handler(BUS(&s->bus), dev, &error_abort);
if (!dev->hotplugged) {
scsi_bus_legacy_handle_cmdline(&s->bus, &err);
@@ -915,6 +918,7 @@ static void virtio_scsi_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
dc->props = virtio_scsi_properties;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
@@ -923,6 +927,8 @@ static void virtio_scsi_class_init(ObjectClass *klass, void *data)
vdc->set_config = virtio_scsi_set_config;
vdc->get_features = virtio_scsi_get_features;
vdc->reset = virtio_scsi_reset;
+ hc->plug = virtio_scsi_hotplug;
+ hc->unplug = virtio_scsi_hotunplug;
}
static const TypeInfo virtio_scsi_common_info = {
@@ -939,6 +945,10 @@ static const TypeInfo virtio_scsi_info = {
.instance_size = sizeof(VirtIOSCSI),
.instance_init = virtio_scsi_instance_init,
.class_init = virtio_scsi_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_HOTPLUG_HANDLER },
+ { }
+ }
};
static void virtio_register_types(void)
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index 5734d19789..d3a92fbabf 100644
--- a/hw/scsi/vmw_pvscsi.c
+++ b/hw/scsi/vmw_pvscsi.c
@@ -524,17 +524,20 @@ pvscsi_send_msg(PVSCSIState *s, SCSIDevice *dev, uint32_t msg_type)
}
static void
-pvscsi_hotplug(SCSIBus *bus, SCSIDevice *dev)
+pvscsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp)
{
- PVSCSIState *s = container_of(bus, PVSCSIState, bus);
- pvscsi_send_msg(s, dev, PVSCSI_MSG_DEV_ADDED);
+ PVSCSIState *s = PVSCSI(hotplug_dev);
+
+ pvscsi_send_msg(s, SCSI_DEVICE(dev), PVSCSI_MSG_DEV_ADDED);
}
static void
-pvscsi_hot_unplug(SCSIBus *bus, SCSIDevice *dev)
+pvscsi_hot_unplug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp)
{
- PVSCSIState *s = container_of(bus, PVSCSIState, bus);
- pvscsi_send_msg(s, dev, PVSCSI_MSG_DEV_REMOVED);
+ PVSCSIState *s = PVSCSI(hotplug_dev);
+
+ pvscsi_send_msg(s, SCSI_DEVICE(dev), PVSCSI_MSG_DEV_REMOVED);
+ qdev_simple_device_unplug_cb(hotplug_dev, dev, errp);
}
static void
@@ -1057,8 +1060,6 @@ static const struct SCSIBusInfo pvscsi_scsi_info = {
.get_sg_list = pvscsi_get_sg_list,
.complete = pvscsi_command_complete,
.cancel = pvscsi_request_cancelled,
- .hotplug = pvscsi_hotplug,
- .hot_unplug = pvscsi_hot_unplug,
};
static int
@@ -1092,6 +1093,8 @@ pvscsi_init(PCIDevice *pci_dev)
scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(pci_dev),
&pvscsi_scsi_info, NULL);
+ /* override default SCSI bus hotplug-handler, with pvscsi's one */
+ qbus_set_hotplug_handler(BUS(&s->bus), DEVICE(s), &error_abort);
pvscsi_reset_state(s);
return 0;
@@ -1187,6 +1190,7 @@ static void pvscsi_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
k->init = pvscsi_init;
k->exit = pvscsi_uninit;
@@ -1199,6 +1203,8 @@ static void pvscsi_class_init(ObjectClass *klass, void *data)
dc->props = pvscsi_properties;
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
k->config_write = pvscsi_write_config;
+ hc->unplug = pvscsi_hot_unplug;
+ hc->plug = pvscsi_hotplug;
}
static const TypeInfo pvscsi_info = {
@@ -1206,6 +1212,10 @@ static const TypeInfo pvscsi_info = {
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PVSCSIState),
.class_init = pvscsi_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_HOTPLUG_HANDLER },
+ { }
+ }
};
static void
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index da1eba9fbd..986b2d8da8 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -24,10 +24,12 @@ static Property usb_props[] = {
static void usb_bus_class_init(ObjectClass *klass, void *data)
{
BusClass *k = BUS_CLASS(klass);
+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
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;
+ hc->unplug = qdev_simple_device_unplug_cb;
}
static const TypeInfo usb_bus_info = {
@@ -35,6 +37,10 @@ static const TypeInfo usb_bus_info = {
.parent = TYPE_BUS,
.instance_size = sizeof(USBBus),
.class_init = usb_bus_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_HOTPLUG_HANDLER },
+ { }
+ }
};
static int next_usb_bus = 0;
@@ -79,9 +85,9 @@ void usb_bus_new(USBBus *bus, size_t bus_size,
USBBusOps *ops, DeviceState *host)
{
qbus_create_inplace(bus, bus_size, TYPE_USB_BUS, host, NULL);
+ qbus_set_bus_hotplug_handler(BUS(bus), &error_abort);
bus->ops = ops;
bus->busnr = next_usb_bus++;
- bus->qbus.allow_hotplug = 1; /* Yes, we can */
QTAILQ_INIT(&bus->free);
QTAILQ_INIT(&bus->used);
QTAILQ_INSERT_TAIL(&busses, bus, next);
@@ -701,7 +707,6 @@ static void usb_device_class_init(ObjectClass *klass, void *data)
{
DeviceClass *k = DEVICE_CLASS(klass);
k->bus_type = TYPE_USB_BUS;
- k->unplug = qdev_simple_unplug_cb;
k->realize = usb_qdev_realize;
k->unrealize = usb_qdev_unrealize;
k->props = usb_props;
diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index 23e3c45b5f..5b95d5c382 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -1371,8 +1371,16 @@ static void usb_net_realize(USBDevice *dev, Error **errrp)
s->conf.macaddr.a[4],
s->conf.macaddr.a[5]);
usb_desc_set_string(dev, STRING_ETHADDR, s->usbstring_mac);
+}
+
+static void usb_net_instance_init(Object *obj)
+{
+ USBDevice *dev = USB_DEVICE(obj);
+ USBNetState *s = DO_UPCAST(USBNetState, dev, dev);
- add_boot_device_path(s->conf.bootindex, &dev->qdev, "/ethernet@0");
+ device_add_bootindex_property(obj, &s->conf.bootindex,
+ "bootindex", "/ethernet-phy@0",
+ &dev->qdev, NULL);
}
static USBDevice *usb_net_init(USBBus *bus, const char *cmdline)
@@ -1438,6 +1446,7 @@ static const TypeInfo net_info = {
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(USBNetState),
.class_init = usb_net_class_initfn,
+ .instance_init = usb_net_instance_init,
};
static void usb_net_register_types(void)
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
index d37ed02d2e..78ce681671 100644
--- a/hw/usb/dev-smartcard-reader.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -1312,8 +1312,8 @@ static void ccid_realize(USBDevice *dev, Error **errp)
usb_desc_init(dev);
qbus_create_inplace(&s->bus, sizeof(s->bus), TYPE_CCID_BUS, DEVICE(dev),
NULL);
+ qbus_set_hotplug_handler(BUS(&s->bus), DEVICE(dev), &error_abort);
s->intr = usb_ep_get(dev, USB_TOKEN_IN, CCID_INT_IN_EP);
- s->bus.qbus.allow_hotplug = 1;
s->card = NULL;
s->migration_state = MIGRATION_NONE;
s->migration_target_ip = 0;
@@ -1439,6 +1439,7 @@ static void ccid_class_initfn(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
uc->realize = ccid_realize;
uc->product_desc = "QEMU USB CCID";
@@ -1451,6 +1452,7 @@ static void ccid_class_initfn(ObjectClass *klass, void *data)
dc->vmsd = &ccid_vmstate;
dc->props = ccid_properties;
set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
+ hc->unplug = qdev_simple_device_unplug_cb;
}
static const TypeInfo ccid_info = {
@@ -1458,6 +1460,10 @@ static const TypeInfo ccid_info = {
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(USBCCIDState),
.class_init = ccid_class_initfn,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_HOTPLUG_HANDLER },
+ { }
+ }
};
static void ccid_card_class_init(ObjectClass *klass, void *data)
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
index bd7cc53e07..5bfc72ca45 100644
--- a/hw/usb/dev-storage.c
+++ b/hw/usb/dev-storage.c
@@ -17,6 +17,7 @@
#include "monitor/monitor.h"
#include "sysemu/sysemu.h"
#include "sysemu/blockdev.h"
+#include "qapi/visitor.h"
//#define DEBUG_MSD
@@ -59,6 +60,7 @@ typedef struct {
/* usb-storage only */
BlockConf conf;
uint32_t removable;
+ SCSIDevice *scsi_dev;
} MSDState;
struct usb_msd_cbw {
@@ -632,8 +634,8 @@ static void usb_msd_realize_storage(USBDevice *dev, Error **errp)
error_propagate(errp, err);
return;
}
- s->bus.qbus.allow_hotplug = 0;
usb_msd_handle_reset(dev);
+ s->scsi_dev = scsi_dev;
if (bdrv_key_required(bs)) {
if (cur_mon) {
@@ -653,7 +655,6 @@ static void usb_msd_realize_bot(USBDevice *dev, Error **errp)
usb_desc_init(dev);
scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
&usb_msd_scsi_info_bot, NULL);
- s->bus.qbus.allow_hotplug = 0;
usb_msd_handle_reset(dev);
}
@@ -767,12 +768,62 @@ static void usb_msd_class_initfn_storage(ObjectClass *klass, void *data)
usb_msd_class_initfn_common(klass);
}
+static void usb_msd_get_bootindex(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ USBDevice *dev = USB_DEVICE(obj);
+ MSDState *s = DO_UPCAST(MSDState, dev, dev);
+
+ visit_type_int32(v, &s->conf.bootindex, name, errp);
+}
+
+static void usb_msd_set_bootindex(Object *obj, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ USBDevice *dev = USB_DEVICE(obj);
+ MSDState *s = DO_UPCAST(MSDState, dev, dev);
+ int32_t boot_index;
+ Error *local_err = NULL;
+
+ visit_type_int32(v, &boot_index, name, &local_err);
+ if (local_err) {
+ goto out;
+ }
+ /* check whether bootindex is present in fw_boot_order list */
+ check_boot_index(boot_index, &local_err);
+ if (local_err) {
+ goto out;
+ }
+ /* change bootindex to a new one */
+ s->conf.bootindex = boot_index;
+
+ if (s->scsi_dev) {
+ object_property_set_int(OBJECT(s->scsi_dev), boot_index, "bootindex",
+ &error_abort);
+ }
+
+out:
+ if (local_err) {
+ error_propagate(errp, local_err);
+ }
+}
+
+static void usb_msd_instance_init(Object *obj)
+{
+ object_property_add(obj, "bootindex", "int32",
+ usb_msd_get_bootindex,
+ usb_msd_set_bootindex, NULL, NULL, NULL);
+ object_property_set_int(obj, -1, "bootindex", NULL);
+}
+
static void usb_msd_class_initfn_bot(ObjectClass *klass, void *data)
{
USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
uc->realize = usb_msd_realize_bot;
usb_msd_class_initfn_common(klass);
+ dc->hotpluggable = false;
}
static const TypeInfo msd_info = {
@@ -780,6 +831,7 @@ static const TypeInfo msd_info = {
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(MSDState),
.class_init = usb_msd_class_initfn_storage,
+ .instance_init = usb_msd_instance_init,
};
static const TypeInfo bot_info = {
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index 45b74e5307..d2d161bc6e 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -978,10 +978,19 @@ static void usb_host_realize(USBDevice *udev, Error **errp)
qemu_add_exit_notifier(&s->exit);
QTAILQ_INSERT_TAIL(&hostdevs, s, next);
- add_boot_device_path(s->bootindex, &udev->qdev, NULL);
usb_host_auto_check(NULL);
}
+static void usb_host_instance_init(Object *obj)
+{
+ USBDevice *udev = USB_DEVICE(obj);
+ USBHostDevice *s = USB_HOST_DEVICE(udev);
+
+ device_add_bootindex_property(obj, &s->bootindex,
+ "bootindex", NULL,
+ &udev->qdev, NULL);
+}
+
static void usb_host_handle_destroy(USBDevice *udev)
{
USBHostDevice *s = USB_HOST_DEVICE(udev);
@@ -1465,7 +1474,6 @@ static Property usb_host_dev_properties[] = {
DEFINE_PROP_UINT32("productid", USBHostDevice, match.product_id, 0),
DEFINE_PROP_UINT32("isobufs", USBHostDevice, iso_urb_count, 4),
DEFINE_PROP_UINT32("isobsize", USBHostDevice, iso_urb_frames, 32),
- DEFINE_PROP_INT32("bootindex", USBHostDevice, bootindex, -1),
DEFINE_PROP_UINT32("loglevel", USBHostDevice, loglevel,
LIBUSB_LOG_LEVEL_WARNING),
DEFINE_PROP_BIT("pipeline", USBHostDevice, options,
@@ -1498,6 +1506,7 @@ static TypeInfo usb_host_dev_info = {
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(USBHostDevice),
.class_init = usb_host_class_initfn,
+ .instance_init = usb_host_instance_init,
};
static void usb_host_register_types(void)
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index e2c98962a2..9fbd59e5ee 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -1401,7 +1401,6 @@ static void usbredir_realize(USBDevice *udev, Error **errp)
usbredir_chardev_read, usbredir_chardev_event, dev);
qemu_add_vm_change_state_handler(usbredir_vm_state_change, dev);
- add_boot_device_path(dev->bootindex, &udev->qdev, NULL);
}
static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
@@ -2471,7 +2470,6 @@ static Property usbredir_properties[] = {
DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, usbredirparser_warning),
DEFINE_PROP_STRING("filter", USBRedirDevice, filter_str),
- DEFINE_PROP_INT32("bootindex", USBRedirDevice, bootindex, -1),
DEFINE_PROP_END_OF_LIST(),
};
@@ -2496,11 +2494,22 @@ static void usbredir_class_initfn(ObjectClass *klass, void *data)
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
}
+static void usbredir_instance_init(Object *obj)
+{
+ USBDevice *udev = USB_DEVICE(obj);
+ USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
+
+ device_add_bootindex_property(obj, &dev->bootindex,
+ "bootindex", NULL,
+ &udev->qdev, NULL);
+}
+
static const TypeInfo usbredir_dev_info = {
.name = "usb-redir",
.parent = TYPE_USB_DEVICE,
.instance_size = sizeof(USBRedirDevice),
.class_init = usbredir_class_initfn,
+ .instance_init = usbredir_instance_init,
};
static void usbredir_register_types(void)
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 18c6e5b55c..2450c13747 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -89,9 +89,6 @@ typedef struct {
VirtioBusState bus;
} VirtIOMMIOProxy;
-static void virtio_mmio_bus_new(VirtioBusState *bus, size_t bus_size,
- VirtIOMMIOProxy *dev);
-
static uint64_t virtio_mmio_read(void *opaque, hwaddr offset, unsigned size)
{
VirtIOMMIOProxy *proxy = (VirtIOMMIOProxy *)opaque;
@@ -362,7 +359,8 @@ static void virtio_mmio_realizefn(DeviceState *d, Error **errp)
VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
SysBusDevice *sbd = SYS_BUS_DEVICE(d);
- virtio_mmio_bus_new(&proxy->bus, sizeof(proxy->bus), proxy);
+ qbus_create_inplace(&proxy->bus, sizeof(proxy->bus), TYPE_VIRTIO_MMIO_BUS,
+ d, NULL);
sysbus_init_irq(sbd, &proxy->irq);
memory_region_init_io(&proxy->iomem, OBJECT(d), &virtio_mem_ops, proxy,
TYPE_VIRTIO_MMIO, 0x200);
@@ -393,17 +391,6 @@ static const TypeInfo virtio_mmio_info = {
/* virtio-mmio-bus. */
-static void virtio_mmio_bus_new(VirtioBusState *bus, size_t bus_size,
- VirtIOMMIOProxy *dev)
-{
- DeviceState *qdev = DEVICE(dev);
- BusState *qbus;
-
- qbus_create_inplace(bus, bus_size, TYPE_VIRTIO_MMIO_BUS, qdev, NULL);
- qbus = BUS(bus);
- qbus->allow_hotplug = 0;
-}
-
static void virtio_mmio_bus_class_init(ObjectClass *klass, void *data)
{
BusClass *bus_class = BUS_CLASS(klass);
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 390f8244f3..ae7fef96d5 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1115,6 +1115,8 @@ static void virtio_blk_pci_instance_init(Object *obj)
TYPE_VIRTIO_BLK);
object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread",
&error_abort);
+ object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
+ "bootindex", &error_abort);
}
static const TypeInfo virtio_blk_pci_info = {
@@ -1466,6 +1468,8 @@ static void virtio_net_pci_instance_init(Object *obj)
virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
TYPE_VIRTIO_NET);
+ object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
+ "bootindex", &error_abort);
}
static const TypeInfo virtio_net_pci_info = {
@@ -1542,13 +1546,10 @@ static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size,
VirtIOPCIProxy *dev)
{
DeviceState *qdev = DEVICE(dev);
- BusState *qbus;
char virtio_bus_name[] = "virtio-bus";
qbus_create_inplace(bus, bus_size, TYPE_VIRTIO_PCI_BUS, qdev,
virtio_bus_name);
- qbus = BUS(bus);
- qbus->allow_hotplug = 1;
}
static void virtio_pci_bus_class_init(ObjectClass *klass, void *data)