[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