Commit 0342e162 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] Fix and Reenable MSI Support on x86_64

From: long <tlnguyen@snoqualmie.dp.intel.com>

MSI support for x86_64 is currently disabled in the kernel 2.6.x.  Below is
the patch, which provides a fix and reenable it.

In addition, the patch provides a info message during kernel boot if
configuring vector-base indexing.

Cc: Andi Kleen <ak@muc.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 8c05319f
......@@ -1411,12 +1411,17 @@ void __init print_IO_APIC(void)
);
}
}
if (use_pci_vector())
printk(KERN_INFO "Using vector-based indexing\n");
printk(KERN_DEBUG "IRQ to pin mappings:\n");
for (i = 0; i < NR_IRQS; i++) {
struct irq_pin_list *entry = irq_2_pin + i;
if (entry->pin < 0)
continue;
printk(KERN_DEBUG "IRQ%d ", i);
if (use_pci_vector() && !platform_legacy_irq(i))
printk(KERN_DEBUG "IRQ%d ", IO_APIC_VECTOR(i));
else
printk(KERN_DEBUG "IRQ%d ", i);
for (;;) {
printk("-> %d:%d", entry->apic, entry->pin);
if (!entry->next)
......
......@@ -47,6 +47,12 @@
BI(x,8) BI(x,9) BI(x,a) BI(x,b) \
BI(x,c) BI(x,d) BI(x,e) BI(x,f)
#define BUILD_14_IRQS(x) \
BI(x,0) BI(x,1) BI(x,2) BI(x,3) \
BI(x,4) BI(x,5) BI(x,6) BI(x,7) \
BI(x,8) BI(x,9) BI(x,a) BI(x,b) \
BI(x,c) BI(x,d)
/*
* ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts:
* (these are usually mapped to vectors 0x20-0x2f)
......@@ -68,9 +74,15 @@ BUILD_16_IRQS(0x0)
BUILD_16_IRQS(0x4) BUILD_16_IRQS(0x5) BUILD_16_IRQS(0x6) BUILD_16_IRQS(0x7)
BUILD_16_IRQS(0x8) BUILD_16_IRQS(0x9) BUILD_16_IRQS(0xa) BUILD_16_IRQS(0xb)
BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd)
#ifdef CONFIG_PCI_USE_VECTOR
BUILD_14_IRQS(0xe)
#endif
#endif
#undef BUILD_16_IRQS
#undef BUILD_14_IRQS
#undef BI
......@@ -83,6 +95,12 @@ BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd)
IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \
IRQ(x,c), IRQ(x,d), IRQ(x,e), IRQ(x,f)
#define IRQLIST_14(x) \
IRQ(x,0), IRQ(x,1), IRQ(x,2), IRQ(x,3), \
IRQ(x,4), IRQ(x,5), IRQ(x,6), IRQ(x,7), \
IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \
IRQ(x,c), IRQ(x,d)
void (*interrupt[NR_IRQS])(void) = {
IRQLIST_16(0x0),
......@@ -91,11 +109,17 @@ void (*interrupt[NR_IRQS])(void) = {
IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7),
IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb),
IRQLIST_16(0xc), IRQLIST_16(0xd)
#ifdef CONFIG_PCI_USE_VECTOR
, IRQLIST_14(0xe)
#endif
#endif
};
#undef IRQ
#undef IRQLIST_16
#undef IRQLIST_14
/*
* This is the 'legacy' 8259A Programmable Interrupt Controller,
......
......@@ -67,8 +67,8 @@ static struct irq_pin_list {
short apic, pin, next;
} irq_2_pin[PIN_MAP_SIZE];
int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1};
#ifdef CONFIG_PCI_USE_VECTOR
int vector_irq[NR_IRQS] = { [0 ... NR_IRQS -1] = -1};
#define vector_to_irq(vector) \
(platform_legacy_irq(vector) ? vector : vector_irq[vector])
#else
......@@ -656,10 +656,14 @@ static inline int IO_APIC_irq_trigger(int irq)
/* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
u8 irq_vector[NR_IRQ_VECTORS] = { FIRST_DEVICE_VECTOR , 0 };
#ifndef CONFIG_PCI_USE_VECTOR
#ifdef CONFIG_PCI_USE_VECTOR
int assign_irq_vector(int irq)
#else
int __init assign_irq_vector(int irq)
#endif
{
static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
BUG_ON(irq >= NR_IRQ_VECTORS);
if (IO_APIC_VECTOR(irq) > 0)
return IO_APIC_VECTOR(irq);
......@@ -668,18 +672,19 @@ int __init assign_irq_vector(int irq)
if (current_vector == IA32_SYSCALL_VECTOR)
goto next;
if (current_vector > FIRST_SYSTEM_VECTOR) {
if (current_vector >= FIRST_SYSTEM_VECTOR) {
offset++;
if (!(offset%8))
return -ENOSPC;
current_vector = FIRST_DEVICE_VECTOR + offset;
}
if (current_vector == FIRST_SYSTEM_VECTOR)
panic("ran out of interrupt sources!");
vector_irq[current_vector] = irq;
if (irq != AUTO_ASSIGN)
IO_APIC_VECTOR(irq) = current_vector;
IO_APIC_VECTOR(irq) = current_vector;
return current_vector;
}
#endif
extern void (*interrupt[NR_IRQS])(void);
static struct hw_interrupt_type ioapic_level_type;
......@@ -925,12 +930,17 @@ void __init print_IO_APIC(void)
);
}
}
if (use_pci_vector())
printk(KERN_INFO "Using vector-based indexing\n");
printk(KERN_DEBUG "IRQ to pin mappings:\n");
for (i = 0; i < NR_IRQS; i++) {
struct irq_pin_list *entry = irq_2_pin + i;
if (entry->pin < 0)
continue;
printk(KERN_DEBUG "IRQ%d ", i);
if (use_pci_vector() && !platform_legacy_irq(i))
printk(KERN_DEBUG "IRQ%d ", IO_APIC_VECTOR(i));
else
printk(KERN_DEBUG "IRQ%d ", i);
for (;;) {
printk("-> %d:%d", entry->apic, entry->pin);
if (!entry->next)
......
......@@ -3,7 +3,7 @@
#
config PCI_USE_VECTOR
bool "Vector-based interrupt indexing (MSI)"
depends on (X86_LOCAL_APIC && X86_IO_APIC && !X86_64) || IA64
depends on (X86_LOCAL_APIC && X86_IO_APIC) || IA64
default n
help
This replaces the current existing IRQ-based index interrupt scheme
......
......@@ -78,6 +78,7 @@ struct hw_interrupt_type;
#ifndef __ASSEMBLY__
extern u8 irq_vector[NR_IRQ_VECTORS];
#define IO_APIC_VECTOR(irq) (irq_vector[irq])
#define AUTO_ASSIGN -1
/*
* Various low-level irq details needed by irq.c, process.c,
......
......@@ -11,11 +11,6 @@
#define LAST_DEVICE_VECTOR 232
#define MSI_DEST_MODE MSI_LOGICAL_MODE
#define MSI_TARGET_CPU_SHIFT 12
#ifdef CONFIG_SMP
#define MSI_TARGET_CPU logical_smp_processor_id()
#else
#define MSI_TARGET_CPU TARGET_CPUS
#endif
#define MSI_TARGET_CPU TARGET_CPUS
#endif /* ASM_MSI_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment