|
|
@@ -731,22 +731,6 @@ struct pci_bus *__ref pci_add_new_bus(struct pci_bus *parent, struct pci_dev *de
|
|
|
return child;
|
|
|
}
|
|
|
|
|
|
-static void pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max)
|
|
|
-{
|
|
|
- struct pci_bus *parent = child->parent;
|
|
|
-
|
|
|
- /* Attempts to fix that up are really dangerous unless
|
|
|
- we're going to re-assign all bus numbers. */
|
|
|
- if (!pcibios_assign_all_busses())
|
|
|
- return;
|
|
|
-
|
|
|
- while (parent->parent && parent->busn_res.end < max) {
|
|
|
- parent->busn_res.end = max;
|
|
|
- pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, max);
|
|
|
- parent = parent->parent;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* 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
|
|
|
@@ -782,7 +766,7 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
|
|
|
/* Check if setup is sensible at all */
|
|
|
if (!pass &&
|
|
|
(primary != bus->number || secondary <= bus->number ||
|
|
|
- secondary > subordinate)) {
|
|
|
+ secondary > subordinate || subordinate > bus->busn_res.end)) {
|
|
|
dev_info(&dev->dev, "bridge configuration invalid ([bus %02x-%02x]), reconfiguring\n",
|
|
|
secondary, subordinate);
|
|
|
broken = 1;
|
|
|
@@ -805,11 +789,10 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
|
|
|
goto out;
|
|
|
|
|
|
/*
|
|
|
- * If we already got to this bus through a different bridge,
|
|
|
- * don't re-add it. This can happen with the i450NX chipset.
|
|
|
- *
|
|
|
- * However, we continue to descend down the hierarchy and
|
|
|
- * scan remaining child buses.
|
|
|
+ * The bus might already exist for two reasons: Either we are
|
|
|
+ * rescanning the bus or the bus is reachable through more than
|
|
|
+ * one bridge. The second case can happen with the i450NX
|
|
|
+ * chipset.
|
|
|
*/
|
|
|
child = pci_find_bus(pci_domain_nr(bus), secondary);
|
|
|
if (!child) {
|
|
|
@@ -822,17 +805,19 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
|
|
|
}
|
|
|
|
|
|
cmax = pci_scan_child_bus(child);
|
|
|
- if (cmax > max)
|
|
|
- max = cmax;
|
|
|
- if (child->busn_res.end > max)
|
|
|
- max = child->busn_res.end;
|
|
|
+ if (cmax > subordinate)
|
|
|
+ dev_warn(&dev->dev, "bridge has subordinate %02x but max busn %02x\n",
|
|
|
+ subordinate, cmax);
|
|
|
+ /* subordinate should equal child->busn_res.end */
|
|
|
+ if (subordinate > max)
|
|
|
+ max = subordinate;
|
|
|
} else {
|
|
|
/*
|
|
|
* We need to assign a number to this bus which we always
|
|
|
* do in the second pass.
|
|
|
*/
|
|
|
if (!pass) {
|
|
|
- if (pcibios_assign_all_busses() || broken)
|
|
|
+ if (pcibios_assign_all_busses() || broken || is_cardbus)
|
|
|
/* Temporarily disable forwarding of the
|
|
|
configuration cycles on all bridges in
|
|
|
this bus segment to avoid possible
|
|
|
@@ -844,19 +829,25 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
+ if (max >= bus->busn_res.end) {
|
|
|
+ dev_warn(&dev->dev, "can't allocate child bus %02x from %pR\n",
|
|
|
+ max, &bus->busn_res);
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
/* Clear errors */
|
|
|
pci_write_config_word(dev, PCI_STATUS, 0xffff);
|
|
|
|
|
|
- /* Prevent assigning a bus number that already exists.
|
|
|
- * This can happen when a bridge is hot-plugged, so in
|
|
|
- * this case we only re-scan this bus. */
|
|
|
+ /* The bus will already exist if we are rescanning */
|
|
|
child = pci_find_bus(pci_domain_nr(bus), max+1);
|
|
|
if (!child) {
|
|
|
- child = pci_add_new_bus(bus, dev, ++max);
|
|
|
+ child = pci_add_new_bus(bus, dev, max+1);
|
|
|
if (!child)
|
|
|
goto out;
|
|
|
- pci_bus_insert_busn_res(child, max, 0xff);
|
|
|
+ pci_bus_insert_busn_res(child, max+1,
|
|
|
+ bus->busn_res.end);
|
|
|
}
|
|
|
+ max++;
|
|
|
buses = (buses & 0xff000000)
|
|
|
| ((unsigned int)(child->primary) << 0)
|
|
|
| ((unsigned int)(child->busn_res.start) << 8)
|
|
|
@@ -878,20 +869,7 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
|
|
|
|
|
|
if (!is_cardbus) {
|
|
|
child->bridge_ctl = bctl;
|
|
|
- /*
|
|
|
- * Adjust subordinate busnr in parent buses.
|
|
|
- * We do this before scanning for children because
|
|
|
- * some devices may not be detected if the bios
|
|
|
- * was lazy.
|
|
|
- */
|
|
|
- pci_fixup_parent_subordinate_busnr(child, max);
|
|
|
- /* Now we can scan all subordinate buses... */
|
|
|
max = pci_scan_child_bus(child);
|
|
|
- /*
|
|
|
- * now fix it up again since we have found
|
|
|
- * the real value of max.
|
|
|
- */
|
|
|
- pci_fixup_parent_subordinate_busnr(child, max);
|
|
|
} else {
|
|
|
/*
|
|
|
* For CardBus bridges, we leave 4 bus numbers
|
|
|
@@ -922,11 +900,15 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass)
|
|
|
}
|
|
|
}
|
|
|
max += i;
|
|
|
- pci_fixup_parent_subordinate_busnr(child, max);
|
|
|
}
|
|
|
/*
|
|
|
* Set the subordinate bus number to its real value.
|
|
|
*/
|
|
|
+ if (max > bus->busn_res.end) {
|
|
|
+ dev_warn(&dev->dev, "max busn %02x is outside %pR\n",
|
|
|
+ max, &bus->busn_res);
|
|
|
+ max = bus->busn_res.end;
|
|
|
+ }
|
|
|
pci_bus_update_busn_res_end(child, max);
|
|
|
pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max);
|
|
|
}
|
|
|
@@ -1835,7 +1817,7 @@ int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max)
|
|
|
res->flags |= IORESOURCE_PCI_FIXED;
|
|
|
}
|
|
|
|
|
|
- conflict = insert_resource_conflict(parent_res, res);
|
|
|
+ conflict = request_resource_conflict(parent_res, res);
|
|
|
|
|
|
if (conflict)
|
|
|
dev_printk(KERN_DEBUG, &b->dev,
|