2 * PCI Backend -- Configuration overlay for MSI capability
5 #include <linux/slab.h>
6 #include "conf_space.h"
7 #include "conf_space_capability.h"
8 #include <xen/interface/io/pciif.h>
9 #include <xen/events.h>
12 int pciback_enable_msi(struct pciback_device *pdev,
13 struct pci_dev *dev, struct xen_pci_op *op)
15 int otherend = pdev->xdev->otherend_id;
18 status = pci_enable_msi(dev);
21 printk(KERN_ERR "error enable msi for guest %x status %x\n",
24 return XEN_PCI_ERR_op_failed;
27 /* The value the guest needs is actually the IDT vector, not the
28 * the local domain's IRQ number. */
30 op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0;
34 int pciback_disable_msi(struct pciback_device *pdev,
35 struct pci_dev *dev, struct xen_pci_op *op)
39 op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0;
43 int pciback_enable_msix(struct pciback_device *pdev,
44 struct pci_dev *dev, struct xen_pci_op *op)
47 struct msix_entry *entries;
49 if (op->value > SH_INFO_MAX_VEC)
52 entries = kmalloc(op->value * sizeof(*entries), GFP_KERNEL);
56 for (i = 0; i < op->value; i++) {
57 entries[i].entry = op->msix_entries[i].entry;
58 entries[i].vector = op->msix_entries[i].vector;
61 result = pci_enable_msix(dev, entries, op->value);
64 for (i = 0; i < op->value; i++) {
65 op->msix_entries[i].entry = entries[i].entry;
66 if (entries[i].vector)
67 op->msix_entries[i].vector =
68 xen_pirq_from_irq(entries[i].vector);
71 printk(KERN_WARNING "pciback: %s: failed to enable MSI-X: err %d!\n",
72 pci_name(dev), result);
81 int pciback_disable_msix(struct pciback_device *pdev,
82 struct pci_dev *dev, struct xen_pci_op *op)
85 pci_disable_msix(dev);
88 * SR-IOV devices (which don't have any legacy IRQ) have
89 * an undefined IRQ value of zero.
91 op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0;