Commit 299de034 authored by Ivan Kokshaysky's avatar Ivan Kokshaysky Committed by Greg Kroah-Hartman

[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: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 90b54929
...@@ -165,6 +165,7 @@ static int __init pcibios_init(void) ...@@ -165,6 +165,7 @@ static int __init pcibios_init(void)
if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT)) if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT))
pcibios_sort(); pcibios_sort();
#endif #endif
pci_assign_unassigned_resources();
return 0; return 0;
} }
......
...@@ -106,11 +106,16 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) ...@@ -106,11 +106,16 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
if ((dev = bus->self)) { if ((dev = bus->self)) {
for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) { for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
r = &dev->resource[idx]; r = &dev->resource[idx];
if (!r->start) if (!r->flags)
continue; continue;
pr = pci_find_parent_resource(dev, r); 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)); 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); pcibios_allocate_bus_resources(&bus->children);
...@@ -227,7 +232,7 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask) ...@@ -227,7 +232,7 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask)
pci_read_config_word(dev, PCI_COMMAND, &cmd); pci_read_config_word(dev, PCI_COMMAND, &cmd);
old_cmd = cmd; old_cmd = cmd;
for(idx=0; idx<6; idx++) { for(idx = 0; idx < PCI_NUM_RESOURCES; idx++) {
/* Only set up the requested stuff */ /* Only set up the requested stuff */
if (!(mask & (1<<idx))) if (!(mask & (1<<idx)))
continue; continue;
......
...@@ -273,6 +273,8 @@ find_free_bus_resource(struct pci_bus *bus, unsigned long type) ...@@ -273,6 +273,8 @@ find_free_bus_resource(struct pci_bus *bus, unsigned long type)
for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
r = bus->resource[i]; r = bus->resource[i];
if (r == &ioport_resource || r == &iomem_resource)
continue;
if (r && (r->flags & type_mask) == type && !r->parent) if (r && (r->flags & type_mask) == type && !r->parent)
return r; return r;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment