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 : :
39 : : /* Get NUMA node, default to 0 if not present */
40 : : snprintf(filename, sizeof(filename), "%s/%s/numa_node",
41 : : dirname, name);
42 [ # # # # ]: 0 : if (access(filename, F_OK) == 0 &&
43 : 0 : eal_parse_sysfs_value(filename, &tmp) == 0)
44 : 0 : dev->device.numa_node = tmp;
45 : : else
46 : 0 : dev->device.numa_node = SOCKET_ID_ANY;
47 : :
48 : 0 : auxiliary_on_scan(dev);
49 : :
50 : : /* Device is valid, add in list (sorted) */
51 [ # # ]: 0 : RTE_BUS_FOREACH_DEV(dev2, &auxiliary_bus) {
52 : 0 : ret = strcmp(dev->name, dev2->name);
53 [ # # ]: 0 : if (ret > 0)
54 : : continue;
55 [ # # ]: 0 : if (ret < 0) {
56 : 0 : rte_bus_insert_device(&auxiliary_bus, &dev2->device, &dev->device);
57 : : } else { /* already registered */
58 [ # # ]: 0 : if (rte_dev_is_probed(&dev2->device) &&
59 [ # # ]: 0 : dev2->device.devargs != dev->device.devargs) {
60 : : /* To probe device with new devargs. */
61 : 0 : rte_devargs_remove(dev2->device.devargs);
62 : 0 : auxiliary_on_scan(dev2);
63 : : }
64 : 0 : free(dev);
65 : : }
66 : : return 0;
67 : : }
68 : 0 : rte_bus_add_device(&auxiliary_bus, &dev->device);
69 : 0 : return 0;
70 : : }
71 : :
72 : : /*
73 : : * Test whether the auxiliary device exist.
74 : : */
75 : : bool
76 : 0 : auxiliary_dev_exists(const char *name)
77 : : {
78 : : DIR *dir;
79 : : char dirname[PATH_MAX];
80 : :
81 : : snprintf(dirname, sizeof(dirname), "%s/%s",
82 : : AUXILIARY_SYSFS_PATH, name);
83 : 0 : dir = opendir(dirname);
84 [ # # ]: 0 : if (dir == NULL)
85 : : return false;
86 : 0 : closedir(dir);
87 : 0 : return true;
88 : : }
89 : :
90 : : /*
91 : : * Scan the devices in the auxiliary bus.
92 : : */
93 : : int
94 : 225 : auxiliary_scan(void)
95 : : {
96 : : struct dirent *e;
97 : : DIR *dir;
98 : : char dirname[PATH_MAX];
99 : : struct rte_auxiliary_driver *drv;
100 : :
101 : 225 : dir = opendir(AUXILIARY_SYSFS_PATH);
102 [ - + ]: 225 : if (dir == NULL) {
103 : 0 : AUXILIARY_LOG(INFO, "%s not found, is auxiliary module loaded?",
104 : : AUXILIARY_SYSFS_PATH);
105 : 0 : return 0;
106 : : }
107 : :
108 [ + + ]: 675 : while ((e = readdir(dir)) != NULL) {
109 [ + - ]: 450 : if (e->d_name[0] == '.')
110 : 450 : continue;
111 : :
112 [ # # ]: 0 : if (rte_bus_device_is_ignored(&auxiliary_bus, e->d_name))
113 : 0 : continue;
114 : :
115 : : snprintf(dirname, sizeof(dirname), "%s/%s",
116 : : AUXILIARY_SYSFS_PATH, e->d_name);
117 : :
118 : : /* Ignore if no driver can handle. */
119 [ # # ]: 0 : RTE_BUS_FOREACH_DRV(drv, &auxiliary_bus) {
120 [ # # ]: 0 : if (drv->match(e->d_name))
121 : : break;
122 : : }
123 [ # # ]: 0 : if (drv == NULL)
124 : 0 : continue;
125 : :
126 [ # # ]: 0 : if (auxiliary_scan_one(dirname, e->d_name) < 0)
127 : 0 : goto error;
128 : : }
129 : 225 : closedir(dir);
130 : 225 : return 0;
131 : :
132 : : error:
133 : 0 : closedir(dir);
134 : 0 : return -1;
135 : : }
|