The patch adds following functions.
- rte_eal_vdev_init();
- rte_eal_vdev_uninit();
- rte_eal_parse_devargs_str().
These functions are used for driver initialization and finalization.
Signed-off-by: Tetsuya Mukawa <mukawa@igel.co.jp>
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <sys/queue.h>
#include <rte_devargs.h>
#include <rte_debug.h>
#include <rte_devargs.h>
+#include <rte_log.h>
#include "eal_private.h"
TAILQ_REMOVE(&dev_driver_list, driver, next);
}
+int
+rte_eal_vdev_init(const char *name, const char *args)
+{
+ struct rte_driver *driver;
+
+ if (name == NULL)
+ return -EINVAL;
+
+ TAILQ_FOREACH(driver, &dev_driver_list, next) {
+ if (driver->type != PMD_VDEV)
+ continue;
+
+ /*
+ * search a driver prefix in virtual device name.
+ * For example, if the driver is pcap PMD, driver->name
+ * will be "eth_pcap", but "name" will be "eth_pcapN".
+ * So use strncmp to compare.
+ */
+ if (!strncmp(driver->name, name, strlen(driver->name)))
+ return driver->init(name, args);
+ }
+
+ RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+ return -EINVAL;
+}
+
int
rte_eal_dev_init(void)
{
if (devargs->type != RTE_DEVTYPE_VIRTUAL)
continue;
- TAILQ_FOREACH(driver, &dev_driver_list, next) {
- if (driver->type != PMD_VDEV)
- continue;
-
- /* search a driver prefix in virtual device name */
- if (!strncmp(driver->name, devargs->virtual.drv_name,
- strlen(driver->name))) {
- driver->init(devargs->virtual.drv_name,
- devargs->args);
- break;
- }
- }
-
- if (driver == NULL) {
- rte_panic("no driver found for %s\n",
- devargs->virtual.drv_name);
+ if (rte_eal_vdev_init(devargs->virtual.drv_name,
+ devargs->args)) {
+ RTE_LOG(ERR, EAL, "failed to initialize %s device\n",
+ devargs->virtual.drv_name);
+ return -1;
}
}
}
return 0;
}
+
+#ifdef RTE_LIBRTE_EAL_HOTPLUG
+int
+rte_eal_vdev_uninit(const char *name)
+{
+ struct rte_driver *driver;
+
+ if (name == NULL)
+ return -EINVAL;
+
+ TAILQ_FOREACH(driver, &dev_driver_list, next) {
+ if (driver->type != PMD_VDEV)
+ continue;
+
+ /*
+ * search a driver prefix in virtual device name.
+ * For example, if the driver is pcap PMD, driver->name
+ * will be "eth_pcap", but "name" will be "eth_pcapN".
+ * So use strncmp to compare.
+ */
+ if (!strncmp(driver->name, name, strlen(driver->name)))
+ return driver->uninit(name);
+ }
+
+ RTE_LOG(ERR, EAL, "no driver found for %s\n", name);
+ return -EINVAL;
+}
+#endif /* RTE_LIBRTE_EAL_HOTPLUG */
struct rte_devargs_list devargs_list =
TAILQ_HEAD_INITIALIZER(devargs_list);
+int
+rte_eal_parse_devargs_str(const char *devargs_str,
+ char **drvname, char **drvargs)
+{
+ char *sep;
+
+ if ((devargs_str) == NULL || (drvname) == NULL || (drvargs == NULL))
+ return -1;
+
+ *drvname = strdup(devargs_str);
+ if (drvname == NULL) {
+ RTE_LOG(ERR, EAL,
+ "cannot allocate temp memory for driver name\n");
+ return -1;
+ }
+
+ /* set the first ',' to '\0' to split name and arguments */
+ sep = strchr(*drvname, ',');
+ if (sep != NULL) {
+ sep[0] = '\0';
+ *drvargs = strdup(sep + 1);
+ } else {
+ *drvargs = strdup("");
+ }
+
+ if (*drvargs == NULL) {
+ RTE_LOG(ERR, EAL,
+ "cannot allocate temp memory for driver arguments\n");
+ free(*drvname);
+ return -1;
+ }
+ return 0;
+}
+
/* store a whitelist parameter for later parsing */
int
rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
{
struct rte_devargs *devargs = NULL;
char *buf = NULL;
- char *sep;
int ret;
/* use malloc instead of rte_malloc as it's called early at init */
memset(devargs, 0, sizeof(*devargs));
devargs->type = devtype;
- buf = strdup(devargs_str);
- if (buf == NULL) {
- RTE_LOG(ERR, EAL, "cannot allocate temp memory for devargs\n");
- goto fail;
- }
-
- /* set the first ',' to '\0' to split name and arguments */
- sep = strchr(buf, ',');
- if (sep != NULL) {
- sep[0] = '\0';
- devargs->args = strdup(sep + 1);
- } else {
- devargs->args = strdup("");
- }
-
- if (devargs->args == NULL) {
- RTE_LOG(ERR, EAL, "cannot allocate for devargs args\n");
+ if (rte_eal_parse_devargs_str(devargs_str, &buf, &devargs->args))
goto fail;
- }
switch (devargs->type) {
case RTE_DEVTYPE_WHITELISTED_PCI:
*/
typedef int (rte_dev_init_t)(const char *name, const char *args);
+/**
+ * Uninitilization function called for each device driver once.
+ */
+typedef int (rte_dev_uninit_t)(const char *name);
+
/**
* Driver type enumeration
*/
enum pmd_type type; /**< PMD Driver type */
const char *name; /**< Driver name. */
rte_dev_init_t *init; /**< Device init. function. */
+ rte_dev_uninit_t *uninit; /**< Device uninit. function. */
};
/**
*/
int rte_eal_dev_init(void);
+/**
+ * Initialize a driver specified by name.
+ *
+ * @param name
+ * The pointer to a driver name to be initialized.
+ * @param args
+ * The pointer to arguments used by driver initialization.
+ * @return
+ * 0 on success, negative on error
+ */
+int rte_eal_vdev_init(const char *name, const char *args);
+
+/**
+ * Uninitalize a driver specified by name.
+ *
+ * @param name
+ * The pointer to a driver name to be initialized.
+ * @return
+ * 0 on success, negative on error
+ */
+int rte_eal_vdev_uninit(const char *name);
+
#define PMD_REGISTER_DRIVER(d)\
void devinitfn_ ##d(void);\
void __attribute__((constructor, used)) devinitfn_ ##d(void)\
/** Global list of user devices */
extern struct rte_devargs_list devargs_list;
+/**
+ * Parse a devargs string.
+ *
+ * For PCI devices, the format of arguments string is "PCI_ADDR" or
+ * "PCI_ADDR,key=val,key2=val2,...". Examples: "08:00.1", "0000:5:00.0",
+ * "04:00.0,arg=val".
+ *
+ * For virtual devices, the format of arguments string is "DRIVER_NAME*"
+ * or "DRIVER_NAME*,key=val,key2=val2,...". Examples: "eth_ring",
+ * "eth_ring0", "eth_pmdAnything,arg=0:arg2=1".
+ *
+ * The function parses the arguments string to get driver name and driver
+ * arguments.
+ *
+ * @param devargs_str
+ * The arguments as given by the user.
+ * @param drvname
+ * The pointer to the string to store parsed driver name.
+ * @param drvargs
+ * The pointer to the string to store parsed driver arguments.
+ *
+ * @return
+ * - 0 on success
+ * - A negative value on error
+ */
+int rte_eal_parse_devargs_str(const char *devargs_str,
+ char **drvname, char **drvargs);
+
/**
* Add a device to the user device list
*
rte_eal_lcore_role;
rte_eal_mp_remote_launch;
rte_eal_mp_wait_lcore;
+ rte_eal_parse_devargs_str;
rte_eal_pci_close_one;
rte_eal_pci_dump;
rte_eal_pci_probe;
rte_eal_tailq_lookup_by_idx;
rte_eal_tailq_reserve;
rte_eal_tailq_reserve_by_idx;
+ rte_eal_vdev_init;
+ rte_eal_vdev_uninit;
rte_eal_wait_lcore;
rte_exit;
rte_get_hpet_cycles;