@@ -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");
@@ -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);
@@ -682,3 +694,11 @@ rte_eal_pci_init(void)
}
return 0;
}
+
+struct rte_bus pci_bus = {
+ .scan = rte_eal_pci_scan,
+ .match = rte_eal_pci_match_default,
+ .probe = rte_eal_pci_probe_default,
+};
+
+RTE_REGISTER_BUS(pci, pci_bus);
@@ -196,7 +196,7 @@ rte_eal_bus_scan(void)
}
static int
-perform_probe(struct rte_bus *bus __rte_unused, struct rte_driver *driver,
+perform_probe(struct rte_bus *bus, struct rte_driver *driver,
struct rte_device *device)
{
int ret;
@@ -208,7 +208,7 @@ perform_probe(struct rte_bus *bus __rte_unused, struct rte_driver *driver,
return 0;
}
- ret = driver->probe(driver, device);
+ ret = bus->probe(driver, device);
if (ret < 0)
/* One of the probes failed */
RTE_LOG(ERR, EAL, "Probe failed for (%s).\n", driver->name);
@@ -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)
@@ -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>
@@ -230,15 +231,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_default(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);
@@ -322,19 +314,24 @@ 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)
return -1;
+ if (!bus)
+ return -1;
+
/* Check if a driver is already loaded */
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 */
@@ -353,15 +350,20 @@ 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) {
+ if (!bus)
+ return -1;
+
+ 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 */
@@ -382,22 +384,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;
@@ -418,20 +429,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;
}
@@ -469,10 +489,10 @@ rte_eal_pci_probe(void)
/* probe all or only whitelisted devices */
if (probe_all)
- ret = pci_probe_all_drivers(dev);
+ ret = pci_probe_all_drivers(NULL, dev);
else if (devargs != NULL &&
devargs->type == RTE_DEVTYPE_WHITELISTED_PCI)
- ret = pci_probe_all_drivers(dev);
+ ret = pci_probe_all_drivers(NULL, dev);
if (ret < 0)
rte_exit(EXIT_FAILURE, "Requested device " PCI_PRI_FMT
" cannot be used\n", dev->addr.domain, dev->addr.bus,
@@ -482,6 +502,44 @@ rte_eal_pci_probe(void)
return 0;
}
+int
+rte_eal_pci_probe_default(struct rte_driver *driver, struct rte_device *device)
+{
+ int ret = 0;
+ struct rte_devargs *devargs;
+ struct rte_pci_device *pci_dev;
+ struct rte_pci_driver *pci_drv;
+
+ if (!driver || !device)
+ return -1;
+
+ 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(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;
+}
+
/* dump one device */
static int
pci_dump_one_device(FILE *f, struct rte_pci_device *dev)
@@ -507,8 +565,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);
}
}
@@ -517,14 +584,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);
}
@@ -126,13 +126,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
@@ -102,6 +102,10 @@ typedef int (*bus_scan_t)(struct rte_bus *bus);
*/
typedef int (*bus_match_t)(struct rte_driver *drv, struct rte_device *dev);
+/** TODO
+ */
+typedef int (*bus_probe_t)(struct rte_driver *drv, struct rte_device *dev);
+
struct rte_bus {
TAILQ_ENTRY(rte_bus) next; /**< Next bus object in linked list */
struct rte_driver_list driver_list;
@@ -112,6 +116,7 @@ struct rte_bus {
bus_scan_t scan; /**< Scan for devices attached to bus */
bus_match_t match;
/**< Match device with drivers associated with the bus */
+ bus_probe_t probe; /**< TODO */
};
/** @internal
@@ -371,6 +371,9 @@ rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
*/
int rte_eal_pci_scan(struct rte_bus *bus);
+int
+rte_eal_pci_probe_default(struct rte_driver *driver, struct rte_device *device);
+
/**
* Match the PCI Driver and Device using the ID Table
*
@@ -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");
@@ -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);
@@ -765,3 +780,11 @@ rte_eal_pci_init(void)
return 0;
}
+
+struct rte_bus pci_bus = {
+ .scan = rte_eal_pci_scan,
+ .match = rte_eal_pci_match_default,
+ .probe = rte_eal_pci_probe_default,
+};
+
+RTE_REGISTER_BUS(pci, pci_bus);