Skip to content

Commit 159fbfd

Browse files
ij-intelbjorn-helgaas
authored andcommitted
PCI: Pass bridge window to pci_bus_release_bridge_resources()
pci_bus_release_bridge_resources() takes type, which is converted into a bridge window resource in pci_bridge_release_resources(). Find out the correct bridge window for resource whose assignment failed. Pass that bridge window to pci_bus_release_bridge_resources() instead of passing the type. When recursing to subordinate, check which bridge windows have to be released and recurse for each. For now, use pbus_select_window_for_type() instead of pbus_select_window() because non-bridge window resources still have their flags reset which destroys the type information from the struct resource. The struct pci_dev_resource holds a copy of the flags which are used instead. Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Link: https://patch.msgid.link/20250829131113.36754-24-ilpo.jarvinen@linux.intel.com
1 parent ebbebd8 commit 159fbfd

File tree

1 file changed

+27
-42
lines changed

1 file changed

+27
-42
lines changed

drivers/pci/setup-bus.c

Lines changed: 27 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1800,51 +1800,24 @@ static void __pci_bridge_assign_resources(const struct pci_dev *bridge,
18001800
}
18011801

18021802
static void pci_bridge_release_resources(struct pci_bus *bus,
1803-
unsigned long type)
1803+
struct resource *b_win)
18041804
{
18051805
struct pci_dev *dev = bus->self;
1806-
struct resource *r;
1807-
struct resource *b_res;
18081806
int idx, ret;
18091807

1810-
b_res = &dev->resource[PCI_BRIDGE_RESOURCES];
1811-
1812-
/*
1813-
* 1. If IO port assignment fails, release bridge IO port.
1814-
* 2. If non pref MMIO assignment fails, release bridge nonpref MMIO.
1815-
* 3. If 64bit pref MMIO assignment fails, and bridge pref is 64bit,
1816-
* release bridge pref MMIO.
1817-
* 4. If pref MMIO assignment fails, and bridge pref is 32bit,
1818-
* release bridge pref MMIO.
1819-
* 5. If pref MMIO assignment fails, and bridge pref is not
1820-
* assigned, release bridge nonpref MMIO.
1821-
*/
1822-
if (type & IORESOURCE_IO)
1823-
idx = 0;
1824-
else if (!(type & IORESOURCE_PREFETCH))
1825-
idx = 1;
1826-
else if ((type & IORESOURCE_MEM_64) &&
1827-
(b_res[2].flags & IORESOURCE_MEM_64))
1828-
idx = 2;
1829-
else if (!(b_res[2].flags & IORESOURCE_MEM_64) &&
1830-
(b_res[2].flags & IORESOURCE_PREFETCH))
1831-
idx = 2;
1832-
else
1833-
idx = 1;
1834-
1835-
r = &b_res[idx];
1836-
1837-
if (!r->parent)
1808+
if (!b_win->parent)
18381809
return;
18391810

1811+
idx = pci_resource_num(dev, b_win);
1812+
18401813
/* If there are children, release them all */
1841-
release_child_resources(r);
1814+
release_child_resources(b_win);
18421815

1843-
ret = pci_release_resource(dev, PCI_BRIDGE_RESOURCES + idx);
1816+
ret = pci_release_resource(dev, idx);
18441817
if (ret)
18451818
return;
18461819

1847-
pci_setup_one_bridge_window(dev, PCI_BRIDGE_RESOURCES + idx);
1820+
pci_setup_one_bridge_window(dev, idx);
18481821
}
18491822

18501823
enum release_type {
@@ -1857,14 +1830,16 @@ enum release_type {
18571830
* a larger window later.
18581831
*/
18591832
static void pci_bus_release_bridge_resources(struct pci_bus *bus,
1860-
unsigned long type,
1833+
struct resource *b_win,
18611834
enum release_type rel_type)
18621835
{
18631836
struct pci_dev *dev;
18641837
bool is_leaf_bridge = true;
18651838

18661839
list_for_each_entry(dev, &bus->devices, bus_list) {
18671840
struct pci_bus *b = dev->subordinate;
1841+
struct resource *res;
1842+
18681843
if (!b)
18691844
continue;
18701845

@@ -1873,9 +1848,15 @@ static void pci_bus_release_bridge_resources(struct pci_bus *bus,
18731848
if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
18741849
continue;
18751850

1876-
if (rel_type == whole_subtree)
1877-
pci_bus_release_bridge_resources(b, type,
1878-
whole_subtree);
1851+
if (rel_type != whole_subtree)
1852+
continue;
1853+
1854+
pci_bus_for_each_resource(b, res) {
1855+
if (res->parent != b_win)
1856+
continue;
1857+
1858+
pci_bus_release_bridge_resources(b, res, whole_subtree);
1859+
}
18791860
}
18801861

18811862
if (pci_is_root_bus(bus))
@@ -1885,7 +1866,7 @@ static void pci_bus_release_bridge_resources(struct pci_bus *bus,
18851866
return;
18861867

18871868
if ((rel_type == whole_subtree) || is_leaf_bridge)
1888-
pci_bridge_release_resources(bus, type);
1869+
pci_bridge_release_resources(bus, b_win);
18891870
}
18901871

18911872
static void pci_bus_dump_res(struct pci_bus *bus)
@@ -2282,9 +2263,13 @@ static void pci_prepare_next_assign_round(struct list_head *fail_head,
22822263
* enough to contain child device resources.
22832264
*/
22842265
list_for_each_entry(fail_res, fail_head, list) {
2285-
pci_bus_release_bridge_resources(fail_res->dev->bus,
2286-
fail_res->flags & PCI_RES_TYPE_MASK,
2287-
rel_type);
2266+
struct pci_bus *bus = fail_res->dev->bus;
2267+
struct resource *b_win;
2268+
2269+
b_win = pbus_select_window_for_type(bus, fail_res->flags);
2270+
if (!b_win)
2271+
continue;
2272+
pci_bus_release_bridge_resources(bus, b_win, rel_type);
22882273
}
22892274

22902275
/* Restore size and flags */

0 commit comments

Comments
 (0)