Kyösti Mälkki has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/30772
Change subject: [WIP] device/pci_device: Do not break tree topology ......................................................................
[WIP] device/pci_device: Do not break tree topology
Function pci_scan_bus() breaks bus->children link in the devicetree topology while scanning a bus. While the scan is in progress, accessing PCI devices with number higher than what is being probed was not possible.
Change-Id: I7bb497f7390628dd2f0310b380f199783a888c4c Signed-off-by: Kyösti Mälkki kyosti.malkki@gmail.com --- M src/device/pci_device.c 1 file changed, 23 insertions(+), 27 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/72/30772/1
diff --git a/src/device/pci_device.c b/src/device/pci_device.c index e35c22c..5aedeb6 100644 --- a/src/device/pci_device.c +++ b/src/device/pci_device.c @@ -998,24 +998,23 @@ * @return Pointer to the device structure found or NULL if we have not * allocated a device for this devfn yet. */ -static struct device *pci_scan_get_dev(struct device **list, unsigned int devfn) +static struct device *pci_scan_get_dev(struct bus *bus, unsigned int devfn) { - struct device *dev; + struct device *dev, **prev;
- dev = 0; - for (; *list; list = &(*list)->sibling) { - if ((*list)->path.type != DEVICE_PATH_PCI) { - printk(BIOS_ERR, "child %s not a PCI device\n", - dev_path(*list)); - continue; - } - if ((*list)->path.pci.devfn == devfn) { + prev = &bus->children; + for (dev = bus->children; dev; dev = dev->sibling) { + if ((dev->path.type == DEVICE_PATH_PCI) && + (dev->path.pci.devfn == devfn)) { /* Unlink from the list. */ - dev = *list; - *list = (*list)->sibling; + *prev = dev->sibling; dev->sibling = NULL; break; + } else { + printk(BIOS_ERR, "child %s not a PCI device\n", + dev_path(dev)); } + prev = &dev->sibling; }
/* @@ -1027,15 +1026,15 @@ if (dev) { struct device *child;
- /* Find the last child of our parent. */ - for (child = dev->bus->children; child && child->sibling;) + /* Find the last child on the bus. */ + for (child = bus->children; child && child->sibling;) child = child->sibling;
- /* Place the device on the list of children of its parent. */ + /* Place the device as last on the bus. */ if (child) child->sibling = dev; else - dev->bus->children = dev; + bus->children = dev; }
return dev; @@ -1180,7 +1179,7 @@ unsigned max_devfn) { unsigned int devfn; - struct device *old_devices; + struct device *left;
printk(BIOS_DEBUG, "PCI: pci_scan_bus for bus %02x\n", bus->secondary);
@@ -1193,9 +1192,6 @@ max_devfn=0xff; }
- old_devices = bus->children; - bus->children = NULL; - post_code(0x24);
/* @@ -1206,7 +1202,7 @@ struct device *dev;
/* First thing setup the device structure. */ - dev = pci_scan_get_dev(&old_devices, devfn); + dev = pci_scan_get_dev(bus, devfn);
/* See if a device is present and setup the device structure. */ dev = pci_probe_dev(dev, bus, devfn); @@ -1228,13 +1224,13 @@ * Warn if any leftover static devices are are found. * There's probably a problem in devicetree.cb. */ - if (old_devices) { - struct device *left; - printk(BIOS_WARNING, "PCI: Left over static devices:\n"); - for (left = old_devices; left; left = left->sibling) - printk(BIOS_WARNING, "%s\n", dev_path(left));
- printk(BIOS_WARNING, "PCI: Check your devicetree.cb.\n"); + printk(BIOS_WARNING, "PCI: Left over static devices:\n"); + for (left = bus->children; left; left = left->sibling) { + if (left->vendor == 0x0) { + printk(BIOS_WARNING, "%s\n", dev_path(left)); + printk(BIOS_WARNING, "PCI: Check your devicetree.cb.\n"); + } }
/*