Commit d8bb00d6 authored by Paolo Bonzini's avatar Paolo Bonzini Committed by Kevin Wolf
Browse files

qdev: switch children device list to QTAILQ



SCSI buses will need to read the children list first-to-last.  This
requires using a QTAILQ, because hell breaks loose if you just try
inserting at the tail (thus reversing the order of all existing
visits from last-to-first to first-to-tail).

Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parent afd4030c
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -276,7 +276,7 @@ static void piix4_update_hotplug(PIIX4PMState *s)

    s->pci0_hotplug_enable = ~0;

    QLIST_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
    QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
        PCIDeviceInfo *info = container_of(qdev->info, PCIDeviceInfo, qdev);
        PCIDevice *pdev = DO_UPCAST(PCIDevice, qdev, qdev);
        int slot = PCI_SLOT(pdev->devfn);
@@ -486,7 +486,7 @@ static void pciej_write(void *opaque, uint32_t addr, uint32_t val)
    PCIDeviceInfo *info;
    int slot = ffs(val) - 1;

    QLIST_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
    QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
        dev = DO_UPCAST(PCIDevice, qdev, qdev);
        info = container_of(qdev->info, PCIDeviceInfo, qdev);
        if (PCI_SLOT(dev->devfn) == slot && !info->no_hotplug) {
+1 −1
Original line number Diff line number Diff line
@@ -84,7 +84,7 @@ int i2c_start_transfer(i2c_bus *bus, uint8_t address, int recv)
    DeviceState *qdev;
    i2c_slave *slave = NULL;

    QLIST_FOREACH(qdev, &bus->qbus.children, sibling) {
    QTAILQ_FOREACH(qdev, &bus->qbus.children, sibling) {
        i2c_slave *candidate = I2C_SLAVE_FROM_QDEV(qdev);
        if (candidate->address == address) {
            slave = candidate;
+3 −3
Original line number Diff line number Diff line
@@ -86,7 +86,7 @@ HDACodecDevice *hda_codec_find(HDACodecBus *bus, uint32_t cad)
    DeviceState *qdev;
    HDACodecDevice *cdev;

    QLIST_FOREACH(qdev, &bus->qbus.children, sibling) {
    QTAILQ_FOREACH(qdev, &bus->qbus.children, sibling) {
        cdev = DO_UPCAST(HDACodecDevice, qdev, qdev);
        if (cdev->cad == cad) {
            return cdev;
@@ -490,7 +490,7 @@ static void intel_hda_notify_codecs(IntelHDAState *d, uint32_t stream, bool runn
    DeviceState *qdev;
    HDACodecDevice *cdev;

    QLIST_FOREACH(qdev, &d->codecs.qbus.children, sibling) {
    QTAILQ_FOREACH(qdev, &d->codecs.qbus.children, sibling) {
        cdev = DO_UPCAST(HDACodecDevice, qdev, qdev);
        if (cdev->info->stream) {
            cdev->info->stream(cdev, stream, running, output);
@@ -1114,7 +1114,7 @@ static void intel_hda_reset(DeviceState *dev)
    d->wall_base_ns = qemu_get_clock_ns(vm_clock);

    /* reset codecs */
    QLIST_FOREACH(qdev, &d->codecs.qbus.children, sibling) {
    QTAILQ_FOREACH(qdev, &d->codecs.qbus.children, sibling) {
        cdev = DO_UPCAST(HDACodecDevice, qdev, qdev);
        if (qdev->info->reset) {
            qdev->info->reset(qdev);
+12 −12
Original line number Diff line number Diff line
@@ -91,7 +91,7 @@ static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
    qdev_prop_set_defaults(dev, dev->info->props);
    qdev_prop_set_defaults(dev, dev->parent_bus->info->props);
    qdev_prop_set_globals(dev);
    QLIST_INSERT_HEAD(&bus->children, dev, sibling);
    QTAILQ_INSERT_HEAD(&bus->children, dev, sibling);
    if (qdev_hotplug) {
        assert(bus->allow_hotplug);
        dev->hotplugged = 1;
@@ -408,7 +408,7 @@ void qdev_free(DeviceState *dev)
        if (dev->opts)
            qemu_opts_del(dev->opts);
    }
    QLIST_REMOVE(dev, sibling);
    QTAILQ_REMOVE(&dev->parent_bus->children, dev, sibling);
    for (prop = dev->info->props; prop && prop->name; prop++) {
        if (prop->info->free) {
            prop->info->free(dev, prop);
@@ -510,7 +510,7 @@ int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
        }
    }

    QLIST_FOREACH(dev, &bus->children, sibling) {
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
        err = qdev_walk_children(dev, devfn, busfn, opaque);
        if (err < 0) {
            return err;
@@ -560,7 +560,7 @@ static BusState *qbus_find_recursive(BusState *bus, const char *name,
        return bus;
    }

    QLIST_FOREACH(dev, &bus->children, sibling) {
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
            ret = qbus_find_recursive(child, name, info);
            if (ret) {
@@ -576,7 +576,7 @@ DeviceState *qdev_find_recursive(BusState *bus, const char *id)
    DeviceState *dev, *ret;
    BusState *child;

    QLIST_FOREACH(dev, &bus->children, sibling) {
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
        if (dev->id && strcmp(dev->id, id) == 0)
            return dev;
        QLIST_FOREACH(child, &dev->child_bus, sibling) {
@@ -609,7 +609,7 @@ static void qbus_list_dev(BusState *bus)
    const char *sep = " ";

    error_printf("devices at \"%s\":", bus->name);
    QLIST_FOREACH(dev, &bus->children, sibling) {
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
        error_printf("%s\"%s\"", sep, dev->info->name);
        if (dev->id)
            error_printf("/\"%s\"", dev->id);
@@ -640,17 +640,17 @@ static DeviceState *qbus_find_dev(BusState *bus, char *elem)
     *   (2) driver name
     *   (3) driver alias, if present
     */
    QLIST_FOREACH(dev, &bus->children, sibling) {
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
        if (dev->id  &&  strcmp(dev->id, elem) == 0) {
            return dev;
        }
    }
    QLIST_FOREACH(dev, &bus->children, sibling) {
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
        if (strcmp(dev->info->name, elem) == 0) {
            return dev;
        }
    }
    QLIST_FOREACH(dev, &bus->children, sibling) {
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
        if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) {
            return dev;
        }
@@ -774,7 +774,7 @@ void qbus_create_inplace(BusState *bus, BusInfo *info,
        bus->name = buf;
    }

    QLIST_INIT(&bus->children);
    QTAILQ_INIT(&bus->children);
    if (parent) {
        QLIST_INSERT_HEAD(&parent->child_bus, bus, sibling);
        parent->num_child_bus++;
@@ -809,7 +809,7 @@ void qbus_free(BusState *bus)
{
    DeviceState *dev;

    while ((dev = QLIST_FIRST(&bus->children)) != NULL) {
    while ((dev = QTAILQ_FIRST(&bus->children)) != NULL) {
        qdev_free(dev);
    }
    if (bus->parent) {
@@ -878,7 +878,7 @@ static void qbus_print(Monitor *mon, BusState *bus, int indent)
    qdev_printf("bus: %s\n", bus->name);
    indent += 2;
    qdev_printf("type %s\n", bus->info->name);
    QLIST_FOREACH(dev, &bus->children, sibling) {
    QTAILQ_FOREACH(dev, &bus->children, sibling) {
        qdev_print(mon, dev, indent);
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ struct DeviceState {
    qemu_irq *gpio_in;
    QLIST_HEAD(, BusState) child_bus;
    int num_child_bus;
    QLIST_ENTRY(DeviceState) sibling;
    QTAILQ_ENTRY(DeviceState) sibling;
    int instance_id_alias;
    int alias_required_for_version;
};
@@ -73,7 +73,7 @@ struct BusState {
    const char *name;
    int allow_hotplug;
    int qdev_allocated;
    QLIST_HEAD(, DeviceState) children;
    QTAILQ_HEAD(, DeviceState) children;
    QLIST_ENTRY(BusState) sibling;
};

Loading