diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 2e708db..56d0698 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -95,3 +95,8 @@ Deprecation Notices
   The non-"do-sig" versions of the hash tables will be removed
   (including the ``signature_offset`` parameter)
   and the "do-sig" versions renamed accordingly.
+
+* eal: the following function is deprecated starting from 17.08 and will
+  be removed in 17.11:
+
+  - ``rte_eal_parse_devargs_str``, replaced by ``rte_eal_devargs_parse``
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 0295ea9..cec3894 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -200,6 +200,7 @@ DPDK_17.08 {
 	rte_bus_find;
 	rte_bus_find_by_device;
 	rte_bus_find_by_name;
+	rte_eal_devargs_parse;
 
 } DPDK_17.05;
 
diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
index 8fe1b39..3ea070d 100644
--- a/lib/librte_eal/common/eal_common_devargs.c
+++ b/lib/librte_eal/common/eal_common_devargs.c
@@ -86,49 +86,77 @@ bus_name_cmp(const struct rte_bus *bus, const void *_name)
 		       strlen(bus->name));
 }
 
-/* store a whitelist parameter for later parsing */
 int
-rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
+rte_eal_devargs_parse(const char *dev, struct rte_devargs *da)
 {
-	struct rte_devargs *devargs = NULL;
 	struct rte_bus *bus = NULL;
-	char *dev = NULL;
 	const char *devname;
-	int ret;
-
-	/* use malloc instead of rte_malloc as it's called early at init */
-	devargs = malloc(sizeof(*devargs));
-	if (devargs == NULL)
-		goto fail;
-
-	memset(devargs, 0, sizeof(*devargs));
-	devargs->type = devtype;
+	const size_t maxlen = sizeof(da->name);
+	size_t i;
 
-	if (rte_eal_parse_devargs_str(devargs_str, &dev, &devargs->args))
-		goto fail;
-	devname = dev;
+	if (dev == NULL || da == NULL)
+		return -EINVAL;
+	/* Retrieve eventual bus info */
 	do {
+		devname = dev;
 		bus = rte_bus_find(bus, bus_name_cmp, dev);
 		if (bus == NULL)
 			break;
 		devname = dev + strlen(bus->name) + 1;
 		if (rte_bus_find_by_device_name(devname) == bus)
 			break;
-		devname = dev;
 	} while (1);
+	/* Store device name */
+	i = 0;
+	while (devname[i] != '\0' && devname[i] != ',') {
+		da->name[i] = devname[i];
+		i++;
+		if (i == maxlen) {
+			fprintf(stderr, "WARNING: Parsing \"%s\": device name should be shorter than %zu\n",
+				dev, maxlen);
+			da->name[i - 1] = '\0';
+			return -EINVAL;
+		}
+	}
+	da->name[i] = '\0';
 	if (bus == NULL) {
-		bus = rte_bus_find_by_device_name(devname);
+		bus = rte_bus_find_by_device_name(da->name);
 		if (bus == NULL) {
-			fprintf(stderr, "ERROR: failed to parse bus info from device declaration\n");
-			goto fail;
+			fprintf(stderr, "ERROR: failed to parse device \"%s\"\n",
+				da->name);
+			return -EFAULT;
 		}
 	}
-	devargs->bus = bus;
+	da->bus = bus;
+	/* Parse eventual device arguments */
+	if (devname[i] == ',')
+		da->args = strdup(&devname[i + 1]);
+	else
+		da->args = strdup("");
+	if (da->args == NULL) {
+		fprintf(stderr, "ERROR: not enough memory to parse arguments\n");
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+/* store a whitelist parameter for later parsing */
+int
+rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
+{
+	struct rte_devargs *devargs = NULL;
+	struct rte_bus *bus = NULL;
+	const char *dev = devargs_str;
 
-	/* save device name. */
-	ret = snprintf(devargs->name, sizeof(devargs->name), "%s", devname);
-	if (ret < 0 || ret >= (int)sizeof(devargs->name))
+	/* use calloc instead of rte_zmalloc as it's called early at init */
+	devargs = calloc(1, sizeof(*devargs));
+	if (devargs == NULL)
 		goto fail;
+
+	if (rte_eal_devargs_parse(dev, devargs))
+		goto fail;
+	devargs->type = devtype;
+	bus = devargs->bus;
 	if (devargs->type == RTE_DEVTYPE_WHITELISTED) {
 		if (bus->conf.scan_mode == RTE_BUS_SCAN_UNDEFINED) {
 			bus->conf.scan_mode = RTE_BUS_SCAN_WHITELIST;
@@ -145,12 +173,10 @@ rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
 		}
 	}
 
-	free(dev);
 	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
 	return 0;
 
 fail:
-	free(dev);
 	if (devargs) {
 		free(devargs->args);
 		free(devargs);
diff --git a/lib/librte_eal/common/include/rte_devargs.h b/lib/librte_eal/common/include/rte_devargs.h
index 6e9e134..2ab8864 100644
--- a/lib/librte_eal/common/include/rte_devargs.h
+++ b/lib/librte_eal/common/include/rte_devargs.h
@@ -119,6 +119,26 @@ int rte_eal_parse_devargs_str(const char *devargs_str,
 				char **drvname, char **drvargs);
 
 /**
+ * Parse a device string.
+ *
+ * Verify that a bus is capable of handling the device passed
+ * in argument. Store which bus will handle the device, its name
+ * and the eventual device parameters.
+ *
+ * @param dev
+ *   The device declaration string.
+ * @param da
+ *   The devargs structure holding the device information.
+ *
+ * @return
+ *   - 0 on success.
+ *   - Negative errno on error.
+ */
+int
+rte_eal_devargs_parse(const char *dev,
+		      struct rte_devargs *da);
+
+/**
  * Add a device to the user device list
  *
  * For PCI devices, the format of arguments string is "PCI_ADDR" or
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index a118fb1..09b875a 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -205,6 +205,7 @@ DPDK_17.08 {
 	rte_bus_find;
 	rte_bus_find_by_device;
 	rte_bus_find_by_name;
+	rte_eal_devargs_parse;
 
 } DPDK_17.05;
 
