eal: add hotplug add/remove device

Signed-off-by: Jan Blunck <jblunck@infradead.org>
This commit is contained in:
Jan Blunck 2017-06-30 20:19:41 +02:00 committed by Thomas Monjalon
parent 00e62aae69
commit a3ee360f44
4 changed files with 138 additions and 0 deletions

View File

@ -202,3 +202,11 @@ DPDK_17.08 {
rte_bus_find_by_name;
} DPDK_17.05;
EXPERIMENTAL {
global:
rte_eal_hotplug_add;
rte_eal_hotplug_remove;
} DPDK_17.08;

View File

@ -37,6 +37,7 @@
#include <inttypes.h>
#include <sys/queue.h>
#include <rte_bus.h>
#include <rte_dev.h>
#include <rte_devargs.h>
#include <rte_debug.h>
@ -45,6 +46,25 @@
#include "eal_private.h"
static int cmp_detached_dev_name(const struct rte_device *dev,
const void *_name)
{
const char *name = _name;
/* skip attached devices */
if (dev->driver != NULL)
return 1;
return strcmp(dev->name, name);
}
static int cmp_dev_name(const struct rte_device *dev, const void *_name)
{
const char *name = _name;
return strcmp(dev->name, name);
}
int rte_eal_dev_attach(const char *name, const char *devargs)
{
struct rte_pci_addr addr;
@ -92,3 +112,71 @@ int rte_eal_dev_detach(const char *name)
RTE_LOG(ERR, EAL, "Driver cannot detach the device (%s)\n", name);
return -EINVAL;
}
int rte_eal_hotplug_add(const char *busname, const char *devname,
const char *devargs)
{
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 (bus->plug == NULL) {
RTE_LOG(ERR, EAL, "Function plug not supported by bus (%s)\n",
bus->name);
return -ENOTSUP;
}
ret = bus->scan();
if (ret)
return ret;
dev = bus->find_device(NULL, cmp_detached_dev_name, devname);
if (dev == NULL) {
RTE_LOG(ERR, EAL, "Cannot find unplugged device (%s)\n",
devname);
return -EINVAL;
}
ret = bus->plug(dev, devargs);
if (ret)
RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n",
dev->name);
return ret;
}
int rte_eal_hotplug_remove(const char *busname, const char *devname)
{
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 (bus->unplug == NULL) {
RTE_LOG(ERR, EAL, "Function unplug not supported by bus (%s)\n",
bus->name);
return -ENOTSUP;
}
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;
}
ret = bus->unplug(dev);
if (ret)
RTE_LOG(ERR, EAL, "Driver cannot detach the device (%s)\n",
dev->name);
return ret;
}

View File

@ -191,6 +191,40 @@ int rte_eal_dev_attach(const char *name, const char *devargs);
*/
int rte_eal_dev_detach(const char *name);
/**
* @warning
* @b EXPERIMENTAL: this API may change without prior notice
*
* Hotplug add a given device to a specific bus.
*
* @param busname
* The bus name the device is added to.
* @param devname
* The device name. Based on this device name, eal will identify a driver
* capable of handling it and pass it to the driver probing function.
* @param devargs
* Device arguments to be passed to the driver.
* @return
* 0 on success, negative on error.
*/
int rte_eal_hotplug_add(const char *busname, const char *devname,
const char *devargs);
/**
* @warning
* @b EXPERIMENTAL: this API may change without prior notice
*
* Hotplug remove a given device from a specific bus.
*
* @param busname
* The bus name the device is removed from.
* @param devname
* The device name being removed.
* @return
* 0 on success, negative on error.
*/
int rte_eal_hotplug_remove(const char *busname, const char *devname);
/**
* Device comparison function.
*

View File

@ -207,3 +207,11 @@ DPDK_17.08 {
rte_bus_find_by_name;
} DPDK_17.05;
EXPERIMENTAL {
global:
rte_eal_hotplug_add;
rte_eal_hotplug_remove;
} DPDK_17.08;