qbus: Make child devices links

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 <aliguori@us.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
This commit is contained in:
Anthony Liguori 2011-12-23 15:34:39 -06:00 committed by Andreas Färber
parent f968fc6892
commit 0866aca1de
15 changed files with 159 additions and 83 deletions

View File

@ -284,7 +284,7 @@ static const VMStateDescription vmstate_acpi = {
static void acpi_piix_eject_slot(PIIX4PMState *s, unsigned slots) 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); BusState *bus = qdev_get_parent_bus(&s->dev.qdev);
int slot = ffs(slots) - 1; int slot = ffs(slots) - 1;
bool slot_free = true; bool slot_free = true;
@ -292,7 +292,8 @@ static void acpi_piix_eject_slot(PIIX4PMState *s, unsigned slots)
/* Mark request as complete */ /* Mark request as complete */
s->pci0_status.down &= ~(1U << slot); 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); PCIDevice *dev = PCI_DEVICE(qdev);
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev); PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
if (PCI_SLOT(dev->devfn) == slot) { if (PCI_SLOT(dev->devfn) == slot) {
@ -313,7 +314,7 @@ static void piix4_update_hotplug(PIIX4PMState *s)
{ {
PCIDevice *dev = &s->dev; PCIDevice *dev = &s->dev;
BusState *bus = qdev_get_parent_bus(&dev->qdev); BusState *bus = qdev_get_parent_bus(&dev->qdev);
DeviceState *qdev, *next; BusChild *kid, *next;
/* Execute any pending removes during reset */ /* Execute any pending removes during reset */
while (s->pci0_status.down) { while (s->pci0_status.down) {
@ -323,7 +324,8 @@ static void piix4_update_hotplug(PIIX4PMState *s)
s->pci0_hotplug_enable = ~0; s->pci0_hotplug_enable = ~0;
s->pci0_slot_device_present = 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); PCIDevice *pdev = PCI_DEVICE(qdev);
PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pdev); PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pdev);
int slot = PCI_SLOT(pdev->devfn); int slot = PCI_SLOT(pdev->devfn);

View File

@ -86,11 +86,12 @@ int i2c_bus_busy(i2c_bus *bus)
/* TODO: Make this handle multiple masters. */ /* TODO: Make this handle multiple masters. */
int i2c_start_transfer(i2c_bus *bus, uint8_t address, int recv) int i2c_start_transfer(i2c_bus *bus, uint8_t address, int recv)
{ {
DeviceState *qdev; BusChild *kid;
I2CSlave *slave = NULL; I2CSlave *slave = NULL;
I2CSlaveClass *sc; 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); I2CSlave *candidate = I2C_SLAVE_FROM_QDEV(qdev);
if (candidate->address == address) { if (candidate->address == address) {
slave = candidate; slave = candidate;

View File

@ -78,10 +78,11 @@ static int hda_codec_dev_exit(DeviceState *qdev)
HDACodecDevice *hda_codec_find(HDACodecBus *bus, uint32_t cad) HDACodecDevice *hda_codec_find(HDACodecBus *bus, uint32_t cad)
{ {
DeviceState *qdev; BusChild *kid;
HDACodecDevice *cdev; 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); cdev = DO_UPCAST(HDACodecDevice, qdev, qdev);
if (cdev->cad == cad) { if (cdev->cad == cad) {
return cdev; 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) static void intel_hda_notify_codecs(IntelHDAState *d, uint32_t stream, bool running, bool output)
{ {
DeviceState *qdev; BusChild *kid;
HDACodecDevice *cdev; HDACodecDevice *cdev;
QTAILQ_FOREACH(qdev, &d->codecs.qbus.children, sibling) { QTAILQ_FOREACH(kid, &d->codecs.qbus.children, sibling) {
DeviceState *qdev = kid->child;
HDACodecDeviceClass *cdc; HDACodecDeviceClass *cdc;
cdev = DO_UPCAST(HDACodecDevice, qdev, qdev); cdev = DO_UPCAST(HDACodecDevice, qdev, qdev);
@ -1105,15 +1107,16 @@ static const MemoryRegionOps intel_hda_mmio_ops = {
static void intel_hda_reset(DeviceState *dev) static void intel_hda_reset(DeviceState *dev)
{ {
BusChild *kid;
IntelHDAState *d = DO_UPCAST(IntelHDAState, pci.qdev, dev); IntelHDAState *d = DO_UPCAST(IntelHDAState, pci.qdev, dev);
DeviceState *qdev;
HDACodecDevice *cdev; HDACodecDevice *cdev;
intel_hda_regs_reset(d); intel_hda_regs_reset(d);
d->wall_base_ns = qemu_get_clock_ns(vm_clock); d->wall_base_ns = qemu_get_clock_ns(vm_clock);
/* reset codecs */ /* 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); cdev = DO_UPCAST(HDACodecDevice, qdev, qdev);
device_reset(DEVICE(cdev)); device_reset(DEVICE(cdev));
d->state_sts |= (1 << cdev->cad); d->state_sts |= (1 << cdev->cad);

View File

@ -1677,9 +1677,10 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)
} }
if (val & LSI_SCNTL1_RST) { if (val & LSI_SCNTL1_RST) {
if (!(s->sstat0 & LSI_SSTAT0_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); device_reset(dev);
} }
s->sstat0 |= LSI_SSTAT0_RST; s->sstat0 |= LSI_SSTAT0_RST;

View File

@ -205,11 +205,12 @@ static void qbus_list_bus(DeviceState *dev)
static void qbus_list_dev(BusState *bus) static void qbus_list_dev(BusState *bus)
{ {
DeviceState *dev; BusChild *kid;
const char *sep = " "; const char *sep = " ";
error_printf("devices at \"%s\":", bus->name); 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))); error_printf("%s\"%s\"", sep, object_get_typename(OBJECT(dev)));
if (dev->id) if (dev->id)
error_printf("/\"%s\"", 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) static DeviceState *qbus_find_dev(BusState *bus, char *elem)
{ {
DeviceState *dev; BusChild *kid;
/* /*
* try to match in order: * try to match in order:
@ -240,17 +241,20 @@ static DeviceState *qbus_find_dev(BusState *bus, char *elem)
* (2) driver name * (2) driver name
* (3) driver alias, if present * (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) { if (dev->id && strcmp(dev->id, elem) == 0) {
return dev; 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) { if (strcmp(object_get_typename(OBJECT(dev)), elem) == 0) {
return dev; return dev;
} }
} }
QTAILQ_FOREACH(dev, &bus->children, sibling) { QTAILQ_FOREACH(kid, &bus->children, sibling) {
DeviceState *dev = kid->child;
DeviceClass *dc = DEVICE_GET_CLASS(dev); DeviceClass *dc = DEVICE_GET_CLASS(dev);
if (qdev_class_has_alias(dc) && 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, static BusState *qbus_find_recursive(BusState *bus, const char *name,
const char *bus_typename) const char *bus_typename)
{ {
DeviceState *dev; BusChild *kid;
BusState *child, *ret; BusState *child, *ret;
int match = 1; int match = 1;
@ -279,7 +283,8 @@ static BusState *qbus_find_recursive(BusState *bus, const char *name,
return bus; 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) { QLIST_FOREACH(child, &dev->child_bus, sibling) {
ret = qbus_find_recursive(child, name, bus_typename); ret = qbus_find_recursive(child, name, bus_typename);
if (ret) { 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) static void qbus_print(Monitor *mon, BusState *bus, int indent)
{ {
struct DeviceState *dev; BusChild *kid;
qdev_printf("bus: %s\n", bus->name); qdev_printf("bus: %s\n", bus->name);
indent += 2; indent += 2;
qdev_printf("type %s\n", object_get_typename(OBJECT(bus))); 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); qdev_print(mon, dev, indent);
} }
} }

View File

@ -60,14 +60,48 @@ bool qdev_exists(const char *name)
static void qdev_property_add_legacy(DeviceState *dev, Property *prop, static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
Error **errp); 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) { if (qdev_hotplug) {
assert(bus->allow_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; 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 /* 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, int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
qbus_walkerfn *busfn, void *opaque) qbus_walkerfn *busfn, void *opaque)
{ {
DeviceState *dev; BusChild *kid;
int err; int err;
if (busfn) { if (busfn) {
@ -320,8 +354,8 @@ int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
} }
} }
QTAILQ_FOREACH(dev, &bus->children, sibling) { QTAILQ_FOREACH(kid, &bus->children, sibling) {
err = qdev_walk_children(dev, devfn, busfn, opaque); err = qdev_walk_children(kid->child, devfn, busfn, opaque);
if (err < 0) { if (err < 0) {
return err; 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 *qdev_find_recursive(BusState *bus, const char *id)
{ {
DeviceState *dev, *ret; BusChild *kid;
DeviceState *ret;
BusState *child; BusState *child;
QTAILQ_FOREACH(dev, &bus->children, sibling) { QTAILQ_FOREACH(kid, &bus->children, sibling) {
if (dev->id && strcmp(dev->id, id) == 0) DeviceState *dev = kid->child;
if (dev->id && strcmp(dev->id, id) == 0) {
return dev; return dev;
}
QLIST_FOREACH(child, &dev->child_bus, sibling) { QLIST_FOREACH(child, &dev->child_bus, sibling) {
ret = qdev_find_recursive(child, id); ret = qdev_find_recursive(child, id);
if (ret) { if (ret) {
@ -431,9 +470,10 @@ BusState *qbus_create(const char *typename, DeviceState *parent, const char *nam
void qbus_free(BusState *bus) 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); qdev_free(dev);
} }
if (bus->parent) { if (bus->parent) {
@ -684,7 +724,9 @@ static void device_finalize(Object *obj)
qemu_opts_del(dev->opts); 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) static void device_class_base_init(ObjectClass *class, void *data)

View File

@ -74,7 +74,6 @@ struct DeviceState {
qemu_irq *gpio_in; qemu_irq *gpio_in;
QLIST_HEAD(, BusState) child_bus; QLIST_HEAD(, BusState) child_bus;
int num_child_bus; int num_child_bus;
QTAILQ_ENTRY(DeviceState) sibling;
int instance_id_alias; int instance_id_alias;
int alias_required_for_version; int alias_required_for_version;
}; };
@ -100,6 +99,12 @@ struct BusClass {
int (*reset)(BusState *bus); int (*reset)(BusState *bus);
}; };
typedef struct BusChild {
DeviceState *child;
int index;
QTAILQ_ENTRY(BusChild) sibling;
} BusChild;
/** /**
* BusState: * BusState:
* @qom_allocated: Indicates whether the object was allocated by QOM. * @qom_allocated: Indicates whether the object was allocated by QOM.
@ -113,7 +118,8 @@ struct BusState {
int allow_hotplug; int allow_hotplug;
bool qom_allocated; bool qom_allocated;
bool glib_allocated; bool glib_allocated;
QTAILQ_HEAD(ChildrenHead, DeviceState) children; int max_index;
QTAILQ_HEAD(ChildrenHead, BusChild) children;
QLIST_ENTRY(BusState) sibling; QLIST_ENTRY(BusState) sibling;
}; };

View File

@ -315,20 +315,20 @@ VirtIOS390Device *s390_virtio_bus_find_vring(VirtIOS390Bus *bus,
ram_addr_t mem, ram_addr_t mem,
int *vq_num) int *vq_num)
{ {
VirtIOS390Device *_dev; BusChild *kid;
DeviceState *dev;
int i; int i;
QTAILQ_FOREACH(dev, &bus->bus.children, sibling) { QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
_dev = (VirtIOS390Device *)dev; VirtIOS390Device *dev = (VirtIOS390Device *)kid->child;
for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) { 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; break;
if (virtio_queue_get_addr(_dev->vdev, i) == mem) { if (virtio_queue_get_addr(dev->vdev, i) == mem) {
if (vq_num) { if (vq_num) {
*vq_num = i; *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 */ /* Find a device by device descriptor location */
VirtIOS390Device *s390_virtio_bus_find_mem(VirtIOS390Bus *bus, ram_addr_t mem) VirtIOS390Device *s390_virtio_bus_find_mem(VirtIOS390Bus *bus, ram_addr_t mem)
{ {
VirtIOS390Device *_dev; BusChild *kid;
DeviceState *dev;
QTAILQ_FOREACH(dev, &bus->bus.children, sibling) { QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
_dev = (VirtIOS390Device *)dev; VirtIOS390Device *dev = (VirtIOS390Device *)kid->child;
if (_dev->dev_offs == mem) { if (dev->dev_offs == mem) {
return _dev; return dev;
} }
} }

View File

@ -315,7 +315,7 @@ static void store_lun(uint8_t *outbuf, int lun)
static bool scsi_target_emulate_report_luns(SCSITargetReq *r) static bool scsi_target_emulate_report_luns(SCSITargetReq *r)
{ {
DeviceState *qdev; BusChild *kid;
int i, len, n; int i, len, n;
int channel, id; int channel, id;
bool found_lun0; bool found_lun0;
@ -330,7 +330,8 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r)
id = r->req.dev->id; id = r->req.dev->id;
found_lun0 = false; found_lun0 = false;
n = 0; 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); SCSIDevice *dev = SCSI_DEVICE(qdev);
if (dev->channel == channel && dev->id == id) { 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); memset(r->buf, 0, len);
stl_be_p(&r->buf, n); stl_be_p(&r->buf, n);
i = found_lun0 ? 8 : 16; 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); SCSIDevice *dev = SCSI_DEVICE(qdev);
if (dev->channel == channel && dev->id == id) { 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) SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun)
{ {
DeviceState *qdev; BusChild *kid;
SCSIDevice *target_dev = NULL; 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); SCSIDevice *dev = SCSI_DEVICE(qdev);
if (dev->channel == channel && dev->id == id) { if (dev->channel == channel && dev->id == id) {

View File

@ -35,17 +35,18 @@
static PCIDevice *find_dev(sPAPREnvironment *spapr, static PCIDevice *find_dev(sPAPREnvironment *spapr,
uint64_t buid, uint32_t config_addr) uint64_t buid, uint32_t config_addr)
{ {
DeviceState *qdev;
int devfn = (config_addr >> 8) & 0xFF; int devfn = (config_addr >> 8) & 0xFF;
sPAPRPHBState *phb; sPAPRPHBState *phb;
QLIST_FOREACH(phb, &spapr->phbs, list) { QLIST_FOREACH(phb, &spapr->phbs, list) {
BusChild *kid;
if (phb->buid != buid) { if (phb->buid != buid) {
continue; continue;
} }
QTAILQ_FOREACH(qdev, &phb->host_state.bus->qbus.children, sibling) { QTAILQ_FOREACH(kid, &phb->host_state.bus->qbus.children, sibling) {
PCIDevice *dev = (PCIDevice *)qdev; PCIDevice *dev = (PCIDevice *)kid->child;
if (dev->devfn == devfn) { if (dev->devfn == devfn) {
return dev; return dev;
} }

View File

@ -62,11 +62,11 @@ static const TypeInfo spapr_vio_bus_info = {
VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg) VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg)
{ {
DeviceState *qdev; BusChild *kid;
VIOsPAPRDevice *dev = NULL; VIOsPAPRDevice *dev = NULL;
QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) { QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
dev = (VIOsPAPRDevice *)qdev; dev = (VIOsPAPRDevice *)kid->child;
if (dev->reg == reg) { if (dev->reg == reg) {
return dev; return dev;
} }
@ -606,7 +606,7 @@ static void rtas_quiesce(sPAPREnvironment *spapr, uint32_t token,
uint32_t nret, target_ulong rets) uint32_t nret, target_ulong rets)
{ {
VIOsPAPRBus *bus = spapr->vio_bus; VIOsPAPRBus *bus = spapr->vio_bus;
DeviceState *qdev; BusChild *kid;
VIOsPAPRDevice *dev = NULL; VIOsPAPRDevice *dev = NULL;
if (nargs != 0) { if (nargs != 0) {
@ -614,8 +614,8 @@ static void rtas_quiesce(sPAPREnvironment *spapr, uint32_t token,
return; return;
} }
QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) { QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
dev = (VIOsPAPRDevice *)qdev; dev = (VIOsPAPRDevice *)kid->child;
spapr_vio_quiesce_one(dev); spapr_vio_quiesce_one(dev);
} }
@ -625,7 +625,7 @@ static void rtas_quiesce(sPAPREnvironment *spapr, uint32_t token,
static VIOsPAPRDevice *reg_conflict(VIOsPAPRDevice *dev) static VIOsPAPRDevice *reg_conflict(VIOsPAPRDevice *dev)
{ {
VIOsPAPRBus *bus = DO_UPCAST(VIOsPAPRBus, bus, dev->qdev.parent_bus); VIOsPAPRBus *bus = DO_UPCAST(VIOsPAPRBus, bus, dev->qdev.parent_bus);
DeviceState *qdev; BusChild *kid;
VIOsPAPRDevice *other; VIOsPAPRDevice *other;
/* /*
@ -633,8 +633,8 @@ static VIOsPAPRDevice *reg_conflict(VIOsPAPRDevice *dev)
* using the requested address. We have to open code this because * using the requested address. We have to open code this because
* the given dev might already be in the list. * the given dev might already be in the list.
*/ */
QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) { QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
other = DO_UPCAST(VIOsPAPRDevice, qdev, qdev); other = DO_UPCAST(VIOsPAPRDevice, qdev, kid->child);
if (other != dev && other->reg == dev->reg) { if (other != dev && other->reg == dev->reg) {
return other; return other;
@ -840,19 +840,20 @@ static int compare_reg(const void *p1, const void *p2)
int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt) int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt)
{ {
DeviceState *qdev, **qdevs; DeviceState *qdev, **qdevs;
BusChild *kid;
int i, num, ret = 0; int i, num, ret = 0;
/* Count qdevs on the bus list */ /* Count qdevs on the bus list */
num = 0; num = 0;
QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) { QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
num++; num++;
} }
/* Copy out into an array of pointers */ /* Copy out into an array of pointers */
qdevs = g_malloc(sizeof(qdev) * num); qdevs = g_malloc(sizeof(qdev) * num);
num = 0; num = 0;
QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) { QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
qdevs[num++] = qdev; qdevs[num++] = kid->child;
} }
/* Sort the array */ /* Sort the array */

View File

@ -160,7 +160,7 @@ static TypeInfo spapr_vty_info = {
VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus) VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus)
{ {
VIOsPAPRDevice *sdev, *selected; VIOsPAPRDevice *sdev, *selected;
DeviceState *iter; BusChild *kid;
/* /*
* To avoid the console bouncing around we want one VTY to be * 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; 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 */ /* Only look at VTY devices */
if (!object_dynamic_cast(OBJECT(iter), "spapr-vty")) { if (!object_dynamic_cast(OBJECT(iter), "spapr-vty")) {
continue; continue;

View File

@ -30,10 +30,11 @@ static int ssi_slave_init(DeviceState *dev)
SSISlave *s = SSI_SLAVE(dev); SSISlave *s = SSI_SLAVE(dev);
SSISlaveClass *ssc = SSI_SLAVE_GET_CLASS(s); SSISlaveClass *ssc = SSI_SLAVE_GET_CLASS(s);
SSIBus *bus; SSIBus *bus;
BusChild *kid;
bus = FROM_QBUS(SSIBus, qdev_get_parent_bus(dev)); bus = FROM_QBUS(SSIBus, qdev_get_parent_bus(dev));
if (QTAILQ_FIRST(&bus->qbus.children) != dev kid = QTAILQ_FIRST(&bus->qbus.children);
|| QTAILQ_NEXT(dev, sibling) != NULL) { if (kid->child != dev || QTAILQ_NEXT(kid, sibling) != NULL) {
hw_error("Too many devices on SSI bus"); 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) uint32_t ssi_transfer(SSIBus *bus, uint32_t val)
{ {
DeviceState *dev; BusChild *kid;
SSISlave *slave; SSISlave *slave;
SSISlaveClass *ssc; SSISlaveClass *ssc;
dev = QTAILQ_FIRST(&bus->qbus.children);
if (!dev) { kid = QTAILQ_FIRST(&bus->qbus.children);
if (!kid) {
return 0; return 0;
} }
slave = SSI_SLAVE(dev); slave = SSI_SLAVE(kid->child);
ssc = SSI_SLAVE_GET_CLASS(slave); ssc = SSI_SLAVE_GET_CLASS(slave);
return ssc->transfer(slave, val); return ssc->transfer(slave, val);
} }

View File

@ -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); SCSIDevice *d = virtio_scsi_device_find(s, req->req.tmf->lun);
SCSIRequest *r, *next; SCSIRequest *r, *next;
DeviceState *qdev; BusChild *kid;
int target; int target;
/* Here VIRTIO_SCSI_S_OK means "FUNCTION COMPLETE". */ /* 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: case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET:
target = req->req.tmf->lun[1]; target = req->req.tmf->lun[1];
s->resetting++; s->resetting++;
QTAILQ_FOREACH(qdev, &s->bus.qbus.children, sibling) { QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {
d = DO_UPCAST(SCSIDevice, qdev, qdev); d = DO_UPCAST(SCSIDevice, qdev, kid->child);
if (d->channel == 0 && d->id == target) { if (d->channel == 0 && d->id == target) {
qdev_reset_all(&d->qdev); qdev_reset_all(&d->qdev);
} }

View File

@ -689,9 +689,16 @@ void object_property_del(Object *obj, const char *name, Error **errp)
{ {
ObjectProperty *prop = object_property_find(obj, name); 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->name);
g_free(prop->type); g_free(prop->type);