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 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",
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 
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 
360 {
361  return libusb_handle_events_completed(jtag_libusb_context, completed);
362 }
const char * adapter_get_required_serial(void)
Retrieves the serial number set with command 'adapter serial'.
Definition: adapter.c:299
bool adapter_usb_location_equal(uint8_t dev_bus, uint8_t *port_path, size_t path_len)
Definition: adapter.c:330
const char * adapter_usb_get_location(void)
Definition: adapter.c:325
char * serial
Definition: adapter.c:47
static const struct device_t * device
Definition: at91rm9200.c:94
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)
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_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 jtag_libusb_handle_events_completed(int *completed)
static bool jtag_libusb_match_ids(struct libusb_device_descriptor *dev_desc, const uint16_t vids[], const uint16_t pids[])
Definition: libusb_helper.c:53
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
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
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 jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], struct libusb_device_handle **out, adapter_get_alternate_serial_fn adapter_get_alternate_serial)
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:120
#define ERROR_FAIL
Definition: log.h:161
#define LOG_ERROR(expr ...)
Definition: log.h:123
#define ERROR_TIMEOUT_REACHED
Definition: log.h:164
#define LOG_INFO(expr ...)
Definition: log.h:117
#define LOG_DEBUG(expr ...)
Definition: log.h:109
#define ERROR_OK
Definition: log.h:155
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