Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 3927

kernel-2.6.18-194.11.1.el5.src.rpm

From: Prarit Bhargava <prarit@redhat.com>
Date: Tue, 11 Nov 2008 14:37:03 -0500
Subject: [x86] fix calls to pci_scan_bus
Message-id: 20081111193703.15623.82176.sendpatchset@prarit.bos.redhat.com
O-Subject: [RHEL5.4 PATCH] HP XW 9400: fix calls to pci_scan_bus()
Bugzilla: 470202
RH-Acked-by: Don Dutile <ddutile@redhat.com>

Booting the i386 kernel, i386 PAE kernel, i386 xen dom0 with "acpi=off" all
resulted in the same panic on an xw9400.

There are a few call paths in RHEL5 in which pci_scan_bus is still being
called with a NULL value.

Fix the ones that are called on the xw9400.

Successfully compiled and tested by me.

Resolves BZ 470202.

Thanks to ddutile for pre-reviewing the Xen changes.

diff --git a/arch/i386/pci/irq-xen.c b/arch/i386/pci/irq-xen.c
index 1398930..9771540 100644
--- a/arch/i386/pci/irq-xen.c
+++ b/arch/i386/pci/irq-xen.c
@@ -141,10 +141,20 @@ static void __init pirq_peer_trick(void)
 		busmap[e->bus] = 1;
 	}
 	for(i = 1; i < 256; i++) {
+		struct pci_sysdata *sd;
 		if (!busmap[i] || pci_find_bus(0, i))
 			continue;
-		if (pci_scan_bus(i, &pci_root_ops, NULL))
+		/* Continuation of the gross hack.
+		   sysdata cannot be NULL here because of PCI_DOMAIN support.
+		   Let's assume we're part of the same domain and node */
+		sd = kzalloc(sizeof(*sd), GFP_KERNEL);
+		if (!sd)
+			panic("Cannot allocate PCI domain sysdata");
+		if (pci_scan_bus(i, &pci_root_ops, sd))
 			printk(KERN_INFO "PCI: Discovered primary peer bus %02x [IRQ]\n", i);
+		else
+			kfree(sd);
+
 	}
 	pcibios_last_bus = -1;
 }
diff --git a/arch/i386/pci/legacy.c b/arch/i386/pci/legacy.c
index 149a958..b9e0cdc 100644
--- a/arch/i386/pci/legacy.c
+++ b/arch/i386/pci/legacy.c
@@ -19,6 +19,11 @@ static void __devinit pcibios_fixup_peer_bridges(void)
 
 	for (n=0; n <= pcibios_last_bus; n++) {
 		u32 l;
+		struct pci_sysdata *sd;
+
+		sd = kzalloc(sizeof(&sd), GFP_KERNEL);
+		if (!sd)
+			panic("Cannot allocate PCI domain sysdata");
 		if (pci_find_bus(0, n))
 			continue;
 		for (devfn = 0; devfn < 256; devfn += 8) {
@@ -26,7 +31,8 @@ static void __devinit pcibios_fixup_peer_bridges(void)
 			    l != 0x0000 && l != 0xffff) {
 				DBG("Found device at %02x:%02x [%04x]\n", n, devfn, l);
 				printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n);
-				pci_scan_bus(n, &pci_root_ops, NULL);
+				if (!pci_scan_bus(n, &pci_root_ops, sd))
+					kfree(sd);
 				break;
 			}
 		}