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 <ink@jurassic.park.msu.ru>
To: Linus Torvalds <torvalds@osdl.org>
Cc: gregkh@suse.de, Andrew Morton <akpm@osdl.org>
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 <ink@jurassic.park.msu.ru>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
 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<<idx)))
 			continue;
--- gregkh-2.6.orig/drivers/pci/setup-bus.c	2005-06-16 14:45:02.000000000 -0700
+++ gregkh-2.6/drivers/pci/setup-bus.c	2005-06-16 14:45:04.000000000 -0700
@@ -273,6 +273,8 @@
 
 	for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
 		r = bus->resource[i];
+		if (r == &ioport_resource || r == &iomem_resource)
+			continue;
 		if (r && (r->flags & type_mask) == type && !r->parent)
 			return r;
 	}