From ink@jurassic.park.msu.ru Wed Jun 15 08:53:07 2005 Date: Wed, 15 Jun 2005 18:59:27 +0400 From: Ivan Kokshaysky To: Linus Torvalds Cc: gregkh@suse.de, Andrew Morton Subject: PCI: pci_assign_unassigned_resources() on x86 Message-ID: <20050615185927.A26093@jurassic.park.msu.ru> - 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 Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/common.c | 1 + arch/i386/pci/i386.c | 11 ++++++++--- drivers/pci/setup-bus.c | 2 ++ 3 files changed, 11 insertions(+), 3 deletions(-) --- gregkh-2.6.orig/arch/i386/pci/common.c 2005-06-16 14:45:02.000000000 -0700 +++ gregkh-2.6/arch/i386/pci/common.c 2005-06-16 14:45:04.000000000 -0700 @@ -165,6 +165,7 @@ if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT)) pcibios_sort(); #endif + pci_assign_unassigned_resources(); return 0; } --- gregkh-2.6.orig/arch/i386/pci/i386.c 2005-06-16 14:45:02.000000000 -0700 +++ gregkh-2.6/arch/i386/pci/i386.c 2005-06-16 14:45:04.000000000 -0700 @@ -106,11 +106,16 @@ 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 @@ 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<resource[i]; + if (r == &ioport_resource || r == &iomem_resource) + continue; if (r && (r->flags & type_mask) == type && !r->parent) return r; }