[PATCH 11/23] bus: factorize driver lookup

David Marchand david.marchand at redhat.com
Wed Apr 29 13:44:44 CEST 2026


Introduce a new bus operation 'match' that checks whether a driver can
handle a given device. This separates the matching logic from iteration,
with buses providing match logic and EAL providing generic iteration
through rte_bus_find_driver().

The match operation returns true if a driver matches a device.
Matching logic is bus-specific (e.g., ID table matching for PCI/CDX,
device type matching for DPAA/FSLMC, UUID matching for IFPGA/VMBUS,
name matching for vdev/platform, API/algorithm matching for uacce).

A generic helper rte_bus_find_driver() iterates through all drivers
on a bus and returns the next matching driver, eliminating the need
for each bus to duplicate iteration logic.

Signed-off-by: David Marchand <david.marchand at redhat.com>
---
 drivers/bus/auxiliary/auxiliary_common.c | 14 ++++-----
 drivers/bus/auxiliary/private.h          |  6 ----
 drivers/bus/cdx/cdx.c                    | 16 +++++-----
 drivers/bus/dpaa/dpaa_bus.c              | 21 ++++++-------
 drivers/bus/fslmc/fslmc_bus.c            | 23 +++++++-------
 drivers/bus/ifpga/ifpga_bus.c            | 14 +++++----
 drivers/bus/pci/pci_common.c             | 20 ++++++-------
 drivers/bus/pci/private.h                | 15 ----------
 drivers/bus/platform/platform.c          |  9 ++++--
 drivers/bus/uacce/uacce.c                | 19 ++++++------
 drivers/bus/vdev/vdev.c                  | 20 +++++++++++++
 drivers/bus/vmbus/vmbus_common.c         | 21 ++++---------
 drivers/dma/idxd/idxd_bus.c              | 35 ++++++++++++++--------
 lib/eal/common/eal_common_bus.c          | 19 ++++++++++++
 lib/eal/include/bus_driver.h             | 38 ++++++++++++++++++++++++
 15 files changed, 173 insertions(+), 117 deletions(-)

diff --git a/drivers/bus/auxiliary/auxiliary_common.c b/drivers/bus/auxiliary/auxiliary_common.c
index 05299db8fe..21b5bcb416 100644
--- a/drivers/bus/auxiliary/auxiliary_common.c
+++ b/drivers/bus/auxiliary/auxiliary_common.c
@@ -59,13 +59,12 @@ auxiliary_on_scan(struct rte_auxiliary_device *aux_dev)
 	aux_dev->device.devargs = rte_bus_find_devargs(&auxiliary_bus.bus, aux_dev->name);
 }
 
-/*
- * Match the auxiliary driver and device using driver function.
- */
-bool
-auxiliary_match(const struct rte_auxiliary_driver *aux_drv,
-		const struct rte_auxiliary_device *aux_dev)
+static bool
+auxiliary_bus_match(const struct rte_driver *drv, const struct rte_device *dev)
 {
+	const struct rte_auxiliary_driver *aux_drv = RTE_BUS_DRIVER(drv, *aux_drv);
+	const struct rte_auxiliary_device *aux_dev = RTE_BUS_DEVICE(dev, *aux_dev);
+
 	if (aux_drv->match == NULL)
 		return false;
 	return aux_drv->match(aux_dev->name);
@@ -82,7 +81,7 @@ rte_auxiliary_probe_one_driver(struct rte_auxiliary_driver *drv,
 	int ret;
 
 	/* Check if driver supports it. */
-	if (!auxiliary_match(drv, dev))
+	if (!auxiliary_bus_match(&drv->driver, &dev->device))
 		/* Match of device and driver failed */
 		return 1;
 
@@ -340,6 +339,7 @@ struct rte_auxiliary_bus auxiliary_bus = {
 		.probe = auxiliary_probe,
 		.cleanup = auxiliary_cleanup,
 		.find_device = rte_bus_generic_find_device,
+		.match = auxiliary_bus_match,
 		.plug = auxiliary_plug,
 		.unplug = auxiliary_unplug,
 		.parse = auxiliary_parse,
diff --git a/drivers/bus/auxiliary/private.h b/drivers/bus/auxiliary/private.h
index 659d798cd6..116154eb56 100644
--- a/drivers/bus/auxiliary/private.h
+++ b/drivers/bus/auxiliary/private.h
@@ -44,10 +44,4 @@ int auxiliary_scan(void);
  */
 void auxiliary_on_scan(struct rte_auxiliary_device *aux_dev);
 
-/*
- * Match the auxiliary driver and device by driver function.
- */
-bool auxiliary_match(const struct rte_auxiliary_driver *aux_drv,
-		     const struct rte_auxiliary_device *aux_dev);
-
 #endif /* BUS_AUXILIARY_PRIVATE_H */
diff --git a/drivers/bus/cdx/cdx.c b/drivers/bus/cdx/cdx.c
index d6f83e2e80..c898ce9271 100644
--- a/drivers/bus/cdx/cdx.c
+++ b/drivers/bus/cdx/cdx.c
@@ -279,13 +279,12 @@ cdx_unmap_resource(void *requested_addr, size_t size)
 			requested_addr, size, rte_strerror(rte_errno));
 	}
 }
-/*
- * Match the CDX Driver and Device using device id and vendor id.
- */
+
 static bool
-cdx_match(const struct rte_cdx_driver *cdx_drv,
-		const struct rte_cdx_device *cdx_dev)
+cdx_bus_match(const struct rte_driver *drv, const struct rte_device *dev)
 {
+	const struct rte_cdx_driver *cdx_drv = RTE_BUS_DRIVER(drv, *cdx_drv);
+	const struct rte_cdx_device *cdx_dev = RTE_BUS_DEVICE(dev, *cdx_dev);
 	const struct rte_cdx_id *id_table;
 
 	for (id_table = cdx_drv->id_table; id_table->vendor_id != 0;
@@ -298,10 +297,10 @@ cdx_match(const struct rte_cdx_driver *cdx_drv,
 				id_table->device_id != RTE_CDX_ANY_ID)
 			continue;
 
-		return 1;
+		return true;
 	}
 
-	return 0;
+	return false;
 }
 
 /*
@@ -317,7 +316,7 @@ cdx_probe_one_driver(struct rte_cdx_driver *dr,
 	int ret;
 
 	/* The device is not blocked; Check if driver supports it */
-	if (!cdx_match(dr, dev))
+	if (!cdx_bus_match(&dr->driver, &dev->device))
 		/* Match of device and driver failed */
 		return 1;
 
@@ -524,6 +523,7 @@ struct rte_cdx_bus rte_cdx_bus = {
 		.scan = cdx_scan,
 		.probe = cdx_probe,
 		.find_device = rte_bus_generic_find_device,
+		.match = cdx_bus_match,
 		.plug = cdx_plug,
 		.unplug = cdx_unplug,
 		.parse = cdx_parse,
diff --git a/drivers/bus/dpaa/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c
index b3a754cbf4..ca80fff6ec 100644
--- a/drivers/bus/dpaa/dpaa_bus.c
+++ b/drivers/bus/dpaa/dpaa_bus.c
@@ -626,19 +626,16 @@ rte_dpaa_driver_unregister(struct rte_dpaa_driver *driver)
 	rte_bus_remove_driver(&rte_dpaa_bus.bus, &driver->driver);
 }
 
-static int
-rte_dpaa_device_match(struct rte_dpaa_driver *drv,
-		      struct rte_dpaa_device *dev)
+static bool
+dpaa_bus_match(const struct rte_driver *drv, const struct rte_device *dev)
 {
-	if (!drv || !dev) {
-		DPAA_BUS_DEBUG("Invalid drv or dev received.");
-		return -1;
-	}
+	const struct rte_dpaa_driver *dpaa_drv = RTE_BUS_DRIVER(drv, *dpaa_drv);
+	const struct rte_dpaa_device *dpaa_dev = RTE_BUS_DEVICE(dev, *dpaa_dev);
 
-	if (drv->drv_type == dev->device_type)
-		return 0;
+	if (dpaa_drv->drv_type == dpaa_dev->device_type)
+		return true;
 
-	return -1;
+	return false;
 }
 
 static int
@@ -793,8 +790,7 @@ 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) {
-			ret = rte_dpaa_device_match(drv, dev);
-			if (ret)
+			if (!dpaa_bus_match(&drv->driver, &dev->device))
 				continue;
 
 			if (rte_dev_is_probed(&dev->device))
@@ -902,6 +898,7 @@ static struct rte_dpaa_bus rte_dpaa_bus = {
 		.dev_compare = dpaa_bus_dev_compare,
 		.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,
 		.dev_iterate = rte_bus_generic_dev_iterate,
diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index 716f0178b5..8cd9b1eb88 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -381,14 +381,16 @@ rte_fslmc_scan(void)
 	return 0;
 }
 
-static int
-rte_fslmc_match(struct rte_dpaa2_driver *dpaa2_drv,
-		struct rte_dpaa2_device *dpaa2_dev)
+static bool
+fslmc_bus_match(const struct rte_driver *drv, const struct rte_device *dev)
 {
+	const struct rte_dpaa2_driver *dpaa2_drv = RTE_BUS_DRIVER(drv, *dpaa2_drv);
+	const struct rte_dpaa2_device *dpaa2_dev = RTE_BUS_DEVICE(dev, *dpaa2_dev);
+
 	if (dpaa2_drv->drv_type == dpaa2_dev->dev_type)
-		return 0;
+		return true;
 
-	return 1;
+	return false;
 }
 
 static int
@@ -455,8 +457,7 @@ rte_fslmc_probe(void)
 
 	RTE_BUS_FOREACH_DEV(dev, &rte_fslmc_bus.bus) {
 		RTE_BUS_FOREACH_DRV(drv, &rte_fslmc_bus.bus) {
-			ret = rte_fslmc_match(drv, dev);
-			if (ret)
+			if (!fslmc_bus_match(&drv->driver, &dev->device))
 				continue;
 
 			if (rte_dev_is_probed(&dev->device))
@@ -504,14 +505,12 @@ rte_fslmc_driver_unregister(struct rte_dpaa2_driver *driver)
 static inline int
 fslmc_all_device_support_iova(void)
 {
-	int ret = 0;
 	struct rte_dpaa2_device *dev;
 	struct rte_dpaa2_driver *drv;
 
 	RTE_BUS_FOREACH_DEV(dev, &rte_fslmc_bus.bus) {
 		RTE_BUS_FOREACH_DRV(drv, &rte_fslmc_bus.bus) {
-			ret = rte_fslmc_match(drv, dev);
-			if (ret)
+			if (!fslmc_bus_match(&drv->driver, &dev->device))
 				continue;
 			/* if the driver is not supporting IOVA */
 			if (!(drv->drv_flags & RTE_DPAA2_DRV_IOVA_AS_VA))
@@ -548,8 +547,7 @@ fslmc_bus_plug(struct rte_device *rte_dev)
 	struct rte_dpaa2_driver *drv;
 
 	RTE_BUS_FOREACH_DRV(drv, &rte_fslmc_bus.bus) {
-		ret = rte_fslmc_match(drv, dev);
-		if (ret)
+		if (!fslmc_bus_match(&drv->driver, &dev->device))
 			continue;
 
 		if (rte_dev_is_probed(&dev->device))
@@ -602,6 +600,7 @@ struct rte_fslmc_bus rte_fslmc_bus = {
 		.dev_compare = fslmc_dev_compare,
 		.find_device = rte_bus_generic_find_device,
 		.get_iommu_class = rte_dpaa2_get_iommu_class,
+		.match = fslmc_bus_match,
 		.plug = fslmc_bus_plug,
 		.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 7d3331fe7e..021171e955 100644
--- a/drivers/bus/ifpga/ifpga_bus.c
+++ b/drivers/bus/ifpga/ifpga_bus.c
@@ -245,10 +245,11 @@ ifpga_scan(void)
 /*
  * Match the AFU Driver and AFU Device using the ID Table
  */
-static int
-rte_afu_match(const struct rte_afu_driver *afu_drv,
-	      const struct rte_afu_device *afu_dev)
+static bool
+ifpga_bus_match(const struct rte_driver *drv, const struct rte_device *dev)
 {
+	const struct rte_afu_driver *afu_drv = RTE_BUS_DRIVER(drv, *afu_drv);
+	const struct rte_afu_device *afu_dev = RTE_BUS_DEVICE(dev, *afu_dev);
 	const struct rte_afu_uuid *id_table;
 
 	for (id_table = afu_drv->id_table;
@@ -260,10 +261,10 @@ rte_afu_match(const struct rte_afu_driver *afu_drv,
 				 afu_dev->id.uuid.uuid_high)
 			continue;
 
-		return 1;
+		return true;
 	}
 
-	return 0;
+	return false;
 }
 
 static int
@@ -272,7 +273,7 @@ ifpga_probe_one_driver(struct rte_afu_driver *drv,
 {
 	int ret;
 
-	if (!rte_afu_match(drv, afu_dev))
+	if (!ifpga_bus_match(&drv->driver, &afu_dev->device))
 		/* Match of device and driver failed */
 		return 1;
 
@@ -452,6 +453,7 @@ static struct rte_bus rte_ifpga_bus = {
 	.probe       = ifpga_probe,
 	.cleanup     = ifpga_cleanup,
 	.find_device = rte_bus_generic_find_device,
+	.match       = ifpga_bus_match,
 	.plug        = ifpga_plug,
 	.unplug      = ifpga_unplug,
 	.parse       = ifpga_parse,
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index 70ce63eac7..d7fda1752a 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -141,13 +141,12 @@ pci_unmap_resource(void *requested_addr, size_t size)
 	} else
 		PCI_LOG(DEBUG, "  PCI memory unmapped at %p", requested_addr);
 }
-/*
- * Match the PCI Driver and Device using the ID Table
- */
-int
-rte_pci_match(const struct rte_pci_driver *pci_drv,
-	      const struct rte_pci_device *pci_dev)
+
+static bool
+pci_bus_match(const struct rte_driver *drv, const struct rte_device *dev)
 {
+	const struct rte_pci_driver *pci_drv = RTE_BUS_DRIVER(drv, *pci_drv);
+	const struct rte_pci_device *pci_dev = RTE_BUS_DEVICE(dev, *pci_dev);
 	const struct rte_pci_id *id_table;
 
 	for (id_table = pci_drv->id_table; id_table->vendor_id != 0;
@@ -171,10 +170,10 @@ rte_pci_match(const struct rte_pci_driver *pci_drv,
 				id_table->class_id != RTE_CLASS_ANY_ID)
 			continue;
 
-		return 1;
+		return true;
 	}
 
-	return 0;
+	return false;
 }
 
 /*
@@ -195,7 +194,7 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 	loc = &dev->addr;
 
 	/* The device is not blocked; Check if driver supports it */
-	if (!rte_pci_match(dr, dev))
+	if (!pci_bus_match(&dr->driver, &dev->device))
 		/* Match of device and driver failed */
 		return 1;
 
@@ -680,7 +679,7 @@ rte_pci_get_iommu_class(void)
 		RTE_BUS_FOREACH_DRV(drv, &rte_pci_bus.bus) {
 			enum rte_iova_mode dev_iova_mode;
 
-			if (!rte_pci_match(drv, dev))
+			if (!pci_bus_match(&drv->driver, &dev->device))
 				continue;
 
 			dev_iova_mode = pci_device_iova_mode(drv, dev);
@@ -861,6 +860,7 @@ struct rte_pci_bus rte_pci_bus = {
 		.probe = pci_probe,
 		.cleanup = pci_cleanup,
 		.find_device = rte_bus_generic_find_device,
+		.match = pci_bus_match,
 		.plug = pci_plug,
 		.unplug = pci_unplug,
 		.parse = pci_parse,
diff --git a/drivers/bus/pci/private.h b/drivers/bus/pci/private.h
index 21637882f8..c54ea7b9d8 100644
--- a/drivers/bus/pci/private.h
+++ b/drivers/bus/pci/private.h
@@ -217,21 +217,6 @@ pci_uio_remap_resource(struct rte_pci_device *dev);
 int pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
 		struct mapped_pci_resource *uio_res, int map_idx);
 
-/*
- * Match the PCI Driver and Device using the ID Table
- *
- * @param pci_drv
- *      PCI driver from which ID table would be extracted
- * @param pci_dev
- *      PCI device to match against the driver
- * @return
- *      1 for successful match
- *      0 for unsuccessful match
- */
-int
-rte_pci_match(const struct rte_pci_driver *pci_drv,
-	      const struct rte_pci_device *pci_dev);
-
 /**
  * OS specific callbacks for rte_pci_get_iommu_class
  *
diff --git a/drivers/bus/platform/platform.c b/drivers/bus/platform/platform.c
index 636f051049..3d6b6efe6e 100644
--- a/drivers/bus/platform/platform.c
+++ b/drivers/bus/platform/platform.c
@@ -371,8 +371,10 @@ driver_probe_device(struct rte_platform_driver *pdrv, struct rte_platform_device
 }
 
 static bool
-driver_match_device(struct rte_platform_driver *pdrv, struct rte_platform_device *pdev)
+platform_bus_match(const struct rte_driver *drv, const struct rte_device *dev)
 {
+	const struct rte_platform_driver *pdrv = RTE_BUS_DRIVER(drv, *pdrv);
+	const struct rte_platform_device *pdev = RTE_BUS_DEVICE(dev, *pdev);
 	bool match = false;
 	char *kdrv;
 
@@ -408,7 +410,7 @@ device_attach(struct rte_platform_device *pdev)
 	struct rte_platform_driver *pdrv;
 
 	RTE_BUS_FOREACH_DRV(pdrv, &platform_bus.bus) {
-		if (driver_match_device(pdrv, pdev))
+		if (platform_bus_match(&pdrv->driver, &pdev->device))
 			break;
 	}
 
@@ -488,7 +490,7 @@ platform_bus_parse(const char *name, void *addr)
 	rte_strscpy(pdev.name, name, sizeof(pdev.name));
 
 	RTE_BUS_FOREACH_DRV(pdrv, &platform_bus.bus) {
-		if (driver_match_device(pdrv, &pdev))
+		if (platform_bus_match(&pdrv->driver, &pdev.device))
 			break;
 	}
 
@@ -556,6 +558,7 @@ struct rte_platform_bus platform_bus = {
 		.scan = platform_bus_scan,
 		.probe = platform_bus_probe,
 		.find_device = rte_bus_generic_find_device,
+		.match = platform_bus_match,
 		.plug = platform_bus_plug,
 		.unplug = platform_bus_unplug,
 		.parse = platform_bus_parse,
diff --git a/drivers/bus/uacce/uacce.c b/drivers/bus/uacce/uacce.c
index 153ebc5eea..bc2858a5c5 100644
--- a/drivers/bus/uacce/uacce.c
+++ b/drivers/bus/uacce/uacce.c
@@ -314,38 +314,36 @@ uacce_match_api(const struct rte_uacce_device *dev, bool forward_compat,
 }
 
 static bool
-uacce_match(const struct rte_uacce_driver *dr, struct rte_uacce_device *dev)
+uacce_bus_match(const struct rte_driver *drv, const struct rte_device *dev)
 {
+	const struct rte_uacce_driver *dr = RTE_BUS_DRIVER(drv, *dr);
+	const struct rte_uacce_device *uacce_dev = RTE_BUS_DEVICE(dev, *uacce_dev);
 	bool forward_compat = !!(dr->drv_flags & RTE_UACCE_DRV_FORWARD_COMPATIBILITY_DEV);
-	uint32_t api_ver = uacce_calc_api_ver(dev->api, NULL);
 	const struct rte_uacce_id *id_table;
 	const char *map;
 	uint32_t len;
 
 	for (id_table = dr->id_table; id_table->dev_api != NULL; id_table++) {
-		if (!uacce_match_api(dev, forward_compat, id_table))
+		if (!uacce_match_api(uacce_dev, forward_compat, id_table))
 			continue;
 
-		if (id_table->dev_alg == NULL) {
-			dev->api_ver = api_ver;
+		if (id_table->dev_alg == NULL)
 			return true;
-		}
 
 		/* The dev->algs's algrothims is separated by new line, for
 		 * example: dev->algs could be: aaa\nbbbb\ncc, which has three
 		 * algorithms: aaa, bbbb and cc.
 		 * The id_table->dev_alg should be a single algrithm, e.g. bbbb.
 		 */
-		map = strstr(dev->algs, id_table->dev_alg);
+		map = strstr(uacce_dev->algs, id_table->dev_alg);
 		if (map == NULL)
 			continue;
-		if (map != dev->algs && map[-1] != '\n')
+		if (map != uacce_dev->algs && map[-1] != '\n')
 			continue;
 		len = strlen(id_table->dev_alg);
 		if (map[len] != '\0' && map[len] != '\n')
 			continue;
 
-		dev->api_ver = api_ver;
 		return true;
 	}
 
@@ -359,7 +357,7 @@ uacce_probe_one_driver(struct rte_uacce_driver *dr, struct rte_uacce_device *dev
 	bool already_probed;
 	int ret;
 
-	if (!uacce_match(dr, dev))
+	if (!uacce_bus_match(&dr->driver, &dev->device))
 		/* Match of device and driver failed */
 		return 1;
 
@@ -626,6 +624,7 @@ static struct rte_uacce_bus uacce_bus = {
 		.scan = uacce_scan,
 		.probe = uacce_probe,
 		.cleanup = uacce_cleanup,
+		.match = uacce_bus_match,
 		.plug = uacce_plug,
 		.unplug = uacce_unplug,
 		.find_device = rte_bus_generic_find_device,
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index 3e610bd780..a4f6168581 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -162,6 +162,25 @@ vdev_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova, size_t len)
 	return 0;
 }
 
+/*
+ * Check if a vdev driver matches a vdev device by name.
+ */
+static bool
+vdev_bus_match(const struct rte_driver *drv, const struct rte_device *dev)
+{
+	const char *name = dev->name;
+
+	/* Check driver name match */
+	if (strncmp(drv->name, name, strlen(drv->name)) == 0)
+		return true;
+
+	/* Check driver alias match */
+	if (drv->alias && strncmp(drv->alias, name, strlen(drv->alias)) == 0)
+		return true;
+
+	return false;
+}
+
 static int
 vdev_probe_all_drivers(struct rte_vdev_device *dev)
 {
@@ -640,6 +659,7 @@ static struct rte_bus rte_vdev_bus = {
 	.probe = vdev_probe,
 	.cleanup = vdev_cleanup,
 	.find_device = vdev_find_device,
+	.match = vdev_bus_match,
 	.plug = vdev_plug,
 	.unplug = vdev_unplug,
 	.parse = vdev_parse,
diff --git a/drivers/bus/vmbus/vmbus_common.c b/drivers/bus/vmbus/vmbus_common.c
index 3260bd5395..d811f1a229 100644
--- a/drivers/bus/vmbus/vmbus_common.c
+++ b/drivers/bus/vmbus/vmbus_common.c
@@ -65,25 +65,15 @@ vmbus_unmap_resource(void *requested_addr, size_t size)
 	}
 }
 
-/**
- * Match the VMBUS driver and device using UUID table
- *
- * @param drv
- *	VMBUS driver from which ID table would be extracted
- * @param pci_dev
- *	VMBUS device to match against the driver
- * @return
- *	true for successful match
- *	false for unsuccessful match
- */
 static bool
-vmbus_match(const struct rte_vmbus_driver *dr,
-	    const struct rte_vmbus_device *dev)
+vmbus_bus_match(const struct rte_driver *drv, const struct rte_device *dev)
 {
+	const struct rte_vmbus_driver *dr = RTE_BUS_DRIVER(drv, *dr);
+	const struct rte_vmbus_device *vmbus_dev = RTE_BUS_DEVICE(dev, *vmbus_dev);
 	const rte_uuid_t *id_table;
 
 	for (id_table = dr->id_table; !rte_uuid_is_null(*id_table); ++id_table) {
-		if (rte_uuid_compare(*id_table, dev->class_id) == 0)
+		if (rte_uuid_compare(*id_table, vmbus_dev->class_id) == 0)
 			return true;
 	}
 
@@ -99,7 +89,7 @@ vmbus_probe_one_driver(struct rte_vmbus_driver *dr,
 	char guid[RTE_UUID_STRLEN];
 	int ret;
 
-	if (!vmbus_match(dr, dev))
+	if (!vmbus_bus_match(&dr->driver, &dev->device))
 		return 1;	 /* not supported */
 
 	rte_uuid_unparse(dev->device_id, guid, sizeof(guid));
@@ -281,6 +271,7 @@ struct rte_vmbus_bus rte_vmbus_bus = {
 		.probe = rte_vmbus_probe,
 		.cleanup = rte_vmbus_cleanup,
 		.find_device = rte_bus_generic_find_device,
+		.match = vmbus_bus_match,
 		.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 1c203e1288..c7591823ad 100644
--- a/drivers/dma/idxd/idxd_bus.c
+++ b/drivers/dma/idxd/idxd_bus.c
@@ -43,6 +43,7 @@ struct rte_dsa_device {
 /* forward prototypes */
 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(void);
 static enum rte_iova_mode dsa_get_iommu_class(void);
 static int dsa_addr_parse(const char *name, void *addr);
@@ -58,6 +59,7 @@ struct dsa_bus {
 struct dsa_bus dsa_bus = {
 	.bus = {
 		.scan = dsa_scan,
+		.match = dsa_match,
 		.probe = dsa_probe,
 		.find_device = rte_bus_generic_find_device,
 		.get_iommu_class = dsa_get_iommu_class,
@@ -126,7 +128,7 @@ idxd_bus_mmap_wq(struct rte_dsa_device *dev)
 }
 
 static int
-read_wq_string(struct rte_dsa_device *dev, const char *filename,
+read_wq_string(const struct rte_dsa_device *dev, const char *filename,
 		char *value, size_t valuelen)
 {
 	char sysfs_node[PATH_MAX];
@@ -241,7 +243,7 @@ idxd_probe_dsa(struct rte_dsa_device *dev)
 }
 
 static int
-is_for_this_process_use(struct rte_dsa_device *dev, const char *name)
+is_for_this_process_use(const char *name)
 {
 	char prefix[256];
 	int retval = 0;
@@ -256,9 +258,6 @@ is_for_this_process_use(struct rte_dsa_device *dev, const char *name)
 	if (strncmp(name, prefix, prefixlen) == 0 && name[prefixlen] == '_')
 		retval = 1;
 
-	if (retval)
-		retval = !rte_bus_device_is_ignored(&dsa_bus.bus, dev->device.name);
-
 	return retval;
 }
 
@@ -268,14 +267,8 @@ dsa_probe(void)
 	struct rte_dsa_device *dev;
 
 	RTE_BUS_FOREACH_DEV(dev, &dsa_bus.bus) {
-		char type[64], name[64];
-
-		if (read_wq_string(dev, "type", type, sizeof(type)) < 0 ||
-				read_wq_string(dev, "name", name, sizeof(name)) < 0)
-			continue;
-
-		if (strncmp(type, "user", 4) == 0 &&
-				is_for_this_process_use(dev, name)) {
+		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);
 			continue;
@@ -286,6 +279,22 @@ dsa_probe(void)
 	return 0;
 }
 
+static bool dsa_match(const struct rte_driver *drv, const struct rte_device *dev)
+{
+	const struct rte_dsa_device *dsa_dev = RTE_BUS_DEVICE(dev, *dsa_dev);
+
+	if (drv == &dsa_bus.driver) {
+		char type[64], name[64];
+
+		if (read_wq_string(dsa_dev, "type", type, sizeof(type)) >= 0 &&
+				read_wq_string(dsa_dev, "name", name, sizeof(name)) >= 0) {
+			return strncmp(type, "user", 4) == 0 && is_for_this_process_use(name);
+		}
+	}
+
+	return false;
+}
+
 static int
 dsa_scan(void)
 {
diff --git a/lib/eal/common/eal_common_bus.c b/lib/eal/common/eal_common_bus.c
index 46a8e68532..4884cdfa50 100644
--- a/lib/eal/common/eal_common_bus.c
+++ b/lib/eal/common/eal_common_bus.c
@@ -473,3 +473,22 @@ rte_bus_generic_dev_iterate(const struct rte_bus *bus,
 	rte_kvargs_free(kvargs);
 	return dev;
 }
+
+RTE_EXPORT_INTERNAL_SYMBOL(rte_bus_find_driver)
+struct rte_driver *
+rte_bus_find_driver(const struct rte_bus *bus, const struct rte_driver *start,
+	const struct rte_device *dev)
+{
+	struct rte_driver *drv;
+
+	if (start != NULL)
+		drv = TAILQ_NEXT(start, next);
+	else
+		drv = TAILQ_FIRST(&bus->driver_list);
+	while (drv != NULL) {
+		if (bus->match(drv, dev))
+			break;
+		drv = TAILQ_NEXT(drv, next);
+	}
+	return drv;
+}
diff --git a/lib/eal/include/bus_driver.h b/lib/eal/include/bus_driver.h
index e3e52928f4..8acd5d52bd 100644
--- a/lib/eal/include/bus_driver.h
+++ b/lib/eal/include/bus_driver.h
@@ -233,6 +233,24 @@ typedef int (*rte_bus_sigbus_handler_t)(const void *failure_addr);
  */
 typedef int (*rte_bus_cleanup_t)(void);
 
+/**
+ * Check if a driver matches a device.
+ *
+ * This function checks whether a driver can handle a given device.
+ * Matching logic is bus-specific (e.g., PCI uses ID tables, vdev uses
+ * name matching, fslmc uses device type).
+ *
+ * @param drv
+ *	Driver to check.
+ * @param dev
+ *	Device to check against.
+ *
+ * @return
+ *	true if the driver matches the device, false otherwise.
+ */
+typedef bool (*rte_bus_match_t)(const struct rte_driver *drv,
+				 const struct rte_device *dev);
+
 /**
  * Bus scan policies
  */
@@ -297,6 +315,7 @@ struct rte_bus {
 	rte_bus_scan_t scan;         /**< Scan for devices attached to 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_unplug_t unplug;     /**< Remove single device from driver */
 	rte_bus_parse_t parse;       /**< Parse a device name */
@@ -542,6 +561,25 @@ void rte_bus_add_driver(struct rte_bus *bus, struct rte_driver *driver);
 __rte_internal
 void rte_bus_remove_driver(struct rte_bus *bus, struct rte_driver *driver);
 
+/**
+ * Find the first driver that matches a device on a bus.
+ *
+ * Iterates through all registered drivers on the bus and returns the next
+ * one that matches the given device according to the bus's match operation.
+ *
+ * @param bus
+ *   A pointer to a rte_bus structure.
+ * @param start
+ *   Starting iteration context.
+ * @param dev
+ *   A pointer to a rte_device structure.
+ * @return
+ *   Pointer to the matching driver, or NULL if no match found.
+ */
+__rte_internal
+struct rte_driver *rte_bus_find_driver(const struct rte_bus *bus, const struct rte_driver *start,
+	const struct rte_device *dev);
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.53.0



More information about the dev mailing list