Signed-off-by: Shreyansh Jain <shreyansh.j...@nxp.com> Reviewed-by: Ferruh Yigit <ferruh.yi...@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