bus/pci: switch to private kernel driver enum
[dpdk.git] / drivers / bus / pci / linux / pci.c
index 1d8d20d..bf27594 100644 (file)
@@ -9,7 +9,6 @@
 #include <rte_bus.h>
 #include <rte_pci.h>
 #include <rte_bus_pci.h>
-#include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
 #include <rte_devargs.h>
 #include <rte_memcpy.h>
@@ -69,14 +68,14 @@ rte_pci_map_device(struct rte_pci_device *dev)
 
        /* try mapping the NIC resources using VFIO if it exists */
        switch (dev->kdrv) {
-       case RTE_KDRV_VFIO:
+       case RTE_PCI_KDRV_VFIO:
 #ifdef VFIO_PRESENT
                if (pci_vfio_is_enabled())
                        ret = pci_vfio_map_resource(dev);
 #endif
                break;
-       case RTE_KDRV_IGB_UIO:
-       case RTE_KDRV_UIO_GENERIC:
+       case RTE_PCI_KDRV_IGB_UIO:
+       case RTE_PCI_KDRV_UIO_GENERIC:
                if (rte_eal_using_phys_addrs()) {
                        /* map resources for devices that use uio */
                        ret = pci_uio_map_resource(dev);
@@ -98,14 +97,14 @@ rte_pci_unmap_device(struct rte_pci_device *dev)
 {
        /* try unmapping the NIC resources using VFIO if it exists */
        switch (dev->kdrv) {
-       case RTE_KDRV_VFIO:
+       case RTE_PCI_KDRV_VFIO:
 #ifdef VFIO_PRESENT
                if (pci_vfio_is_enabled())
                        pci_vfio_unmap_resource(dev);
 #endif
                break;
-       case RTE_KDRV_IGB_UIO:
-       case RTE_KDRV_UIO_GENERIC:
+       case RTE_PCI_KDRV_IGB_UIO:
+       case RTE_PCI_KDRV_UIO_GENERIC:
                /* unmap resources for devices that use uio */
                pci_uio_unmap_resource(dev);
                break;
@@ -324,16 +323,17 @@ pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
 
        if (!ret) {
                if (!strcmp(driver, "vfio-pci"))
-                       dev->kdrv = RTE_KDRV_VFIO;
+                       dev->kdrv = RTE_PCI_KDRV_VFIO;
                else if (!strcmp(driver, "igb_uio"))
-                       dev->kdrv = RTE_KDRV_IGB_UIO;
+                       dev->kdrv = RTE_PCI_KDRV_IGB_UIO;
                else if (!strcmp(driver, "uio_pci_generic"))
-                       dev->kdrv = RTE_KDRV_UIO_GENERIC;
+                       dev->kdrv = RTE_PCI_KDRV_UIO_GENERIC;
                else
-                       dev->kdrv = RTE_KDRV_UNKNOWN;
-       } else
-               dev->kdrv = RTE_KDRV_NONE;
-
+                       dev->kdrv = RTE_PCI_KDRV_UNKNOWN;
+       } else {
+               dev->kdrv = RTE_PCI_KDRV_NONE;
+               return 0;
+       }
        /* device is valid, add in list (sorted) */
        if (TAILQ_EMPTY(&rte_pci_bus.device_list)) {
                rte_pci_add_device(dev);
@@ -378,6 +378,11 @@ pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
                                                 */
                                                RTE_LOG(ERR, EAL, "Unexpected device scan at %s!\n",
                                                        filename);
+                                       else if (dev2->device.devargs !=
+                                                dev->device.devargs) {
+                                               rte_devargs_remove(dev2->device.devargs);
+                                               pci_name_set(dev2);
+                                       }
                                }
                                free(dev);
                        }
@@ -483,6 +488,9 @@ rte_pci_scan(void)
                if (parse_pci_addr_format(e->d_name, sizeof(e->d_name), &addr) != 0)
                        continue;
 
+               if (rte_pci_ignore_device(&addr))
+                       continue;
+
                snprintf(dirname, sizeof(dirname), "%s/%s",
                                rte_pci_get_sysfs_path(), e->d_name);
 
@@ -498,12 +506,11 @@ error:
 }
 
 #if defined(RTE_ARCH_X86)
-static bool
-pci_one_device_iommu_support_va(const struct rte_pci_device *dev)
+bool
+pci_device_iommu_support_va(const struct rte_pci_device *dev)
 {
 #define VTD_CAP_MGAW_SHIFT     16
 #define VTD_CAP_MGAW_MASK      (0x3fULL << VTD_CAP_MGAW_SHIFT)
-#define X86_VA_WIDTH 47 /* From Documentation/x86/x86_64/mm.txt */
        const struct rte_pci_addr *addr = &dev->addr;
        char filename[PATH_MAX];
        FILE *fp;
@@ -513,18 +520,19 @@ pci_one_device_iommu_support_va(const struct rte_pci_device *dev)
                 "%s/" PCI_PRI_FMT "/iommu/intel-iommu/cap",
                 rte_pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid,
                 addr->function);
-       if (access(filename, F_OK) == -1) {
-               /* We don't have an Intel IOMMU, assume VA supported*/
-               return true;
-       }
 
-       /* We have an intel IOMMU */
        fp = fopen(filename, "r");
        if (fp == NULL) {
-               RTE_LOG(ERR, EAL, "%s(): can't open %s\n", __func__, filename);
+               /* We don't have an Intel IOMMU, assume VA supported */
+               if (errno == ENOENT)
+                       return true;
+
+               RTE_LOG(ERR, EAL, "%s(): can't open %s: %s\n",
+                       __func__, filename, strerror(errno));
                return false;
        }
 
+       /* We have an Intel IOMMU */
        if (fscanf(fp, "%" PRIx64, &vtd_cap_reg) != 1) {
                RTE_LOG(ERR, EAL, "%s(): can't read %s\n", __func__, filename);
                fclose(fp);
@@ -547,14 +555,47 @@ pci_one_device_iommu_support_va(const struct rte_pci_device *dev)
        return true;
 }
 #elif defined(RTE_ARCH_PPC_64)
-static bool
-pci_one_device_iommu_support_va(__rte_unused const struct rte_pci_device *dev)
+bool
+pci_device_iommu_support_va(__rte_unused const struct rte_pci_device *dev)
 {
-       return false;
+       /*
+        * IOMMU is always present on a PowerNV host (IOMMUv2).
+        * IOMMU is also present in a KVM/QEMU VM (IOMMUv1) but is not
+        * currently supported by DPDK. Test for our current environment
+        * and report VA support as appropriate.
+        */
+
+       char *line = NULL;
+       size_t len = 0;
+       char filename[PATH_MAX] = "/proc/cpuinfo";
+       FILE *fp = fopen(filename, "r");
+       bool ret = false;
+
+       if (fp == NULL) {
+               RTE_LOG(ERR, EAL, "%s(): can't open %s: %s\n",
+                       __func__, filename, strerror(errno));
+               return ret;
+       }
+
+       /* Check for a PowerNV platform */
+       while (getline(&line, &len, fp) != -1) {
+               if (strstr(line, "platform") != NULL)
+                       continue;
+
+               if (strstr(line, "PowerNV") != NULL) {
+                       RTE_LOG(DEBUG, EAL, "Running on a PowerNV system\n");
+                       ret = true;
+                       break;
+               }
+       }
+
+       free(line);
+       fclose(fp);
+       return ret;
 }
 #else
-static bool
-pci_one_device_iommu_support_va(__rte_unused const struct rte_pci_device *dev)
+bool
+pci_device_iommu_support_va(__rte_unused const struct rte_pci_device *dev)
 {
        return true;
 }
@@ -565,10 +606,9 @@ pci_device_iova_mode(const struct rte_pci_driver *pdrv,
                     const struct rte_pci_device *pdev)
 {
        enum rte_iova_mode iova_mode = RTE_IOVA_DC;
-       static int iommu_no_va = -1;
 
        switch (pdev->kdrv) {
-       case RTE_KDRV_VFIO: {
+       case RTE_PCI_KDRV_VFIO: {
 #ifdef VFIO_PRESENT
                static int is_vfio_noiommu_enabled = -1;
 
@@ -586,8 +626,8 @@ pci_device_iova_mode(const struct rte_pci_driver *pdrv,
                break;
        }
 
-       case RTE_KDRV_IGB_UIO:
-       case RTE_KDRV_UIO_GENERIC:
+       case RTE_PCI_KDRV_IGB_UIO:
+       case RTE_PCI_KDRV_UIO_GENERIC:
                iova_mode = RTE_IOVA_PA;
                break;
 
@@ -596,18 +636,6 @@ pci_device_iova_mode(const struct rte_pci_driver *pdrv,
                        iova_mode = RTE_IOVA_VA;
                break;
        }
-
-       if (iova_mode != RTE_IOVA_PA) {
-               /*
-                * We can check this only once, because the IOMMU hardware is
-                * the same for all of them.
-                */
-               if (iommu_no_va == -1)
-                       iommu_no_va = pci_one_device_iommu_support_va(pdev)
-                                       ? 0 : 1;
-               if (iommu_no_va != 0)
-                       iova_mode = RTE_IOVA_PA;
-       }
        return iova_mode;
 }
 
@@ -619,11 +647,11 @@ int rte_pci_read_config(const struct rte_pci_device *device,
        const struct rte_intr_handle *intr_handle = &device->intr_handle;
 
        switch (device->kdrv) {
-       case RTE_KDRV_IGB_UIO:
-       case RTE_KDRV_UIO_GENERIC:
+       case RTE_PCI_KDRV_IGB_UIO:
+       case RTE_PCI_KDRV_UIO_GENERIC:
                return pci_uio_read_config(intr_handle, buf, len, offset);
 #ifdef VFIO_PRESENT
-       case RTE_KDRV_VFIO:
+       case RTE_PCI_KDRV_VFIO:
                return pci_vfio_read_config(intr_handle, buf, len, offset);
 #endif
        default:
@@ -643,11 +671,11 @@ int rte_pci_write_config(const struct rte_pci_device *device,
        const struct rte_intr_handle *intr_handle = &device->intr_handle;
 
        switch (device->kdrv) {
-       case RTE_KDRV_IGB_UIO:
-       case RTE_KDRV_UIO_GENERIC:
+       case RTE_PCI_KDRV_IGB_UIO:
+       case RTE_PCI_KDRV_UIO_GENERIC:
                return pci_uio_write_config(intr_handle, buf, len, offset);
 #ifdef VFIO_PRESENT
-       case RTE_KDRV_VFIO:
+       case RTE_PCI_KDRV_VFIO:
                return pci_vfio_write_config(intr_handle, buf, len, offset);
 #endif
        default:
@@ -671,6 +699,12 @@ pci_ioport_map(struct rte_pci_device *dev, int bar __rte_unused,
        int found = 0;
        size_t linesz;
 
+       if (rte_eal_iopl_init() != 0) {
+               RTE_LOG(ERR, EAL, "%s(): insufficient ioport permissions for PCI device %s\n",
+                       __func__, dev->name);
+               return -1;
+       }
+
        snprintf(pci_id, sizeof(pci_id), PCI_PRI_FMT,
                 dev->addr.domain, dev->addr.bus,
                 dev->addr.devid, dev->addr.function);
@@ -726,24 +760,19 @@ rte_pci_ioport_map(struct rte_pci_device *dev, int bar,
 
        switch (dev->kdrv) {
 #ifdef VFIO_PRESENT
-       case RTE_KDRV_VFIO:
+       case RTE_PCI_KDRV_VFIO:
                if (pci_vfio_is_enabled())
                        ret = pci_vfio_ioport_map(dev, bar, p);
                break;
 #endif
-       case RTE_KDRV_IGB_UIO:
+       case RTE_PCI_KDRV_IGB_UIO:
                ret = pci_uio_ioport_map(dev, bar, p);
                break;
-       case RTE_KDRV_UIO_GENERIC:
+       case RTE_PCI_KDRV_UIO_GENERIC:
 #if defined(RTE_ARCH_X86)
                ret = pci_ioport_map(dev, bar, p);
 #else
                ret = pci_uio_ioport_map(dev, bar, p);
-#endif
-               break;
-       case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-               ret = pci_ioport_map(dev, bar, p);
 #endif
                break;
        default:
@@ -762,21 +791,16 @@ rte_pci_ioport_read(struct rte_pci_ioport *p,
 {
        switch (p->dev->kdrv) {
 #ifdef VFIO_PRESENT
-       case RTE_KDRV_VFIO:
+       case RTE_PCI_KDRV_VFIO:
                pci_vfio_ioport_read(p, data, len, offset);
                break;
 #endif
-       case RTE_KDRV_IGB_UIO:
+       case RTE_PCI_KDRV_IGB_UIO:
                pci_uio_ioport_read(p, data, len, offset);
                break;
-       case RTE_KDRV_UIO_GENERIC:
+       case RTE_PCI_KDRV_UIO_GENERIC:
                pci_uio_ioport_read(p, data, len, offset);
                break;
-       case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-               pci_uio_ioport_read(p, data, len, offset);
-#endif
-               break;
        default:
                break;
        }
@@ -788,21 +812,16 @@ rte_pci_ioport_write(struct rte_pci_ioport *p,
 {
        switch (p->dev->kdrv) {
 #ifdef VFIO_PRESENT
-       case RTE_KDRV_VFIO:
+       case RTE_PCI_KDRV_VFIO:
                pci_vfio_ioport_write(p, data, len, offset);
                break;
 #endif
-       case RTE_KDRV_IGB_UIO:
+       case RTE_PCI_KDRV_IGB_UIO:
                pci_uio_ioport_write(p, data, len, offset);
                break;
-       case RTE_KDRV_UIO_GENERIC:
+       case RTE_PCI_KDRV_UIO_GENERIC:
                pci_uio_ioport_write(p, data, len, offset);
                break;
-       case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-               pci_uio_ioport_write(p, data, len, offset);
-#endif
-               break;
        default:
                break;
        }
@@ -815,24 +834,19 @@ rte_pci_ioport_unmap(struct rte_pci_ioport *p)
 
        switch (p->dev->kdrv) {
 #ifdef VFIO_PRESENT
-       case RTE_KDRV_VFIO:
+       case RTE_PCI_KDRV_VFIO:
                if (pci_vfio_is_enabled())
                        ret = pci_vfio_ioport_unmap(p);
                break;
 #endif
-       case RTE_KDRV_IGB_UIO:
+       case RTE_PCI_KDRV_IGB_UIO:
                ret = pci_uio_ioport_unmap(p);
                break;
-       case RTE_KDRV_UIO_GENERIC:
+       case RTE_PCI_KDRV_UIO_GENERIC:
 #if defined(RTE_ARCH_X86)
                ret = 0;
 #else
                ret = pci_uio_ioport_unmap(p);
-#endif
-               break;
-       case RTE_KDRV_NONE:
-#if defined(RTE_ARCH_X86)
-               ret = 0;
 #endif
                break;
        default: