summaryrefslogtreecommitdiffstats
path: root/arch/ia64
diff options
context:
space:
mode:
authorRajesh Shah <rajesh.shah@intel.com>2005-04-28 00:25:46 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2005-06-27 21:52:39 -0700
commit71c3511c22e8e0648094672abec898b3bf84c18b (patch)
treee85aa826d22c53f7ecb5c040fc0d242c8576a8a2 /arch/ia64
parentfab3fb0ac8c83072465b28ca859c420da6c6511c (diff)
downloadlinux-71c3511c22e8e0648094672abec898b3bf84c18b.tar.bz2
[PATCH] acpi bridge hotadd: Make pcibios_fixup_bus() hot-plug safe
PCI scan code calls the arch specific pcibios_fixup_bus() each time it scans a new bridge. For root bridge hot-plug, the bridge and it's attached devices may not have been configured properly yet, so it's not safe to claim those resources at this time. This code goes away when we clean up the way pci resources are claimed (in pci_enable_device()), so this is only a stopgap fix. Signed-off-by: Rajesh Shah <rajesh.shah@intel.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/pci/pci.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 2a1487758490..d929858cfb3e 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -373,6 +373,25 @@ void pcibios_bus_to_resource(struct pci_dev *dev,
res->end = region->end + offset;
}
+static int __devinit is_valid_resource(struct pci_dev *dev, int idx)
+{
+ unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM;
+ struct resource *devr = &dev->resource[idx];
+
+ if (!dev->bus)
+ return 0;
+ for (i=0; i<PCI_BUS_NUM_RESOURCES; i++) {
+ struct resource *busr = dev->bus->resource[i];
+
+ if (!busr || ((busr->flags ^ devr->flags) & type_mask))
+ continue;
+ if ((devr->start) && (devr->start >= busr->start) &&
+ (devr->end <= busr->end))
+ return 1;
+ }
+ return 0;
+}
+
static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
{
struct pci_bus_region region;
@@ -386,7 +405,8 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
region.start = dev->resource[i].start;
region.end = dev->resource[i].end;
pcibios_bus_to_resource(dev, &dev->resource[i], &region);
- pci_claim_resource(dev, i);
+ if ((is_valid_resource(dev, i)))
+ pci_claim_resource(dev, i);
}
}