X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_eal%2Fcommon%2Feal_common_pci.c;h=609c424ceeaca41aa480a931511d7d5913c2c7c9;hb=13a1317d3ba7;hp=8ef805736d6f1766c2e2922357f368aeb2c64095;hpb=4d4ebca430474180cdc5cb14edfda04ee4189d19;p=dpdk.git diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c index 8ef805736d..609c424cee 100644 --- a/lib/librte_eal/common/eal_common_pci.c +++ b/lib/librte_eal/common/eal_common_pci.c @@ -82,8 +82,23 @@ #include "eal_private.h" -struct pci_driver_list pci_driver_list; -struct pci_device_list pci_device_list; +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) +{ + const char *path = NULL; + + path = getenv("SYSFS_PCI_DEVICES"); + if (path == NULL) + return SYSFS_PCI_DEVICES; + + return path; +} static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev) { @@ -137,65 +152,8 @@ pci_unmap_resource(void *requested_addr, size_t size) requested_addr); } -/* Map pci device */ -static int -pci_map_device(struct rte_pci_device *dev) -{ - int ret = -1; - - /* try mapping the NIC resources using VFIO if it exists */ - 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_KDRV_IGB_UIO: - case RTE_KDRV_UIO_GENERIC: - case RTE_KDRV_NIC_UIO: - /* map resources for devices that use uio */ - ret = pci_uio_map_resource(dev); - break; - default: - RTE_LOG(DEBUG, EAL, " Not managed by a supported kernel driver," - " skipped\n"); - ret = 1; - break; - } - - return ret; -} - -#ifdef RTE_LIBRTE_EAL_HOTPLUG -/* Unmap pci device */ -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: - case RTE_KDRV_NIC_UIO: - /* 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 + * If vendor/device ID match, call the probe() function of the * driver. */ static int @@ -219,33 +177,30 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *d if (id_table->subsystem_device_id != dev->id.subsystem_device_id && id_table->subsystem_device_id != PCI_ANY_ID) continue; + if (id_table->class_id != dev->id.class_id && + id_table->class_id != RTE_CLASS_ANY_ID) + continue; struct rte_pci_addr *loc = &dev->addr; - RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n", + 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); - - RTE_LOG(DEBUG, EAL, " probe driver: %x:%x %s\n", dev->id.vendor_id, - dev->id.device_id, dr->name); + dev->device.numa_node); /* no initialization when blacklisted, return without error */ - if (dev->devargs != NULL && - dev->devargs->type == RTE_DEVTYPE_BLACKLISTED_PCI) { - RTE_LOG(DEBUG, EAL, " Device is blacklisted, not initializing\n"); + 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; } + RTE_LOG(INFO, EAL, " probe driver: %x:%x %s\n", dev->id.vendor_id, + dev->id.device_id, dr->driver.name); + if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) { -#ifdef RTE_PCI_CONFIG - /* - * Set PCIe config space for high performance. - * Return value can be ignored. - */ - pci_config_space_set(dev); -#endif /* map resources for devices that use igb_uio */ - ret = pci_map_device(dev); + ret = rte_eal_pci_map_device(dev); if (ret != 0) return ret; } else if (dr->drv_flags & RTE_PCI_DRV_FORCE_UNBIND && @@ -258,20 +213,19 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *d /* reference driver structure */ dev->driver = dr; - /* call the driver devinit() function */ - return dr->devinit(dr, dev); + /* call the driver probe() function */ + return dr->probe(dr, dev); } - /* return positive value if driver is not found */ + /* return positive value if driver doesn't support this device */ return 1; } -#ifdef RTE_LIBRTE_EAL_HOTPLUG /* - * If vendor/device ID match, call the devuninit() function of the + * If vendor/device ID match, call the remove() function of the * driver. */ static int -rte_eal_pci_close_one_driver(struct rte_pci_driver *dr, +rte_eal_pci_detach_dev(struct rte_pci_driver *dr, struct rte_pci_device *dev) { const struct rte_pci_id *id_table; @@ -299,13 +253,12 @@ rte_eal_pci_close_one_driver(struct rte_pci_driver *dr, 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->name); + dev->id.device_id, dr->driver.name); - /* call the driver devuninit() function */ - if (dr->devuninit && (dr->devuninit(dev) < 0)) + if (dr->remove && (dr->remove(dev) < 0)) return -1; /* negative value is an error */ /* clear driver structure */ @@ -313,18 +266,17 @@ rte_eal_pci_close_one_driver(struct rte_pci_driver *dr, if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) /* unmap resources for devices that use igb_uio */ - pci_unmap_device(dev); + rte_eal_pci_unmap_device(dev); return 0; } - /* return positive value if driver is not found */ + /* return positive value if driver doesn't support this device */ return 1; } -#endif /* RTE_LIBRTE_EAL_HOTPLUG */ /* - * If vendor/device ID match, call the devinit() function of all + * If vendor/device ID match, call the probe() function of all * registered driver for the given device. Return -1 if initialization * failed, return 1 if no driver is found for this device. */ @@ -343,21 +295,20 @@ pci_probe_all_drivers(struct rte_pci_device *dev) /* negative value is an error */ return -1; if (rc > 0) - /* positive value means driver not found */ + /* positive value means driver doesn't support it */ continue; return 0; } return 1; } -#ifdef RTE_LIBRTE_EAL_HOTPLUG /* - * If vendor/device ID match, call the devuninit() function of all + * If vendor/device ID match, call the remove() function of all * registered driver for the given device. Return -1 if initialization * failed, return 1 if no driver is found for this device. */ static int -pci_close_all_drivers(struct rte_pci_device *dev) +pci_detach_all_drivers(struct rte_pci_device *dev) { struct rte_pci_driver *dr = NULL; int rc = 0; @@ -366,12 +317,12 @@ pci_close_all_drivers(struct rte_pci_device *dev) return -1; TAILQ_FOREACH(dr, &pci_driver_list, next) { - rc = rte_eal_pci_close_one_driver(dr, dev); + rc = rte_eal_pci_detach_dev(dr, dev); if (rc < 0) /* negative value is an error */ return -1; if (rc > 0) - /* positive value means driver not found */ + /* positive value means driver doesn't support it */ continue; return 0; } @@ -391,6 +342,12 @@ rte_eal_pci_probe_one(const struct rte_pci_addr *addr) if (addr == NULL) 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) + goto err_return; + TAILQ_FOREACH(dev, &pci_device_list, next) { if (rte_eal_compare_pci_addr(&dev->addr, addr)) continue; @@ -403,18 +360,17 @@ rte_eal_pci_probe_one(const struct rte_pci_addr *addr) return -1; err_return: - RTE_LOG(WARNING, EAL, "Requested device " PCI_PRI_FMT - " cannot be used\n", dev->addr.domain, dev->addr.bus, - dev->addr.devid, dev->addr.function); + RTE_LOG(WARNING, EAL, + "Requested device " PCI_PRI_FMT " cannot be used\n", + addr->domain, addr->bus, addr->devid, addr->function); return -1; } /* - * Find the pci device specified by pci address, then invoke close function of - * the driver of the devive. + * Detach device specified by its pci address. */ int -rte_eal_pci_close_one(const struct rte_pci_addr *addr) +rte_eal_pci_detach(const struct rte_pci_addr *addr) { struct rte_pci_device *dev = NULL; int ret = 0; @@ -426,7 +382,7 @@ rte_eal_pci_close_one(const struct rte_pci_addr *addr) if (rte_eal_compare_pci_addr(&dev->addr, addr)) continue; - ret = pci_close_all_drivers(dev); + ret = pci_detach_all_drivers(dev); if (ret < 0) goto err_return; @@ -441,10 +397,9 @@ err_return: dev->addr.devid, dev->addr.function); return -1; } -#endif /* RTE_LIBRTE_EAL_HOTPLUG */ /* - * Scan the content of the PCI bus, and call the devinit() function for + * 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. */ @@ -464,7 +419,7 @@ rte_eal_pci_probe(void) /* 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) @@ -517,11 +472,13 @@ void 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); }