#define IRQ_DEBUG      0
 
+/* These can be overridden in platform_irq_init */
+int ia64_first_device_vector = IA64_DEF_FIRST_DEVICE_VECTOR;
+int ia64_last_device_vector = IA64_DEF_LAST_DEVICE_VECTOR;
+
 /* default base addr of IPI table */
 void __iomem *ipi_base_addr = ((void __iomem *)
                               (__IA64_UNCACHED_OFFSET | IA64_IPI_DEFAULT_BASE_ADDR));
 };
 EXPORT_SYMBOL(isa_irq_to_vector_map);
 
-static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_NUM_DEVICE_VECTORS)];
+static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_MAX_DEVICE_VECTORS)];
 
 int
 assign_irq_vector (int irq)
                printk(KERN_WARNING "%s: double free!\n", __FUNCTION__);
 }
 
+int
+reserve_irq_vector (int vector)
+{
+       int pos;
+
+       if (vector < IA64_FIRST_DEVICE_VECTOR ||
+           vector > IA64_LAST_DEVICE_VECTOR)
+               return -EINVAL;
+
+       pos = vector - IA64_FIRST_DEVICE_VECTOR;
+       return test_and_set_bit(pos, ia64_vector_mask);
+}
+
 #ifdef CONFIG_SMP
 #      define IS_RESCHEDULE(vec)       (vec == IA64_IPI_RESCHEDULE)
 #else
 
        int i;
        irq_desc_t *base_desc = irq_desc;
 
+       ia64_first_device_vector = IA64_SN2_FIRST_DEVICE_VECTOR;
+       ia64_last_device_vector = IA64_SN2_LAST_DEVICE_VECTOR;
+
        for (i = 0; i < NR_IRQS; i++) {
                if (base_desc[i].handler == &no_irq_type) {
                        base_desc[i].handler = &irq_type_sn;
        /* link it into the sn_irq[irq] list */
        spin_lock(&sn_irq_info_lock);
        list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]);
+       reserve_irq_vector(sn_irq_info->irq_irq);
        spin_unlock(&sn_irq_info_lock);
 
        register_intr_pda(sn_irq_info);
        spin_lock(&sn_irq_info_lock);
        list_del_rcu(&sn_irq_info->list);
        spin_unlock(&sn_irq_info_lock);
+       if (list_empty(sn_irq_lh[sn_irq_info->irq_irq]))
+               free_irq_vector(sn_irq_info->irq_irq);
        call_rcu(&sn_irq_info->rcu, sn_irq_info_free);
        pci_dev_put(pci_dev);
+
 }
 
 static inline void
 
 
 #ifndef CONFIG_X86_IO_APIC
 int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1};
-u8 irq_vector[NR_IRQ_VECTORS] = { FIRST_DEVICE_VECTOR , 0 };
+u8 irq_vector[NR_IRQ_VECTORS];
 #endif
 
 static struct msi_ops *msi_ops;
                return status;
        }
 
+#ifndef CONFIG_X86_IO_APIC
+       irq_vector[0] = FIRST_DEVICE_VECTOR;
+#endif
+
        if (last_alloc_vector < 0) {
                pci_msi_enable = 0;
                printk(KERN_WARNING "PCI: No interrupt vectors available for MSI\n");
 
 #define IA64_CMC_VECTOR                        0x1f    /* corrected machine-check interrupt vector */
 /*
  * Vectors 0x20-0x2f are reserved for legacy ISA IRQs.
+ * Use vectors 0x30-0xe7 as the default device vector range for ia64.
+ * Platforms may choose to reduce this range in platform_irq_setup, but the
+ * platform range must fall within
+ *     [IA64_DEF_FIRST_DEVICE_VECTOR..IA64_DEF_LAST_DEVICE_VECTOR]
  */
-#define IA64_FIRST_DEVICE_VECTOR       0x30
-#define IA64_LAST_DEVICE_VECTOR                0xe7
+extern int ia64_first_device_vector;
+extern int ia64_last_device_vector;
+
+#define IA64_DEF_FIRST_DEVICE_VECTOR   0x30
+#define IA64_DEF_LAST_DEVICE_VECTOR    0xe7
+#define IA64_FIRST_DEVICE_VECTOR       ia64_first_device_vector
+#define IA64_LAST_DEVICE_VECTOR                ia64_last_device_vector
+#define IA64_MAX_DEVICE_VECTORS                (IA64_DEF_LAST_DEVICE_VECTOR - IA64_DEF_FIRST_DEVICE_VECTOR + 1)
 #define IA64_NUM_DEVICE_VECTORS                (IA64_LAST_DEVICE_VECTOR - IA64_FIRST_DEVICE_VECTOR + 1)
 
 #define IA64_MCA_RENDEZ_VECTOR         0xe8    /* MCA rendez interrupt */
 
 extern int assign_irq_vector (int irq);        /* allocate a free vector */
 extern void free_irq_vector (int vector);
+extern int reserve_irq_vector (int vector);
 extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect);
 extern void register_percpu_irq (ia64_vector vec, struct irqaction *action);