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 struct pciback_dev_data *dev_data;
16 int otherend = pdev->xdev->otherend_id;
19 if (unlikely(verbose_request))
20 printk(KERN_DEBUG "pciback: %s: enable MSI\n", pci_name(dev));
22 status = pci_enable_msi(dev);
25 printk(KERN_ERR "error enable msi for guest %x status %x\n",
28 return XEN_PCI_ERR_op_failed;
31 /* The value the guest needs is actually the IDT vector, not the
32 * the local domain's IRQ number. */
34 op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0;
35 if (unlikely(verbose_request))
36 printk(KERN_DEBUG "pciback: %s: MSI: %d\n", pci_name(dev),
39 dev_data = pci_get_drvdata(dev);
41 dev_data->ack_intr = 0;
46 int pciback_disable_msi(struct pciback_device *pdev,
47 struct pci_dev *dev, struct xen_pci_op *op)
49 struct pciback_dev_data *dev_data;
51 if (unlikely(verbose_request))
52 printk(KERN_DEBUG "pciback: %s: disable MSI\n", pci_name(dev));
56 op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0;
57 if (unlikely(verbose_request))
58 printk(KERN_DEBUG "pciback: %s: MSI: %d\n", pci_name(dev),
60 dev_data = pci_get_drvdata(dev);
62 dev_data->ack_intr = 1;
66 int pciback_enable_msix(struct pciback_device *pdev,
67 struct pci_dev *dev, struct xen_pci_op *op)
69 struct pciback_dev_data *dev_data;
71 struct msix_entry *entries;
73 if (unlikely(verbose_request))
74 printk(KERN_DEBUG "pciback: %s: enable MSI-X\n",
77 if (op->value > SH_INFO_MAX_VEC)
80 entries = kmalloc(op->value * sizeof(*entries), GFP_KERNEL);
84 for (i = 0; i < op->value; i++) {
85 entries[i].entry = op->msix_entries[i].entry;
86 entries[i].vector = op->msix_entries[i].vector;
89 result = pci_enable_msix(dev, entries, op->value);
92 for (i = 0; i < op->value; i++) {
93 op->msix_entries[i].entry = entries[i].entry;
94 if (entries[i].vector)
95 op->msix_entries[i].vector =
96 xen_pirq_from_irq(entries[i].vector);
97 if (unlikely(verbose_request))
98 printk(KERN_DEBUG "pciback: %s: " \
101 op->msix_entries[i].vector);
104 printk(KERN_WARNING "pciback: %s: failed to enable MSI-X: err %d!\n",
105 pci_name(dev), result);
110 dev_data = pci_get_drvdata(dev);
112 dev_data->ack_intr = 0;
117 int pciback_disable_msix(struct pciback_device *pdev,
118 struct pci_dev *dev, struct xen_pci_op *op)
120 struct pciback_dev_data *dev_data;
122 if (unlikely(verbose_request))
123 printk(KERN_DEBUG "pciback: %s: disable MSI-X\n",
126 pci_disable_msix(dev);
129 * SR-IOV devices (which don't have any legacy IRQ) have
130 * an undefined IRQ value of zero.
132 op->value = dev->irq ? xen_pirq_from_irq(dev->irq) : 0;
133 if (unlikely(verbose_request))
134 printk(KERN_DEBUG "pciback: %s: MSI-X: %d\n", pci_name(dev),
136 dev_data = pci_get_drvdata(dev);
138 dev_data->ack_intr = 1;