PCI: Handle IORESOURCE_PCI_FIXED when assigning resources
The new Enhanced Allocation (EA) capability support (patches to follow) creates resources with the IORESOURCE_PCI_FIXED set. During resource assignment in pci_bus_assign_resources(), IORESOURCE_PCI_FIXED resources are not given a parent. This, in turn, causes pci_enable_resources() to fail with a "not claimed" error. So, in __pci_bus_assign_resources(), for IORESOURCE_PCI_FIXED resources, try to request the resource from a parent bus. Signed-off-by: David Daney <david.daney@cavium.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Acked-by: Sean O. Stalley <sean.stalley@intel.com>
This commit is contained in:
parent
a2220d804b
commit
d04d0111c7
1 changed files with 43 additions and 0 deletions
|
@ -1341,6 +1341,47 @@ void pci_bus_size_bridges(struct pci_bus *bus)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(pci_bus_size_bridges);
|
EXPORT_SYMBOL(pci_bus_size_bridges);
|
||||||
|
|
||||||
|
static void assign_fixed_resource_on_bus(struct pci_bus *b, struct resource *r)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct resource *parent_r;
|
||||||
|
unsigned long mask = IORESOURCE_IO | IORESOURCE_MEM |
|
||||||
|
IORESOURCE_PREFETCH;
|
||||||
|
|
||||||
|
pci_bus_for_each_resource(b, parent_r, i) {
|
||||||
|
if (!parent_r)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((r->flags & mask) == (parent_r->flags & mask) &&
|
||||||
|
resource_contains(parent_r, r))
|
||||||
|
request_resource(parent_r, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try to assign any resources marked as IORESOURCE_PCI_FIXED, as they
|
||||||
|
* are skipped by pbus_assign_resources_sorted().
|
||||||
|
*/
|
||||||
|
static void pdev_assign_fixed_resources(struct pci_dev *dev)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
|
||||||
|
struct pci_bus *b;
|
||||||
|
struct resource *r = &dev->resource[i];
|
||||||
|
|
||||||
|
if (r->parent || !(r->flags & IORESOURCE_PCI_FIXED) ||
|
||||||
|
!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
b = dev->bus;
|
||||||
|
while (b && !r->parent) {
|
||||||
|
assign_fixed_resource_on_bus(b, r);
|
||||||
|
b = b->parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void __pci_bus_assign_resources(const struct pci_bus *bus,
|
void __pci_bus_assign_resources(const struct pci_bus *bus,
|
||||||
struct list_head *realloc_head,
|
struct list_head *realloc_head,
|
||||||
struct list_head *fail_head)
|
struct list_head *fail_head)
|
||||||
|
@ -1351,6 +1392,8 @@ void __pci_bus_assign_resources(const struct pci_bus *bus,
|
||||||
pbus_assign_resources_sorted(bus, realloc_head, fail_head);
|
pbus_assign_resources_sorted(bus, realloc_head, fail_head);
|
||||||
|
|
||||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||||
|
pdev_assign_fixed_resources(dev);
|
||||||
|
|
||||||
b = dev->subordinate;
|
b = dev->subordinate;
|
||||||
if (!b)
|
if (!b)
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Reference in a new issue