|
@@ -667,6 +667,42 @@ extend_lmmio_len(unsigned long start, unsigned long end, unsigned long lba_len)
|
|
|
#define truncate_pat_collision(r,n) (0)
|
|
|
#endif
|
|
|
|
|
|
+static void pcibios_allocate_bridge_resources(struct pci_dev *dev)
|
|
|
+{
|
|
|
+ int idx;
|
|
|
+ struct resource *r;
|
|
|
+
|
|
|
+ for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
|
|
|
+ r = &dev->resource[idx];
|
|
|
+ if (!r->flags)
|
|
|
+ continue;
|
|
|
+ if (r->parent) /* Already allocated */
|
|
|
+ continue;
|
|
|
+ if (!r->start || pci_claim_bridge_resource(dev, idx) < 0) {
|
|
|
+ /*
|
|
|
+ * Something is wrong with the region.
|
|
|
+ * Invalidate the resource to prevent
|
|
|
+ * child resource allocations in this
|
|
|
+ * range.
|
|
|
+ */
|
|
|
+ r->start = r->end = 0;
|
|
|
+ r->flags = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void pcibios_allocate_bus_resources(struct pci_bus *bus)
|
|
|
+{
|
|
|
+ struct pci_bus *child;
|
|
|
+
|
|
|
+ /* Depth-First Search on bus tree */
|
|
|
+ if (bus->self)
|
|
|
+ pcibios_allocate_bridge_resources(bus->self);
|
|
|
+ list_for_each_entry(child, &bus->children, node)
|
|
|
+ pcibios_allocate_bus_resources(child);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
/*
|
|
|
** The algorithm is generic code.
|
|
|
** But it needs to access local data structures to get the IRQ base.
|
|
@@ -693,11 +729,11 @@ lba_fixup_bus(struct pci_bus *bus)
|
|
|
** pci_alloc_primary_bus() mangles this.
|
|
|
*/
|
|
|
if (bus->parent) {
|
|
|
- int i;
|
|
|
/* PCI-PCI Bridge */
|
|
|
pci_read_bridge_bases(bus);
|
|
|
- for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++)
|
|
|
- pci_claim_bridge_resource(bus->self, i);
|
|
|
+
|
|
|
+ /* check and allocate bridge resources */
|
|
|
+ pcibios_allocate_bus_resources(bus);
|
|
|
} else {
|
|
|
/* Host-PCI Bridge */
|
|
|
int err;
|