From 0866aca1de15a12547f52ff8563cf7c163e1898e Mon Sep 17 00:00:00 2001 From: Anthony Liguori Date: Fri, 23 Dec 2011 15:34:39 -0600 Subject: [PATCH] qbus: Make child devices links MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Make qbus children show up as link<> properties. There is no stable addressing for qbus children so we use an unstable naming convention. This is okay in QOM though because the composition name is expected to be what's stable. Signed-off-by: Anthony Liguori Signed-off-by: Paolo Bonzini Signed-off-by: Andreas Färber --- hw/acpi_piix4.c | 10 ++++---- hw/i2c.c | 5 ++-- hw/intel-hda.c | 15 +++++++----- hw/lsi53c895a.c | 5 ++-- hw/qdev-monitor.c | 26 +++++++++++++-------- hw/qdev.c | 64 +++++++++++++++++++++++++++++++++++++++++++--------- hw/qdev.h | 10 ++++++-- hw/s390-virtio-bus.c | 25 ++++++++++---------- hw/scsi-bus.c | 13 +++++++---- hw/spapr_pci.c | 7 +++--- hw/spapr_vio.c | 25 ++++++++++---------- hw/spapr_vty.c | 6 +++-- hw/ssi.c | 14 +++++++----- hw/virtio-scsi.c | 6 ++--- qom/object.c | 11 +++++++-- 15 files changed, 159 insertions(+), 83 deletions(-) diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c index 0345490..a11c8e7 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 319b249..296bece 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 e343096..c11fd30 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 f022a02..2fe141d 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 691b864..17452c8 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 dc46e7b..fc79b24 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 736271e..e39f82e 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 2aec756..4d49b96 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 276c794..dbfccdc 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 25b400a..97d417a 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 b7611ff..c8271c6 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 c9674f3..f340b83 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 8db99c2..e5f14a0 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 5e39ce9..e1a767e 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 d5c6ff7..27cc651 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; + } + + if (prop->release) { + prop->release(obj, name, prop->opaque); + } - prop->release(obj, prop->name, prop->opaque); + QTAILQ_REMOVE(&obj->properties, prop, node); g_free(prop->name); g_free(prop->type); -- 2.7.4