[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 3/5] Add MSI capability to the pciback driver.



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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.