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