This is a reverse commit of a previous patch that
disabled the functionality. It is essentially a copy of the MSI
functionality from the linux-2.6.18.hg tree.
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
---
drivers/xen/pciback/Makefile | 1 +
drivers/xen/pciback/conf_space_capability_msi.c | 79 +++++++++++++++++++++++
drivers/xen/pciback/pci_stub.c | 15 ++++
drivers/xen/pciback/pciback.h | 14 ++++
drivers/xen/pciback/pciback_ops.c | 14 ++++
5 files changed, 123 insertions(+), 0 deletions(-)
create mode 100644 drivers/xen/pciback/conf_space_capability_msi.c
diff --git a/drivers/xen/pciback/Makefile b/drivers/xen/pciback/Makefile
index a99bdaa..106dae7 100644
--- a/drivers/xen/pciback/Makefile
+++ b/drivers/xen/pciback/Makefile
@@ -6,6 +6,7 @@ pciback-y += conf_space.o conf_space_header.o \
conf_space_capability_vpd.o \
conf_space_capability_pm.o \
conf_space_quirks.o
+pciback-$(CONFIG_PCI_MSI) += conf_space_capability_msi.o
pciback-$(CONFIG_XEN_PCIDEV_BACKEND_VPCI) += vpci.o
pciback-$(CONFIG_XEN_PCIDEV_BACKEND_SLOT) += slot.o
pciback-$(CONFIG_XEN_PCIDEV_BACKEND_PASS) += passthrough.o
diff --git a/drivers/xen/pciback/conf_space_capability_msi.c
b/drivers/xen/pciback/conf_space_capability_msi.c
new file mode 100644
index 0000000..762e396
--- /dev/null
+++ b/drivers/xen/pciback/conf_space_capability_msi.c
@@ -0,0 +1,79 @@
+/*
+ * PCI Backend -- Configuration overlay for MSI capability
+ */
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include "conf_space.h"
+#include "conf_space_capability.h"
+#include <xen/interface/io/pciif.h>
+#include "pciback.h"
+
+int pciback_enable_msi(struct pciback_device *pdev,
+ struct pci_dev *dev, struct xen_pci_op *op)
+{
+ int otherend = pdev->xdev->otherend_id;
+ int status;
+
+ status = pci_enable_msi(dev);
+
+ if (status) {
+ printk("error enable msi for guest %x status %x\n", otherend,
status);
+ op->value = 0;
+ return XEN_PCI_ERR_op_failed;
+ }
+
+ op->value = dev->irq;
+ return 0;
+}
+
+int pciback_disable_msi(struct pciback_device *pdev,
+ struct pci_dev *dev, struct xen_pci_op *op)
+{
+ pci_disable_msi(dev);
+
+ op->value = dev->irq;
+ return 0;
+}
+
+int pciback_enable_msix(struct pciback_device *pdev,
+ struct pci_dev *dev, struct xen_pci_op *op)
+{
+ int i, result;
+ struct msix_entry *entries;
+
+ if (op->value > SH_INFO_MAX_VEC)
+ return -EINVAL;
+
+ entries = kmalloc(op->value * sizeof(*entries), GFP_KERNEL);
+ if (entries == NULL)
+ return -ENOMEM;
+
+ for (i = 0; i < op->value; i++) {
+ entries[i].entry = op->msix_entries[i].entry;
+ entries[i].vector = op->msix_entries[i].vector;
+ }
+
+ result = pci_enable_msix(dev, entries, op->value);
+
+ for (i = 0; i < op->value; i++) {
+ op->msix_entries[i].entry = entries[i].entry;
+ op->msix_entries[i].vector = entries[i].vector;
+ }
+
+ kfree(entries);
+
+ op->value = result;
+
+ return result;
+}
+
+int pciback_disable_msix(struct pciback_device *pdev,
+ struct pci_dev *dev, struct xen_pci_op *op)
+{
+
+ pci_disable_msix(dev);
+
+ op->value = dev->irq;
+ return 0;
+}
+
diff --git a/drivers/xen/pciback/pci_stub.c b/drivers/xen/pciback/pci_stub.c
index 5ea594b..88c742b 100644
--- a/drivers/xen/pciback/pci_stub.c
+++ b/drivers/xen/pciback/pci_stub.c
@@ -1173,6 +1173,21 @@ static ssize_t permissive_show(struct device_driver
*drv, char *buf)
DRIVER_ATTR(permissive, S_IRUSR | S_IWUSR, permissive_show, permissive_add);
+#ifdef CONFIG_PCI_MSI
+
+int pciback_get_owner(struct pci_dev *dev)
+{
+ struct pcistub_device *psdev;
+
+ psdev = pcistub_device_find(pci_domain_nr(dev->bus), dev->bus->number,
+ PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+
+ if (!psdev || !psdev->pdev)
+ return -1;
+
+ return psdev->pdev->xdev->otherend_id;
+}
+#endif
static void pcistub_exit(void)
{
diff --git a/drivers/xen/pciback/pciback.h b/drivers/xen/pciback/pciback.h
index 421b81e..5e8e14e 100644
--- a/drivers/xen/pciback/pciback.h
+++ b/drivers/xen/pciback/pciback.h
@@ -104,6 +104,20 @@ void pciback_do_op(struct work_struct *data);
int pciback_xenbus_register(void);
void pciback_xenbus_unregister(void);
+#ifdef CONFIG_PCI_MSI
+int pciback_enable_msi(struct pciback_device *pdev,
+ struct pci_dev *dev, struct xen_pci_op *op);
+
+int pciback_disable_msi(struct pciback_device *pdev,
+ struct pci_dev *dev, struct xen_pci_op *op);
+
+
+int pciback_enable_msix(struct pciback_device *pdev,
+ struct pci_dev *dev, struct xen_pci_op *op);
+
+int pciback_disable_msix(struct pciback_device *pdev,
+ struct pci_dev *dev, struct xen_pci_op *op);
+#endif
extern int verbose_request;
void test_and_schedule_op(struct pciback_device *pdev);
diff --git a/drivers/xen/pciback/pciback_ops.c
b/drivers/xen/pciback/pciback_ops.c
index 834663d..6624faf 100644
--- a/drivers/xen/pciback/pciback_ops.c
+++ b/drivers/xen/pciback/pciback_ops.c
@@ -89,6 +89,20 @@ void pciback_do_op(struct work_struct *data)
op->err = pciback_config_write(dev,
op->offset, op->size, op->value);
break;
+#ifdef CONFIG_PCI_MSI
+ case XEN_PCI_OP_enable_msi:
+ op->err = pciback_enable_msi(pdev, dev, op);
+ break;
+ case XEN_PCI_OP_disable_msi:
+ op->err = pciback_disable_msi(pdev, dev, op);
+ break;
+ case XEN_PCI_OP_enable_msix:
+ op->err = pciback_enable_msix(pdev, dev, op);
+ break;
+ case XEN_PCI_OP_disable_msix:
+ op->err = pciback_disable_msix(pdev, dev, op);
+ break;
+#endif
default:
op->err = XEN_PCI_ERR_not_implemented;
break;
--
1.6.2.5
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|