[dpdk-dev,v1,06/18] eal/dev: implement device iteration initialization
Checks
Commit Message
Parse a device description.
Split this description in their relevant part for both abstraction
layer.
No dynamic allocation is performed.
Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
---
lib/librte_eal/common/eal_common_dev.c | 58 +++++++++++++++++++++++++++++++++
lib/librte_eal/common/include/rte_dev.h | 23 +++++++++++++
lib/librte_eal/rte_eal_version.map | 1 +
3 files changed, 82 insertions(+)
@@ -10,6 +10,7 @@
#include <rte_compat.h>
#include <rte_bus.h>
+#include <rte_class.h>
#include <rte_dev.h>
#include <rte_devargs.h>
#include <rte_debug.h>
@@ -245,3 +246,60 @@ rte_eal_hotplug_remove(const char *busname, const char *devname)
rte_eal_devargs_remove(busname, devname);
return ret;
}
+
+int __rte_experimental
+rte_dev_iterator_init(struct rte_dev_iterator *it, const char *str)
+{
+ struct rte_bus *bus = NULL;
+ struct rte_class *cls = NULL;
+ struct rte_kvarg kv;
+
+ /* Having both busstr and clsstr NULL is illegal,
+ * marking this iterator as invalid unless
+ * everything goes well.
+ */
+ it->busstr = NULL;
+ it->clsstr = NULL;
+ /* Safety checks and prep-work */
+ if (rte_parse_kv(str, &kv)) {
+ RTE_LOG(ERR, EAL, "Could not parse: %s\n", str);
+ return -1;
+ }
+ it->device = NULL;
+ it->class_device = NULL;
+ if (strcmp(kv.key, "bus") == 0) {
+ char *slash;
+
+ bus = rte_bus_find_by_name(kv.value);
+ it->busstr = str;
+ slash = strchr(str, '/');
+ if (slash != NULL) {
+ if (rte_parse_kv(slash + 1, &kv))
+ return -1;
+ cls = rte_class_find_by_name(kv.value);
+ it->clsstr = slash + 1;
+ }
+ } else if (strcmp(kv.key, "class") == 0) {
+ cls = rte_class_find_by_name(kv.value);
+ it->clsstr = str;
+ } else {
+ rte_errno = EINVAL;
+ return -rte_errno;
+ }
+ /* The string should have at least
+ * one layer specified.
+ */
+ if (bus == NULL && cls == NULL) {
+ rte_errno = EINVAL;
+ return -rte_errno;
+ }
+ if ((bus != NULL && bus->dev_iterate == NULL) ||
+ (cls != NULL && cls->dev_iterate == NULL)) {
+ rte_errno = ENOTSUP;
+ return -rte_errno;
+ }
+ it->devstr = str;
+ it->bus = bus;
+ it->cls = cls;
+ return 0;
+}
@@ -299,6 +299,29 @@ struct rte_dev_iterator {
*/
typedef struct rte_device *(*rte_dev_iterate_t)(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.
+ */
+int __rte_experimental
+rte_dev_iterator_init(struct rte_dev_iterator *it, const char *str);
+
#ifdef __cplusplus
}
#endif
@@ -228,6 +228,7 @@ EXPERIMENTAL {
rte_mp_sendmsg;
rte_mp_request;
rte_mp_reply;
+ rte_dev_iterator_init;
rte_service_attr_get;
rte_service_attr_reset_all;
rte_service_component_register;