diff options
author | Ivan Kokshaysky <ink@jurassic.park.msu.ru> | 2005-06-15 10:59:27 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2005-07-01 16:35:50 -0400 |
commit | 299de0343c7d18448a69c635378342e9214b14af (patch) | |
tree | 0a456358b5f919328e234868139c983813f4cb80 | |
parent | 90b54929b626c80056262d9d99b3f48522e404d0 (diff) |
[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>
-rw-r--r-- | arch/i386/pci/common.c | 1 | ||||
-rw-r--r-- | arch/i386/pci/i386.c | 11 | ||||
-rw-r--r-- | drivers/pci/setup-bus.c | 2 |
3 files changed, 11 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) | |||
165 | if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT)) | 165 | if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT)) |
166 | pcibios_sort(); | 166 | pcibios_sort(); |
167 | #endif | 167 | #endif |
168 | pci_assign_unassigned_resources(); | ||
168 | return 0; | 169 | return 0; |
169 | } | 170 | } |
170 | 171 | ||
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) | |||
106 | if ((dev = bus->self)) { | 106 | if ((dev = bus->self)) { |
107 | for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) { | 107 | for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) { |
108 | r = &dev->resource[idx]; | 108 | r = &dev->resource[idx]; |
109 | if (!r->start) | 109 | if (!r->flags) |
110 | continue; | 110 | continue; |
111 | pr = pci_find_parent_resource(dev, r); | 111 | pr = pci_find_parent_resource(dev, r); |
112 | if (!pr || request_resource(pr, r) < 0) | 112 | if (!r->start || !pr || request_resource(pr, r) < 0) { |
113 | printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, pci_name(dev)); | 113 | printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, pci_name(dev)); |
114 | /* Something is wrong with the region. | ||
115 | Invalidate the resource to prevent child | ||
116 | resource allocations in this range. */ | ||
117 | r->flags = 0; | ||
118 | } | ||
114 | } | 119 | } |
115 | } | 120 | } |
116 | pcibios_allocate_bus_resources(&bus->children); | 121 | pcibios_allocate_bus_resources(&bus->children); |
@@ -227,7 +232,7 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask) | |||
227 | 232 | ||
228 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | 233 | pci_read_config_word(dev, PCI_COMMAND, &cmd); |
229 | old_cmd = cmd; | 234 | old_cmd = cmd; |
230 | for(idx=0; idx<6; idx++) { | 235 | for(idx = 0; idx < PCI_NUM_RESOURCES; idx++) { |
231 | /* Only set up the requested stuff */ | 236 | /* Only set up the requested stuff */ |
232 | if (!(mask & (1<<idx))) | 237 | if (!(mask & (1<<idx))) |
233 | continue; | 238 | continue; |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 6b628de948af..c1bdfb424658 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -273,6 +273,8 @@ find_free_bus_resource(struct pci_bus *bus, unsigned long type) | |||
273 | 273 | ||
274 | for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { | 274 | for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { |
275 | r = bus->resource[i]; | 275 | r = bus->resource[i]; |
276 | if (r == &ioport_resource || r == &iomem_resource) | ||
277 | continue; | ||
276 | if (r && (r->flags & type_mask) == type && !r->parent) | 278 | if (r && (r->flags & type_mask) == type && !r->parent) |
277 | return r; | 279 | return r; |
278 | } | 280 | } |