openocd: fix SPDX tag format for files .c
[fw/openocd] / src / jtag / drivers / libusb_helper.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4  *   Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net>          *
5  *                                                                         *
6  *   Copyright (C) 2011 by Mauro Gamba <maurillo71@gmail.com>              *
7  ***************************************************************************/
8
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif
12
13 #include <string.h>
14
15 #include <helper/log.h>
16 #include <jtag/adapter.h>
17 #include "libusb_helper.h"
18
19 /*
20  * comment from libusb:
21  * As per the USB 3.0 specs, the current maximum limit for the depth is 7.
22  */
23 #define MAX_USB_PORTS   7
24
25 static struct libusb_context *jtag_libusb_context; /**< Libusb context **/
26 static struct libusb_device **devs; /**< The usb device list **/
27
28 static int jtag_libusb_error(int err)
29 {
30         switch (err) {
31         case LIBUSB_SUCCESS:
32                 return ERROR_OK;
33         case LIBUSB_ERROR_TIMEOUT:
34                 return ERROR_TIMEOUT_REACHED;
35         case LIBUSB_ERROR_IO:
36         case LIBUSB_ERROR_INVALID_PARAM:
37         case LIBUSB_ERROR_ACCESS:
38         case LIBUSB_ERROR_NO_DEVICE:
39         case LIBUSB_ERROR_NOT_FOUND:
40         case LIBUSB_ERROR_BUSY:
41         case LIBUSB_ERROR_OVERFLOW:
42         case LIBUSB_ERROR_PIPE:
43         case LIBUSB_ERROR_INTERRUPTED:
44         case LIBUSB_ERROR_NO_MEM:
45         case LIBUSB_ERROR_NOT_SUPPORTED:
46         case LIBUSB_ERROR_OTHER:
47                 return ERROR_FAIL;
48         default:
49                 return ERROR_FAIL;
50         }
51 }
52
53 static bool jtag_libusb_match_ids(struct libusb_device_descriptor *dev_desc,
54                 const uint16_t vids[], const uint16_t pids[])
55 {
56         for (unsigned i = 0; vids[i]; i++) {
57                 if (dev_desc->idVendor == vids[i] &&
58                         dev_desc->idProduct == pids[i]) {
59                         return true;
60                 }
61         }
62         return false;
63 }
64
65 #ifdef HAVE_LIBUSB_GET_PORT_NUMBERS
66 static bool jtag_libusb_location_equal(struct libusb_device *device)
67 {
68         uint8_t port_path[MAX_USB_PORTS];
69         uint8_t dev_bus;
70         int path_len;
71
72         path_len = libusb_get_port_numbers(device, port_path, MAX_USB_PORTS);
73         if (path_len == LIBUSB_ERROR_OVERFLOW) {
74                 LOG_WARNING("cannot determine path to usb device! (more than %i ports in path)\n",
75                         MAX_USB_PORTS);
76                 return false;
77         }
78         dev_bus = libusb_get_bus_number(device);
79
80         return adapter_usb_location_equal(dev_bus, port_path, path_len);
81 }
82 #else /* HAVE_LIBUSB_GET_PORT_NUMBERS */
83 static bool jtag_libusb_location_equal(struct libusb_device *device)
84 {
85         return true;
86 }
87 #endif /* HAVE_LIBUSB_GET_PORT_NUMBERS */
88
89
90 /* Returns true if the string descriptor indexed by str_index in device matches string */
91 static bool string_descriptor_equal(struct libusb_device_handle *device, uint8_t str_index,
92                                                                         const char *string)
93 {
94         int retval;
95         bool matched;
96         char desc_string[256+1]; /* Max size of string descriptor */
97
98         if (str_index == 0)
99                 return false;
100
101         retval = libusb_get_string_descriptor_ascii(device, str_index,
102                         (unsigned char *)desc_string, sizeof(desc_string)-1);
103         if (retval < 0) {
104                 LOG_ERROR("libusb_get_string_descriptor_ascii() failed with %d", retval);
105                 return false;
106         }
107
108         /* Null terminate descriptor string in case it needs to be logged. */
109         desc_string[sizeof(desc_string)-1] = '\0';
110
111         matched = strncmp(string, desc_string, sizeof(desc_string)) == 0;
112         if (!matched)
113                 LOG_DEBUG("Device serial number '%s' doesn't match requested serial '%s'",
114                         desc_string, string);
115         return matched;
116 }
117
118 static bool jtag_libusb_match_serial(struct libusb_device_handle *device,
119                 struct libusb_device_descriptor *dev_desc, const char *serial,
120                 adapter_get_alternate_serial_fn adapter_get_alternate_serial)
121 {
122         if (string_descriptor_equal(device, dev_desc->iSerialNumber, serial))
123                 return true;
124
125         /* check the alternate serial helper */
126         if (!adapter_get_alternate_serial)
127                 return false;
128
129         /* get the alternate serial */
130         char *alternate_serial = adapter_get_alternate_serial(device, dev_desc);
131
132         /* check possible failures */
133         if (!alternate_serial)
134                 return false;
135
136         /* then compare and free the alternate serial */
137         bool match = false;
138         if (strcmp(serial, alternate_serial) == 0)
139                 match = true;
140         else
141                 LOG_DEBUG("Device alternate serial number '%s' doesn't match requested serial '%s'",
142                                 alternate_serial, serial);
143
144         free(alternate_serial);
145         return match;
146 }
147
148 int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[],
149                 struct libusb_device_handle **out,
150                 adapter_get_alternate_serial_fn adapter_get_alternate_serial)
151 {
152         int cnt, idx, err_code;
153         int retval = ERROR_FAIL;
154         bool serial_mismatch = false;
155         struct libusb_device_handle *libusb_handle = NULL;
156         const char *serial = adapter_get_required_serial();
157
158         if (libusb_init(&jtag_libusb_context) < 0)
159                 return ERROR_FAIL;
160
161         cnt = libusb_get_device_list(jtag_libusb_context, &devs);
162
163         for (idx = 0; idx < cnt; idx++) {
164                 struct libusb_device_descriptor dev_desc;
165
166                 if (libusb_get_device_descriptor(devs[idx], &dev_desc) != 0)
167                         continue;
168
169                 if (!jtag_libusb_match_ids(&dev_desc, vids, pids))
170                         continue;
171
172                 if (adapter_usb_get_location() && !jtag_libusb_location_equal(devs[idx]))
173                         continue;
174
175                 err_code = libusb_open(devs[idx], &libusb_handle);
176
177                 if (err_code) {
178                         LOG_ERROR("libusb_open() failed with %s",
179                                   libusb_error_name(err_code));
180                         continue;
181                 }
182
183                 /* Device must be open to use libusb_get_string_descriptor_ascii. */
184                 if (serial &&
185                                 !jtag_libusb_match_serial(libusb_handle, &dev_desc, serial, adapter_get_alternate_serial)) {
186                         serial_mismatch = true;
187                         libusb_close(libusb_handle);
188                         continue;
189                 }
190
191                 /* Success. */
192                 *out = libusb_handle;
193                 retval = ERROR_OK;
194                 serial_mismatch = false;
195                 break;
196         }
197         if (cnt >= 0)
198                 libusb_free_device_list(devs, 1);
199
200         if (serial_mismatch)
201                 LOG_INFO("No device matches the serial string");
202
203         if (retval != ERROR_OK)
204                 libusb_exit(jtag_libusb_context);
205
206         return retval;
207 }
208
209 void jtag_libusb_close(struct libusb_device_handle *dev)
210 {
211         /* Close device */
212         libusb_close(dev);
213
214         libusb_exit(jtag_libusb_context);
215 }
216
217 int jtag_libusb_control_transfer(struct libusb_device_handle *dev, uint8_t request_type,
218                 uint8_t request, uint16_t value, uint16_t index, char *bytes,
219                 uint16_t size, unsigned int timeout)
220 {
221         int transferred = 0;
222
223         transferred = libusb_control_transfer(dev, request_type, request, value, index,
224                                 (unsigned char *)bytes, size, timeout);
225
226         if (transferred < 0)
227                 transferred = 0;
228
229         return transferred;
230 }
231
232 int jtag_libusb_bulk_write(struct libusb_device_handle *dev, int ep, char *bytes,
233                            int size, int timeout, int *transferred)
234 {
235         int ret;
236
237         *transferred = 0;
238
239         ret = libusb_bulk_transfer(dev, ep, (unsigned char *)bytes, size,
240                                    transferred, timeout);
241         if (ret != LIBUSB_SUCCESS) {
242                 LOG_ERROR("libusb_bulk_write error: %s", libusb_error_name(ret));
243                 return jtag_libusb_error(ret);
244         }
245
246         return ERROR_OK;
247 }
248
249 int jtag_libusb_bulk_read(struct libusb_device_handle *dev, int ep, char *bytes,
250                           int size, int timeout, int *transferred)
251 {
252         int ret;
253
254         *transferred = 0;
255
256         ret = libusb_bulk_transfer(dev, ep, (unsigned char *)bytes, size,
257                                    transferred, timeout);
258         if (ret != LIBUSB_SUCCESS) {
259                 LOG_ERROR("libusb_bulk_read error: %s", libusb_error_name(ret));
260                 return jtag_libusb_error(ret);
261         }
262
263         return ERROR_OK;
264 }
265
266 int jtag_libusb_set_configuration(struct libusb_device_handle *devh,
267                 int configuration)
268 {
269         struct libusb_device *udev = libusb_get_device(devh);
270         int retval = -99;
271
272         struct libusb_config_descriptor *config = NULL;
273         int current_config = -1;
274
275         retval = libusb_get_configuration(devh, &current_config);
276         if (retval != 0)
277                 return retval;
278
279         retval = libusb_get_config_descriptor(udev, configuration, &config);
280         if (retval != 0 || !config)
281                 return retval;
282
283         /* Only change the configuration if it is not already set to the
284            same one. Otherwise this issues a lightweight reset and hangs
285            LPC-Link2 with JLink firmware. */
286         if (current_config != config->bConfigurationValue)
287                 retval = libusb_set_configuration(devh, config->bConfigurationValue);
288
289         libusb_free_config_descriptor(config);
290
291         return retval;
292 }
293
294 int jtag_libusb_choose_interface(struct libusb_device_handle *devh,
295                 unsigned int *usb_read_ep,
296                 unsigned int *usb_write_ep,
297                 int bclass, int subclass, int protocol, int trans_type)
298 {
299         struct libusb_device *udev = libusb_get_device(devh);
300         const struct libusb_interface *inter;
301         const struct libusb_interface_descriptor *interdesc;
302         const struct libusb_endpoint_descriptor *epdesc;
303         struct libusb_config_descriptor *config;
304
305         *usb_read_ep = *usb_write_ep = 0;
306
307         libusb_get_config_descriptor(udev, 0, &config);
308         for (int i = 0; i < (int)config->bNumInterfaces; i++) {
309                 inter = &config->interface[i];
310
311                 interdesc = &inter->altsetting[0];
312                 for (int k = 0;
313                      k < (int)interdesc->bNumEndpoints; k++) {
314                         if ((bclass > 0 && interdesc->bInterfaceClass != bclass) ||
315                             (subclass > 0 && interdesc->bInterfaceSubClass != subclass) ||
316                             (protocol > 0 && interdesc->bInterfaceProtocol != protocol))
317                                 continue;
318
319                         epdesc = &interdesc->endpoint[k];
320                         if (trans_type > 0 && (epdesc->bmAttributes & 0x3) != trans_type)
321                                 continue;
322
323                         uint8_t epnum = epdesc->bEndpointAddress;
324                         bool is_input = epnum & 0x80;
325                         LOG_DEBUG("usb ep %s %02x",
326                                   is_input ? "in" : "out", epnum);
327
328                         if (is_input)
329                                 *usb_read_ep = epnum;
330                         else
331                                 *usb_write_ep = epnum;
332
333                         if (*usb_read_ep && *usb_write_ep) {
334                                 LOG_DEBUG("Claiming interface %d", (int)interdesc->bInterfaceNumber);
335                                 libusb_claim_interface(devh, (int)interdesc->bInterfaceNumber);
336                                 libusb_free_config_descriptor(config);
337                                 return ERROR_OK;
338                         }
339                 }
340         }
341         libusb_free_config_descriptor(config);
342
343         return ERROR_FAIL;
344 }
345
346 int jtag_libusb_get_pid(struct libusb_device *dev, uint16_t *pid)
347 {
348         struct libusb_device_descriptor dev_desc;
349
350         if (libusb_get_device_descriptor(dev, &dev_desc) == 0) {
351                 *pid = dev_desc.idProduct;
352
353                 return ERROR_OK;
354         }
355
356         return ERROR_FAIL;
357 }
358
359 int jtag_libusb_handle_events_completed(int *completed)
360 {
361         return libusb_handle_events_completed(jtag_libusb_context, completed);
362 }