This functions wraps attaching and detaching functions for physical and virtual
device.
When rte_eal_dev_attach() is called, the function tries to
realize the device name as pci address. If this is done successfully,
rte_eal_dev_attach() will call rte_eal_dev_attach_pdev(). If not, calls
rte_eal_dev_attach_vdev().
When rte_eal_dev_detach() is called, the function gets the device type of
this port to know whether the port is came from physical or virtual. And
then rte_eal_dev_detach_pdev() or rte_eal_dev_detach_vdev() will be called.

Signed-off-by: Tetsuya Mukawa <mukawa at igel.co.jp>
---
 app/test/virtual_pmd.c                       |  2 +-
 lib/librte_eal/common/eal_common_dev.c       | 34 ++++++++++++++++++++++++++++
 lib/librte_eal/common/include/rte_dev.h      | 25 ++++++++++++++++++++
 lib/librte_ether/rte_ethdev.c                | 14 ++++++++++--
 lib/librte_ether/rte_ethdev.h                | 24 +++++++++++++++++++-
 lib/librte_pmd_af_packet/rte_eth_af_packet.c |  2 +-
 lib/librte_pmd_bond/rte_eth_bond_api.c       |  2 +-
 lib/librte_pmd_pcap/rte_eth_pcap.c           |  2 +-
 lib/librte_pmd_ring/rte_eth_ring.c           |  2 +-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.c     |  2 +-
 10 files changed, 100 insertions(+), 9 deletions(-)

diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c
index ade6cb0..ff8f747 100644
--- a/app/test/virtual_pmd.c
+++ b/app/test/virtual_pmd.c
@@ -556,7 +556,7 @@ virtual_ethdev_create(const char *name, struct ether_addr 
*mac_addr,
                goto err;

        /* reserve an ethdev entry */
-       eth_dev = rte_eth_dev_allocate(name);
+       eth_dev = rte_eth_dev_allocate(name, RTE_ETH_DEV_PHYSICAL);
        if (eth_dev == NULL)
                goto err;

diff --git a/lib/librte_eal/common/eal_common_dev.c 
b/lib/librte_eal/common/eal_common_dev.c
index 9ff03ed..c9d4894 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -322,4 +322,38 @@ err:
        RTE_LOG(ERR, EAL, "Drver, cannot detach the device\n");
        return -1;
 }
+
+/* attach the new device, then store port_id of the device */
+int
+rte_eal_dev_attach(const char *devargs, uint8_t *port_id)
+{
+       struct rte_pci_addr addr;
+
+       if (eal_parse_pci_DomBDF(devargs, &addr) == 0)
+               return rte_eal_dev_attach_pdev(&addr, port_id);
+       else
+               return rte_eal_dev_attach_vdev(devargs, port_id);
+}
+
+/* detach the device, then store the name of the device */
+int
+rte_eal_dev_detach(uint8_t port_id, char *name)
+{
+       struct rte_pci_addr addr;
+       int ret;
+
+       if (rte_eth_dev_get_device_type(port_id) == RTE_ETH_DEV_PHYSICAL) {
+               ret = rte_eth_dev_get_addr_by_port(port_id, &addr);
+               if (ret < 0)
+                       return ret;
+
+               ret = rte_eal_dev_detach_pdev(port_id, &addr);
+               if (ret == 0)
+                       snprintf(name, RTE_ETH_NAME_MAX_LEN, 
"%04x.%02x.%02x.%d",
+                               addr.domain, addr.bus, addr.devid, 
addr.function);
+
+               return ret;
+       } else
+               return rte_eal_dev_detach_vdev(port_id, name);
+}
 #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 f0677cb..1f8f24a 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -151,6 +151,31 @@ int rte_eal_dev_detach_pdev(uint8_t port_id, struct 
rte_pci_addr *addr);
  */
 int rte_eal_dev_detach_vdev(uint8_t port_id, char *vdevname);

+/**
+ * Attach a new device.
+ *
+ * @param devargs
+ *   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(const char *devargs, uint8_t *port_id);
+
+/**
+ * Detach a device.
+ *
+ * @param port_id
+ *   The port identifier of the device to detach.
+ * @param addr
+ *  A pointer to a device name actually detached.
+ * @return
+ *  0 on success and devname is filled, negative on error
+ */
+int rte_eal_dev_detach(uint8_t port_id, char *devname);
+
 #endif /* RTE_LIBRTE_EAL_HOTPLUG & RTE_LIBRTE_EAL_LINUXAPP */

 /**
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 86200e0..cd5ef67 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -232,7 +232,7 @@ rte_eth_dev_allocate_new_port(void)
 }

 struct rte_eth_dev *
-rte_eth_dev_allocate(const char *name)
+rte_eth_dev_allocate(const char *name, enum rte_eth_dev_type type)
 {
        uint8_t port_id;
        struct rte_eth_dev *eth_dev;
@@ -256,6 +256,7 @@ rte_eth_dev_allocate(const char *name)
        snprintf(eth_dev->data->name, sizeof(eth_dev->data->name), "%s", name);
        eth_dev->data->port_id = port_id;
        eth_dev->attached = DEV_CONNECTED;
+       eth_dev->dev_type = type;
        nb_ports++;
        return eth_dev;
 }
@@ -273,6 +274,7 @@ rte_eth_dev_free(const char *name)
        }

        eth_dev->attached = 0;
+       eth_dev->dev_type = RTE_ETH_DEV_UNKNOWN;
        nb_ports--;
        return eth_dev;
 }
@@ -293,7 +295,7 @@ rte_eth_dev_init(struct rte_pci_driver *pci_drv,
        snprintf(ethdev_name, RTE_ETH_NAME_MAX_LEN, "%d:%d.%d",
                        pci_dev->addr.bus, pci_dev->addr.devid, 
pci_dev->addr.function);

-       eth_dev = rte_eth_dev_allocate(ethdev_name);
+       eth_dev = rte_eth_dev_allocate(ethdev_name, RTE_ETH_DEV_PHYSICAL);
        if (eth_dev == NULL)
                return -ENOMEM;

@@ -416,6 +418,14 @@ rte_eth_dev_count(void)
        return (nb_ports);
 }

+enum rte_eth_dev_type
+rte_eth_dev_get_device_type(uint8_t port_id)
+{
+       if (rte_eth_dev_validate_port(port_id) == DEV_INVALID)
+               return -1;
+       return rte_eth_devices[port_id].dev_type;
+}
+
 void
 rte_eth_dev_save(struct rte_eth_dev *devs)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 47622a2..0d500eb 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1548,6 +1548,16 @@ struct eth_dev_ops {
 };

 /**
+ * The eth device type
+ */
+enum rte_eth_dev_type {
+       RTE_ETH_DEV_UNKNOWN,    /**< unknown device type */
+       RTE_ETH_DEV_PHYSICAL,   /**< physical device type */
+       RTE_ETH_DEV_VIRTUAL,    /**< virtual device type */
+       RTE_ETH_DEV_MAX         /**< max value of this enum */
+};
+
+/**
  * @internal
  * The generic data structure associated with each ethernet device.
  *
@@ -1566,6 +1576,7 @@ struct rte_eth_dev {
        struct rte_pci_device *pci_dev; /**< PCI info. supplied by probing */
        struct rte_eth_dev_cb_list callbacks; /**< User application callbacks */
        uint8_t attached; /**< Flag indicating the port is attached */
+       enum rte_eth_dev_type dev_type; /**< Flag indicating the device type */
 };

 struct rte_eth_dev_sriov {
@@ -1643,6 +1654,15 @@ extern uint8_t rte_eth_dev_count(void);

 /**
  * Function for internal use by port hotplug functions.
+ * Get the device type to know whether the device is physical or virtual.
+ *
+ * @return
+ *   - Device type.
+ */
+extern enum rte_eth_dev_type rte_eth_dev_get_device_type(uint8_t port_id);
+
+/**
+ * Function for internal use by port hotplug functions.
  * Copies current ethdev structures to the specified pointer.
  *
  * @param      devs    The pointer to the ethdev structures
@@ -1728,10 +1748,12 @@ extern struct rte_eth_dev *rte_eth_dev_allocated(const 
char *name);
  * to that slot for the driver to use.
  *
  * @param      name    Unique identifier name for each Ethernet device
+ * @param      type    Device type of this Ethernet device
  * @return
  *   - Slot in the rte_dev_devices array for a new device;
  */
-struct rte_eth_dev *rte_eth_dev_allocate(const char *name);
+struct rte_eth_dev *rte_eth_dev_allocate(const char *name,
+               enum rte_eth_dev_type type);

 /**
  * Function for internal use by dummy drivers primarily, e.g. ring-based
diff --git a/lib/librte_pmd_af_packet/rte_eth_af_packet.c 
b/lib/librte_pmd_af_packet/rte_eth_af_packet.c
index d0fb3eb..1237903 100644
--- a/lib/librte_pmd_af_packet/rte_eth_af_packet.c
+++ b/lib/librte_pmd_af_packet/rte_eth_af_packet.c
@@ -642,7 +642,7 @@ rte_pmd_init_internals(const char *name,
        }

        /* reserve an ethdev entry */
-       *eth_dev = rte_eth_dev_allocate(name);
+       *eth_dev = rte_eth_dev_allocate(name, RTE_ETH_DEV_VIRTUAL);
        if (*eth_dev == NULL)
                goto error;

diff --git a/lib/librte_pmd_bond/rte_eth_bond_api.c 
b/lib/librte_pmd_bond/rte_eth_bond_api.c
index ef5ddf4..a6986e3 100644
--- a/lib/librte_pmd_bond/rte_eth_bond_api.c
+++ b/lib/librte_pmd_bond/rte_eth_bond_api.c
@@ -231,7 +231,7 @@ rte_eth_bond_create(const char *name, uint8_t mode, uint8_t 
socket_id)
        }

        /* reserve an ethdev entry */
-       eth_dev = rte_eth_dev_allocate(name);
+       eth_dev = rte_eth_dev_allocate(name, RTE_ETH_DEV_VIRTUAL);
        if (eth_dev == NULL) {
                RTE_BOND_LOG(ERR, "Unable to allocate rte_eth_dev");
                goto err;
diff --git a/lib/librte_pmd_pcap/rte_eth_pcap.c 
b/lib/librte_pmd_pcap/rte_eth_pcap.c
index f12d1e7..0f34f73 100644
--- a/lib/librte_pmd_pcap/rte_eth_pcap.c
+++ b/lib/librte_pmd_pcap/rte_eth_pcap.c
@@ -710,7 +710,7 @@ rte_pmd_init_internals(const char *name, const unsigned 
nb_rx_queues,
                goto error;

        /* reserve an ethdev entry */
-       *eth_dev = rte_eth_dev_allocate(name);
+       *eth_dev = rte_eth_dev_allocate(name, VIRTUAL);
        if (*eth_dev == NULL)
                goto error;

diff --git a/lib/librte_pmd_ring/rte_eth_ring.c 
b/lib/librte_pmd_ring/rte_eth_ring.c
index 4f1b6ed..d901053 100644
--- a/lib/librte_pmd_ring/rte_eth_ring.c
+++ b/lib/librte_pmd_ring/rte_eth_ring.c
@@ -256,7 +256,7 @@ rte_eth_from_rings(const char *name, struct rte_ring *const 
rx_queues[],
                goto error;

        /* reserve an ethdev entry */
-       eth_dev = rte_eth_dev_allocate(name);
+       eth_dev = rte_eth_dev_allocate(name, RTE_ETH_DEV_VIRTUAL);
        if (eth_dev == NULL)
                goto error;

diff --git a/lib/librte_pmd_xenvirt/rte_eth_xenvirt.c 
b/lib/librte_pmd_xenvirt/rte_eth_xenvirt.c
index 6555ec5..4f0eda5 100644
--- a/lib/librte_pmd_xenvirt/rte_eth_xenvirt.c
+++ b/lib/librte_pmd_xenvirt/rte_eth_xenvirt.c
@@ -647,7 +647,7 @@ eth_dev_xenvirt_create(const char *name, const char *params,
                goto err;

        /* reserve an ethdev entry */
-       eth_dev = rte_eth_dev_allocate(name);
+       eth_dev = rte_eth_dev_allocate(name, VIRTUAL);
        if (eth_dev == NULL)
                goto err;

-- 
1.9.1

Reply via email to