Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+43 −15
Original line number Diff line number Diff line
@@ -1164,17 +1164,16 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus,
			additional_io_size  = pci_hotplug_io_size;
			additional_mem_size = pci_hotplug_mem_size;
		}
		/*
		 * Follow thru
		 */
		/* Fall through */
	default:
		pbus_size_io(bus, realloc_head ? 0 : additional_io_size,
			     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
		   non-prefetchable range for both types of PCI memory
		   resources. */

		/*
		 * If there's a 64-bit prefetchable MMIO window, compute
		 * the size required to put all 64-bit prefetchable
		 * resources in it.
		 */
		b_res = &bus->self->resource[PCI_BRIDGE_RESOURCES];
		mask = IORESOURCE_MEM;
		prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH;
@@ -1184,29 +1183,58 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus,
				  prefmask, prefmask,
				  realloc_head ? 0 : additional_mem_size,
				  additional_mem_size, realloc_head);
			if (ret == 0) {

			/*
				 * Success, with pref mmio64,
				 * next will size non-pref or
				 * non-mmio64 */
			 * If successful, all non-prefetchable resources
			 * and any 32-bit prefetchable resources will go in
			 * the non-prefetchable window.
			 */
			if (ret == 0) {
				mask = prefmask;
				type2 = prefmask & ~IORESOURCE_MEM_64;
				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) {
			prefmask &= ~IORESOURCE_MEM_64;
			ret = pbus_size_mem(bus, prefmask, prefmask,
					 prefmask, prefmask,
					 realloc_head ? 0 : additional_mem_size,
					 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;
			} else
			else
				additional_mem_size += additional_mem_size;

			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,
				realloc_head ? 0 : additional_mem_size,
				additional_mem_size, realloc_head);
+19 −16
Original line number Diff line number Diff line
@@ -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;

	/* 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,
				     IORESOURCE_PREFETCH | IORESOURCE_MEM_64,
				     pcibios_align_resource, dev);
	if (ret == 0)
		return 0;

	if ((res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) ==
	     (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) {
	/*
		 * That failed.
		 *
		 * Try 32bit pref
	 * If the prefetchable window is only 32 bits wide, we can put
	 * 64-bit prefetchable resources in it.
	 */
	if ((res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) ==
	     (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) {
		ret = pci_bus_alloc_resource(bus, res, size, align, min,
					     IORESOURCE_PREFETCH,
					     pcibios_align_resource, dev);
@@ -230,18 +235,16 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
			return 0;
	}

	if (res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64)) {
	/*
		 * That failed.
		 *
		 * But a prefetching area can handle a non-prefetching
		 * window (it will just not perform as well).
		 *
		 * Also can put 64bit under 32bit range. (below 4g).
	 * 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
	 * non-prefetchable, the first call already tried the only possibility
	 * so we don't need to try again.
	 */
	if (res->flags & (IORESOURCE_PREFETCH | IORESOURCE_MEM_64))
		ret = pci_bus_alloc_resource(bus, res, size, align, min, 0,
					     pcibios_align_resource, dev);
	}

	return ret;
}