To remove assumption, do like followings.

- Add 'attached' member to rte_eth_dev structure.
  This member is used for indicating the port is attached, or not.
- Add rte_eth_dev_allocate_new_port().
  This function is used for allocating new port.

Signed-off-by: Tetsuya Mukawa <mukawa at igel.co.jp>
---
 lib/librte_ether/rte_ethdev.c | 24 ++++++++++++++++++++----
 lib/librte_ether/rte_ethdev.h |  5 +++++
 2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index ff1c769..e37a25a 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -208,12 +208,25 @@ rte_eth_dev_allocated(const char *name)
        return NULL;
 }

+static uint8_t
+rte_eth_dev_allocate_new_port(void)
+{
+       unsigned i;
+
+       for (i = 0; i < RTE_MAX_ETHPORTS; i++)
+               if (!rte_eth_devices[i].attached)
+                       return i;
+       return RTE_MAX_ETHPORTS;
+}
+
 struct rte_eth_dev *
 rte_eth_dev_allocate(const char *name)
 {
+       uint8_t port_id;
        struct rte_eth_dev *eth_dev;

-       if (nb_ports == RTE_MAX_ETHPORTS) {
+       port_id = rte_eth_dev_allocate_new_port();
+       if (port_id == RTE_MAX_ETHPORTS) {
                PMD_DEBUG_TRACE("Reached maximum number of Ethernet ports\n");
                return NULL;
        }
@@ -226,10 +239,12 @@ rte_eth_dev_allocate(const char *name)
                return NULL;
        }

-       eth_dev = &rte_eth_devices[nb_ports];
-       eth_dev->data = &rte_eth_dev_data[nb_ports];
+       eth_dev = &rte_eth_devices[port_id];
+       eth_dev->data = &rte_eth_dev_data[port_id];
        snprintf(eth_dev->data->name, sizeof(eth_dev->data->name), "%s", name);
-       eth_dev->data->port_id = nb_ports++;
+       eth_dev->data->port_id = port_id;
+       eth_dev->attached = 1;
+       nb_ports++;
        return eth_dev;
 }

@@ -283,6 +298,7 @@ rte_eth_dev_init(struct rte_pci_driver *pci_drv,
                        (unsigned) pci_dev->id.device_id);
        if (rte_eal_process_type() == RTE_PROC_PRIMARY)
                rte_free(eth_dev->data->dev_private);
+       eth_dev->attached = 0;
        nb_ports--;
        return diag;
 }
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 8bf274d..5d3956a 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1534,6 +1534,7 @@ struct eth_dev_ops {
  * process, while the actual configuration data for the device is shared.
  */
 struct rte_eth_dev {
+       uint8_t attached; /**< Flag indicating the port is attached */
        eth_rx_burst_t rx_pkt_burst; /**< Pointer to PMD receive function. */
        eth_tx_burst_t tx_pkt_burst; /**< Pointer to PMD transmit function. */
        struct rte_eth_dev_data *data;  /**< Pointer to device data */
@@ -1606,6 +1607,10 @@ extern struct rte_eth_dev rte_eth_devices[];
  * initialized by the [matching] Ethernet driver during the PCI probing phase.
  * All devices whose port identifier is in the range
  * [0,  rte_eth_dev_count() - 1] can be operated on by network applications.
+ * immediately after invoking rte_eal_init().
+ * If the application unplugs a port using hotplug function, The enabled port
+ * numbers may be noncontiguous. In the case, the applications need to manage
+ * enabled port by themselves.
  *
  * @return
  *   - The total number of usable Ethernet devices.
-- 
1.9.1

Reply via email to