1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) 2021 NVIDIA Corporation & Affiliates 3 */ 4 5 #include <string.h> 6 #include <dirent.h> 7 8 #include <rte_log.h> 9 #include <rte_bus.h> 10 #include <rte_malloc.h> 11 #include <rte_devargs.h> 12 #include <rte_memcpy.h> 13 #include <eal_filesystem.h> 14 15 #include "../rte_bus_auxiliary.h" 16 #include "../private.h" 17 18 #define AUXILIARY_SYSFS_PATH "/sys/bus/auxiliary/devices" 19 20 /* Scan one auxiliary sysfs entry, and fill the devices list from it. */ 21 static int 22 auxiliary_scan_one(const char *dirname, const char *name) 23 { 24 struct rte_auxiliary_device *dev; 25 struct rte_auxiliary_device *dev2; 26 char filename[PATH_MAX]; 27 unsigned long tmp; 28 int ret; 29 30 dev = malloc(sizeof(*dev)); 31 if (dev == NULL) 32 return -1; 33 34 memset(dev, 0, sizeof(*dev)); 35 if (rte_strscpy(dev->name, name, sizeof(dev->name)) < 0) { 36 free(dev); 37 return -1; 38 } 39 dev->device.name = dev->name; 40 dev->device.bus = &auxiliary_bus.bus; 41 42 /* Get NUMA node, default to 0 if not present */ 43 snprintf(filename, sizeof(filename), "%s/%s/numa_node", 44 dirname, name); 45 if (access(filename, F_OK) != -1) { 46 if (eal_parse_sysfs_value(filename, &tmp) == 0) 47 dev->device.numa_node = tmp; 48 else 49 dev->device.numa_node = -1; 50 } else { 51 dev->device.numa_node = 0; 52 } 53 54 auxiliary_on_scan(dev); 55 56 /* Device is valid, add in list (sorted) */ 57 TAILQ_FOREACH(dev2, &auxiliary_bus.device_list, next) { 58 ret = strcmp(dev->name, dev2->name); 59 if (ret > 0) 60 continue; 61 if (ret < 0) { 62 auxiliary_insert_device(dev2, dev); 63 } else { /* already registered */ 64 if (rte_dev_is_probed(&dev2->device) && 65 dev2->device.devargs != dev->device.devargs) { 66 /* To probe device with new devargs. */ 67 rte_devargs_remove(dev2->device.devargs); 68 auxiliary_on_scan(dev2); 69 } 70 free(dev); 71 } 72 return 0; 73 } 74 auxiliary_add_device(dev); 75 return 0; 76 } 77 78 /* 79 * Test whether the auxiliary device exist. 80 */ 81 bool 82 auxiliary_dev_exists(const char *name) 83 { 84 DIR *dir; 85 char dirname[PATH_MAX]; 86 87 snprintf(dirname, sizeof(dirname), "%s/%s", 88 AUXILIARY_SYSFS_PATH, name); 89 dir = opendir(dirname); 90 if (dir == NULL) 91 return false; 92 closedir(dir); 93 return true; 94 } 95 96 /* 97 * Scan the devices in the auxiliary bus. 98 */ 99 int 100 auxiliary_scan(void) 101 { 102 struct dirent *e; 103 DIR *dir; 104 char dirname[PATH_MAX]; 105 struct rte_auxiliary_driver *drv; 106 107 dir = opendir(AUXILIARY_SYSFS_PATH); 108 if (dir == NULL) { 109 AUXILIARY_LOG(INFO, "%s not found, is auxiliary module loaded?", 110 AUXILIARY_SYSFS_PATH); 111 return 0; 112 } 113 114 while ((e = readdir(dir)) != NULL) { 115 if (e->d_name[0] == '.') 116 continue; 117 118 if (auxiliary_is_ignored_device(e->d_name)) 119 continue; 120 121 snprintf(dirname, sizeof(dirname), "%s/%s", 122 AUXILIARY_SYSFS_PATH, e->d_name); 123 124 /* Ignore if no driver can handle. */ 125 FOREACH_DRIVER_ON_AUXILIARY_BUS(drv) { 126 if (drv->match(e->d_name)) 127 break; 128 } 129 if (drv == NULL) 130 continue; 131 132 if (auxiliary_scan_one(dirname, e->d_name) < 0) 133 goto error; 134 } 135 closedir(dir); 136 return 0; 137 138 error: 139 closedir(dir); 140 return -1; 141 } 142