Branch data Line data Source code
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
20 : 0 : 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 : 0 : dev = malloc(sizeof(*dev));
29 [ # # ]: 0 : if (dev == NULL)
30 : : return -1;
31 : :
32 : : memset(dev, 0, sizeof(*dev));
33 [ # # ]: 0 : if (rte_strscpy(dev->name, name, sizeof(dev->name)) < 0) {
34 : 0 : free(dev);
35 : 0 : return -1;
36 : : }
37 : 0 : dev->device.name = dev->name;
38 : 0 : 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 [ # # # # ]: 0 : if (access(filename, F_OK) == 0 &&
44 : 0 : eal_parse_sysfs_value(filename, &tmp) == 0)
45 : 0 : dev->device.numa_node = tmp;
46 : : else
47 : 0 : dev->device.numa_node = SOCKET_ID_ANY;
48 : :
49 : 0 : auxiliary_on_scan(dev);
50 : :
51 : : /* Device is valid, add in list (sorted) */
52 [ # # ]: 0 : TAILQ_FOREACH(dev2, &auxiliary_bus.device_list, next) {
53 : 0 : ret = strcmp(dev->name, dev2->name);
54 [ # # ]: 0 : if (ret > 0)
55 : : continue;
56 [ # # ]: 0 : if (ret < 0) {
57 : 0 : auxiliary_insert_device(dev2, dev);
58 : : } else { /* already registered */
59 [ # # ]: 0 : if (rte_dev_is_probed(&dev2->device) &&
60 [ # # ]: 0 : dev2->device.devargs != dev->device.devargs) {
61 : : /* To probe device with new devargs. */
62 : 0 : rte_devargs_remove(dev2->device.devargs);
63 : 0 : auxiliary_on_scan(dev2);
64 : : }
65 : 0 : free(dev);
66 : : }
67 : : return 0;
68 : : }
69 : 0 : auxiliary_add_device(dev);
70 : 0 : return 0;
71 : : }
72 : :
73 : : /*
74 : : * Test whether the auxiliary device exist.
75 : : */
76 : : bool
77 : 0 : 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 : 0 : dir = opendir(dirname);
85 [ # # ]: 0 : if (dir == NULL)
86 : : return false;
87 : 0 : closedir(dir);
88 : 0 : return true;
89 : : }
90 : :
91 : : /*
92 : : * Scan the devices in the auxiliary bus.
93 : : */
94 : : int
95 : 185 : auxiliary_scan(void)
96 : : {
97 : : struct dirent *e;
98 : : DIR *dir;
99 : : char dirname[PATH_MAX];
100 : : struct rte_auxiliary_driver *drv;
101 : :
102 : 185 : dir = opendir(AUXILIARY_SYSFS_PATH);
103 [ + - ]: 185 : if (dir == NULL) {
104 : 185 : AUXILIARY_LOG(INFO, "%s not found, is auxiliary module loaded?",
105 : : AUXILIARY_SYSFS_PATH);
106 : 185 : return 0;
107 : : }
108 : :
109 [ # # ]: 0 : while ((e = readdir(dir)) != NULL) {
110 [ # # ]: 0 : if (e->d_name[0] == '.')
111 : 0 : continue;
112 : :
113 [ # # ]: 0 : if (auxiliary_is_ignored_device(e->d_name))
114 : 0 : 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 [ # # ]: 0 : FOREACH_DRIVER_ON_AUXILIARY_BUS(drv) {
121 [ # # ]: 0 : if (drv->match(e->d_name))
122 : : break;
123 : : }
124 [ # # ]: 0 : if (drv == NULL)
125 : 0 : continue;
126 : :
127 [ # # ]: 0 : if (auxiliary_scan_one(dirname, e->d_name) < 0)
128 : 0 : goto error;
129 : : }
130 : 0 : closedir(dir);
131 : 0 : return 0;
132 : :
133 : : error:
134 : 0 : closedir(dir);
135 : 0 : return -1;
136 : : }
|