From 4959674753873b6dc7bb2c045a4fb62590cdc7b5 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 3 Feb 2004 18:31:59 -0800 Subject: [PATCH] [PATCH] ia32 MSI vector handling fix From: "Nakajima, Jun" To get the vector-based interrupt handling work, we need to give the vector number to device drivers instead of the IRQ if IRQ < 16. It was not happening for SCI, and the patch fixes it. In many cases, the IRQ for SCI is 9, and the problem was not detected, but one particular machine exposed the bug. --- arch/i386/kernel/acpi/boot.c | 10 +++++++++- arch/i386/kernel/mpparse.c | 11 ++++------- drivers/acpi/osl.c | 4 ++-- include/asm-i386/acpi.h | 1 + 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 5b67389c6c449..b4feecc962e75 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -311,7 +312,14 @@ __setup("acpi_pic_sci=", acpi_pic_sci_setup); #endif /* CONFIG_ACPI_BUS */ - +#ifdef CONFIG_X86_IO_APIC +int acpi_irq_to_vector(u32 irq) +{ + if (use_pci_vector() && !platform_legacy_irq(irq)) + irq = IO_APIC_VECTOR(irq); + return irq; +} +#endif static unsigned long __init acpi_scan_rsdp ( diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c index f7750e9233485..6f0be72349d49 100644 --- a/arch/i386/kernel/mpparse.c +++ b/arch/i386/kernel/mpparse.c @@ -1126,7 +1126,8 @@ void __init mp_parse_prt (void) /* Don't set up the ACPI SCI because it's already set up */ if (acpi_fadt.sci_int == irq) { - entry->irq = irq; /*we still need to set entry's irq*/ + irq = acpi_irq_to_vector(irq); + entry->irq = irq; /* we still need to set entry's irq */ continue; } @@ -1156,18 +1157,14 @@ void __init mp_parse_prt (void) if ((1<irq = irq; + entry->irq = acpi_irq_to_vector(irq); continue; } mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<irq = irq; + entry->irq = acpi_irq_to_vector(irq); } printk(KERN_DEBUG "%02x:%02x:%02x[%c] -> %d-%d -> IRQ %d\n", entry->id.segment, entry->id.bus, diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 913aaf3852a83..8f506d258b842 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -249,7 +249,7 @@ acpi_os_install_interrupt_handler(u32 irq, OSD_HANDLER handler, void *context) */ irq = acpi_fadt.sci_int; -#ifdef CONFIG_IA64 +#if defined(CONFIG_IA64) || defined(CONFIG_PCI_USE_VECTOR) irq = acpi_irq_to_vector(irq); if (irq < 0) { printk(KERN_ERR PREFIX "SCI (ACPI interrupt %d) not registered\n", @@ -272,7 +272,7 @@ acpi_status acpi_os_remove_interrupt_handler(u32 irq, OSD_HANDLER handler) { if (irq) { -#ifdef CONFIG_IA64 +#if defined(CONFIG_IA64) || defined(CONFIG_PCI_USE_VECTOR) irq = acpi_irq_to_vector(irq); #endif free_irq(irq, acpi_irq); diff --git a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h index 1d21e333b3245..d7d2c9aa5907c 100644 --- a/include/asm-i386/acpi.h +++ b/include/asm-i386/acpi.h @@ -116,6 +116,7 @@ extern int acpi_noirq; #ifdef CONFIG_X86_IO_APIC extern int skip_ioapic_setup; +extern int acpi_irq_to_vector(u32 irq); static inline void disable_ioapic_setup(void) { -- 2.53.0