bus = new_bus(parent->bridge, p->domain, p->bus);
}
+ if (!bus && b == &host_bridge)
+ {
+ for (b=b->child; b; b=b->prev)
+ if (b->domain == (unsigned)p->domain)
+ break;
+ if (!b)
+ b = &host_bridge;
+ }
+
if (!bus && ! (bus = find_bus(b, p->domain, p->bus)))
{
struct bridge *c;
struct device *d;
struct bridge **last_br, *b;
+ last_br = &host_bridge.chain;
+
+ /* Build list of top level domain bridges */
+
+ for (d=first_dev; d; d=d->next)
+ {
+ for (b=host_bridge.chain; b; b=b->chain)
+ if (b->domain == (unsigned)d->dev->domain)
+ break;
+ if (b)
+ continue;
+ b = xmalloc(sizeof(struct bridge));
+ b->domain = d->dev->domain;
+ b->primary = ~0;
+ b->secondary = 0;
+ b->subordinate = ~0;
+ *last_br = b;
+ last_br = &b->chain;
+ b->prev = b->child = NULL;
+ b->first_bus = NULL;
+ b->last_bus = NULL;
+ b->br_dev = NULL;
+ b->chain = NULL;
+ pacc->debug("Tree: domain %04x\n", b->domain);
+ }
+
/* Build list of bridges */
- last_br = &host_bridge.chain;
for (d=first_dev; d; d=d->next)
{
struct pci_dev *dd = d->dev;
/* Create a bridge tree */
- for (b=&host_bridge; b; b=b->chain)
+ for (b=host_bridge.chain; b; b=b->chain)
{
struct device *br_dev = b->br_dev;
struct bridge *c, *best = NULL;
for (c=&host_bridge; c; c=c->chain)
if (c != b && (c == &host_bridge || b->domain == c->domain) &&
b->primary >= c->secondary && b->primary <= c->subordinate &&
- (!best || best->subordinate - best->primary > c->subordinate - c->primary))
+ (!best || best == &host_bridge || best->subordinate - best->primary > c->subordinate - c->primary))
best = c;
if (best)
{
/* Insert secondary bus for each bridge */
- for (b=&host_bridge; b; b=b->chain)
- if (!find_bus(b, b->domain, b->secondary))
+ for (b=host_bridge.chain; b; b=b->chain)
+ if (b->br_dev && !find_bus(b, b->domain, b->secondary))
new_bus(b, b->domain, b->secondary);
/* Create bus structs and link devices */
char namebuf[256];
p = tree_printf(line, p, "%02x.%x", q->dev, q->func);
- for (b=&host_bridge; b; b=b->chain)
+ for (b=host_bridge.chain; b; b=b->chain)
if (b->br_dev == d)
{
if (b->secondary == 0)
if (pci_filter_match(filter, d->dev))
return 1;
- for (br = &host_bridge; br; br = br->chain)
+ for (br = host_bridge.chain; br; br = br->chain)
if (br->br_dev == d)
{
for (b = br->first_bus; b; b = b->sibling)
{
if (check_bus_filter(filter, b->first_bus))
{
- if (b == &host_bridge)
- p = tree_printf(line, p, "[%04x:%02x]-", b->domain, b->first_bus->number);
+ if (!b->br_dev)
+ p = tree_printf(line, p, "[%04x:%02x]-", b->first_bus->domain, b->first_bus->number);
show_tree_bus(filter, b->first_bus, line, p);
}
else
show_forest(struct pci_filter *filter)
{
char line[LINE_BUF_SIZE];
- show_tree_bridge(filter, &host_bridge, line, line);
+ struct bridge *b;
+ if (host_bridge.child)
+ {
+ for (b=host_bridge.child; b->prev; b=b->prev)
+ show_tree_bridge(filter, b, line, line);
+ }
}