aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/ia64/kernel/iosapic.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 88b014381df5..40afbfa47eca 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -562,7 +562,7 @@ static inline int vector_is_shared (int vector)
562 return (iosapic_intr_info[vector].count > 1); 562 return (iosapic_intr_info[vector].count > 1);
563} 563}
564 564
565static void 565static int
566register_intr (unsigned int gsi, int vector, unsigned char delivery, 566register_intr (unsigned int gsi, int vector, unsigned char delivery,
567 unsigned long polarity, unsigned long trigger) 567 unsigned long polarity, unsigned long trigger)
568{ 568{
@@ -577,7 +577,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
577 index = find_iosapic(gsi); 577 index = find_iosapic(gsi);
578 if (index < 0) { 578 if (index < 0) {
579 printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n", __FUNCTION__, gsi); 579 printk(KERN_WARNING "%s: No IOSAPIC for GSI %u\n", __FUNCTION__, gsi);
580 return; 580 return -ENODEV;
581 } 581 }
582 582
583 iosapic_address = iosapic_lists[index].addr; 583 iosapic_address = iosapic_lists[index].addr;
@@ -588,7 +588,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
588 rte = iosapic_alloc_rte(); 588 rte = iosapic_alloc_rte();
589 if (!rte) { 589 if (!rte) {
590 printk(KERN_WARNING "%s: cannot allocate memory\n", __FUNCTION__); 590 printk(KERN_WARNING "%s: cannot allocate memory\n", __FUNCTION__);
591 return; 591 return -ENOMEM;
592 } 592 }
593 593
594 rte_index = gsi - gsi_base; 594 rte_index = gsi - gsi_base;
@@ -603,7 +603,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
603 struct iosapic_intr_info *info = &iosapic_intr_info[vector]; 603 struct iosapic_intr_info *info = &iosapic_intr_info[vector];
604 if (info->trigger != trigger || info->polarity != polarity) { 604 if (info->trigger != trigger || info->polarity != polarity) {
605 printk (KERN_WARNING "%s: cannot override the interrupt\n", __FUNCTION__); 605 printk (KERN_WARNING "%s: cannot override the interrupt\n", __FUNCTION__);
606 return; 606 return -EINVAL;
607 } 607 }
608 } 608 }
609 609
@@ -623,6 +623,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery,
623 __FUNCTION__, vector, idesc->handler->typename, irq_type->typename); 623 __FUNCTION__, vector, idesc->handler->typename, irq_type->typename);
624 idesc->handler = irq_type; 624 idesc->handler = irq_type;
625 } 625 }
626 return 0;
626} 627}
627 628
628static unsigned int 629static unsigned int
@@ -710,7 +711,7 @@ int
710iosapic_register_intr (unsigned int gsi, 711iosapic_register_intr (unsigned int gsi,
711 unsigned long polarity, unsigned long trigger) 712 unsigned long polarity, unsigned long trigger)
712{ 713{
713 int vector, mask = 1; 714 int vector, mask = 1, err;
714 unsigned int dest; 715 unsigned int dest;
715 unsigned long flags; 716 unsigned long flags;
716 struct iosapic_rte_info *rte; 717 struct iosapic_rte_info *rte;
@@ -735,8 +736,11 @@ again:
735 736
736 /* If vector is running out, we try to find a sharable vector */ 737 /* If vector is running out, we try to find a sharable vector */
737 vector = assign_irq_vector_nopanic(AUTO_ASSIGN); 738 vector = assign_irq_vector_nopanic(AUTO_ASSIGN);
738 if (vector < 0) 739 if (vector < 0) {
739 vector = iosapic_find_sharable_vector(trigger, polarity); 740 vector = iosapic_find_sharable_vector(trigger, polarity);
741 if (vector < 0)
742 Return -ENOSPC;
743 }
740 744
741 spin_lock_irqsave(&irq_descp(vector)->lock, flags); 745 spin_lock_irqsave(&irq_descp(vector)->lock, flags);
742 spin_lock(&iosapic_lock); 746 spin_lock(&iosapic_lock);
@@ -750,8 +754,13 @@ again:
750 } 754 }
751 755
752 dest = get_target_cpu(gsi, vector); 756 dest = get_target_cpu(gsi, vector);
753 register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, 757 err = register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY,
754 polarity, trigger); 758 polarity, trigger);
759 if (err < 0) {
760 spin_unlock(&iosapic_lock);
761 spin_unlock_irqrestore(&irq_descp(vector)->lock, flags);
762 return err;
763 }
755 764
756 /* 765 /*
757 * If the vector is shared and already unmasked for 766 * If the vector is shared and already unmasked for