PCI hotplug: make sure child bridges are enabled at hotplug time
authorYinghai Lu <yinghai@kernel.org>
Fri, 21 May 2010 21:35:06 +0000 (14:35 -0700)
committerJesse Barnes <jbarnes@virtuousgeek.org>
Fri, 30 Jul 2010 16:29:16 +0000 (09:29 -0700)
Found one PCIe Module with several bridges built-in where a "cold"
hotadd doesn't work.

If we end up reassigning bridge windows at hotadd time, and have to loop
through assigning new ranges, we won't end up enabling the child bridges
because the first assignment pass already tried to enable them, which
prevents __pci_bridge_assign_resource from updating the windows.

So try to move enabling of child bridges to the end, and only do it
once.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
drivers/pci/setup-bus.c

index 19b111383f62fe63c9859dfd509de2cda3801d9e..66cb8f4cc5f4b37fbfc965fda9c63fc1fb1da913 100644 (file)
@@ -874,19 +874,16 @@ void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
 again:
        pci_bus_size_bridges(parent);
        __pci_bridge_assign_resources(bridge, &head);
-       retval = pci_reenable_device(bridge);
-       pci_set_master(bridge);
-       pci_enable_bridges(parent);
 
        tried_times++;
 
        if (!head.next)
-               return;
+               goto enable_all;
 
        if (tried_times >= 2) {
                /* still fail, don't need to try more */
                free_failed_list(&head);
-               return;
+               goto enable_all;
        }
 
        printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n",
@@ -919,5 +916,10 @@ again:
        free_failed_list(&head);
 
        goto again;
+
+enable_all:
+       retval = pci_reenable_device(bridge);
+       pci_set_master(bridge);
+       pci_enable_bridges(parent);
 }
 EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources);