diff -Naur linux-2.6.6-rc1/arch/ia64/kernel/iosapic.c linux-2.6.6-rc1-changed/arch/ia64/kernel/iosapic.c
--- linux-2.6.6-rc1/arch/ia64/kernel/iosapic.c	2004-04-19 16:10:25.970346988 +0900
+++ linux-2.6.6-rc1-changed/arch/ia64/kernel/iosapic.c	2004-04-19 16:25:23.251036926 +0900
@@ -101,15 +101,23 @@
 
 /* These tables map IA-64 vectors to the IOSAPIC pin that generates this vector. */
 
-static struct iosapic_intr_info {
+struct iosapic_pin {
+	struct list_head pin_list;	/* IOSAPIC pins which share the same vector */
 	char		*addr;		/* base address of IOSAPIC */
 	u32		low32;		/* current value of low word of Redirection table entry */
 	unsigned int	gsi_base;	/* first GSI assigned to this IOSAPIC */
-	char		rte_index;	/* IOSAPIC RTE index (-1 => not an IOSAPIC interrupt) */
-	unsigned char	dmode	: 3;	/* delivery mode (see iosapic.h) */
+	char		rte_index;	/* IOSAPIC RTE index */
 	unsigned char 	polarity: 1;	/* interrupt polarity (see iosapic.h) */
+};
+
+static struct iosapic_intr_info {
+	struct list_head pin_head;	/* List head of IOSAPIC pins */
+	struct iosapic_pin pin;		/* First entry of IOSAPIC pins list */
+	int		count;		/* # of pins (0 => not an IOSAPIC interrupt) */
+	unsigned char	dmode	: 3;	/* delivery mode (see iosapic.h) */
 	unsigned char	trigger	: 1;	/* trigger mode (see iosapic.h) */
-} iosapic_intr_info[IA64_NUM_VECTORS];
+	unsigned char	type	: 1;	/* Vector type */
+} iosapic_intr_info[IA64_NUM_VECTORS] __cacheline_aligned;
 
 static struct iosapic {
 	char		*addr;		/* base address of IOSAPIC */
@@ -142,10 +150,14 @@
 _gsi_to_vector (unsigned int gsi)
 {
 	struct iosapic_intr_info *info;
+	struct iosapic_pin *pin;
 
-	for (info = iosapic_intr_info; info < iosapic_intr_info + IA64_NUM_VECTORS; ++info)
-		if (info->gsi_base + info->rte_index == gsi)
-			return info - iosapic_intr_info;
+	for (info = iosapic_intr_info; info < iosapic_intr_info + IA64_NUM_VECTORS; ++info) {
+		list_for_each_entry(pin, &info->pin_head, pin_list) {
+			if (pin->gsi_base + pin->rte_index == gsi)
+				return info - iosapic_intr_info;
+		}
+	}
 	return -1;
 }
 
@@ -177,15 +189,13 @@
 	char *addr;
 	int rte_index;
 	char redir;
+	struct iosapic_pin *pin;
 
 	DBG(KERN_DEBUG"IOSAPIC: routing vector %d to 0x%x\n", vector, dest);
 
-	rte_index = iosapic_intr_info[vector].rte_index;
-	if (rte_index < 0)
+	if (!iosapic_intr_info[vector].count)
 		return;		/* not an IOSAPIC interrupt */
 
-	addr    = iosapic_intr_info[vector].addr;
-	pol     = iosapic_intr_info[vector].polarity;
 	trigger = iosapic_intr_info[vector].trigger;
 	dmode   = iosapic_intr_info[vector].dmode;
 
@@ -193,31 +203,47 @@
 #ifdef CONFIG_SMP
 	{
 		unsigned int irq;
+		cpumask_t cpumask;
 
 		for (irq = 0; irq < NR_IRQS; ++irq)
 			if (irq_to_vector(irq) == vector) {
-				set_irq_affinity_info(irq, (int)(dest & 0xffff), redir);
+				/* All pins should use the same destination CPU */
+				cpumask = get_irq_affinity_info(irq);
+				if (cpumask != CPU_MASK_ALL)
+					dest = cpu_physical_id(first_cpu(mask));
+				else
+					set_irq_affinity_info(irq, (int)(dest & 0xffff), redir);
 				break;
 			}
 	}
 #endif
 
-	low32 = ((pol << IOSAPIC_POLARITY_SHIFT) |
-		 (trigger << IOSAPIC_TRIGGER_SHIFT) |
-		 (dmode << IOSAPIC_DELIVERY_SHIFT) |
-		 ((mask ? 1 : 0) << IOSAPIC_MASK_SHIFT) |
-		 vector);
-
 	/* dest contains both id and eid */
 	high32 = (dest << IOSAPIC_DEST_SHIFT);
 
 	spin_lock_irqsave(&iosapic_lock, flags);
 	{
-		writel(IOSAPIC_RTE_HIGH(rte_index), addr + IOSAPIC_REG_SELECT);
-		writel(high32, addr + IOSAPIC_WINDOW);
-		writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
-		writel(low32, addr + IOSAPIC_WINDOW);
-		iosapic_intr_info[vector].low32 = low32;
+		list_for_each_entry(pin, &iosapic_intr_info[vector].pin_head, pin_list) {
+			/* Don't change RTE which is already unmasked */
+			if (!(pin->low32 & IOSAPIC_MASK))
+				continue;
+
+			rte_index = pin->rte_index;
+			addr    = pin->addr;
+			pol     = pin->polarity;
+
+			low32 = ((pol << IOSAPIC_POLARITY_SHIFT) |
+				 (trigger << IOSAPIC_TRIGGER_SHIFT) |
+				 (dmode << IOSAPIC_DELIVERY_SHIFT) |
+				 ((mask ? 1 : 0) << IOSAPIC_MASK_SHIFT) |
+				 vector);
+
+			writel(IOSAPIC_RTE_HIGH(rte_index), addr + IOSAPIC_REG_SELECT);
+			writel(high32, addr + IOSAPIC_WINDOW);
+			writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
+			writel(low32, addr + IOSAPIC_WINDOW);
+			pin->low32 = low32;
+		}
 	}
 	spin_unlock_irqrestore(&iosapic_lock, flags);
 }
@@ -236,21 +262,24 @@
 	u32 low32;
 	int rte_index;
 	ia64_vector vec = irq_to_vector(irq);
+	struct iosapic_pin *pin;
 
-	addr = iosapic_intr_info[vec].addr;
-	rte_index = iosapic_intr_info[vec].rte_index;
-
-	if (rte_index < 0)
+	if (!iosapic_intr_info[vec].count)
 		return;			/* not an IOSAPIC interrupt! */
 
 	spin_lock_irqsave(&iosapic_lock, flags);
 	{
-		writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
+		list_for_each_entry(pin, &iosapic_intr_info[vec].pin_head, pin_list) {
+			addr = pin->addr;
+			rte_index = pin->rte_index;
+			
+			writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
 
-		/* set only the mask bit */
-		low32 = iosapic_intr_info[vec].low32 |= IOSAPIC_MASK;
+			/* set only the mask bit */
+			low32 = pin->low32 |= IOSAPIC_MASK;
 
-		writel(low32, addr + IOSAPIC_WINDOW);
+			writel(low32, addr + IOSAPIC_WINDOW);
+		}
 	}
 	spin_unlock_irqrestore(&iosapic_lock, flags);
 }
@@ -263,17 +292,21 @@
 	u32 low32;
 	int rte_index;
 	ia64_vector vec = irq_to_vector(irq);
+	struct iosapic_pin *pin;
 
-	addr = iosapic_intr_info[vec].addr;
-	rte_index = iosapic_intr_info[vec].rte_index;
-	if (rte_index < 0)
+	if (!iosapic_intr_info[vec].count)
 		return;			/* not an IOSAPIC interrupt! */
 
 	spin_lock_irqsave(&iosapic_lock, flags);
 	{
-		writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
-		low32 = iosapic_intr_info[vec].low32 &= ~IOSAPIC_MASK;
-		writel(low32, addr + IOSAPIC_WINDOW);
+		list_for_each_entry(pin, &iosapic_intr_info[vec].pin_head, pin_list) {
+			addr = pin->addr;
+			rte_index = pin->rte_index;
+
+			writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
+			low32 = pin->low32 &= ~IOSAPIC_MASK;
+			writel(low32, addr + IOSAPIC_WINDOW);
+		}
 	}
 	spin_unlock_irqrestore(&iosapic_lock, flags);
 }
@@ -289,6 +322,7 @@
 	char *addr;
 	int redir = (irq & IA64_IRQ_REDIRECTED) ? 1 : 0;
 	ia64_vector vec;
+	struct iosapic_pin *pin;
 
 	irq &= (~IA64_IRQ_REDIRECTED);
 	vec = irq_to_vector(irq);
@@ -298,10 +332,7 @@
 
 	dest = cpu_physical_id(first_cpu(mask));
 
-	rte_index = iosapic_intr_info[vec].rte_index;
-	addr = iosapic_intr_info[vec].addr;
-
-	if (rte_index < 0)
+	if (!iosapic_intr_info[vec].count)
 		return;			/* not an IOSAPIC interrupt */
 
 	set_irq_affinity_info(irq, dest, redir);
@@ -311,21 +342,26 @@
 
 	spin_lock_irqsave(&iosapic_lock, flags);
 	{
-		/* get current delivery mode by reading the low32 */
-		writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
-		low32 = iosapic_intr_info[vec].low32 & ~(7 << IOSAPIC_DELIVERY_SHIFT);
-		if (redir)
-		        /* change delivery mode to lowest priority */
-			low32 |= (IOSAPIC_LOWEST_PRIORITY << IOSAPIC_DELIVERY_SHIFT);
-		else
-		        /* change delivery mode to fixed */
-			low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT);
-
-		iosapic_intr_info[vec].low32 = low32;
-		writel(IOSAPIC_RTE_HIGH(rte_index), addr + IOSAPIC_REG_SELECT);
-		writel(high32, addr + IOSAPIC_WINDOW);
-		writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
-		writel(low32, addr + IOSAPIC_WINDOW);
+		list_for_each_entry(pin, &iosapic_intr_info[vec].pin_head, pin_list) {
+			rte_index = pin->rte_index;
+			addr = pin->addr;
+
+			/* get current delivery mode by reading the low32 */
+			writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
+			low32 = pin->low32 & ~(7 << IOSAPIC_DELIVERY_SHIFT);
+			if (redir)
+				/* change delivery mode to lowest priority */
+				low32 |= (IOSAPIC_LOWEST_PRIORITY << IOSAPIC_DELIVERY_SHIFT);
+			else
+				/* change delivery mode to fixed */
+				low32 |= (IOSAPIC_FIXED << IOSAPIC_DELIVERY_SHIFT);
+
+			pin->low32 = low32;
+			writel(IOSAPIC_RTE_HIGH(rte_index), addr + IOSAPIC_REG_SELECT);
+			writel(high32, addr + IOSAPIC_WINDOW);
+			writel(IOSAPIC_RTE_LOW(rte_index), addr + IOSAPIC_REG_SELECT);
+			writel(low32, addr + IOSAPIC_WINDOW);
+		}
 	}
 	spin_unlock_irqrestore(&iosapic_lock, flags);
 #endif
@@ -346,8 +382,11 @@
 iosapic_end_level_irq (unsigned int irq)
 {
 	ia64_vector vec = irq_to_vector(irq);
+	struct iosapic_pin *pin;
 
-	writel(vec, iosapic_intr_info[vec].addr + IOSAPIC_EOI);
+	list_for_each_entry(pin, &iosapic_intr_info[vec].pin_head, pin_list) {
+		writel(vec, pin->addr + IOSAPIC_EOI);
+	}
 }
 
 #define iosapic_shutdown_level_irq	mask_irq
@@ -427,6 +466,30 @@
 }
 
 /*
+ * Find a sharable vector.
+ *
+ * NOTE: This function assumes that platform interrupt doesn't share
+ * the vector.
+ */
+static int
+iosapic_find_sharable_vector (unsigned long trigger)
+{
+	int i;
+	static int next_vector = IA64_FIRST_DEVICE_VECTOR;
+
+	for (i = 0; i < IA64_LAST_DEVICE_VECTOR - IA64_FIRST_DEVICE_VECTOR + 1; i++) {
+		if (next_vector > IA64_LAST_DEVICE_VECTOR)
+			next_vector = IA64_FIRST_DEVICE_VECTOR;
+
+		if (iosapic_intr_info[next_vector].type == IOSAPIC_VECTOR_SHARABLE &&
+		    iosapic_intr_info[next_vector].trigger == trigger)
+			return next_vector++;
+	}
+
+	return -1;
+}
+
+/*
  * if the given vector is already owned by other,
  *  assign a new vector for the other and make the vector available
  */
@@ -435,22 +498,20 @@
 {
 	int new_vector;
 
-	if (iosapic_intr_info[vector].rte_index >= 0 || iosapic_intr_info[vector].addr
-	    || iosapic_intr_info[vector].gsi_base || iosapic_intr_info[vector].dmode
-	    || iosapic_intr_info[vector].polarity || iosapic_intr_info[vector].trigger)
+	if (!iosapic_intr_info[vector].count)
 	{
 		new_vector = assign_irq_vector(AUTO_ASSIGN);
 		printk(KERN_INFO "Reassigning vector %d to %d\n", vector, new_vector);
 		memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector],
 		       sizeof(struct iosapic_intr_info));
 		memset(&iosapic_intr_info[vector], 0, sizeof(struct iosapic_intr_info));
-		iosapic_intr_info[vector].rte_index = -1;
+		INIT_LIST_HEAD(&iosapic_intr_info[vector].pin_head);
 	}
 }
 
 static void
 register_intr (unsigned int gsi, int vector, unsigned char delivery,
-	       unsigned long polarity, unsigned long trigger)
+	       unsigned long polarity, unsigned long trigger, unsigned long type)
 {
 	irq_desc_t *idesc;
 	struct hw_interrupt_type *irq_type;
@@ -458,6 +519,7 @@
 	int index;
 	unsigned long gsi_base;
 	char *iosapic_address;
+	struct iosapic_pin *pin, *tmp;
 
 	index = find_iosapic(gsi);
 	if (index < 0) {
@@ -468,13 +530,86 @@
 	iosapic_address = iosapic_lists[index].addr;
 	gsi_base = iosapic_lists[index].gsi_base;
 
-	rte_index = gsi - gsi_base;
-	iosapic_intr_info[vector].rte_index = rte_index;
-	iosapic_intr_info[vector].polarity = polarity;
-	iosapic_intr_info[vector].dmode    = delivery;
-	iosapic_intr_info[vector].addr     = iosapic_address;
-	iosapic_intr_info[vector].gsi_base = gsi_base;
-	iosapic_intr_info[vector].trigger  = trigger;
+	/*
+	 * Only interrupt sources whose delivery mode is IOSAPIC_LOWEST_PRIORITY or
+	 * IOSAPIC_FIXED can share the vector in the current implementation.
+	 */
+	if (delivery != IOSAPIC_LOWEST_PRIORITY &&
+	    delivery != IOSAPIC_FIXED &&
+	    type != IOSAPIC_VECTOR_EXCLUSIVE)
+	{
+		type = IOSAPIC_VECTOR_EXCLUSIVE;
+	}
+
+	pin = NULL;
+	list_for_each_entry(tmp, &iosapic_intr_info[vector].pin_head, pin_list) {
+		if (tmp->gsi_base + tmp->rte_index == gsi) {
+			pin = tmp;
+			break;
+		}
+	}
+
+	if (!pin) {
+		/*
+		 * Register a new interrupt
+		 */
+		if (!iosapic_intr_info[vector].count) {
+			pin = &iosapic_intr_info[vector].pin;
+			iosapic_intr_info[vector].dmode   = delivery;
+			iosapic_intr_info[vector].trigger = trigger;
+			iosapic_intr_info[vector].type    = type;
+		}
+		else if (type == IOSAPIC_VECTOR_EXCLUSIVE) {
+			printk (KERN_WARNING "%s: vector %d is in use\n", __FUNCTION__, vector);
+			return;
+		}
+		else if (iosapic_intr_info[vector].type == IOSAPIC_VECTOR_EXCLUSIVE) {
+			printk (KERN_WARNING "%s: cannot share the vector %d\n", __FUNCTION__, vector);
+			return;
+		}
+		else {
+			pin = kmalloc(sizeof(struct iosapic_pin), GFP_KERNEL);
+			if (!pin) {
+				printk (KERN_WARNING "%s: cannot allocate memory\n", __FUNCTION__);
+				return;
+			}
+		}
+		
+		rte_index = gsi - gsi_base;
+		pin->rte_index = rte_index;
+		pin->polarity = polarity;
+		pin->addr     = iosapic_address;
+		pin->gsi_base = gsi_base;
+		pin->low32    = IOSAPIC_MASK;
+
+		list_add_tail(&pin->pin_list, &iosapic_intr_info[vector].pin_head);
+		iosapic_intr_info[vector].count++;
+	}
+	else {
+		/*
+		 * Override a existing interupt
+		 */
+		if (iosapic_intr_info[vector].count > 1) {
+			if (iosapic_intr_info[vector].trigger != trigger) {
+				printk (KERN_WARNING "%s: cannot change trigger mode\n", __FUNCTION__);
+				return;
+			}
+			if (type == IOSAPIC_VECTOR_EXCLUSIVE) {
+				printk (KERN_WARNING "%s: vector %d is already shared\n", __FUNCTION__, vector);
+				return;
+			}
+		}
+
+		rte_index = gsi - gsi_base;
+		pin->rte_index = rte_index;
+		pin->polarity = polarity;
+		pin->addr     = iosapic_address;
+		pin->gsi_base = gsi_base;
+		pin->low32    = IOSAPIC_MASK;
+		iosapic_intr_info[vector].dmode   = delivery;
+		iosapic_intr_info[vector].trigger = trigger;
+		iosapic_intr_info[vector].type    = type;
+	}
 
 	if (trigger == IOSAPIC_EDGE)
 		irq_type = &irq_type_iosapic_edge;
@@ -504,10 +639,17 @@
 
 	vector = gsi_to_vector(gsi);
 	if (vector < 0)
-		vector = assign_irq_vector(AUTO_ASSIGN);
+		vector = assign_irq_vector_nopanic(AUTO_ASSIGN);
+
+	if (vector < 0)
+		vector = iosapic_find_sharable_vector(trigger);
+
+	if (vector < 0)
+		panic ("%s: out of interrupt vectors!", __FUNCTION__);
 
 	register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
-		      polarity, trigger);
+		      polarity, trigger,
+		      (trigger == IOSAPIC_EDGE ? IOSAPIC_VECTOR_EXCLUSIVE : IOSAPIC_VECTOR_SHARABLE));
 
 	printk(KERN_INFO "GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
 	       gsi, (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
@@ -555,7 +697,7 @@
 	}
 
 	register_intr(gsi, vector, delivery, polarity,
-		      trigger);
+		      trigger, IOSAPIC_VECTOR_EXCLUSIVE);
 
 	printk(KERN_INFO "PLATFORM int 0x%x: GSI 0x%x(%s,%s) -> CPU 0x%04x vector %d\n",
 	       int_type, gsi, (polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
@@ -581,7 +723,7 @@
 
 	vector = isa_irq_to_vector(isa_irq);
 
-	register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, trigger);
+	register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, polarity, trigger, IOSAPIC_VECTOR_EXCLUSIVE);
 
 	DBG("ISA: IRQ %u -> GSI 0x%x (%s,%s) -> CPU 0x%04x vector %d\n",
 	    isa_irq, gsi, polarity == IOSAPIC_POL_HIGH ? "high" : "low",
@@ -596,8 +738,10 @@
 {
 	int vector;
 
-	for (vector = 0; vector < IA64_NUM_VECTORS; ++vector)
-		iosapic_intr_info[vector].rte_index = -1;	/* mark as unused */
+	for (vector = 0; vector < IA64_NUM_VECTORS; ++vector) {
+		iosapic_intr_info[vector].count = 0;	/* mark as unused */
+		INIT_LIST_HEAD(&iosapic_intr_info[vector].pin_head);
+	}
 
 	pcat_compat = system_pcat_compat;
 	if (pcat_compat) {
@@ -710,12 +854,17 @@
 			/* allocate a vector for this interrupt line */
 			if (pcat_compat && (gsi < 16))
 				vector = isa_irq_to_vector(gsi);
-			else
+			else {
 				/* new GSI; allocate a vector for it */
-				vector = assign_irq_vector(AUTO_ASSIGN);
+				vector = assign_irq_vector_nopanic(AUTO_ASSIGN);
+				if (vector < 0)
+					vector = iosapic_find_sharable_vector(IOSAPIC_LEVEL);
+				if (vector < 0)
+					panic ("%s: out of interrupt vectors!", __FUNCTION__);
+			}
 
 			register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW,
-				      IOSAPIC_LEVEL);
+				      IOSAPIC_LEVEL, IOSAPIC_VECTOR_SHARABLE);
 		}
 		entry->irq = vector;
 		snprintf(pci_id, sizeof(pci_id), "%02x:%02x:%02x[%c]",
@@ -728,7 +877,7 @@
 		idesc = irq_descp(vector);
 		if (idesc->handler != irq_type)
 			register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW,
-				      IOSAPIC_LEVEL);
+				      IOSAPIC_LEVEL, IOSAPIC_VECTOR_SHARABLE);
 
 	}
 }
diff -Naur linux-2.6.6-rc1/arch/ia64/kernel/irq.c linux-2.6.6-rc1-changed/arch/ia64/kernel/irq.c
--- linux-2.6.6-rc1/arch/ia64/kernel/irq.c	2004-04-04 12:38:13.000000000 +0900
+++ linux-2.6.6-rc1-changed/arch/ia64/kernel/irq.c	2004-04-19 16:10:53.513448673 +0900
@@ -935,6 +935,11 @@
 	}
 }
 
+cpumask_t get_irq_affinity_info (unsigned int irq)
+{
+	return irq_affinity[irq];
+}
+
 static int irq_affinity_read_proc (char *page, char **start, off_t off,
 			int count, int *eof, void *data)
 {
diff -Naur linux-2.6.6-rc1/arch/ia64/kernel/irq_ia64.c linux-2.6.6-rc1-changed/arch/ia64/kernel/irq_ia64.c
--- linux-2.6.6-rc1/arch/ia64/kernel/irq_ia64.c	2004-04-19 16:10:25.971323555 +0900
+++ linux-2.6.6-rc1-changed/arch/ia64/kernel/irq_ia64.c	2004-04-19 16:10:53.513448673 +0900
@@ -72,17 +72,25 @@
 	preempt_enable_no_resched();
 }
 
+static int next_vector = IA64_FIRST_DEVICE_VECTOR;
+
 int
 assign_irq_vector (int irq)
 {
-	static int next_vector = IA64_FIRST_DEVICE_VECTOR;
-
 	if (next_vector > IA64_LAST_DEVICE_VECTOR)
 		/* XXX could look for sharable vectors instead of panic'ing... */
 		panic("assign_irq_vector: out of interrupt vectors!");
 	return next_vector++;
 }
 
+int
+assign_irq_vector_nopanic (int irq)
+{
+	if (next_vector > IA64_LAST_DEVICE_VECTOR)
+		return -1;
+	return next_vector++;
+}
+
 extern unsigned int do_IRQ(unsigned long irq, struct pt_regs *regs);
 
 /*
diff -Naur linux-2.6.6-rc1/include/asm-ia64/hw_irq.h linux-2.6.6-rc1-changed/include/asm-ia64/hw_irq.h
--- linux-2.6.6-rc1/include/asm-ia64/hw_irq.h	2004-04-19 16:10:27.139297942 +0900
+++ linux-2.6.6-rc1-changed/include/asm-ia64/hw_irq.h	2004-04-19 16:10:53.514425240 +0900
@@ -83,6 +83,7 @@
 extern struct hw_interrupt_type irq_type_ia64_lsapic;	/* CPU-internal interrupt controller */
 
 extern int assign_irq_vector (int irq);	/* allocate a free vector */
+extern int assign_irq_vector_nopanic (int irq);
 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);
 
diff -Naur linux-2.6.6-rc1/include/asm-ia64/iosapic.h linux-2.6.6-rc1-changed/include/asm-ia64/iosapic.h
--- linux-2.6.6-rc1/include/asm-ia64/iosapic.h	2004-04-04 12:37:23.000000000 +0900
+++ linux-2.6.6-rc1-changed/include/asm-ia64/iosapic.h	2004-04-19 16:10:53.514425240 +0900
@@ -49,6 +49,12 @@
 #define	IOSAPIC_MASK_SHIFT		16
 #define	IOSAPIC_MASK			(1<<IOSAPIC_MASK_SHIFT)
 
+/*
+ * Vector type
+ */
+#define IOSAPIC_VECTOR_EXCLUSIVE	(0)
+#define IOSAPIC_VECTOR_SHARABLE		(1)
+
 #ifndef __ASSEMBLY__
 
 #ifdef CONFIG_IOSAPIC
diff -Naur linux-2.6.6-rc1/include/asm-ia64/irq.h linux-2.6.6-rc1-changed/include/asm-ia64/irq.h
--- linux-2.6.6-rc1/include/asm-ia64/irq.h	2004-04-19 16:10:27.140274509 +0900
+++ linux-2.6.6-rc1-changed/include/asm-ia64/irq.h	2004-04-19 16:10:53.514425240 +0900
@@ -29,6 +29,10 @@
 extern void disable_irq_nosync (unsigned int);
 extern void enable_irq (unsigned int);
 extern void set_irq_affinity_info (unsigned int irq, int dest, int redir);
+#ifdef CONFIG_SMP
+#include <asm/cpumask.h>
+extern cpumask_t get_irq_affinity_info (unsigned int irq);
+#endif /* CONFIG_SMP */
 
 struct irqaction;
 struct pt_regs;
