Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 250097
b: refs/heads/master
c: da7822e
h: refs/heads/master
i:
  250095: 3597784
v: v3
  • Loading branch information
Yinghai Lu authored and Jesse Barnes committed May 21, 2011
1 parent 9f532cb commit e2e57a5
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 9 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f8fcfd775523347afe460dc3a0f45d0479e784a2
refs/heads/master: da7822e5ad71ec9b745b412639f1e5e0ba795a20
125 changes: 117 additions & 8 deletions trunk/drivers/pci/setup-bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -991,30 +991,139 @@ static void pci_bus_dump_resources(struct pci_bus *bus)
}
}

static int __init pci_bus_get_depth(struct pci_bus *bus)
{
int depth = 0;
struct pci_dev *dev;

list_for_each_entry(dev, &bus->devices, bus_list) {
int ret;
struct pci_bus *b = dev->subordinate;
if (!b)
continue;

ret = pci_bus_get_depth(b);
if (ret + 1 > depth)
depth = ret + 1;
}

return depth;
}
static int __init pci_get_max_depth(void)
{
int depth = 0;
struct pci_bus *bus;

list_for_each_entry(bus, &pci_root_buses, node) {
int ret;

ret = pci_bus_get_depth(bus);
if (ret > depth)
depth = ret;
}

return depth;
}

/*
* first try will not touch pci bridge res
* second and later try will clear small leaf bridge res
* will stop till to the max deepth if can not find good one
*/
void __init
pci_assign_unassigned_resources(void)
{
struct pci_bus *bus;
struct resource_list_x add_list; /* list of resources that
want additional resources */
int tried_times = 0;
enum release_type rel_type = leaf_only;
struct resource_list_x head, *list;
unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
IORESOURCE_PREFETCH;
unsigned long failed_type;
int max_depth = pci_get_max_depth();
int pci_try_num;


head.next = NULL;
add_list.next = NULL;

pci_try_num = max_depth + 1;
printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n",
max_depth, pci_try_num);

again:
/* Depth first, calculate sizes and alignments of all
subordinate buses. */
list_for_each_entry(bus, &pci_root_buses, node) {
list_for_each_entry(bus, &pci_root_buses, node)
__pci_bus_size_bridges(bus, &add_list);
}

/* Depth last, allocate resources and update the hardware. */
list_for_each_entry(bus, &pci_root_buses, node) {
__pci_bus_assign_resources(bus, &add_list, NULL);
pci_enable_bridges(bus);
}
list_for_each_entry(bus, &pci_root_buses, node)
__pci_bus_assign_resources(bus, &add_list, &head);
BUG_ON(add_list.next);
tried_times++;

/* any device complain? */
if (!head.next)
goto enable_and_dump;
failed_type = 0;
for (list = head.next; list;) {
failed_type |= list->flags;
list = list->next;
}
/*
* io port are tight, don't try extra
* or if reach the limit, don't want to try more
*/
failed_type &= type_mask;
if ((failed_type == IORESOURCE_IO) || (tried_times >= pci_try_num)) {
free_list(resource_list_x, &head);
goto enable_and_dump;
}

printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n",
tried_times + 1);

/* third times and later will not check if it is leaf */
if ((tried_times + 1) > 2)
rel_type = whole_subtree;

/*
* Try to release leaf bridge's resources that doesn't fit resource of
* child device under that bridge
*/
for (list = head.next; list;) {
bus = list->dev->bus;
pci_bus_release_bridge_resources(bus, list->flags & type_mask,
rel_type);
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_list(resource_list_x, &head);

goto again;

enable_and_dump:
/* Depth last, update the hardware. */
list_for_each_entry(bus, &pci_root_buses, node)
pci_enable_bridges(bus);

/* dump the resource on buses */
list_for_each_entry(bus, &pci_root_buses, node) {
list_for_each_entry(bus, &pci_root_buses, node)
pci_bus_dump_resources(bus);
}
}

void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
Expand Down

0 comments on commit e2e57a5

Please sign in to comment.