summaryrefslogtreecommitdiffstats
path: root/drivers/pci/bus.c
diff options
context:
space:
mode:
authorLukas Wunner <lukas@wunner.de>2016-05-02 13:48:25 -0500
committerBjorn Helgaas <bhelgaas@google.com>2016-05-02 13:48:25 -0500
commit1e398eae8407abdc02cde8a449b14d17ed193d56 (patch)
tree58726e551ae0412004dbaeff0ac85eeb06b3e8da /drivers/pci/bus.c
parent67e658794ca191b3221b143f2a1c10d002c40bc8 (diff)
downloadlinux-1e398eae8407abdc02cde8a449b14d17ed193d56.tar.gz
linux-1e398eae8407abdc02cde8a449b14d17ed193d56.tar.bz2
linux-1e398eae8407abdc02cde8a449b14d17ed193d56.zip
PCI: Fix BUG on device attach failure
Previously when pci_bus_add_device() called device_attach() and it returned a negative value, we emitted a WARN but carried on. Commit ab1a187bba5c ("PCI: Check device_attach() return value always"), introduced in Linux 4.6-rc1, changed this to unwind all steps preceding device_attach() and to not set dev->is_added = 1. The latter leads to a BUG if pci_bus_add_device() was called from pci_bus_add_devices(). Fix by not recursing to a child bus if device_attach() failed for the bridge leading to it. This can be triggered by plugging in a PCI device (e.g. Thunderbolt) while the system is asleep. The system locks up when woken because device_attach() returns -EPROBE_DEFER. Fixes: ab1a187bba5c ("PCI: Check device_attach() return value always") Signed-off-by: Lukas Wunner <lukas@wunner.de> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/pci/bus.c')
-rw-r--r--drivers/pci/bus.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 6c9f5467bc5f..23a39fdc311e 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -324,7 +324,9 @@ void pci_bus_add_devices(const struct pci_bus *bus)
}
list_for_each_entry(dev, &bus->devices, bus_list) {
- BUG_ON(!dev->is_added);
+ /* Skip if device attach failed */
+ if (!dev->is_added)
+ continue;
child = dev->subordinate;
if (child)
pci_bus_add_devices(child);