[dpdk-dev,16/25] eal/pci: Add port hotplug functions for virtual devices.
Commit Message
The patch adds rte_eal_dev_attach_vdev() and rte_eal_dev_detach_vdev().
rte_eal_dev_attach_vdev() receives virtual device name and parameters,
and returns an attached port number.
rte_eal_dev_detach_vdev() receives a port number, and returns device
name actually detached.
Signed-off-by: Tetsuya Mukawa <mukawa@igel.co.jp>
---
lib/librte_eal/common/eal_common_dev.c | 76 +++++++++++++++++++++++++++++++++
lib/librte_eal/common/include/rte_dev.h | 29 +++++++++++++
2 files changed, 105 insertions(+)
@@ -180,4 +180,80 @@ rte_eal_dev_close_one(const char *name)
{
return rte_eal_dev_find_and_invoke(name, INVOKE_CLOSE);
}
+
+static void
+get_vdev_name(char *vdevargs)
+{
+ char *sep;
+
+ /* set the first ',' to '\0' to split name and arguments */
+ sep = strchr(vdevargs, ',');
+ if (sep != NULL)
+ sep[0] = '\0';
+}
+
+/* attach the new virtual device, then store port_id of the device */
+int
+rte_eal_dev_attach_vdev(const char *vdevargs, uint8_t *port_id)
+{
+ char *args;
+ uint8_t new_port_id;
+ struct rte_eth_dev devs[RTE_MAX_ETHPORTS];
+
+ args = strdup(vdevargs);
+ if (args == NULL)
+ return -1;
+
+ /* save current port status */
+ rte_eth_dev_save(devs);
+ /* add the vdevargs to devargs_list */
+ if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, args))
+ goto err0;
+ /* parse vdevargs, then retrieve device name */
+ get_vdev_name(args);
+ /* walk around dev_driver_list to find the driver of the device,
+ * then invoke probe function o the driver */
+ if (rte_eal_dev_init_one(args))
+ goto err1;
+ /* get port_id enabled by above procedures */
+ if (rte_eth_dev_get_changed_port(devs, &new_port_id))
+ goto err1;
+
+ free(args);
+ *port_id = new_port_id;
+ return 0;
+err1:
+ rte_eal_devargs_remove(RTE_DEVTYPE_VIRTUAL, args);
+err0:
+ RTE_LOG(ERR, EAL, "Drver, cannot detach the device\n");
+ free(args);
+ return -1;
+}
+
+/* detach the new virtual device, then store the name of the device */
+int
+rte_eal_dev_detach_vdev(uint8_t port_id, char *vdevname)
+{
+ char name[RTE_ETH_NAME_MAX_LEN];
+
+ /* check whether the driver supports detach feature, or not */
+ if (!rte_eth_dev_check_detachable(port_id))
+ goto err;
+
+ /* get device name by port id */
+ if (rte_eth_dev_get_name_by_port(port_id, name))
+ goto err;
+ /* walk around dev_driver_list to find the driver of the device,
+ * then invoke close function o the driver */
+ if (rte_eal_dev_close_one(name))
+ goto err;
+ /* remove the vdevname from devargs_list */
+ rte_eal_devargs_remove(RTE_DEVTYPE_VIRTUAL, name);
+
+ strncpy(vdevname, name, sizeof(name));
+ return 0;
+err:
+ RTE_LOG(ERR, EAL, "Drver, cannot detach the device\n");
+ return -1;
+}
#endif /* RTE_LIBRTE_EAL_HOTPLUG & RTE_LIBRTE_EAL_LINUXAPP */
@@ -98,6 +98,35 @@ void rte_eal_driver_register(struct rte_driver *driver);
*/
void rte_eal_driver_unregister(struct rte_driver *driver);
+#if defined(RTE_LIBRTE_EAL_HOTPLUG) && defined(RTE_LIBRTE_EAL_LINUXAPP)
+
+/**
+ * Attach a new virtual device.
+ *
+ * @param vdevargs
+ * A pointer to a strings array describing the new device
+ * to be attached.
+ * @param port_id
+ * A pointer to a port identifier actually attached.
+ * @return
+ * 0 on success and port_id is filled, negative on error
+ */
+int rte_eal_dev_attach_vdev(const char *vdevargs, uint8_t *port_id);
+
+/**
+ * Detach a virtual device.
+ *
+ * @param port_id
+ * The port identifier of the virtual device to detach.
+ * @param addr
+ * A pointer to a virtual device name actually detached.
+ * @return
+ * 0 on success and vdevname is filled, negative on error
+ */
+int rte_eal_dev_detach_vdev(uint8_t port_id, char *vdevname);
+
+#endif /* RTE_LIBRTE_EAL_HOTPLUG & RTE_LIBRTE_EAL_LINUXAPP */
+
/**
* Initalize all the registered drivers in this process
*/