]> git.droids-corp.org - dpdk.git/commitdiff
pci: add kernel driver type
authorMichael Qiu <michael.qiu@intel.com>
Wed, 25 Feb 2015 19:32:16 +0000 (04:32 +0900)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Wed, 25 Feb 2015 22:38:00 +0000 (23:38 +0100)
Currently, dpdk has no ability to know which type of driver(
vfio-pci/igb_uio/uio_pci_generic) the device used. It only can
check whether vfio is enabled or not statically.

It really useful to have the flag, because different type need to
handle differently in runtime. For example, pci memory map,
pot hotplug, and so on.

This patch add a flag field for pci device to solve above issue.

Signed-off-by: Michael Qiu <michael.qiu@intel.com>
Signed-off-by: Tetsuya Mukawa <mukawa@igel.co.jp>
Acked-by: Bernard Iremonger <bernard.iremonger@intel.com>
lib/librte_eal/common/include/rte_pci.h
lib/librte_eal/linuxapp/eal/eal_pci.c

index 3df07e8e8a3bf9a56fe98d498a84a854798c629a..a87b4b3b8892983998b42bcc767448afeedf83af 100644 (file)
@@ -142,6 +142,13 @@ struct rte_pci_addr {
 
 struct rte_devargs;
 
+enum rte_pt_driver {
+       RTE_PT_UNKNOWN          = 0,
+       RTE_PT_IGB_UIO          = 1,
+       RTE_PT_VFIO             = 2,
+       RTE_PT_UIO_GENERIC      = 3,
+};
+
 /**
  * A structure describing a PCI device.
  */
@@ -155,6 +162,7 @@ struct rte_pci_device {
        uint16_t max_vfs;                       /**< sriov enable if not zero */
        int numa_node;                          /**< NUMA node connection */
        struct rte_devargs *devargs;            /**< Device user arguments */
+       enum rte_pt_driver pt_driver;           /**< Driver of passthrough */
 };
 
 /** Any PCI device identifier (vendor, device, ...) */
index a4fd5f5a10e34aa0d41251a1a13d9128eb517f5c..4615756bc7e505de616c751f44fbc6f8041cb10a 100644 (file)
@@ -97,6 +97,35 @@ error:
        return -1;
 }
 
+static int
+pci_get_kernel_driver_by_path(const char *filename, char *dri_name)
+{
+       int count;
+       char path[PATH_MAX];
+       char *name;
+
+       if (!filename || !dri_name)
+               return -1;
+
+       count = readlink(filename, path, PATH_MAX);
+       if (count >= PATH_MAX)
+               return -1;
+
+       /* For device does not have a driver */
+       if (count < 0)
+               return 1;
+
+       path[count] = '\0';
+
+       name = strrchr(path, '/');
+       if (name) {
+               strncpy(dri_name, name + 1, strlen(name + 1) + 1);
+               return 0;
+       }
+
+       return -1;
+}
+
 void *
 pci_find_max_end_va(void)
 {
@@ -221,11 +250,12 @@ pci_scan_one(const char *dirname, uint16_t domain, uint8_t bus,
        char filename[PATH_MAX];
        unsigned long tmp;
        struct rte_pci_device *dev;
+       char driver[PATH_MAX];
+       int ret;
 
        dev = malloc(sizeof(*dev));
-       if (dev == NULL) {
+       if (dev == NULL)
                return -1;
-       }
 
        memset(dev, 0, sizeof(*dev));
        dev->addr.domain = domain;
@@ -304,6 +334,25 @@ pci_scan_one(const char *dirname, uint16_t domain, uint8_t bus,
                return -1;
        }
 
+       /* parse driver */
+       snprintf(filename, sizeof(filename), "%s/driver", dirname);
+       ret = pci_get_kernel_driver_by_path(filename, driver);
+       if (!ret) {
+               if (!strcmp(driver, "vfio-pci"))
+                       dev->pt_driver = RTE_PT_VFIO;
+               else if (!strcmp(driver, "igb_uio"))
+                       dev->pt_driver = RTE_PT_IGB_UIO;
+               else if (!strcmp(driver, "uio_pci_generic"))
+                       dev->pt_driver = RTE_PT_UIO_GENERIC;
+               else
+                       dev->pt_driver = RTE_PT_UNKNOWN;
+       } else if (ret < 0) {
+               RTE_LOG(ERR, EAL, "Fail to get kernel driver\n");
+               free(dev);
+               return -1;
+       } else
+               dev->pt_driver = RTE_PT_UNKNOWN;
+
        /* device is valid, add in list (sorted) */
        if (TAILQ_EMPTY(&pci_device_list)) {
                TAILQ_INSERT_TAIL(&pci_device_list, dev, next);