This patch adds a shared enum between user and kernel space to rte_pci_device.
The value of intr_mode is parsed by eal_pci during pci_uio_map_resource

Signed-off-by: Alan Carew <alan.carew at intel.com>
---
 lib/librte_eal/common/Makefile          |    1 +
 lib/librte_eal/common/include/rte_pci.h |    2 +
 lib/librte_eal/linuxapp/eal/eal_pci.c   |   78 +++++++++++++++++++++++++++++++
 3 files changed, 81 insertions(+), 0 deletions(-)

diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index 0016fc5..52d46f3 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -35,6 +35,7 @@ INC := rte_atomic.h rte_branch_prediction.h rte_byteorder.h 
rte_common.h
 INC += rte_cycles.h rte_debug.h rte_eal.h rte_errno.h rte_launch.h rte_lcore.h
 INC += rte_log.h rte_memcpy.h rte_memory.h rte_memzone.h rte_pci.h
 INC += rte_pci_dev_ids.h rte_per_lcore.h rte_prefetch.h rte_random.h
+INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h
 INC += rte_rwlock.h rte_spinlock.h rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_cpuflags.h rte_version.h rte_tailq_elem.h
 INC += rte_eal_memconfig.h rte_malloc_heap.h
diff --git a/lib/librte_eal/common/include/rte_pci.h 
b/lib/librte_eal/common/include/rte_pci.h
index c793773..5883cd9 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -81,6 +81,7 @@ extern "C" {
 #include <stdint.h>
 #include <inttypes.h>
 #include <rte_interrupts.h>
+#include <rte_pci_dev_feature_defs.h>

 TAILQ_HEAD(pci_device_list, rte_pci_device); /**< PCI devices in D-linked Q. */
 TAILQ_HEAD(pci_driver_list, rte_pci_driver); /**< PCI drivers in D-linked Q. */
@@ -150,6 +151,7 @@ struct rte_pci_device {
        const struct rte_pci_driver *driver;    /**< Associated driver */
        uint16_t max_vfs;                       /**< sriov enable if not zero */
        int numa_node;                          /**< NUMA node connection */
+       enum igbuio_intr_mode intr_mode;        /**< Interrupt mode */
        struct rte_devargs *devargs;            /**< Device user arguments */
 };

diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c 
b/lib/librte_eal/linuxapp/eal/eal_pci.c
index ac2c1fe..7dba446 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -67,6 +67,7 @@
 #include <rte_devargs.h>

 #include "rte_pci_dev_ids.h"
+#include "rte_pci_dev_feature_defs.h"
 #include "eal_filesystem.h"
 #include "eal_private.h"

@@ -89,6 +90,17 @@ struct uio_map {
        uint64_t phaddr;
 };

+struct rte_pci_dev_intr_mode {
+       enum igbuio_intr_mode mode;
+       const char *name;
+};
+
+/* Table of interrupt modes */
+const struct rte_pci_dev_intr_mode interrupt_modes[] = {
+#define RTE_PCI_DEV_INTR_MODE(id, mode_name) {INTR_MODE(id, mode_name)},
+#include <rte_pci_dev_features.h>
+};
+
 /*
  * For multi-process we need to reproduce all PCI mappings in secondary
  * processes, so save them in a tailq.
@@ -106,6 +118,7 @@ TAILQ_HEAD(uio_res_list, uio_resource);

 static struct uio_res_list *uio_res_list = NULL;
 static int pci_parse_sysfs_value(const char *filename, uint64_t *val);
+static int pci_parse_sysfs_intr_mode(const char *filename, struct 
rte_pci_device *dev);

 /* unbind kernel driver for this device */
 static int
@@ -400,6 +413,7 @@ pci_uio_map_resource(struct rte_pci_device *dev)
        int i, j;
        char dirname[PATH_MAX];
        char devname[PATH_MAX]; /* contains the /dev/uioX */
+    char filename[PATH_MAX];
        void *mapaddr;
        int uio_num;
        uint64_t phaddr;
@@ -435,6 +449,18 @@ pci_uio_map_resource(struct rte_pci_device *dev)
        }
        dev->intr_handle.type = RTE_INTR_HANDLE_UIO;

+       rte_snprintf(filename, sizeof(filename),
+                       SYSFS_PCI_DEVICES "/" PCI_PRI_FMT
+                       "/"RTE_PCI_DEV_FEATURE_INTR_MODE,
+                       loc->domain, loc->bus, loc->devid, loc->function);
+
+    /* Get the kernel configured interrupt mode */
+       if (pci_parse_sysfs_intr_mode(filename, dev) < 0) {
+               RTE_LOG(ERR, EAL, "%s(): cannot determine interrupt_mode\n",
+                               __func__);
+               return -1;
+       }
+
        /* allocate the mapping details for secondary processes*/
        if ((uio_res = rte_zmalloc("UIO_RES", sizeof (*uio_res), 0)) == NULL) {
                RTE_LOG(ERR, EAL,
@@ -591,6 +617,58 @@ pci_parse_sysfs_value(const char *filename, uint64_t *val)
         return 0;
 }

+/* 
+ * Parse a sysfs file containing a string
+ */ 
+static int
+pci_parse_sysfs_string(const char *filename, char *result_str, int max_len)
+{
+       FILE *f;
+       size_t len;
+
+       f = fopen(filename, "r");
+       if (f == NULL) {
+               RTE_LOG(ERR, EAL, "%s(): cannot open sysfs value %s\n",
+                               __func__, filename);
+               return -1;
+       }
+       if (fgets(result_str, max_len, f) == NULL) {
+               RTE_LOG(ERR, EAL, "%s(): cannot read sysfs value %s\n",
+                               __func__, filename);
+               fclose(f);
+               return -1;
+       }
+       len = strnlen(result_str, max_len) -1;
+       if (result_str[len] == '\n')
+               result_str[len] = '\0';
+
+       fclose(f);
+       return 0;
+}
+
+/*
+ * Determine the kernel configured interrupt mode
+ */
+static int
+pci_parse_sysfs_intr_mode(const char *filename, struct rte_pci_device *dev)
+{
+       char intr_mode[INTR_NAME_LEN];
+       unsigned int i, num_intr_modes = RTE_DIM(interrupt_modes);
+
+       if (pci_parse_sysfs_string(filename, intr_mode, RTE_DIM(intr_mode)) < 
0) {
+               RTE_LOG(ERR, EAL, "%s(): cannot parse interrupt_mode\n",
+                       __func__);
+               return -1;
+       }
+
+       for (i = 0; i < num_intr_modes; i++)
+               if (!strncmp(intr_mode, interrupt_modes[i].name, 
INTR_NAME_LEN)) {
+                       dev->intr_mode = interrupt_modes[i].mode;
+                       return 0;
+               }
+       return -1;
+}
+
 /* Compare two PCI device addresses. */
 static int
 pci_addr_comparison(struct rte_pci_addr *addr, struct rte_pci_addr *addr2)
-- 
1.7.0.7

Reply via email to