-grow_tree(void)
-{
- struct device *d, *d2;
- struct bridge **last_br, *b;
-
- /* Build list of bridges */
-
- last_br = &host_bridge.chain;
- for(d=first_dev; d; d=d->next)
- {
- word class = get_conf_word(d, PCI_CLASS_DEVICE);
- byte ht = get_conf_byte(d, PCI_HEADER_TYPE) & 0x7f;
- if (class == PCI_CLASS_BRIDGE_PCI &&
- (ht == PCI_HEADER_TYPE_BRIDGE || ht == PCI_HEADER_TYPE_CARDBUS))
- {
- b = xmalloc(sizeof(struct bridge));
- if (ht == PCI_HEADER_TYPE_BRIDGE)
- {
- b->primary = get_conf_byte(d, PCI_CB_PRIMARY_BUS);
- b->secondary = get_conf_byte(d, PCI_CB_CARD_BUS);
- b->subordinate = get_conf_byte(d, PCI_CB_SUBORDINATE_BUS);
- }
- else
- {
- b->primary = get_conf_byte(d, PCI_PRIMARY_BUS);
- b->secondary = get_conf_byte(d, PCI_SECONDARY_BUS);
- b->subordinate = get_conf_byte(d, PCI_SUBORDINATE_BUS);
- }
- *last_br = b;
- last_br = &b->chain;
- b->next = b->child = NULL;
- b->first_bus = NULL;
- b->br_dev = d;
- }
- }
- *last_br = NULL;
-
- /* Create a bridge tree */
-
- for(b=&host_bridge; b; b=b->chain)
- {
- struct bridge *c, *best;
- best = NULL;
- for(c=&host_bridge; c; c=c->chain)
- if (c != b && b->primary >= c->secondary && b->primary <= c->subordinate &&
- (!best || best->subordinate - best->primary > c->subordinate - c->primary))
- best = c;
- if (best)
- {
- b->next = best->child;
- best->child = b;
- }
- }
-
- /* Insert secondary bus for each bridge */
-
- for(b=&host_bridge; b; b=b->chain)
- if (!find_bus(b, b->secondary))
- new_bus(b, b->secondary);
-
- /* Create bus structs and link devices */
-
- for(d=first_dev; d;)
- {
- d2 = d->next;
- insert_dev(d, &host_bridge);
- d = d2;
- }
-}
-
-static void
-print_it(byte *line, byte *p)
-{
- *p++ = '\n';
- *p = 0;
- fputs(line, stdout);
- for(p=line; *p; p++)
- if (*p == '+' || *p == '|')
- *p = '|';
- else
- *p = ' ';
-}
-
-static void show_tree_bridge(struct bridge *, byte *, byte *);
-
-static void
-show_tree_dev(struct device *d, byte *line, byte *p)
-{
- struct pci_dev *q = d->dev;
- struct bridge *b;
- char namebuf[256];
-
- p += sprintf(p, "%02x.%x", q->dev, q->func);
- for(b=&host_bridge; b; b=b->chain)
- if (b->br_dev == d)
- {
- if (b->secondary == b->subordinate)
- p += sprintf(p, "-[%02x]-", b->secondary);
- else
- p += sprintf(p, "-[%02x-%02x]-", b->secondary, b->subordinate);
- show_tree_bridge(b, line, p);
- return;
- }
- if (verbose)
- p += sprintf(p, " %s",
- pci_lookup_name(pacc, namebuf, sizeof(namebuf),
- PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE,
- q->vendor_id, q->device_id));
- print_it(line, p);
-}
-
-static void
-show_tree_bus(struct bus *b, byte *line, byte *p)
-{
- if (!b->first_dev)
- print_it(line, p);
- else if (!b->first_dev->next)
- {
- *p++ = '-';
- *p++ = '-';
- show_tree_dev(b->first_dev, line, p);
- }
- else
- {
- struct device *d = b->first_dev;
- while (d->next)
- {
- p[0] = '+';
- p[1] = '-';
- show_tree_dev(d, line, p+2);
- d = d->next;
- }
- p[0] = '\\';
- p[1] = '-';
- show_tree_dev(d, line, p+2);
- }
-}
-
-static void
-show_tree_bridge(struct bridge *b, byte *line, byte *p)
-{
- *p++ = '-';
- if (!b->first_bus->sibling)
- {
- if (b == &host_bridge)
- p += sprintf(p, "[%02x]-", b->first_bus->number);
- show_tree_bus(b->first_bus, line, p);
- }
- else
- {
- struct bus *u = b->first_bus;
- byte *k;
-
- while (u->sibling)
- {
- k = p + sprintf(p, "+-[%02x]-", u->number);
- show_tree_bus(u, line, k);
- u = u->sibling;
- }
- k = p + sprintf(p, "\\-[%02x]-", u->number);
- show_tree_bus(u, line, k);
- }
-}
-
-static void
-show_forest(void)