xref: /dpdk/drivers/bus/auxiliary/auxiliary_common.c (revision 30d38a718b9f63f0bda9e24dae90486303f1b206)
11afce308SXueming Li /* SPDX-License-Identifier: BSD-3-Clause
21afce308SXueming Li  * Copyright (c) 2021 NVIDIA Corporation & Affiliates
31afce308SXueming Li  */
41afce308SXueming Li 
51afce308SXueming Li #include <string.h>
61afce308SXueming Li #include <inttypes.h>
71afce308SXueming Li #include <stdint.h>
81afce308SXueming Li #include <stdbool.h>
91afce308SXueming Li #include <stdlib.h>
101afce308SXueming Li #include <stdio.h>
111afce308SXueming Li #include <sys/queue.h>
121afce308SXueming Li #include <rte_errno.h>
131afce308SXueming Li #include <rte_interrupts.h>
141afce308SXueming Li #include <rte_log.h>
15a04322f6SDavid Marchand #include <bus_driver.h>
161afce308SXueming Li #include <rte_per_lcore.h>
171afce308SXueming Li #include <rte_memory.h>
181afce308SXueming Li #include <rte_eal.h>
191afce308SXueming Li #include <rte_eal_paging.h>
20e9b3d79bSDmitry Kozlyuk #include <rte_lcore.h>
211afce308SXueming Li #include <rte_string_fns.h>
221afce308SXueming Li #include <rte_common.h>
231afce308SXueming Li #include <rte_devargs.h>
241afce308SXueming Li 
251afce308SXueming Li #include "private.h"
261afce308SXueming Li 
271afce308SXueming Li static struct rte_devargs *
auxiliary_devargs_lookup(const char * name)281afce308SXueming Li auxiliary_devargs_lookup(const char *name)
291afce308SXueming Li {
301afce308SXueming Li 	struct rte_devargs *devargs;
311afce308SXueming Li 
321afce308SXueming Li 	RTE_EAL_DEVARGS_FOREACH(RTE_BUS_AUXILIARY_NAME, devargs) {
331afce308SXueming Li 		if (strcmp(devargs->name, name) == 0)
341afce308SXueming Li 			return devargs;
351afce308SXueming Li 	}
361afce308SXueming Li 	return NULL;
371afce308SXueming Li }
381afce308SXueming Li 
391afce308SXueming Li /*
401afce308SXueming Li  * Test whether the auxiliary device exist.
411afce308SXueming Li  *
421afce308SXueming Li  * Stub for OS not supporting auxiliary bus.
431afce308SXueming Li  */
441afce308SXueming Li __rte_weak bool
auxiliary_dev_exists(const char * name)451afce308SXueming Li auxiliary_dev_exists(const char *name)
461afce308SXueming Li {
471afce308SXueming Li 	RTE_SET_USED(name);
481afce308SXueming Li 	return false;
491afce308SXueming Li }
501afce308SXueming Li 
511afce308SXueming Li /*
521afce308SXueming Li  * Scan the devices in the auxiliary bus.
531afce308SXueming Li  *
541afce308SXueming Li  * Stub for OS not supporting auxiliary bus.
551afce308SXueming Li  */
561afce308SXueming Li __rte_weak int
auxiliary_scan(void)571afce308SXueming Li auxiliary_scan(void)
581afce308SXueming Li {
591afce308SXueming Li 	return 0;
601afce308SXueming Li }
611afce308SXueming Li 
621afce308SXueming Li /*
631afce308SXueming Li  * Update a device's devargs being scanned.
641afce308SXueming Li  */
651afce308SXueming Li void
auxiliary_on_scan(struct rte_auxiliary_device * aux_dev)661afce308SXueming Li auxiliary_on_scan(struct rte_auxiliary_device *aux_dev)
671afce308SXueming Li {
681afce308SXueming Li 	aux_dev->device.devargs = auxiliary_devargs_lookup(aux_dev->name);
691afce308SXueming Li }
701afce308SXueming Li 
711afce308SXueming Li /*
721afce308SXueming Li  * Match the auxiliary driver and device using driver function.
731afce308SXueming Li  */
741afce308SXueming Li bool
auxiliary_match(const struct rte_auxiliary_driver * aux_drv,const struct rte_auxiliary_device * aux_dev)751afce308SXueming Li auxiliary_match(const struct rte_auxiliary_driver *aux_drv,
761afce308SXueming Li 		const struct rte_auxiliary_device *aux_dev)
771afce308SXueming Li {
781afce308SXueming Li 	if (aux_drv->match == NULL)
791afce308SXueming Li 		return false;
801afce308SXueming Li 	return aux_drv->match(aux_dev->name);
811afce308SXueming Li }
821afce308SXueming Li 
831afce308SXueming Li /*
841afce308SXueming Li  * Call the probe() function of the driver.
851afce308SXueming Li  */
861afce308SXueming Li static int
rte_auxiliary_probe_one_driver(struct rte_auxiliary_driver * drv,struct rte_auxiliary_device * dev)871afce308SXueming Li rte_auxiliary_probe_one_driver(struct rte_auxiliary_driver *drv,
881afce308SXueming Li 			       struct rte_auxiliary_device *dev)
891afce308SXueming Li {
901afce308SXueming Li 	enum rte_iova_mode iova_mode;
911afce308SXueming Li 	int ret;
921afce308SXueming Li 
931afce308SXueming Li 	if (drv == NULL || dev == NULL)
941afce308SXueming Li 		return -EINVAL;
951afce308SXueming Li 
961afce308SXueming Li 	/* Check if driver supports it. */
971afce308SXueming Li 	if (!auxiliary_match(drv, dev))
981afce308SXueming Li 		/* Match of device and driver failed */
991afce308SXueming Li 		return 1;
1001afce308SXueming Li 
1011afce308SXueming Li 	/* No initialization when marked as blocked, return without error. */
1021afce308SXueming Li 	if (dev->device.devargs != NULL &&
1031afce308SXueming Li 	    dev->device.devargs->policy == RTE_DEV_BLOCKED) {
1041afce308SXueming Li 		AUXILIARY_LOG(INFO, "Device is blocked, not initializing");
1051afce308SXueming Li 		return -1;
1061afce308SXueming Li 	}
1071afce308SXueming Li 
1087dcd73e3SOlivier Matz 	if (dev->device.numa_node < 0 && rte_socket_count() > 1)
109*30d38a71SDavid Marchand 		AUXILIARY_LOG(INFO, "Device %s is not NUMA-aware", dev->name);
1101afce308SXueming Li 
111bc967149SBing Zhao 	if (rte_dev_is_probed(&dev->device)) {
112*30d38a71SDavid Marchand 		AUXILIARY_LOG(DEBUG, "Device %s is already probed on auxiliary bus",
113bc967149SBing Zhao 			dev->device.name);
114bc967149SBing Zhao 		return -EEXIST;
115bc967149SBing Zhao 	}
116bc967149SBing Zhao 
1171afce308SXueming Li 	iova_mode = rte_eal_iova_mode();
1181afce308SXueming Li 	if ((drv->drv_flags & RTE_AUXILIARY_DRV_NEED_IOVA_AS_VA) > 0 &&
1191afce308SXueming Li 	    iova_mode != RTE_IOVA_VA) {
1201afce308SXueming Li 		AUXILIARY_LOG(ERR, "Driver %s expecting VA IOVA mode but current mode is PA, not initializing",
1211afce308SXueming Li 			      drv->driver.name);
1221afce308SXueming Li 		return -EINVAL;
1231afce308SXueming Li 	}
1241afce308SXueming Li 
125d61138d4SHarman Kalra 	/* Allocate interrupt instance */
126d61138d4SHarman Kalra 	dev->intr_handle =
127d61138d4SHarman Kalra 		rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE);
128d61138d4SHarman Kalra 	if (dev->intr_handle == NULL) {
129d61138d4SHarman Kalra 		AUXILIARY_LOG(ERR, "Could not allocate interrupt instance for device %s",
130d61138d4SHarman Kalra 			dev->name);
131d61138d4SHarman Kalra 		return -ENOMEM;
132d61138d4SHarman Kalra 	}
133d61138d4SHarman Kalra 
1341afce308SXueming Li 	dev->driver = drv;
1351afce308SXueming Li 
1361afce308SXueming Li 	AUXILIARY_LOG(INFO, "Probe auxiliary driver: %s device: %s (NUMA node %i)",
1371afce308SXueming Li 		      drv->driver.name, dev->name, dev->device.numa_node);
1381afce308SXueming Li 	ret = drv->probe(drv, dev);
139d61138d4SHarman Kalra 	if (ret != 0) {
1401afce308SXueming Li 		dev->driver = NULL;
141d61138d4SHarman Kalra 		rte_intr_instance_free(dev->intr_handle);
142d61138d4SHarman Kalra 		dev->intr_handle = NULL;
143d61138d4SHarman Kalra 	} else {
1441afce308SXueming Li 		dev->device.driver = &drv->driver;
145d61138d4SHarman Kalra 	}
1461afce308SXueming Li 
1471afce308SXueming Li 	return ret;
1481afce308SXueming Li }
1491afce308SXueming Li 
1501afce308SXueming Li /*
1511afce308SXueming Li  * Call the remove() function of the driver.
1521afce308SXueming Li  */
1531afce308SXueming Li static int
rte_auxiliary_driver_remove_dev(struct rte_auxiliary_device * dev)1541afce308SXueming Li rte_auxiliary_driver_remove_dev(struct rte_auxiliary_device *dev)
1551afce308SXueming Li {
1561afce308SXueming Li 	struct rte_auxiliary_driver *drv;
1571afce308SXueming Li 	int ret = 0;
1581afce308SXueming Li 
1591afce308SXueming Li 	if (dev == NULL)
1601afce308SXueming Li 		return -EINVAL;
1611afce308SXueming Li 
1621afce308SXueming Li 	drv = dev->driver;
1631afce308SXueming Li 
1641afce308SXueming Li 	AUXILIARY_LOG(DEBUG, "Driver %s remove auxiliary device %s on NUMA node %i",
1651afce308SXueming Li 		      drv->driver.name, dev->name, dev->device.numa_node);
1661afce308SXueming Li 
1671afce308SXueming Li 	if (drv->remove != NULL) {
1681afce308SXueming Li 		ret = drv->remove(dev);
1691afce308SXueming Li 		if (ret < 0)
1701afce308SXueming Li 			return ret;
1711afce308SXueming Li 	}
1721afce308SXueming Li 
1731afce308SXueming Li 	/* clear driver structure */
1741afce308SXueming Li 	dev->driver = NULL;
1751afce308SXueming Li 	dev->device.driver = NULL;
1761afce308SXueming Li 
1771afce308SXueming Li 	return 0;
1781afce308SXueming Li }
1791afce308SXueming Li 
1801afce308SXueming Li /*
1811afce308SXueming Li  * Call the probe() function of all registered drivers for the given device.
1821afce308SXueming Li  * Return < 0 if initialization failed.
1831afce308SXueming Li  * Return 1 if no driver is found for this device.
1841afce308SXueming Li  */
1851afce308SXueming Li static int
auxiliary_probe_all_drivers(struct rte_auxiliary_device * dev)1861afce308SXueming Li auxiliary_probe_all_drivers(struct rte_auxiliary_device *dev)
1871afce308SXueming Li {
1881afce308SXueming Li 	struct rte_auxiliary_driver *drv;
1891afce308SXueming Li 	int rc;
1901afce308SXueming Li 
1911afce308SXueming Li 	if (dev == NULL)
1921afce308SXueming Li 		return -EINVAL;
1931afce308SXueming Li 
1941afce308SXueming Li 	FOREACH_DRIVER_ON_AUXILIARY_BUS(drv) {
1951afce308SXueming Li 		if (!drv->match(dev->name))
1961afce308SXueming Li 			continue;
1971afce308SXueming Li 
1981afce308SXueming Li 		rc = rte_auxiliary_probe_one_driver(drv, dev);
1991afce308SXueming Li 		if (rc < 0)
2001afce308SXueming Li 			/* negative value is an error */
2011afce308SXueming Li 			return rc;
2021afce308SXueming Li 		if (rc > 0)
2031afce308SXueming Li 			/* positive value means driver doesn't support it */
2041afce308SXueming Li 			continue;
2051afce308SXueming Li 		return 0;
2061afce308SXueming Li 	}
2071afce308SXueming Li 	return 1;
2081afce308SXueming Li }
2091afce308SXueming Li 
2101afce308SXueming Li /*
2111afce308SXueming Li  * Scan the content of the auxiliary bus, and call the probe function for
2121afce308SXueming Li  * all registered drivers to try to probe discovered devices.
2131afce308SXueming Li  */
2141afce308SXueming Li static int
auxiliary_probe(void)2151afce308SXueming Li auxiliary_probe(void)
2161afce308SXueming Li {
2171afce308SXueming Li 	struct rte_auxiliary_device *dev = NULL;
2181afce308SXueming Li 	size_t probed = 0, failed = 0;
2191afce308SXueming Li 	int ret = 0;
2201afce308SXueming Li 
2211afce308SXueming Li 	FOREACH_DEVICE_ON_AUXILIARY_BUS(dev) {
2221afce308SXueming Li 		probed++;
2231afce308SXueming Li 
2241afce308SXueming Li 		ret = auxiliary_probe_all_drivers(dev);
2251afce308SXueming Li 		if (ret < 0) {
2261afce308SXueming Li 			if (ret != -EEXIST) {
2271afce308SXueming Li 				AUXILIARY_LOG(ERR, "Requested device %s cannot be used",
2281afce308SXueming Li 					      dev->name);
2291afce308SXueming Li 				rte_errno = errno;
2301afce308SXueming Li 				failed++;
2311afce308SXueming Li 			}
2321afce308SXueming Li 			ret = 0;
2331afce308SXueming Li 		}
2341afce308SXueming Li 	}
2351afce308SXueming Li 
2361afce308SXueming Li 	return (probed && probed == failed) ? -1 : 0;
2371afce308SXueming Li }
2381afce308SXueming Li 
2391afce308SXueming Li static int
auxiliary_parse(const char * name,void * addr)2401afce308SXueming Li auxiliary_parse(const char *name, void *addr)
2411afce308SXueming Li {
2421afce308SXueming Li 	struct rte_auxiliary_driver *drv = NULL;
2431afce308SXueming Li 	const char **out = addr;
2441afce308SXueming Li 
2451afce308SXueming Li 	/* Allow empty device name "auxiliary:" to bypass entire bus scan. */
2461afce308SXueming Li 	if (strlen(name) == 0)
2471afce308SXueming Li 		return 0;
2481afce308SXueming Li 
2491afce308SXueming Li 	FOREACH_DRIVER_ON_AUXILIARY_BUS(drv) {
2501afce308SXueming Li 		if (drv->match(name))
2511afce308SXueming Li 			break;
2521afce308SXueming Li 	}
2531afce308SXueming Li 	if (drv != NULL && addr != NULL)
2541afce308SXueming Li 		*out = name;
2551afce308SXueming Li 	return drv != NULL ? 0 : -1;
2561afce308SXueming Li }
2571afce308SXueming Li 
2581afce308SXueming Li /* Register a driver */
2591afce308SXueming Li void
rte_auxiliary_register(struct rte_auxiliary_driver * driver)2601afce308SXueming Li rte_auxiliary_register(struct rte_auxiliary_driver *driver)
2611afce308SXueming Li {
2621afce308SXueming Li 	TAILQ_INSERT_TAIL(&auxiliary_bus.driver_list, driver, next);
2631afce308SXueming Li }
2641afce308SXueming Li 
2651afce308SXueming Li /* Unregister a driver */
2661afce308SXueming Li void
rte_auxiliary_unregister(struct rte_auxiliary_driver * driver)2671afce308SXueming Li rte_auxiliary_unregister(struct rte_auxiliary_driver *driver)
2681afce308SXueming Li {
2691afce308SXueming Li 	TAILQ_REMOVE(&auxiliary_bus.driver_list, driver, next);
2701afce308SXueming Li }
2711afce308SXueming Li 
2721afce308SXueming Li /* Add a device to auxiliary bus */
2731afce308SXueming Li void
auxiliary_add_device(struct rte_auxiliary_device * aux_dev)2741afce308SXueming Li auxiliary_add_device(struct rte_auxiliary_device *aux_dev)
2751afce308SXueming Li {
2761afce308SXueming Li 	TAILQ_INSERT_TAIL(&auxiliary_bus.device_list, aux_dev, next);
2771afce308SXueming Li }
2781afce308SXueming Li 
2791afce308SXueming Li /* Insert a device into a predefined position in auxiliary bus */
2801afce308SXueming Li void
auxiliary_insert_device(struct rte_auxiliary_device * exist_aux_dev,struct rte_auxiliary_device * new_aux_dev)2811afce308SXueming Li auxiliary_insert_device(struct rte_auxiliary_device *exist_aux_dev,
2821afce308SXueming Li 			struct rte_auxiliary_device *new_aux_dev)
2831afce308SXueming Li {
2841afce308SXueming Li 	TAILQ_INSERT_BEFORE(exist_aux_dev, new_aux_dev, next);
2851afce308SXueming Li }
2861afce308SXueming Li 
2871afce308SXueming Li /* Remove a device from auxiliary bus */
2881afce308SXueming Li static void
rte_auxiliary_remove_device(struct rte_auxiliary_device * auxiliary_dev)2891afce308SXueming Li rte_auxiliary_remove_device(struct rte_auxiliary_device *auxiliary_dev)
2901afce308SXueming Li {
2911afce308SXueming Li 	TAILQ_REMOVE(&auxiliary_bus.device_list, auxiliary_dev, next);
2921afce308SXueming Li }
2931afce308SXueming Li 
2941afce308SXueming Li static struct rte_device *
auxiliary_find_device(const struct rte_device * start,rte_dev_cmp_t cmp,const void * data)2951afce308SXueming Li auxiliary_find_device(const struct rte_device *start, rte_dev_cmp_t cmp,
2961afce308SXueming Li 		      const void *data)
2971afce308SXueming Li {
2981afce308SXueming Li 	const struct rte_auxiliary_device *pstart;
2991afce308SXueming Li 	struct rte_auxiliary_device *adev;
3001afce308SXueming Li 
3011afce308SXueming Li 	if (start != NULL) {
3021afce308SXueming Li 		pstart = RTE_DEV_TO_AUXILIARY_CONST(start);
3031afce308SXueming Li 		adev = TAILQ_NEXT(pstart, next);
3041afce308SXueming Li 	} else {
3051afce308SXueming Li 		adev = TAILQ_FIRST(&auxiliary_bus.device_list);
3061afce308SXueming Li 	}
3071afce308SXueming Li 	while (adev != NULL) {
3081afce308SXueming Li 		if (cmp(&adev->device, data) == 0)
3091afce308SXueming Li 			return &adev->device;
3101afce308SXueming Li 		adev = TAILQ_NEXT(adev, next);
3111afce308SXueming Li 	}
3121afce308SXueming Li 	return NULL;
3131afce308SXueming Li }
3141afce308SXueming Li 
3151afce308SXueming Li static int
auxiliary_plug(struct rte_device * dev)3161afce308SXueming Li auxiliary_plug(struct rte_device *dev)
3171afce308SXueming Li {
3181afce308SXueming Li 	if (!auxiliary_dev_exists(dev->name))
3191afce308SXueming Li 		return -ENOENT;
3201afce308SXueming Li 	return auxiliary_probe_all_drivers(RTE_DEV_TO_AUXILIARY(dev));
3211afce308SXueming Li }
3221afce308SXueming Li 
3231afce308SXueming Li static int
auxiliary_unplug(struct rte_device * dev)3241afce308SXueming Li auxiliary_unplug(struct rte_device *dev)
3251afce308SXueming Li {
3261afce308SXueming Li 	struct rte_auxiliary_device *adev;
3271afce308SXueming Li 	int ret;
3281afce308SXueming Li 
3291afce308SXueming Li 	adev = RTE_DEV_TO_AUXILIARY(dev);
3301afce308SXueming Li 	ret = rte_auxiliary_driver_remove_dev(adev);
3311afce308SXueming Li 	if (ret == 0) {
3321afce308SXueming Li 		rte_auxiliary_remove_device(adev);
3331afce308SXueming Li 		rte_devargs_remove(dev->devargs);
334d61138d4SHarman Kalra 		rte_intr_instance_free(adev->intr_handle);
3351afce308SXueming Li 		free(adev);
3361afce308SXueming Li 	}
3371afce308SXueming Li 	return ret;
3381afce308SXueming Li }
3391afce308SXueming Li 
3401afce308SXueming Li static int
auxiliary_cleanup(void)341057a0082SXueming Li auxiliary_cleanup(void)
342057a0082SXueming Li {
343057a0082SXueming Li 	struct rte_auxiliary_device *dev, *tmp_dev;
344057a0082SXueming Li 	int error = 0;
345057a0082SXueming Li 
346057a0082SXueming Li 	RTE_TAILQ_FOREACH_SAFE(dev, &auxiliary_bus.device_list, next, tmp_dev) {
347057a0082SXueming Li 		int ret;
348057a0082SXueming Li 
349057a0082SXueming Li 		ret = auxiliary_unplug(&dev->device);
350057a0082SXueming Li 		if (ret < 0) {
351057a0082SXueming Li 			rte_errno = errno;
352057a0082SXueming Li 			error = -1;
353057a0082SXueming Li 		}
354057a0082SXueming Li 	}
355057a0082SXueming Li 
356057a0082SXueming Li 	return error;
357057a0082SXueming Li }
358057a0082SXueming Li 
359057a0082SXueming Li static int
auxiliary_dma_map(struct rte_device * dev,void * addr,uint64_t iova,size_t len)3601afce308SXueming Li auxiliary_dma_map(struct rte_device *dev, void *addr, uint64_t iova, size_t len)
3611afce308SXueming Li {
3621afce308SXueming Li 	struct rte_auxiliary_device *aux_dev = RTE_DEV_TO_AUXILIARY(dev);
3631afce308SXueming Li 
3641afce308SXueming Li 	if (dev == NULL || aux_dev->driver == NULL) {
3651afce308SXueming Li 		rte_errno = EINVAL;
3661afce308SXueming Li 		return -1;
3671afce308SXueming Li 	}
3681afce308SXueming Li 	if (aux_dev->driver->dma_map == NULL) {
3691afce308SXueming Li 		rte_errno = ENOTSUP;
3701afce308SXueming Li 		return -1;
3711afce308SXueming Li 	}
3721afce308SXueming Li 	return aux_dev->driver->dma_map(aux_dev, addr, iova, len);
3731afce308SXueming Li }
3741afce308SXueming Li 
3751afce308SXueming Li static int
auxiliary_dma_unmap(struct rte_device * dev,void * addr,uint64_t iova,size_t len)3761afce308SXueming Li auxiliary_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova,
3771afce308SXueming Li 		    size_t len)
3781afce308SXueming Li {
3791afce308SXueming Li 	struct rte_auxiliary_device *aux_dev = RTE_DEV_TO_AUXILIARY(dev);
3801afce308SXueming Li 
3811afce308SXueming Li 	if (dev == NULL || aux_dev->driver == NULL) {
3821afce308SXueming Li 		rte_errno = EINVAL;
3831afce308SXueming Li 		return -1;
3841afce308SXueming Li 	}
3851afce308SXueming Li 	if (aux_dev->driver->dma_unmap == NULL) {
3861afce308SXueming Li 		rte_errno = ENOTSUP;
3871afce308SXueming Li 		return -1;
3881afce308SXueming Li 	}
3891afce308SXueming Li 	return aux_dev->driver->dma_unmap(aux_dev, addr, iova, len);
3901afce308SXueming Li }
3911afce308SXueming Li 
3921afce308SXueming Li bool
auxiliary_is_ignored_device(const char * name)3931afce308SXueming Li auxiliary_is_ignored_device(const char *name)
3941afce308SXueming Li {
3951afce308SXueming Li 	struct rte_devargs *devargs = auxiliary_devargs_lookup(name);
3961afce308SXueming Li 
3971afce308SXueming Li 	switch (auxiliary_bus.bus.conf.scan_mode) {
3981afce308SXueming Li 	case RTE_BUS_SCAN_ALLOWLIST:
3991afce308SXueming Li 		if (devargs && devargs->policy == RTE_DEV_ALLOWED)
4001afce308SXueming Li 			return false;
4011afce308SXueming Li 		break;
4021afce308SXueming Li 	case RTE_BUS_SCAN_UNDEFINED:
4031afce308SXueming Li 	case RTE_BUS_SCAN_BLOCKLIST:
4041afce308SXueming Li 		if (devargs == NULL || devargs->policy != RTE_DEV_BLOCKED)
4051afce308SXueming Li 			return false;
4061afce308SXueming Li 		break;
4071afce308SXueming Li 	}
4081afce308SXueming Li 	return true;
4091afce308SXueming Li }
4101afce308SXueming Li 
4111afce308SXueming Li static enum rte_iova_mode
auxiliary_get_iommu_class(void)4121afce308SXueming Li auxiliary_get_iommu_class(void)
4131afce308SXueming Li {
4141afce308SXueming Li 	const struct rte_auxiliary_driver *drv;
4151afce308SXueming Li 
4161afce308SXueming Li 	FOREACH_DRIVER_ON_AUXILIARY_BUS(drv) {
4171afce308SXueming Li 		if ((drv->drv_flags & RTE_AUXILIARY_DRV_NEED_IOVA_AS_VA) > 0)
4181afce308SXueming Li 			return RTE_IOVA_VA;
4191afce308SXueming Li 	}
4201afce308SXueming Li 
4211afce308SXueming Li 	return RTE_IOVA_DC;
4221afce308SXueming Li }
4231afce308SXueming Li 
4241afce308SXueming Li struct rte_auxiliary_bus auxiliary_bus = {
4251afce308SXueming Li 	.bus = {
4261afce308SXueming Li 		.scan = auxiliary_scan,
4271afce308SXueming Li 		.probe = auxiliary_probe,
428057a0082SXueming Li 		.cleanup = auxiliary_cleanup,
4291afce308SXueming Li 		.find_device = auxiliary_find_device,
4301afce308SXueming Li 		.plug = auxiliary_plug,
4311afce308SXueming Li 		.unplug = auxiliary_unplug,
4321afce308SXueming Li 		.parse = auxiliary_parse,
4331afce308SXueming Li 		.dma_map = auxiliary_dma_map,
4341afce308SXueming Li 		.dma_unmap = auxiliary_dma_unmap,
4351afce308SXueming Li 		.get_iommu_class = auxiliary_get_iommu_class,
4361afce308SXueming Li 		.dev_iterate = auxiliary_dev_iterate,
4371afce308SXueming Li 	},
4381afce308SXueming Li 	.device_list = TAILQ_HEAD_INITIALIZER(auxiliary_bus.device_list),
4391afce308SXueming Li 	.driver_list = TAILQ_HEAD_INITIALIZER(auxiliary_bus.driver_list),
4401afce308SXueming Li };
4411afce308SXueming Li 
4421afce308SXueming Li RTE_REGISTER_BUS(auxiliary, auxiliary_bus.bus);
4431afce308SXueming Li RTE_LOG_REGISTER_DEFAULT(auxiliary_bus_logtype, NOTICE);
444