Patch from Russell King Now we tackle pci_add_new_bus and pci_scan_bridge. The hotplug code currently uses this, but I'd like it to die off; pci_scan_bridge() should be used to scan behind bridges. This may mean hotplug needs some changes to pci_scan_bridge - if so, we need to find out what changes are required and fix it. pci_alloc_child_bus() does what pci_add_new_bus() did, except it doesn't attach the new bus to the parents list of child buses. The only way this bus can be reached from the parent bus is by scanning the parents devices list, and locating a device with a non-NULL subordinate bus. The only code which should be doing this is the PCI code. Since the new bus will have an empty list head for bus->node, we can detect unattached buses prety easily. (see pci-3.diff. maybe we want a pci_bus_unattached() to make it more readable?) pci_scan_bridge() changes slightly - we use our new pci_scan_child_bus() function from pci-3.diff, which doesn't attach devices to the global tree. This means callers of pci_scan_child_bus() and pci_scan_bridge() (ie, hotplug) will need to call pci_bus_add_devices(). 25-akpm/drivers/pci/probe.c | 75 +++++++++++++++++++++++++++++--------------- 1 files changed, 50 insertions(+), 25 deletions(-) diff -puN drivers/pci/probe.c~pci-5 drivers/pci/probe.c --- 25/drivers/pci/probe.c~pci-5 Tue Mar 4 16:52:22 2003 +++ 25-akpm/drivers/pci/probe.c Tue Mar 4 16:52:22 2003 @@ -228,41 +228,57 @@ static struct pci_bus * __devinit pci_al return b; } -struct pci_bus * __devinit pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr) +static struct pci_bus * __devinit +pci_alloc_child_bus(struct pci_bus *parent, struct pci_dev *bridge, int busnr) { struct pci_bus *child; - int i; /* * Allocate a new bus, and inherit stuff from the parent.. */ child = pci_alloc_bus(); - list_add_tail(&child->node, &parent->children); - child->self = dev; - dev->subordinate = child; - child->parent = parent; - child->ops = parent->ops; - child->sysdata = parent->sysdata; - child->dev = &dev->dev; + if (child) { + int i; - /* - * Set up the primary, secondary and subordinate - * bus numbers. - */ - child->number = child->secondary = busnr; - child->primary = parent->secondary; - child->subordinate = 0xff; - - /* Set up default resource pointers and names.. */ - for (i = 0; i < 4; i++) { - child->resource[i] = &dev->resource[PCI_BRIDGE_RESOURCES+i]; - child->resource[i]->name = child->name; + child->self = bridge; + child->parent = parent; + child->ops = parent->ops; + child->sysdata = parent->sysdata; + child->dev = &bridge->dev; + + /* + * Set up the primary, secondary and subordinate + * bus numbers. + */ + child->number = child->secondary = busnr; + child->primary = parent->secondary; + child->subordinate = 0xff; + + /* Set up default resource pointers and names.. */ + for (i = 0; i < 4; i++) { + child->resource[i] = &bridge->resource[PCI_BRIDGE_RESOURCES+i]; + child->resource[i]->name = child->name; + } + + bridge->subordinate = child; } return child; } +struct pci_bus * __devinit pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr) +{ + struct pci_bus *child; + + child = pci_alloc_child_bus(parent, dev, busnr); + if (child) + list_add_tail(&child->node, &parent->children); + return child; +} + +static unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus); + /* * If it's a bridge, configure it and scan the bus behind it. * For CardBus bridges, we don't scan behind as the devices will @@ -289,12 +305,12 @@ int __devinit pci_scan_bridge(struct pci */ if (pass) return max; - child = pci_add_new_bus(bus, dev, 0); + child = pci_alloc_child_bus(bus, dev, 0); child->primary = buses & 0xFF; child->secondary = (buses >> 8) & 0xFF; child->subordinate = (buses >> 16) & 0xFF; child->number = child->secondary; - cmax = pci_do_scan_bus(child); + cmax = pci_scan_child_bus(child); if (cmax > max) max = cmax; } else { /* @@ -307,18 +323,27 @@ int __devinit pci_scan_bridge(struct pci /* Clear errors */ pci_write_config_word(dev, PCI_STATUS, 0xffff); - child = pci_add_new_bus(bus, dev, ++max); + child = pci_alloc_child_bus(bus, dev, ++max); buses = (buses & 0xff000000) | ((unsigned int)(child->primary) << 0) | ((unsigned int)(child->secondary) << 8) | ((unsigned int)(child->subordinate) << 16); + + /* + * yenta.c forces a secondary latency timer of 176. + * Copy that behaviour here. + */ + if (is_cardbus) + buses = (buses & 0x00ffffff) | (176 << 24); + /* * We need to blast all three values with a single write. */ pci_write_config_dword(dev, PCI_PRIMARY_BUS, buses); + if (!is_cardbus) { /* Now we can scan all subordinate buses... */ - max = pci_do_scan_bus(child); + max = pci_scan_child_bus(child); } else { /* * For CardBus bridges, we leave 4 bus numbers _