|
@@ -401,33 +401,40 @@ EXPORT_SYMBOL_GPL(pci_find_ht_capability);
|
|
|
* @res: child resource record for which parent is sought
|
|
|
*
|
|
|
* For given resource region of given device, return the resource
|
|
|
- * region of parent bus the given region is contained in or where
|
|
|
- * it should be allocated from.
|
|
|
+ * region of parent bus the given region is contained in.
|
|
|
*/
|
|
|
struct resource *
|
|
|
pci_find_parent_resource(const struct pci_dev *dev, struct resource *res)
|
|
|
{
|
|
|
const struct pci_bus *bus = dev->bus;
|
|
|
+ struct resource *r;
|
|
|
int i;
|
|
|
- struct resource *best = NULL, *r;
|
|
|
|
|
|
pci_bus_for_each_resource(bus, r, i) {
|
|
|
if (!r)
|
|
|
continue;
|
|
|
- if (res->start && !(res->start >= r->start && res->end <= r->end))
|
|
|
- continue; /* Not contained */
|
|
|
- if ((res->flags ^ r->flags) & (IORESOURCE_IO | IORESOURCE_MEM))
|
|
|
- continue; /* Wrong type */
|
|
|
- if (!((res->flags ^ r->flags) & IORESOURCE_PREFETCH))
|
|
|
- return r; /* Exact match */
|
|
|
- /* We can't insert a non-prefetch resource inside a prefetchable parent .. */
|
|
|
- if (r->flags & IORESOURCE_PREFETCH)
|
|
|
- continue;
|
|
|
- /* .. but we can put a prefetchable resource inside a non-prefetchable one */
|
|
|
- if (!best)
|
|
|
- best = r;
|
|
|
+ if (res->start && resource_contains(r, res)) {
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If the window is prefetchable but the BAR is
|
|
|
+ * not, the allocator made a mistake.
|
|
|
+ */
|
|
|
+ if (r->flags & IORESOURCE_PREFETCH &&
|
|
|
+ !(res->flags & IORESOURCE_PREFETCH))
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If we're below a transparent bridge, there may
|
|
|
+ * be both a positively-decoded aperture and a
|
|
|
+ * subtractively-decoded region that contain the BAR.
|
|
|
+ * We want the positively-decoded one, so this depends
|
|
|
+ * on pci_bus_for_each_resource() giving us those
|
|
|
+ * first.
|
|
|
+ */
|
|
|
+ return r;
|
|
|
+ }
|
|
|
}
|
|
|
- return best;
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
/**
|