Skip to content

Commit bdb3235

Browse files
ij-intelbjorn-helgaas
authored andcommitted
sparc/PCI: Correct 64-bit non-pref -> pref BAR resources
SPARC T5-2 dts describes some PCI BARs as 64-bit resources without the pref(etchable) bit (0x83... vs 0xc3... in assigned-addresses) for address ranges above the 4G threshold. Such resources cannot be placed into a non-prefetchable PCI bridge window that is capable only of 32-bit addressing. As such, it looks like the platform is improperly described by the dts. The kernel detects this problem (see the IORESOURCE_PREFETCH check in pci_find_parent_resource()) and fails to assign these BAR resources to the resource tree due to lack of a compatible bridge window. Prior to 754baba ("sparc/PCI: Remove pcibios_enable_device() as they do nothing extra") SPARC arch code did not test whether device resources were successfully in the resource tree when enabling a device, effectively hiding the problem. After removing the arch-specific enable code, pci_enable_resources() refuses to enable the device when it finds not all mem resources are assigned, and therefore mpt3sas can't be enabled: pci 0001:04:00.0: reg 0x14: [mem 0x801110000000-0x80111000ffff 64bit] pci 0001:04:00.0: reg 0x1c: [mem 0x801110040000-0x80111007ffff 64bit] pci 0001:04:00.0: BAR 1 [mem 0x801110000000-0x80111000ffff 64bit]: can't claim; no compatible bridge window pci 0001:04:00.0: BAR 3 [mem 0x801110040000-0x80111007ffff 64bit]: can't claim; no compatible bridge window mpt3sas 0001:04:00.0: BAR 1 [mem size 0x00010000 64bit]: not assigned; can't enable device For clarity, this filtered log only shows failures for one mpt3sas device but other devices fail similarly. In the reported case, the end result with all the failures is an unbootable system. Things appeared to "work" before 754baba ("sparc/PCI: Remove pcibios_enable_device() as they do nothing extra") because the resource tree is agnostic to whether PCI BAR resources are properly in the tree or not. So as long as there was a parent resource (e.g. a root bus resource) that contains the address range, the resource tree code just places resource request underneath it without any consideration to the intermediate BAR resource. While it worked, it's incorrect setup still. Add an OF fixup to set the IORESOURCE_PREFETCH flag for a 64-bit PCI resource that has the end address above 4G requiring placement into the prefetchable window. Also log the issue. Fixes: 754baba ("sparc/PCI: Remove pcibios_enable_device() as they do nothing extra") Reported-by: Nathaniel Roach <nroach44@gmail.com> Closes: sparclinux/issues#22 Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Tested-by: Nathaniel Roach <nroach44@gmail.com> Link: https://patch.msgid.link/20251124170411.3709-1-ilpo.jarvinen@linux.intel.com
1 parent df27c03 commit bdb3235

1 file changed

Lines changed: 23 additions & 0 deletions

File tree

arch/sparc/kernel/pci.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,28 @@ static int __init ofpci_debug(char *str)
181181

182182
__setup("ofpci_debug=", ofpci_debug);
183183

184+
static void of_fixup_pci_pref(struct pci_dev *dev, int index,
185+
struct resource *res)
186+
{
187+
struct pci_bus_region region;
188+
189+
if (!(res->flags & IORESOURCE_MEM_64))
190+
return;
191+
192+
if (!resource_size(res))
193+
return;
194+
195+
pcibios_resource_to_bus(dev->bus, &region, res);
196+
if (region.end <= ~((u32)0))
197+
return;
198+
199+
if (!(res->flags & IORESOURCE_PREFETCH)) {
200+
res->flags |= IORESOURCE_PREFETCH;
201+
pci_info(dev, "reg 0x%x: fixup: pref added to 64-bit resource\n",
202+
index);
203+
}
204+
}
205+
184206
static unsigned long pci_parse_of_flags(u32 addr0)
185207
{
186208
unsigned long flags = 0;
@@ -244,6 +266,7 @@ static void pci_parse_of_addrs(struct platform_device *op,
244266
res->end = op_res->end;
245267
res->flags = flags;
246268
res->name = pci_name(dev);
269+
of_fixup_pci_pref(dev, i, res);
247270

248271
pci_info(dev, "reg 0x%x: %pR\n", i, res);
249272
}

0 commit comments

Comments
 (0)