[dpdk-dev] [PATCH v2 11/12] eal: enable PCI bus

Shreyansh Jain shreyansh.jain at nxp.com
Tue Dec 13 14:37:11 CET 2016


Register a PCI bus with Scan/match and probe callbacks. Necessary changes
in EAL layer for enabling bus interfaces. PCI devices and drivers now
reside within the Bus object.

Now that PCI bus handles the scan/probe methods, independent calls to
PCI scan and probe can be removed from the code.
PCI device and driver list are also removed.

rte_device and rte_driver list continue to exist. As does the VDEV lists.

Note: With this patch, all PCI PMDs would cease to work because of lack
      rte_driver->probe/remove implementations. Next patch would do that.

Signed-off-by: Shreyansh Jain <shreyansh.jain at nxp.com>
---
 lib/librte_eal/bsdapp/eal/eal.c                 |   7 -
 lib/librte_eal/bsdapp/eal/eal_pci.c             |  52 ++++---
 lib/librte_eal/bsdapp/eal/rte_eal_version.map   |   7 +-
 lib/librte_eal/common/eal_common_bus.c          |   1 +
 lib/librte_eal/common/eal_common_pci.c          | 187 +++++++++++++++---------
 lib/librte_eal/common/eal_private.h             |  14 +-
 lib/librte_eal/common/include/rte_pci.h         |  53 ++++---
 lib/librte_eal/linuxapp/eal/eal.c               |   7 -
 lib/librte_eal/linuxapp/eal/eal_pci.c           |  54 ++++---
 lib/librte_eal/linuxapp/eal/rte_eal_version.map |   7 +-
 10 files changed, 220 insertions(+), 169 deletions(-)

diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 30afc6b..79d82d4 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -562,9 +562,6 @@ rte_eal_init(int argc, char **argv)
 	if (rte_eal_timer_init() < 0)
 		rte_panic("Cannot init HPET or TSC timers\n");
 
-	if (rte_eal_pci_init() < 0)
-		rte_panic("Cannot init PCI\n");
-
 	eal_check_mem_on_local_socket();
 
 	if (eal_plugins_init() < 0)
@@ -616,10 +613,6 @@ rte_eal_init(int argc, char **argv)
 	rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MASTER);
 	rte_eal_mp_wait_lcore();
 
-	/* Probe & Initialize PCI devices */
-	if (rte_eal_pci_probe())
-		rte_panic("Cannot probe PCI\n");
-
 	if (rte_eal_bus_probe())
 		rte_panic("Cannot probe devices\n");
 
diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
index 10b234e..ab9f9d2 100644
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ b/lib/librte_eal/bsdapp/eal/eal_pci.c
@@ -58,6 +58,7 @@
 
 #include <rte_interrupts.h>
 #include <rte_log.h>
+#include <rte_bus.h>
 #include <rte_pci.h>
 #include <rte_common.h>
 #include <rte_launch.h>
@@ -249,7 +250,7 @@ pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
 }
 
 static int
-pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
+pci_scan_one(struct rte_bus *bus, int dev_pci_fd, struct pci_conf *conf)
 {
 	struct rte_pci_device *dev;
 	struct pci_bar_io bar;
@@ -322,19 +323,23 @@ pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
 	}
 
 	/* device is valid, add in list (sorted) */
-	if (TAILQ_EMPTY(&pci_device_list)) {
-		TAILQ_INSERT_TAIL(&pci_device_list, dev, next);
+	if (TAILQ_EMPTY(&bus->device_list)) {
+		rte_eal_bus_add_device(bus, &dev->device);
 	}
 	else {
 		struct rte_pci_device *dev2 = NULL;
+		struct rte_device *r_dev2;
 		int ret;
 
-		TAILQ_FOREACH(dev2, &pci_device_list, next) {
+		TAILQ_FOREACH(r_dev2, &bus->device_list, next) {
+			dev2 = container_of(r_dev2, struct rte_pci_device,
+					    device);
 			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
 			if (ret > 0)
 				continue;
 			else if (ret < 0) {
-				TAILQ_INSERT_BEFORE(dev2, dev, next);
+				rte_eal_bus_insert_device(bus, &dev2->device,
+							  &dev->device);
 				return 0;
 			} else { /* already registered */
 				dev2->kdrv = dev->kdrv;
@@ -346,7 +351,7 @@ pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
 				return 0;
 			}
 		}
-		TAILQ_INSERT_TAIL(&pci_device_list, dev, next);
+		rte_eal_bus_add_device(bus, &dev->device);
 	}
 
 	return 0;
@@ -361,7 +366,7 @@ pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
  * list. Call pci_scan_one() for each pci entry found.
  */
 int
-rte_eal_pci_scan(struct rte_bus *bus __rte_unused)
+rte_eal_pci_scan(struct rte_bus *bus)
 {
 	int fd;
 	unsigned dev_count = 0;
@@ -374,6 +379,10 @@ rte_eal_pci_scan(struct rte_bus *bus __rte_unused)
 			.matches = &matches[0],
 	};
 
+	/* for debug purposes, PCI can be disabled */
+	if (internal_config.no_pci)
+		return 0;
+
 	fd = open("/dev/pci", O_RDONLY);
 	if (fd < 0) {
 		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
@@ -389,7 +398,7 @@ rte_eal_pci_scan(struct rte_bus *bus __rte_unused)
 		}
 
 		for (i = 0; i < conf_io.num_matches; i++)
-			if (pci_scan_one(fd, &matches[i]) < 0)
+			if (pci_scan_one(bus, fd, &matches[i]) < 0)
 				goto error;
 
 		dev_count += conf_io.num_matches;
@@ -407,9 +416,9 @@ rte_eal_pci_scan(struct rte_bus *bus __rte_unused)
 }
 
 int
-pci_update_device(const struct rte_pci_addr *addr)
+pci_update_device(struct rte_bus *bus, const struct rte_pci_addr *addr)
 {
-	int fd;
+	int fd = -1;
 	struct pci_conf matches[2];
 	struct pci_match_conf match = {
 		.pc_sel = {
@@ -427,6 +436,9 @@ pci_update_device(const struct rte_pci_addr *addr)
 		.matches = &matches[0],
 	};
 
+	if (!bus)
+		goto error;
+
 	fd = open("/dev/pci", O_RDONLY);
 	if (fd < 0) {
 		RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
@@ -442,7 +454,7 @@ pci_update_device(const struct rte_pci_addr *addr)
 	if (conf_io.num_matches != 1)
 		goto error;
 
-	if (pci_scan_one(fd, &matches[0]) < 0)
+	if (pci_scan_one(bus, fd, &matches[0]) < 0)
 		goto error;
 
 	close(fd);
@@ -668,17 +680,9 @@ rte_eal_pci_ioport_unmap(struct rte_pci_ioport *p)
 	return ret;
 }
 
-/* Init the PCI EAL subsystem */
-int
-rte_eal_pci_init(void)
-{
-	/* for debug purposes, PCI can be disabled */
-	if (internal_config.no_pci)
-		return 0;
+struct rte_bus pci_bus = {
+	.scan = rte_eal_pci_scan,
+	.match = rte_eal_pci_match,
+};
 
-	if (rte_eal_pci_scan(NULL) < 0) {
-		RTE_LOG(ERR, EAL, "%s(): Cannot scan PCI bus\n", __func__);
-		return -1;
-	}
-	return 0;
-}
+RTE_REGISTER_BUS(pci, pci_bus);
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 23fc1c1..3dcf439 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -6,8 +6,6 @@ DPDK_2.0 {
 	eal_parse_sysfs_value;
 	eal_timer_source;
 	lcore_config;
-	pci_device_list;
-	pci_driver_list;
 	per_lcore__lcore_id;
 	per_lcore__rte_errno;
 	rte_calloc;
@@ -41,7 +39,6 @@ DPDK_2.0 {
 	rte_eal_mp_wait_lcore;
 	rte_eal_parse_devargs_str;
 	rte_eal_pci_dump;
-	rte_eal_pci_probe;
 	rte_eal_pci_probe_one;
 	rte_eal_pci_register;
 	rte_eal_pci_scan;
@@ -187,5 +184,9 @@ DPDK_17.02 {
 	rte_eal_bus_remove_device;
 	rte_eal_bus_remove_driver;
 	rte_eal_bus_unregister;
+	rte_eal_pci_match;
+	rte_eal_pci_probe;
+	rte_eal_pci_remove;
+	rte_eal_pci_scan;
 
 } DPDK_16.11;
diff --git a/lib/librte_eal/common/eal_common_bus.c b/lib/librte_eal/common/eal_common_bus.c
index 469abac..d9ee347 100644
--- a/lib/librte_eal/common/eal_common_bus.c
+++ b/lib/librte_eal/common/eal_common_bus.c
@@ -234,6 +234,7 @@ rte_eal_bus_probe(void)
 			TAILQ_FOREACH(driver, &bus->driver_list, next) {
 				ret = bus->match(driver, device);
 				if (!ret) {
+					device->driver = driver;
 					ret = perform_probe(bus, driver,
 							    device);
 					if (ret < 0)
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index 562c0fd..fb4e39f 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -71,6 +71,7 @@
 
 #include <rte_interrupts.h>
 #include <rte_log.h>
+#include <rte_bus.h>
 #include <rte_pci.h>
 #include <rte_per_lcore.h>
 #include <rte_memory.h>
@@ -82,11 +83,6 @@
 
 #include "eal_private.h"
 
-struct pci_driver_list pci_driver_list =
-	TAILQ_HEAD_INITIALIZER(pci_driver_list);
-struct pci_device_list pci_device_list =
-	TAILQ_HEAD_INITIALIZER(pci_device_list);
-
 #define SYSFS_PCI_DEVICES "/sys/bus/pci/devices"
 
 const char *pci_get_sysfs_path(void)
@@ -206,15 +202,11 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr,
 			     struct rte_pci_device *dev)
 {
 	int ret;
-	struct rte_driver *driver;
-	struct rte_device *device;
 	struct rte_pci_addr *loc;
 
 	if ((dr == NULL) || (dev == NULL))
 		return -EINVAL;
 
-	driver = &dr->driver;
-	device = &dev->device;
 	loc = &dev->addr;
 
 	RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
@@ -230,15 +222,6 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr,
 		return 1;
 	}
 
-	/* The device is not blacklisted; Check if driver supports it */
-	ret = rte_eal_pci_match(driver, device);
-	if (ret) {
-		/* Match of device and driver failed */
-		RTE_LOG(DEBUG, EAL, "Driver (%s) doesn't match the device\n",
-			driver->name);
-		return 1;
-	}
-
 	RTE_LOG(INFO, EAL, "  probe driver: %x:%x %s\n", dev->id.vendor_id,
 			dev->id.device_id, dr->driver.name);
 
@@ -276,23 +259,11 @@ static int
 rte_eal_pci_detach_dev(struct rte_pci_driver *dr,
 		struct rte_pci_device *dev)
 {
-	int ret;
-	struct rte_driver *driver = NULL;
-	struct rte_device *device;
 	struct rte_pci_addr *loc;
 
 	if ((dr == NULL) || (dev == NULL))
 		return -EINVAL;
 
-	driver = &(dr->driver);
-	device = &(dev->device);
-
-	ret = rte_eal_pci_match(driver, device);
-	if (ret) {
-		/* Device and driver don't match */
-		return 1;
-	}
-
 	loc = &dev->addr;
 
 	RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
@@ -321,9 +292,10 @@ rte_eal_pci_detach_dev(struct rte_pci_driver *dr,
  * failed, return 1 if no driver is found for this device.
  */
 static int
-pci_probe_all_drivers(struct rte_pci_device *dev)
+pci_probe_all_drivers(struct rte_bus *bus, struct rte_pci_device *dev)
 {
 	struct rte_pci_driver *dr = NULL;
+	struct rte_driver *r_dr = NULL;
 	int rc = 0;
 
 	if (dev == NULL)
@@ -333,7 +305,8 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
 	if (dev->driver != NULL)
 		return 0;
 
-	TAILQ_FOREACH(dr, &pci_driver_list, next) {
+	TAILQ_FOREACH(r_dr, &bus->driver_list, next) {
+		dr = container_of(r_dr, struct rte_pci_driver, driver);
 		rc = rte_eal_pci_probe_one_driver(dr, dev);
 		if (rc < 0)
 			/* negative value is an error */
@@ -352,15 +325,17 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
  * failed, return 1 if no driver is found for this device.
  */
 static int
-pci_detach_all_drivers(struct rte_pci_device *dev)
+pci_detach_all_drivers(struct rte_bus *bus, struct rte_pci_device *dev)
 {
 	struct rte_pci_driver *dr = NULL;
+	struct rte_driver *r_dr = NULL;
 	int rc = 0;
 
 	if (dev == NULL)
 		return -1;
 
-	TAILQ_FOREACH(dr, &pci_driver_list, next) {
+	TAILQ_FOREACH(r_dr, &bus->driver_list, next) {
+		dr = container_of(r_dr, struct rte_pci_driver, driver);
 		rc = rte_eal_pci_detach_dev(dr, dev);
 		if (rc < 0)
 			/* negative value is an error */
@@ -381,22 +356,31 @@ int
 rte_eal_pci_probe_one(const struct rte_pci_addr *addr)
 {
 	struct rte_pci_device *dev = NULL;
+	struct rte_device *r_dev = NULL;
+	struct rte_bus *bus;
 	int ret = 0;
 
 	if (addr == NULL)
 		return -1;
 
+	bus = rte_eal_get_bus("pci");
+	if (!bus) {
+		RTE_LOG(ERR, EAL, "PCI Bus not registered\n");
+		return -1;
+	}
+
 	/* update current pci device in global list, kernel bindings might have
 	 * changed since last time we looked at it.
 	 */
-	if (pci_update_device(addr) < 0)
+	if (pci_update_device(bus, addr) < 0)
 		goto err_return;
 
-	TAILQ_FOREACH(dev, &pci_device_list, next) {
+	TAILQ_FOREACH(r_dev, &bus->device_list, next) {
+		dev = container_of(r_dev, struct rte_pci_device, device);
 		if (rte_eal_compare_pci_addr(&dev->addr, addr))
 			continue;
 
-		ret = pci_probe_all_drivers(dev);
+		ret = pci_probe_all_drivers(bus, dev);
 		if (ret)
 			goto err_return;
 		return 0;
@@ -417,20 +401,29 @@ int
 rte_eal_pci_detach(const struct rte_pci_addr *addr)
 {
 	struct rte_pci_device *dev = NULL;
+	struct rte_device *r_dev = NULL;
+	struct rte_bus *bus;
 	int ret = 0;
 
 	if (addr == NULL)
 		return -1;
 
-	TAILQ_FOREACH(dev, &pci_device_list, next) {
+	bus = rte_eal_get_bus("pci");
+	if (!bus) {
+		RTE_LOG(ERR, EAL, "PCI Bus is not registered\n");
+		return -1;
+	}
+
+	TAILQ_FOREACH(r_dev, &bus->device_list, next) {
+		dev = container_of(r_dev, struct rte_pci_device, device);
 		if (rte_eal_compare_pci_addr(&dev->addr, addr))
 			continue;
 
-		ret = pci_detach_all_drivers(dev);
+		ret = pci_detach_all_drivers(bus, dev);
 		if (ret < 0)
 			goto err_return;
 
-		TAILQ_REMOVE(&pci_device_list, dev, next);
+		rte_eal_bus_remove_device(r_dev);
 		free(dev);
 		return 0;
 	}
@@ -443,41 +436,66 @@ rte_eal_pci_detach(const struct rte_pci_addr *addr)
 	return -1;
 }
 
-/*
- * Scan the content of the PCI bus, and call the probe() function for
- * all registered drivers that have a matching entry in its id_table
- * for discovered devices.
- */
 int
-rte_eal_pci_probe(void)
+rte_eal_pci_probe(struct rte_driver *driver, struct rte_device *device)
 {
-	struct rte_pci_device *dev = NULL;
-	struct rte_devargs *devargs;
-	int probe_all = 0;
 	int ret = 0;
+	struct rte_devargs *devargs;
+	struct rte_pci_device *pci_dev;
+	struct rte_pci_driver *pci_drv;
 
-	if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) == 0)
-		probe_all = 1;
+	if (!driver || !device)
+		return -1;
 
-	TAILQ_FOREACH(dev, &pci_device_list, next) {
+	pci_dev = container_of(device, struct rte_pci_device, device);
+	pci_drv = container_of(driver, struct rte_pci_driver, driver);
 
+	ret = rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI);
+	if (ret != 0) {
 		/* set devargs in PCI structure */
-		devargs = pci_devargs_lookup(dev);
-		if (devargs != NULL)
-			dev->device.devargs = devargs;
-
-		/* probe all or only whitelisted devices */
-		if (probe_all)
-			ret = pci_probe_all_drivers(dev);
-		else if (devargs != NULL &&
-			devargs->type == RTE_DEVTYPE_WHITELISTED_PCI)
-			ret = pci_probe_all_drivers(dev);
-		if (ret < 0)
-			rte_exit(EXIT_FAILURE, "Requested device " PCI_PRI_FMT
-				 " cannot be used\n", dev->addr.domain, dev->addr.bus,
-				 dev->addr.devid, dev->addr.function);
+		devargs = pci_devargs_lookup(pci_dev);
+		if (devargs != NULL &&
+		    devargs->type == RTE_DEVTYPE_WHITELISTED_PCI) {
+			pci_dev->device.devargs = devargs;
+		} else {
+			/* Ignore the device */
+			return 0;
+		}
+	}
+
+	ret = rte_eal_pci_probe_one_driver(pci_drv, pci_dev);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT
+			" cannot be used\n", pci_dev->addr.domain,
+			pci_dev->addr.bus, pci_dev->addr.devid,
+			pci_dev->addr.function);
+		return ret;
 	}
+	return 0;
+}
+
+int
+rte_eal_pci_remove(struct rte_device *device)
+{
+	int ret = 0;
+	struct rte_pci_device *pci_dev;
+
+	if (!device)
+		return -1;
+
+	pci_dev = container_of(device, struct rte_pci_device, device);
 
+	if (!pci_dev->driver)
+		return -1;
+
+	ret = rte_eal_pci_detach_dev(pci_dev->driver, pci_dev);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT
+			" cannot be used\n", pci_dev->addr.domain,
+			pci_dev->addr.bus, pci_dev->addr.devid,
+			pci_dev->addr.function);
+		return ret;
+	}
 	return 0;
 }
 
@@ -506,8 +524,17 @@ void
 rte_eal_pci_dump(FILE *f)
 {
 	struct rte_pci_device *dev = NULL;
+	struct rte_device *r_dev = NULL;
+	struct rte_bus *bus;
 
-	TAILQ_FOREACH(dev, &pci_device_list, next) {
+	bus = rte_eal_get_bus("pci");
+	if (!bus) {
+		RTE_LOG(ERR, EAL, "PCI Bus not registered\n");
+		return;
+	}
+
+	TAILQ_FOREACH(r_dev, &bus->device_list, next) {
+		dev = container_of(r_dev, struct rte_pci_device, device);
 		pci_dump_one_device(f, dev);
 	}
 }
@@ -516,14 +543,32 @@ rte_eal_pci_dump(FILE *f)
 void
 rte_eal_pci_register(struct rte_pci_driver *driver)
 {
-	TAILQ_INSERT_TAIL(&pci_driver_list, driver, next);
-	rte_eal_driver_register(&driver->driver);
+	struct rte_bus *bus;
+
+	RTE_VERIFY(driver);
+
+	bus = rte_eal_get_bus("pci");
+	if (!bus) {
+		RTE_LOG(ERR, EAL, "PCI Bus not registered\n");
+		return;
+	}
+
+	rte_eal_bus_add_driver(bus, &driver->driver);
 }
 
 /* unregister a driver */
 void
 rte_eal_pci_unregister(struct rte_pci_driver *driver)
 {
-	rte_eal_driver_unregister(&driver->driver);
-	TAILQ_REMOVE(&pci_driver_list, driver, next);
+	struct rte_bus *bus;
+
+	RTE_VERIFY(driver);
+
+	bus = driver->driver.bus;
+	if (!bus) {
+		RTE_LOG(ERR, EAL, "PCI Bus not registered\n");
+		return;
+	}
+
+	rte_eal_bus_remove_driver(&driver->driver);
 }
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 9e7d8f6..06ec172 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -108,16 +108,6 @@ int rte_eal_timer_init(void);
  */
 int rte_eal_log_init(const char *id, int facility);
 
-/**
- * Init the PCI infrastructure
- *
- * This function is private to EAL.
- *
- * @return
- *   0 on success, negative on error
- */
-int rte_eal_pci_init(void);
-
 struct rte_pci_driver;
 struct rte_pci_device;
 
@@ -126,13 +116,15 @@ struct rte_pci_device;
  *
  * This function is private to EAL.
  *
+ * @param bus
+ *	The PCI bus on which device is connected
  * @param addr
  *	The PCI Bus-Device-Function address to look for
  * @return
  *   - 0 on success.
  *   - negative on error.
  */
-int pci_update_device(const struct rte_pci_addr *addr);
+int pci_update_device(struct rte_bus *bus, const struct rte_pci_addr *addr);
 
 /**
  * Unbind kernel driver for this device
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 10108a4..ec8f672 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -86,12 +86,6 @@ extern "C" {
 #include <rte_interrupts.h>
 #include <rte_dev.h>
 
-TAILQ_HEAD(pci_device_list, rte_pci_device); /**< PCI devices in D-linked Q. */
-TAILQ_HEAD(pci_driver_list, rte_pci_driver); /**< PCI drivers in D-linked Q. */
-
-extern struct pci_driver_list pci_driver_list; /**< Global list of PCI drivers. */
-extern struct pci_device_list pci_device_list; /**< Global list of PCI devices. */
-
 /** Pathname of PCI devices directory. */
 const char *pci_get_sysfs_path(void);
 
@@ -372,6 +366,40 @@ rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
 int rte_eal_pci_scan(struct rte_bus *bus);
 
 /**
+ * Probe callback for the PCI bus
+ *
+ * For each matched pair of PCI device and driver on PCI bus, perform devargs
+ * check, and call a series of callbacks to allocate ethdev/cryptodev instances
+ * and intializing them.
+ *
+ * @param driver
+ *	Generic driver object matched with the device
+ * @param device
+ *	Generic device object to initialize
+ * @return
+ *   - 0 on success.
+ *   - !0 on error.
+ */
+int
+rte_eal_pci_probe(struct rte_driver *driver, struct rte_device *device);
+
+/**
+ * Remove callback for the PCI bus
+ *
+ * Called when a device needs to be removed from a bus; wraps around the
+ * PCI specific implementation layered over rte_pci_driver->remove. Default
+ * handler used by PCI PMDs
+ *
+ * @param device
+ *	rte_device object referring to device to be removed
+ * @return
+ *	- 0 for successful removal
+ *	- !0 for failure in removal of device
+ */
+int
+rte_eal_pci_remove(struct rte_device *device);
+
+/**
  * Match the PCI Driver and Device using the ID Table
  *
  * @param drv
@@ -387,19 +415,6 @@ rte_eal_pci_match(struct rte_driver *drv,
 		  struct rte_device *dev);
 
 /**
- * Probe the PCI bus for registered drivers.
- *
- * Scan the content of the PCI bus, and call the probe() function for
- * all registered drivers that have a matching entry in its id_table
- * for discovered devices.
- *
- * @return
- *   - 0 on success.
- *   - Negative on error.
- */
-int rte_eal_pci_probe(void);
-
-/**
  * Map the PCI device resources in user space virtual memory address
  *
  * Note that driver should not call this function when flag
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 01d0cee..ff92de2 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -803,9 +803,6 @@ rte_eal_init(int argc, char **argv)
 	if (rte_eal_log_init(logid, internal_config.syslog_facility) < 0)
 		rte_panic("Cannot init logs\n");
 
-	if (rte_eal_pci_init() < 0)
-		rte_panic("Cannot init PCI\n");
-
 #ifdef VFIO_PRESENT
 	if (rte_eal_vfio_setup() < 0)
 		rte_panic("Cannot init VFIO\n");
@@ -887,10 +884,6 @@ rte_eal_init(int argc, char **argv)
 	rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MASTER);
 	rte_eal_mp_wait_lcore();
 
-	/* Probe & Initialize PCI devices */
-	if (rte_eal_pci_probe())
-		rte_panic("Cannot probe PCI\n");
-
 	if (rte_eal_bus_probe())
 		rte_panic("Cannot probe devices\n");
 
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index cbd25df..5cc89c5 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -35,6 +35,7 @@
 #include <dirent.h>
 
 #include <rte_log.h>
+#include <rte_bus.h>
 #include <rte_pci.h>
 #include <rte_eal_memconfig.h>
 #include <rte_malloc.h>
@@ -267,7 +268,8 @@ pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
 
 /* Scan one pci sysfs entry, and fill the devices list from it. */
 static int
-pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
+pci_scan_one(struct rte_bus *bus, const char *dirname,
+	     const struct rte_pci_addr *addr)
 {
 	char filename[PATH_MAX];
 	unsigned long tmp;
@@ -385,20 +387,24 @@ pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
 		dev->kdrv = RTE_KDRV_NONE;
 
 	/* device is valid, add in list (sorted) */
-	if (TAILQ_EMPTY(&pci_device_list)) {
+	if (TAILQ_EMPTY(&bus->device_list)) {
 		rte_eal_device_insert(&dev->device);
-		TAILQ_INSERT_TAIL(&pci_device_list, dev, next);
+		rte_eal_bus_add_device(bus, &dev->device);
 	} else {
 		struct rte_pci_device *dev2;
+		struct rte_device *r_dev2;
 		int ret;
 
-		TAILQ_FOREACH(dev2, &pci_device_list, next) {
+		TAILQ_FOREACH(r_dev2, &bus->device_list, next) {
+			dev2 = container_of(r_dev2, struct rte_pci_device,
+					    device);
 			ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
 			if (ret > 0)
 				continue;
 
 			if (ret < 0) {
-				TAILQ_INSERT_BEFORE(dev2, dev, next);
+				rte_eal_bus_insert_device(bus, &dev2->device,
+							  &dev->device);
 				rte_eal_device_insert(&dev->device);
 			} else { /* already registered */
 				dev2->kdrv = dev->kdrv;
@@ -410,14 +416,14 @@ pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
 			return 0;
 		}
 		rte_eal_device_insert(&dev->device);
-		TAILQ_INSERT_TAIL(&pci_device_list, dev, next);
+		rte_eal_bus_add_device(bus, &dev->device);
 	}
 
 	return 0;
 }
 
 int
-pci_update_device(const struct rte_pci_addr *addr)
+pci_update_device(struct rte_bus *bus, const struct rte_pci_addr *addr)
 {
 	char filename[PATH_MAX];
 
@@ -425,7 +431,7 @@ pci_update_device(const struct rte_pci_addr *addr)
 		 pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid,
 		 addr->function);
 
-	return pci_scan_one(filename, addr);
+	return pci_scan_one(bus, filename, addr);
 }
 
 /*
@@ -479,13 +485,22 @@ parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr)
  * list
  */
 int
-rte_eal_pci_scan(struct rte_bus *bus_p __rte_unused)
+rte_eal_pci_scan(struct rte_bus *bus_p)
 {
 	struct dirent *e;
 	DIR *dir;
 	char dirname[PATH_MAX];
 	struct rte_pci_addr addr;
 
+	if (!bus_p) {
+		RTE_LOG(ERR, EAL, "PCI Bus is not registered\n");
+		return -1;
+	}
+
+	/* for debug purposes, PCI can be disabled */
+	if (internal_config.no_pci)
+		return 0;
+
 	dir = opendir(pci_get_sysfs_path());
 	if (dir == NULL) {
 		RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
@@ -504,7 +519,7 @@ rte_eal_pci_scan(struct rte_bus *bus_p __rte_unused)
 
 		snprintf(dirname, sizeof(dirname), "%s/%s",
 				pci_get_sysfs_path(), e->d_name);
-		if (pci_scan_one(dirname, &addr) < 0)
+		if (pci_scan_one(bus_p, dirname, &addr) < 0)
 			goto error;
 	}
 	closedir(dir);
@@ -750,18 +765,9 @@ rte_eal_pci_ioport_unmap(struct rte_pci_ioport *p)
 	return ret;
 }
 
-/* Init the PCI EAL subsystem */
-int
-rte_eal_pci_init(void)
-{
-	/* for debug purposes, PCI can be disabled */
-	if (internal_config.no_pci)
-		return 0;
-
-	if (rte_eal_pci_scan(NULL) < 0) {
-		RTE_LOG(ERR, EAL, "%s(): Cannot scan PCI bus\n", __func__);
-		return -1;
-	}
+struct rte_bus pci_bus = {
+	.scan = rte_eal_pci_scan,
+	.match = rte_eal_pci_match,
+};
 
-	return 0;
-}
+RTE_REGISTER_BUS(pci, pci_bus);
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index c873a7f..6e0ec51 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -6,8 +6,6 @@ DPDK_2.0 {
 	eal_parse_sysfs_value;
 	eal_timer_source;
 	lcore_config;
-	pci_device_list;
-	pci_driver_list;
 	per_lcore__lcore_id;
 	per_lcore__rte_errno;
 	rte_calloc;
@@ -41,7 +39,6 @@ DPDK_2.0 {
 	rte_eal_mp_wait_lcore;
 	rte_eal_parse_devargs_str;
 	rte_eal_pci_dump;
-	rte_eal_pci_probe;
 	rte_eal_pci_probe_one;
 	rte_eal_pci_register;
 	rte_eal_pci_scan;
@@ -191,5 +188,9 @@ DPDK_17.02 {
 	rte_eal_bus_remove_device;
 	rte_eal_bus_remove_driver;
 	rte_eal_bus_unregister;
+	rte_eal_pci_match;
+	rte_eal_pci_probe;
+	rte_eal_pci_remove;
+	rte_eal_pci_scan;
 
 } DPDK_16.11;
-- 
2.7.4



More information about the dev mailing list