[dpdk-dev] [PATCH v11 05/13] app/test: check bus scan

Thomas Monjalon thomas.monjalon at 6wind.com
Thu Jan 19 05:45:09 CET 2017


From: Shreyansh Jain <shreyansh.jain at nxp.com>

Signed-off-by: Shreyansh Jain <shreyansh.jain at nxp.com>
---
 app/test/test_bus.c | 174 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 174 insertions(+)

diff --git a/app/test/test_bus.c b/app/test/test_bus.c
index e2a58fa..de4f1ab 100644
--- a/app/test/test_bus.c
+++ b/app/test/test_bus.c
@@ -106,10 +106,26 @@ struct dummy_bus_map {
 struct rte_bus_list orig_bus_list =
 	TAILQ_HEAD_INITIALIZER(orig_bus_list);
 
+/* Forward declarations for callbacks from bus */
+
+/* Bus A
+ * Scan would register devA1 and devA2 to bus
+ */
+static int scan_fn_for_busA(void);
+
+/* Bus B
+ * Scan would register devB1 and devB2 to bus
+ */
+static int scan_fn_for_busB(void);
+
+/* generic implementations wrapped around by above declarations */
+static int generic_scan_fn(struct rte_bus *bus);
+
 struct dummy_bus busA = {
 	.name = "busA_impl", /* busA */
 	.bus = {
 		.name = "busA",
+		.scan = scan_fn_for_busA,
 	},
 };
 
@@ -117,6 +133,7 @@ struct dummy_bus busB = {
 	.name = "busB_impl", /* busB */
 	.bus = {
 		.name = "busB",
+		.scan = scan_fn_for_busB,
 	},
 };
 
@@ -222,9 +239,80 @@ dump_device_tree(void)
 	printf("------>8-------\n");
 }
 
+/* @internal
+ * Move over the bus_map and find the entry matching the bus object
+ * passed as argument.
+ * For each device in that bus_map list, register.
+ *
+ * @param bus
+ *	bus to scan againt test entry
+ * @return
+ *	0 for successful scan, even if no devices are found
+ *	!0 for any error in scanning (like, invalid bus)
+ */
+static int
+generic_scan_fn(struct rte_bus *bus)
+{
+	int i = 0;
+	struct dummy_device *ddev = NULL;
+	struct dummy_bus_map *dbmap = NULL;
+	struct dummy_bus *db = NULL;
+
+	if (!bus)
+		return -1;
+
+	/* Extract the device tree node using the bus passed */
+	for (i = 0; bus_map[i].name; i++) {
+		if (!strcmp(bus_map[i].name, bus->name)) {
+			dbmap = &bus_map[i];
+			break;
+		}
+	}
+
+	if (!dbmap)
+		return -1;
+
+	db = dbmap->dbus;
+
+	/* For all the devices in the device tree (bus_map), add device */
+	for (i = 0; dbmap->ddevices[i]; i++) {
+		ddev = dbmap->ddevices[i];
+		TAILQ_INSERT_TAIL(&db->device_list, ddev, next);
+	}
+
+	return 0;
+}
+
+int
+scan_fn_for_busA(void) {
+	struct dummy_bus_map *dbm;
+
+	dbm = &bus_map[0];
+	while (dbm) {
+		if (strcmp(dbm->name, "busA") == 0)
+			return generic_scan_fn(&dbm->dbus->bus);
+		dbm++;
+	}
+	return 1;
+}
+
+int
+scan_fn_for_busB(void) {
+	struct dummy_bus_map *dbm;
+
+	dbm = &bus_map[0];
+	while (dbm) {
+		if (strcmp(dbm->name, "busB") == 0)
+			return generic_scan_fn(&dbm->dbus->bus);
+		dbm++;
+	}
+	return 1;
+}
+
 static int
 test_bus_setup(void)
 {
+	int i = 0;
 	struct rte_bus *bus_p = NULL;
 
 	/* Preserve the original bus list before executing test */
@@ -234,6 +322,13 @@ test_bus_setup(void)
 		TAILQ_INSERT_TAIL(&orig_bus_list, bus_p, next);
 	}
 
+	/* Initialize the bus lists */
+	for (i = 0; bus_map[i].name; i++) {
+		TAILQ_INIT(&bus_map[i].dbus->device_list);
+		TAILQ_INIT(&bus_map[i].dbus->driver_list);
+	}
+
+	dump_device_tree();
 	return 0;
 }
 
@@ -332,6 +427,79 @@ test_bus_unregistration(void)
 	return 0;
 }
 
+static int
+test_device_unregistration_on_bus(void)
+{
+	int i;
+	struct rte_bus *bus = NULL;
+	struct dummy_device *ddev;
+	struct dummy_bus *dbus;
+
+	for (i = 0; bus_map[i].name; i++) {
+		bus = &(bus_map[i].dbus->bus);
+		if (!bus) {
+			printf("Unable to find bus (%s)\n",
+			       bus_map[i].name);
+			return -1;
+		}
+
+		dbus = container_of(bus, struct dummy_bus, bus);
+		/* For bus 'bus', unregister all devices */
+		TAILQ_FOREACH(ddev, &dbus->device_list, next) {
+			TAILQ_REMOVE(&dbus->device_list, ddev, next);
+		}
+	}
+
+	for (i = 0; bus_map[i].name; i++) {
+		bus = &(bus_map[i].dbus->bus);
+		dbus = container_of(bus, struct dummy_bus, bus);
+
+		if (!TAILQ_EMPTY(&dbus->device_list)) {
+			printf("Unable to remove all devices on bus (%s)\n",
+			       bus->name);
+			return -1;
+		}
+	}
+
+	/* All devices from all buses have been removed */
+	printf("All devices on all buses unregistered.\n");
+	dump_device_tree();
+
+	return 0;
+}
+
+/* @internal
+ * For each bus registered, call the scan function to identify devices
+ * on the bus.
+ *
+ * @param void
+ * @return
+ *	0 for successful scan
+ *	!0 for unsuccessful scan
+ *
+ */
+static int
+test_bus_scan(void)
+{
+	int ret;
+	struct rte_bus *bus;
+
+	TAILQ_FOREACH(bus, &rte_bus_list, next) {
+		/* Call the scan function for each bus */
+		ret = bus->scan();
+		if (ret) {
+			printf("Scan of buses failed.\n");
+			return -1;
+		}
+	}
+
+	printf("Scan of all buses completed.\n");
+	dump_device_tree();
+
+	return 0;
+}
+
+
 int
 test_bus(void)
 {
@@ -342,6 +510,12 @@ test_bus(void)
 	if (test_bus_registration())
 		return -1;
 
+	if (test_bus_scan())
+		return -1;
+
+	if (test_device_unregistration_on_bus())
+		return -1;
+
 	if (test_bus_unregistration())
 		return -1;
 
-- 
2.7.0



More information about the dev mailing list