[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250822145605.18172-8-ilpo.jarvinen@linux.intel.com>
Date: Fri, 22 Aug 2025 17:55:48 +0300
From: Ilpo Järvinen <ilpo.jarvinen@...ux.intel.com>
To: Andreas Larsson <andreas@...sler.com>,
Bjorn Helgaas <bhelgaas@...gle.com>,
"David S. Miller" <davem@...emloft.net>,
Geert Uytterhoeven <geert@...ux-m68k.org>,
linux-m68k@...ts.linux-m68k.org,
linux-mips@...r.kernel.org,
linux-pci@...r.kernel.org,
sparclinux@...r.kernel.org,
Thomas Bogendoerfer <tsbogend@...ha.franken.de>,
Christian König <christian.koenig@....com>,
Yinghai Lu <yinghai@...nel.org>,
Igor Mammedov <imammedo@...hat.com>,
"Rafael J . Wysocki" <rafael@...nel.org>,
Jonathan Cameron <Jonathan.Cameron@...wei.com>,
Lorenzo Pieralisi <lorenzo.pieralisi@....com>,
Krzysztof Wilczyński <kw@...ux.com>,
linux-kernel@...r.kernel.org
Cc: Michał Winiarski <michal.winiarski@...el.com>,
linuxppc-dev@...ts.ozlabs.org,
Ilpo Järvinen <ilpo.jarvinen@...ux.intel.com>
Subject: [PATCH 07/24] PCI: Disable non-claimed bridge window
If clipping or claiming the bridge window fails, the bridge window is
left into a state that does not match with the kernel's view on what
the bridge window is.
Disable the bridge window by writing the magic disable value into the
Base and Limit Registers if clipping or claiming failed. To detect if
claiming the resource was successful, add res->parent checks into the
bridge setup functions.
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@...ux.intel.com>
---
drivers/pci/setup-bus.c | 25 ++++++++++++-------------
1 file changed, 12 insertions(+), 13 deletions(-)
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index b477f68b236c..6bdc1af887da 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -660,7 +660,7 @@ void pci_setup_cardbus(struct pci_bus *bus)
res = bus->resource[0];
pcibios_resource_to_bus(bridge->bus, ®ion, res);
- if (res->flags & IORESOURCE_IO) {
+ if (res->parent && res->flags & IORESOURCE_IO) {
/*
* The IO resource is allocated a range twice as large as it
* would normally need. This allows us to set both IO regs.
@@ -674,7 +674,7 @@ void pci_setup_cardbus(struct pci_bus *bus)
res = bus->resource[1];
pcibios_resource_to_bus(bridge->bus, ®ion, res);
- if (res->flags & IORESOURCE_IO) {
+ if (res->parent && res->flags & IORESOURCE_IO) {
pci_info(bridge, " bridge window %pR\n", res);
pci_write_config_dword(bridge, PCI_CB_IO_BASE_1,
region.start);
@@ -684,7 +684,7 @@ void pci_setup_cardbus(struct pci_bus *bus)
res = bus->resource[2];
pcibios_resource_to_bus(bridge->bus, ®ion, res);
- if (res->flags & IORESOURCE_MEM) {
+ if (res->parent && res->flags & IORESOURCE_MEM) {
pci_info(bridge, " bridge window %pR\n", res);
pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0,
region.start);
@@ -694,7 +694,7 @@ void pci_setup_cardbus(struct pci_bus *bus)
res = bus->resource[3];
pcibios_resource_to_bus(bridge->bus, ®ion, res);
- if (res->flags & IORESOURCE_MEM) {
+ if (res->parent && res->flags & IORESOURCE_MEM) {
pci_info(bridge, " bridge window %pR\n", res);
pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1,
region.start);
@@ -735,7 +735,7 @@ static void pci_setup_bridge_io(struct pci_dev *bridge)
res = &bridge->resource[PCI_BRIDGE_IO_WINDOW];
res_name = pci_resource_name(bridge, PCI_BRIDGE_IO_WINDOW);
pcibios_resource_to_bus(bridge->bus, ®ion, res);
- if (res->flags & IORESOURCE_IO) {
+ if (res->parent && res->flags & IORESOURCE_IO) {
pci_read_config_word(bridge, PCI_IO_BASE, &l);
io_base_lo = (region.start >> 8) & io_mask;
io_limit_lo = (region.end >> 8) & io_mask;
@@ -767,7 +767,7 @@ static void pci_setup_bridge_mmio(struct pci_dev *bridge)
res = &bridge->resource[PCI_BRIDGE_MEM_WINDOW];
res_name = pci_resource_name(bridge, PCI_BRIDGE_MEM_WINDOW);
pcibios_resource_to_bus(bridge->bus, ®ion, res);
- if (res->flags & IORESOURCE_MEM) {
+ if (res->parent && res->flags & IORESOURCE_MEM) {
l = (region.start >> 16) & 0xfff0;
l |= region.end & 0xfff00000;
pci_info(bridge, " %s %pR\n", res_name, res);
@@ -796,7 +796,7 @@ static void pci_setup_bridge_mmio_pref(struct pci_dev *bridge)
res = &bridge->resource[PCI_BRIDGE_PREF_MEM_WINDOW];
res_name = pci_resource_name(bridge, PCI_BRIDGE_PREF_MEM_WINDOW);
pcibios_resource_to_bus(bridge->bus, ®ion, res);
- if (res->flags & IORESOURCE_PREFETCH) {
+ if (res->parent && res->flags & IORESOURCE_PREFETCH) {
l = (region.start >> 16) & 0xfff0;
l |= region.end & 0xfff00000;
if (res->flags & IORESOURCE_MEM_64) {
@@ -848,6 +848,8 @@ static void pci_setup_bridge(struct pci_bus *bus)
int pci_claim_bridge_resource(struct pci_dev *bridge, int i)
{
+ int ret = -EINVAL;
+
if (i < PCI_BRIDGE_RESOURCES || i > PCI_BRIDGE_RESOURCE_END)
return 0;
@@ -861,11 +863,8 @@ int pci_claim_bridge_resource(struct pci_dev *bridge, int i)
return -EINVAL;
/* Try to clip the resource and claim the smaller window */
- if (!pci_bus_clip_resource(bridge, i))
- return -EINVAL; /* Clipping didn't change anything */
-
- if (!pci_claim_resource(bridge, i))
- return -EINVAL;
+ if (pci_bus_clip_resource(bridge, i))
+ ret = pci_claim_resource(bridge, i);
switch (i) {
case PCI_BRIDGE_IO_WINDOW:
@@ -881,7 +880,7 @@ int pci_claim_bridge_resource(struct pci_dev *bridge, int i)
return -EINVAL;
}
- return 0;
+ return ret;
}
/*
--
2.39.5
Powered by blists - more mailing lists