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