OpenOCD
libusb0_common.c
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net> *
3  * *
4  * Copyright (C) 2011 by Mauro Gamba <maurillo71@gmail.com> *
5  * *
6  * This program is free software; you can redistribute it and/or modify *
7  * it under the terms of the GNU General Public License as published by *
8  * the Free Software Foundation; either version 2 of the License, or *
9  * (at your option) any later version. *
10  * *
11  * This program is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14  * GNU General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU General Public License *
17  * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18  ***************************************************************************/
19 
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 #include "log.h"
24 #include "libusb0_common.h"
25 
26 static bool jtag_libusb_match(struct jtag_libusb_device *dev,
27  const uint16_t vids[], const uint16_t pids[])
28 {
29  for (unsigned i = 0; vids[i]; i++) {
30  if (dev->descriptor.idVendor == vids[i] &&
31  dev->descriptor.idProduct == pids[i]) {
32  return true;
33  }
34  }
35  return false;
36 }
37 
38 /* Returns true if the string descriptor indexed by str_index in device matches string */
39 static bool string_descriptor_equal(usb_dev_handle *device, uint8_t str_index,
40  const char *string)
41 {
42  int retval;
43  bool matched;
44  char desc_string[256+1]; /* Max size of string descriptor */
45 
46  if (str_index == 0)
47  return false;
48 
49  retval = usb_get_string_simple(device, str_index,
50  desc_string, sizeof(desc_string)-1);
51  if (retval < 0) {
52  LOG_ERROR("usb_get_string_simple() failed with %d", retval);
53  return false;
54  }
55 
56  /* Null terminate descriptor string in case it needs to be logged. */
57  desc_string[sizeof(desc_string)-1] = '\0';
58 
59  matched = strncmp(string, desc_string, sizeof(desc_string)) == 0;
60  if (!matched)
61  LOG_DEBUG("Device serial number '%s' doesn't match requested serial '%s'",
62  desc_string, string);
63  return matched;
64 }
65 
66 int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[],
67  const char *serial,
68  struct jtag_libusb_device_handle **out)
69 {
70  int retval = -ENODEV;
71  struct jtag_libusb_device_handle *libusb_handle;
72  usb_init();
73 
74  usb_find_busses();
75  usb_find_devices();
76 
77  struct usb_bus *busses = usb_get_busses();
78  for (struct usb_bus *bus = busses; bus; bus = bus->next) {
79  for (struct usb_device *dev = bus->devices;
80  dev; dev = dev->next) {
81  if (!jtag_libusb_match(dev, vids, pids))
82  continue;
83 
84  libusb_handle = usb_open(dev);
85  if (NULL == libusb_handle) {
86  retval = -errno;
87  continue;
88  }
89 
90  /* Device must be open to use libusb_get_string_descriptor_ascii. */
91  if (serial != NULL &&
92  !string_descriptor_equal(libusb_handle, dev->descriptor.iSerialNumber, serial)) {
93  usb_close(libusb_handle);
94  continue;
95  }
96  *out = libusb_handle;
97  retval = 0;
98  break;
99  }
100  }
101  return retval;
102 }
103 
105 {
106  /* Close device */
107  usb_close(dev);
108 }
109 
111  uint8_t request, uint16_t wValue, uint16_t wIndex, char *bytes,
112  uint16_t size, unsigned int timeout)
113 {
114  int transferred = 0;
115 
116  transferred = usb_control_msg(dev, requestType, request, wValue, wIndex,
117  bytes, size, timeout);
118 
119  if (transferred < 0)
120  transferred = 0;
121 
122  return transferred;
123 }
124 
125 int jtag_libusb_bulk_write(jtag_libusb_device_handle *dev, int ep, char *bytes,
126  int size, int timeout)
127 {
128  return usb_bulk_write(dev, ep, bytes, size, timeout);
129 }
130 
131 int jtag_libusb_bulk_read(jtag_libusb_device_handle *dev, int ep, char *bytes,
132  int size, int timeout)
133 {
134  return usb_bulk_read(dev, ep, bytes, size, timeout);
135 }
136 
138  int configuration)
139 {
140  struct jtag_libusb_device *udev = jtag_libusb_get_device(devh);
141 
142  return usb_set_configuration(devh,
143  udev->config[configuration].bConfigurationValue);
144 }
145 
147  unsigned int *usb_read_ep,
148  unsigned int *usb_write_ep,
149  int bclass, int subclass, int protocol)
150 {
151  struct jtag_libusb_device *udev = jtag_libusb_get_device(devh);
152  struct usb_interface *iface = udev->config->interface;
153  struct usb_interface_descriptor *desc = iface->altsetting;
154 
155  *usb_read_ep = *usb_write_ep = 0;
156 
157  for (int i = 0; i < desc->bNumEndpoints; i++) {
158  if ((bclass > 0 && desc->bInterfaceClass != bclass) ||
159  (subclass > 0 && desc->bInterfaceSubClass != subclass) ||
160  (protocol > 0 && desc->bInterfaceProtocol != protocol))
161  continue;
162 
163  uint8_t epnum = desc->endpoint[i].bEndpointAddress;
164  bool is_input = epnum & 0x80;
165  LOG_DEBUG("usb ep %s %02x", is_input ? "in" : "out", epnum);
166  if (is_input)
167  *usb_read_ep = epnum;
168  else
169  *usb_write_ep = epnum;
170 
171  if (*usb_read_ep && *usb_write_ep) {
172  LOG_DEBUG("Claiming interface %d", (int)desc->bInterfaceNumber);
173  usb_claim_interface(devh, (int)desc->bInterfaceNumber);
174  return ERROR_OK;
175  }
176  }
177 
178  return ERROR_FAIL;
179 }
180 
181 int jtag_libusb_get_pid(struct jtag_libusb_device *dev, uint16_t *pid)
182 {
183  if (!dev)
184  return ERROR_FAIL;
185 
186  *pid = dev->descriptor.idProduct;
187  return ERROR_OK;
188 }
int jtag_libusb_control_transfer(jtag_libusb_device_handle *dev, uint8_t requestType, uint8_t request, uint16_t wValue, uint16_t wIndex, char *bytes, uint16_t size, unsigned int timeout)
#define LOG_DEBUG(expr...)
Definition: log.h:105
struct usb_bus * busses
Definition: usbprog.c:364
uint8_t bInterfaceClass
Class code.
Definition: usb.h:85
#define jtag_libusb_get_device(devh)
static const struct device_t * device
Definition: at91rm9200.c:105
#define ERROR_FAIL
Definition: log.h:140
int jtag_libusb_get_pid(struct jtag_libusb_device *dev, uint16_t *pid)
int jtag_libusb_choose_interface(struct jtag_libusb_device_handle *devh, unsigned int *usb_read_ep, unsigned int *usb_write_ep, int bclass, int subclass, int protocol)
Find the first interface optionally matching class, subclass and protocol and claim it...
int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], const char *serial, struct jtag_libusb_device_handle **out)
USB Interface Descriptor.
Definition: usb.h:79
#define jtag_libusb_device_handle
uint8_t bInterfaceProtocol
Protocol code.
Definition: usb.h:87
#define jtag_libusb_device
int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh, int configuration)
int jtag_libusb_bulk_read(jtag_libusb_device_handle *dev, int ep, char *bytes, int size, int timeout)
void usb_init(void)
USB initialization.
Definition: usb.c:531
#define LOG_ERROR(expr...)
Definition: log.h:119
static bool string_descriptor_equal(usb_dev_handle *device, uint8_t str_index, const char *string)
uint8_t bInterfaceNumber
Interface number.
Definition: usb.h:82
int jtag_libusb_bulk_write(jtag_libusb_device_handle *dev, int ep, char *bytes, int size, int timeout)
void jtag_libusb_close(jtag_libusb_device_handle *dev)
#define ERROR_OK
Definition: log.h:134
uint8_t bNumEndpoints
Number of endpoints used by this interface.
Definition: usb.h:84
static bool jtag_libusb_match(struct jtag_libusb_device *dev, const uint16_t vids[], const uint16_t pids[])
#define NULL
Definition: usb.h:27