aboutsummaryrefslogtreecommitdiff
path: root/drivers/pci/setup-bus.c
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2010-05-21 14:35:06 -0700
committerJesse Barnes <jbarnes@virtuousgeek.org>2010-07-30 09:29:16 -0700
commit3f579c340fe6d6bdd8c6f9f144e7c3b85d4174ec (patch)
tree7dbffa4e375aa2315c19db402857a07b24c82b40 /drivers/pci/setup-bus.c
parent0ba10bc75271e4139eb9ca67d107624d581e3a94 (diff)
PCI hotplug: make sure child bridges are enabled at hotplug time
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>
Diffstat (limited to 'drivers/pci/setup-bus.c')
-rw-r--r--drivers/pci/setup-bus.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 19b111383f6..66cb8f4cc5f 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -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);