eal: implement device iteration initialization
authorGaetan Rivet <gaetan.rivet@6wind.com>
Wed, 11 Jul 2018 21:45:00 +0000 (23:45 +0200)
committerThomas Monjalon <thomas@monjalon.net>
Sun, 15 Jul 2018 21:43:53 +0000 (23:43 +0200)
Parse a device description.
Split this description in their relevant part for each layers.
No dynamic allocation is performed.

Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
lib/librte_eal/common/eal_common_dev.c
lib/librte_eal/common/include/rte_dev.h
lib/librte_eal/rte_eal_version.map

index ce4b514..63e329b 100644 (file)
 
 #include <rte_compat.h>
 #include <rte_bus.h>
+#include <rte_class.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include <rte_debug.h>
+#include <rte_errno.h>
+#include <rte_kvargs.h>
 #include <rte_log.h>
 #include <rte_spinlock.h>
 #include <rte_malloc.h>
@@ -343,3 +346,55 @@ dev_callback_process(char *device_name, enum rte_dev_event_type event)
        }
        rte_spinlock_unlock(&dev_event_lock);
 }
+
+__rte_experimental
+int
+rte_dev_iterator_init(struct rte_dev_iterator *it,
+                     const char *dev_str)
+{
+       struct rte_devargs devargs;
+       struct rte_class *cls = NULL;
+       struct rte_bus *bus = NULL;
+
+       /* Having both bus_str and cls_str NULL is illegal,
+        * marking this iterator as invalid unless
+        * everything goes well.
+        */
+       it->bus_str = NULL;
+       it->cls_str = NULL;
+
+       devargs.data = dev_str;
+       if (rte_devargs_layers_parse(&devargs, dev_str))
+               goto get_out;
+
+       bus = devargs.bus;
+       cls = devargs.cls;
+       /* The string should have at least
+        * one layer specified.
+        */
+       if (bus == NULL && cls == NULL) {
+               RTE_LOG(ERR, EAL,
+                       "Either bus or class must be specified.\n");
+               rte_errno = EINVAL;
+               goto get_out;
+       }
+       if (bus != NULL && bus->dev_iterate == NULL) {
+               RTE_LOG(ERR, EAL, "Bus %s not supported\n", bus->name);
+               rte_errno = ENOTSUP;
+               goto get_out;
+       }
+       if (cls != NULL && cls->dev_iterate == NULL) {
+               RTE_LOG(ERR, EAL, "Class %s not supported\n", cls->name);
+               rte_errno = ENOTSUP;
+               goto get_out;
+       }
+       it->bus_str = devargs.bus_str;
+       it->cls_str = devargs.cls_str;
+       it->dev_str = dev_str;
+       it->bus = bus;
+       it->cls = cls;
+       it->device = NULL;
+       it->class_device = NULL;
+get_out:
+       return -rte_errno;
+}
index d16bc8c..2ce3c8c 100644 (file)
@@ -330,6 +330,30 @@ typedef void *(*rte_dev_iterate_t)(const void *start,
                                   const char *devstr,
                                   const struct rte_dev_iterator *it);
 
+/**
+ * Initializes a device iterator.
+ *
+ * This iterator allows accessing a list of devices matching a criteria.
+ * The device matching is made among all buses and classes currently registered,
+ * filtered by the device description given as parameter.
+ *
+ * This function will not allocate any memory. It is safe to stop the
+ * iteration at any moment and let the iterator go out of context.
+ *
+ * @param it
+ *   Device iterator handle.
+ *
+ * @param str
+ *   Device description string.
+ *
+ * @return
+ *   0 on successful initialization.
+ *   <0 on error.
+ */
+__rte_experimental
+int
+rte_dev_iterator_init(struct rte_dev_iterator *it, const char *str);
+
 #ifdef __cplusplus
 }
 #endif
index 0f99c0b..f0d1289 100644 (file)
@@ -263,6 +263,7 @@ EXPERIMENTAL {
        rte_dev_event_callback_unregister;
        rte_dev_event_monitor_start;
        rte_dev_event_monitor_stop;
+       rte_dev_iterator_init;
        rte_devargs_add;
        rte_devargs_dump;
        rte_devargs_insert;