[PATCH 12/23] bus: refactor device probe
David Marchand
david.marchand at redhat.com
Wed Apr 29 13:44:45 CEST 2026
Introduce a new rte_bus_probe_device_t operation with signature
(struct rte_driver *drv, struct rte_device *dev).
Replace the existing .plug field in the struct rte_bus with .probe_device.
Update all in-tree buses to use .probe_device instead of .plug.
Each bus probe() function now calls rte_bus_find_driver() (which uses the
match operation added in previous commit) and passes the found driver
to bus.probe_device(driver, device).
Signed-off-by: David Marchand <david.marchand at redhat.com>
---
drivers/bus/auxiliary/auxiliary_common.c | 98 ++++++---------
drivers/bus/cdx/cdx.c | 81 +++++--------
drivers/bus/dpaa/dpaa_bus.c | 63 +++++-----
drivers/bus/fslmc/fslmc_bus.c | 73 +++++-------
drivers/bus/ifpga/ifpga_bus.c | 68 ++++-------
drivers/bus/pci/pci_common.c | 145 +++++++++--------------
drivers/bus/platform/platform.c | 38 +++---
drivers/bus/uacce/uacce.c | 67 ++++-------
drivers/bus/vdev/vdev.c | 58 +++++----
drivers/bus/vmbus/vmbus_common.c | 84 ++++++-------
drivers/dma/idxd/idxd_bus.c | 23 ++--
lib/eal/common/eal_common_bus.c | 5 +-
lib/eal/common/eal_common_dev.c | 14 ++-
lib/eal/include/bus_driver.h | 17 ++-
14 files changed, 354 insertions(+), 480 deletions(-)
diff --git a/drivers/bus/auxiliary/auxiliary_common.c b/drivers/bus/auxiliary/auxiliary_common.c
index 21b5bcb416..7824c26f92 100644
--- a/drivers/bus/auxiliary/auxiliary_common.c
+++ b/drivers/bus/auxiliary/auxiliary_common.c
@@ -74,61 +74,60 @@ auxiliary_bus_match(const struct rte_driver *drv, const struct rte_device *dev)
* Call the probe() function of the driver.
*/
static int
-rte_auxiliary_probe_one_driver(struct rte_auxiliary_driver *drv,
- struct rte_auxiliary_device *dev)
+auxiliary_probe_device(struct rte_driver *drv, struct rte_device *dev)
{
+ struct rte_auxiliary_device *aux_dev = RTE_BUS_DEVICE(dev, *aux_dev);
+ struct rte_auxiliary_driver *aux_drv = RTE_BUS_DRIVER(drv, *aux_drv);
enum rte_iova_mode iova_mode;
int ret;
- /* Check if driver supports it. */
- if (!auxiliary_bus_match(&drv->driver, &dev->device))
- /* Match of device and driver failed */
- return 1;
+ if (!auxiliary_dev_exists(dev->name))
+ return -ENOENT;
/* No initialization when marked as blocked, return without error. */
- if (dev->device.devargs != NULL &&
- dev->device.devargs->policy == RTE_DEV_BLOCKED) {
+ if (aux_dev->device.devargs != NULL &&
+ aux_dev->device.devargs->policy == RTE_DEV_BLOCKED) {
AUXILIARY_LOG(INFO, "Device is blocked, not initializing");
return -1;
}
- if (dev->device.numa_node < 0 && rte_socket_count() > 1)
- AUXILIARY_LOG(INFO, "Device %s is not NUMA-aware", dev->name);
+ if (aux_dev->device.numa_node < 0 && rte_socket_count() > 1)
+ AUXILIARY_LOG(INFO, "Device %s is not NUMA-aware", aux_dev->name);
- if (rte_dev_is_probed(&dev->device)) {
+ if (rte_dev_is_probed(&aux_dev->device)) {
AUXILIARY_LOG(DEBUG, "Device %s is already probed on auxiliary bus",
- dev->device.name);
+ aux_dev->device.name);
return -EEXIST;
}
iova_mode = rte_eal_iova_mode();
- if ((drv->drv_flags & RTE_AUXILIARY_DRV_NEED_IOVA_AS_VA) > 0 &&
+ if ((aux_drv->drv_flags & RTE_AUXILIARY_DRV_NEED_IOVA_AS_VA) > 0 &&
iova_mode != RTE_IOVA_VA) {
AUXILIARY_LOG(ERR, "Driver %s expecting VA IOVA mode but current mode is PA, not initializing",
- drv->driver.name);
+ aux_drv->driver.name);
return -EINVAL;
}
/* Allocate interrupt instance */
- dev->intr_handle =
+ aux_dev->intr_handle =
rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE);
- if (dev->intr_handle == NULL) {
+ if (aux_dev->intr_handle == NULL) {
AUXILIARY_LOG(ERR, "Could not allocate interrupt instance for device %s",
- dev->name);
+ aux_dev->name);
return -ENOMEM;
}
- dev->driver = drv;
+ aux_dev->driver = aux_drv;
AUXILIARY_LOG(INFO, "Probe auxiliary driver: %s device: %s (NUMA node %i)",
- drv->driver.name, dev->name, dev->device.numa_node);
- ret = drv->probe(drv, dev);
+ aux_drv->driver.name, aux_dev->name, aux_dev->device.numa_node);
+ ret = aux_drv->probe(aux_drv, aux_dev);
if (ret != 0) {
- dev->driver = NULL;
- rte_intr_instance_free(dev->intr_handle);
- dev->intr_handle = NULL;
+ aux_dev->driver = NULL;
+ rte_intr_instance_free(aux_dev->intr_handle);
+ aux_dev->intr_handle = NULL;
} else {
- dev->device.driver = &drv->driver;
+ aux_dev->device.driver = &aux_drv->driver;
}
return ret;
@@ -159,33 +158,6 @@ rte_auxiliary_driver_remove_dev(struct rte_auxiliary_device *dev)
return 0;
}
-/*
- * Call the probe() function of all registered drivers for the given device.
- * Return < 0 if initialization failed.
- * Return 1 if no driver is found for this device.
- */
-static int
-auxiliary_probe_all_drivers(struct rte_auxiliary_device *dev)
-{
- struct rte_auxiliary_driver *drv;
- int rc;
-
- RTE_BUS_FOREACH_DRV(drv, &auxiliary_bus.bus) {
- if (!drv->match(dev->name))
- continue;
-
- rc = rte_auxiliary_probe_one_driver(drv, dev);
- if (rc < 0)
- /* negative value is an error */
- return rc;
- if (rc > 0)
- /* positive value means driver doesn't support it */
- continue;
- return 0;
- }
- return 1;
-}
-
/*
* Scan the content of the auxiliary bus, and call the probe function for
* all registered drivers to try to probe discovered devices.
@@ -195,12 +167,19 @@ auxiliary_probe(void)
{
struct rte_auxiliary_device *dev = NULL;
size_t probed = 0, failed = 0;
- int ret = 0;
RTE_BUS_FOREACH_DEV(dev, &auxiliary_bus.bus) {
+ struct rte_driver *drv = NULL;
+ int ret;
+
probed++;
- ret = auxiliary_probe_all_drivers(dev);
+next_driver:
+ drv = rte_bus_find_driver(&auxiliary_bus.bus, drv, &dev->device);
+ if (drv == NULL)
+ continue;
+
+ ret = auxiliary_bus.bus.probe_device(drv, &dev->device);
if (ret < 0) {
if (ret != -EEXIST) {
AUXILIARY_LOG(ERR, "Requested device %s cannot be used",
@@ -208,7 +187,8 @@ auxiliary_probe(void)
rte_errno = errno;
failed++;
}
- ret = 0;
+ } else if (ret > 0) {
+ goto next_driver;
}
}
@@ -250,14 +230,6 @@ rte_auxiliary_unregister(struct rte_auxiliary_driver *driver)
rte_bus_remove_driver(&auxiliary_bus.bus, &driver->driver);
}
-static int
-auxiliary_plug(struct rte_device *dev)
-{
- if (!auxiliary_dev_exists(dev->name))
- return -ENOENT;
- return auxiliary_probe_all_drivers(RTE_BUS_DEVICE(dev, struct rte_auxiliary_device));
-}
-
static int
auxiliary_unplug(struct rte_device *dev)
{
@@ -340,7 +312,7 @@ struct rte_auxiliary_bus auxiliary_bus = {
.cleanup = auxiliary_cleanup,
.find_device = rte_bus_generic_find_device,
.match = auxiliary_bus_match,
- .plug = auxiliary_plug,
+ .probe_device = auxiliary_probe_device,
.unplug = auxiliary_unplug,
.parse = auxiliary_parse,
.dma_map = auxiliary_dma_map,
diff --git a/drivers/bus/cdx/cdx.c b/drivers/bus/cdx/cdx.c
index c898ce9271..c38eae325b 100644
--- a/drivers/bus/cdx/cdx.c
+++ b/drivers/bus/cdx/cdx.c
@@ -308,29 +308,23 @@ cdx_bus_match(const struct rte_driver *drv, const struct rte_device *dev)
* driver.
*/
static int
-cdx_probe_one_driver(struct rte_cdx_driver *dr,
- struct rte_cdx_device *dev)
+cdx_probe_device(struct rte_driver *drv, struct rte_device *dev)
{
- const char *dev_name = dev->name;
- bool already_probed;
+ struct rte_cdx_device *cdx_dev = RTE_BUS_DEVICE(dev, *cdx_dev);
+ struct rte_cdx_driver *cdx_drv = RTE_BUS_DRIVER(drv, *cdx_drv);
+ const char *dev_name = cdx_dev->name;
int ret;
- /* The device is not blocked; Check if driver supports it */
- if (!cdx_bus_match(&dr->driver, &dev->device))
- /* Match of device and driver failed */
- return 1;
-
- already_probed = rte_dev_is_probed(&dev->device);
- if (already_probed) {
+ if (rte_dev_is_probed(&cdx_dev->device)) {
CDX_BUS_INFO("Device %s is already probed", dev_name);
return -EEXIST;
}
CDX_BUS_DEBUG(" probe device %s using driver: %s", dev_name,
- dr->driver.name);
+ cdx_drv->driver.name);
- if (dr->drv_flags & RTE_CDX_DRV_NEED_MAPPING) {
- ret = cdx_vfio_map_resource(dev);
+ if (cdx_drv->drv_flags & RTE_CDX_DRV_NEED_MAPPING) {
+ ret = cdx_vfio_map_resource(cdx_dev);
if (ret != 0) {
CDX_BUS_ERR("CDX map device failed: %d", ret);
goto error_map_device;
@@ -338,50 +332,26 @@ cdx_probe_one_driver(struct rte_cdx_driver *dr,
}
/* call the driver probe() function */
- ret = dr->probe(dr, dev);
+ ret = cdx_drv->probe(cdx_drv, cdx_dev);
if (ret) {
CDX_BUS_ERR("Probe CDX driver: %s device: %s failed: %d",
- dr->driver.name, dev_name, ret);
+ cdx_drv->driver.name, dev_name, ret);
goto error_probe;
} else {
- dev->device.driver = &dr->driver;
+ cdx_dev->device.driver = &cdx_drv->driver;
}
- dev->driver = dr;
+ cdx_dev->driver = cdx_drv;
return ret;
error_probe:
- cdx_vfio_unmap_resource(dev);
- rte_intr_instance_free(dev->intr_handle);
- dev->intr_handle = NULL;
+ cdx_vfio_unmap_resource(cdx_dev);
+ rte_intr_instance_free(cdx_dev->intr_handle);
+ cdx_dev->intr_handle = NULL;
error_map_device:
return ret;
}
-/*
- * If vendor/device ID match, call the probe() function of all
- * registered driver for the given device. Return < 0 if initialization
- * failed, return 1 if no driver is found for this device.
- */
-static int
-cdx_probe_all_drivers(struct rte_cdx_device *dev)
-{
- struct rte_cdx_driver *dr = NULL;
- int rc = 0;
-
- RTE_BUS_FOREACH_DRV(dr, &rte_cdx_bus.bus) {
- rc = cdx_probe_one_driver(dr, dev);
- if (rc < 0)
- /* negative value is an error */
- return rc;
- if (rc > 0)
- /* positive value means driver doesn't support it */
- continue;
- return 0;
- }
- return 1;
-}
-
/*
* Scan the content of the CDX bus, and call the probe() function for
* all registered drivers that have a matching entry in its id_table
@@ -392,17 +362,26 @@ cdx_probe(void)
{
struct rte_cdx_device *dev = NULL;
size_t probed = 0, failed = 0;
- int ret = 0;
RTE_BUS_FOREACH_DEV(dev, &rte_cdx_bus.bus) {
+ struct rte_driver *drv = NULL;
+ int ret;
+
probed++;
- ret = cdx_probe_all_drivers(dev);
+next_driver:
+ drv = rte_bus_find_driver(&rte_cdx_bus.bus, drv, &dev->device);
+ if (drv == NULL)
+ continue;
+
+ ret = rte_cdx_bus.bus.probe_device(drv, &dev->device);
if (ret < 0) {
CDX_BUS_ERR("Requested device %s cannot be used",
dev->name);
rte_errno = errno;
failed++;
+ } else if (ret > 0) {
+ goto next_driver;
}
}
@@ -470,12 +449,6 @@ cdx_detach_dev(struct rte_cdx_device *dev)
return 0;
}
-static int
-cdx_plug(struct rte_device *dev)
-{
- return cdx_probe_all_drivers(RTE_BUS_DEVICE(dev, struct rte_cdx_device));
-}
-
static int
cdx_unplug(struct rte_device *dev)
{
@@ -524,7 +497,7 @@ struct rte_cdx_bus rte_cdx_bus = {
.probe = cdx_probe,
.find_device = rte_bus_generic_find_device,
.match = cdx_bus_match,
- .plug = cdx_plug,
+ .probe_device = cdx_probe_device,
.unplug = cdx_unplug,
.parse = cdx_parse,
.dma_map = cdx_dma_map,
diff --git a/drivers/bus/dpaa/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c
index ca80fff6ec..14cd64cc32 100644
--- a/drivers/bus/dpaa/dpaa_bus.c
+++ b/drivers/bus/dpaa/dpaa_bus.c
@@ -706,7 +706,6 @@ rte_dpaa_bus_probe(void)
{
int ret = -1;
struct rte_dpaa_device *dev;
- struct rte_dpaa_driver *drv;
FILE *svr_file = NULL;
uint32_t svr_ver;
static int process_once;
@@ -789,25 +788,18 @@ rte_dpaa_bus_probe(void)
/* For each registered driver, and device, call the driver->probe */
RTE_BUS_FOREACH_DEV(dev, &rte_dpaa_bus.bus) {
- RTE_BUS_FOREACH_DRV(drv, &rte_dpaa_bus.bus) {
- if (!dpaa_bus_match(&drv->driver, &dev->device))
- continue;
-
- if (rte_dev_is_probed(&dev->device))
- continue;
-
- if (rte_bus_device_is_ignored(&rte_dpaa_bus.bus, dev->name))
- continue;
-
- ret = drv->probe(drv, dev);
- if (ret) {
- DPAA_BUS_ERR("unable to probe: %s", dev->name);
- } else {
- dev->driver = drv;
- dev->device.driver = &drv->driver;
- }
- break;
- }
+ struct rte_driver *driver = NULL;
+
+next_driver:
+ driver = rte_bus_find_driver(&rte_dpaa_bus.bus, driver, &dev->device);
+ if (driver == NULL)
+ continue;
+
+ ret = rte_dpaa_bus.bus.probe_device(driver, &dev->device);
+ if (ret < 0)
+ DPAA_BUS_ERR("Failed to probe device %s", dev->name);
+ else if (ret > 0)
+ goto next_driver;
}
dpaa_bus_global_init = 1;
@@ -828,17 +820,27 @@ rte_dpaa_get_iommu_class(void)
}
static int
-dpaa_bus_plug(struct rte_device *dev __rte_unused)
+dpaa_bus_probe_device(struct rte_driver *drv, struct rte_device *dev)
{
- /* No operation is performed while plugging the device */
- return 0;
-}
+ struct rte_dpaa_device *dpaa_dev = RTE_BUS_DEVICE(dev, *dpaa_dev);
+ struct rte_dpaa_driver *dpaa_drv = RTE_BUS_DRIVER(drv, *dpaa_drv);
+ int ret;
-static int
-dpaa_bus_unplug(struct rte_device *dev __rte_unused)
-{
- /* No operation is performed while unplugging the device */
- return 0;
+ if (rte_dev_is_probed(&dpaa_dev->device))
+ return 0;
+
+ if (rte_bus_device_is_ignored(&rte_dpaa_bus.bus, dpaa_dev->name))
+ return 0;
+
+ ret = dpaa_drv->probe(dpaa_drv, dpaa_dev);
+ if (ret != 0) {
+ DPAA_BUS_ERR("unable to probe: %s", dpaa_dev->name);
+ } else {
+ dpaa_dev->driver = dpaa_drv;
+ dpaa_dev->device.driver = &dpaa_drv->driver;
+ }
+
+ return ret;
}
static int
@@ -899,8 +901,7 @@ static struct rte_dpaa_bus rte_dpaa_bus = {
.find_device = rte_bus_generic_find_device,
.get_iommu_class = rte_dpaa_get_iommu_class,
.match = dpaa_bus_match,
- .plug = dpaa_bus_plug,
- .unplug = dpaa_bus_unplug,
+ .probe_device = dpaa_bus_probe_device,
.dev_iterate = rte_bus_generic_dev_iterate,
.cleanup = dpaa_bus_cleanup,
},
diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index 8cd9b1eb88..a975e464c1 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -411,7 +411,6 @@ rte_fslmc_probe(void)
int ret = 0;
struct rte_dpaa2_device *dev;
- struct rte_dpaa2_driver *drv;
static const struct rte_mbuf_dynfield dpaa2_seqn_dynfield_desc = {
.name = DPAA2_SEQN_DYNFIELD_NAME,
@@ -456,25 +455,21 @@ rte_fslmc_probe(void)
}
RTE_BUS_FOREACH_DEV(dev, &rte_fslmc_bus.bus) {
- RTE_BUS_FOREACH_DRV(drv, &rte_fslmc_bus.bus) {
- if (!fslmc_bus_match(&drv->driver, &dev->device))
- continue;
+ struct rte_driver *driver = NULL;
- if (rte_dev_is_probed(&dev->device))
- continue;
+ if (rte_bus_device_is_ignored(&rte_fslmc_bus.bus, dev->device.name))
+ continue;
- if (rte_bus_device_is_ignored(&rte_fslmc_bus.bus, dev->device.name))
- continue;
+next_driver:
+ driver = rte_bus_find_driver(&rte_fslmc_bus.bus, driver, &dev->device);
+ if (driver == NULL)
+ continue;
- ret = drv->probe(drv, dev);
- if (ret) {
- DPAA2_BUS_ERR("Unable to probe");
- } else {
- dev->driver = drv;
- dev->device.driver = &drv->driver;
- }
- break;
- }
+ ret = rte_fslmc_bus.bus.probe_device(driver, &dev->device);
+ if (ret < 0)
+ DPAA2_BUS_ERR("Failed to probe device %s", dev->device.name);
+ else if (ret > 0)
+ goto next_driver;
}
return 0;
@@ -540,35 +535,29 @@ rte_dpaa2_get_iommu_class(void)
}
static int
-fslmc_bus_plug(struct rte_device *rte_dev)
+fslmc_bus_probe_device(struct rte_driver *driver, struct rte_device *rte_dev)
{
- int ret = 0;
struct rte_dpaa2_device *dev = RTE_BUS_DEVICE(rte_dev, *dev);
- struct rte_dpaa2_driver *drv;
-
- RTE_BUS_FOREACH_DRV(drv, &rte_fslmc_bus.bus) {
- if (!fslmc_bus_match(&drv->driver, &dev->device))
- continue;
+ struct rte_dpaa2_driver *drv = RTE_BUS_DRIVER(driver, *drv);
+ int ret = 0;
- if (rte_dev_is_probed(&dev->device))
- continue;
+ if (rte_dev_is_probed(&dev->device))
+ return 0;
- if (dev->device.devargs &&
- dev->device.devargs->policy == RTE_DEV_BLOCKED) {
- DPAA2_BUS_DEBUG("%s Blocked, skipping",
- dev->device.name);
- continue;
- }
+ if (dev->device.devargs &&
+ dev->device.devargs->policy == RTE_DEV_BLOCKED) {
+ DPAA2_BUS_DEBUG("%s Blocked, skipping",
+ dev->device.name);
+ return 0;
+ }
- ret = drv->probe(drv, dev);
- if (ret) {
- DPAA2_BUS_ERR("Unable to probe");
- } else {
- dev->driver = drv;
- dev->device.driver = &drv->driver;
- DPAA2_BUS_INFO("%s Plugged", dev->device.name);
- }
- break;
+ ret = drv->probe(drv, dev);
+ if (ret != 0) {
+ DPAA2_BUS_ERR("Unable to probe");
+ } else {
+ dev->driver = drv;
+ dev->device.driver = &drv->driver;
+ DPAA2_BUS_INFO("%s Plugged", dev->device.name);
}
return ret;
@@ -601,7 +590,7 @@ struct rte_fslmc_bus rte_fslmc_bus = {
.find_device = rte_bus_generic_find_device,
.get_iommu_class = rte_dpaa2_get_iommu_class,
.match = fslmc_bus_match,
- .plug = fslmc_bus_plug,
+ .probe_device = fslmc_bus_probe_device,
.unplug = fslmc_bus_unplug,
.dev_iterate = rte_bus_generic_dev_iterate,
},
diff --git a/drivers/bus/ifpga/ifpga_bus.c b/drivers/bus/ifpga/ifpga_bus.c
index 021171e955..92ad3513e0 100644
--- a/drivers/bus/ifpga/ifpga_bus.c
+++ b/drivers/bus/ifpga/ifpga_bus.c
@@ -268,57 +268,32 @@ ifpga_bus_match(const struct rte_driver *drv, const struct rte_device *dev)
}
static int
-ifpga_probe_one_driver(struct rte_afu_driver *drv,
- struct rte_afu_device *afu_dev)
+ifpga_probe_device(struct rte_driver *drv, struct rte_device *dev)
{
+ struct rte_afu_device *afu_dev = RTE_BUS_DEVICE(dev, *afu_dev);
+ struct rte_afu_driver *afu_drv = RTE_BUS_DRIVER(drv, *afu_drv);
int ret;
- if (!ifpga_bus_match(&drv->driver, &afu_dev->device))
- /* Match of device and driver failed */
- return 1;
+ /* Check if a driver is already loaded */
+ if (rte_dev_is_probed(&afu_dev->device)) {
+ IFPGA_BUS_DEBUG("Device %s is already probed",
+ rte_ifpga_device_name(afu_dev));
+ return -EEXIST;
+ }
/* reference driver structure */
- afu_dev->driver = drv;
+ afu_dev->driver = afu_drv;
/* call the driver probe() function */
- ret = drv->probe(afu_dev);
+ ret = afu_drv->probe(afu_dev);
if (ret)
afu_dev->driver = NULL;
else
- afu_dev->device.driver = &drv->driver;
+ afu_dev->device.driver = &afu_drv->driver;
return ret;
}
-static int
-ifpga_probe_all_drivers(struct rte_afu_device *afu_dev)
-{
- struct rte_afu_driver *drv = NULL;
- int ret = 0;
-
- /* Check if a driver is already loaded */
- if (rte_dev_is_probed(&afu_dev->device)) {
- IFPGA_BUS_DEBUG("Device %s is already probed",
- rte_ifpga_device_name(afu_dev));
- return -EEXIST;
- }
-
- RTE_BUS_FOREACH_DRV(drv, &rte_ifpga_bus) {
- ret = ifpga_probe_one_driver(drv, afu_dev);
- if (ret < 0)
- /* negative value is an error */
- return ret;
- if (ret > 0)
- /* positive value means driver doesn't support it */
- continue;
- return 0;
- }
- if ((ret > 0) && (afu_dev->driver == NULL))
- return 0;
- else
- return ret;
-}
-
/*
* Scan the content of the Intel FPGA bus, and call the probe() function for
* all registered drivers that have a matching entry in its id_table
@@ -331,12 +306,21 @@ ifpga_probe(void)
int ret = 0;
RTE_BUS_FOREACH_DEV(afu_dev, &rte_ifpga_bus) {
- ret = ifpga_probe_all_drivers(afu_dev);
+ struct rte_driver *drv = NULL;
+
+next_driver:
+ drv = rte_bus_find_driver(&rte_ifpga_bus, drv, &afu_dev->device);
+ if (drv == NULL)
+ continue;
+
+ ret = rte_ifpga_bus.probe_device(drv, &afu_dev->device);
if (ret == -EEXIST)
continue;
if (ret < 0)
IFPGA_BUS_ERR("failed to initialize %s device",
rte_ifpga_device_name(afu_dev));
+ else if (ret > 0)
+ goto next_driver;
}
return ret;
@@ -379,12 +363,6 @@ ifpga_cleanup(void)
return error;
}
-static int
-ifpga_plug(struct rte_device *dev)
-{
- return ifpga_probe_all_drivers(RTE_BUS_DEVICE(dev, struct rte_afu_device));
-}
-
static int
ifpga_unplug(struct rte_device *dev)
{
@@ -454,7 +432,7 @@ static struct rte_bus rte_ifpga_bus = {
.cleanup = ifpga_cleanup,
.find_device = rte_bus_generic_find_device,
.match = ifpga_bus_match,
- .plug = ifpga_plug,
+ .probe_device = ifpga_probe_device,
.unplug = ifpga_unplug,
.parse = ifpga_parse,
};
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index d7fda1752a..b57320064e 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -181,51 +181,42 @@ pci_bus_match(const struct rte_driver *drv, const struct rte_device *dev)
* driver.
*/
static int
-rte_pci_probe_one_driver(struct rte_pci_driver *dr,
- struct rte_pci_device *dev)
+pci_probe_device(struct rte_driver *drv, struct rte_device *dev)
{
- int ret;
+ struct rte_pci_device *pci_dev = RTE_BUS_DEVICE(dev, *pci_dev);
+ struct rte_pci_driver *pci_drv = RTE_BUS_DRIVER(drv, *pci_drv);
+ struct rte_pci_addr *loc = &pci_dev->addr;
bool already_probed;
- struct rte_pci_addr *loc;
-
- if ((dr == NULL) || (dev == NULL))
- return -EINVAL;
-
- loc = &dev->addr;
-
- /* The device is not blocked; Check if driver supports it */
- if (!pci_bus_match(&dr->driver, &dev->device))
- /* Match of device and driver failed */
- return 1;
+ int ret;
PCI_LOG(DEBUG, "PCI device "PCI_PRI_FMT" on NUMA socket %i",
loc->domain, loc->bus, loc->devid, loc->function,
- dev->device.numa_node);
+ pci_dev->device.numa_node);
/* no initialization when marked as blocked, return without error */
- if (dev->device.devargs != NULL &&
- dev->device.devargs->policy == RTE_DEV_BLOCKED) {
+ if (pci_dev->device.devargs != NULL &&
+ pci_dev->device.devargs->policy == RTE_DEV_BLOCKED) {
PCI_LOG(INFO, " Device is blocked, not initializing");
return 1;
}
- if (dev->device.numa_node < 0 && rte_socket_count() > 1)
- PCI_LOG(INFO, "Device %s is not NUMA-aware", dev->name);
+ if (pci_dev->device.numa_node < 0 && rte_socket_count() > 1)
+ PCI_LOG(INFO, "Device %s is not NUMA-aware", pci_dev->name);
- already_probed = rte_dev_is_probed(&dev->device);
- if (already_probed && !(dr->drv_flags & RTE_PCI_DRV_PROBE_AGAIN)) {
- PCI_LOG(DEBUG, "Device %s is already probed", dev->device.name);
+ already_probed = rte_dev_is_probed(&pci_dev->device);
+ if (already_probed && !(pci_drv->drv_flags & RTE_PCI_DRV_PROBE_AGAIN)) {
+ PCI_LOG(DEBUG, "Device %s is already probed", pci_dev->device.name);
return -EEXIST;
}
- PCI_LOG(DEBUG, " probe driver: %x:%x %s", dev->id.vendor_id,
- dev->id.device_id, dr->driver.name);
+ PCI_LOG(DEBUG, " probe driver: %x:%x %s", pci_dev->id.vendor_id,
+ pci_dev->id.device_id, pci_drv->driver.name);
if (!already_probed) {
enum rte_iova_mode dev_iova_mode;
enum rte_iova_mode iova_mode;
- dev_iova_mode = pci_device_iova_mode(dr, dev);
+ dev_iova_mode = pci_device_iova_mode(pci_drv, pci_dev);
iova_mode = rte_eal_iova_mode();
if (dev_iova_mode != RTE_IOVA_DC &&
dev_iova_mode != iova_mode) {
@@ -236,21 +227,21 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
}
/* Allocate interrupt instance for pci device */
- dev->intr_handle =
+ pci_dev->intr_handle =
rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE);
- if (dev->intr_handle == NULL) {
+ if (pci_dev->intr_handle == NULL) {
PCI_LOG(ERR, "Failed to create interrupt instance for %s",
- dev->device.name);
+ pci_dev->device.name);
return -ENOMEM;
}
- dev->vfio_req_intr_handle =
+ pci_dev->vfio_req_intr_handle =
rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE);
- if (dev->vfio_req_intr_handle == NULL) {
- rte_intr_instance_free(dev->intr_handle);
- dev->intr_handle = NULL;
+ if (pci_dev->vfio_req_intr_handle == NULL) {
+ rte_intr_instance_free(pci_dev->intr_handle);
+ pci_dev->intr_handle = NULL;
PCI_LOG(ERR, "Failed to create vfio req interrupt instance for %s",
- dev->device.name);
+ pci_dev->device.name);
return -ENOMEM;
}
@@ -259,43 +250,43 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
* This needs to be before rte_pci_map_device(), as it enables
* to use driver flags for adjusting configuration.
*/
- dev->driver = dr;
- if (dev->driver->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
- ret = rte_pci_map_device(dev);
+ pci_dev->driver = pci_drv;
+ if (pci_dev->driver->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
+ ret = rte_pci_map_device(pci_dev);
if (ret != 0) {
- dev->driver = NULL;
- rte_intr_instance_free(dev->vfio_req_intr_handle);
- dev->vfio_req_intr_handle = NULL;
- rte_intr_instance_free(dev->intr_handle);
- dev->intr_handle = NULL;
+ pci_dev->driver = NULL;
+ rte_intr_instance_free(pci_dev->vfio_req_intr_handle);
+ pci_dev->vfio_req_intr_handle = NULL;
+ rte_intr_instance_free(pci_dev->intr_handle);
+ pci_dev->intr_handle = NULL;
return ret;
}
}
}
PCI_LOG(INFO, "Probe PCI driver: %s (%x:%04x) device: "PCI_PRI_FMT" (socket %i)",
- dr->driver.name, dev->id.vendor_id, dev->id.device_id,
+ pci_drv->driver.name, pci_dev->id.vendor_id, pci_dev->id.device_id,
loc->domain, loc->bus, loc->devid, loc->function,
- dev->device.numa_node);
+ pci_dev->device.numa_node);
/* call the driver probe() function */
- ret = dr->probe(dr, dev);
+ ret = pci_drv->probe(pci_drv, pci_dev);
if (already_probed)
return ret; /* no rollback if already succeeded earlier */
if (ret) {
- dev->driver = NULL;
- if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
+ pci_dev->driver = NULL;
+ if ((pci_drv->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
/* Don't unmap if device is unsupported and
* driver needs mapped resources.
*/
!(ret > 0 &&
- (dr->drv_flags & RTE_PCI_DRV_KEEP_MAPPED_RES)))
- rte_pci_unmap_device(dev);
- rte_intr_instance_free(dev->vfio_req_intr_handle);
- dev->vfio_req_intr_handle = NULL;
- rte_intr_instance_free(dev->intr_handle);
- dev->intr_handle = NULL;
+ (pci_drv->drv_flags & RTE_PCI_DRV_KEEP_MAPPED_RES)))
+ rte_pci_unmap_device(pci_dev);
+ rte_intr_instance_free(pci_dev->vfio_req_intr_handle);
+ pci_dev->vfio_req_intr_handle = NULL;
+ rte_intr_instance_free(pci_dev->intr_handle);
+ pci_dev->intr_handle = NULL;
} else {
- dev->device.driver = &dr->driver;
+ pci_dev->device.driver = &pci_drv->driver;
}
return ret;
@@ -343,33 +334,6 @@ rte_pci_detach_dev(struct rte_pci_device *dev)
return 0;
}
-/*
- * If vendor/device ID match, call the probe() function of all
- * registered driver for the given device. Return < 0 if initialization
- * failed, return 1 if no driver is found for this device.
- */
-static int
-pci_probe_all_drivers(struct rte_pci_device *dev)
-{
- struct rte_pci_driver *dr = NULL;
- int rc = 0;
-
- if (dev == NULL)
- return -EINVAL;
-
- RTE_BUS_FOREACH_DRV(dr, &rte_pci_bus.bus) {
- rc = rte_pci_probe_one_driver(dr, dev);
- if (rc < 0)
- /* negative value is an error */
- return rc;
- if (rc > 0)
- /* positive value means driver doesn't support it */
- continue;
- return 0;
- }
- return 1;
-}
-
/*
* Scan the content of the PCI bus, and call the probe() function for
* all registered drivers that have a matching entry in its id_table
@@ -380,12 +344,19 @@ pci_probe(void)
{
struct rte_pci_device *dev = NULL;
size_t probed = 0, failed = 0;
- int ret = 0;
RTE_BUS_FOREACH_DEV(dev, &rte_pci_bus.bus) {
+ struct rte_driver *drv = NULL;
+ int ret;
+
probed++;
- ret = pci_probe_all_drivers(dev);
+next_driver:
+ drv = rte_bus_find_driver(&rte_pci_bus.bus, drv, &dev->device);
+ if (drv == NULL)
+ continue;
+
+ ret = rte_pci_bus.bus.probe_device(drv, &dev->device);
if (ret < 0) {
if (ret != -EEXIST) {
PCI_LOG(ERR, "Requested device " PCI_PRI_FMT " cannot be used",
@@ -395,6 +366,8 @@ pci_probe(void)
failed++;
}
ret = 0;
+ } else if (ret > 0) {
+ goto next_driver;
}
}
@@ -595,12 +568,6 @@ pci_sigbus_handler(const void *failure_addr)
return ret;
}
-static int
-pci_plug(struct rte_device *dev)
-{
- return pci_probe_all_drivers(RTE_BUS_DEVICE(dev, struct rte_pci_device));
-}
-
static int
pci_unplug(struct rte_device *dev)
{
@@ -861,7 +828,7 @@ struct rte_pci_bus rte_pci_bus = {
.cleanup = pci_cleanup,
.find_device = rte_bus_generic_find_device,
.match = pci_bus_match,
- .plug = pci_plug,
+ .probe_device = pci_probe_device,
.unplug = pci_unplug,
.parse = pci_parse,
.dev_compare = pci_dev_compare,
diff --git a/drivers/bus/platform/platform.c b/drivers/bus/platform/platform.c
index 3d6b6efe6e..22979f31b3 100644
--- a/drivers/bus/platform/platform.c
+++ b/drivers/bus/platform/platform.c
@@ -404,43 +404,36 @@ platform_bus_match(const struct rte_driver *drv, const struct rte_device *dev)
return match;
}
-static int
-device_attach(struct rte_platform_device *pdev)
-{
- struct rte_platform_driver *pdrv;
-
- RTE_BUS_FOREACH_DRV(pdrv, &platform_bus.bus) {
- if (platform_bus_match(&pdrv->driver, &pdev->device))
- break;
- }
-
- if (pdrv == NULL)
- return -ENODEV;
-
- return driver_probe_device(pdrv, pdev);
-}
-
static int
platform_bus_probe(void)
{
struct rte_platform_device *pdev;
- int ret;
RTE_BUS_FOREACH_DEV(pdev, &platform_bus.bus) {
- ret = device_attach(pdev);
+ struct rte_driver *drv = NULL;
+ int ret;
+
+next_driver:
+ drv = rte_bus_find_driver(&platform_bus.bus, drv, &pdev->device);
+ if (drv == NULL)
+ continue;
+
+ ret = platform_bus.bus.probe_device(drv, &pdev->device);
if (ret == -EBUSY) {
PLATFORM_LOG_LINE(DEBUG, "device %s already probed", pdev->name);
continue;
}
- if (ret)
+ if (ret < 0)
PLATFORM_LOG_LINE(ERR, "failed to probe %s", pdev->name);
+ else if (ret > 0)
+ goto next_driver;
}
return 0;
}
static int
-platform_bus_plug(struct rte_device *dev)
+platform_bus_probe_device(struct rte_driver *drv, struct rte_device *dev)
{
if (rte_bus_device_is_ignored(&platform_bus.bus, dev->name))
return -EPERM;
@@ -448,7 +441,8 @@ platform_bus_plug(struct rte_device *dev)
if (!dev_is_bound_vfio_platform(dev->name))
return -EPERM;
- return device_attach(RTE_BUS_DEVICE(dev, struct rte_platform_device));
+ return driver_probe_device(RTE_BUS_DRIVER(drv, struct rte_platform_driver),
+ RTE_BUS_DEVICE(dev, struct rte_platform_device));
}
static void
@@ -559,7 +553,7 @@ struct rte_platform_bus platform_bus = {
.probe = platform_bus_probe,
.find_device = rte_bus_generic_find_device,
.match = platform_bus_match,
- .plug = platform_bus_plug,
+ .probe_device = platform_bus_probe_device,
.unplug = platform_bus_unplug,
.parse = platform_bus_parse,
.dma_map = platform_bus_dma_map,
diff --git a/drivers/bus/uacce/uacce.c b/drivers/bus/uacce/uacce.c
index bc2858a5c5..d8e15cd479 100644
--- a/drivers/bus/uacce/uacce.c
+++ b/drivers/bus/uacce/uacce.c
@@ -351,74 +351,59 @@ uacce_bus_match(const struct rte_driver *drv, const struct rte_device *dev)
}
static int
-uacce_probe_one_driver(struct rte_uacce_driver *dr, struct rte_uacce_device *dev)
+uacce_probe_device(struct rte_driver *drv, struct rte_device *dev)
{
- const char *dev_name = dev->name;
- bool already_probed;
+ struct rte_uacce_device *uacce_dev = RTE_BUS_DEVICE(dev, *uacce_dev);
+ struct rte_uacce_driver *uacce_drv = RTE_BUS_DRIVER(drv, *uacce_drv);
+ const char *dev_name = uacce_dev->name;
int ret;
- if (!uacce_bus_match(&dr->driver, &dev->device))
- /* Match of device and driver failed */
- return 1;
-
- already_probed = rte_dev_is_probed(&dev->device);
- if (already_probed) {
+ if (rte_dev_is_probed(&uacce_dev->device)) {
UACCE_BUS_INFO("device %s is already probed", dev_name);
return -EEXIST;
}
- UACCE_BUS_DEBUG("probe device %s using driver %s", dev_name, dr->driver.name);
+ UACCE_BUS_DEBUG("probe device %s using driver %s", dev_name, uacce_drv->driver.name);
- ret = dr->probe(dr, dev);
+ ret = uacce_drv->probe(uacce_drv, uacce_dev);
if (ret != 0) {
UACCE_BUS_ERR("probe device %s with driver %s failed %d",
- dev_name, dr->driver.name, ret);
+ dev_name, uacce_drv->driver.name, ret);
} else {
- dev->device.driver = &dr->driver;
- dev->driver = dr;
+ uacce_dev->device.driver = &uacce_drv->driver;
+ uacce_dev->driver = uacce_drv;
UACCE_BUS_DEBUG("probe device %s with driver %s success",
- dev_name, dr->driver.name);
+ dev_name, uacce_drv->driver.name);
}
return ret;
}
-static int
-uacce_probe_all_drivers(struct rte_uacce_device *dev)
-{
- struct rte_uacce_driver *dr;
- int rc;
-
- RTE_BUS_FOREACH_DRV(dr, &uacce_bus.bus) {
- rc = uacce_probe_one_driver(dr, dev);
- if (rc < 0)
- /* negative value is an error */
- return rc;
- if (rc > 0)
- /* positive value means driver doesn't support it */
- continue;
- return 0;
- }
-
- return 1;
-}
-
static int
uacce_probe(void)
{
size_t probed = 0, failed = 0;
struct rte_uacce_device *dev;
- int ret;
RTE_BUS_FOREACH_DEV(dev, &uacce_bus.bus) {
+ struct rte_driver *drv = NULL;
+ int ret;
+
probed++;
- ret = uacce_probe_all_drivers(dev);
+next_driver:
+ drv = rte_bus_find_driver(&uacce_bus.bus, drv, &dev->device);
+ if (drv == NULL)
+ continue;
+
+ ret = uacce_bus.bus.probe_device(drv, &dev->device);
if (ret < 0) {
UACCE_BUS_LOG(ERR, "Requested device %s cannot be used",
dev->name);
rte_errno = errno;
failed++;
+ } else if (ret > 0) {
+ goto next_driver;
}
}
@@ -456,12 +441,6 @@ uacce_cleanup(void)
return error;
}
-static int
-uacce_plug(struct rte_device *dev)
-{
- return uacce_probe_all_drivers(RTE_BUS_DEVICE(dev, struct rte_uacce_device));
-}
-
static int
uacce_detach_dev(struct rte_uacce_device *dev)
{
@@ -625,7 +604,7 @@ static struct rte_uacce_bus uacce_bus = {
.probe = uacce_probe,
.cleanup = uacce_cleanup,
.match = uacce_bus_match,
- .plug = uacce_plug,
+ .probe_device = uacce_probe_device,
.unplug = uacce_unplug,
.find_device = rte_bus_generic_find_device,
.parse = uacce_parse,
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index a4f6168581..5464fe28d4 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -182,32 +182,30 @@ vdev_bus_match(const struct rte_driver *drv, const struct rte_device *dev)
}
static int
-vdev_probe_all_drivers(struct rte_vdev_device *dev)
+vdev_probe_device(struct rte_driver *drv, struct rte_device *dev)
{
+ struct rte_vdev_device *vdev_dev = RTE_BUS_DEVICE(dev, *vdev_dev);
+ struct rte_vdev_driver *vdev_drv = RTE_BUS_DRIVER(drv, *vdev_drv);
const char *name;
- struct rte_vdev_driver *driver;
enum rte_iova_mode iova_mode;
int ret;
- if (rte_dev_is_probed(&dev->device))
+ if (rte_dev_is_probed(&vdev_dev->device))
return -EEXIST;
- name = rte_vdev_device_name(dev);
+ name = rte_vdev_device_name(vdev_dev);
VDEV_LOG(DEBUG, "Search driver to probe device %s", name);
- if (vdev_parse(name, &driver))
- return -1;
-
iova_mode = rte_eal_iova_mode();
- if ((driver->drv_flags & RTE_VDEV_DRV_NEED_IOVA_AS_VA) && (iova_mode == RTE_IOVA_PA)) {
+ if ((vdev_drv->drv_flags & RTE_VDEV_DRV_NEED_IOVA_AS_VA) && (iova_mode == RTE_IOVA_PA)) {
VDEV_LOG(ERR, "%s requires VA IOVA mode but current mode is PA, not initializing",
name);
return -1;
}
- ret = driver->probe(dev);
+ ret = vdev_drv->probe(vdev_dev);
if (ret == 0)
- dev->device.driver = &driver->driver;
+ vdev_dev->device.driver = &vdev_drv->driver;
return ret;
}
@@ -323,14 +321,23 @@ rte_vdev_init(const char *name, const char *args)
rte_spinlock_recursive_lock(&vdev_device_list_lock);
ret = insert_vdev(name, args, &dev, true);
if (ret == 0) {
- ret = vdev_probe_all_drivers(dev);
- if (ret) {
- if (ret > 0)
- VDEV_LOG(ERR, "no driver found for %s", name);
+ struct rte_driver *drv = NULL;
+
+next_driver:
+ drv = rte_bus_find_driver(&rte_vdev_bus, drv, &dev->device);
+ if (drv == NULL) {
+ VDEV_LOG(ERR, "no driver found for %s", name);
+ ret = -1;
+ } else {
+ ret = rte_vdev_bus.probe_device(drv, &dev->device);
+ }
+ if (ret < 0) {
/* If fails, remove it from vdev list */
rte_bus_remove_device(&rte_vdev_bus, &dev->device);
rte_devargs_remove(dev->device.devargs);
free(dev);
+ } else if (ret > 0) {
+ goto next_driver;
}
}
rte_spinlock_recursive_unlock(&vdev_device_list_lock);
@@ -393,8 +400,6 @@ struct vdev_param {
char name[RTE_DEV_NAME_MAX_LEN];
};
-static int vdev_plug(struct rte_device *dev);
-
/**
* This function works as the action for both primary and secondary process
* for static vdev discovery when a secondary process is booting.
@@ -552,18 +557,27 @@ vdev_probe(void)
/* call the init function for each virtual device */
RTE_BUS_FOREACH_DEV(dev, &rte_vdev_bus) {
+ struct rte_driver *drv = NULL;
+
/* we don't use the vdev lock here, as it's only used in DPDK
* initialization; and we don't want to hold such a lock when
* we call each driver probe.
*/
- r = vdev_probe_all_drivers(dev);
- if (r != 0) {
+next_driver:
+ drv = rte_bus_find_driver(&rte_vdev_bus, drv, &dev->device);
+ if (drv == NULL)
+ continue;
+
+ r = rte_vdev_bus.probe_device(drv, &dev->device);
+ if (r < 0) {
if (r == -EEXIST)
continue;
VDEV_LOG(ERR, "failed to initialize %s device",
rte_vdev_device_name(dev));
ret = -1;
+ } else if (r > 0) {
+ goto next_driver;
}
}
@@ -623,12 +637,6 @@ vdev_find_device(const struct rte_bus *bus __rte_unused, const struct rte_device
return dev;
}
-static int
-vdev_plug(struct rte_device *dev)
-{
- return vdev_probe_all_drivers(RTE_BUS_DEVICE(dev, struct rte_vdev_device));
-}
-
static int
vdev_unplug(struct rte_device *dev)
{
@@ -660,7 +668,7 @@ static struct rte_bus rte_vdev_bus = {
.cleanup = vdev_cleanup,
.find_device = vdev_find_device,
.match = vdev_bus_match,
- .plug = vdev_plug,
+ .probe_device = vdev_probe_device,
.unplug = vdev_unplug,
.parse = vdev_parse,
.dma_map = vdev_dma_map,
diff --git a/drivers/bus/vmbus/vmbus_common.c b/drivers/bus/vmbus/vmbus_common.c
index d811f1a229..ba923a2669 100644
--- a/drivers/bus/vmbus/vmbus_common.c
+++ b/drivers/bus/vmbus/vmbus_common.c
@@ -79,85 +79,59 @@ vmbus_bus_match(const struct rte_driver *drv, const struct rte_device *dev)
return false;
}
+
/*
* If device ID match, call the devinit() function of the driver.
*/
static int
-vmbus_probe_one_driver(struct rte_vmbus_driver *dr,
- struct rte_vmbus_device *dev)
+vmbus_probe_device(struct rte_driver *drv, struct rte_device *dev)
{
+ struct rte_vmbus_device *vmbus_dev = RTE_BUS_DEVICE(dev, *vmbus_dev);
+ struct rte_vmbus_driver *vmbus_drv = RTE_BUS_DRIVER(drv, *vmbus_drv);
char guid[RTE_UUID_STRLEN];
int ret;
- if (!vmbus_bus_match(&dr->driver, &dev->device))
- return 1; /* not supported */
+ /* Check if a driver is already loaded */
+ if (rte_dev_is_probed(&vmbus_dev->device)) {
+ VMBUS_LOG(DEBUG, "VMBUS driver already loaded");
+ return 0;
+ }
- rte_uuid_unparse(dev->device_id, guid, sizeof(guid));
+ rte_uuid_unparse(vmbus_dev->device_id, guid, sizeof(guid));
VMBUS_LOG(INFO, "VMBUS device %s on NUMA socket %i",
- guid, dev->device.numa_node);
+ guid, vmbus_dev->device.numa_node);
/* no initialization when marked as blocked, return without error */
- if (dev->device.devargs != NULL &&
- dev->device.devargs->policy == RTE_DEV_BLOCKED) {
+ if (vmbus_dev->device.devargs != NULL &&
+ vmbus_dev->device.devargs->policy == RTE_DEV_BLOCKED) {
VMBUS_LOG(INFO, " Device is blocked, not initializing");
return 1;
}
/* map resources for device */
- ret = rte_vmbus_map_device(dev);
+ ret = rte_vmbus_map_device(vmbus_dev);
if (ret != 0)
return ret;
/* reference driver structure */
- dev->driver = dr;
+ vmbus_dev->driver = vmbus_drv;
- if (dev->device.numa_node < 0 && rte_socket_count() > 1)
+ if (vmbus_dev->device.numa_node < 0 && rte_socket_count() > 1)
VMBUS_LOG(INFO, "Device %s is not NUMA-aware", guid);
/* call the driver probe() function */
- VMBUS_LOG(INFO, " probe driver: %s", dr->driver.name);
- ret = dr->probe(dr, dev);
- if (ret) {
- dev->driver = NULL;
- rte_vmbus_unmap_device(dev);
+ VMBUS_LOG(INFO, " probe driver: %s", vmbus_drv->driver.name);
+ ret = vmbus_drv->probe(vmbus_drv, vmbus_dev);
+ if (ret != 0) {
+ vmbus_dev->driver = NULL;
+ rte_vmbus_unmap_device(vmbus_dev);
} else {
- dev->device.driver = &dr->driver;
+ vmbus_dev->device.driver = &vmbus_drv->driver;
}
return ret;
}
-/*
- * If device class GUID matches, call the probe function of
- * register drivers for the vmbus device.
- * Return -1 if initialization failed,
- * and 1 if no driver found for this device.
- */
-static int
-vmbus_probe_all_drivers(struct rte_vmbus_device *dev)
-{
- struct rte_vmbus_driver *dr;
- int rc;
-
- /* Check if a driver is already loaded */
- if (rte_dev_is_probed(&dev->device)) {
- VMBUS_LOG(DEBUG, "VMBUS driver already loaded");
- return 0;
- }
-
- RTE_BUS_FOREACH_DRV(dr, &rte_vmbus_bus.bus) {
- rc = vmbus_probe_one_driver(dr, dev);
- if (rc < 0) /* negative is an error */
- return -1;
-
- if (rc > 0) /* positive driver doesn't support it */
- continue;
-
- return 0;
- }
- return 1;
-}
-
/*
* Scan the vmbus, and call the devinit() function for
* all registered drivers that have a matching entry in its id_table
@@ -172,6 +146,9 @@ rte_vmbus_probe(void)
char ubuf[RTE_UUID_STRLEN];
RTE_BUS_FOREACH_DEV(dev, &rte_vmbus_bus.bus) {
+ struct rte_driver *drv = NULL;
+ int ret;
+
probed++;
rte_uuid_unparse(dev->device_id, ubuf, sizeof(ubuf));
@@ -179,11 +156,19 @@ rte_vmbus_probe(void)
if (rte_bus_device_is_ignored(&rte_vmbus_bus.bus, ubuf))
continue;
- if (vmbus_probe_all_drivers(dev) < 0) {
+next_driver:
+ drv = rte_bus_find_driver(&rte_vmbus_bus.bus, drv, &dev->device);
+ if (drv == NULL)
+ continue;
+
+ ret = rte_vmbus_bus.bus.probe_device(drv, &dev->device);
+ if (ret < 0) {
VMBUS_LOG(NOTICE,
"Requested device %s cannot be used", ubuf);
rte_errno = errno;
failed++;
+ } else if (ret > 0) {
+ goto next_driver;
}
}
@@ -272,6 +257,7 @@ struct rte_vmbus_bus rte_vmbus_bus = {
.cleanup = rte_vmbus_cleanup,
.find_device = rte_bus_generic_find_device,
.match = vmbus_bus_match,
+ .probe_device = vmbus_probe_device,
.parse = vmbus_parse,
.dev_compare = vmbus_dev_compare,
},
diff --git a/drivers/dma/idxd/idxd_bus.c b/drivers/dma/idxd/idxd_bus.c
index c7591823ad..8215bcbba6 100644
--- a/drivers/dma/idxd/idxd_bus.c
+++ b/drivers/dma/idxd/idxd_bus.c
@@ -44,6 +44,7 @@ struct rte_dsa_device {
struct dsa_bus;
static int dsa_scan(void);
static bool dsa_match(const struct rte_driver *drv, const struct rte_device *dev);
+static int dsa_probe_device(struct rte_driver *drv, struct rte_device *dev);
static int dsa_probe(void);
static enum rte_iova_mode dsa_get_iommu_class(void);
static int dsa_addr_parse(const char *name, void *addr);
@@ -60,6 +61,7 @@ struct dsa_bus dsa_bus = {
.bus = {
.scan = dsa_scan,
.match = dsa_match,
+ .probe_device = dsa_probe_device,
.probe = dsa_probe,
.find_device = rte_bus_generic_find_device,
.get_iommu_class = dsa_get_iommu_class,
@@ -210,32 +212,33 @@ read_device_int(struct rte_dsa_device *dev, const char *filename,
}
static int
-idxd_probe_dsa(struct rte_dsa_device *dev)
+dsa_probe_device(__rte_unused struct rte_driver *drv, struct rte_device *dev)
{
+ struct rte_dsa_device *dsa_dev = RTE_BUS_DEVICE(dev, *dsa_dev);
struct idxd_dmadev idxd = {0};
int ret = 0;
IDXD_PMD_INFO("Probing device %s on numa node %d",
- dev->wq_name, dev->device.numa_node);
- if (read_wq_int(dev, "size", &ret) < 0)
+ dsa_dev->wq_name, dsa_dev->device.numa_node);
+ if (read_wq_int(dsa_dev, "size", &ret) < 0)
return -1;
idxd.max_batches = ret;
- if (read_wq_int(dev, "max_batch_size", &ret) < 0)
+ if (read_wq_int(dsa_dev, "max_batch_size", &ret) < 0)
return -1;
idxd.max_batch_size = ret;
- idxd.qid = dev->addr.wq_id;
- idxd.u.bus.dsa_id = dev->addr.device_id;
+ idxd.qid = dsa_dev->addr.wq_id;
+ idxd.u.bus.dsa_id = dsa_dev->addr.device_id;
idxd.sva_support = 1;
- idxd.portal = idxd_bus_mmap_wq(dev);
+ idxd.portal = idxd_bus_mmap_wq(dsa_dev);
if (idxd.portal == NULL) {
IDXD_PMD_ERR("WQ mmap failed");
return -ENOENT;
}
- ret = idxd_dmadev_create(dev->wq_name, &dev->device, &idxd, &idxd_bus_ops);
+ ret = idxd_dmadev_create(dsa_dev->wq_name, dev, &idxd, &idxd_bus_ops);
if (ret) {
- IDXD_PMD_ERR("Failed to create dmadev %s", dev->wq_name);
+ IDXD_PMD_ERR("Failed to create dmadev %s", dsa_dev->wq_name);
return ret;
}
@@ -270,7 +273,7 @@ dsa_probe(void)
if (dsa_match(&dsa_bus.driver, &dev->device) &&
!rte_bus_device_is_ignored(&dsa_bus.bus, dev->device.name)) {
dev->device.driver = &dsa_bus.driver;
- idxd_probe_dsa(dev);
+ dsa_probe_device(&dsa_bus.driver, &dev->device);
continue;
}
IDXD_PMD_DEBUG("WQ '%s', not allocated to DPDK", dev->wq_name);
diff --git a/lib/eal/common/eal_common_bus.c b/lib/eal/common/eal_common_bus.c
index 4884cdfa50..88c417e8d3 100644
--- a/lib/eal/common/eal_common_bus.c
+++ b/lib/eal/common/eal_common_bus.c
@@ -36,8 +36,9 @@ rte_bus_register(struct rte_bus *bus)
RTE_VERIFY(bus->scan);
RTE_VERIFY(bus->probe);
RTE_VERIFY(bus->find_device);
- /* Buses supporting driver plug also require unplug. */
- RTE_VERIFY(!bus->plug || bus->unplug);
+
+ /* A bus providing probe_device requires match. */
+ RTE_VERIFY(!bus->probe_device || bus->match);
TAILQ_INIT(&bus->device_list);
TAILQ_INIT(&bus->driver_list);
diff --git a/lib/eal/common/eal_common_dev.c b/lib/eal/common/eal_common_dev.c
index 17e8901546..a38c211e5d 100644
--- a/lib/eal/common/eal_common_dev.c
+++ b/lib/eal/common/eal_common_dev.c
@@ -179,6 +179,7 @@ int
local_dev_probe(const char *devargs, struct rte_device **new_dev)
{
struct rte_device *dev;
+ struct rte_driver *drv;
struct rte_devargs *da;
int ret;
@@ -191,7 +192,7 @@ local_dev_probe(const char *devargs, struct rte_device **new_dev)
if (ret)
goto err_devarg;
- if (da->bus->plug == NULL) {
+ if (da->bus->probe_device == NULL) {
EAL_LOG(ERR, "Function plug not supported by bus (%s)",
da->bus->name);
ret = -ENOTSUP;
@@ -219,9 +220,16 @@ local_dev_probe(const char *devargs, struct rte_device **new_dev)
* those devargs shouldn't be removed manually anymore.
*/
- ret = dev->bus->plug(dev);
- if (ret > 0)
+ drv = NULL;
+next_driver:
+ drv = rte_bus_find_driver(dev->bus, drv, dev);
+ if (drv == NULL) {
ret = -ENOTSUP;
+ } else {
+ ret = dev->bus->probe_device(drv, dev);
+ if (ret > 0)
+ goto next_driver;
+ }
if (ret && !rte_dev_is_probed(dev)) { /* if hasn't ever succeeded */
EAL_LOG(ERR, "Driver cannot attach the device (%s)",
diff --git a/lib/eal/include/bus_driver.h b/lib/eal/include/bus_driver.h
index 8acd5d52bd..55568fe08a 100644
--- a/lib/eal/include/bus_driver.h
+++ b/lib/eal/include/bus_driver.h
@@ -85,6 +85,21 @@ typedef struct rte_device *
*/
typedef int (*rte_bus_plug_t)(struct rte_device *dev);
+/**
+ * Implementation specific probe function which is responsible for linking
+ * devices on that bus with applicable drivers.
+ *
+ * @param drv
+ * Driver that matches the device.
+ * @param dev
+ * Device pointer that was returned by a previous call to find_device.
+ *
+ * @return
+ * 0 on success.
+ * !0 on error.
+ */
+typedef int (*rte_bus_probe_device_t)(struct rte_driver *drv, struct rte_device *dev);
+
/**
* Implementation specific remove function which is responsible for unlinking
* devices on that bus from assigned driver.
@@ -316,7 +331,7 @@ struct rte_bus {
rte_bus_probe_t probe; /**< Probe devices on bus */
rte_bus_find_device_t find_device; /**< Find a device on the bus */
rte_bus_match_t match; /**< Check if driver matches device */
- rte_bus_plug_t plug; /**< Probe single device for drivers */
+ rte_bus_probe_device_t probe_device; /**< Probe single device with driver */
rte_bus_unplug_t unplug; /**< Remove single device from driver */
rte_bus_parse_t parse; /**< Parse a device name */
rte_bus_dev_compare_t dev_compare; /**< Compare two device names */
--
2.53.0
More information about the dev
mailing list