If get_pbus() is called for a device which has no parent/ancestor bus
with nonzero PCI bus operations, get_pbus() will get stuck in a silent
endless loop.
Detect the endless loop and break out with an error message.

Such a situation can happen if the device tree is not yet
initialized/walked completely.

This fixes the unexplainable hang if pci_{read,write}_config{8,16,32}was
used in early mainboard code for the AMD DBM690T. Instead, the code will
now die() with a meaningful error message.

Thanks to Ward Vandewege for testing my patches to track down that bug.

Signed-off-by: Carl-Daniel Hailfinger <[email protected]>

Index: LinuxBIOSv2-asus_m2a-vm/src/devices/pci_ops.c
===================================================================
--- LinuxBIOSv2-asus_m2a-vm/src/devices/pci_ops.c       (Revision 3967)
+++ LinuxBIOSv2-asus_m2a-vm/src/devices/pci_ops.c       (Arbeitskopie)
@@ -28,6 +28,12 @@
 {
        struct bus *pbus = dev->bus;
        while(pbus && pbus->dev && !ops_pci_bus(pbus)) {
+               if (pbus == pbus->dev->bus) {
+                       printk_alert("%s in endless loop looking for a parent "
+                               "bus with ops_pci_bus for %s, breaking out\n",
+                                __func__, dev_path(dev));
+                       break;
+               }
                pbus = pbus->dev->bus;
        }
        if (!pbus || !pbus->dev || !pbus->dev->ops || 
!pbus->dev->ops->ops_pci_bus) {


-- 
http://www.hailfinger.org/

Index: LinuxBIOSv2-asus_m2a-vm/src/devices/pci_ops.c
===================================================================
--- LinuxBIOSv2-asus_m2a-vm/src/devices/pci_ops.c       (Revision 3967)
+++ LinuxBIOSv2-asus_m2a-vm/src/devices/pci_ops.c       (Arbeitskopie)
@@ -28,6 +28,12 @@
 {
        struct bus *pbus = dev->bus;
        while(pbus && pbus->dev && !ops_pci_bus(pbus)) {
+               if (pbus == pbus->dev->bus) {
+                       printk_alert("%s in endless loop looking for a parent "
+                               "bus with ops_pci_bus for %s, breaking out\n",
+                                __func__, dev_path(dev));
+                       break;
+               }
                pbus = pbus->dev->bus;
        }
        if (!pbus || !pbus->dev || !pbus->dev->ops || 
!pbus->dev->ops->ops_pci_bus) {
--
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to