diff options
| -rw-r--r-- | arch/x86/pci/xen.c | 45 | ||||
| -rw-r--r-- | drivers/xen/events.c | 41 | ||||
| -rw-r--r-- | include/xen/events.h | 1 |
3 files changed, 40 insertions, 47 deletions
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index ffd8c7a2cdb..8c4085a95ef 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c | |||
| @@ -185,15 +185,50 @@ static void xen_teardown_msi_irq(unsigned int irq) | |||
| 185 | #ifdef CONFIG_XEN_DOM0 | 185 | #ifdef CONFIG_XEN_DOM0 |
| 186 | static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | 186 | static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) |
| 187 | { | 187 | { |
| 188 | int irq; | 188 | int ret = 0; |
| 189 | struct msi_desc *msidesc; | 189 | struct msi_desc *msidesc; |
| 190 | 190 | ||
| 191 | list_for_each_entry(msidesc, &dev->msi_list, list) { | 191 | list_for_each_entry(msidesc, &dev->msi_list, list) { |
| 192 | irq = xen_create_msi_irq(dev, msidesc, type); | 192 | struct physdev_map_pirq map_irq; |
| 193 | if (irq < 0) | 193 | |
| 194 | return -1; | 194 | memset(&map_irq, 0, sizeof(map_irq)); |
| 195 | map_irq.domid = DOMID_SELF; | ||
| 196 | map_irq.type = MAP_PIRQ_TYPE_MSI; | ||
| 197 | map_irq.index = -1; | ||
| 198 | map_irq.pirq = -1; | ||
| 199 | map_irq.bus = dev->bus->number; | ||
| 200 | map_irq.devfn = dev->devfn; | ||
| 201 | |||
| 202 | if (type == PCI_CAP_ID_MSIX) { | ||
| 203 | int pos; | ||
| 204 | u32 table_offset, bir; | ||
| 205 | |||
| 206 | pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); | ||
| 207 | |||
| 208 | pci_read_config_dword(dev, pos + PCI_MSIX_TABLE, | ||
| 209 | &table_offset); | ||
| 210 | bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); | ||
| 211 | |||
| 212 | map_irq.table_base = pci_resource_start(dev, bir); | ||
| 213 | map_irq.entry_nr = msidesc->msi_attrib.entry_nr; | ||
| 214 | } | ||
| 215 | |||
| 216 | ret = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq); | ||
| 217 | if (ret) { | ||
| 218 | dev_warn(&dev->dev, "xen map irq failed %d\n", ret); | ||
| 219 | goto out; | ||
| 220 | } | ||
| 221 | |||
| 222 | ret = xen_bind_pirq_msi_to_irq(dev, msidesc, | ||
| 223 | map_irq.pirq, map_irq.index, | ||
| 224 | (type == PCI_CAP_ID_MSIX) ? | ||
| 225 | "msi-x" : "msi"); | ||
| 226 | if (ret < 0) | ||
| 227 | goto out; | ||
| 195 | } | 228 | } |
| 196 | return 0; | 229 | ret = 0; |
| 230 | out: | ||
| 231 | return ret; | ||
| 197 | } | 232 | } |
| 198 | #endif | 233 | #endif |
| 199 | #endif | 234 | #endif |
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 34469489087..6befe622715 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
| @@ -644,9 +644,6 @@ out: | |||
| 644 | } | 644 | } |
| 645 | 645 | ||
| 646 | #ifdef CONFIG_PCI_MSI | 646 | #ifdef CONFIG_PCI_MSI |
| 647 | #include <linux/msi.h> | ||
| 648 | #include "../pci/msi.h" | ||
| 649 | |||
| 650 | int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc) | 647 | int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc) |
| 651 | { | 648 | { |
| 652 | int rc; | 649 | int rc; |
| @@ -688,44 +685,6 @@ error_irq: | |||
| 688 | xen_free_irq(irq); | 685 | xen_free_irq(irq); |
| 689 | return -1; | 686 | return -1; |
| 690 | } | 687 | } |
| 691 | |||
| 692 | int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type) | ||
| 693 | { | ||
| 694 | struct physdev_map_pirq map_irq; | ||
| 695 | int rc; | ||
| 696 | int pos; | ||
| 697 | u32 table_offset, bir; | ||
| 698 | |||
| 699 | memset(&map_irq, 0, sizeof(map_irq)); | ||
| 700 | map_irq.domid = DOMID_SELF; | ||
| 701 | map_irq.type = MAP_PIRQ_TYPE_MSI; | ||
| 702 | map_irq.index = -1; | ||
| 703 | map_irq.pirq = -1; | ||
| 704 | map_irq.bus = dev->bus->number; | ||
| 705 | map_irq.devfn = dev->devfn; | ||
| 706 | |||
| 707 | if (type == PCI_CAP_ID_MSIX) { | ||
| 708 | pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); | ||
| 709 | |||
| 710 | pci_read_config_dword(dev, msix_table_offset_reg(pos), | ||
| 711 | &table_offset); | ||
| 712 | bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); | ||
| 713 | |||
| 714 | map_irq.table_base = pci_resource_start(dev, bir); | ||
| 715 | map_irq.entry_nr = msidesc->msi_attrib.entry_nr; | ||
| 716 | } | ||
| 717 | |||
| 718 | rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq); | ||
| 719 | if (rc) { | ||
| 720 | dev_warn(&dev->dev, "xen map irq failed %d\n", rc); | ||
| 721 | return -1; | ||
| 722 | } | ||
| 723 | |||
| 724 | return xen_bind_pirq_msi_to_irq(dev, msidesc, | ||
| 725 | map_irq.pirq, map_irq.index, | ||
| 726 | (type == PCI_CAP_ID_MSIX) ? | ||
| 727 | "msi-x" : "msi"); | ||
| 728 | } | ||
| 729 | #endif | 688 | #endif |
| 730 | 689 | ||
| 731 | int xen_destroy_irq(int irq) | 690 | int xen_destroy_irq(int irq) |
diff --git a/include/xen/events.h b/include/xen/events.h index 45c08a0d580..962da2ced5b 100644 --- a/include/xen/events.h +++ b/include/xen/events.h | |||
| @@ -78,7 +78,6 @@ int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name); | |||
| 78 | int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc); | 78 | int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc); |
| 79 | int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc, | 79 | int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc, |
| 80 | int pirq, int vector, const char *name); | 80 | int pirq, int vector, const char *name); |
| 81 | int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type); | ||
| 82 | #endif | 81 | #endif |
| 83 | 82 | ||
| 84 | /* De-allocates the above mentioned physical interrupt. */ | 83 | /* De-allocates the above mentioned physical interrupt. */ |
