summaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
authorIvan Kokshaysky <ink@jurassic.park.msu.ru>2005-06-15 16:59:27 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2005-07-01 22:35:50 +0200
commit299de0343c7d18448a69c635378342e9214b14af (patch)
tree0a456358b5f919328e234868139c983813f4cb80 /arch/i386
parent[PATCH] PCI: handle subtractive decode pci-pci bridge better (diff)
downloadlinux-299de0343c7d18448a69c635378342e9214b14af.tar.xz
linux-299de0343c7d18448a69c635378342e9214b14af.zip
[PATCH] PCI: pci_assign_unassigned_resources() on x86
- Add sanity check for io[port,mem]_resource in setup-bus.c. These resources look like "free" as they have no parents, but obviously we must not touch them. - In i386.c:pci_allocate_bus_resources(), if a bridge resource cannot be allocated for some reason, then clear its flags. This prevents any child allocations in this range, so the setup-bus code will work with a clean resource sub-tree. - i386.c:pcibios_enable_resources() doesn't enable bridges, as it checks only resources 0-5, which looks like a clear bug to me. I suspect it might break hotplug as well in some cases. From: Ivan Kokshaysky <ink@jurassic.park.msu.ru> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'arch/i386')
-rw-r--r--arch/i386/pci/common.c1
-rw-r--r--arch/i386/pci/i386.c11
2 files changed, 9 insertions, 3 deletions
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c
index 87325263cd4f..70bcd53451f6 100644
--- a/arch/i386/pci/common.c
+++ b/arch/i386/pci/common.c
@@ -165,6 +165,7 @@ static int __init pcibios_init(void)
if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT))
pcibios_sort();
#endif
+ pci_assign_unassigned_resources();
return 0;
}
diff --git a/arch/i386/pci/i386.c b/arch/i386/pci/i386.c
index c205ea7e233b..93a364c82150 100644
--- a/arch/i386/pci/i386.c
+++ b/arch/i386/pci/i386.c
@@ -106,11 +106,16 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
if ((dev = bus->self)) {
for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
r = &dev->resource[idx];
- if (!r->start)
+ if (!r->flags)
continue;
pr = pci_find_parent_resource(dev, r);
- if (!pr || request_resource(pr, r) < 0)
+ if (!r->start || !pr || request_resource(pr, r) < 0) {
printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, pci_name(dev));
+ /* Something is wrong with the region.
+ Invalidate the resource to prevent child
+ resource allocations in this range. */
+ r->flags = 0;
+ }
}
}
pcibios_allocate_bus_resources(&bus->children);
@@ -227,7 +232,7 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask)
pci_read_config_word(dev, PCI_COMMAND, &cmd);
old_cmd = cmd;
- for(idx=0; idx<6; idx++) {
+ for(idx = 0; idx < PCI_NUM_RESOURCES; idx++) {
/* Only set up the requested stuff */
if (!(mask & (1<<idx)))
continue;