diff options
author | Yinghai Lu <yinghai@kernel.org> | 2013-07-22 17:37:16 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2013-07-25 14:35:03 -0400 |
commit | 55ed83a615730c2578da155bc99b68f4417ffe20 (patch) | |
tree | d055dc5e4298e45eede69f51ce7ac14da2267bcd /drivers/pci/setup-bus.c | |
parent | 967260cdb13f9c0de3cf56e305b34eb363e41d5b (diff) |
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: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/setup-bus.c')
-rw-r--r-- | drivers/pci/setup-bus.c | 62 |
1 files changed, 25 insertions, 37 deletions
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 4aaa8d57443f..4d9ebb4ce015 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -1315,21 +1315,6 @@ static int __init pci_bus_get_depth(struct pci_bus *bus) | |||
1315 | 1315 | ||
1316 | return depth; | 1316 | return depth; |
1317 | } | 1317 | } |
1318 | static int __init pci_get_max_depth(void) | ||
1319 | { | ||
1320 | int depth = 0; | ||
1321 | struct pci_bus *bus; | ||
1322 | |||
1323 | list_for_each_entry(bus, &pci_root_buses, node) { | ||
1324 | int ret; | ||
1325 | |||
1326 | ret = pci_bus_get_depth(bus); | ||
1327 | if (ret > depth) | ||
1328 | depth = ret; | ||
1329 | } | ||
1330 | |||
1331 | return depth; | ||
1332 | } | ||
1333 | 1318 | ||
1334 | /* | 1319 | /* |
1335 | * -1: undefined, will auto detect later | 1320 | * -1: undefined, will auto detect later |
@@ -1410,10 +1395,9 @@ static enum enable_type __init pci_realloc_detect(struct pci_bus *bus, | |||
1410 | * second and later try will clear small leaf bridge res | 1395 | * second and later try will clear small leaf bridge res |
1411 | * will stop till to the max deepth if can not find good one | 1396 | * will stop till to the max deepth if can not find good one |
1412 | */ | 1397 | */ |
1413 | void __init | 1398 | static void __init |
1414 | pci_assign_unassigned_resources(void) | 1399 | pci_assign_unassigned_root_bus_resources(struct pci_bus *bus) |
1415 | { | 1400 | { |
1416 | struct pci_bus *bus; | ||
1417 | LIST_HEAD(realloc_head); /* list of resources that | 1401 | LIST_HEAD(realloc_head); /* list of resources that |
1418 | want additional resources */ | 1402 | want additional resources */ |
1419 | struct list_head *add_list = NULL; | 1403 | struct list_head *add_list = NULL; |
@@ -1424,17 +1408,17 @@ pci_assign_unassigned_resources(void) | |||
1424 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | | 1408 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | |
1425 | IORESOURCE_PREFETCH; | 1409 | IORESOURCE_PREFETCH; |
1426 | int pci_try_num = 1; | 1410 | int pci_try_num = 1; |
1427 | enum enable_type enable_local = pci_realloc_enable; | 1411 | enum enable_type enable_local; |
1428 | |||
1429 | list_for_each_entry(bus, &pci_root_buses, node) | ||
1430 | enable_local = pci_realloc_detect(bus, enable_local); | ||
1431 | 1412 | ||
1413 | /* don't realloc if asked to do so */ | ||
1414 | enable_local = pci_realloc_detect(bus, pci_realloc_enable); | ||
1432 | if (pci_realloc_enabled(enable_local)) { | 1415 | if (pci_realloc_enabled(enable_local)) { |
1433 | int max_depth = pci_get_max_depth(); | 1416 | int max_depth = pci_bus_get_depth(bus); |
1434 | 1417 | ||
1435 | pci_try_num = max_depth + 1; | 1418 | pci_try_num = max_depth + 1; |
1436 | printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n", | 1419 | dev_printk(KERN_DEBUG, &bus->dev, |
1437 | max_depth, pci_try_num); | 1420 | "max bus depth: %d pci_try_num: %d\n", |
1421 | max_depth, pci_try_num); | ||
1438 | } | 1422 | } |
1439 | 1423 | ||
1440 | again: | 1424 | again: |
@@ -1446,12 +1430,10 @@ again: | |||
1446 | add_list = &realloc_head; | 1430 | add_list = &realloc_head; |
1447 | /* Depth first, calculate sizes and alignments of all | 1431 | /* Depth first, calculate sizes and alignments of all |
1448 | subordinate buses. */ | 1432 | subordinate buses. */ |
1449 | list_for_each_entry(bus, &pci_root_buses, node) | 1433 | __pci_bus_size_bridges(bus, add_list); |
1450 | __pci_bus_size_bridges(bus, add_list); | ||
1451 | 1434 | ||
1452 | /* Depth last, allocate resources and update the hardware. */ | 1435 | /* Depth last, allocate resources and update the hardware. */ |
1453 | list_for_each_entry(bus, &pci_root_buses, node) | 1436 | __pci_bus_assign_resources(bus, add_list, &fail_head); |
1454 | __pci_bus_assign_resources(bus, add_list, &fail_head); | ||
1455 | if (add_list) | 1437 | if (add_list) |
1456 | BUG_ON(!list_empty(add_list)); | 1438 | BUG_ON(!list_empty(add_list)); |
1457 | tried_times++; | 1439 | tried_times++; |
@@ -1462,16 +1444,16 @@ again: | |||
1462 | 1444 | ||
1463 | if (tried_times >= pci_try_num) { | 1445 | if (tried_times >= pci_try_num) { |
1464 | if (enable_local == undefined) | 1446 | if (enable_local == undefined) |
1465 | printk(KERN_INFO "Some PCI device resources are unassigned, try booting with pci=realloc\n"); | 1447 | dev_info(&bus->dev, "Some PCI device resources are unassigned, try booting with pci=realloc\n"); |
1466 | else if (enable_local == auto_enabled) | 1448 | else if (enable_local == auto_enabled) |
1467 | printk(KERN_INFO "Automatically enabled pci realloc, if you have problem, try booting with pci=realloc=off\n"); | 1449 | dev_info(&bus->dev, "Automatically enabled pci realloc, if you have problem, try booting with pci=realloc=off\n"); |
1468 | 1450 | ||
1469 | free_list(&fail_head); | 1451 | free_list(&fail_head); |
1470 | goto enable_and_dump; | 1452 | goto enable_and_dump; |
1471 | } | 1453 | } |
1472 | 1454 | ||
1473 | printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n", | 1455 | dev_printk(KERN_DEBUG, &bus->dev, |
1474 | tried_times + 1); | 1456 | "No. %d try to assign unassigned res\n", tried_times + 1); |
1475 | 1457 | ||
1476 | /* third times and later will not check if it is leaf */ | 1458 | /* third times and later will not check if it is leaf */ |
1477 | if ((tried_times + 1) > 2) | 1459 | if ((tried_times + 1) > 2) |
@@ -1502,12 +1484,18 @@ again: | |||
1502 | 1484 | ||
1503 | enable_and_dump: | 1485 | enable_and_dump: |
1504 | /* Depth last, update the hardware. */ | 1486 | /* Depth last, update the hardware. */ |
1505 | list_for_each_entry(bus, &pci_root_buses, node) | 1487 | pci_enable_bridges(bus); |
1506 | pci_enable_bridges(bus); | ||
1507 | 1488 | ||
1508 | /* dump the resource on buses */ | 1489 | /* dump the resource on buses */ |
1509 | list_for_each_entry(bus, &pci_root_buses, node) | 1490 | pci_bus_dump_resources(bus); |
1510 | pci_bus_dump_resources(bus); | 1491 | } |
1492 | |||
1493 | void __init pci_assign_unassigned_resources(void) | ||
1494 | { | ||
1495 | struct pci_bus *root_bus; | ||
1496 | |||
1497 | list_for_each_entry(root_bus, &pci_root_buses, node) | ||
1498 | pci_assign_unassigned_root_bus_resources(root_bus); | ||
1511 | } | 1499 | } |
1512 | 1500 | ||
1513 | void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge) | 1501 | void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge) |