summaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel
diff options
context:
space:
mode:
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>2005-07-11 06:49:00 +0200
committerTony Luck <tony.luck@intel.com>2005-07-11 19:30:07 +0200
commit3b5cc09033f49d004006acf44e5b05036bd46a85 (patch)
treedcae13f5768234fe59736e877885ee6d8b4fc0fc /arch/ia64/kernel
parent[IA64] use msleep_interruptible() instead of schedule_timeout (diff)
downloadlinux-3b5cc09033f49d004006acf44e5b05036bd46a85.tar.xz
linux-3b5cc09033f49d004006acf44e5b05036bd46a85.zip
[IA64] assign_irq_vector() should not panic
Current assign_irq_vector() will panic if interrupt vectors is running out. But I think how to handle the case of lack of interrupt vectors should be handled by the caller of this function. For example, some PCI devices can raise the interrupt signal via both MSI and I/O APIC. So even if the driver for these device fails to allocate a vector for MSI, the driver still has a chance to use I/O APIC based interrupt. But currently there is no chance for these driver to use I/O APIC based interrupt because kernel will panic when assign_irq_vector() fails to allocate interrupt vector. The following patch changes assign_irq_vector() for ia64 to return -ENOSPC on error instead of panic (as i386 and x86_64 versions do). Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64/kernel')
-rw-r--r--arch/ia64/kernel/iosapic.c13
-rw-r--r--arch/ia64/kernel/irq_ia64.c15
2 files changed, 11 insertions, 17 deletions
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index c170be095ccd..7936b62f7a2e 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -489,8 +489,6 @@ static int iosapic_find_sharable_vector (unsigned long trigger, unsigned long po
}
}
}
- if (vector < 0)
- panic("%s: out of interrupt vectors!\n", __FUNCTION__);
return vector;
}
@@ -506,6 +504,8 @@ iosapic_reassign_vector (int vector)
if (!list_empty(&iosapic_intr_info[vector].rtes)) {
new_vector = assign_irq_vector(AUTO_ASSIGN);
+ if (new_vector < 0)
+ panic("%s: out of interrupt vectors!\n", __FUNCTION__);
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));
@@ -734,9 +734,12 @@ again:
spin_unlock_irqrestore(&iosapic_lock, flags);
/* If vector is running out, we try to find a sharable vector */
- vector = assign_irq_vector_nopanic(AUTO_ASSIGN);
- if (vector < 0)
+ vector = assign_irq_vector(AUTO_ASSIGN);
+ if (vector < 0) {
vector = iosapic_find_sharable_vector(trigger, polarity);
+ if (vector < 0)
+ panic("%s: out of interrupt vectors!\n", __FUNCTION__);
+ }
spin_lock_irqsave(&irq_descp(vector)->lock, flags);
spin_lock(&iosapic_lock);
@@ -884,6 +887,8 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
break;
case ACPI_INTERRUPT_INIT:
vector = assign_irq_vector(AUTO_ASSIGN);
+ if (vector < 0)
+ panic("%s: out of interrupt vectors!\n", __FUNCTION__);
delivery = IOSAPIC_INIT;
break;
case ACPI_INTERRUPT_CPEI:
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
index 4fe60c7a2e90..6c4d59fd0364 100644
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -63,30 +63,19 @@ EXPORT_SYMBOL(isa_irq_to_vector_map);
static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_NUM_DEVICE_VECTORS)];
int
-assign_irq_vector_nopanic (int irq)
+assign_irq_vector (int irq)
{
int pos, vector;
again:
pos = find_first_zero_bit(ia64_vector_mask, IA64_NUM_DEVICE_VECTORS);
vector = IA64_FIRST_DEVICE_VECTOR + pos;
if (vector > IA64_LAST_DEVICE_VECTOR)
- return -1;
+ return -ENOSPC;
if (test_and_set_bit(pos, ia64_vector_mask))
goto again;
return vector;
}
-int
-assign_irq_vector (int irq)
-{
- int vector = assign_irq_vector_nopanic(irq);
-
- if (vector < 0)
- panic("assign_irq_vector: out of interrupt vectors!");
-
- return vector;
-}
-
void
free_irq_vector (int vector)
{