X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_eal%2Fcommon%2Feal_common_dev.c;h=fc8a4d2278ea2fac0e60da14cefba5ae49891bb3;hb=7b681637d26eb91c1253c03e3d0268a7e3e29b66;hp=555e0d9f44c756636c13b11686c9beee7e484084;hpb=a16040453968e0b397cf1bc4ce3e2b25d3deb561;p=dpdk.git diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c index 555e0d9f44..fc8a4d2278 100644 --- a/lib/librte_eal/common/eal_common_dev.c +++ b/lib/librte_eal/common/eal_common_dev.c @@ -37,112 +37,210 @@ #include #include +#include #include #include #include -#include #include #include "eal_private.h" -/** Global list of device drivers. */ -static struct rte_driver_list dev_driver_list = - TAILQ_HEAD_INITIALIZER(dev_driver_list); - -/* register a driver */ -void -rte_eal_driver_register(struct rte_driver *driver) +static int cmp_detached_dev_name(const struct rte_device *dev, + const void *_name) { - TAILQ_INSERT_TAIL(&dev_driver_list, driver, next); + const char *name = _name; + + /* skip attached devices */ + if (dev->driver != NULL) + return 1; + + return strcmp(dev->name, name); } -/* unregister a driver */ -void -rte_eal_driver_unregister(struct rte_driver *driver) +static int cmp_dev_name(const struct rte_device *dev, const void *_name) { - TAILQ_REMOVE(&dev_driver_list, driver, next); + const char *name = _name; + + return strcmp(dev->name, name); } -int -rte_eal_dev_init(void) +int rte_eal_dev_attach(const char *name, const char *devargs) { - struct rte_devargs *devargs; - struct rte_driver *driver; + struct rte_bus *bus; + int ret; + + if (name == NULL || devargs == NULL) { + RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n"); + return -EINVAL; + } + + bus = rte_bus_find_by_device_name(name); + if (bus == NULL) { + RTE_LOG(ERR, EAL, "Unable to find a bus for the device '%s'\n", + name); + return -EINVAL; + } + if (strcmp(bus->name, "pci") == 0) + return rte_eal_hotplug_add("pci", name, devargs); + if (strcmp(bus->name, "vdev") != 0) { + RTE_LOG(ERR, EAL, "Device attach is only supported for PCI and vdev devices.\n"); + return -ENOTSUP; + } /* - * Note that the dev_driver_list is populated here - * from calls made to rte_eal_driver_register from constructor functions - * embedded into PMD modules via the DRIVER_REGISTER_VDEV macro + * If we haven't found a bus device the user meant to "hotplug" a + * virtual device instead. */ + ret = rte_vdev_init(name, devargs); + if (ret) + RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n", + name); + return ret; +} - /* call the init function for each virtual device */ - TAILQ_FOREACH(devargs, &devargs_list, next) { +int rte_eal_dev_detach(struct rte_device *dev) +{ + struct rte_bus *bus; + int ret; - if (devargs->type != RTE_DEVTYPE_VIRTUAL) - continue; + if (dev == NULL) { + RTE_LOG(ERR, EAL, "Invalid device provided.\n"); + return -EINVAL; + } - if (rte_eal_vdev_init(devargs->virt.drv_name, - devargs->args)) { - RTE_LOG(ERR, EAL, "failed to initialize %s device\n", - devargs->virt.drv_name); - return -1; - } + bus = rte_bus_find_by_device(dev); + if (bus == NULL) { + RTE_LOG(ERR, EAL, "Cannot find bus for device (%s)\n", + dev->name); + return -EINVAL; } - /* Once the vdevs are initalized, start calling all the pdev drivers */ - TAILQ_FOREACH(driver, &dev_driver_list, next) { - if (driver->type != PMD_PDEV) - continue; - /* PDEV drivers don't get passed any parameters */ - driver->init(NULL, NULL); + if (bus->unplug == NULL) { + RTE_LOG(ERR, EAL, "Bus function not supported\n"); + return -ENOTSUP; } - return 0; + + ret = bus->unplug(dev); + if (ret) + RTE_LOG(ERR, EAL, "Driver cannot detach the device (%s)\n", + dev->name); + return ret; } -int rte_eal_dev_attach(const char *name, const char *devargs) +static char * +full_dev_name(const char *bus, const char *dev, const char *args) { - struct rte_pci_addr addr; + char *name; + size_t len; - if (name == NULL || devargs == NULL) { - RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n"); - return -EINVAL; + len = snprintf(NULL, 0, "%s:%s,%s", bus, dev, args); + name = calloc(1, len); + if (name == NULL) { + RTE_LOG(ERR, EAL, "Could not allocate full device name\n"); + return NULL; + } + snprintf(name, len, "%s:%s,%s", bus, dev, args); + return name; +} + +int rte_eal_hotplug_add(const char *busname, const char *devname, + const char *devargs) +{ + struct rte_bus *bus; + struct rte_device *dev; + struct rte_devargs *da; + char *name; + int ret; + + bus = rte_bus_find_by_name(busname); + if (bus == NULL) { + RTE_LOG(ERR, EAL, "Cannot find bus (%s)\n", busname); + return -ENOENT; + } + + if (bus->plug == NULL) { + RTE_LOG(ERR, EAL, "Function plug not supported by bus (%s)\n", + bus->name); + return -ENOTSUP; } - if (eal_parse_pci_DomBDF(name, &addr) == 0) { - if (rte_eal_pci_probe_one(&addr) < 0) - goto err; + name = full_dev_name(busname, devname, devargs); + if (name == NULL) + return -ENOMEM; - } else { - if (rte_eal_vdev_init(name, devargs)) - goto err; + da = calloc(1, sizeof(*da)); + if (da == NULL) { + ret = -ENOMEM; + goto err_name; } + ret = rte_eal_devargs_parse(name, da); + if (ret) + goto err_devarg; + + ret = rte_eal_devargs_insert(da); + if (ret) + goto err_devarg; + + ret = bus->scan(); + if (ret) + goto err_devarg; + + dev = bus->find_device(NULL, cmp_detached_dev_name, devname); + if (dev == NULL) { + RTE_LOG(ERR, EAL, "Cannot find unplugged device (%s)\n", + devname); + ret = -ENODEV; + goto err_devarg; + } + + ret = bus->plug(dev); + if (ret) { + RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n", + dev->name); + goto err_devarg; + } + free(name); return 0; -err: - RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n", name); - return -EINVAL; +err_devarg: + if (rte_eal_devargs_remove(busname, devname)) { + free(da->args); + free(da); + } +err_name: + free(name); + return ret; } -int rte_eal_dev_detach(const char *name) +int rte_eal_hotplug_remove(const char *busname, const char *devname) { - struct rte_pci_addr addr; + struct rte_bus *bus; + struct rte_device *dev; + int ret; + + bus = rte_bus_find_by_name(busname); + if (bus == NULL) { + RTE_LOG(ERR, EAL, "Cannot find bus (%s)\n", busname); + return -ENOENT; + } - if (name == NULL) { - RTE_LOG(ERR, EAL, "Invalid device provided.\n"); - return -EINVAL; + if (bus->unplug == NULL) { + RTE_LOG(ERR, EAL, "Function unplug not supported by bus (%s)\n", + bus->name); + return -ENOTSUP; } - if (eal_parse_pci_DomBDF(name, &addr) == 0) { - if (rte_eal_pci_detach(&addr) < 0) - goto err; - } else { - if (rte_eal_vdev_uninit(name)) - goto err; + dev = bus->find_device(NULL, cmp_dev_name, devname); + if (dev == NULL) { + RTE_LOG(ERR, EAL, "Cannot find plugged device (%s)\n", devname); + return -EINVAL; } - return 0; -err: - RTE_LOG(ERR, EAL, "Driver cannot detach the device (%s)\n", name); - return -EINVAL; + ret = bus->unplug(dev); + if (ret) + RTE_LOG(ERR, EAL, "Driver cannot detach the device (%s)\n", + dev->name); + rte_eal_devargs_remove(busname, devname); + return ret; }