[dpdk-dev,16/25] eal/pci: Add port hotplug functions for virtual devices.

Message ID 1416474399-16851-17-git-send-email-mukawa@igel.co.jp (mailing list archive)
State Superseded, archived
Headers

Commit Message

Tetsuya Mukawa Nov. 20, 2014, 9:06 a.m. UTC
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(+)
  

Patch

diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 183d65b..0518e3c 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -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 */
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 71d40c3..159d5a5 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -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
  */