Commit 55ed83a6 authored by Yinghai Lu's avatar Yinghai Lu Committed by Bjorn Helgaas

PCI: Assign resources on a per-bus basis

Previously, we did resource assignment globally.  This patch splits up
pci_assign_unassigned_resources() so assignment is done for each root bus
in turn.  We check each root bus individually to see whether it needs any
reassignment, and if it does, we assign resources for just that bus.

[bhelgaas: changelog]
Signed-off-by: default avatarYinghai Lu <yinghai@kernel.org>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
parent 967260cd
...@@ -1315,21 +1315,6 @@ static int __init pci_bus_get_depth(struct pci_bus *bus) ...@@ -1315,21 +1315,6 @@ static int __init pci_bus_get_depth(struct pci_bus *bus)
return depth; return depth;
} }
static int __init pci_get_max_depth(void)
{
int depth = 0;
struct pci_bus *bus;
list_for_each_entry(bus, &pci_root_buses, node) {
int ret;
ret = pci_bus_get_depth(bus);
if (ret > depth)
depth = ret;
}
return depth;
}
/* /*
* -1: undefined, will auto detect later * -1: undefined, will auto detect later
...@@ -1410,10 +1395,9 @@ static enum enable_type __init pci_realloc_detect(struct pci_bus *bus, ...@@ -1410,10 +1395,9 @@ static enum enable_type __init pci_realloc_detect(struct pci_bus *bus,
* second and later try will clear small leaf bridge res * second and later try will clear small leaf bridge res
* will stop till to the max deepth if can not find good one * will stop till to the max deepth if can not find good one
*/ */
void __init static void __init
pci_assign_unassigned_resources(void) pci_assign_unassigned_root_bus_resources(struct pci_bus *bus)
{ {
struct pci_bus *bus;
LIST_HEAD(realloc_head); /* list of resources that LIST_HEAD(realloc_head); /* list of resources that
want additional resources */ want additional resources */
struct list_head *add_list = NULL; struct list_head *add_list = NULL;
...@@ -1424,16 +1408,16 @@ pci_assign_unassigned_resources(void) ...@@ -1424,16 +1408,16 @@ pci_assign_unassigned_resources(void)
unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
IORESOURCE_PREFETCH; IORESOURCE_PREFETCH;
int pci_try_num = 1; int pci_try_num = 1;
enum enable_type enable_local = pci_realloc_enable; enum enable_type enable_local;
list_for_each_entry(bus, &pci_root_buses, node)
enable_local = pci_realloc_detect(bus, enable_local);
/* don't realloc if asked to do so */
enable_local = pci_realloc_detect(bus, pci_realloc_enable);
if (pci_realloc_enabled(enable_local)) { if (pci_realloc_enabled(enable_local)) {
int max_depth = pci_get_max_depth(); int max_depth = pci_bus_get_depth(bus);
pci_try_num = max_depth + 1; pci_try_num = max_depth + 1;
printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n", dev_printk(KERN_DEBUG, &bus->dev,
"max bus depth: %d pci_try_num: %d\n",
max_depth, pci_try_num); max_depth, pci_try_num);
} }
...@@ -1446,11 +1430,9 @@ pci_assign_unassigned_resources(void) ...@@ -1446,11 +1430,9 @@ pci_assign_unassigned_resources(void)
add_list = &realloc_head; add_list = &realloc_head;
/* Depth first, calculate sizes and alignments of all /* Depth first, calculate sizes and alignments of all
subordinate buses. */ subordinate buses. */
list_for_each_entry(bus, &pci_root_buses, node)
__pci_bus_size_bridges(bus, add_list); __pci_bus_size_bridges(bus, add_list);
/* Depth last, allocate resources and update the hardware. */ /* Depth last, allocate resources and update the hardware. */
list_for_each_entry(bus, &pci_root_buses, node)
__pci_bus_assign_resources(bus, add_list, &fail_head); __pci_bus_assign_resources(bus, add_list, &fail_head);
if (add_list) if (add_list)
BUG_ON(!list_empty(add_list)); BUG_ON(!list_empty(add_list));
...@@ -1462,16 +1444,16 @@ pci_assign_unassigned_resources(void) ...@@ -1462,16 +1444,16 @@ pci_assign_unassigned_resources(void)
if (tried_times >= pci_try_num) { if (tried_times >= pci_try_num) {
if (enable_local == undefined) if (enable_local == undefined)
printk(KERN_INFO "Some PCI device resources are unassigned, try booting with pci=realloc\n"); dev_info(&bus->dev, "Some PCI device resources are unassigned, try booting with pci=realloc\n");
else if (enable_local == auto_enabled) else if (enable_local == auto_enabled)
printk(KERN_INFO "Automatically enabled pci realloc, if you have problem, try booting with pci=realloc=off\n"); dev_info(&bus->dev, "Automatically enabled pci realloc, if you have problem, try booting with pci=realloc=off\n");
free_list(&fail_head); free_list(&fail_head);
goto enable_and_dump; goto enable_and_dump;
} }
printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n", dev_printk(KERN_DEBUG, &bus->dev,
tried_times + 1); "No. %d try to assign unassigned res\n", tried_times + 1);
/* third times and later will not check if it is leaf */ /* third times and later will not check if it is leaf */
if ((tried_times + 1) > 2) if ((tried_times + 1) > 2)
...@@ -1502,14 +1484,20 @@ pci_assign_unassigned_resources(void) ...@@ -1502,14 +1484,20 @@ pci_assign_unassigned_resources(void)
enable_and_dump: enable_and_dump:
/* Depth last, update the hardware. */ /* Depth last, update the hardware. */
list_for_each_entry(bus, &pci_root_buses, node)
pci_enable_bridges(bus); pci_enable_bridges(bus);
/* dump the resource on buses */ /* dump the resource on buses */
list_for_each_entry(bus, &pci_root_buses, node)
pci_bus_dump_resources(bus); pci_bus_dump_resources(bus);
} }
void __init pci_assign_unassigned_resources(void)
{
struct pci_bus *root_bus;
list_for_each_entry(root_bus, &pci_root_buses, node)
pci_assign_unassigned_root_bus_resources(root_bus);
}
void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge) void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
{ {
struct pci_bus *parent = bridge->subordinate; struct pci_bus *parent = bridge->subordinate;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment