jtag: drivers: provide initial support for usb path filtering
[fw/openocd] / src / jtag / drivers / jtag_usb_common.c
1 /*
2  * SPDX-License-Identifier: GPL-2.0+
3  * Copyright (c) 2018 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>
4  */
5
6 #include <helper/log.h>
7
8 #include "jtag_usb_common.h"
9
10 static char *jtag_usb_location;
11 /*
12  * 1 char: bus
13  * 2 * 7 chars: max 7 ports
14  * 1 char: test for overflow
15  * ------
16  * 16 chars
17  */
18 #define JTAG_USB_MAX_LOCATION_LENGHT    16
19
20 void jtag_usb_set_location(const char *location)
21 {
22         if (strnlen(location, JTAG_USB_MAX_LOCATION_LENGHT) ==
23             JTAG_USB_MAX_LOCATION_LENGHT)
24                 LOG_WARNING("usb location string is too long!!\n");
25
26         if (jtag_usb_location)
27                 free(jtag_usb_location);
28
29         jtag_usb_location = strndup(location, JTAG_USB_MAX_LOCATION_LENGHT);
30 }
31
32 const char *jtag_usb_get_location(void)
33 {
34         return jtag_usb_location;
35 }
36
37 bool jtag_usb_location_equal(uint8_t dev_bus, uint8_t *port_path,
38                              size_t path_len)
39 {
40         size_t path_step, string_lengh;
41         char *ptr, *loc;
42         bool equal = false;
43
44         /* strtok need non const char */
45         loc = strndup(jtag_usb_get_location(), JTAG_USB_MAX_LOCATION_LENGHT);
46         string_lengh = strnlen(loc, JTAG_USB_MAX_LOCATION_LENGHT);
47
48         ptr = strtok(loc, "-");
49         if (ptr == NULL) {
50                 LOG_WARNING("no '-' in usb path\n");
51                 goto done;
52         }
53
54         string_lengh -= 1;
55         /* check bus mismatch */
56         if (atoi(ptr) != dev_bus)
57                 goto done;
58
59         path_step = 0;
60         while (path_step < path_len) {
61                 ptr = strtok(NULL, ".");
62
63                 /* no more tokens in path */
64                 if (ptr == NULL)
65                         break;
66
67                 /* path mismatch at some step */
68                 if (path_step < path_len && atoi(ptr) != port_path[path_step])
69                         break;
70
71                 path_step++;
72                 string_lengh -= 2;
73         };
74
75         /* walked the full path, all elements match */
76         if (path_step == path_len && !string_lengh)
77                 equal = true;
78         else
79                 LOG_WARNING("excluded by device path option: %s\n",
80                             jtag_usb_get_location());
81
82 done:
83         free(loc);
84         return equal;
85 }