remove trailing whitespaces
[dpdk.git] / lib / librte_eal / linuxapp / igb_uio / igb_uio.c
index ccf4f61..6fa7396 100644 (file)
@@ -1,23 +1,23 @@
 /*-
  * GPL LICENSE SUMMARY
- * 
- *   Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
- * 
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of version 2 of the GNU General Public License as
  *   published by the Free Software Foundation.
- * 
+ *
  *   This program is distributed in the hope that it will be useful, but
  *   WITHOUT ANY WARRANTY; without even the implied warranty of
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  *   General Public License for more details.
- * 
+ *
  *   You should have received a copy of the GNU General Public License
  *   along with this program; if not, write to the Free Software
  *   Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  *   The full GNU General Public License is included in this distribution
  *   in the file called LICENSE.GPL.
- * 
+ *
  *   Contact Information:
  *   Intel Corporation
  */
 #include <linux/msi.h>
 #include <linux/version.h>
 
+#ifdef CONFIG_XEN_DOM0
+#include <xen/xen.h>
+#endif
+
 /**
  * MSI-X related macros, copy from linux/pci_regs.h in kernel 2.6.39,
  * but none of them in kernel 2.6.35.
@@ -75,6 +79,12 @@ static struct pci_device_id igbuio_pci_ids[] = {
 #define RTE_PCI_DEV_ID_DECL_IGBVF(vend, dev) {PCI_DEVICE(vend, dev)},
 #define RTE_PCI_DEV_ID_DECL_IXGBE(vend, dev) {PCI_DEVICE(vend, dev)},
 #define RTE_PCI_DEV_ID_DECL_IXGBEVF(vend, dev) {PCI_DEVICE(vend, dev)},
+#ifdef RTE_LIBRTE_VIRTIO_PMD
+#define RTE_PCI_DEV_ID_DECL_VIRTIO(vend, dev) {PCI_DEVICE(vend, dev)},
+#endif
+#ifdef RTE_LIBRTE_VMXNET3_PMD
+#define RTE_PCI_DEV_ID_DECL_VMXNET3(vend, dev) {PCI_DEVICE(vend, dev)},
+#endif
 #include <rte_pci_dev_ids.h>
 { 0, },
 };
@@ -103,7 +113,7 @@ int local_pci_num_vf(struct pci_dev *dev)
 
        if (!dev->is_physfn)
                return 0;
-       
+
        return iov->nr_virtfn;
 #else
        return pci_num_vf(dev);
@@ -136,7 +146,7 @@ store_max_vfs(struct device *dev, struct device_attribute *attr,
        else /* do nothing if change max_vfs number */
                err = -EINVAL;
 
-       return err ? err : count;                                                       
+       return err ? err : count;
 }
 
 static DEVICE_ATTR(max_vfs, S_IRUGO | S_IWUSR, show_max_vfs, store_max_vfs);
@@ -311,6 +321,48 @@ spin_unlock:
        return ret;
 }
 
+#ifdef CONFIG_XEN_DOM0
+static int
+igbuio_dom0_mmap_phys(struct uio_info *info, struct vm_area_struct *vma)
+{
+       int idx;
+       idx = (int)vma->vm_pgoff;
+       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+       vma->vm_page_prot.pgprot |= _PAGE_IOMAP;
+
+       return remap_pfn_range(vma,
+                       vma->vm_start,
+                       info->mem[idx].addr >> PAGE_SHIFT,
+                       vma->vm_end - vma->vm_start,
+                       vma->vm_page_prot);
+}
+
+/**
+ * This is uio device mmap method which will use igbuio mmap for Xen
+ * Dom0 environment.
+ */
+static int
+igbuio_dom0_pci_mmap(struct uio_info *info, struct vm_area_struct *vma)
+{
+       int idx;
+
+       if (vma->vm_pgoff >= MAX_UIO_MAPS)
+               return -EINVAL;
+       if(info->mem[vma->vm_pgoff].size == 0)
+               return  -EINVAL;
+
+       idx = (int)vma->vm_pgoff;
+       switch (info->mem[idx].memtype) {
+       case UIO_MEM_PHYS:
+               return igbuio_dom0_mmap_phys(info, vma);
+       case UIO_MEM_LOGICAL:
+       case UIO_MEM_VIRTUAL:
+       default:
+               return -EINVAL;
+       }
+}
+#endif
+
 /* Remap pci resources described by bar #pci_bar in uio resource n. */
 static int
 igbuio_pci_setup_iomem(struct pci_dev *dev, struct uio_info *info,
@@ -319,7 +371,7 @@ igbuio_pci_setup_iomem(struct pci_dev *dev, struct uio_info *info,
        unsigned long addr, len;
        void *internal_addr;
 
-       if (sizeof(info->mem) / sizeof (info->mem[0]) <= n)  
+       if (sizeof(info->mem) / sizeof (info->mem[0]) <= n)
                return (EINVAL);
 
        addr = pci_resource_start(dev, pci_bar);
@@ -344,7 +396,7 @@ igbuio_pci_setup_ioport(struct pci_dev *dev, struct uio_info *info,
 {
        unsigned long addr, len;
 
-       if (sizeof(info->port) / sizeof (info->port[0]) <= n)  
+       if (sizeof(info->port) / sizeof (info->port[0]) <= n)
                return (EINVAL);
 
        addr = pci_resource_start(dev, pci_bar);
@@ -461,6 +513,11 @@ igbuio_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
        udev->info.version = "0.1";
        udev->info.handler = igbuio_pci_irqhandler;
        udev->info.irqcontrol = igbuio_pci_irqcontrol;
+#ifdef CONFIG_XEN_DOM0
+       /* check if the driver run on Xen Dom0 */
+       if (xen_initial_domain())
+               udev->info.mmap = igbuio_dom0_pci_mmap;
+#endif
        udev->info.priv = udev;
        udev->pdev = dev;
        udev->mode = 0; /* set the default value for interrupt mode */