#include <rte_log.h>
#include <rte_pci.h>
-#include <rte_tailq.h>
#include <rte_eal_memconfig.h>
#include <rte_malloc.h>
#include <rte_devargs.h>
* IGB_UIO driver (or doesn't initialize, if the device wasn't bound to it).
*/
-struct mapped_pci_res_list *pci_res_list = NULL;
-
/* unbind kernel driver for this device */
static int
pci_unbind_kernel_driver(struct rte_pci_device *dev)
ret = pci_get_kernel_driver_by_path(filename, driver);
if (!ret) {
if (!strcmp(driver, "vfio-pci"))
- dev->pt_driver = RTE_PT_VFIO;
+ dev->kdrv = RTE_KDRV_VFIO;
else if (!strcmp(driver, "igb_uio"))
- dev->pt_driver = RTE_PT_IGB_UIO;
+ dev->kdrv = RTE_KDRV_IGB_UIO;
else if (!strcmp(driver, "uio_pci_generic"))
- dev->pt_driver = RTE_PT_UIO_GENERIC;
+ dev->kdrv = RTE_KDRV_UIO_GENERIC;
else
- dev->pt_driver = RTE_PT_UNKNOWN;
+ dev->kdrv = RTE_KDRV_UNKNOWN;
} else if (ret < 0) {
RTE_LOG(ERR, EAL, "Fail to get kernel driver\n");
free(dev);
return -1;
} else
- dev->pt_driver = RTE_PT_UNKNOWN;
+ dev->kdrv = RTE_KDRV_UNKNOWN;
/* device is valid, add in list (sorted) */
if (TAILQ_EMPTY(&pci_device_list)) {
TAILQ_INSERT_BEFORE(dev2, dev, next);
return 0;
} else { /* already registered */
- /* update pt_driver */
- dev2->pt_driver = dev->pt_driver;
+ dev2->kdrv = dev->kdrv;
dev2->max_vfs = dev->max_vfs;
memmove(dev2->mem_resource,
dev->mem_resource,
* Scan the content of the PCI bus, and the devices in the devices
* list
*/
-static int
-pci_scan(void)
+int
+rte_eal_pci_scan(void)
{
struct dirent *e;
DIR *dir;
int ret = -1;
/* try mapping the NIC resources using VFIO if it exists */
- switch (dev->pt_driver) {
- case RTE_PT_VFIO:
+ switch (dev->kdrv) {
+ case RTE_KDRV_VFIO:
#ifdef VFIO_PRESENT
if (pci_vfio_is_enabled())
ret = pci_vfio_map_resource(dev);
#endif
break;
- case RTE_PT_IGB_UIO:
- case RTE_PT_UIO_GENERIC:
+ case RTE_KDRV_IGB_UIO:
+ case RTE_KDRV_UIO_GENERIC:
/* map resources for devices that use uio */
ret = pci_uio_map_resource(dev);
break;
default:
- RTE_LOG(DEBUG, EAL, " Not managed by known pt driver,"
+ RTE_LOG(DEBUG, EAL, " Not managed by a supported kernel driver,"
" skipped\n");
ret = 1;
break;
return ret;
}
+#ifdef RTE_LIBRTE_EAL_HOTPLUG
+static void
+pci_unmap_device(struct rte_pci_device *dev)
+{
+ if (dev == NULL)
+ return;
+
+ /* try unmapping the NIC resources using VFIO if it exists */
+ switch (dev->kdrv) {
+ case RTE_KDRV_VFIO:
+ RTE_LOG(ERR, EAL, "Hotplug doesn't support vfio yet\n");
+ break;
+ case RTE_KDRV_IGB_UIO:
+ case RTE_KDRV_UIO_GENERIC:
+ /* unmap resources for devices that use uio */
+ pci_uio_unmap_resource(dev);
+ break;
+ default:
+ RTE_LOG(DEBUG, EAL, " Not managed by a supported kernel driver,"
+ " skipped\n");
+ break;
+ }
+}
+#endif /* RTE_LIBRTE_EAL_HOTPLUG */
+
/*
* If vendor/device ID match, call the devinit() function of the
* driver.
rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *dev)
{
int ret;
- struct rte_pci_id *id_table;
+ const struct rte_pci_id *id_table;
- for (id_table = dr->id_table ; id_table->vendor_id != 0; id_table++) {
+ for (id_table = dr->id_table; id_table->vendor_id != 0; id_table++) {
/* check if device's identifiers match the driver's ones */
if (id_table->vendor_id != dev->id.vendor_id &&
return 1;
}
+#ifdef RTE_LIBRTE_EAL_HOTPLUG
+/*
+ * If vendor/device ID match, call the devuninit() function of the
+ * driver.
+ */
+int
+rte_eal_pci_close_one_driver(struct rte_pci_driver *dr,
+ struct rte_pci_device *dev)
+{
+ const struct rte_pci_id *id_table;
+
+ if ((dr == NULL) || (dev == NULL))
+ return -EINVAL;
+
+ for (id_table = dr->id_table; id_table->vendor_id != 0; id_table++) {
+
+ /* check if device's identifiers match the driver's ones */
+ if (id_table->vendor_id != dev->id.vendor_id &&
+ id_table->vendor_id != PCI_ANY_ID)
+ continue;
+ if (id_table->device_id != dev->id.device_id &&
+ id_table->device_id != PCI_ANY_ID)
+ continue;
+ if (id_table->subsystem_vendor_id !=
+ dev->id.subsystem_vendor_id &&
+ id_table->subsystem_vendor_id != PCI_ANY_ID)
+ continue;
+ if (id_table->subsystem_device_id !=
+ dev->id.subsystem_device_id &&
+ id_table->subsystem_device_id != PCI_ANY_ID)
+ continue;
+
+ struct rte_pci_addr *loc = &dev->addr;
+
+ 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);
+
+ RTE_LOG(DEBUG, EAL, " remove driver: %x:%x %s\n",
+ dev->id.vendor_id, dev->id.device_id,
+ dr->name);
+
+ /* call the driver devuninit() function */
+ if (dr->devuninit && (dr->devuninit(dev) < 0))
+ return -1; /* negative value is an error */
+
+ /* clear driver structure */
+ dev->driver = NULL;
+
+ if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
+ /* unmap resources for devices that use igb_uio */
+ pci_unmap_device(dev);
+
+ return 0;
+ }
+ /* return positive value if driver is not found */
+ return 1;
+}
+#else /* RTE_LIBRTE_EAL_HOTPLUG */
+int
+rte_eal_pci_close_one_driver(struct rte_pci_driver *dr __rte_unused,
+ struct rte_pci_device *dev __rte_unused)
+{
+ RTE_LOG(ERR, EAL, "Hotplug support isn't enabled\n");
+ return -1;
+}
+#endif /* RTE_LIBRTE_EAL_HOTPLUG */
+
/* Init the PCI EAL subsystem */
int
rte_eal_pci_init(void)
{
TAILQ_INIT(&pci_driver_list);
TAILQ_INIT(&pci_device_list);
- pci_res_list = RTE_TAILQ_RESERVE_BY_IDX(RTE_TAILQ_PCI,
- mapped_pci_res_list);
/* for debug purposes, PCI can be disabled */
if (internal_config.no_pci)
return 0;
- if (pci_scan() < 0) {
+ if (rte_eal_pci_scan() < 0) {
RTE_LOG(ERR, EAL, "%s(): Cannot scan PCI bus\n", __func__);
return -1;
}