Commit 32180e40 authored by Yinghai Lu's avatar Yinghai Lu Committed by Jesse Barnes

PCI: pciehp: second try to get big range for pcie devices

Handle the case where the slot bridge that doesn't get a pre-allocated
resource big enough to handle its child resources..  For example pcie
devices need 256M, but the bridge only gets 2M preallocated.
Signed-off-by: default avatarYinghai Lu <yinghai@kernel.org>
Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
parent 9789ac97
...@@ -964,12 +964,61 @@ pci_assign_unassigned_resources(void) ...@@ -964,12 +964,61 @@ pci_assign_unassigned_resources(void)
void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge) void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
{ {
struct pci_bus *parent = bridge->subordinate; struct pci_bus *parent = bridge->subordinate;
int tried_times = 0;
struct resource_list_x head, *list;
int retval; int retval;
unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
IORESOURCE_PREFETCH;
head.next = NULL;
again:
pci_bus_size_bridges(parent); pci_bus_size_bridges(parent);
__pci_bridge_assign_resources(bridge, NULL); __pci_bridge_assign_resources(bridge, &head);
retval = pci_reenable_device(bridge); retval = pci_reenable_device(bridge);
pci_set_master(bridge); pci_set_master(bridge);
pci_enable_bridges(parent); pci_enable_bridges(parent);
tried_times++;
if (!head.next)
return;
if (tried_times >= 2) {
/* still fail, don't need to try more */
free_failed_list(&head);
return;
}
printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n",
tried_times + 1);
/*
* Try to release leaf bridge's resources that doesn't fit resource of
* child device under that bridge
*/
for (list = head.next; list;) {
struct pci_bus *bus = list->dev->bus;
unsigned long flags = list->flags;
pci_bus_release_bridge_resources(bus, flags & type_mask,
whole_subtree);
list = list->next;
}
/* restore size and flags */
for (list = head.next; list;) {
struct resource *res = list->res;
res->start = list->start;
res->end = list->end;
res->flags = list->flags;
if (list->dev->subordinate)
res->flags = 0;
list = list->next;
}
free_failed_list(&head);
goto again;
} }
EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources); EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources);
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