From 043b7dc050ba3fdf076db3e8c606048ab3a4f25e Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Fri, 22 Jan 2010 01:02:27 -0800 Subject: [PATCH] --- yaml --- r: 180981 b: refs/heads/master c: 32180e402f9ff1f3389c99edf3f393425e706080 h: refs/heads/master i: 180979: 7c80b05cdba8014f38892a1e85ca6b4e27102636 v: v3 --- [refs] | 2 +- trunk/drivers/pci/setup-bus.c | 51 ++++++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index da70bcb10443..fc1da285c2c7 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 9789ac979b6b6ae6cc09f7b29c88e95ecb14ec39 +refs/heads/master: 32180e402f9ff1f3389c99edf3f393425e706080 diff --git a/trunk/drivers/pci/setup-bus.c b/trunk/drivers/pci/setup-bus.c index b19a56b8b17a..ed545f669459 100644 --- a/trunk/drivers/pci/setup-bus.c +++ b/trunk/drivers/pci/setup-bus.c @@ -964,12 +964,61 @@ pci_assign_unassigned_resources(void) void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge) { struct pci_bus *parent = bridge->subordinate; + int tried_times = 0; + struct resource_list_x head, *list; int retval; + unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | + IORESOURCE_PREFETCH; + + head.next = NULL; +again: pci_bus_size_bridges(parent); - __pci_bridge_assign_resources(bridge, NULL); + __pci_bridge_assign_resources(bridge, &head); retval = pci_reenable_device(bridge); pci_set_master(bridge); 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);