- struct bus *bus;
-
- if (! (bus = find_bus(b, d->bus)))
- {
- struct bridge *c;
- for(c=b->child; c; c=c->next)
- if (c->secondary <= d->bus && d->bus <= c->subordinate)
- return insert_dev(d, c);
- bus = new_bus(b, d->bus);
- }
- /* Simple insertion at the end _does_ guarantee the correct order as the
- * original device list was sorted by (bus, devfn) lexicographically
- * and all devices on the new list have the same bus number.
- */
- *bus->last_dev = d;
- bus->last_dev = &d->next;
- d->next = NULL;
-}
-
-static void
-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;)