
From: <Natalie.Protasevich@unisys.com>

In arch/i386/kernel/acpi/boot.c, platform GSI does not propagate back from
mp_register_gsi() to a calling routine which results in IRQ to be set for
wrong GSI.  This causes most of the PCI slots on the first PCI module to
fail.  This patch fixes the problem by returning new GSI back to
acpi_register_gsi().

Signed-off-by: Natalie Protasevich <Natalie.Protasevich@unisys.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/arch/i386/kernel/acpi/boot.c |    5 +++--
 25-akpm/arch/i386/kernel/mpparse.c   |   11 ++++++-----
 25-akpm/arch/x86_64/kernel/mpparse.c |   13 +++++++------
 25-akpm/include/asm-i386/mpspec.h    |    2 +-
 25-akpm/include/asm-x86_64/mpspec.h  |    2 +-
 5 files changed, 18 insertions(+), 15 deletions(-)

diff -puN arch/i386/kernel/acpi/boot.c~incorrect-pci-interrupt-assignment-on-es7000-for-platform-gsi arch/i386/kernel/acpi/boot.c
--- 25/arch/i386/kernel/acpi/boot.c~incorrect-pci-interrupt-assignment-on-es7000-for-platform-gsi	2004-09-26 17:20:47.145248512 -0700
+++ 25-akpm/arch/i386/kernel/acpi/boot.c	2004-09-26 17:20:47.155246992 -0700
@@ -450,6 +450,7 @@ int acpi_gsi_to_irq(u32 gsi, unsigned in
 unsigned int acpi_register_gsi(u32 gsi, int edge_level, int active_high_low)
 {
 	unsigned int irq;
+	unsigned int plat_gsi = gsi;
 
 #ifdef CONFIG_PCI
 	/*
@@ -471,10 +472,10 @@ unsigned int acpi_register_gsi(u32 gsi, 
 
 #ifdef CONFIG_X86_IO_APIC
 	if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) {
-		mp_register_gsi(gsi, edge_level, active_high_low);
+		plat_gsi = mp_register_gsi(gsi, edge_level, active_high_low);
 	}
 #endif
-	acpi_gsi_to_irq(gsi, &irq);
+	acpi_gsi_to_irq(plat_gsi, &irq);
 	return irq;
 }
 EXPORT_SYMBOL(acpi_register_gsi);
diff -puN arch/i386/kernel/mpparse.c~incorrect-pci-interrupt-assignment-on-es7000-for-platform-gsi arch/i386/kernel/mpparse.c
--- 25/arch/i386/kernel/mpparse.c~incorrect-pci-interrupt-assignment-on-es7000-for-platform-gsi	2004-09-26 17:20:47.147248208 -0700
+++ 25-akpm/arch/i386/kernel/mpparse.c	2004-09-26 17:20:47.156246840 -0700
@@ -1051,7 +1051,7 @@ void __init mp_config_acpi_legacy_irqs (
 
 int (*platform_rename_gsi)(int ioapic, int gsi);
 
-void mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
+int mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
 {
 	int			ioapic = -1;
 	int			ioapic_pin = 0;
@@ -1060,13 +1060,13 @@ void mp_register_gsi (u32 gsi, int edge_
 #ifdef CONFIG_ACPI_BUS
 	/* Don't set up the ACPI SCI because it's already set up */
 	if (acpi_fadt.sci_int == gsi)
-		return;
+		return gsi;
 #endif
 
 	ioapic = mp_find_ioapic(gsi);
 	if (ioapic < 0) {
 		printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi);
-		return;
+		return gsi;
 	}
 
 	ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
@@ -1085,12 +1085,12 @@ void mp_register_gsi (u32 gsi, int edge_
 		printk(KERN_ERR "Invalid reference to IOAPIC pin "
 			"%d-%d\n", mp_ioapic_routing[ioapic].apic_id, 
 			ioapic_pin);
-		return;
+		return gsi;
 	}
 	if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
 		Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
 			mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
-		return;
+		return gsi;
 	}
 
 	mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
@@ -1098,6 +1098,7 @@ void mp_register_gsi (u32 gsi, int edge_
 	io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
 		    edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1,
 		    active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1);
+	return gsi;
 }
 
 #endif /*CONFIG_X86_IO_APIC && (CONFIG_ACPI_INTERPRETER || CONFIG_ACPI_BOOT)*/
diff -puN include/asm-i386/mpspec.h~incorrect-pci-interrupt-assignment-on-es7000-for-platform-gsi include/asm-i386/mpspec.h
--- 25/include/asm-i386/mpspec.h~incorrect-pci-interrupt-assignment-on-es7000-for-platform-gsi	2004-09-26 17:20:47.148248056 -0700
+++ 25-akpm/include/asm-i386/mpspec.h	2004-09-26 17:20:47.157246688 -0700
@@ -33,7 +33,7 @@ extern void mp_register_lapic_address (u
 extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base);
 extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 gsi);
 extern void mp_config_acpi_legacy_irqs (void);
-extern void mp_register_gsi (u32 gsi, int edge_level, int active_high_low);
+extern int mp_register_gsi (u32 gsi, int edge_level, int active_high_low);
 #endif /*CONFIG_ACPI_BOOT*/
 
 #define PHYSID_ARRAY_SIZE	BITS_TO_LONGS(MAX_APICS)
diff -puN arch/x86_64/kernel/mpparse.c~incorrect-pci-interrupt-assignment-on-es7000-for-platform-gsi arch/x86_64/kernel/mpparse.c
--- 25/arch/x86_64/kernel/mpparse.c~incorrect-pci-interrupt-assignment-on-es7000-for-platform-gsi	2004-09-26 17:20:47.150247752 -0700
+++ 25-akpm/arch/x86_64/kernel/mpparse.c	2004-09-26 17:20:47.158246536 -0700
@@ -895,25 +895,25 @@ void __init mp_config_acpi_legacy_irqs (
 	return;
 }
 
-void mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
+int mp_register_gsi(u32 gsi, int edge_level, int active_high_low)
 {
 	int			ioapic = -1;
 	int			ioapic_pin = 0;
 	int			idx, bit = 0;
 
 	if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
-		return;
+		return gsi;
 
 #ifdef CONFIG_ACPI_BUS
 	/* Don't set up the ACPI SCI because it's already set up */
 	if (acpi_fadt.sci_int == gsi)
-		return;
+		return gsi;
 #endif
 
 	ioapic = mp_find_ioapic(gsi);
 	if (ioapic < 0) {
 		printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi);
-		return;
+		return gsi;
 	}
 
 	ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_start;
@@ -929,12 +929,12 @@ void mp_register_gsi (u32 gsi, int edge_
 		printk(KERN_ERR "Invalid reference to IOAPIC pin "
 			"%d-%d\n", mp_ioapic_routing[ioapic].apic_id, 
 			ioapic_pin);
-		return;
+		return gsi;
 	}
 	if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
 		Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
 			mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
-		return;
+		return gsi;
 	}
 
 	mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
@@ -942,6 +942,7 @@ void mp_register_gsi (u32 gsi, int edge_
 	io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
 		edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1,
 		active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1);
+	return gsi;
 }
 
 #endif /*CONFIG_X86_IO_APIC*/
diff -puN include/asm-x86_64/mpspec.h~incorrect-pci-interrupt-assignment-on-es7000-for-platform-gsi include/asm-x86_64/mpspec.h
--- 25/include/asm-x86_64/mpspec.h~incorrect-pci-interrupt-assignment-on-es7000-for-platform-gsi	2004-09-26 17:20:47.152247448 -0700
+++ 25-akpm/include/asm-x86_64/mpspec.h	2004-09-26 17:20:47.158246536 -0700
@@ -188,7 +188,7 @@ extern void mp_register_lapic_address (u
 extern void mp_register_ioapic (u8 id, u32 address, u32 gsi_base);
 extern void mp_override_legacy_irq (u8 bus_irq, u8 polarity, u8 trigger, u32 gsi);
 extern void mp_config_acpi_legacy_irqs (void);
-extern void mp_register_gsi (u32 gsi, int edge_level, int active_high_low);
+extern int mp_register_gsi (u32 gsi, int edge_level, int active_high_low);
 #endif /*CONFIG_X86_IO_APIC*/
 #endif
 
_
