Commit 67d29b5c authored by Bjorn Helgaas's avatar Bjorn Helgaas

PCI: Add resource allocation comments

Add comments in the code to match the allocation strategy of 7c671426dfc3
("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources").

No functional change.
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
parent d3689df0
...@@ -1164,17 +1164,16 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus, ...@@ -1164,17 +1164,16 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus,
additional_io_size = pci_hotplug_io_size; additional_io_size = pci_hotplug_io_size;
additional_mem_size = pci_hotplug_mem_size; additional_mem_size = pci_hotplug_mem_size;
} }
/* /* Fall through */
* Follow thru
*/
default: default:
pbus_size_io(bus, realloc_head ? 0 : additional_io_size, pbus_size_io(bus, realloc_head ? 0 : additional_io_size,
additional_io_size, realloc_head); additional_io_size, realloc_head);
/* If the bridge supports prefetchable range, size it
separately. If it doesn't, or its prefetchable window /*
has already been allocated by arch code, try * If there's a 64-bit prefetchable MMIO window, compute
non-prefetchable range for both types of PCI memory * the size required to put all 64-bit prefetchable
resources. */ * resources in it.
*/
b_res = &bus->self->resource[PCI_BRIDGE_RESOURCES]; b_res = &bus->self->resource[PCI_BRIDGE_RESOURCES];
mask = IORESOURCE_MEM; mask = IORESOURCE_MEM;
prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH; prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH;
...@@ -1184,29 +1183,58 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus, ...@@ -1184,29 +1183,58 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus,
prefmask, prefmask, prefmask, prefmask,
realloc_head ? 0 : additional_mem_size, realloc_head ? 0 : additional_mem_size,
additional_mem_size, realloc_head); additional_mem_size, realloc_head);
if (ret == 0) {
/* /*
* Success, with pref mmio64, * If successful, all non-prefetchable resources
* next will size non-pref or * and any 32-bit prefetchable resources will go in
* non-mmio64 */ * the non-prefetchable window.
*/
if (ret == 0) {
mask = prefmask; mask = prefmask;
type2 = prefmask & ~IORESOURCE_MEM_64; type2 = prefmask & ~IORESOURCE_MEM_64;
type3 = prefmask & ~IORESOURCE_PREFETCH; type3 = prefmask & ~IORESOURCE_PREFETCH;
} }
} }
/*
* If there is no 64-bit prefetchable window, compute the
* size required to put all prefetchable resources in the
* 32-bit prefetchable window (if there is one).
*/
if (!type2) { if (!type2) {
prefmask &= ~IORESOURCE_MEM_64; prefmask &= ~IORESOURCE_MEM_64;
ret = pbus_size_mem(bus, prefmask, prefmask, ret = pbus_size_mem(bus, prefmask, prefmask,
prefmask, prefmask, prefmask, prefmask,
realloc_head ? 0 : additional_mem_size, realloc_head ? 0 : additional_mem_size,
additional_mem_size, realloc_head); additional_mem_size, realloc_head);
if (ret == 0) {
/* Success, next will size non-prefetch. */ /*
* If successful, only non-prefetchable resources
* will go in the non-prefetchable window.
*/
if (ret == 0)
mask = prefmask; mask = prefmask;
} else else
additional_mem_size += additional_mem_size; additional_mem_size += additional_mem_size;
type2 = type3 = IORESOURCE_MEM; type2 = type3 = IORESOURCE_MEM;
} }
/*
* Compute the size required to put everything else in the
* non-prefetchable window. This includes:
*
* - all non-prefetchable resources
* - 32-bit prefetchable resources if there's a 64-bit
* prefetchable window or no prefetchable window at all
* - 64-bit prefetchable resources if there's no
* prefetchable window at all
*
* Note that the strategy in __pci_assign_resource() must
* match that used here. Specifically, we cannot put a
* 32-bit prefetchable resource in a 64-bit prefetchable
* window.
*/
pbus_size_mem(bus, mask, IORESOURCE_MEM, type2, type3, pbus_size_mem(bus, mask, IORESOURCE_MEM, type2, type3,
realloc_head ? 0 : additional_mem_size, realloc_head ? 0 : additional_mem_size,
additional_mem_size, realloc_head); additional_mem_size, realloc_head);
......
...@@ -209,20 +209,25 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, ...@@ -209,20 +209,25 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
/* First, try exact prefetching match.. */ /*
* First, try exact prefetching match. Even if a 64-bit
* prefetchable bridge window is below 4GB, we can't put a 32-bit
* prefetchable resource in it because pbus_size_mem() assumes a
* 64-bit window will contain no 32-bit resources. If we assign
* things differently than they were sized, not everything will fit.
*/
ret = pci_bus_alloc_resource(bus, res, size, align, min, ret = pci_bus_alloc_resource(bus, res, size, align, min,
IORESOURCE_PREFETCH | IORESOURCE_MEM_64, IORESOURCE_PREFETCH | IORESOURCE_MEM_64,
pcibios_align_resource, dev); pcibios_align_resource, dev);
if (ret == 0) if (ret == 0)
return 0; return 0;
if ((res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) ==
(IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) {
/* /*
* That failed. * If the prefetchable window is only 32 bits wide, we can put
* * 64-bit prefetchable resources in it.
* Try 32bit pref
*/ */
if ((res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) ==
(IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) {
ret = pci_bus_alloc_resource(bus, res, size, align, min, ret = pci_bus_alloc_resource(bus, res, size, align, min,
IORESOURCE_PREFETCH, IORESOURCE_PREFETCH,
pcibios_align_resource, dev); pcibios_align_resource, dev);
...@@ -230,18 +235,16 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, ...@@ -230,18 +235,16 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
return 0; return 0;
} }
if (res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) {
/* /*
* That failed. * If we didn't find a better match, we can put any memory resource
* * in a non-prefetchable window. If this resource is 32 bits and
* But a prefetching area can handle a non-prefetching * non-prefetchable, the first call already tried the only possibility
* window (it will just not perform as well). * so we don't need to try again.
*
* Also can put 64bit under 32bit range. (below 4g).
*/ */
if (res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64))
ret = pci_bus_alloc_resource(bus, res, size, align, min, 0, ret = pci_bus_alloc_resource(bus, res, size, align, min, 0,
pcibios_align_resource, dev); pcibios_align_resource, dev);
}
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment