[dpdk-dev] [RFC PATCH v2 24/28] eal/pci: Add port hotplug functions for physical devices.

Tetsuya Mukawa mukawa at igel.co.jp
Tue Nov 4 04:45:44 CET 2014


The patch adds rte_eal_dev_attach_pdev() and rte_eal_dev_detach_pdev().

rte_eal_dev_attach_pdev() receives a PCI address of the device and
returns an attached port number.
rte_eal_dev_detach_pdev() receives a port number, and returns a PCI
address actually detached.

Signed-off-by: Tetsuya Mukawa <mukawa at igel.co.jp>
---
 lib/librte_eal/common/eal_common_dev.c  | 58 +++++++++++++++++++++++++++++++++
 lib/librte_eal/common/include/rte_dev.h | 25 ++++++++++++++
 2 files changed, 83 insertions(+)

diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 0518e3c..c2d5cd6 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -181,6 +181,64 @@ rte_eal_dev_close_one(const char *name)
 	return rte_eal_dev_find_and_invoke(name, INVOKE_CLOSE);
 }
 
+/* attach the new physical device, then store port_id of the device */
+int
+rte_eal_dev_attach_pdev(struct rte_pci_addr *addr, uint8_t *port_id)
+{
+	uint8_t new_port_id;
+	struct rte_eth_dev devs[RTE_MAX_ETHPORTS];
+
+	/* save current port status */
+	rte_eth_dev_save(devs);
+	/* re-construct pci_device_list */
+	if (rte_eal_pci_scan())
+		goto err;
+	/* invoke probe func of the driver can handle the new device */
+	if (rte_eal_pci_probe_one(addr))
+		goto err;
+	/* get port_id enabled by above procedures */
+	if (rte_eth_dev_get_changed_port(devs, &new_port_id))
+		goto err;
+
+	*port_id = new_port_id;
+	return 0;
+err:
+	RTE_LOG(ERR, EAL, "Drver, cannot attach the device\n");
+	return -1;
+}
+
+/* detach the new physical device, then store pci_addr of the device */
+int
+rte_eal_dev_detach_pdev(uint8_t port_id, struct rte_pci_addr *addr)
+{
+	struct rte_pci_addr freed_addr;
+	struct rte_pci_addr vp;
+
+	/* check whether the driver supports detach feature, or not */
+	if (!rte_eth_dev_check_detachable(port_id))
+		goto err;
+
+	/* get pci address by port id */
+	if (rte_eth_dev_get_addr_by_port(port_id, &freed_addr))
+		goto err;
+
+	/* Zerod pci addr means the port comes from virtual device */
+	vp.domain = vp.bus = vp.devid = vp.function = 0;
+	if (eal_compare_pci_addr(&vp, &freed_addr) == 0)
+		goto err;
+
+	/* invoke close func of the driver,
+	 * also remove the device from pci_device_list */
+	if (rte_eal_pci_close_one(&freed_addr))
+		goto err;
+
+	*addr = freed_addr;
+	return 0;
+err:
+	RTE_LOG(ERR, EAL, "Drver, cannot detach the device\n");
+	return -1;
+}
+
 static void
 get_vdev_name(char *vdevargs)
 {
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 159d5a5..26d7526 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -101,6 +101,19 @@ void rte_eal_driver_unregister(struct rte_driver *driver);
 #if defined(RTE_LIBRTE_EAL_HOTPLUG) && defined(RTE_LIBRTE_EAL_LINUXAPP)
 
 /**
+ * Attach a new physical device.
+ *
+ * @param addr
+ *   A pointer to a pci address structure 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_pdev(struct rte_pci_addr *addr, uint8_t *port_id);
+
+/**
  * Attach a new virtual device.
  *
  * @param vdevargs
@@ -114,6 +127,18 @@ void rte_eal_driver_unregister(struct rte_driver *driver);
 int rte_eal_dev_attach_vdev(const char *vdevargs, uint8_t *port_id);
 
 /**
+ * Detach a physical device.
+ *
+ * @param port_id
+ *   The port identifier of the physical device to detach.
+ * @param addr
+ *  A pointer to a pci address structure actually detached.
+ * @return
+ *  0 on success and addr is filled, negative on error
+ */
+int rte_eal_dev_detach_pdev(uint8_t port_id, struct rte_pci_addr *addr);
+
+/**
  * Detach a virtual device.
  *
  * @param port_id
-- 
1.9.1



More information about the dev mailing list