X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fx86_64%2Fkernel%2Fio_apic.c;h=6cb45b7eb857122b4b63cd3bcee2b89303737300;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=718504a3274161d07feb4dd42449c447f42e7fa2;hpb=db216c3d5e4c040e557a50f8f5d35d5c415e8c1c;p=linux-2.6.git diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 718504a32..6cb45b7eb 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -67,8 +67,8 @@ static struct irq_pin_list { short apic, pin, next; } irq_2_pin[PIN_MAP_SIZE]; -#ifdef CONFIG_PCI_USE_VECTOR -int vector_irq[NR_IRQS] = { [0 ... NR_IRQS -1] = -1}; +int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1}; +#ifdef CONFIG_PCI_MSI #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_MSI +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 @@ next: 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) @@ -1384,7 +1394,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) unsigned long flags; unsigned int dest; - dest = cpu_mask_to_apicid(mk_cpumask_const(mask)); + dest = cpu_mask_to_apicid(mask); /* * Only the first 8 bits are valid. @@ -1396,7 +1406,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) spin_unlock_irqrestore(&ioapic_lock, flags); } -#ifdef CONFIG_PCI_USE_VECTOR +#ifdef CONFIG_PCI_MSI static unsigned int startup_edge_ioapic_vector(unsigned int vector) { int irq = vector_to_irq(vector); @@ -1737,7 +1747,7 @@ static inline void check_timer(void) return; } printk(" failed :(.\n"); - panic("IO-APIC + timer doesn't work! pester mingo@redhat.com"); + panic("IO-APIC + timer doesn't work! Try using the 'noapic' kernel parameter\n"); } /*