[dpdk-dev] [PATCH v10 09/13] test: add test cases for scan and probe on BUS

Shreyansh Jain shreyansh.jain at nxp.com
Wed Jan 18 15:05:25 CET 2017


Signed-off-by: Shreyansh Jain <shreyansh.jain at nxp.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit at intel.com>
---
 app/test/test_bus.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 152 insertions(+)

diff --git a/app/test/test_bus.c b/app/test/test_bus.c
index 0b6d011..ef7fa89 100644
--- a/app/test/test_bus.c
+++ b/app/test/test_bus.c
@@ -120,12 +120,15 @@ static int scan_fn_for_busB(void);
 
 /* generic implementations wrapped around by above declarations */
 static int generic_scan_fn(struct rte_bus *bus);
+static int generic_probe_fn(void);
+static int dummy_match_fn(struct rte_driver *drv, struct rte_device *dev);
 
 struct dummy_bus busA = {
 	.name = "busA_impl", /* busA */
 	.bus = {
 		.name = "busA",
 		.scan = scan_fn_for_busA,
+		.probe = generic_probe_fn,
 	},
 };
 
@@ -134,6 +137,7 @@ struct dummy_bus busB = {
 	.bus = {
 		.name = "busB",
 		.scan = scan_fn_for_busB,
+		.probe = generic_probe_fn,
 	},
 };
 
@@ -288,6 +292,46 @@ generic_scan_fn(struct rte_bus *bus)
 	return 0;
 }
 
+/* @internal
+ * Obtain bus from driver object. Match the address of rte_device object
+ * with all the devices associated with that bus.
+ *
+ * Being a test function, all this does is validate that device object
+ * provided is available on the same bus to which driver is registered.
+ *
+ * @param drv
+ *	driver to match with
+ * @param dev
+ *	device object
+ * @return
+ *	0 for successful match
+ *	!0 for failed match
+ */
+static int
+dummy_match_fn(struct rte_driver *drv __rte_unused, struct rte_device *dev)
+{
+	struct rte_bus *bus;
+	struct dummy_device *ddev = NULL;
+	struct dummy_device *ddev_as_arg;
+	struct dummy_bus *dbus = NULL;
+
+	/* Match is based entirely on address of 'dev' and 'dev_p' extracted
+	 * from bus->device_list.
+	 */
+
+	/* a driver is registered with the bus *before* the scan. */
+	bus = dev->bus;
+	dbus = container_of(bus, struct dummy_bus, bus);
+	ddev_as_arg = container_of(dev, struct dummy_device, dev);
+
+	TAILQ_FOREACH(ddev, &dbus->device_list, next) {
+		if (ddev == ddev_as_arg)
+			return 0;
+	}
+
+	return 1;
+}
+
 int
 scan_fn_for_busA(void) {
 	struct dummy_bus_map *dbm;
@@ -504,6 +548,110 @@ test_bus_scan(void)
 	return 0;
 }
 
+/*
+ *
+ */
+static int
+generic_probe_fn(void)
+{
+	int ret = 0;
+	int i, j;
+	struct rte_driver *drv;
+	struct rte_device *dev;
+	struct dummy_bus *dbus = NULL;
+	struct dummy_device *ddev = NULL;
+	struct dummy_driver *ddrv = NULL;
+
+	/* In case of this test:
+	 * 1. for each bus in rte_bus_list
+	 * 2.  for each device on that bus (bus specific->device_list)
+	 * 3.   for each driver on that bus (bus specific->driver_list)
+	 * 4.    call match
+	 * 5.    link driver and device
+	 * 6. Verify the linkage.
+	 */
+	for (i = 0; bus_map[i].name; i++) {
+		/* get bus pointer from bus_map itself */
+		dbus = bus_map[i].dbus;
+
+		/* Looping over all scanned devices */
+		TAILQ_FOREACH(ddev, &dbus->device_list, next) {
+			/* There is a list of drivers within dummy_bus_map.
+			 * In case of PMDs, this would be driver registration
+			 * APIs/list
+			 */
+			for (j = 0; bus_map[i].ddrivers[j]; j++) {
+				ddrv = bus_map[i].ddrivers[j];
+
+				drv = &ddrv->drv;
+				dev = &ddev->dev;
+				ret = dummy_match_fn(drv, dev);
+				if (!ret) {
+					/* As match is generic, it always
+					 * results in dev->drv pointing to
+					 * first driver entry in bus_map[i]
+					 */
+					dev->driver = drv;
+					dev->bus = &dbus->bus;
+				}
+				/* Else, continue */
+			}
+		}
+	}
+
+	/* Verify the linkage. All devices belonging to a bus_map[i]
+	 * should have same driver (first driver entry of bus_map[i])
+	 */
+	for (i = 0; bus_map[i].name; i++) {
+		ddrv = bus_map[i].ddrivers[0];
+		drv = &ddrv->drv;
+
+		for (j = 0; bus_map[i].ddevices[j]; j++) {
+			ddev = bus_map[i].ddevices[j];
+			dev = &ddev->dev;
+			if (dev->driver != drv) {
+				printf("Incorrect driver<->device linkage.\n");
+				return -1;
+			}
+		}
+	}
+
+	return 0;
+}
+
+/* @internal
+ * Function to perform 'probe' and link devices and drivers on a bus.
+ * This would work over all the buses registered, and all devices and drivers
+ * registered with it - call match on each pair.
+ *
+ * @param void
+ * @return
+ *	0 for successful probe
+ *	!0 for failure in probe
+ *
+ */
+static int
+test_probe_on_bus(void)
+{
+	int ret = 0;
+	int i;
+	struct dummy_bus *dbus;
+	struct rte_bus *bus;
+
+	for (i = 0; bus_map[i].name; i++) {
+		/* get bus pointer from bus_map itself */
+		dbus = bus_map[i].dbus;
+		bus = &dbus->bus;
+		ret = bus->probe();
+		if (ret)
+			printf("Probe for %s failed.\n", bus_map[i].name);
+	}
+
+	printf("Probe on all buses successful.\n");
+	dump_device_tree();
+
+	return 0;
+}
 
 int
 test_bus(void)
@@ -518,6 +666,10 @@ test_bus(void)
 	if (test_bus_scan())
 		return -1;
 
+	/* Now that the devices and drivers are registered, perform probe */
+	if (test_probe_on_bus())
+		return -1;
+
 	if (test_device_unregistration_on_bus())
 		return -1;
 
-- 
2.7.4



More information about the dev mailing list