diff options
author | Yinghai Lu <yinghai@kernel.org> | 2012-11-04 08:39:26 +0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2013-01-08 02:58:16 +0400 |
commit | 83edc87ce8b284a3d60ab8072e55041c76a68277 (patch) | |
tree | ef8b9a395f563d97e433245d293d92a93d50ac96 | |
parent | c7f4bbc92feee2986212ef3b42c806e2257197dc (diff) | |
download | linux-83edc87ce8b284a3d60ab8072e55041c76a68277.tar.xz |
x86/PCI: Allocate resources on a per-bus basis for hot-adding root buses
Previously pcibios_allocate_resources() allocated resources at boot-time
for all PCI devices using for_each_pci_dev(). This patch changes
pcibios_allocate_resources() so we can specify a bus, so we can do
similar allocation when hot-adding a root bus.
[bhelgaas: changelog]
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-rw-r--r-- | arch/x86/pci/i386.c | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index 5817cf235d9a..84696ed1f0e9 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c @@ -215,16 +215,15 @@ static void __init pcibios_allocate_bridge_resources(struct pci_dev *dev) } } -static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) +static void __init pcibios_allocate_bus_resources(struct pci_bus *bus) { - struct pci_bus *bus; + struct pci_bus *child; /* Depth-First Search on bus tree */ - list_for_each_entry(bus, bus_list, node) { - if (bus->self) - pcibios_allocate_bridge_resources(bus->self); - pcibios_allocate_bus_resources(&bus->children); - } + if (bus->self) + pcibios_allocate_bridge_resources(bus->self); + list_for_each_entry(child, &bus->children, node) + pcibios_allocate_bus_resources(child); } struct pci_check_idx_range { @@ -285,12 +284,18 @@ static void __init pcibios_allocate_dev_resources(struct pci_dev *dev, int pass) } } -static void __init pcibios_allocate_resources(int pass) +static void __init pcibios_allocate_resources(struct pci_bus *bus, int pass) { - struct pci_dev *dev = NULL; + struct pci_dev *dev; + struct pci_bus *child; - for_each_pci_dev(dev) + list_for_each_entry(dev, &bus->devices, bus_list) { pcibios_allocate_dev_resources(dev, pass); + + child = dev->subordinate; + if (child) + pcibios_allocate_resources(child, pass); + } } static int __init pcibios_assign_resources(void) @@ -323,10 +328,17 @@ static int __init pcibios_assign_resources(void) void __init pcibios_resource_survey(void) { + struct pci_bus *bus; + DBG("PCI: Allocating resources\n"); - pcibios_allocate_bus_resources(&pci_root_buses); - pcibios_allocate_resources(0); - pcibios_allocate_resources(1); + + list_for_each_entry(bus, &pci_root_buses, node) + pcibios_allocate_bus_resources(bus); + + list_for_each_entry(bus, &pci_root_buses, node) + pcibios_allocate_resources(bus, 0); + list_for_each_entry(bus, &pci_root_buses, node) + pcibios_allocate_resources(bus, 1); e820_reserve_resources_late(); /* |