aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>2005-07-11 00:49:00 -0400
committerTony Luck <tony.luck@intel.com>2005-07-11 13:30:07 -0400
commit3b5cc09033f49d004006acf44e5b05036bd46a85 (patch)
treedcae13f5768234fe59736e877885ee6d8b4fc0fc
parent699139279d29e36e39d353b0536b510dab2e5ffa (diff)
[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>
-rw-r--r--arch/ia64/hp/sim/simeth.c6
-rw-r--r--arch/ia64/hp/sim/simserial.c7
-rw-r--r--arch/ia64/kernel/iosapic.c13
-rw-r--r--arch/ia64/kernel/irq_ia64.c15
-rw-r--r--include/asm-ia64/hw_irq.h1
5 files changed, 20 insertions, 22 deletions
diff --git a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c
index ae84a1018a89..0639ec0ed015 100644
--- a/arch/ia64/hp/sim/simeth.c
+++ b/arch/ia64/hp/sim/simeth.c
@@ -191,7 +191,7 @@ simeth_probe1(void)
191 unsigned char mac_addr[ETH_ALEN]; 191 unsigned char mac_addr[ETH_ALEN];
192 struct simeth_local *local; 192 struct simeth_local *local;
193 struct net_device *dev; 193 struct net_device *dev;
194 int fd, i, err; 194 int fd, i, err, rc;
195 195
196 /* 196 /*
197 * XXX Fix me 197 * XXX Fix me
@@ -228,7 +228,9 @@ simeth_probe1(void)
228 return err; 228 return err;
229 } 229 }
230 230
231 dev->irq = assign_irq_vector(AUTO_ASSIGN); 231 if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0)
232 panic("%s: out of interrupt vectors!\n", __FUNCTION__);
233 dev->irq = rc;
232 234
233 /* 235 /*
234 * attach the interrupt in the simulator, this does enable interrupts 236 * attach the interrupt in the simulator, this does enable interrupts
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c
index 7a8ae0f4b387..7dcb8582ae0d 100644
--- a/arch/ia64/hp/sim/simserial.c
+++ b/arch/ia64/hp/sim/simserial.c
@@ -982,7 +982,7 @@ static struct tty_operations hp_ops = {
982static int __init 982static int __init
983simrs_init (void) 983simrs_init (void)
984{ 984{
985 int i; 985 int i, rc;
986 struct serial_state *state; 986 struct serial_state *state;
987 987
988 if (!ia64_platform_is("hpsim")) 988 if (!ia64_platform_is("hpsim"))
@@ -1017,7 +1017,10 @@ simrs_init (void)
1017 if (state->type == PORT_UNKNOWN) continue; 1017 if (state->type == PORT_UNKNOWN) continue;
1018 1018
1019 if (!state->irq) { 1019 if (!state->irq) {
1020 state->irq = assign_irq_vector(AUTO_ASSIGN); 1020 if ((rc = assign_irq_vector(AUTO_ASSIGN)) < 0)
1021 panic("%s: out of interrupt vectors!\n",
1022 __FUNCTION__);
1023 state->irq = rc;
1021 ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq); 1024 ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq);
1022 } 1025 }
1023 1026
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
489 } 489 }
490 } 490 }
491 } 491 }
492 if (vector < 0)
493 panic("%s: out of interrupt vectors!\n", __FUNCTION__);
494 492
495 return vector; 493 return vector;
496} 494}
@@ -506,6 +504,8 @@ iosapic_reassign_vector (int vector)
506 504
507 if (!list_empty(&iosapic_intr_info[vector].rtes)) { 505 if (!list_empty(&iosapic_intr_info[vector].rtes)) {
508 new_vector = assign_irq_vector(AUTO_ASSIGN); 506 new_vector = assign_irq_vector(AUTO_ASSIGN);
507 if (new_vector < 0)
508 panic("%s: out of interrupt vectors!\n", __FUNCTION__);
509 printk(KERN_INFO "Reassigning vector %d to %d\n", vector, new_vector); 509 printk(KERN_INFO "Reassigning vector %d to %d\n", vector, new_vector);
510 memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector], 510 memcpy(&iosapic_intr_info[new_vector], &iosapic_intr_info[vector],
511 sizeof(struct iosapic_intr_info)); 511 sizeof(struct iosapic_intr_info));
@@ -734,9 +734,12 @@ again:
734 spin_unlock_irqrestore(&iosapic_lock, flags); 734 spin_unlock_irqrestore(&iosapic_lock, flags);
735 735
736 /* If vector is running out, we try to find a sharable vector */ 736 /* If vector is running out, we try to find a sharable vector */
737 vector = assign_irq_vector_nopanic(AUTO_ASSIGN); 737 vector = assign_irq_vector(AUTO_ASSIGN);
738 if (vector < 0) 738 if (vector < 0) {
739 vector = iosapic_find_sharable_vector(trigger, polarity); 739 vector = iosapic_find_sharable_vector(trigger, polarity);
740 if (vector < 0)
741 panic("%s: out of interrupt vectors!\n", __FUNCTION__);
742 }
740 743
741 spin_lock_irqsave(&irq_descp(vector)->lock, flags); 744 spin_lock_irqsave(&irq_descp(vector)->lock, flags);
742 spin_lock(&iosapic_lock); 745 spin_lock(&iosapic_lock);
@@ -884,6 +887,8 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
884 break; 887 break;
885 case ACPI_INTERRUPT_INIT: 888 case ACPI_INTERRUPT_INIT:
886 vector = assign_irq_vector(AUTO_ASSIGN); 889 vector = assign_irq_vector(AUTO_ASSIGN);
890 if (vector < 0)
891 panic("%s: out of interrupt vectors!\n", __FUNCTION__);
887 delivery = IOSAPIC_INIT; 892 delivery = IOSAPIC_INIT;
888 break; 893 break;
889 case ACPI_INTERRUPT_CPEI: 894 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);
63static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_NUM_DEVICE_VECTORS)]; 63static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_NUM_DEVICE_VECTORS)];
64 64
65int 65int
66assign_irq_vector_nopanic (int irq) 66assign_irq_vector (int irq)
67{ 67{
68 int pos, vector; 68 int pos, vector;
69 again: 69 again:
70 pos = find_first_zero_bit(ia64_vector_mask, IA64_NUM_DEVICE_VECTORS); 70 pos = find_first_zero_bit(ia64_vector_mask, IA64_NUM_DEVICE_VECTORS);
71 vector = IA64_FIRST_DEVICE_VECTOR + pos; 71 vector = IA64_FIRST_DEVICE_VECTOR + pos;
72 if (vector > IA64_LAST_DEVICE_VECTOR) 72 if (vector > IA64_LAST_DEVICE_VECTOR)
73 return -1; 73 return -ENOSPC;
74 if (test_and_set_bit(pos, ia64_vector_mask)) 74 if (test_and_set_bit(pos, ia64_vector_mask))
75 goto again; 75 goto again;
76 return vector; 76 return vector;
77} 77}
78 78
79int
80assign_irq_vector (int irq)
81{
82 int vector = assign_irq_vector_nopanic(irq);
83
84 if (vector < 0)
85 panic("assign_irq_vector: out of interrupt vectors!");
86
87 return vector;
88}
89
90void 79void
91free_irq_vector (int vector) 80free_irq_vector (int vector)
92{ 81{
diff --git a/include/asm-ia64/hw_irq.h b/include/asm-ia64/hw_irq.h
index cd4e06b74ab6..041ab8c51a64 100644
--- a/include/asm-ia64/hw_irq.h
+++ b/include/asm-ia64/hw_irq.h
@@ -81,7 +81,6 @@ extern __u8 isa_irq_to_vector_map[16];
81 81
82extern struct hw_interrupt_type irq_type_ia64_lsapic; /* CPU-internal interrupt controller */ 82extern struct hw_interrupt_type irq_type_ia64_lsapic; /* CPU-internal interrupt controller */
83 83
84extern int assign_irq_vector_nopanic (int irq); /* allocate a free vector without panic */
85extern int assign_irq_vector (int irq); /* allocate a free vector */ 84extern int assign_irq_vector (int irq); /* allocate a free vector */
86extern void free_irq_vector (int vector); 85extern void free_irq_vector (int vector);
87extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect); 86extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect);