VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / arch / x86_64 / kernel / io_apic.c
index 2fceed5..6cb45b7 100644 (file)
@@ -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
@@ -237,6 +237,7 @@ void __init check_ioapic(void)
                        for (func = 0; func < 8; func++) { 
                                u32 class;
                                u32 vendor;
+                               u8 type;
                                class = read_pci_config(num,slot,func,
                                                        PCI_CLASS_REVISION);
                                if (class == 0xffffffff)
@@ -251,14 +252,15 @@ void __init check_ioapic(void)
                                switch (vendor) { 
                                case PCI_VENDOR_ID_VIA:
 #ifdef CONFIG_GART_IOMMU
-                                       if (end_pfn >= (0xffffffff>>PAGE_SHIFT) &&
+                                       if ((end_pfn >= (0xffffffff>>PAGE_SHIFT) ||
+                                            force_iommu) &&
                                            !iommu_aperture_allowed) {
                                                printk(KERN_INFO
     "Looks like a VIA chipset. Disabling IOMMU. Overwrite with \"iommu=allowed\"\n");
                                                iommu_aperture_disabled = 1;
                                        }
 #endif
-                                       /* FALL THROUGH */
+                                       return;
                                case PCI_VENDOR_ID_NVIDIA:
 #ifndef CONFIG_SMP
                                        printk(KERN_INFO 
@@ -270,8 +272,8 @@ void __init check_ioapic(void)
                                } 
 
                                /* No multi-function device? */
-                               u8 type = read_pci_config_byte(num,slot,func,
-                                                              PCI_HEADER_TYPE);
+                               type = read_pci_config_byte(num,slot,func,
+                                                           PCI_HEADER_TYPE);
                                if (!(type & 0x80))
                                        break;
                        } 
@@ -654,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);
@@ -666,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;
@@ -923,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)
@@ -1382,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.
@@ -1394,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);
@@ -1735,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");
 }
 
 /*