OpenOCD
libusb_helper.c
Go to the documentation of this file.
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;
26 static struct libusb_device **devs;
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 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",
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  const char *product, 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  bool product_mismatch = false;
156  struct libusb_device_handle *libusb_handle = NULL;
157  const char *serial = adapter_get_required_serial();
158 
159  if (libusb_init(&jtag_libusb_context) < 0)
160  return ERROR_FAIL;
161 
162  cnt = libusb_get_device_list(jtag_libusb_context, &devs);
163 
164  for (idx = 0; idx < cnt; idx++) {
165  struct libusb_device_descriptor dev_desc;
166 
167  if (libusb_get_device_descriptor(devs[idx], &dev_desc) != 0)
168  continue;
169 
170  if (!jtag_libusb_match_ids(&dev_desc, vids, pids))
171  continue;
172 
174  continue;
175 
176  err_code = libusb_open(devs[idx], &libusb_handle);
177 
178  if (err_code) {
179  LOG_ERROR("libusb_open() failed with %s",
180  libusb_error_name(err_code));
181  continue;
182  }
183 
184  /* Device must be open to use libusb_get_string_descriptor_ascii. */
185  if (serial &&
186  !jtag_libusb_match_serial(libusb_handle, &dev_desc, serial, adapter_get_alternate_serial)) {
187  serial_mismatch = true;
188  libusb_close(libusb_handle);
189  continue;
190  }
191 
192  if (product &&
193  !string_descriptor_equal(libusb_handle, dev_desc.iProduct, product)) {
194  product_mismatch = true;
195  libusb_close(libusb_handle);
196  continue;
197  }
198 
199  /* Success. */
200  *out = libusb_handle;
201  retval = ERROR_OK;
202  serial_mismatch = false;
203  product_mismatch = false;
204  break;
205  }
206  if (cnt >= 0)
207  libusb_free_device_list(devs, 1);
208 
209  if (serial_mismatch)
210  LOG_INFO("No device matches the serial string");
211 
212  if (product_mismatch)
213  LOG_INFO("No device matches the product string");
214 
215  if (retval != ERROR_OK)
216  libusb_exit(jtag_libusb_context);
217 
218  return retval;
219 }
220 
221 void jtag_libusb_close(struct libusb_device_handle *dev)
222 {
223  /* Close device */
224  libusb_close(dev);
225 
226  libusb_exit(jtag_libusb_context);
227 }
228 
229 int jtag_libusb_control_transfer(struct libusb_device_handle *dev, uint8_t request_type,
230  uint8_t request, uint16_t value, uint16_t index, char *bytes,
231  uint16_t size, unsigned int timeout, int *transferred)
232 {
233  int retval = libusb_control_transfer(dev, request_type, request, value, index,
234  (unsigned char *)bytes, size, timeout);
235 
236  if (retval < 0) {
237  LOG_ERROR("libusb_control_transfer error: %s", libusb_error_name(retval));
238  if (transferred)
239  *transferred = 0;
240  return jtag_libusb_error(retval);
241  }
242 
243  if (transferred)
244  *transferred = retval;
245 
246  return ERROR_OK;
247 }
248 
249 int jtag_libusb_bulk_write(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_write error: %s", libusb_error_name(ret));
260  return jtag_libusb_error(ret);
261  }
262 
263  return ERROR_OK;
264 }
265 
266 int jtag_libusb_bulk_read(struct libusb_device_handle *dev, int ep, char *bytes,
267  int size, int timeout, int *transferred)
268 {
269  int ret;
270 
271  *transferred = 0;
272 
273  ret = libusb_bulk_transfer(dev, ep, (unsigned char *)bytes, size,
274  transferred, timeout);
275  if (ret != LIBUSB_SUCCESS) {
276  LOG_ERROR("libusb_bulk_read error: %s", libusb_error_name(ret));
277  return jtag_libusb_error(ret);
278  }
279 
280  return ERROR_OK;
281 }
282 
283 int jtag_libusb_set_configuration(struct libusb_device_handle *devh,
284  int configuration)
285 {
286  struct libusb_device *udev = libusb_get_device(devh);
287  int retval = -99;
288 
289  struct libusb_config_descriptor *config = NULL;
290  int current_config = -1;
291 
292  retval = libusb_get_configuration(devh, &current_config);
293  if (retval != 0)
294  return retval;
295 
296  retval = libusb_get_config_descriptor(udev, configuration, &config);
297  if (retval != 0 || !config)
298  return retval;
299 
300  /* Only change the configuration if it is not already set to the
301  same one. Otherwise this issues a lightweight reset and hangs
302  LPC-Link2 with JLink firmware. */
303  if (current_config != config->bConfigurationValue)
304  retval = libusb_set_configuration(devh, config->bConfigurationValue);
305 
306  libusb_free_config_descriptor(config);
307 
308  return retval;
309 }
310 
311 int jtag_libusb_choose_interface(struct libusb_device_handle *devh,
312  unsigned int *usb_read_ep,
313  unsigned int *usb_write_ep,
314  int bclass, int subclass, int protocol, int trans_type)
315 {
316  struct libusb_device *udev = libusb_get_device(devh);
317  const struct libusb_interface *inter;
318  const struct libusb_interface_descriptor *interdesc;
319  const struct libusb_endpoint_descriptor *epdesc;
320  struct libusb_config_descriptor *config;
321 
322  *usb_read_ep = *usb_write_ep = 0;
323 
324  libusb_get_config_descriptor(udev, 0, &config);
325  for (int i = 0; i < (int)config->bNumInterfaces; i++) {
326  inter = &config->interface[i];
327 
328  interdesc = &inter->altsetting[0];
329  for (int k = 0;
330  k < (int)interdesc->bNumEndpoints; k++) {
331  if ((bclass > 0 && interdesc->bInterfaceClass != bclass) ||
332  (subclass > 0 && interdesc->bInterfaceSubClass != subclass) ||
333  (protocol > 0 && interdesc->bInterfaceProtocol != protocol))
334  continue;
335 
336  epdesc = &interdesc->endpoint[k];
337  if (trans_type > 0 && (epdesc->bmAttributes & 0x3) != trans_type)
338  continue;
339 
340  uint8_t epnum = epdesc->bEndpointAddress;
341  bool is_input = epnum & 0x80;
342  LOG_DEBUG("usb ep %s %02x",
343  is_input ? "in" : "out", epnum);
344 
345  if (is_input)
346  *usb_read_ep = epnum;
347  else
348  *usb_write_ep = epnum;
349 
350  if (*usb_read_ep && *usb_write_ep) {
351  LOG_DEBUG("Claiming interface %d", (int)interdesc->bInterfaceNumber);
352  libusb_claim_interface(devh, (int)interdesc->bInterfaceNumber);
353  libusb_free_config_descriptor(config);
354  return ERROR_OK;
355  }
356  }
357  }
358  libusb_free_config_descriptor(config);
359 
360  return ERROR_FAIL;
361 }
362 
363 int jtag_libusb_get_pid(struct libusb_device *dev, uint16_t *pid)
364 {
365  struct libusb_device_descriptor dev_desc;
366 
367  if (libusb_get_device_descriptor(dev, &dev_desc) == 0) {
368  *pid = dev_desc.idProduct;
369 
370  return ERROR_OK;
371  }
372 
373  return ERROR_FAIL;
374 }
375 
377 {
378  return libusb_handle_events_completed(jtag_libusb_context, completed);
379 }
380 
381 static enum {
386 
387 /* Older libusb does not implement following API calls - define stubs instead */
388 #if !defined(LIBUSB_API_VERSION) || (LIBUSB_API_VERSION < 0x01000105)
389 static uint8_t *libusb_dev_mem_alloc(libusb_device_handle *devh, size_t length)
390 {
391  return NULL;
392 }
393 
394 static int libusb_dev_mem_free(libusb_device_handle *devh,
395  uint8_t *buffer, size_t length)
396 {
397  return LIBUSB_ERROR_NOT_SUPPORTED;
398 }
399 #endif
400 
401 uint8_t *oocd_libusb_dev_mem_alloc(libusb_device_handle *devh,
402  size_t length)
403 {
404  uint8_t *buffer = NULL;
407 
410 
412  buffer = malloc(length);
413 
414  return buffer;
415 }
416 
417 int oocd_libusb_dev_mem_free(libusb_device_handle *devh,
418  uint8_t *buffer, size_t length)
419 {
420  if (!buffer)
421  return ERROR_OK;
422 
423  switch (dev_mem_allocation) {
424  case DEV_MEM_AVAILABLE:
426 
428  free(buffer);
429  return ERROR_OK;
430 
432  return ERROR_FAIL;
433  }
434  return ERROR_FAIL;
435 }
const char * adapter_get_required_serial(void)
Retrieves the serial number set with command 'adapter serial'.
Definition: adapter.c:298
bool adapter_usb_location_equal(uint8_t dev_bus, uint8_t *port_path, size_t path_len)
Definition: adapter.c:329
const char * adapter_usb_get_location(void)
Definition: adapter.c:324
char * serial
Definition: adapter.c:43
static const struct device_t * device
Definition: at91rm9200.c:94
uint8_t length
Definition: esp_usb_jtag.c:1
static enum @27 dev_mem_allocation
static bool jtag_libusb_match_serial(struct libusb_device_handle *device, struct libusb_device_descriptor *dev_desc, const char *serial, adapter_get_alternate_serial_fn adapter_get_alternate_serial)
int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], const char *product, struct libusb_device_handle **out, adapter_get_alternate_serial_fn adapter_get_alternate_serial)
static bool jtag_libusb_location_equal(struct libusb_device *device)
Definition: libusb_helper.c:83
int jtag_libusb_bulk_write(struct libusb_device_handle *dev, int ep, char *bytes, int size, int timeout, int *transferred)
int jtag_libusb_handle_events_completed(int *completed)
int jtag_libusb_get_pid(struct libusb_device *dev, uint16_t *pid)
#define MAX_USB_PORTS
Definition: libusb_helper.c:23
static bool string_descriptor_equal(struct libusb_device_handle *device, uint8_t str_index, const char *string)
Definition: libusb_helper.c:91
uint8_t * oocd_libusb_dev_mem_alloc(libusb_device_handle *devh, size_t length)
Attempts to allocate a block of persistent DMA memory suitable for transfers against the USB device.
int jtag_libusb_control_transfer(struct libusb_device_handle *dev, uint8_t request_type, uint8_t request, uint16_t value, uint16_t index, char *bytes, uint16_t size, unsigned int timeout, int *transferred)
static struct libusb_device ** devs
The usb device list.
Definition: libusb_helper.c:26
static int jtag_libusb_error(int err)
Definition: libusb_helper.c:28
static int libusb_dev_mem_free(libusb_device_handle *devh, uint8_t *buffer, size_t length)
int jtag_libusb_set_configuration(struct libusb_device_handle *devh, int configuration)
void jtag_libusb_close(struct libusb_device_handle *dev)
int jtag_libusb_bulk_read(struct libusb_device_handle *dev, int ep, char *bytes, int size, int timeout, int *transferred)
int oocd_libusb_dev_mem_free(libusb_device_handle *devh, uint8_t *buffer, size_t length)
Free device memory allocated with oocd_libusb_dev_mem_alloc().
@ DEV_MEM_NOT_YET_DECIDED
@ DEV_MEM_AVAILABLE
@ DEV_MEM_FALLBACK_MALLOC
bool jtag_libusb_match_ids(struct libusb_device_descriptor *dev_desc, const uint16_t vids[], const uint16_t pids[])
Definition: libusb_helper.c:53
static uint8_t * libusb_dev_mem_alloc(libusb_device_handle *devh, size_t length)
static struct libusb_context * jtag_libusb_context
Libusb context.
Definition: libusb_helper.c:25
int jtag_libusb_choose_interface(struct libusb_device_handle *devh, unsigned int *usb_read_ep, unsigned int *usb_write_ep, int bclass, int subclass, int protocol, int trans_type)
Find the first interface optionally matching class, subclass and protocol and claim it.
char *(* adapter_get_alternate_serial_fn)(struct libusb_device_handle *device, struct libusb_device_descriptor *dev_desc)
Definition: libusb_helper.h:30
#define LOG_WARNING(expr ...)
Definition: log.h:129
#define ERROR_FAIL
Definition: log.h:170
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define ERROR_TIMEOUT_REACHED
Definition: log.h:173
#define LOG_INFO(expr ...)
Definition: log.h:126
#define LOG_DEBUG(expr ...)
Definition: log.h:109
#define ERROR_OK
Definition: log.h:164
size_t size
Size of the control block search area.
Definition: rtt/rtt.c:30
Definition: psoc6.c:84
#define NULL
Definition: usb.h:16