diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index 0345490ee0..a11c8e7ae0 100644 --- a/hw/acpi_piix4.c +++ b/hw/acpi_piix4.c @@ -284,7 +284,7 @@ static const VMStateDescription vmstate_acpi = { static void acpi_piix_eject_slot(PIIX4PMState *s, unsigned slots) { - DeviceState *qdev, *next; + BusChild *kid, *next; BusState *bus = qdev_get_parent_bus(&s->dev.qdev); int slot = ffs(slots) - 1; bool slot_free = true; @@ -292,7 +292,8 @@ static void acpi_piix_eject_slot(PIIX4PMState *s, unsigned slots) /* Mark request as complete */ s->pci0_status.down &= ~(1U << slot); - QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) { + QTAILQ_FOREACH_SAFE(kid, &bus->children, sibling, next) { + DeviceState *qdev = kid->child; PCIDevice *dev = PCI_DEVICE(qdev); PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev); if (PCI_SLOT(dev->devfn) == slot) { @@ -313,7 +314,7 @@ static void piix4_update_hotplug(PIIX4PMState *s) { PCIDevice *dev = &s->dev; BusState *bus = qdev_get_parent_bus(&dev->qdev); - DeviceState *qdev, *next; + BusChild *kid, *next; /* Execute any pending removes during reset */ while (s->pci0_status.down) { @@ -323,7 +324,8 @@ static void piix4_update_hotplug(PIIX4PMState *s) s->pci0_hotplug_enable = ~0; s->pci0_slot_device_present = 0; - QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) { + QTAILQ_FOREACH_SAFE(kid, &bus->children, sibling, next) { + DeviceState *qdev = kid->child; PCIDevice *pdev = PCI_DEVICE(qdev); PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pdev); int slot = PCI_SLOT(pdev->devfn); diff --git a/hw/i2c.c b/hw/i2c.c index 319b249da3..296bece119 100644 --- a/hw/i2c.c +++ b/hw/i2c.c @@ -86,11 +86,12 @@ int i2c_bus_busy(i2c_bus *bus) /* TODO: Make this handle multiple masters. */ int i2c_start_transfer(i2c_bus *bus, uint8_t address, int recv) { - DeviceState *qdev; + BusChild *kid; I2CSlave *slave = NULL; I2CSlaveClass *sc; - QTAILQ_FOREACH(qdev, &bus->qbus.children, sibling) { + QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) { + DeviceState *qdev = kid->child; I2CSlave *candidate = I2C_SLAVE_FROM_QDEV(qdev); if (candidate->address == address) { slave = candidate; diff --git a/hw/intel-hda.c b/hw/intel-hda.c index e343096534..c11fd30cab 100644 --- a/hw/intel-hda.c +++ b/hw/intel-hda.c @@ -78,10 +78,11 @@ static int hda_codec_dev_exit(DeviceState *qdev) HDACodecDevice *hda_codec_find(HDACodecBus *bus, uint32_t cad) { - DeviceState *qdev; + BusChild *kid; HDACodecDevice *cdev; - QTAILQ_FOREACH(qdev, &bus->qbus.children, sibling) { + QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) { + DeviceState *qdev = kid->child; cdev = DO_UPCAST(HDACodecDevice, qdev, qdev); if (cdev->cad == cad) { return cdev; @@ -483,10 +484,11 @@ static void intel_hda_parse_bdl(IntelHDAState *d, IntelHDAStream *st) static void intel_hda_notify_codecs(IntelHDAState *d, uint32_t stream, bool running, bool output) { - DeviceState *qdev; + BusChild *kid; HDACodecDevice *cdev; - QTAILQ_FOREACH(qdev, &d->codecs.qbus.children, sibling) { + QTAILQ_FOREACH(kid, &d->codecs.qbus.children, sibling) { + DeviceState *qdev = kid->child; HDACodecDeviceClass *cdc; cdev = DO_UPCAST(HDACodecDevice, qdev, qdev); @@ -1105,15 +1107,16 @@ static const MemoryRegionOps intel_hda_mmio_ops = { static void intel_hda_reset(DeviceState *dev) { + BusChild *kid; IntelHDAState *d = DO_UPCAST(IntelHDAState, pci.qdev, dev); - DeviceState *qdev; HDACodecDevice *cdev; intel_hda_regs_reset(d); d->wall_base_ns = qemu_get_clock_ns(vm_clock); /* reset codecs */ - QTAILQ_FOREACH(qdev, &d->codecs.qbus.children, sibling) { + QTAILQ_FOREACH(kid, &d->codecs.qbus.children, sibling) { + DeviceState *qdev = kid->child; cdev = DO_UPCAST(HDACodecDevice, qdev, qdev); device_reset(DEVICE(cdev)); d->state_sts |= (1 << cdev->cad); diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index f022a02447..2fe141d24e 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -1677,9 +1677,10 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val) } if (val & LSI_SCNTL1_RST) { if (!(s->sstat0 & LSI_SSTAT0_RST)) { - DeviceState *dev; + BusChild *kid; - QTAILQ_FOREACH(dev, &s->bus.qbus.children, sibling) { + QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) { + DeviceState *dev = kid->child; device_reset(dev); } s->sstat0 |= LSI_SSTAT0_RST; diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c index 691b864c54..17452c8c01 100644 --- a/hw/qdev-monitor.c +++ b/hw/qdev-monitor.c @@ -205,11 +205,12 @@ static void qbus_list_bus(DeviceState *dev) static void qbus_list_dev(BusState *bus) { - DeviceState *dev; + BusChild *kid; const char *sep = " "; error_printf("devices at \"%s\":", bus->name); - QTAILQ_FOREACH(dev, &bus->children, sibling) { + QTAILQ_FOREACH(kid, &bus->children, sibling) { + DeviceState *dev = kid->child; error_printf("%s\"%s\"", sep, object_get_typename(OBJECT(dev))); if (dev->id) error_printf("/\"%s\"", dev->id); @@ -232,7 +233,7 @@ static BusState *qbus_find_bus(DeviceState *dev, char *elem) static DeviceState *qbus_find_dev(BusState *bus, char *elem) { - DeviceState *dev; + BusChild *kid; /* * try to match in order: @@ -240,17 +241,20 @@ static DeviceState *qbus_find_dev(BusState *bus, char *elem) * (2) driver name * (3) driver alias, if present */ - QTAILQ_FOREACH(dev, &bus->children, sibling) { + QTAILQ_FOREACH(kid, &bus->children, sibling) { + DeviceState *dev = kid->child; if (dev->id && strcmp(dev->id, elem) == 0) { return dev; } } - QTAILQ_FOREACH(dev, &bus->children, sibling) { + QTAILQ_FOREACH(kid, &bus->children, sibling) { + DeviceState *dev = kid->child; if (strcmp(object_get_typename(OBJECT(dev)), elem) == 0) { return dev; } } - QTAILQ_FOREACH(dev, &bus->children, sibling) { + QTAILQ_FOREACH(kid, &bus->children, sibling) { + DeviceState *dev = kid->child; DeviceClass *dc = DEVICE_GET_CLASS(dev); if (qdev_class_has_alias(dc) && @@ -264,7 +268,7 @@ static DeviceState *qbus_find_dev(BusState *bus, char *elem) static BusState *qbus_find_recursive(BusState *bus, const char *name, const char *bus_typename) { - DeviceState *dev; + BusChild *kid; BusState *child, *ret; int match = 1; @@ -279,7 +283,8 @@ static BusState *qbus_find_recursive(BusState *bus, const char *name, return bus; } - QTAILQ_FOREACH(dev, &bus->children, sibling) { + QTAILQ_FOREACH(kid, &bus->children, sibling) { + DeviceState *dev = kid->child; QLIST_FOREACH(child, &dev->child_bus, sibling) { ret = qbus_find_recursive(child, name, bus_typename); if (ret) { @@ -533,12 +538,13 @@ static void qdev_print(Monitor *mon, DeviceState *dev, int indent) static void qbus_print(Monitor *mon, BusState *bus, int indent) { - struct DeviceState *dev; + BusChild *kid; qdev_printf("bus: %s\n", bus->name); indent += 2; qdev_printf("type %s\n", object_get_typename(OBJECT(bus))); - QTAILQ_FOREACH(dev, &bus->children, sibling) { + QTAILQ_FOREACH(kid, &bus->children, sibling) { + DeviceState *dev = kid->child; qdev_print(mon, dev, indent); } } diff --git a/hw/qdev.c b/hw/qdev.c index dc46e7bd10..fc79b24103 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -60,14 +60,48 @@ bool qdev_exists(const char *name) static void qdev_property_add_legacy(DeviceState *dev, Property *prop, Error **errp); -void qdev_set_parent_bus(DeviceState *dev, BusState *bus) +static void bus_remove_child(BusState *bus, DeviceState *child) { + BusChild *kid; + + QTAILQ_FOREACH(kid, &bus->children, sibling) { + if (kid->child == child) { + char name[32]; + + snprintf(name, sizeof(name), "child[%d]", kid->index); + QTAILQ_REMOVE(&bus->children, kid, sibling); + object_property_del(OBJECT(bus), name, NULL); + g_free(kid); + return; + } + } +} + +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; + + QTAILQ_INSERT_HEAD(&bus->children, kid, sibling); + + snprintf(name, sizeof(name), "child[%d]", kid->index); + object_property_add_link(OBJECT(bus), name, + object_get_typename(OBJECT(child)), + (Object **)&kid->child, + NULL); +} + +void qdev_set_parent_bus(DeviceState *dev, BusState *bus) +{ dev->parent_bus = bus; - QTAILQ_INSERT_HEAD(&bus->children, dev, sibling); + bus_add_child(bus, dev); } /* Create a new device. This only initializes the device state structure @@ -310,7 +344,7 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char *name) int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn, qbus_walkerfn *busfn, void *opaque) { - DeviceState *dev; + BusChild *kid; int err; if (busfn) { @@ -320,8 +354,8 @@ int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn, } } - QTAILQ_FOREACH(dev, &bus->children, sibling) { - err = qdev_walk_children(dev, devfn, busfn, opaque); + QTAILQ_FOREACH(kid, &bus->children, sibling) { + err = qdev_walk_children(kid->child, devfn, busfn, opaque); if (err < 0) { return err; } @@ -355,12 +389,17 @@ int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn, DeviceState *qdev_find_recursive(BusState *bus, const char *id) { - DeviceState *dev, *ret; + BusChild *kid; + DeviceState *ret; BusState *child; - QTAILQ_FOREACH(dev, &bus->children, sibling) { - if (dev->id && strcmp(dev->id, id) == 0) + QTAILQ_FOREACH(kid, &bus->children, sibling) { + DeviceState *dev = kid->child; + + if (dev->id && strcmp(dev->id, id) == 0) { return dev; + } + QLIST_FOREACH(child, &dev->child_bus, sibling) { ret = qdev_find_recursive(child, id); if (ret) { @@ -431,9 +470,10 @@ BusState *qbus_create(const char *typename, DeviceState *parent, const char *nam void qbus_free(BusState *bus) { - DeviceState *dev; + BusChild *kid; - while ((dev = QTAILQ_FIRST(&bus->children)) != NULL) { + while ((kid = QTAILQ_FIRST(&bus->children)) != NULL) { + DeviceState *dev = kid->child; qdev_free(dev); } if (bus->parent) { @@ -684,7 +724,9 @@ static void device_finalize(Object *obj) qemu_opts_del(dev->opts); } } - QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling); + if (dev->parent_bus) { + bus_remove_child(dev->parent_bus, dev); + } } static void device_class_base_init(ObjectClass *class, void *data) diff --git a/hw/qdev.h b/hw/qdev.h index 736271ecef..e39f82e029 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -74,7 +74,6 @@ struct DeviceState { qemu_irq *gpio_in; QLIST_HEAD(, BusState) child_bus; int num_child_bus; - QTAILQ_ENTRY(DeviceState) sibling; int instance_id_alias; int alias_required_for_version; }; @@ -100,6 +99,12 @@ struct BusClass { int (*reset)(BusState *bus); }; +typedef struct BusChild { + DeviceState *child; + int index; + QTAILQ_ENTRY(BusChild) sibling; +} BusChild; + /** * BusState: * @qom_allocated: Indicates whether the object was allocated by QOM. @@ -113,7 +118,8 @@ struct BusState { int allow_hotplug; bool qom_allocated; bool glib_allocated; - QTAILQ_HEAD(ChildrenHead, DeviceState) children; + int max_index; + QTAILQ_HEAD(ChildrenHead, BusChild) children; QLIST_ENTRY(BusState) sibling; }; diff --git a/hw/s390-virtio-bus.c b/hw/s390-virtio-bus.c index 2aec756da1..4d49b96f94 100644 --- a/hw/s390-virtio-bus.c +++ b/hw/s390-virtio-bus.c @@ -315,20 +315,20 @@ VirtIOS390Device *s390_virtio_bus_find_vring(VirtIOS390Bus *bus, ram_addr_t mem, int *vq_num) { - VirtIOS390Device *_dev; - DeviceState *dev; + BusChild *kid; int i; - QTAILQ_FOREACH(dev, &bus->bus.children, sibling) { - _dev = (VirtIOS390Device *)dev; + QTAILQ_FOREACH(kid, &bus->bus.children, sibling) { + VirtIOS390Device *dev = (VirtIOS390Device *)kid->child; + for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) { - if (!virtio_queue_get_addr(_dev->vdev, i)) + if (!virtio_queue_get_addr(dev->vdev, i)) break; - if (virtio_queue_get_addr(_dev->vdev, i) == mem) { + if (virtio_queue_get_addr(dev->vdev, i) == mem) { if (vq_num) { *vq_num = i; } - return _dev; + return dev; } } } @@ -339,13 +339,12 @@ VirtIOS390Device *s390_virtio_bus_find_vring(VirtIOS390Bus *bus, /* Find a device by device descriptor location */ VirtIOS390Device *s390_virtio_bus_find_mem(VirtIOS390Bus *bus, ram_addr_t mem) { - VirtIOS390Device *_dev; - DeviceState *dev; + BusChild *kid; - QTAILQ_FOREACH(dev, &bus->bus.children, sibling) { - _dev = (VirtIOS390Device *)dev; - if (_dev->dev_offs == mem) { - return _dev; + QTAILQ_FOREACH(kid, &bus->bus.children, sibling) { + VirtIOS390Device *dev = (VirtIOS390Device *)kid->child; + if (dev->dev_offs == mem) { + return dev; } } diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 276c794f47..dbfccdc24a 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -315,7 +315,7 @@ static void store_lun(uint8_t *outbuf, int lun) static bool scsi_target_emulate_report_luns(SCSITargetReq *r) { - DeviceState *qdev; + BusChild *kid; int i, len, n; int channel, id; bool found_lun0; @@ -330,7 +330,8 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r) id = r->req.dev->id; found_lun0 = false; n = 0; - QTAILQ_FOREACH(qdev, &r->req.bus->qbus.children, sibling) { + QTAILQ_FOREACH(kid, &r->req.bus->qbus.children, sibling) { + DeviceState *qdev = kid->child; SCSIDevice *dev = SCSI_DEVICE(qdev); if (dev->channel == channel && dev->id == id) { @@ -352,7 +353,8 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r) memset(r->buf, 0, len); stl_be_p(&r->buf, n); i = found_lun0 ? 8 : 16; - QTAILQ_FOREACH(qdev, &r->req.bus->qbus.children, sibling) { + QTAILQ_FOREACH(kid, &r->req.bus->qbus.children, sibling) { + DeviceState *qdev = kid->child; SCSIDevice *dev = SCSI_DEVICE(qdev); if (dev->channel == channel && dev->id == id) { @@ -1487,10 +1489,11 @@ static char *scsibus_get_fw_dev_path(DeviceState *dev) SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun) { - DeviceState *qdev; + BusChild *kid; SCSIDevice *target_dev = NULL; - QTAILQ_FOREACH_REVERSE(qdev, &bus->qbus.children, ChildrenHead, sibling) { + QTAILQ_FOREACH_REVERSE(kid, &bus->qbus.children, ChildrenHead, sibling) { + DeviceState *qdev = kid->child; SCSIDevice *dev = SCSI_DEVICE(qdev); if (dev->channel == channel && dev->id == id) { diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c index 25b400aa47..97d417a997 100644 --- a/hw/spapr_pci.c +++ b/hw/spapr_pci.c @@ -35,17 +35,18 @@ static PCIDevice *find_dev(sPAPREnvironment *spapr, uint64_t buid, uint32_t config_addr) { - DeviceState *qdev; int devfn = (config_addr >> 8) & 0xFF; sPAPRPHBState *phb; QLIST_FOREACH(phb, &spapr->phbs, list) { + BusChild *kid; + if (phb->buid != buid) { continue; } - QTAILQ_FOREACH(qdev, &phb->host_state.bus->qbus.children, sibling) { - PCIDevice *dev = (PCIDevice *)qdev; + QTAILQ_FOREACH(kid, &phb->host_state.bus->qbus.children, sibling) { + PCIDevice *dev = (PCIDevice *)kid->child; if (dev->devfn == devfn) { return dev; } diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c index b7611ff865..c8271c626c 100644 --- a/hw/spapr_vio.c +++ b/hw/spapr_vio.c @@ -62,11 +62,11 @@ static const TypeInfo spapr_vio_bus_info = { VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg) { - DeviceState *qdev; + BusChild *kid; VIOsPAPRDevice *dev = NULL; - QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) { - dev = (VIOsPAPRDevice *)qdev; + QTAILQ_FOREACH(kid, &bus->bus.children, sibling) { + dev = (VIOsPAPRDevice *)kid->child; if (dev->reg == reg) { return dev; } @@ -606,7 +606,7 @@ static void rtas_quiesce(sPAPREnvironment *spapr, uint32_t token, uint32_t nret, target_ulong rets) { VIOsPAPRBus *bus = spapr->vio_bus; - DeviceState *qdev; + BusChild *kid; VIOsPAPRDevice *dev = NULL; if (nargs != 0) { @@ -614,8 +614,8 @@ static void rtas_quiesce(sPAPREnvironment *spapr, uint32_t token, return; } - QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) { - dev = (VIOsPAPRDevice *)qdev; + QTAILQ_FOREACH(kid, &bus->bus.children, sibling) { + dev = (VIOsPAPRDevice *)kid->child; spapr_vio_quiesce_one(dev); } @@ -625,7 +625,7 @@ static void rtas_quiesce(sPAPREnvironment *spapr, uint32_t token, static VIOsPAPRDevice *reg_conflict(VIOsPAPRDevice *dev) { VIOsPAPRBus *bus = DO_UPCAST(VIOsPAPRBus, bus, dev->qdev.parent_bus); - DeviceState *qdev; + BusChild *kid; VIOsPAPRDevice *other; /* @@ -633,8 +633,8 @@ static VIOsPAPRDevice *reg_conflict(VIOsPAPRDevice *dev) * using the requested address. We have to open code this because * the given dev might already be in the list. */ - QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) { - other = DO_UPCAST(VIOsPAPRDevice, qdev, qdev); + QTAILQ_FOREACH(kid, &bus->bus.children, sibling) { + other = DO_UPCAST(VIOsPAPRDevice, qdev, kid->child); if (other != dev && other->reg == dev->reg) { return other; @@ -840,19 +840,20 @@ static int compare_reg(const void *p1, const void *p2) int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt) { DeviceState *qdev, **qdevs; + BusChild *kid; int i, num, ret = 0; /* Count qdevs on the bus list */ num = 0; - QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) { + QTAILQ_FOREACH(kid, &bus->bus.children, sibling) { num++; } /* Copy out into an array of pointers */ qdevs = g_malloc(sizeof(qdev) * num); num = 0; - QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) { - qdevs[num++] = qdev; + QTAILQ_FOREACH(kid, &bus->bus.children, sibling) { + qdevs[num++] = kid->child; } /* Sort the array */ diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c index c9674f36a6..f340b83237 100644 --- a/hw/spapr_vty.c +++ b/hw/spapr_vty.c @@ -160,7 +160,7 @@ static TypeInfo spapr_vty_info = { VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus) { VIOsPAPRDevice *sdev, *selected; - DeviceState *iter; + BusChild *kid; /* * To avoid the console bouncing around we want one VTY to be @@ -169,7 +169,9 @@ VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus) */ selected = NULL; - QTAILQ_FOREACH(iter, &bus->bus.children, sibling) { + QTAILQ_FOREACH(kid, &bus->bus.children, sibling) { + DeviceState *iter = kid->child; + /* Only look at VTY devices */ if (!object_dynamic_cast(OBJECT(iter), "spapr-vty")) { continue; diff --git a/hw/ssi.c b/hw/ssi.c index 8db99c29e4..e5f14a0cef 100644 --- a/hw/ssi.c +++ b/hw/ssi.c @@ -30,10 +30,11 @@ static int ssi_slave_init(DeviceState *dev) SSISlave *s = SSI_SLAVE(dev); SSISlaveClass *ssc = SSI_SLAVE_GET_CLASS(s); SSIBus *bus; + BusChild *kid; bus = FROM_QBUS(SSIBus, qdev_get_parent_bus(dev)); - if (QTAILQ_FIRST(&bus->qbus.children) != dev - || QTAILQ_NEXT(dev, sibling) != NULL) { + kid = QTAILQ_FIRST(&bus->qbus.children); + if (kid->child != dev || QTAILQ_NEXT(kid, sibling) != NULL) { hw_error("Too many devices on SSI bus"); } @@ -72,14 +73,15 @@ SSIBus *ssi_create_bus(DeviceState *parent, const char *name) uint32_t ssi_transfer(SSIBus *bus, uint32_t val) { - DeviceState *dev; + BusChild *kid; SSISlave *slave; SSISlaveClass *ssc; - dev = QTAILQ_FIRST(&bus->qbus.children); - if (!dev) { + + kid = QTAILQ_FIRST(&bus->qbus.children); + if (!kid) { return 0; } - slave = SSI_SLAVE(dev); + slave = SSI_SLAVE(kid->child); ssc = SSI_SLAVE_GET_CLASS(slave); return ssc->transfer(slave, val); } diff --git a/hw/virtio-scsi.c b/hw/virtio-scsi.c index 5e39ce93c4..e1a767ea78 100644 --- a/hw/virtio-scsi.c +++ b/hw/virtio-scsi.c @@ -275,7 +275,7 @@ static void virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req) { SCSIDevice *d = virtio_scsi_device_find(s, req->req.tmf->lun); SCSIRequest *r, *next; - DeviceState *qdev; + BusChild *kid; int target; /* Here VIRTIO_SCSI_S_OK means "FUNCTION COMPLETE". */ @@ -346,8 +346,8 @@ static void virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req) case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET: target = req->req.tmf->lun[1]; s->resetting++; - QTAILQ_FOREACH(qdev, &s->bus.qbus.children, sibling) { - d = DO_UPCAST(SCSIDevice, qdev, qdev); + QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) { + d = DO_UPCAST(SCSIDevice, qdev, kid->child); if (d->channel == 0 && d->id == target) { qdev_reset_all(&d->qdev); } diff --git a/qom/object.c b/qom/object.c index d5c6ff7471..27cc651a91 100644 --- a/qom/object.c +++ b/qom/object.c @@ -689,9 +689,16 @@ void object_property_del(Object *obj, const char *name, Error **errp) { ObjectProperty *prop = object_property_find(obj, name); - QTAILQ_REMOVE(&obj->properties, prop, node); + if (prop == NULL) { + error_set(errp, QERR_PROPERTY_NOT_FOUND, "", name); + return; + } - prop->release(obj, prop->name, prop->opaque); + if (prop->release) { + prop->release(obj, name, prop->opaque); + } + + QTAILQ_REMOVE(&obj->properties, prop, node); g_free(prop->name); g_free(prop->type);