xref: /dpdk/drivers/bus/auxiliary/linux/auxiliary.c (revision 7dcd73e37965ba0bfa430efeac362fe183ed0ae2)
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 <dirent.h>
71afce308SXueming Li 
81afce308SXueming Li #include <rte_log.h>
91afce308SXueming Li #include <rte_malloc.h>
101afce308SXueming Li #include <rte_devargs.h>
111afce308SXueming Li #include <rte_memcpy.h>
121afce308SXueming Li #include <eal_filesystem.h>
131afce308SXueming Li 
141afce308SXueming Li #include "../private.h"
151afce308SXueming Li 
161afce308SXueming Li #define AUXILIARY_SYSFS_PATH "/sys/bus/auxiliary/devices"
171afce308SXueming Li 
181afce308SXueming Li /* Scan one auxiliary sysfs entry, and fill the devices list from it. */
191afce308SXueming Li static int
auxiliary_scan_one(const char * dirname,const char * name)201afce308SXueming Li auxiliary_scan_one(const char *dirname, const char *name)
211afce308SXueming Li {
221afce308SXueming Li 	struct rte_auxiliary_device *dev;
231afce308SXueming Li 	struct rte_auxiliary_device *dev2;
241afce308SXueming Li 	char filename[PATH_MAX];
251afce308SXueming Li 	unsigned long tmp;
261afce308SXueming Li 	int ret;
271afce308SXueming Li 
281afce308SXueming Li 	dev = malloc(sizeof(*dev));
291afce308SXueming Li 	if (dev == NULL)
301afce308SXueming Li 		return -1;
311afce308SXueming Li 
321afce308SXueming Li 	memset(dev, 0, sizeof(*dev));
331afce308SXueming Li 	if (rte_strscpy(dev->name, name, sizeof(dev->name)) < 0) {
341afce308SXueming Li 		free(dev);
351afce308SXueming Li 		return -1;
361afce308SXueming Li 	}
371afce308SXueming Li 	dev->device.name = dev->name;
381afce308SXueming Li 	dev->device.bus = &auxiliary_bus.bus;
391afce308SXueming Li 
401afce308SXueming Li 	/* Get NUMA node, default to 0 if not present */
411afce308SXueming Li 	snprintf(filename, sizeof(filename), "%s/%s/numa_node",
421afce308SXueming Li 		 dirname, name);
43*7dcd73e3SOlivier Matz 	if (access(filename, F_OK) == 0 &&
44*7dcd73e3SOlivier Matz 	    eal_parse_sysfs_value(filename, &tmp) == 0)
451afce308SXueming Li 		dev->device.numa_node = tmp;
461afce308SXueming Li 	else
47*7dcd73e3SOlivier Matz 		dev->device.numa_node = SOCKET_ID_ANY;
481afce308SXueming Li 
491afce308SXueming Li 	auxiliary_on_scan(dev);
501afce308SXueming Li 
511afce308SXueming Li 	/* Device is valid, add in list (sorted) */
521afce308SXueming Li 	TAILQ_FOREACH(dev2, &auxiliary_bus.device_list, next) {
531afce308SXueming Li 		ret = strcmp(dev->name, dev2->name);
541afce308SXueming Li 		if (ret > 0)
551afce308SXueming Li 			continue;
561afce308SXueming Li 		if (ret < 0) {
571afce308SXueming Li 			auxiliary_insert_device(dev2, dev);
581afce308SXueming Li 		} else { /* already registered */
591afce308SXueming Li 			if (rte_dev_is_probed(&dev2->device) &&
601afce308SXueming Li 			    dev2->device.devargs != dev->device.devargs) {
611afce308SXueming Li 				/* To probe device with new devargs. */
621afce308SXueming Li 				rte_devargs_remove(dev2->device.devargs);
631afce308SXueming Li 				auxiliary_on_scan(dev2);
641afce308SXueming Li 			}
651afce308SXueming Li 			free(dev);
661afce308SXueming Li 		}
671afce308SXueming Li 		return 0;
681afce308SXueming Li 	}
691afce308SXueming Li 	auxiliary_add_device(dev);
701afce308SXueming Li 	return 0;
711afce308SXueming Li }
721afce308SXueming Li 
731afce308SXueming Li /*
741afce308SXueming Li  * Test whether the auxiliary device exist.
751afce308SXueming Li  */
761afce308SXueming Li bool
auxiliary_dev_exists(const char * name)771afce308SXueming Li auxiliary_dev_exists(const char *name)
781afce308SXueming Li {
791afce308SXueming Li 	DIR *dir;
801afce308SXueming Li 	char dirname[PATH_MAX];
811afce308SXueming Li 
821afce308SXueming Li 	snprintf(dirname, sizeof(dirname), "%s/%s",
831afce308SXueming Li 		 AUXILIARY_SYSFS_PATH, name);
841afce308SXueming Li 	dir = opendir(dirname);
851afce308SXueming Li 	if (dir == NULL)
861afce308SXueming Li 		return false;
871afce308SXueming Li 	closedir(dir);
881afce308SXueming Li 	return true;
891afce308SXueming Li }
901afce308SXueming Li 
911afce308SXueming Li /*
921afce308SXueming Li  * Scan the devices in the auxiliary bus.
931afce308SXueming Li  */
941afce308SXueming Li int
auxiliary_scan(void)951afce308SXueming Li auxiliary_scan(void)
961afce308SXueming Li {
971afce308SXueming Li 	struct dirent *e;
981afce308SXueming Li 	DIR *dir;
991afce308SXueming Li 	char dirname[PATH_MAX];
1001afce308SXueming Li 	struct rte_auxiliary_driver *drv;
1011afce308SXueming Li 
1021afce308SXueming Li 	dir = opendir(AUXILIARY_SYSFS_PATH);
1031afce308SXueming Li 	if (dir == NULL) {
1041afce308SXueming Li 		AUXILIARY_LOG(INFO, "%s not found, is auxiliary module loaded?",
1051afce308SXueming Li 			      AUXILIARY_SYSFS_PATH);
1061afce308SXueming Li 		return 0;
1071afce308SXueming Li 	}
1081afce308SXueming Li 
1091afce308SXueming Li 	while ((e = readdir(dir)) != NULL) {
1101afce308SXueming Li 		if (e->d_name[0] == '.')
1111afce308SXueming Li 			continue;
1121afce308SXueming Li 
1131afce308SXueming Li 		if (auxiliary_is_ignored_device(e->d_name))
1141afce308SXueming Li 			continue;
1151afce308SXueming Li 
1161afce308SXueming Li 		snprintf(dirname, sizeof(dirname), "%s/%s",
1171afce308SXueming Li 			 AUXILIARY_SYSFS_PATH, e->d_name);
1181afce308SXueming Li 
1191afce308SXueming Li 		/* Ignore if no driver can handle. */
1201afce308SXueming Li 		FOREACH_DRIVER_ON_AUXILIARY_BUS(drv) {
1211afce308SXueming Li 			if (drv->match(e->d_name))
1221afce308SXueming Li 				break;
1231afce308SXueming Li 		}
1241afce308SXueming Li 		if (drv == NULL)
1251afce308SXueming Li 			continue;
1261afce308SXueming Li 
1271afce308SXueming Li 		if (auxiliary_scan_one(dirname, e->d_name) < 0)
1281afce308SXueming Li 			goto error;
1291afce308SXueming Li 	}
1301afce308SXueming Li 	closedir(dir);
1311afce308SXueming Li 	return 0;
1321afce308SXueming Li 
1331afce308SXueming Li error:
1341afce308SXueming Li 	closedir(dir);
1351afce308SXueming Li 	return -1;
1361afce308SXueming Li }
137