diff options
-rw-r--r-- | arch/ia64/kernel/iosapic.c | 23 |
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 | ||
565 | static void | 565 | static int |
566 | register_intr (unsigned int gsi, int vector, unsigned char delivery, | 566 | register_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 | ||
628 | static unsigned int | 629 | static unsigned int |
@@ -710,7 +711,7 @@ int | |||
710 | iosapic_register_intr (unsigned int gsi, | 711 | iosapic_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 |