PCI: enumerate the PCI device only removed out PCI hieratchy of OS when re-scanning PCI
authorTiejun Chen <tiejun.chen@windriver.com>
Thu, 2 Jun 2011 03:02:50 +0000 (11:02 +0800)
committerJesse Barnes <jbarnes@virtuousgeek.org>
Fri, 22 Jul 2011 15:25:38 +0000 (08:25 -0700)
When hot-plugging a root bridge, we always prevent assigning a bus number
that already exists. This makes sure we don't step over an existing bus.
But sometimes we only remove PCI device in PCI hieratchy of OS, i,e.

echo 1 > /sys/bus/pci/devices/.../remove

but actually don't hotplug this device out the platform, so in this case
we still should re-scan this bus to enumerate this device when re-scanning
PCI again.

Signed-off-by: Tiejun Chen <tiejun.chen@windriver.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
drivers/pci/probe.c

index bafb3c3d4a8963e6a635d94a414e290e4998af40..f03ed96533d5b872156eb953883483a21439f699 100644 (file)
@@ -724,12 +724,14 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
                pci_write_config_word(dev, PCI_STATUS, 0xffff);
 
                /* Prevent assigning a bus number that already exists.
-                * This can happen when a bridge is hot-plugged */
-               if (pci_find_bus(pci_domain_nr(bus), max+1))
-                       goto out;
-               child = pci_add_new_bus(bus, dev, ++max);
-               if (!child)
-                       goto out;
+                * This can happen when a bridge is hot-plugged, so in
+                * this case we only re-scan this bus. */
+               child = pci_find_bus(pci_domain_nr(bus), max+1);
+               if (!child) {
+                       child = pci_add_new_bus(bus, dev, ++max);
+                       if (!child)
+                               goto out;
+               }
                buses = (buses & 0xff000000)
                      | ((unsigned int)(child->primary)     <<  0)
                      | ((unsigned int)(child->secondary)   <<  8)