jtag/drivers/cmsis_dap: fix usb bulk connection logic
[fw/openocd] / src / jtag / drivers / cmsis_dap_usb_bulk.c
1 /***************************************************************************
2  *   Copyright (C) 2018 by MickaĆ«l Thomas                                  *
3  *   mickael9@gmail.com                                                    *
4  *                                                                         *
5  *   Copyright (C) 2016 by Maksym Hilliaka                                 *
6  *   oter@frozen-team.com                                                  *
7  *                                                                         *
8  *   Copyright (C) 2016 by Phillip Pearson                                 *
9  *   pp@myelin.co.nz                                                       *
10  *                                                                         *
11  *   Copyright (C) 2014 by Paul Fertser                                    *
12  *   fercerpav@gmail.com                                                   *
13  *                                                                         *
14  *   Copyright (C) 2013 by mike brown                                      *
15  *   mike@theshedworks.org.uk                                              *
16  *                                                                         *
17  *   Copyright (C) 2013 by Spencer Oliver                                  *
18  *   spen@spen-soft.co.uk                                                  *
19  *                                                                         *
20  *   This program is free software; you can redistribute it and/or modify  *
21  *   it under the terms of the GNU General Public License as published by  *
22  *   the Free Software Foundation; either version 2 of the License, or     *
23  *   (at your option) any later version.                                   *
24  *                                                                         *
25  *   This program is distributed in the hope that it will be useful,       *
26  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
27  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
28  *   GNU General Public License for more details.                          *
29  *                                                                         *
30  *   You should have received a copy of the GNU General Public License     *
31  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
32  ***************************************************************************/
33
34 #ifdef HAVE_CONFIG_H
35 #include "config.h"
36 #endif
37
38 #include <libusb.h>
39 #include <helper/log.h>
40
41 #include "cmsis_dap.h"
42
43 struct cmsis_dap_backend_data {
44         libusb_context *usb_ctx;
45         libusb_device_handle *dev_handle;
46         unsigned int ep_out;
47         unsigned int ep_in;
48         int interface;
49 };
50
51 static int cmsis_dap_usb_interface = -1;
52
53 static int cmsis_dap_usb_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t pids[], char *serial)
54 {
55         int err;
56         libusb_context *ctx;
57         libusb_device **device_list;
58
59         err = libusb_init(&ctx);
60         if (err) {
61                 LOG_ERROR("libusb initialization failed: %s", libusb_strerror(err));
62                 return ERROR_FAIL;
63         }
64
65         int num_devices = libusb_get_device_list(ctx, &device_list);
66         if (num_devices < 0) {
67                 LOG_ERROR("could not enumerate USB devices: %s", libusb_strerror(num_devices));
68                 libusb_exit(ctx);
69                 return ERROR_FAIL;
70         }
71
72         for (int i = 0; i < num_devices; i++) {
73                 libusb_device *dev = device_list[i];
74                 struct libusb_device_descriptor dev_desc;
75
76                 err = libusb_get_device_descriptor(dev, &dev_desc);
77                 if (err) {
78                         LOG_ERROR("could not get device descriptor for device %d: %s", i, libusb_strerror(err));
79                         continue;
80                 }
81
82                 /* Match VID/PID */
83
84                 bool id_match = false;
85                 bool id_filter = vids[0] || pids[0];
86                 for (int id = 0; vids[id] || pids[id]; id++) {
87                         id_match = !vids[id] || dev_desc.idVendor == vids[id];
88                         id_match &= !pids[id] || dev_desc.idProduct == pids[id];
89
90                         if (id_match)
91                                 break;
92                 }
93
94                 if (id_filter && !id_match)
95                         continue;
96
97                 /* Don't continue if we asked for a serial number and the device doesn't have one */
98                 if (dev_desc.iSerialNumber == 0 && serial && serial[0])
99                         continue;
100
101                 libusb_device_handle *dev_handle = NULL;
102                 err = libusb_open(dev, &dev_handle);
103                 if (err) {
104                         /* It's to be expected that most USB devices can't be opened
105                          * so only report an error if it was explicitly selected
106                          */
107                         if (id_filter) {
108                                 LOG_ERROR("could not open device 0x%04x:0x%04x: %s",
109                                                 dev_desc.idVendor, dev_desc.idProduct, libusb_strerror(err));
110                         } else {
111                                 LOG_DEBUG("could not open device 0x%04x:0x%04x: %s",
112                                                 dev_desc.idVendor, dev_desc.idProduct, libusb_strerror(err));
113                         }
114                         continue;
115                 }
116
117                 /* Match serial number */
118
119                 bool serial_match = false;
120                 char dev_serial[256] = {0};
121                 if (dev_desc.iSerialNumber > 0) {
122                         err = libusb_get_string_descriptor_ascii(
123                                         dev_handle, dev_desc.iSerialNumber,
124                                         (uint8_t *)dev_serial, sizeof(dev_serial));
125
126                         if (err < 0) {
127                                 const char *msg = "could not read serial number for device 0x%04x:0x%04x: %s";
128                                 if (serial)
129                                         LOG_WARNING(msg, dev_desc.idVendor, dev_desc.idProduct,
130                                                                 libusb_strerror(err));
131                                 else
132                                         LOG_DEBUG(msg, dev_desc.idVendor, dev_desc.idProduct,
133                                                                 libusb_strerror(err));
134                         } else if (serial && strncmp(dev_serial, serial, sizeof(dev_serial)) == 0) {
135                                 serial_match = true;
136                         }
137                 }
138
139                 if (serial && !serial_match) {
140                         libusb_close(dev_handle);
141                         continue;
142                 }
143
144                 /* Find the CMSIS-DAP string in product string */
145
146                 bool cmsis_dap_in_product_str = false;
147                 char product_string[256] = {0};
148                 if (dev_desc.iProduct > 0) {
149                         err = libusb_get_string_descriptor_ascii(
150                                         dev_handle, dev_desc.iProduct,
151                                         (uint8_t *)product_string, sizeof(product_string));
152                         if (err < 0) {
153                                 LOG_WARNING("could not read product string for device 0x%04x:0x%04x: %s",
154                                                 dev_desc.idVendor, dev_desc.idProduct, libusb_strerror(err));
155                         } else if (strstr(product_string, "CMSIS-DAP")) {
156                                 LOG_DEBUG("found product string of 0x%04x:0x%04x '%s'",
157                                                   dev_desc.idVendor, dev_desc.idProduct, product_string);
158                                 cmsis_dap_in_product_str = true;
159                         }
160                 }
161
162                 bool device_identified_reliably = cmsis_dap_in_product_str
163                                                                                         || serial_match || id_match;
164
165                 /* Find the CMSIS-DAP interface */
166
167                 for (int config = 0; config < dev_desc.bNumConfigurations; config++) {
168                         struct libusb_config_descriptor *config_desc;
169                         err = libusb_get_config_descriptor(dev, config, &config_desc);
170                         if (err) {
171                                 LOG_ERROR("could not get configuration descriptor %d for device 0x%04x:0x%04x: %s",
172                                                 config, dev_desc.idVendor, dev_desc.idProduct, libusb_strerror(err));
173                                 continue;
174                         }
175
176                         LOG_DEBUG("enumerating interfaces of 0x%04x:0x%04x",
177                                           dev_desc.idVendor, dev_desc.idProduct);
178                         int config_num = config_desc->bConfigurationValue;
179                         const struct libusb_interface_descriptor *intf_desc_candidate = NULL;
180                         const struct libusb_interface_descriptor *intf_desc_found = NULL;
181
182                         for (int interface = 0; interface < config_desc->bNumInterfaces; interface++) {
183                                 const struct libusb_interface_descriptor *intf_desc = &config_desc->interface[interface].altsetting[0];
184                                 int interface_num = intf_desc->bInterfaceNumber;
185
186                                 /* Skip this interface if another one was requested explicitly */
187                                 if (cmsis_dap_usb_interface != -1 && cmsis_dap_usb_interface != interface_num)
188                                         continue;
189
190                                 /* CMSIS-DAP v2 spec says:
191                                  *
192                                  * CMSIS-DAP with default V2 configuration uses WinUSB and is therefore faster.
193                                  * Optionally support for streaming SWO trace is provided via an additional USB endpoint.
194                                  *
195                                  * The WinUSB configuration requires custom class support with the interface setting
196                                  *     Class Code: 0xFF (Vendor specific)
197                                  *     Subclass: 0x00
198                                  *     Protocol code: 0x00
199                                  *
200                                  * Depending on the configuration it uses the following USB endpoints which should be configured
201                                  * in the interface descriptor in this order:
202                                  *  - Endpoint 1: Bulk Out ā€“ used for commands received from host PC.
203                                  *  - Endpoint 2: Bulk In ā€“ used for responses send to host PC.
204                                  *  - Endpoint 3: Bulk In (optional) ā€“ used for streaming SWO trace (if enabled with SWO_STREAM).
205                                  */
206
207                                 /* Search for "CMSIS-DAP" in the interface string */
208                                 bool cmsis_dap_in_interface_str = false;
209                                 if (intf_desc->iInterface != 0) {
210
211                                         char interface_str[256] = {0};
212
213                                         err = libusb_get_string_descriptor_ascii(
214                                                         dev_handle, intf_desc->iInterface,
215                                                         (uint8_t *)interface_str, sizeof(interface_str));
216                                         if (err < 0) {
217                                                 LOG_DEBUG("could not read interface string %d for device 0x%04x:0x%04x: %s",
218                                                                   intf_desc->iInterface,
219                                                                   dev_desc.idVendor, dev_desc.idProduct,
220                                                                   libusb_strerror(err));
221                                         } else if (strstr(interface_str, "CMSIS-DAP")) {
222                                                 cmsis_dap_in_interface_str = true;
223                                                 LOG_DEBUG("found interface %d string '%s'",
224                                                                   interface_num, interface_str);
225                                         }
226                                 }
227
228                                 /* Bypass the following check if this interface was explicitly requested. */
229                                 if (cmsis_dap_usb_interface == -1) {
230                                         if (!cmsis_dap_in_product_str && !cmsis_dap_in_interface_str)
231                                                 continue;
232                                 }
233
234                                 /* check endpoints */
235                                 if (intf_desc->bNumEndpoints < 2) {
236                                         LOG_DEBUG("skipping interface %d, has only %d endpoints",
237                                                           interface_num, intf_desc->bNumEndpoints);
238                                         continue;
239                                 }
240
241                                 if ((intf_desc->endpoint[0].bmAttributes & 3) != LIBUSB_TRANSFER_TYPE_BULK ||
242                                                 (intf_desc->endpoint[0].bEndpointAddress & 0x80) != LIBUSB_ENDPOINT_OUT) {
243                                         LOG_DEBUG("skipping interface %d, endpoint[0] is not bulk out",
244                                                           interface_num);
245                                         continue;
246                                 }
247
248                                 if ((intf_desc->endpoint[1].bmAttributes & 3) != LIBUSB_TRANSFER_TYPE_BULK ||
249                                                 (intf_desc->endpoint[1].bEndpointAddress & 0x80) != LIBUSB_ENDPOINT_IN) {
250                                         LOG_DEBUG("skipping interface %d, endpoint[1] is not bulk in",
251                                                           interface_num);
252                                         continue;
253                                 }
254
255                                 /* We can rely on the interface is really CMSIS-DAP if
256                                  * - we've seen CMSIS-DAP in the interface string
257                                  * - config asked explicitly for an interface number
258                                  * - the device has only one interface
259                                  * The later two cases should be honored only if we know
260                                  * we are on the rigt device */
261                                 bool intf_identified_reliably = cmsis_dap_in_interface_str
262                                                         || (device_identified_reliably &&
263                                                                         (cmsis_dap_usb_interface != -1
264                                                                          || config_desc->bNumInterfaces == 1));
265
266                                 if (intf_desc->bInterfaceClass != LIBUSB_CLASS_VENDOR_SPEC ||
267                                                 intf_desc->bInterfaceSubClass != 0 || intf_desc->bInterfaceProtocol != 0) {
268                                         /* If the interface is reliably identified
269                                          * then we need not insist on setting USB class, subclass and protocol
270                                          * exactly as the specification requires.
271                                          * At least KitProg3 uses class 0 contrary to the specification */
272                                         if (intf_identified_reliably) {
273                                                 LOG_WARNING("Using CMSIS-DAPv2 interface %d with wrong class %" PRId8
274                                                                   " subclass %" PRId8 " or protocol %" PRId8,
275                                                                   interface_num,
276                                                                   intf_desc->bInterfaceClass,
277                                                                   intf_desc->bInterfaceSubClass,
278                                                                   intf_desc->bInterfaceProtocol);
279                                         } else {
280                                                 LOG_DEBUG("skipping interface %d, class %" PRId8
281                                                                   " subclass %" PRId8 " protocol %" PRId8,
282                                                                   interface_num,
283                                                                   intf_desc->bInterfaceClass,
284                                                                   intf_desc->bInterfaceSubClass,
285                                                                   intf_desc->bInterfaceProtocol);
286                                                 continue;
287
288                                         }
289                                 }
290
291                                 if (intf_identified_reliably) {
292                                         /* That's the one! */
293                                         intf_desc_found = intf_desc;
294                                         break;
295                                 }
296
297                                 if (!intf_desc_candidate && device_identified_reliably) {
298                                         /* This interface looks suitable for CMSIS-DAP. Store the pointer to it
299                                          * and keep searching for another one with CMSIS-DAP in interface string */
300                                         intf_desc_candidate = intf_desc;
301                                 }
302                         }
303
304                         if (!intf_desc_found) {
305                                 /* We were not able to identify reliably which interface is CMSIS-DAP.
306                                  * Let's use the first suitable if we found one */
307                                 intf_desc_found = intf_desc_candidate;
308                         }
309
310                         if (!intf_desc_found) {
311                                 libusb_free_config_descriptor(config_desc);
312                                 continue;
313                         }
314
315                         /* We've chosen an interface, connect to it */
316                         int interface_num = intf_desc_found->bInterfaceNumber;
317                         int packet_size = intf_desc_found->endpoint[0].wMaxPacketSize;
318                         int ep_out = intf_desc_found->endpoint[0].bEndpointAddress;
319                         int ep_in = intf_desc_found->endpoint[1].bEndpointAddress;
320
321                         libusb_free_config_descriptor(config_desc);
322                         libusb_free_device_list(device_list, true);
323
324                         LOG_INFO("Using CMSIS-DAPv2 interface with VID:PID=0x%04x:0x%04x, serial=%s",
325                                         dev_desc.idVendor, dev_desc.idProduct, dev_serial);
326
327                         int current_config;
328                         err = libusb_get_configuration(dev_handle, &current_config);
329                         if (err) {
330                                 LOG_ERROR("could not find current configuration: %s", libusb_strerror(err));
331                                 libusb_close(dev_handle);
332                                 libusb_exit(ctx);
333                                 return ERROR_FAIL;
334                         }
335
336                         if (config_num != current_config) {
337                                 err = libusb_set_configuration(dev_handle, config_num);
338                                 if (err) {
339                                         LOG_ERROR("could not set configuration: %s", libusb_strerror(err));
340                                         libusb_close(dev_handle);
341                                         libusb_exit(ctx);
342                                         return ERROR_FAIL;
343                                 }
344                         }
345
346                         err = libusb_claim_interface(dev_handle, interface_num);
347                         if (err)
348                                 LOG_WARNING("could not claim interface: %s", libusb_strerror(err));
349
350                         dap->bdata = malloc(sizeof(struct cmsis_dap_backend_data));
351                         if (dap->bdata == NULL) {
352                                 LOG_ERROR("unable to allocate memory");
353                                 libusb_release_interface(dev_handle, interface_num);
354                                 libusb_close(dev_handle);
355                                 libusb_exit(ctx);
356                                 return ERROR_FAIL;
357                         }
358
359                         dap->packet_size = packet_size + 1; /* "+ 1" for compatibility with the HID backend */
360                         dap->bdata->usb_ctx = ctx;
361                         dap->bdata->dev_handle = dev_handle;
362                         dap->bdata->ep_out = ep_out;
363                         dap->bdata->ep_in = ep_in;
364                         dap->bdata->interface = interface_num;
365                         return ERROR_OK;
366                 }
367
368                 libusb_close(dev_handle);
369         }
370
371         libusb_free_device_list(device_list, true);
372
373         libusb_exit(ctx);
374         return ERROR_FAIL;
375 }
376
377 static void cmsis_dap_usb_close(struct cmsis_dap *dap)
378 {
379         libusb_release_interface(dap->bdata->dev_handle, dap->bdata->interface);
380         libusb_close(dap->bdata->dev_handle);
381         libusb_exit(dap->bdata->usb_ctx);
382         free(dap->bdata);
383         dap->bdata = NULL;
384 }
385
386 static int cmsis_dap_usb_read(struct cmsis_dap *dap, int timeout_ms)
387 {
388         int transferred = 0;
389         int err;
390
391         err = libusb_bulk_transfer(dap->bdata->dev_handle, dap->bdata->ep_in,
392                                                         dap->packet_buffer, dap->packet_size, &transferred, timeout_ms);
393         if (err) {
394                 if (err == LIBUSB_ERROR_TIMEOUT) {
395                         return ERROR_TIMEOUT_REACHED;
396                 } else {
397                         LOG_ERROR("error reading data: %s", libusb_strerror(err));
398                         return ERROR_FAIL;
399                 }
400         }
401
402         memset(&dap->packet_buffer[transferred], 0, dap->packet_size - transferred);
403
404         return transferred;
405 }
406
407 static int cmsis_dap_usb_write(struct cmsis_dap *dap, int txlen, int timeout_ms)
408 {
409         int transferred = 0;
410         int err;
411
412         /* skip the first byte that is only used by the HID backend */
413         err = libusb_bulk_transfer(dap->bdata->dev_handle, dap->bdata->ep_out,
414                                                         dap->packet_buffer + 1, txlen - 1, &transferred, timeout_ms);
415         if (err) {
416                 if (err == LIBUSB_ERROR_TIMEOUT) {
417                         return ERROR_TIMEOUT_REACHED;
418                 } else {
419                         LOG_ERROR("error writing data: %s", libusb_strerror(err));
420                         return ERROR_FAIL;
421                 }
422         }
423
424         return transferred;
425 }
426
427 COMMAND_HANDLER(cmsis_dap_handle_usb_interface_command)
428 {
429         if (CMD_ARGC == 1)
430                 cmsis_dap_usb_interface = strtoul(CMD_ARGV[0], NULL, 10);
431         else
432                 LOG_ERROR("expected exactly one argument to cmsis_dap_usb_interface <interface_number>");
433
434         return ERROR_OK;
435 }
436
437 const struct command_registration cmsis_dap_usb_subcommand_handlers[] = {
438         {
439                 .name = "interface",
440                 .handler = &cmsis_dap_handle_usb_interface_command,
441                 .mode = COMMAND_CONFIG,
442                 .help = "set the USB interface number to use (for USB bulk backend only)",
443                 .usage = "<interface_number>",
444         },
445         COMMAND_REGISTRATION_DONE
446 };
447
448 const struct cmsis_dap_backend cmsis_dap_usb_backend = {
449         .name = "usb_bulk",
450         .open = cmsis_dap_usb_open,
451         .close = cmsis_dap_usb_close,
452         .read = cmsis_dap_usb_read,
453         .write = cmsis_dap_usb_write,
454 };