Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2023 Marvell.
3 : : */
4 : :
5 : : #include <dirent.h>
6 : : #include <inttypes.h>
7 : : #include <stdlib.h>
8 : : #include <string.h>
9 : : #include <sys/ioctl.h>
10 : : #include <sys/mman.h>
11 : : #include <sys/queue.h>
12 : : #include <unistd.h>
13 : :
14 : : #include <bus_driver.h>
15 : : #include <bus_platform_driver.h>
16 : : #include <eal_export.h>
17 : : #include <eal_filesystem.h>
18 : : #include <rte_bus.h>
19 : : #include <rte_devargs.h>
20 : : #include <rte_errno.h>
21 : : #include <rte_log.h>
22 : : #include <rte_memory.h>
23 : : #include <rte_string_fns.h>
24 : : #include <rte_vfio.h>
25 : :
26 : : #include "private.h"
27 : :
28 : : #ifdef VFIO_PRESENT
29 : :
30 : : #define PLATFORM_BUS_DEVICES_PATH "/sys/bus/platform/devices"
31 : :
32 : : RTE_EXPORT_INTERNAL_SYMBOL(rte_platform_register)
33 : : void
34 : 0 : rte_platform_register(struct rte_platform_driver *pdrv)
35 : : {
36 : 0 : TAILQ_INSERT_TAIL(&platform_bus.driver_list, pdrv, next);
37 : 0 : }
38 : :
39 : : RTE_EXPORT_INTERNAL_SYMBOL(rte_platform_unregister)
40 : : void
41 : 0 : rte_platform_unregister(struct rte_platform_driver *pdrv)
42 : : {
43 [ # # ]: 0 : TAILQ_REMOVE(&platform_bus.driver_list, pdrv, next);
44 : 0 : }
45 : :
46 : : static struct rte_devargs *
47 : 2220 : dev_devargs(const char *dev_name)
48 : : {
49 : : struct rte_devargs *devargs;
50 : :
51 [ - + ]: 2220 : RTE_EAL_DEVARGS_FOREACH("platform", devargs) {
52 [ # # ]: 0 : if (!strcmp(devargs->name, dev_name))
53 : 0 : return devargs;
54 : : }
55 : :
56 : : return NULL;
57 : : }
58 : :
59 : : static bool
60 : 2220 : dev_allowed(const char *dev_name)
61 : : {
62 : : struct rte_devargs *devargs;
63 : :
64 : 2220 : devargs = dev_devargs(dev_name);
65 [ - + ]: 2220 : if (devargs == NULL)
66 : : return true;
67 : :
68 [ # # # ]: 0 : switch (platform_bus.bus.conf.scan_mode) {
69 : 0 : case RTE_BUS_SCAN_UNDEFINED:
70 : : case RTE_BUS_SCAN_ALLOWLIST:
71 : 0 : if (devargs->policy == RTE_DEV_ALLOWED)
72 : : return true;
73 : : break;
74 : 0 : case RTE_BUS_SCAN_BLOCKLIST:
75 [ # # ]: 0 : if (devargs->policy == RTE_DEV_BLOCKED)
76 : 0 : return false;
77 : : break;
78 : : }
79 : :
80 : : return true;
81 : : }
82 : :
83 : : static int
84 : 0 : dev_add(const char *dev_name)
85 : : {
86 : : struct rte_platform_device *pdev, *tmp;
87 : : char path[PATH_MAX];
88 : : unsigned long val;
89 : :
90 : 0 : pdev = calloc(1, sizeof(*pdev));
91 [ # # ]: 0 : if (pdev == NULL)
92 : : return -ENOMEM;
93 : :
94 : 0 : rte_strscpy(pdev->name, dev_name, sizeof(pdev->name));
95 : 0 : pdev->device.name = pdev->name;
96 : 0 : pdev->device.devargs = dev_devargs(dev_name);
97 : 0 : pdev->device.bus = &platform_bus.bus;
98 : : snprintf(path, sizeof(path), PLATFORM_BUS_DEVICES_PATH "/%s/numa_node", dev_name);
99 [ # # ]: 0 : pdev->device.numa_node = eal_parse_sysfs_value(path, &val) ? rte_socket_id() : val;
100 : :
101 [ # # ]: 0 : FOREACH_DEVICE_ON_PLATFORM_BUS(tmp) {
102 [ # # ]: 0 : if (!strcmp(tmp->name, pdev->name)) {
103 : 0 : PLATFORM_LOG_LINE(INFO, "device %s already added", pdev->name);
104 : :
105 [ # # ]: 0 : if (tmp->device.devargs != pdev->device.devargs)
106 : 0 : rte_devargs_remove(pdev->device.devargs);
107 : :
108 : 0 : free(pdev);
109 : 0 : return -EEXIST;
110 : : }
111 : : }
112 : :
113 [ # # ]: 0 : TAILQ_INSERT_HEAD(&platform_bus.device_list, pdev, next);
114 : :
115 : 0 : PLATFORM_LOG_LINE(INFO, "adding device %s to the list", dev_name);
116 : :
117 : 0 : return 0;
118 : : }
119 : :
120 : : static char *
121 : 2220 : dev_kernel_driver_name(const char *dev_name)
122 : : {
123 : 2220 : char path[PATH_MAX], buf[BUFSIZ] = { };
124 : : char *kdrv;
125 : : int ret;
126 : :
127 : : snprintf(path, sizeof(path), PLATFORM_BUS_DEVICES_PATH "/%s/driver", dev_name);
128 : : /* save space for NUL */
129 : 2220 : ret = readlink(path, buf, sizeof(buf) - 1);
130 [ + + ]: 2220 : if (ret <= 0)
131 : : return NULL;
132 : :
133 : : /* last token is kernel driver name */
134 : 925 : kdrv = strrchr(buf, '/');
135 [ + - ]: 925 : if (kdrv != NULL)
136 : 925 : return strdup(kdrv + 1);
137 : :
138 : : return NULL;
139 : : }
140 : :
141 : : static bool
142 : 2220 : dev_is_bound_vfio_platform(const char *dev_name)
143 : : {
144 : : char *kdrv;
145 : : int ret;
146 : :
147 : 2220 : kdrv = dev_kernel_driver_name(dev_name);
148 [ + + ]: 2220 : if (!kdrv)
149 : : return false;
150 : :
151 : 925 : ret = strcmp(kdrv, "vfio-platform");
152 : 925 : free(kdrv);
153 : :
154 : 925 : return ret == 0;
155 : : }
156 : :
157 : : static int
158 : 185 : platform_bus_scan(void)
159 : : {
160 : : const struct dirent *ent;
161 : : const char *dev_name;
162 : : int ret = 0;
163 : : DIR *dp;
164 : :
165 : 185 : dp = opendir(PLATFORM_BUS_DEVICES_PATH);
166 [ - + ]: 185 : if (dp == NULL) {
167 : 0 : PLATFORM_LOG_LINE(INFO, "failed to open %s", PLATFORM_BUS_DEVICES_PATH);
168 : 0 : return -errno;
169 : : }
170 : :
171 [ + + ]: 2775 : while ((ent = readdir(dp))) {
172 : 2590 : dev_name = ent->d_name;
173 [ + + ]: 2590 : if (dev_name[0] == '.')
174 : 370 : continue;
175 : :
176 [ - + ]: 2220 : if (!dev_allowed(dev_name))
177 : 0 : continue;
178 : :
179 [ + - ]: 2220 : if (!dev_is_bound_vfio_platform(dev_name))
180 : 2220 : continue;
181 : :
182 : 0 : ret = dev_add(dev_name);
183 [ # # ]: 0 : if (ret)
184 : : break;
185 : : }
186 : :
187 : 185 : closedir(dp);
188 : :
189 : 185 : return ret;
190 : : }
191 : :
192 : : static int
193 : 0 : device_map_resource_offset(struct rte_platform_device *pdev, struct rte_platform_resource *res,
194 : : size_t offset)
195 : : {
196 : 0 : res->mem.addr = mmap(NULL, res->mem.len, PROT_READ | PROT_WRITE, MAP_SHARED, pdev->dev_fd,
197 : : offset);
198 [ # # ]: 0 : if (res->mem.addr == MAP_FAILED)
199 : 0 : return -errno;
200 : :
201 : 0 : PLATFORM_LOG_LINE(DEBUG, "adding resource va = %p len = %"PRIu64" name = %s", res->mem.addr,
202 : : res->mem.len, res->name);
203 : :
204 : 0 : return 0;
205 : : }
206 : :
207 : : static void
208 : 0 : device_unmap_resources(struct rte_platform_device *pdev)
209 : : {
210 : : struct rte_platform_resource *res;
211 : : unsigned int i;
212 : :
213 [ # # ]: 0 : for (i = 0; i < pdev->num_resource; i++) {
214 : 0 : res = &pdev->resource[i];
215 : 0 : munmap(res->mem.addr, res->mem.len);
216 : 0 : free(res->name);
217 : : }
218 : :
219 : 0 : free(pdev->resource);
220 : 0 : pdev->resource = NULL;
221 : 0 : pdev->num_resource = 0;
222 : 0 : }
223 : :
224 : : static int
225 : 0 : read_sysfs_string(const char *path, char *buf, size_t size)
226 : : {
227 : : FILE *f;
228 : : char *p;
229 : :
230 : 0 : f = fopen(path, "r");
231 [ # # ]: 0 : if (f == NULL)
232 : 0 : return -errno;
233 : :
234 [ # # # # ]: 0 : if (fgets(buf, size, f) == NULL) {
235 : 0 : fclose(f);
236 : 0 : return -ENODATA;
237 : : }
238 : :
239 : 0 : fclose(f);
240 : :
241 : 0 : p = strrchr(buf, '\n');
242 [ # # ]: 0 : if (p != NULL)
243 : 0 : *p = '\0';
244 : :
245 : : return 0;
246 : : }
247 : :
248 : : static char *
249 : 0 : of_resource_name(const char *dev_name, int index)
250 : : {
251 : 0 : char path[PATH_MAX], buf[BUFSIZ] = { };
252 : : int num = 0, ret;
253 : : char *name;
254 : :
255 : : snprintf(path, sizeof(path), PLATFORM_BUS_DEVICES_PATH "/%s/of_node/reg-names", dev_name);
256 : 0 : ret = read_sysfs_string(path, buf, sizeof(buf) - 1);
257 [ # # ]: 0 : if (ret)
258 : : return NULL;
259 : :
260 [ # # ]: 0 : for (name = buf; *name != 0; name += strlen(name) + 1) {
261 [ # # ]: 0 : if (num++ != index)
262 : : continue;
263 : 0 : return strdup(name);
264 : : }
265 : :
266 : : return NULL;
267 : : }
268 : :
269 : : static int
270 : 0 : device_map_resources(struct rte_platform_device *pdev, unsigned int num)
271 : : {
272 : : struct rte_platform_resource *res;
273 : : unsigned int i;
274 : : int ret;
275 : :
276 [ # # ]: 0 : if (num == 0) {
277 : 0 : PLATFORM_LOG_LINE(WARNING, "device %s has no resources", pdev->name);
278 : 0 : return 0;
279 : : }
280 : :
281 : 0 : pdev->resource = calloc(num, sizeof(*pdev->resource));
282 [ # # ]: 0 : if (pdev->resource == NULL)
283 : : return -ENOMEM;
284 : :
285 [ # # ]: 0 : for (i = 0; i < num; i++) {
286 : 0 : struct vfio_region_info reg_info = {
287 : : .argsz = sizeof(reg_info),
288 : : .index = i,
289 : : };
290 : :
291 : 0 : ret = ioctl(pdev->dev_fd, VFIO_DEVICE_GET_REGION_INFO, ®_info);
292 [ # # ]: 0 : if (ret) {
293 : 0 : PLATFORM_LOG_LINE(ERR, "failed to get region info at %d", i);
294 : 0 : ret = -errno;
295 : 0 : goto out;
296 : : }
297 : :
298 : 0 : res = &pdev->resource[i];
299 : 0 : res->name = of_resource_name(pdev->name, reg_info.index);
300 : 0 : res->mem.len = reg_info.size;
301 : 0 : ret = device_map_resource_offset(pdev, res, reg_info.offset);
302 [ # # ]: 0 : if (ret) {
303 : 0 : PLATFORM_LOG_LINE(ERR, "failed to ioremap resource at %d", i);
304 : 0 : goto out;
305 : : }
306 : :
307 : 0 : pdev->num_resource++;
308 : : }
309 : :
310 : : return 0;
311 : : out:
312 : 0 : device_unmap_resources(pdev);
313 : :
314 : 0 : return ret;
315 : : }
316 : :
317 : : static void
318 : 0 : device_cleanup(struct rte_platform_device *pdev)
319 : : {
320 : 0 : device_unmap_resources(pdev);
321 : 0 : rte_vfio_release_device(PLATFORM_BUS_DEVICES_PATH, pdev->name, pdev->dev_fd);
322 : 0 : }
323 : :
324 : : static int
325 : 0 : device_setup(struct rte_platform_device *pdev)
326 : : {
327 : 0 : struct vfio_device_info dev_info = { .argsz = sizeof(dev_info), };
328 : 0 : const char *name = pdev->name;
329 : : int ret;
330 : :
331 : 0 : ret = rte_vfio_setup_device(PLATFORM_BUS_DEVICES_PATH, name, &pdev->dev_fd, &dev_info);
332 [ # # ]: 0 : if (ret) {
333 : 0 : PLATFORM_LOG_LINE(ERR, "failed to setup %s", name);
334 : 0 : return -ENODEV;
335 : : }
336 : :
337 : : /* This is an extra check to confirm that platform device was initialized
338 : : * by a kernel vfio-platform driver. On kernels that predate vfio-platform
339 : : * driver this flag obviously does not exist. In such scenarios this
340 : : * check needs to be removed otherwise compilation fails.
341 : : *
342 : : * Now, on such old kernels code will never reach here because
343 : : * there is another check much earlier which verifies whether
344 : : * device has been bound to vfio-platform driver.
345 : : */
346 : : #ifdef VFIO_DEVICE_FLAGS_PLATFORM
347 [ # # ]: 0 : if (!(dev_info.flags & VFIO_DEVICE_FLAGS_PLATFORM)) {
348 : 0 : PLATFORM_LOG_LINE(ERR, "device not backed by vfio-platform");
349 : : ret = -ENOTSUP;
350 : 0 : goto out;
351 : : }
352 : : #endif
353 : :
354 : 0 : ret = device_map_resources(pdev, dev_info.num_regions);
355 [ # # ]: 0 : if (ret) {
356 : 0 : PLATFORM_LOG_LINE(ERR, "failed to setup platform resources");
357 : 0 : goto out;
358 : : }
359 : :
360 : : return 0;
361 : 0 : out:
362 : 0 : device_cleanup(pdev);
363 : :
364 : 0 : return ret;
365 : : }
366 : :
367 : : static int
368 : 0 : driver_call_probe(struct rte_platform_driver *pdrv, struct rte_platform_device *pdev)
369 : : {
370 : : int ret;
371 : :
372 [ # # ]: 0 : if (rte_dev_is_probed(&pdev->device))
373 : : return -EBUSY;
374 : :
375 [ # # ]: 0 : if (pdrv->probe != NULL) {
376 : 0 : pdev->driver = pdrv;
377 : 0 : ret = pdrv->probe(pdev);
378 [ # # ]: 0 : if (ret)
379 : : return ret;
380 : : }
381 : :
382 : 0 : pdev->device.driver = &pdrv->driver;
383 : :
384 : 0 : return 0;
385 : : }
386 : :
387 : : static int
388 : 0 : driver_probe_device(struct rte_platform_driver *pdrv, struct rte_platform_device *pdev)
389 : : {
390 : : enum rte_iova_mode iova_mode;
391 : : int ret;
392 : :
393 : 0 : iova_mode = rte_eal_iova_mode();
394 [ # # # # ]: 0 : if (pdrv->drv_flags & RTE_PLATFORM_DRV_NEED_IOVA_AS_VA && iova_mode != RTE_IOVA_VA) {
395 : 0 : PLATFORM_LOG_LINE(ERR, "driver %s expects VA IOVA mode but current mode is PA",
396 : : pdrv->driver.name);
397 : 0 : return -EINVAL;
398 : : }
399 : :
400 : 0 : ret = device_setup(pdev);
401 [ # # ]: 0 : if (ret)
402 : : return ret;
403 : :
404 : 0 : ret = driver_call_probe(pdrv, pdev);
405 [ # # ]: 0 : if (ret)
406 : 0 : device_cleanup(pdev);
407 : :
408 : : return ret;
409 : : }
410 : :
411 : : static bool
412 : 0 : driver_match_device(struct rte_platform_driver *pdrv, struct rte_platform_device *pdev)
413 : : {
414 : : bool match = false;
415 : : char *kdrv;
416 : :
417 : 0 : kdrv = dev_kernel_driver_name(pdev->name);
418 [ # # ]: 0 : if (!kdrv)
419 : : return false;
420 : :
421 : : /* match by driver name */
422 [ # # ]: 0 : if (!strcmp(kdrv, pdrv->driver.name)) {
423 : : match = true;
424 : 0 : goto out;
425 : : }
426 : :
427 : : /* match by driver alias */
428 [ # # # # ]: 0 : if (pdrv->driver.alias != NULL && !strcmp(kdrv, pdrv->driver.alias)) {
429 : : match = true;
430 : 0 : goto out;
431 : : }
432 : :
433 : : /* match by device name */
434 [ # # ]: 0 : if (!strcmp(pdev->name, pdrv->driver.name))
435 : : match = true;
436 : :
437 : 0 : out:
438 : 0 : free(kdrv);
439 : :
440 : 0 : return match;
441 : : }
442 : :
443 : : static int
444 : 0 : device_attach(struct rte_platform_device *pdev)
445 : : {
446 : : struct rte_platform_driver *pdrv;
447 : :
448 [ # # ]: 0 : FOREACH_DRIVER_ON_PLATFORM_BUS(pdrv) {
449 [ # # ]: 0 : if (driver_match_device(pdrv, pdev))
450 : : break;
451 : : }
452 : :
453 [ # # ]: 0 : if (pdrv == NULL)
454 : : return -ENODEV;
455 : :
456 : 0 : return driver_probe_device(pdrv, pdev);
457 : : }
458 : :
459 : : static int
460 : 180 : platform_bus_probe(void)
461 : : {
462 : : struct rte_platform_device *pdev;
463 : : int ret;
464 : :
465 [ - + ]: 180 : FOREACH_DEVICE_ON_PLATFORM_BUS(pdev) {
466 : 0 : ret = device_attach(pdev);
467 [ # # ]: 0 : if (ret == -EBUSY) {
468 : 0 : PLATFORM_LOG_LINE(DEBUG, "device %s already probed", pdev->name);
469 : 0 : continue;
470 : : }
471 [ # # ]: 0 : if (ret)
472 : 0 : PLATFORM_LOG_LINE(ERR, "failed to probe %s", pdev->name);
473 : : }
474 : :
475 : 180 : return 0;
476 : : }
477 : :
478 : : static struct rte_device *
479 : 0 : platform_bus_find_device(const struct rte_device *start, rte_dev_cmp_t cmp, const void *data)
480 : : {
481 : : struct rte_platform_device *pdev;
482 : :
483 [ # # ]: 0 : pdev = start ? RTE_TAILQ_NEXT(RTE_DEV_TO_PLATFORM_DEV_CONST(start), next) :
484 : : RTE_TAILQ_FIRST(&platform_bus.device_list);
485 [ # # ]: 0 : while (pdev) {
486 [ # # ]: 0 : if (cmp(&pdev->device, data) == 0)
487 : 0 : return &pdev->device;
488 : :
489 : 0 : pdev = RTE_TAILQ_NEXT(pdev, next);
490 : : }
491 : :
492 : : return NULL;
493 : : }
494 : :
495 : : static int
496 : 0 : platform_bus_plug(struct rte_device *dev)
497 : : {
498 : : struct rte_platform_device *pdev;
499 : :
500 [ # # ]: 0 : if (!dev_allowed(dev->name))
501 : : return -EPERM;
502 : :
503 [ # # ]: 0 : if (!dev_is_bound_vfio_platform(dev->name))
504 : : return -EPERM;
505 : :
506 : 0 : pdev = RTE_DEV_TO_PLATFORM_DEV(dev);
507 [ # # ]: 0 : if (pdev == NULL)
508 : : return -EINVAL;
509 : :
510 : 0 : return device_attach(pdev);
511 : : }
512 : :
513 : : static void
514 : 0 : device_release_driver(struct rte_platform_device *pdev)
515 : : {
516 : : struct rte_platform_driver *pdrv;
517 : : int ret;
518 : :
519 : 0 : pdrv = pdev->driver;
520 [ # # # # ]: 0 : if (pdrv != NULL && pdrv->remove != NULL) {
521 : 0 : ret = pdrv->remove(pdev);
522 [ # # ]: 0 : if (ret)
523 : 0 : PLATFORM_LOG_LINE(WARNING, "failed to remove %s", pdev->name);
524 : : }
525 : :
526 : 0 : pdev->device.driver = NULL;
527 : 0 : pdev->driver = NULL;
528 : 0 : }
529 : :
530 : : static int
531 : 0 : platform_bus_unplug(struct rte_device *dev)
532 : : {
533 : : struct rte_platform_device *pdev;
534 : :
535 : 0 : pdev = RTE_DEV_TO_PLATFORM_DEV(dev);
536 [ # # ]: 0 : if (pdev == NULL)
537 : : return -EINVAL;
538 : :
539 : 0 : device_release_driver(pdev);
540 : 0 : device_cleanup(pdev);
541 : 0 : rte_devargs_remove(pdev->device.devargs);
542 : 0 : free(pdev);
543 : :
544 : 0 : return 0;
545 : : }
546 : :
547 : : static int
548 : 28 : platform_bus_parse(const char *name, void *addr)
549 : : {
550 : 28 : struct rte_platform_device pdev = { };
551 : : struct rte_platform_driver *pdrv;
552 : : const char **out = addr;
553 : :
554 : 28 : rte_strscpy(pdev.name, name, sizeof(pdev.name));
555 : :
556 [ - + ]: 28 : FOREACH_DRIVER_ON_PLATFORM_BUS(pdrv) {
557 [ # # ]: 0 : if (driver_match_device(pdrv, &pdev))
558 : : break;
559 : : }
560 : :
561 [ - + ]: 28 : if (pdrv != NULL && addr != NULL)
562 : 0 : *out = name;
563 : :
564 [ + - ]: 28 : return pdrv != NULL ? 0 : -ENODEV;
565 : : }
566 : :
567 : : static int
568 : 0 : platform_bus_dma_map(struct rte_device *dev, void *addr, uint64_t iova, size_t len)
569 : : {
570 : : struct rte_platform_device *pdev;
571 : :
572 : 0 : pdev = RTE_DEV_TO_PLATFORM_DEV(dev);
573 [ # # # # ]: 0 : if (pdev == NULL || pdev->driver == NULL) {
574 : 0 : rte_errno = EINVAL;
575 : 0 : return -1;
576 : : }
577 : :
578 [ # # ]: 0 : if (pdev->driver->dma_map != NULL)
579 : 0 : return pdev->driver->dma_map(pdev, addr, iova, len);
580 : :
581 : 0 : return rte_vfio_container_dma_map(RTE_VFIO_DEFAULT_CONTAINER_FD, (uint64_t)addr, iova, len);
582 : : }
583 : :
584 : : static int
585 : 0 : platform_bus_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova, size_t len)
586 : : {
587 : : struct rte_platform_device *pdev;
588 : :
589 : 0 : pdev = RTE_DEV_TO_PLATFORM_DEV(dev);
590 [ # # # # ]: 0 : if (pdev == NULL || pdev->driver == NULL) {
591 : 0 : rte_errno = EINVAL;
592 : 0 : return -1;
593 : : }
594 : :
595 [ # # ]: 0 : if (pdev->driver->dma_unmap != NULL)
596 : 0 : return pdev->driver->dma_unmap(pdev, addr, iova, len);
597 : :
598 : 0 : return rte_vfio_container_dma_unmap(RTE_VFIO_DEFAULT_CONTAINER_FD, (uint64_t)addr, iova,
599 : : len);
600 : : }
601 : :
602 : : static enum rte_iova_mode
603 : 185 : platform_bus_get_iommu_class(void)
604 : : {
605 : : struct rte_platform_driver *pdrv;
606 : : struct rte_platform_device *pdev;
607 : :
608 [ - + ]: 185 : FOREACH_DEVICE_ON_PLATFORM_BUS(pdev) {
609 : 0 : pdrv = pdev->driver;
610 [ # # # # ]: 0 : if (pdrv != NULL && pdrv->drv_flags & RTE_PLATFORM_DRV_NEED_IOVA_AS_VA)
611 : : return RTE_IOVA_VA;
612 : : }
613 : :
614 : : return RTE_IOVA_DC;
615 : : }
616 : :
617 : : static int
618 : 252 : platform_bus_cleanup(void)
619 : : {
620 : : struct rte_platform_device *pdev, *tmp;
621 : :
622 [ - + ]: 252 : RTE_TAILQ_FOREACH_SAFE(pdev, &platform_bus.device_list, next, tmp) {
623 [ # # ]: 0 : TAILQ_REMOVE(&platform_bus.device_list, pdev, next);
624 : 0 : platform_bus_unplug(&pdev->device);
625 : : }
626 : :
627 : 252 : return 0;
628 : : }
629 : :
630 : : struct rte_platform_bus platform_bus = {
631 : : .bus = {
632 : : .scan = platform_bus_scan,
633 : : .probe = platform_bus_probe,
634 : : .find_device = platform_bus_find_device,
635 : : .plug = platform_bus_plug,
636 : : .unplug = platform_bus_unplug,
637 : : .parse = platform_bus_parse,
638 : : .dma_map = platform_bus_dma_map,
639 : : .dma_unmap = platform_bus_dma_unmap,
640 : : .get_iommu_class = platform_bus_get_iommu_class,
641 : : .dev_iterate = platform_bus_dev_iterate,
642 : : .cleanup = platform_bus_cleanup,
643 : : },
644 : : .device_list = TAILQ_HEAD_INITIALIZER(platform_bus.device_list),
645 : : .driver_list = TAILQ_HEAD_INITIALIZER(platform_bus.driver_list),
646 : : };
647 : :
648 : 252 : RTE_REGISTER_BUS(platform, platform_bus.bus);
649 [ - + ]: 252 : RTE_LOG_REGISTER_DEFAULT(platform_bus_logtype, NOTICE);
650 : :
651 : : #endif /* VFIO_PRESENT */
|