aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorIan Campbell <ian.campbell@citrix.com>2011-02-18 11:43:32 -0500
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2011-03-10 14:44:40 -0500
commitbf480d952bcf25e8ff7e95d2a23964107513ac51 (patch)
treeb2d1a75e39bfdf82021ccdefb5f9613a17087040 /drivers
parent5cad61a6ba6f4956a218ffbb64cafcc1daefaca0 (diff)
xen: events: separate MSI PIRQ allocation from PIRQ binding to IRQ
Split the binding aspect of xen_allocate_pirq_msi out into a new xen_bind_pirq_to_irq function. In xen_hvm_setup_msi_irq when allocating a pirq write the MSI message to signal the PIRQ as soon as the pirq is obtained. There is no way to free the pirq back so if the subsequent binding to an IRQ fails we want to ensure that we will reuse the PIRQ next time rather than leak it. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/xen/events.c30
1 files changed, 14 insertions, 16 deletions
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index c21066fc30be..1033f6284f31 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -647,12 +647,12 @@ out:
647#include <linux/msi.h> 647#include <linux/msi.h>
648#include "../pci/msi.h" 648#include "../pci/msi.h"
649 649
650static int find_unbound_pirq(int type) 650int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc)
651{ 651{
652 int rc; 652 int rc;
653 struct physdev_get_free_pirq op_get_free_pirq; 653 struct physdev_get_free_pirq op_get_free_pirq;
654 654
655 op_get_free_pirq.type = type; 655 op_get_free_pirq.type = MAP_PIRQ_TYPE_MSI;
656 rc = HYPERVISOR_physdev_op(PHYSDEVOP_get_free_pirq, &op_get_free_pirq); 656 rc = HYPERVISOR_physdev_op(PHYSDEVOP_get_free_pirq, &op_get_free_pirq);
657 657
658 WARN_ONCE(rc == -ENOSYS, 658 WARN_ONCE(rc == -ENOSYS,
@@ -661,9 +661,10 @@ static int find_unbound_pirq(int type)
661 return rc ? -1 : op_get_free_pirq.pirq; 661 return rc ? -1 : op_get_free_pirq.pirq;
662} 662}
663 663
664int xen_allocate_pirq_msi(char *name, int *pirq, int alloc_pirq) 664int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc,
665 int pirq, const char *name)
665{ 666{
666 int irq; 667 int irq, ret;
667 668
668 spin_lock(&irq_mapping_update_lock); 669 spin_lock(&irq_mapping_update_lock);
669 670
@@ -671,24 +672,21 @@ int xen_allocate_pirq_msi(char *name, int *pirq, int alloc_pirq)
671 if (irq == -1) 672 if (irq == -1)
672 goto out; 673 goto out;
673 674
674 if (alloc_pirq) {
675 *pirq = find_unbound_pirq(MAP_PIRQ_TYPE_MSI);
676 if (*pirq == -1) {
677 xen_free_irq(irq);
678 irq = -1;
679 goto out;
680 }
681 }
682
683 set_irq_chip_and_handler_name(irq, &xen_pirq_chip, 675 set_irq_chip_and_handler_name(irq, &xen_pirq_chip,
684 handle_level_irq, name); 676 handle_level_irq, name);
685 677
686 irq_info[irq] = mk_pirq_info(0, *pirq, 0, 0); 678 irq_info[irq] = mk_pirq_info(0, pirq, 0, 0);
687 pirq_to_irq[*pirq] = irq; 679 pirq_to_irq[pirq] = irq;
688 680 ret = set_irq_msi(irq, msidesc);
681 if (ret < 0)
682 goto error_irq;
689out: 683out:
690 spin_unlock(&irq_mapping_update_lock); 684 spin_unlock(&irq_mapping_update_lock);
691 return irq; 685 return irq;
686error_irq:
687 spin_unlock(&irq_mapping_update_lock);
688 xen_free_irq(irq);
689 return -1;
692} 690}
693 691
694int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type) 692int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type)