From: Shreyansh Jain <shreyansh.j...@nxp.com>

Signed-off-by: Shreyansh Jain <shreyansh.j...@nxp.com>
Reviewed-by: Ferruh Yigit <ferruh.yi...@intel.com>
---
 app/test/test_pci.c | 164 ++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 114 insertions(+), 50 deletions(-)

diff --git a/app/test/test_pci.c b/app/test/test_pci.c
index cda186d..09261cc 100644
--- a/app/test/test_pci.c
+++ b/app/test/test_pci.c
@@ -38,9 +38,11 @@
 #include <sys/queue.h>
 
 #include <rte_interrupts.h>
+#include <rte_bus.h>
 #include <rte_pci.h>
 #include <rte_ethdev.h>
 #include <rte_devargs.h>
+#include <rte_tailq.h>
 
 #include "test.h"
 #include "resource.h"
@@ -61,10 +63,31 @@
 
 int test_pci_run = 0; /* value checked by the multiprocess test */
 static unsigned pci_dev_count;
+struct test_pci_bus;
+static struct test_pci_bus *pci_bus; /* global reference to a Test PCI bus */
+
+/** List of PCI devices */
+TAILQ_HEAD(test_pci_device_list, rte_pci_device);
+/** List of PCI drivers */
+TAILQ_HEAD(test_pci_driver_list, rte_pci_driver);
 
 static int my_driver_init(struct rte_pci_driver *dr,
                          struct rte_pci_device *dev);
 
+struct test_pci_bus {
+       struct rte_bus bus;
+       struct test_pci_device_list test_device_list;
+       struct test_pci_driver_list test_driver_list;
+};
+
+struct test_pci_bus test_pci_bus = {
+       .bus = {
+               .name = "test_pci_bus",
+               .scan = rte_eal_pci_scan,
+               .probe = rte_eal_pci_probe,
+       },
+};
+
 /* IXGBE NICS */
 struct rte_pci_id my_driver_id[] = {
        {RTE_PCI_DEVICE(0x0001, 0x1234)},
@@ -79,7 +102,7 @@ struct rte_pci_id my_driver_id2[] = {
 
 struct rte_pci_driver my_driver = {
        .driver = {
-               .name = "test_driver"
+               .name = "test_driver",
        },
        .probe = my_driver_init,
        .id_table = my_driver_id,
@@ -88,7 +111,7 @@ struct rte_pci_driver my_driver = {
 
 struct rte_pci_driver my_driver2 = {
        .driver = {
-               .name = "test_driver2"
+               .name = "test_driver2",
        },
        .probe = my_driver_init,
        .id_table = my_driver_id2,
@@ -108,6 +131,55 @@ my_driver_init(__attribute__((unused)) struct 
rte_pci_driver *dr,
        return 0;
 }
 
+/* dump devices on the bus */
+static void
+do_pci_device_dump(FILE *f)
+{
+       int i;
+       struct rte_pci_device *dev = NULL;
+
+       TAILQ_FOREACH(dev, &test_pci_bus.test_device_list, next) {
+
+               fprintf(f, PCI_PRI_FMT, dev->addr.domain, dev->addr.bus,
+                      dev->addr.devid, dev->addr.function);
+               fprintf(f, " - vendor:%x device:%x\n", dev->id.vendor_id,
+                      dev->id.device_id);
+
+               for (i = 0; i != sizeof(dev->mem_resource) /
+                       sizeof(dev->mem_resource[0]); i++) {
+                       fprintf(f, "   %16.16"PRIx64" %16.16"PRIx64"\n",
+                               dev->mem_resource[i].phys_addr,
+                               dev->mem_resource[i].len);
+               }
+       }
+}
+
+/* Dummy implementation for rte_eal_pci_probe() over test_pci_bus */
+static int
+do_pci_bus_probe(void)
+{
+       int ret;
+       struct rte_pci_device *device;
+       struct rte_pci_driver *driver;
+
+       TAILQ_FOREACH(device, &test_pci_bus.test_device_list, next) {
+               TAILQ_FOREACH(driver, &test_pci_bus.test_driver_list, next) {
+                       ret = rte_pci_match(driver, device);
+                       if (!ret) {
+                               if (!driver->probe)
+                                       continue;
+
+                               device->driver = driver;
+                               ret = driver->probe(driver, device);
+                               if (ret != 0)
+                                       return ret;
+                       }
+               }
+       }
+
+       return 0;
+}
+
 static void
 blacklist_all_devices(void)
 {
@@ -115,7 +187,7 @@ blacklist_all_devices(void)
        unsigned i = 0;
        char pci_addr_str[16];
 
-       TAILQ_FOREACH(dev, &pci_device_list, next) {
+       TAILQ_FOREACH(dev, &(test_pci_bus.test_device_list), next) {
                snprintf(pci_addr_str, sizeof(pci_addr_str), PCI_PRI_FMT,
                        dev->addr.domain, dev->addr.bus, dev->addr.devid,
                        dev->addr.function);
@@ -142,19 +214,11 @@ static void free_devargs_list(void)
        }
 }
 
-/* backup real devices & drivers (not used for testing) */
-struct pci_driver_list real_pci_driver_list =
-       TAILQ_HEAD_INITIALIZER(real_pci_driver_list);
-struct pci_device_list real_pci_device_list =
-       TAILQ_HEAD_INITIALIZER(real_pci_device_list);
-
 REGISTER_LINKED_RESOURCE(test_pci_sysfs);
 
 static int
 test_pci_setup(void)
 {
-       struct rte_pci_device *dev;
-       struct rte_pci_driver *dr;
        const struct resource *r;
        int ret;
 
@@ -167,22 +231,22 @@ test_pci_setup(void)
        ret = setenv("SYSFS_PCI_DEVICES", "test_pci_sysfs/bus/pci/devices", 1);
        TEST_ASSERT_SUCCESS(ret, "failed to setenv");
 
-       /* Unregister original devices & drivers lists */
-       while (!TAILQ_EMPTY(&pci_driver_list)) {
-               dr = TAILQ_FIRST(&pci_driver_list);
-               rte_eal_pci_unregister(dr);
-               TAILQ_INSERT_TAIL(&real_pci_driver_list, dr, next);
-       }
+       TAILQ_INIT(&test_pci_bus.test_device_list);
+       TAILQ_INIT(&test_pci_bus.test_driver_list);
 
-       while (!TAILQ_EMPTY(&pci_device_list)) {
-               dev = TAILQ_FIRST(&pci_device_list);
-               TAILQ_REMOVE(&pci_device_list, dev, next);
-               TAILQ_INSERT_TAIL(&real_pci_device_list, dev, next);
-       }
+       /* Create a new Bus called 'test_pci_bus' */
+       /* Bus doesn't exist; Create the test bus */
+       printf("Creating a Test PCI bus\n");
+       rte_bus_register(&test_pci_bus.bus);
+       pci_bus = &test_pci_bus;
+
+       printf("Scan for Test devices and add to bus\n");
+       ret = pci_bus->bus.scan();
 
-       ret = rte_eal_pci_scan();
        TEST_ASSERT_SUCCESS(ret, "failed to scan PCI bus");
-       rte_eal_pci_dump(stdout);
+
+       printf("Dump of all devices scanned:\n");
+       do_pci_device_dump(stdout);
 
        return 0;
 }
@@ -190,10 +254,11 @@ test_pci_setup(void)
 static int
 test_pci_cleanup(void)
 {
-       struct rte_pci_device *dev;
-       struct rte_pci_driver *dr;
+       struct rte_pci_device *dev = NULL;
+       struct rte_pci_driver *dr = NULL;
        const struct resource *r;
        int ret;
+       void *temp;
 
        unsetenv("SYSFS_PCI_DEVICES");
 
@@ -203,28 +268,23 @@ test_pci_cleanup(void)
        ret = resource_rm_by_tar(r);
        TEST_ASSERT_SUCCESS(ret, "Failed to delete resource %s", r->name);
 
+       TEST_ASSERT_NOT_NULL(pci_bus, "Invalid bus specified");
+
        /*
         * FIXME: there is no API in DPDK to free a rte_pci_device so we
         * cannot free the devices in the right way. Let's assume that we
         * don't care for tests.
         */
-       while (!TAILQ_EMPTY(&pci_device_list)) {
-               dev = TAILQ_FIRST(&pci_device_list);
-               TAILQ_REMOVE(&pci_device_list, dev, next);
+       TAILQ_FOREACH_SAFE(dev, &(test_pci_bus.test_device_list), next, temp) {
+               TAILQ_REMOVE(&(test_pci_bus.test_device_list), dev, next);
+               dev->driver = NULL;
        }
 
-       /* Restore original devices & drivers lists */
-       while (!TAILQ_EMPTY(&real_pci_driver_list)) {
-               dr = TAILQ_FIRST(&real_pci_driver_list);
-               TAILQ_REMOVE(&real_pci_driver_list, dr, next);
-               rte_eal_pci_register(dr);
+       TAILQ_FOREACH_SAFE(dr, &(test_pci_bus.test_driver_list), next, temp) {
+               TAILQ_REMOVE(&(test_pci_bus.test_driver_list), dr, next);
        }
 
-       while (!TAILQ_EMPTY(&real_pci_device_list)) {
-               dev = TAILQ_FIRST(&real_pci_device_list);
-               TAILQ_REMOVE(&real_pci_device_list, dev, next);
-               TAILQ_INSERT_TAIL(&pci_device_list, dev, next);
-       }
+       rte_bus_unregister(&pci_bus->bus);
 
        return 0;
 }
@@ -234,16 +294,19 @@ test_pci_blacklist(void)
 {
        struct rte_devargs_list save_devargs_list;
 
-       printf("Dump all devices\n");
-       TEST_ASSERT(TAILQ_EMPTY(&pci_driver_list),
-                       "pci_driver_list not empty");
+       TEST_ASSERT_NOT_NULL(pci_bus, "Invalid bus specified");
 
-       rte_eal_pci_register(&my_driver);
-       rte_eal_pci_register(&my_driver2);
+       TEST_ASSERT(TAILQ_EMPTY(&test_pci_bus.test_driver_list),
+                   "PCI Driver list not empty");
+
+       /* Add test drivers to Bus */
+       TAILQ_INSERT_TAIL(&test_pci_bus.test_driver_list, &my_driver, next);
+       TAILQ_INSERT_TAIL(&test_pci_bus.test_driver_list, &my_driver2, next);
 
        pci_dev_count = 0;
-       printf("Scan bus\n");
-       rte_eal_pci_probe();
+
+       printf("Probe the Test Bus\n");
+       do_pci_bus_probe();
 
        if (pci_dev_count == 0) {
                printf("no device detected\n");
@@ -257,8 +320,8 @@ test_pci_blacklist(void)
        blacklist_all_devices();
 
        pci_dev_count = 0;
-       printf("Scan bus with all devices blacklisted\n");
-       rte_eal_pci_probe();
+       printf("Probe bus with all devices blacklisted\n");
+       do_pci_bus_probe();
 
        free_devargs_list();
        devargs_list = save_devargs_list;
@@ -270,8 +333,9 @@ test_pci_blacklist(void)
 
        test_pci_run = 1;
 
-       rte_eal_pci_unregister(&my_driver);
-       rte_eal_pci_unregister(&my_driver2);
+       /* Clear the test drivers added to Test Bus */
+       TAILQ_REMOVE(&(test_pci_bus.test_driver_list), &my_driver, next);
+       TAILQ_REMOVE(&(test_pci_bus.test_driver_list), &my_driver2, next);
 
        return 0;
 }
-- 
2.7.0

Reply via email to