All of lore.kernel.org
 help / color / mirror / Atom feed
From: Shreyansh Jain <shreyansh.jain@nxp.com>
To: <dev@dpdk.org>
Cc: Shreyansh Jain <shreyansh.jain@nxp.com>,
	thomas.monjalon@6wind.com, viktorin@rehivetech.com
Subject: [PATCH v7 11/21] eal/soc: implement probing of drivers
Date: Fri, 28 Oct 2016 17:56:28 +0530	[thread overview]
Message-ID: <1477657598-826-12-git-send-email-shreyansh.jain@nxp.com> (raw)
In-Reply-To: <1477657598-826-1-git-send-email-shreyansh.jain@nxp.com>

Each SoC PMD registers a set of callback for scanning its own bus/infra and
matching devices to drivers when probe is called.
This patch introduces the infra for calls to SoC scan on rte_eal_soc_init()
and match on rte_eal_soc_probe().

Patch also adds test case for scan and probe.

Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
--
v4:
 - Update test_soc for descriptive test function names
 - Comments over test functions
 - devinit and devuninint --> probe/remove
 - RTE_VERIFY at some places
---
 app/test/test_soc.c                             | 205 ++++++++++++++++++++++-
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   4 +
 lib/librte_eal/common/eal_common_soc.c          | 213 +++++++++++++++++++++++-
 lib/librte_eal/common/include/rte_soc.h         |  75 ++++++++-
 lib/librte_eal/linuxapp/eal/eal.c               |   5 +
 lib/librte_eal/linuxapp/eal/eal_soc.c           |  21 ++-
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   4 +
 7 files changed, 519 insertions(+), 8 deletions(-)

diff --git a/app/test/test_soc.c b/app/test/test_soc.c
index ac03e64..b587d5e 100644
--- a/app/test/test_soc.c
+++ b/app/test/test_soc.c
@@ -87,14 +87,65 @@ static int test_compare_addr(void)
  */
 struct test_wrapper {
 	struct rte_soc_driver soc_drv;
+	struct rte_soc_device soc_dev;
 };
 
+static int empty_pmd0_probe(struct rte_soc_driver *drv,
+			      struct rte_soc_device *dev);
+static int empty_pmd0_remove(struct rte_soc_device *dev);
+
+static void always_find_dev0_cb(void);
+static int match_dev0_by_name(struct rte_soc_driver *drv,
+				  struct rte_soc_device *dev);
+
+static void always_find_dev1_cb(void);
+static int match_dev1_by_name(struct rte_soc_driver *drv,
+				  struct rte_soc_device *dev);
+
+/**
+ * Dummy probe handler for PMD driver 'pmd0'.
+ *
+ * @param drv
+ *	driver object
+ * @param dev
+ *	device object
+ * @return
+ *	0 on success
+ */
+static int
+empty_pmd0_probe(struct rte_soc_driver *drv __rte_unused,
+		   struct rte_soc_device *dev __rte_unused)
+{
+	return 0;
+}
+
+/**
+ * Remove handler for PMD driver 'pmd0'.
+ *
+ * @param dev
+ *	device to remove
+ * @return
+ *	0 on success
+ */
+static int
+empty_pmd0_remove(struct rte_soc_device *dev)
+{
+	/* Release the memory associated with dev->addr.name */
+	free(dev->addr.name);
+
+	return 0;
+}
+
 struct test_wrapper empty_pmd0 = {
 	.soc_drv = {
 		.driver = {
 			.name = "empty_pmd0"
 		},
-	},
+		.probe = empty_pmd0_probe,
+		.remove = empty_pmd0_remove,
+		.scan_fn = always_find_dev0_cb,
+		.match_fn = match_dev0_by_name,
+	}
 };
 
 struct test_wrapper empty_pmd1 = {
@@ -102,9 +153,87 @@ struct test_wrapper empty_pmd1 = {
 		.driver = {
 			.name = "empty_pmd1"
 		},
+		.scan_fn = always_find_dev1_cb,
+		.match_fn = match_dev1_by_name,
 	},
 };
 
+/**
+ * Bus scan by PMD 'pmd0' for adding device 'dev0'
+ *
+ * @param void
+ * @return void
+ */
+static void
+always_find_dev0_cb(void)
+{
+	/* SoC's scan would scan devices on its bus and add to
+	 * soc_device_list
+	 */
+	empty_pmd0.soc_dev.addr.name = strdup("empty_pmd0_dev");
+
+	TAILQ_INSERT_TAIL(&soc_device_list, &empty_pmd0.soc_dev, next);
+}
+
+/**
+ * Match device 'dev0' with driver PMD pmd0
+ *
+ * @param drv
+ *	Driver with this matching needs to be done; unused here
+ * @param dev
+ *	device to be matched against driver
+ * @return
+ *	0 on successful matched
+ *	1 if driver<=>device don't match
+ */
+static int
+match_dev0_by_name(struct rte_soc_driver *drv __rte_unused,
+		       struct rte_soc_device *dev)
+{
+	if (!dev->addr.name || strcmp(dev->addr.name, "empty_pmd0_dev"))
+		return 0;
+
+	return 1;
+}
+
+/**
+ * Bus scan by PMD 'pmd0' for adding device 'dev1'
+ *
+ * @param void
+ * @return void
+ */
+static void
+always_find_dev1_cb(void)
+{
+	/* SoC's scan would scan devices on its bus and add to
+	 * soc_device_list
+	 */
+	empty_pmd0.soc_dev.addr.name = strdup("empty_pmd1_dev");
+
+	TAILQ_INSERT_TAIL(&soc_device_list, &empty_pmd1.soc_dev, next);
+}
+
+/**
+ * Match device 'dev1' with driver PMD pmd0
+ *
+ * @param drv
+ *	Driver with this matching needs to be done; unused here
+ * @param dev
+ *	device to be matched against driver
+ * @return
+ *	0 on successful matched
+ *	1 if driver<=>device don't match
+ */
+static int
+match_dev1_by_name(struct rte_soc_driver *drv __rte_unused,
+		       struct rte_soc_device *dev)
+{
+	if (!dev->addr.name || strcmp(dev->addr.name, "empty_pmd1_dev"))
+		return 0;
+
+	return 1;
+}
+
 static int
 count_registered_socdrvs(void)
 {
@@ -148,13 +277,68 @@ test_register_unregister(void)
 	return 0;
 }
 
+/* Test Probe (scan and match) functionality */
+static int
+test_soc_scan_and_match(void)
+{
+	int drv_count = 0;
+	struct rte_soc_driver *drv;
+
+	/* Registering dummy drivers */
+	rte_eal_soc_register(&empty_pmd0.soc_drv);
+	rte_eal_soc_register(&empty_pmd1.soc_drv);
+	/* Assuming that test_register_unregister is working, not verifying
+	 * that drivers are indeed registered
+	*/
+
+	/* rte_eal_soc_init is called by rte_eal_init, which in turn calls the
+	 * scan_fn of each driver.
+	 */
+	TAILQ_FOREACH(drv, &soc_driver_list, next) {
+		if (drv && drv->scan_fn)
+			drv->scan_fn();
+		drv_count++;
+	}
+
+	/* rte_eal_init() would perform other inits here */
+
+	/* Probe would link the SoC devices<=>drivers */
+	rte_eal_soc_probe();
+
+	/* Unregistering dummy drivers */
+	rte_eal_soc_unregister(&empty_pmd0.soc_drv);
+	rte_eal_soc_unregister(&empty_pmd1.soc_drv);
+
+	/* Verify the Unregistering has removed the driver from list */
+	TAILQ_FOREACH(drv, &soc_driver_list, next) {
+		if (drv)
+			drv_count--;
+	}
+
+	free(empty_pmd0.soc_dev.addr.name);
+
+	/* If drv_count is anything other than 0, Unregistering failed */
+	if (drv_count) {
+		printf("%s has failed\n", __func__);
+		return 1;
+	}
+
+	printf("%s has been successful\n", __func__);
+	return 0;
+}
+
 /* save real devices and drivers until the tests finishes */
 struct soc_driver_list real_soc_driver_list =
 	TAILQ_HEAD_INITIALIZER(real_soc_driver_list);
 
+/* save real devices and drivers until the tests finishes */
+struct soc_device_list real_soc_device_list =
+	TAILQ_HEAD_INITIALIZER(real_soc_device_list);
+
 static int test_soc_setup(void)
 {
 	struct rte_soc_driver *drv;
+	struct rte_soc_device *dev;
 
 	/* no real drivers for the test */
 	while (!TAILQ_EMPTY(&soc_driver_list)) {
@@ -163,12 +347,20 @@ static int test_soc_setup(void)
 		TAILQ_INSERT_TAIL(&real_soc_driver_list, drv, next);
 	}
 
+	/* And, no real devices for the test */
+	while (!TAILQ_EMPTY(&soc_device_list)) {
+		dev = TAILQ_FIRST(&soc_device_list);
+		TAILQ_REMOVE(&soc_device_list, dev, next);
+		TAILQ_INSERT_TAIL(&real_soc_device_list, dev, next);
+	}
+
 	return 0;
 }
 
 static int test_soc_cleanup(void)
 {
 	struct rte_soc_driver *drv;
+	struct rte_soc_device *dev;
 
 	/* bring back real drivers after the test */
 	while (!TAILQ_EMPTY(&real_soc_driver_list)) {
@@ -177,6 +369,13 @@ static int test_soc_cleanup(void)
 		rte_eal_soc_register(drv);
 	}
 
+	/* And, bring back real devices after the test */
+	while (!TAILQ_EMPTY(&real_soc_device_list)) {
+		dev = TAILQ_FIRST(&real_soc_device_list);
+		TAILQ_REMOVE(&real_soc_device_list, dev, next);
+		TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
+	}
+
 	return 0;
 }
 
@@ -192,6 +391,10 @@ test_soc(void)
 	if (test_register_unregister())
 		return -1;
 
+	/* Assuming test_register_unregister has succeeded */
+	if (test_soc_scan_and_match())
+		return -1;
+
 	if (test_soc_cleanup())
 		return -1;
 
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 86e3cfd..dfbb1ac 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -171,7 +171,11 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	rte_eal_map_resource;
+	rte_eal_soc_detach;
 	rte_eal_soc_dump;
+	rte_eal_soc_match;
+	rte_eal_soc_probe;
+	rte_eal_soc_probe_one;
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
 	rte_eal_unmap_resource;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 5dcddc5..256cef8 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -36,6 +36,8 @@
 #include <sys/queue.h>
 
 #include <rte_log.h>
+#include <rte_common.h>
+#include <rte_soc.h>
 
 #include "eal_private.h"
 
@@ -45,6 +47,208 @@ struct soc_driver_list soc_driver_list =
 struct soc_device_list soc_device_list =
 	TAILQ_HEAD_INITIALIZER(soc_device_list);
 
+int
+rte_eal_soc_match_compat(struct rte_soc_driver *drv,
+			 struct rte_soc_device *dev)
+{
+	int i, j;
+
+	RTE_VERIFY(drv != NULL && drv->id_table != NULL);
+	RTE_VERIFY(dev != NULL && dev->id != NULL);
+
+	for (i = 0; drv->id_table[i].compatible; ++i) {
+		const char *drv_compat = drv->id_table[i].compatible;
+
+		for (j = 0; dev->id[j].compatible; ++j) {
+			const char *dev_compat = dev->id[j].compatible;
+
+			if (!strcmp(drv_compat, dev_compat))
+				return 0;
+		}
+	}
+
+	return 1;
+}
+
+static int
+rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
+			     struct rte_soc_device *dev)
+{
+	int ret = 1;
+
+	RTE_VERIFY(drv->match_fn);
+
+	ret = drv->match_fn(drv, dev);
+	if (ret) {
+		RTE_LOG(DEBUG, EAL,
+			" match function failed, skipping\n");
+		return ret;
+	}
+
+	dev->driver = drv;
+	RTE_VERIFY(drv->probe != NULL);
+	return drv->probe(drv, dev);
+}
+
+static int
+soc_probe_all_drivers(struct rte_soc_device *dev)
+{
+	struct rte_soc_driver *drv = NULL;
+	int rc = 0;
+
+	if (dev == NULL)
+		return -1;
+
+	TAILQ_FOREACH(drv, &soc_driver_list, next) {
+		rc = rte_eal_soc_probe_one_driver(drv, dev);
+		if (rc < 0)
+			/* negative value is an error */
+			return -1;
+		if (rc > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+		return 0;
+	}
+	return 1;
+}
+
+/* If the IDs match, call the remove() function of the driver. */
+static int
+rte_eal_soc_detach_dev(struct rte_soc_driver *drv,
+		       struct rte_soc_device *dev)
+{
+	int ret;
+
+	if ((drv == NULL) || (dev == NULL))
+		return -EINVAL;
+
+	ret = drv->match_fn(drv, dev);
+	if (ret) {
+		RTE_LOG(DEBUG, EAL, " driver (%s) didn't match device (%s)\n",
+			drv->driver.name, dev->addr.name);
+		return ret;
+	}
+
+	RTE_LOG(DEBUG, EAL, "SoC device %s\n",
+		dev->addr.name);
+
+	RTE_LOG(DEBUG, EAL, "  remove driver: %s\n", drv->driver.name);
+
+	if (drv->remove && (drv->remove(dev) < 0))
+		return -1;	/* negative value is an error */
+
+	/* clear driver structure */
+	dev->driver = NULL;
+
+	return 0;
+}
+
+/*
+ * Call the remove() function of all registered drivers for the device.
+ *
+ * @param dev
+ *	Device for which detach is to be performed
+ * @return
+ *       0 when successful
+ *      -1 if deinitialization fails
+ *       1 if no driver is found for this device.
+ */
+static int
+soc_detach_all_drivers(struct rte_soc_device *dev)
+{
+	struct rte_soc_driver *dr = NULL;
+	int rc = 0;
+
+	if (dev == NULL)
+		return -1;
+
+	TAILQ_FOREACH(dr, &soc_driver_list, next) {
+		rc = rte_eal_soc_detach_dev(dr, dev);
+		if (rc < 0)
+			/* negative value is an error */
+			return -1;
+		if (rc > 0)
+			/* positive value means driver doesn't support it */
+			continue;
+		return 0;
+	}
+	return 1;
+}
+
+int
+rte_eal_soc_detach(const struct rte_soc_addr *addr)
+{
+	struct rte_soc_device *dev = NULL;
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		if (rte_eal_compare_soc_addr(&dev->addr, addr))
+			continue;
+
+		ret = soc_detach_all_drivers(dev);
+		if (ret < 0)
+			goto err_return;
+
+		TAILQ_REMOVE(&soc_device_list, dev, next);
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL, "Requested device %s cannot be used\n",
+		dev->addr.name);
+	return -1;
+}
+
+int
+rte_eal_soc_probe_one(const struct rte_soc_addr *addr)
+{
+	struct rte_soc_device *dev = NULL;
+	int ret = 0;
+
+	if (addr == NULL)
+		return -1;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		if (rte_eal_compare_soc_addr(&dev->addr, addr))
+			continue;
+
+		ret = soc_probe_all_drivers(dev);
+		if (ret < 0)
+			goto err_return;
+		return 0;
+	}
+	return -1;
+
+err_return:
+	RTE_LOG(WARNING, EAL,
+		"Requested device %s cannot be used\n", addr->name);
+	return -1;
+}
+
+int
+rte_eal_soc_probe(void)
+{
+	struct rte_soc_device *dev = NULL;
+	int ret = 0;
+
+	TAILQ_FOREACH(dev, &soc_device_list, next) {
+		ret = soc_probe_all_drivers(dev);
+		if (ret < 0) {
+			RTE_LOG(DEBUG, EAL, "Requested device %s"
+				 " cannot be used\n", dev->addr.name);
+			/* Failure for a particular device is logged and
+			 * ignored
+			 */
+		}
+	}
+
+	return ret;
+}
+
 /* dump one device */
 static int
 soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
@@ -61,7 +265,6 @@ soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
 	return 0;
 }
 
-/* dump devices on the bus to an output stream */
 void
 rte_eal_soc_dump(FILE *f)
 {
@@ -75,14 +278,18 @@ rte_eal_soc_dump(FILE *f)
 	}
 }
 
-/* register a driver */
 void
 rte_eal_soc_register(struct rte_soc_driver *driver)
 {
+	/* For a valid soc driver, match and scan function
+	 * should be provided.
+	 */
+	RTE_VERIFY(driver != NULL);
+	RTE_VERIFY(driver->match_fn != NULL);
+	RTE_VERIFY(driver->scan_fn != NULL);
 	TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
 }
 
-/* unregister a driver */
 void
 rte_eal_soc_unregister(struct rte_soc_driver *driver)
 {
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 347e611..53a321b 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -62,7 +62,6 @@ extern struct soc_device_list soc_device_list;
 TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
 TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
 
-
 struct rte_soc_id {
 	const char *compatible; /**< OF compatible specification */
 	uint64_t priv_data;     /**< SoC Driver specific data */
@@ -97,6 +96,23 @@ typedef int (soc_probe_t)(struct rte_soc_driver *, struct rte_soc_device *);
 typedef int (soc_remove_t)(struct rte_soc_device *);
 
 /**
+ * SoC device scan callback, called from rte_eal_soc_init.
+ * For various SoC, the bus on which devices are attached maynot be compliant
+ * to a standard platform (or platform bus itself). In which case, extra
+ * steps are implemented by PMD to scan over the bus and add devices to SoC
+ * device list.
+ */
+typedef void (soc_scan_t)(void);
+
+/**
+ * Custom device<=>driver match callback for SoC
+ * Unlike PCI, SoC devices don't have a fixed definition of device
+ * identification. PMDs can implement a specific matching function in which
+ * driver and device objects are provided to perform custom match.
+ */
+typedef int (soc_match_t)(struct rte_soc_driver *, struct rte_soc_device *);
+
+/**
  * A structure describing a SoC driver.
  */
 struct rte_soc_driver {
@@ -104,6 +120,8 @@ struct rte_soc_driver {
 	struct rte_driver driver;          /**< Inherit core driver. */
 	soc_probe_t *probe;                /**< Device probe */
 	soc_remove_t *remove;              /**< Device remove */
+	soc_scan_t *scan_fn;               /**< Callback for scanning SoC bus*/
+	soc_match_t *match_fn;             /**< Callback to match dev<->drv */
 	const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
 };
 
@@ -146,12 +164,63 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
 }
 
 /**
+ * Default function for matching the Soc driver with device. Each driver can
+ * either use this function or define their own soc matching function.
+ * This function relies on the compatible string extracted from sysfs. But,
+ * a SoC might have different way of identifying its devices. Such SoC can
+ * override match_fn.
+ *
+ * @return
+ *	 0 on success
+ *	-1 when no match found
+  */
+int
+rte_eal_soc_match_compat(struct rte_soc_driver *drv,
+			 struct rte_soc_device *dev);
+
+/**
+ * Probe SoC devices for registered drivers.
+ *
+ * @return
+ *	0 on success
+ *	!0 in case of any failure in probe
+ */
+int rte_eal_soc_probe(void);
+
+/**
+ * Probe the single SoC device.
+ */
+int rte_eal_soc_probe_one(const struct rte_soc_addr *addr);
+
+/**
+ * Close the single SoC device.
+ *
+ * Scan the SoC devices and find the SoC device specified by the SoC
+ * address, then call the remove() function for registered driver
+ * that has a matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ *	The SoC address to close.
+ * @return
+ *   - 0 on success.
+ *   - Negative on error.
+ */
+int rte_eal_soc_detach(const struct rte_soc_addr *addr);
+
+/**
  * Dump discovered SoC devices.
+ *
+ * @param f
+ *	File to dump device info in.
  */
 void rte_eal_soc_dump(FILE *f);
 
 /**
  * Register a SoC driver.
+ *
+ * @param driver
+ *	Object for SoC driver to register
+ * @return void
  */
 void rte_eal_soc_register(struct rte_soc_driver *driver);
 
@@ -167,6 +236,10 @@ RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
 
 /**
  * Unregister a SoC driver.
+ *
+ * @param driver
+ *	Object for SoC driver to unregister
+ * @return void
  */
 void rte_eal_soc_unregister(struct rte_soc_driver *driver);
 
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 098ba02..bd775f3 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -70,6 +70,7 @@
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
 #include <rte_pci.h>
+#include <rte_soc.h>
 #include <rte_dev.h>
 #include <rte_devargs.h>
 #include <rte_common.h>
@@ -890,6 +891,10 @@ rte_eal_init(int argc, char **argv)
 	if (rte_eal_pci_probe())
 		rte_panic("Cannot probe PCI\n");
 
+	/* Probe & Initialize SoC devices */
+	if (rte_eal_soc_probe())
+		rte_panic("Cannot probe SoC\n");
+
 	rte_eal_mcfg_complete();
 
 	return fctret;
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index 04848b9..3929a76 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -44,13 +44,28 @@
 #include <rte_log.h>
 #include <rte_soc.h>
 
-#include "eal_internal_cfg.h"
-#include "eal_filesystem.h"
-#include "eal_private.h"
+#include <eal_internal_cfg.h>
+#include <eal_filesystem.h>
+#include <eal_private.h>
 
 /* Init the SoC EAL subsystem */
 int
 rte_eal_soc_init(void)
 {
+	struct rte_soc_driver *drv;
+
+	/* SoC is disabled by default */
+	if (!internal_config.enable_soc)
+		return 0;
+
+	/* For each registered driver, call their scan routine to perform any
+	 * custom scan for devices (for example, custom buses)
+	 */
+	TAILQ_FOREACH(drv, &soc_driver_list, next) {
+		RTE_VERIFY(drv->scan_fn);
+		drv->scan_fn();
+		/* Ignore all errors from this */
+	}
+
 	return 0;
 }
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 0155025..c28e093 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -175,7 +175,11 @@ DPDK_16.11 {
 	rte_eal_dev_attach;
 	rte_eal_dev_detach;
 	rte_eal_map_resource;
+	rte_eal_soc_detach;
 	rte_eal_soc_dump;
+	rte_eal_soc_match;
+	rte_eal_soc_probe;
+	rte_eal_soc_probe_one;
 	rte_eal_soc_register;
 	rte_eal_soc_unregister;
 	rte_eal_unmap_resource;
-- 
2.7.4

  parent reply	other threads:[~2016-10-28 12:30 UTC|newest]

Thread overview: 231+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-01 21:05 [RFC 0/7] Support non-PCI devices Jan Viktorin
2016-01-01 21:05 ` [RFC 1/7] eal/common: define rte_soc_* related common interface Jan Viktorin
2016-01-02 18:01   ` Stephen Hemminger
2016-01-02 18:35     ` Wiles, Keith
2016-01-02 18:52       ` Jan Viktorin
2016-01-02 19:13         ` Wiles, Keith
2016-01-02 19:14         ` Stephen Hemminger
2016-01-02 19:22           ` Wiles, Keith
2016-01-02 18:45     ` Jan Viktorin
2016-01-03 17:12       ` Jan Viktorin
2016-01-04 15:21         ` Wiles, Keith
2016-01-01 21:05 ` [RFC 2/7] eal: introduce --no-soc option Jan Viktorin
2016-01-01 21:05 ` [RFC 3/7] eal: add common part of the SoC infra Jan Viktorin
2016-01-01 21:05 ` [RFC 4/7] eal/linuxapp: support SoC infra in linuxapp Jan Viktorin
2016-01-01 21:05 ` [RFC 5/7] eal: init SoC infra on rte_eal_init Jan Viktorin
2016-01-01 21:05 ` [RFC 6/7] eal/soc: make SoC infra testable on any platform Jan Viktorin
2016-01-01 21:05 ` [RFC 7/7] app/test: add SoC infra probe/detach test Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 00/28] Support non-PCI devices Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 01/28] eal: make enum rte_kernel_driver non-PCI specific Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 02/28] eal: extract function eal_parse_sysfs_valuef Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 03/28] eal/linux: extract function rte_eal_unbind_kernel_driver Jan Viktorin
2016-05-13  1:22   ` Jianbo Liu
2016-05-17 18:14     ` Jan Viktorin
2016-05-18 13:45       ` Jianbo Liu
2016-05-06 13:47 ` [PATCH v1 04/28] eal/linux: extract function rte_eal_get_kernel_driver_by_path Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 05/28] eal: remove pci_ prefix from pci_(un)map_resource Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 06/28] eal/soc: introduce very essential SoC infra definitions Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 07/28] eal/soc: add rte_eal_soc_register/unregister logic Jan Viktorin
2016-06-13 14:19   ` Shreyansh Jain
2016-06-13 14:25     ` Jan Viktorin
2016-06-15  5:57     ` Shreyansh Jain
2016-06-15  9:50       ` Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 08/28] eal/soc: implement SoC device discovery Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 09/28] eal: introduce --no-soc option Jan Viktorin
2016-05-13  3:28   ` Jianbo Liu
2016-05-17 18:10     ` Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 10/28] eal/soc: init SoC infra from EAL Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 11/28] eal/soc: implement probing of drivers Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 12/28] eal/soc: extend and utilize devargs Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 13/28] eal/soc: update device on probe when already exists Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 14/28] eal/soc: detect assigned kernel driver Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 15/28] eal/soc: map/unmap resources Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 16/28] eal/soc: add intr_handle Jan Viktorin
2016-05-06 13:47 ` [PATCH v1 17/28] eal/soc: hack (const char *) compatible setting Jan Viktorin
2016-05-06 13:48 ` [PATCH v1 18/28] eal/soc: detect numa_node of the rte_soc_device Jan Viktorin
2016-05-06 13:48 ` [PATCH v1 19/28] eal/soc: add drv_flags Jan Viktorin
2016-06-13 14:21   ` Shreyansh Jain
2016-06-13 14:26     ` Jan Viktorin
2016-05-06 13:48 ` [PATCH v1 20/28] eal/soc: map resources conditionally Jan Viktorin
2016-05-06 13:48 ` [PATCH v1 21/28] eal/soc: unbind kernel driver on probe Jan Viktorin
2016-05-06 13:48 ` [PATCH v1 22/28] eal/soc: detect DMA non-coherent devices Jan Viktorin
2016-05-06 13:48 ` [PATCH v1 23/28] eal: define macro container_of Jan Viktorin
2016-05-06 13:48 ` [PATCH v1 24/28] ether: utilize container_of for pci_drv Jan Viktorin
2016-05-06 13:48 ` [PATCH v1 25/28] ether: verify we copy info from a PCI device Jan Viktorin
2016-05-06 13:48 ` [PATCH v1 26/28] ether: extract function eth_dev_get_intr_handle Jan Viktorin
2016-05-06 13:48 ` [PATCH v1 27/28] ether: extract function eth_dev_get_driver_name Jan Viktorin
2016-05-06 13:48 ` [PATCH v1 28/28] ether: support SoC device/driver Jan Viktorin
2016-06-29  9:42   ` Shreyansh jain
2016-07-04 13:04     ` Jan Viktorin
2016-07-04 14:27       ` Shreyansh jain
2016-07-04 14:36         ` Jan Viktorin
2016-07-05  4:42           ` Shreyansh jain
2016-07-05  5:16             ` Jan Viktorin
2016-07-07 10:29               ` Shreyansh jain
2016-07-12  8:45           ` Shreyansh jain
2016-07-12 10:41             ` Jan Viktorin
2016-08-31 11:00 ` [PATCH v2 00/14] Introduce SoC device/driver framework for EAL Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 01/14] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 02/14] eal/soc: add rte_eal_soc_register/unregister logic Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 03/14] eal/soc: Implement SoC device list and dump Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 04/14] eal: introduce --no-soc option Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 05/14] eal/soc: init SoC infra from EAL Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 06/14] eal/soc: implement probing of drivers Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 07/14] eal/soc: extend and utilize devargs Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 08/14] eal/soc: add drv_flags Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 09/14] eal/soc: add intr_handle Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 10/14] ether: utilize container_of for pci_drv Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 11/14] ether: verify we copy info from a PCI device Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 12/14] ether: extract function eth_dev_get_intr_handle Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 13/14] ether: extract function eth_dev_get_driver_name Shreyansh Jain
2016-08-31 11:00   ` [PATCH v2 14/14] ether: Support rte_soc_driver/device for etherdev Shreyansh Jain
2016-09-09  8:43 ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Shreyansh Jain
2016-09-09  8:43   ` [PATCH v3 01/15] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
2016-09-15 12:58     ` Hunt, David
2016-09-16  6:17       ` Shreyansh Jain
2016-09-09  8:43   ` [PATCH v3 02/15] eal/soc: add rte_eal_soc_register/unregister logic Shreyansh Jain
2016-09-15 13:00     ` Hunt, David
2016-09-15 13:09       ` Jan Viktorin
2016-09-15 14:09         ` Thomas Monjalon
2016-09-16  7:32           ` Panu Matilainen
2016-09-09  8:43   ` [PATCH v3 03/15] eal/soc: Implement SoC device list and dump Shreyansh Jain
2016-09-09  8:43   ` [PATCH v3 04/15] eal: introduce --no-soc option Shreyansh Jain
2016-09-16 11:36     ` Jan Viktorin
2016-09-16 11:55       ` Shreyansh Jain
2016-09-09  8:43   ` [PATCH v3 05/15] eal/soc: init SoC infra from EAL Shreyansh Jain
2016-09-09  8:43   ` [PATCH v3 06/15] eal/soc: implement probing of drivers Shreyansh Jain
2016-09-16 12:27     ` Jan Viktorin
2016-09-19  6:47       ` Shreyansh Jain
2016-09-19 11:34         ` Jan Viktorin
2016-09-20  6:46           ` Shreyansh Jain
2016-09-20 10:49             ` Jan Viktorin
2016-09-09  8:43   ` [PATCH v3 07/15] eal/soc: extend and utilize devargs Shreyansh Jain
2016-09-09  8:43   ` [PATCH v3 08/15] eal/soc: add drv_flags Shreyansh Jain
2016-09-09  8:43   ` [PATCH v3 09/15] eal/soc: add intr_handle Shreyansh Jain
2016-09-09  8:43   ` [PATCH v3 10/15] ether: utilize container_of for pci_drv Shreyansh Jain
2016-09-09  8:43   ` [PATCH v3 11/15] ether: verify we copy info from a PCI device Shreyansh Jain
2016-09-09  8:43   ` [PATCH v3 12/15] ether: extract function eth_dev_get_intr_handle Shreyansh Jain
2016-09-15 13:02     ` Hunt, David
2016-09-15 14:05       ` Thomas Monjalon
2016-09-16  7:17         ` Panu Matilainen
2016-09-09  8:43   ` [PATCH v3 13/15] ether: extract function eth_dev_get_driver_name Shreyansh Jain
2016-09-15 13:03     ` Hunt, David
2016-09-09  8:43   ` [PATCH v3 14/15] ether: Support rte_soc_driver/device for etherdev Shreyansh Jain
2016-09-09  8:43   ` [PATCH v3 15/15] eal/crypto: Support rte_soc_driver/device for cryptodev Shreyansh Jain
2016-09-15 12:56   ` [PATCH v3 00/15] Introduce SoC device/driver framework for EAL Hunt, David
2016-09-16  6:14     ` Shreyansh Jain
2016-09-18  5:58   ` Jianbo Liu
2016-09-18  7:22     ` Jan Viktorin
2016-09-18  8:56       ` Jianbo Liu
2016-09-18  9:17         ` Jan Viktorin
2016-09-18  9:41           ` Hemant Agrawal
2016-09-18 10:04             ` Jan Viktorin
2016-09-19 12:33               ` Hemant Agrawal
2016-10-15 13:44   ` [PATCH v4 00/17] " Shreyansh Jain
2016-10-15 13:44     ` [PATCH v4 01/17] eal: define container macro Shreyansh Jain
2016-10-15 13:44     ` [PATCH v4 02/17] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
2016-10-15 13:44     ` [PATCH v4 03/17] eal/soc: add SoC PMD register/unregister logic Shreyansh Jain
2016-10-15 13:44     ` [PATCH v4 04/17] eal/soc: implement SoC device list and dump Shreyansh Jain
2016-10-15 13:44     ` [PATCH v4 05/17] eal: introduce command line enable SoC option Shreyansh Jain
2016-10-15 13:44     ` [PATCH v4 06/17] eal/soc: init SoC infra from EAL Shreyansh Jain
2016-10-15 13:44     ` [PATCH v4 07/17] eal/soc: implement probing of drivers Shreyansh Jain
2016-10-15 13:44     ` [PATCH v4 08/17] eal/soc: extend and utilize devargs Shreyansh Jain
2016-10-15 13:45     ` [PATCH v4 09/17] eal/soc: add drv_flags Shreyansh Jain
2016-10-15 13:45     ` [PATCH v4 10/17] eal/soc: add intr_handle Shreyansh Jain
2016-10-15 13:45     ` [PATCH v4 11/17] eal/soc: add default scan for Soc devices Shreyansh Jain
2016-10-16  0:56       ` Jan Viktorin
2016-10-16  7:12         ` Shreyansh Jain
2016-10-24 12:08           ` Shreyansh Jain
2016-10-24 16:11             ` Jan Viktorin
2016-10-15 13:45     ` [PATCH v4 12/17] eal/soc: additional features for SoC Shreyansh Jain
2016-10-15 13:45     ` [PATCH v4 13/17] ether: utilize container_of for pci_drv Shreyansh Jain
2016-10-15 13:45     ` [PATCH v4 14/17] ether: verify we copy info from a PCI device Shreyansh Jain
2016-10-15 13:45     ` [PATCH v4 15/17] ether: extract function eth_dev_get_intr_handle Shreyansh Jain
2016-10-15 13:45     ` [PATCH v4 16/17] ether: introduce ethernet dev probe remove Shreyansh Jain
2016-10-15 13:45     ` [PATCH v4 17/17] eal/crypto: Support rte_soc_driver/device for cryptodev Shreyansh Jain
2016-10-15 13:53     ` [PATCH v4 00/17] Introduce SoC device/driver framework for EAL Shreyansh Jain
2016-10-24 11:59     ` [PATCH v5 00/21] " Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 01/21] eal: generalize PCI kernel driver enum to EAL Shreyansh Jain
2016-10-24 16:13         ` Jan Viktorin
2016-10-24 11:59       ` [PATCH v5 02/21] eal: generalize PCI map/unmap resource " Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 03/21] eal/linux: generalize PCI kernel unbinding driver " Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 04/21] eal/linux: generalize PCI kernel driver extraction " Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 05/21] eal: define container macro Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 06/21] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
2016-10-24 16:21         ` Jan Viktorin
2016-10-25  5:36           ` Shreyansh Jain
2016-10-25 12:38             ` Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 07/21] eal/soc: add SoC PMD register/unregister logic Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 08/21] eal/soc: implement SoC device list and dump Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 09/21] eal: introduce command line enable SoC option Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 10/21] eal/soc: init SoC infra from EAL Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 11/21] eal/soc: implement probing of drivers Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 12/21] eal/soc: extend and utilize devargs Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 13/21] eal/soc: add drv_flags Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 14/21] eal/soc: add intr_handle Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 15/21] eal/soc: add default scan for Soc devices Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 16/21] eal/soc: additional features for SoC Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 17/21] ether: utilize container_of for pci_drv Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 18/21] ether: verify we copy info from a PCI device Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 19/21] ether: extract function eth_dev_get_intr_handle Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 20/21] ether: introduce ethernet dev probe remove Shreyansh Jain
2016-10-24 11:59       ` [PATCH v5 21/21] eal/crypto: Support rte_soc_driver/device for cryptodev Shreyansh Jain
2016-10-27 15:17       ` [PATCH v6 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 01/21] eal: generalize PCI kernel driver enum to EAL Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 02/21] eal: generalize PCI map/unmap resource " Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 03/21] eal/linux: generalize PCI kernel unbinding driver " Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 04/21] eal/linux: generalize PCI kernel driver extraction " Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 05/21] eal: define container macro Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 06/21] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 07/21] eal/soc: add SoC PMD register/unregister logic Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 08/21] eal/soc: implement SoC device list and dump Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 09/21] eal: introduce command line enable SoC option Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 10/21] eal/soc: init SoC infra from EAL Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 12/21] eal/soc: extend and utilize devargs Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 13/21] eal/soc: add drv_flags Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 14/21] eal/soc: add intr_handle Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 15/21] eal/soc: add default scan for Soc devices Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 16/21] eal/soc: additional features for SoC Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 17/21] ether: utilize container_of for pci_drv Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 18/21] ether: verify we copy info from a PCI device Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 19/21] ether: extract function eth_dev_get_intr_handle Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 20/21] ether: introduce ethernet dev probe remove Shreyansh Jain
2016-10-27 15:17         ` [PATCH v6 21/21] eal/crypto: Support rte_soc_driver/device for cryptodev Shreyansh Jain
2016-10-28 12:26         ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 01/21] eal: generalize PCI kernel driver enum to EAL Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 02/21] eal: generalize PCI map/unmap resource " Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 03/21] eal/linux: generalize PCI kernel unbinding driver " Shreyansh Jain
2016-11-10  2:24             ` Jianbo Liu
2016-11-10  5:46               ` Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 04/21] eal/linux: generalize PCI kernel driver extraction " Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 05/21] eal: define container macro Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 06/21] eal/soc: introduce very essential SoC infra definitions Shreyansh Jain
2016-11-10  4:09             ` Jianbo Liu
2016-11-10  5:51               ` Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 07/21] eal/soc: add SoC PMD register/unregister logic Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 08/21] eal/soc: implement SoC device list and dump Shreyansh Jain
2016-11-10  3:06             ` Jianbo Liu
2016-11-10  5:56               ` Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 09/21] eal: introduce command line enable SoC option Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 10/21] eal/soc: init SoC infra from EAL Shreyansh Jain
2016-10-28 12:26           ` Shreyansh Jain [this message]
2016-11-10  3:30             ` [PATCH v7 11/21] eal/soc: implement probing of drivers Jianbo Liu
2016-11-10  6:10               ` Shreyansh Jain
2016-11-10  7:41                 ` Jianbo Liu
2016-11-10  9:10                   ` Shreyansh Jain
2016-11-10  9:26                     ` Thomas Monjalon
2016-11-11  1:58                       ` Jianbo Liu
2016-11-11  6:04                       ` Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 12/21] eal/soc: extend and utilize devargs Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 13/21] eal/soc: add drv_flags Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 14/21] eal/soc: add intr_handle Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 15/21] eal/soc: add default scan for Soc devices Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 16/21] eal/soc: additional features for SoC Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 17/21] ether: utilize container_of for pci_drv Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 18/21] ether: verify we copy info from a PCI device Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 19/21] ether: extract function eth_dev_get_intr_handle Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 20/21] ether: introduce ethernet dev probe remove Shreyansh Jain
2016-10-28 12:26           ` [PATCH v7 21/21] eal/crypto: Support rte_soc_driver/device for cryptodev Shreyansh Jain
2016-10-28 12:35           ` [PATCH v7 00/21] Introduce SoC device/driver framework for EAL Shreyansh Jain
2016-11-09 10:17           ` Thomas Monjalon
2016-11-09 13:36             ` Shreyansh Jain

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1477657598-826-12-git-send-email-shreyansh.jain@nxp.com \
    --to=shreyansh.jain@nxp.com \
    --cc=dev@dpdk.org \
    --cc=thomas.monjalon@6wind.com \
    --cc=viktorin@rehivetech.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.