Skip to content

Commit 99e2c73

Browse files
committed
Merge branch 'pci/resource'
- Distribute resources to unconfigured hotplug bridges at boot-time (not just when hot-adding such a bridge), which makes hot-adding devices to docks work (Mika Westerberg) - Fix the "revert to firmware assignment" code so we do the revert only if the address is actually reachable. Previously we sometimes assigned addresses that could not be reached via upstream bridges (Maciej W. Rozycki) * pci/resource: PCI: Sanitise firmware BAR assignments behind a PCI-PCI bridge PCI: Fix typo in pci_scan_child_bus_extend() PCI: Fix whitespace and indentation PCI: Distribute available resources for root buses, too PCI: Move pci_assign_unassigned_root_bus_resources() PCI: Pass available buses even if the bridge is already configured PCI: Fix used_buses calculation in pci_scan_child_bus_extend()
2 parents c3acb56 + 0e32818 commit 99e2c73

File tree

3 files changed

+192
-122
lines changed

3 files changed

+192
-122
lines changed

drivers/pci/probe.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,7 +1297,7 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
12971297

12981298
if ((secondary || subordinate) && !pcibios_assign_all_busses() &&
12991299
!is_cardbus && !broken) {
1300-
unsigned int cmax;
1300+
unsigned int cmax, buses;
13011301

13021302
/*
13031303
* Bus already configured by firmware, process it in the
@@ -1322,7 +1322,8 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
13221322
child->bridge_ctl = bctl;
13231323
}
13241324

1325-
cmax = pci_scan_child_bus(child);
1325+
buses = subordinate - secondary;
1326+
cmax = pci_scan_child_bus_extend(child, buses);
13261327
if (cmax > subordinate)
13271328
pci_warn(dev, "bridge has subordinate %02x but max busn %02x\n",
13281329
subordinate, cmax);
@@ -2920,16 +2921,15 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus,
29202921
* hotplug bridges too much during the second scan below.
29212922
*/
29222923
used_buses++;
2923-
if (cmax - max > 1)
2924-
used_buses += cmax - max - 1;
2924+
if (max - cmax > 1)
2925+
used_buses += max - cmax - 1;
29252926
}
29262927

29272928
/* Scan bridges that need to be reconfigured */
29282929
for_each_pci_bridge(dev, bus) {
29292930
unsigned int buses = 0;
29302931

29312932
if (!hotplug_bridges && normal_bridges == 1) {
2932-
29332933
/*
29342934
* There is only one bridge on the bus (upstream
29352935
* port) so it gets all available buses which it
@@ -2938,7 +2938,6 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus,
29382938
*/
29392939
buses = available_buses;
29402940
} else if (dev->is_hotplug_bridge) {
2941-
29422941
/*
29432942
* Distribute the extra buses between hotplug
29442943
* bridges if any.
@@ -2957,7 +2956,7 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus,
29572956
/*
29582957
* Make sure a hotplug bridge has at least the minimum requested
29592958
* number of buses but allow it to grow up to the maximum available
2960-
* bus number of there is room.
2959+
* bus number if there is room.
29612960
*/
29622961
if (bus->self && bus->self->is_hotplug_bridge) {
29632962
used_buses = max_t(unsigned int, available_buses,

drivers/pci/setup-bus.c

Lines changed: 175 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1745,119 +1745,6 @@ static enum enable_type pci_realloc_detect(struct pci_bus *bus,
17451745
}
17461746
#endif
17471747

1748-
/*
1749-
* First try will not touch PCI bridge res.
1750-
* Second and later try will clear small leaf bridge res.
1751-
* Will stop till to the max depth if can not find good one.
1752-
*/
1753-
void pci_assign_unassigned_root_bus_resources(struct pci_bus *bus)
1754-
{
1755-
LIST_HEAD(realloc_head);
1756-
/* List of resources that want additional resources */
1757-
struct list_head *add_list = NULL;
1758-
int tried_times = 0;
1759-
enum release_type rel_type = leaf_only;
1760-
LIST_HEAD(fail_head);
1761-
struct pci_dev_resource *fail_res;
1762-
int pci_try_num = 1;
1763-
enum enable_type enable_local;
1764-
1765-
/* Don't realloc if asked to do so */
1766-
enable_local = pci_realloc_detect(bus, pci_realloc_enable);
1767-
if (pci_realloc_enabled(enable_local)) {
1768-
int max_depth = pci_bus_get_depth(bus);
1769-
1770-
pci_try_num = max_depth + 1;
1771-
dev_info(&bus->dev, "max bus depth: %d pci_try_num: %d\n",
1772-
max_depth, pci_try_num);
1773-
}
1774-
1775-
again:
1776-
/*
1777-
* Last try will use add_list, otherwise will try good to have as must
1778-
* have, so can realloc parent bridge resource
1779-
*/
1780-
if (tried_times + 1 == pci_try_num)
1781-
add_list = &realloc_head;
1782-
/*
1783-
* Depth first, calculate sizes and alignments of all subordinate buses.
1784-
*/
1785-
__pci_bus_size_bridges(bus, add_list);
1786-
1787-
/* Depth last, allocate resources and update the hardware. */
1788-
__pci_bus_assign_resources(bus, add_list, &fail_head);
1789-
if (add_list)
1790-
BUG_ON(!list_empty(add_list));
1791-
tried_times++;
1792-
1793-
/* Any device complain? */
1794-
if (list_empty(&fail_head))
1795-
goto dump;
1796-
1797-
if (tried_times >= pci_try_num) {
1798-
if (enable_local == undefined)
1799-
dev_info(&bus->dev, "Some PCI device resources are unassigned, try booting with pci=realloc\n");
1800-
else if (enable_local == auto_enabled)
1801-
dev_info(&bus->dev, "Automatically enabled pci realloc, if you have problem, try booting with pci=realloc=off\n");
1802-
1803-
free_list(&fail_head);
1804-
goto dump;
1805-
}
1806-
1807-
dev_info(&bus->dev, "No. %d try to assign unassigned res\n",
1808-
tried_times + 1);
1809-
1810-
/* Third times and later will not check if it is leaf */
1811-
if ((tried_times + 1) > 2)
1812-
rel_type = whole_subtree;
1813-
1814-
/*
1815-
* Try to release leaf bridge's resources that doesn't fit resource of
1816-
* child device under that bridge.
1817-
*/
1818-
list_for_each_entry(fail_res, &fail_head, list)
1819-
pci_bus_release_bridge_resources(fail_res->dev->bus,
1820-
fail_res->flags & PCI_RES_TYPE_MASK,
1821-
rel_type);
1822-
1823-
/* Restore size and flags */
1824-
list_for_each_entry(fail_res, &fail_head, list) {
1825-
struct resource *res = fail_res->res;
1826-
int idx;
1827-
1828-
res->start = fail_res->start;
1829-
res->end = fail_res->end;
1830-
res->flags = fail_res->flags;
1831-
1832-
if (pci_is_bridge(fail_res->dev)) {
1833-
idx = res - &fail_res->dev->resource[0];
1834-
if (idx >= PCI_BRIDGE_RESOURCES &&
1835-
idx <= PCI_BRIDGE_RESOURCE_END)
1836-
res->flags = 0;
1837-
}
1838-
}
1839-
free_list(&fail_head);
1840-
1841-
goto again;
1842-
1843-
dump:
1844-
/* Dump the resource on buses */
1845-
pci_bus_dump_resources(bus);
1846-
}
1847-
1848-
void __init pci_assign_unassigned_resources(void)
1849-
{
1850-
struct pci_bus *root_bus;
1851-
1852-
list_for_each_entry(root_bus, &pci_root_buses, node) {
1853-
pci_assign_unassigned_root_bus_resources(root_bus);
1854-
1855-
/* Make sure the root bridge has a companion ACPI device */
1856-
if (ACPI_HANDLE(root_bus->bridge))
1857-
acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
1858-
}
1859-
}
1860-
18611748
static void adjust_bridge_window(struct pci_dev *bridge, struct resource *res,
18621749
struct list_head *add_list,
18631750
resource_size_t new_size)
@@ -1881,7 +1768,10 @@ static void adjust_bridge_window(struct pci_dev *bridge, struct resource *res,
18811768
}
18821769

18831770
res->end = res->start + new_size - 1;
1884-
remove_from_list(add_list, res);
1771+
1772+
/* If the resource is part of the add_list remove it now */
1773+
if (add_list)
1774+
remove_from_list(add_list, res);
18851775
}
18861776

18871777
static void pci_bus_distribute_available_resources(struct pci_bus *bus,
@@ -2029,13 +1919,15 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus,
20291919
}
20301920

20311921
static void pci_bridge_distribute_available_resources(struct pci_dev *bridge,
2032-
struct list_head *add_list)
1922+
struct list_head *add_list)
20331923
{
20341924
struct resource available_io, available_mmio, available_mmio_pref;
20351925

20361926
if (!bridge->is_hotplug_bridge)
20371927
return;
20381928

1929+
pci_dbg(bridge, "distributing available resources\n");
1930+
20391931
/* Take the initial extra resources from the hotplug port */
20401932
available_io = bridge->resource[PCI_BRIDGE_IO_WINDOW];
20411933
available_mmio = bridge->resource[PCI_BRIDGE_MEM_WINDOW];
@@ -2047,6 +1939,174 @@ static void pci_bridge_distribute_available_resources(struct pci_dev *bridge,
20471939
available_mmio_pref);
20481940
}
20491941

1942+
static bool pci_bridge_resources_not_assigned(struct pci_dev *dev)
1943+
{
1944+
const struct resource *r;
1945+
1946+
/*
1947+
* Check the child device's resources and if they are not yet
1948+
* assigned it means we are configuring them (not the boot
1949+
* firmware) so we should be able to extend the upstream
1950+
* bridge's (that's the hotplug downstream PCIe port) resources
1951+
* in the same way we do with the normal hotplug case.
1952+
*/
1953+
r = &dev->resource[PCI_BRIDGE_IO_WINDOW];
1954+
if (!r->flags || !(r->flags & IORESOURCE_STARTALIGN))
1955+
return false;
1956+
r = &dev->resource[PCI_BRIDGE_MEM_WINDOW];
1957+
if (!r->flags || !(r->flags & IORESOURCE_STARTALIGN))
1958+
return false;
1959+
r = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
1960+
if (!r->flags || !(r->flags & IORESOURCE_STARTALIGN))
1961+
return false;
1962+
1963+
return true;
1964+
}
1965+
1966+
static void pci_root_bus_distribute_available_resources(struct pci_bus *bus,
1967+
struct list_head *add_list)
1968+
{
1969+
struct pci_dev *dev, *bridge = bus->self;
1970+
1971+
for_each_pci_bridge(dev, bus) {
1972+
struct pci_bus *b;
1973+
1974+
b = dev->subordinate;
1975+
if (!b)
1976+
continue;
1977+
1978+
/*
1979+
* Need to check "bridge" here too because it is NULL
1980+
* in case of root bus.
1981+
*/
1982+
if (bridge && pci_bridge_resources_not_assigned(dev)) {
1983+
pci_bridge_distribute_available_resources(bridge, add_list);
1984+
/*
1985+
* There is only PCIe upstream port on the bus
1986+
* so we don't need to go futher.
1987+
*/
1988+
return;
1989+
}
1990+
1991+
pci_root_bus_distribute_available_resources(b, add_list);
1992+
}
1993+
}
1994+
1995+
/*
1996+
* First try will not touch PCI bridge res.
1997+
* Second and later try will clear small leaf bridge res.
1998+
* Will stop till to the max depth if can not find good one.
1999+
*/
2000+
void pci_assign_unassigned_root_bus_resources(struct pci_bus *bus)
2001+
{
2002+
LIST_HEAD(realloc_head);
2003+
/* List of resources that want additional resources */
2004+
struct list_head *add_list = NULL;
2005+
int tried_times = 0;
2006+
enum release_type rel_type = leaf_only;
2007+
LIST_HEAD(fail_head);
2008+
struct pci_dev_resource *fail_res;
2009+
int pci_try_num = 1;
2010+
enum enable_type enable_local;
2011+
2012+
/* Don't realloc if asked to do so */
2013+
enable_local = pci_realloc_detect(bus, pci_realloc_enable);
2014+
if (pci_realloc_enabled(enable_local)) {
2015+
int max_depth = pci_bus_get_depth(bus);
2016+
2017+
pci_try_num = max_depth + 1;
2018+
dev_info(&bus->dev, "max bus depth: %d pci_try_num: %d\n",
2019+
max_depth, pci_try_num);
2020+
}
2021+
2022+
again:
2023+
/*
2024+
* Last try will use add_list, otherwise will try good to have as must
2025+
* have, so can realloc parent bridge resource
2026+
*/
2027+
if (tried_times + 1 == pci_try_num)
2028+
add_list = &realloc_head;
2029+
/*
2030+
* Depth first, calculate sizes and alignments of all subordinate buses.
2031+
*/
2032+
__pci_bus_size_bridges(bus, add_list);
2033+
2034+
pci_root_bus_distribute_available_resources(bus, add_list);
2035+
2036+
/* Depth last, allocate resources and update the hardware. */
2037+
__pci_bus_assign_resources(bus, add_list, &fail_head);
2038+
if (add_list)
2039+
BUG_ON(!list_empty(add_list));
2040+
tried_times++;
2041+
2042+
/* Any device complain? */
2043+
if (list_empty(&fail_head))
2044+
goto dump;
2045+
2046+
if (tried_times >= pci_try_num) {
2047+
if (enable_local == undefined)
2048+
dev_info(&bus->dev, "Some PCI device resources are unassigned, try booting with pci=realloc\n");
2049+
else if (enable_local == auto_enabled)
2050+
dev_info(&bus->dev, "Automatically enabled pci realloc, if you have problem, try booting with pci=realloc=off\n");
2051+
2052+
free_list(&fail_head);
2053+
goto dump;
2054+
}
2055+
2056+
dev_info(&bus->dev, "No. %d try to assign unassigned res\n",
2057+
tried_times + 1);
2058+
2059+
/* Third times and later will not check if it is leaf */
2060+
if ((tried_times + 1) > 2)
2061+
rel_type = whole_subtree;
2062+
2063+
/*
2064+
* Try to release leaf bridge's resources that doesn't fit resource of
2065+
* child device under that bridge.
2066+
*/
2067+
list_for_each_entry(fail_res, &fail_head, list)
2068+
pci_bus_release_bridge_resources(fail_res->dev->bus,
2069+
fail_res->flags & PCI_RES_TYPE_MASK,
2070+
rel_type);
2071+
2072+
/* Restore size and flags */
2073+
list_for_each_entry(fail_res, &fail_head, list) {
2074+
struct resource *res = fail_res->res;
2075+
int idx;
2076+
2077+
res->start = fail_res->start;
2078+
res->end = fail_res->end;
2079+
res->flags = fail_res->flags;
2080+
2081+
if (pci_is_bridge(fail_res->dev)) {
2082+
idx = res - &fail_res->dev->resource[0];
2083+
if (idx >= PCI_BRIDGE_RESOURCES &&
2084+
idx <= PCI_BRIDGE_RESOURCE_END)
2085+
res->flags = 0;
2086+
}
2087+
}
2088+
free_list(&fail_head);
2089+
2090+
goto again;
2091+
2092+
dump:
2093+
/* Dump the resource on buses */
2094+
pci_bus_dump_resources(bus);
2095+
}
2096+
2097+
void __init pci_assign_unassigned_resources(void)
2098+
{
2099+
struct pci_bus *root_bus;
2100+
2101+
list_for_each_entry(root_bus, &pci_root_buses, node) {
2102+
pci_assign_unassigned_root_bus_resources(root_bus);
2103+
2104+
/* Make sure the root bridge has a companion ACPI device */
2105+
if (ACPI_HANDLE(root_bus->bridge))
2106+
acpi_ioapic_add(ACPI_HANDLE(root_bus->bridge));
2107+
}
2108+
}
2109+
20502110
void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
20512111
{
20522112
struct pci_bus *parent = bridge->subordinate;

drivers/pci/setup-res.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,17 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev,
214214

215215
root = pci_find_parent_resource(dev, res);
216216
if (!root) {
217+
/*
218+
* If dev is behind a bridge, accesses will only reach it
219+
* if res is inside the relevant bridge window.
220+
*/
221+
if (pci_upstream_bridge(dev))
222+
return -ENXIO;
223+
224+
/*
225+
* On the root bus, assume the host bridge will forward
226+
* everything.
227+
*/
217228
if (res->flags & IORESOURCE_IO)
218229
root = &ioport_resource;
219230
else

0 commit comments

Comments
 (0)