#include <sys/queue.h>
#include <sys/mman.h>
+#include <rte_errno.h>
#include <rte_interrupts.h>
#include <rte_log.h>
#include <rte_pci.h>
RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
loc->domain, loc->bus, loc->devid, loc->function,
- dev->numa_node);
+ dev->device.numa_node);
/* no initialization when blacklisted, return without error */
- if (dev->devargs != NULL &&
- dev->devargs->type == RTE_DEVTYPE_BLACKLISTED_PCI) {
+ if (dev->device.devargs != NULL &&
+ dev->device.devargs->type ==
+ RTE_DEVTYPE_BLACKLISTED_PCI) {
RTE_LOG(INFO, EAL, " Device is blacklisted, not initializing\n");
return 1;
}
dev->id.device_id, dr->driver.name);
if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
- /* map resources for devices that use igb_uio */
+ /* map resources for devices that use igb_uio or VFIO */
ret = rte_eal_pci_map_device(dev);
if (ret != 0)
return ret;
- } else if (dr->drv_flags & RTE_PCI_DRV_FORCE_UNBIND &&
- rte_eal_process_type() == RTE_PROC_PRIMARY) {
- /* unbind current driver */
- if (pci_unbind_kernel_driver(dev) < 0)
- return -1;
}
/* reference driver structure */
dev->driver = dr;
/* call the driver probe() function */
- return dr->probe(dr, dev);
+ ret = dr->probe(dr, dev);
+ if (ret) {
+ dev->driver = NULL;
+ if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
+ rte_eal_pci_unmap_device(dev);
+ }
+
+ return ret;
}
/* return positive value if driver doesn't support this device */
return 1;
RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
loc->domain, loc->bus, loc->devid,
- loc->function, dev->numa_node);
+ loc->function, dev->device.numa_node);
RTE_LOG(DEBUG, EAL, " remove driver: %x:%x %s\n", dev->id.vendor_id,
dev->id.device_id, dr->driver.name);
if (dev == NULL)
return -1;
+ /* Check if a driver is already loaded */
+ if (dev->driver != NULL)
+ return 0;
+
TAILQ_FOREACH(dr, &pci_driver_list, next) {
rc = rte_eal_pci_probe_one_driver(dr, dev);
if (rc < 0)
continue;
ret = pci_probe_all_drivers(dev);
- if (ret < 0)
+ if (ret)
goto err_return;
return 0;
}
goto err_return;
TAILQ_REMOVE(&pci_device_list, dev, next);
+ free(dev);
return 0;
}
return -1;
rte_eal_pci_probe(void)
{
struct rte_pci_device *dev = NULL;
+ size_t probed = 0, failed = 0;
struct rte_devargs *devargs;
int probe_all = 0;
int ret = 0;
probe_all = 1;
TAILQ_FOREACH(dev, &pci_device_list, next) {
+ probed++;
/* set devargs in PCI structure */
devargs = pci_devargs_lookup(dev);
if (devargs != NULL)
- dev->devargs = devargs;
+ dev->device.devargs = devargs;
/* probe all or only whitelisted devices */
if (probe_all)
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
+ if (ret < 0) {
+ RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT
" cannot be used\n", dev->addr.domain, dev->addr.bus,
dev->addr.devid, dev->addr.function);
+ rte_errno = errno;
+ failed++;
+ ret = 0;
+ }
}
- return 0;
+ return (probed && probed == failed) ? -1 : 0;
}
/* dump one device */
rte_eal_pci_register(struct rte_pci_driver *driver)
{
TAILQ_INSERT_TAIL(&pci_driver_list, driver, next);
+ rte_eal_driver_register(&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);
}