jtag/drivers/cmsis_dap: implement canceling of pending USB requests
[openocd.git] / src / jtag / drivers / cmsis_dap_usb_bulk.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4 * Copyright (C) 2018 by Mickaƫl Thomas *
5 * mickael9@gmail.com *
6 * *
7 * Copyright (C) 2016 by Maksym Hilliaka *
8 * oter@frozen-team.com *
9 * *
10 * Copyright (C) 2016 by Phillip Pearson *
11 * pp@myelin.co.nz *
12 * *
13 * Copyright (C) 2014 by Paul Fertser *
14 * fercerpav@gmail.com *
15 * *
16 * Copyright (C) 2013 by mike brown *
17 * mike@theshedworks.org.uk *
18 * *
19 * Copyright (C) 2013 by Spencer Oliver *
20 * spen@spen-soft.co.uk *
21 ***************************************************************************/
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <helper/system.h>
28 #include <libusb.h>
29 #include <helper/log.h>
30 #include <helper/replacements.h>
31 #include <jtag/jtag.h> /* ERROR_JTAG_DEVICE_ERROR only */
32
33 #include "cmsis_dap.h"
34 #include "libusb_helper.h"
35
36 #if !defined(LIBUSB_API_VERSION) || (LIBUSB_API_VERSION < 0x01000105) \
37 || defined(_WIN32) || defined(__CYGWIN__)
38 #define libusb_dev_mem_alloc(dev, sz) malloc(sz)
39 #define libusb_dev_mem_free(dev, buffer, sz) free(buffer)
40 #endif
41
42 enum {
43 CMSIS_DAP_TRANSFER_PENDING = 0, /* must be 0, used in libusb_handle_events_completed */
44 CMSIS_DAP_TRANSFER_IDLE,
45 CMSIS_DAP_TRANSFER_COMPLETED
46 };
47
48 struct cmsis_dap_bulk_transfer {
49 struct libusb_transfer *transfer;
50 uint8_t *buffer;
51 int status; /* either CMSIS_DAP_TRANSFER_ enum or error code */
52 int transferred;
53 };
54
55 struct cmsis_dap_backend_data {
56 struct libusb_context *usb_ctx;
57 struct libusb_device_handle *dev_handle;
58 unsigned int ep_out;
59 unsigned int ep_in;
60 int interface;
61
62 struct cmsis_dap_bulk_transfer command_transfers[MAX_PENDING_REQUESTS];
63 struct cmsis_dap_bulk_transfer response_transfers[MAX_PENDING_REQUESTS];
64 };
65
66 static int cmsis_dap_usb_interface = -1;
67
68 static void cmsis_dap_usb_close(struct cmsis_dap *dap);
69 static int cmsis_dap_usb_alloc(struct cmsis_dap *dap, unsigned int pkt_sz);
70 static void cmsis_dap_usb_free(struct cmsis_dap *dap);
71
72 static int cmsis_dap_usb_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t pids[], const char *serial)
73 {
74 int err;
75 struct libusb_context *ctx;
76 struct libusb_device **device_list;
77
78 err = libusb_init(&ctx);
79 if (err) {
80 LOG_ERROR("libusb initialization failed: %s", libusb_strerror(err));
81 return ERROR_FAIL;
82 }
83
84 int num_devices = libusb_get_device_list(ctx, &device_list);
85 if (num_devices < 0) {
86 LOG_ERROR("could not enumerate USB devices: %s", libusb_strerror(num_devices));
87 libusb_exit(ctx);
88 return ERROR_FAIL;
89 }
90
91 for (int i = 0; i < num_devices; i++) {
92 struct libusb_device *dev = device_list[i];
93 struct libusb_device_descriptor dev_desc;
94
95 err = libusb_get_device_descriptor(dev, &dev_desc);
96 if (err) {
97 LOG_ERROR("could not get device descriptor for device %d: %s", i, libusb_strerror(err));
98 continue;
99 }
100
101 /* Match VID/PID */
102
103 bool id_match = false;
104 bool id_filter = vids[0] || pids[0];
105 for (int id = 0; vids[id] || pids[id]; id++) {
106 id_match = !vids[id] || dev_desc.idVendor == vids[id];
107 id_match &= !pids[id] || dev_desc.idProduct == pids[id];
108
109 if (id_match)
110 break;
111 }
112
113 if (id_filter && !id_match)
114 continue;
115
116 /* Don't continue if we asked for a serial number and the device doesn't have one */
117 if (dev_desc.iSerialNumber == 0 && serial && serial[0])
118 continue;
119
120 struct libusb_device_handle *dev_handle = NULL;
121 err = libusb_open(dev, &dev_handle);
122 if (err) {
123 /* It's to be expected that most USB devices can't be opened
124 * so only report an error if it was explicitly selected
125 */
126 if (id_filter) {
127 LOG_ERROR("could not open device 0x%04x:0x%04x: %s",
128 dev_desc.idVendor, dev_desc.idProduct, libusb_strerror(err));
129 } else {
130 LOG_DEBUG("could not open device 0x%04x:0x%04x: %s",
131 dev_desc.idVendor, dev_desc.idProduct, libusb_strerror(err));
132 }
133 continue;
134 }
135
136 /* Match serial number */
137
138 bool serial_match = false;
139 char dev_serial[256] = {0};
140 if (dev_desc.iSerialNumber > 0) {
141 err = libusb_get_string_descriptor_ascii(
142 dev_handle, dev_desc.iSerialNumber,
143 (uint8_t *)dev_serial, sizeof(dev_serial));
144
145 if (err < 0) {
146 const char *msg = "could not read serial number for device 0x%04x:0x%04x: %s";
147 if (serial)
148 LOG_WARNING(msg, dev_desc.idVendor, dev_desc.idProduct,
149 libusb_strerror(err));
150 else
151 LOG_DEBUG(msg, dev_desc.idVendor, dev_desc.idProduct,
152 libusb_strerror(err));
153 } else if (serial && strncmp(dev_serial, serial, sizeof(dev_serial)) == 0) {
154 serial_match = true;
155 }
156 }
157
158 if (serial && !serial_match) {
159 libusb_close(dev_handle);
160 continue;
161 }
162
163 /* Find the CMSIS-DAP string in product string */
164
165 bool cmsis_dap_in_product_str = false;
166 char product_string[256] = {0};
167 if (dev_desc.iProduct > 0) {
168 err = libusb_get_string_descriptor_ascii(
169 dev_handle, dev_desc.iProduct,
170 (uint8_t *)product_string, sizeof(product_string));
171 if (err < 0) {
172 LOG_WARNING("could not read product string for device 0x%04x:0x%04x: %s",
173 dev_desc.idVendor, dev_desc.idProduct, libusb_strerror(err));
174 } else if (strstr(product_string, "CMSIS-DAP")) {
175 LOG_DEBUG("found product string of 0x%04x:0x%04x '%s'",
176 dev_desc.idVendor, dev_desc.idProduct, product_string);
177 cmsis_dap_in_product_str = true;
178 }
179 }
180
181 bool device_identified_reliably = cmsis_dap_in_product_str
182 || serial_match || id_match;
183
184 /* Find the CMSIS-DAP interface */
185
186 for (int config = 0; config < dev_desc.bNumConfigurations; config++) {
187 struct libusb_config_descriptor *config_desc;
188 err = libusb_get_config_descriptor(dev, config, &config_desc);
189 if (err) {
190 LOG_ERROR("could not get configuration descriptor %d for device 0x%04x:0x%04x: %s",
191 config, dev_desc.idVendor, dev_desc.idProduct, libusb_strerror(err));
192 continue;
193 }
194
195 LOG_DEBUG("enumerating interfaces of 0x%04x:0x%04x",
196 dev_desc.idVendor, dev_desc.idProduct);
197 int config_num = config_desc->bConfigurationValue;
198 const struct libusb_interface_descriptor *intf_desc_candidate = NULL;
199 const struct libusb_interface_descriptor *intf_desc_found = NULL;
200
201 for (int interface = 0; interface < config_desc->bNumInterfaces; interface++) {
202 const struct libusb_interface_descriptor *intf_desc = &config_desc->interface[interface].altsetting[0];
203 int interface_num = intf_desc->bInterfaceNumber;
204
205 /* Skip this interface if another one was requested explicitly */
206 if (cmsis_dap_usb_interface != -1 && cmsis_dap_usb_interface != interface_num)
207 continue;
208
209 /* CMSIS-DAP v2 spec says:
210 *
211 * CMSIS-DAP with default V2 configuration uses WinUSB and is therefore faster.
212 * Optionally support for streaming SWO trace is provided via an additional USB endpoint.
213 *
214 * The WinUSB configuration requires custom class support with the interface setting
215 * Class Code: 0xFF (Vendor specific)
216 * Subclass: 0x00
217 * Protocol code: 0x00
218 *
219 * Depending on the configuration it uses the following USB endpoints which should be configured
220 * in the interface descriptor in this order:
221 * - Endpoint 1: Bulk Out ā€“ used for commands received from host PC.
222 * - Endpoint 2: Bulk In ā€“ used for responses send to host PC.
223 * - Endpoint 3: Bulk In (optional) ā€“ used for streaming SWO trace (if enabled with SWO_STREAM).
224 */
225
226 /* Search for "CMSIS-DAP" in the interface string */
227 bool cmsis_dap_in_interface_str = false;
228 if (intf_desc->iInterface != 0) {
229
230 char interface_str[256] = {0};
231
232 err = libusb_get_string_descriptor_ascii(
233 dev_handle, intf_desc->iInterface,
234 (uint8_t *)interface_str, sizeof(interface_str));
235 if (err < 0) {
236 LOG_DEBUG("could not read interface string %d for device 0x%04x:0x%04x: %s",
237 intf_desc->iInterface,
238 dev_desc.idVendor, dev_desc.idProduct,
239 libusb_strerror(err));
240 } else if (strstr(interface_str, "CMSIS-DAP")) {
241 cmsis_dap_in_interface_str = true;
242 LOG_DEBUG("found interface %d string '%s'",
243 interface_num, interface_str);
244 }
245 }
246
247 /* Bypass the following check if this interface was explicitly requested. */
248 if (cmsis_dap_usb_interface == -1) {
249 if (!cmsis_dap_in_product_str && !cmsis_dap_in_interface_str)
250 continue;
251 }
252
253 /* check endpoints */
254 if (intf_desc->bNumEndpoints < 2) {
255 LOG_DEBUG("skipping interface %d, has only %d endpoints",
256 interface_num, intf_desc->bNumEndpoints);
257 continue;
258 }
259
260 if ((intf_desc->endpoint[0].bmAttributes & 3) != LIBUSB_TRANSFER_TYPE_BULK ||
261 (intf_desc->endpoint[0].bEndpointAddress & 0x80) != LIBUSB_ENDPOINT_OUT) {
262 LOG_DEBUG("skipping interface %d, endpoint[0] is not bulk out",
263 interface_num);
264 continue;
265 }
266
267 if ((intf_desc->endpoint[1].bmAttributes & 3) != LIBUSB_TRANSFER_TYPE_BULK ||
268 (intf_desc->endpoint[1].bEndpointAddress & 0x80) != LIBUSB_ENDPOINT_IN) {
269 LOG_DEBUG("skipping interface %d, endpoint[1] is not bulk in",
270 interface_num);
271 continue;
272 }
273
274 /* We can rely on the interface is really CMSIS-DAP if
275 * - we've seen CMSIS-DAP in the interface string
276 * - config asked explicitly for an interface number
277 * - the device has only one interface
278 * The later two cases should be honored only if we know
279 * we are on the right device */
280 bool intf_identified_reliably = cmsis_dap_in_interface_str
281 || (device_identified_reliably &&
282 (cmsis_dap_usb_interface != -1
283 || config_desc->bNumInterfaces == 1));
284
285 if (intf_desc->bInterfaceClass != LIBUSB_CLASS_VENDOR_SPEC ||
286 intf_desc->bInterfaceSubClass != 0 || intf_desc->bInterfaceProtocol != 0) {
287 /* If the interface is reliably identified
288 * then we need not insist on setting USB class, subclass and protocol
289 * exactly as the specification requires.
290 * Just filter out the well known classes, mainly CDC and MSC.
291 * At least KitProg3 uses class 0 contrary to the specification */
292 if (intf_identified_reliably &&
293 (intf_desc->bInterfaceClass == 0 || intf_desc->bInterfaceClass > 0x12)) {
294 LOG_WARNING("Using CMSIS-DAPv2 interface %d with wrong class %" PRId8
295 " subclass %" PRId8 " or protocol %" PRId8,
296 interface_num,
297 intf_desc->bInterfaceClass,
298 intf_desc->bInterfaceSubClass,
299 intf_desc->bInterfaceProtocol);
300 } else {
301 LOG_DEBUG("skipping interface %d, class %" PRId8
302 " subclass %" PRId8 " protocol %" PRId8,
303 interface_num,
304 intf_desc->bInterfaceClass,
305 intf_desc->bInterfaceSubClass,
306 intf_desc->bInterfaceProtocol);
307 continue;
308
309 }
310 }
311
312 if (intf_identified_reliably) {
313 /* That's the one! */
314 intf_desc_found = intf_desc;
315 break;
316 }
317
318 if (!intf_desc_candidate && device_identified_reliably) {
319 /* This interface looks suitable for CMSIS-DAP. Store the pointer to it
320 * and keep searching for another one with CMSIS-DAP in interface string */
321 intf_desc_candidate = intf_desc;
322 }
323 }
324
325 if (!intf_desc_found) {
326 /* We were not able to identify reliably which interface is CMSIS-DAP.
327 * Let's use the first suitable if we found one */
328 intf_desc_found = intf_desc_candidate;
329 }
330
331 if (!intf_desc_found) {
332 libusb_free_config_descriptor(config_desc);
333 continue;
334 }
335
336 /* We've chosen an interface, connect to it */
337 int interface_num = intf_desc_found->bInterfaceNumber;
338 int packet_size = intf_desc_found->endpoint[0].wMaxPacketSize;
339 int ep_out = intf_desc_found->endpoint[0].bEndpointAddress;
340 int ep_in = intf_desc_found->endpoint[1].bEndpointAddress;
341
342 libusb_free_config_descriptor(config_desc);
343 libusb_free_device_list(device_list, true);
344
345 LOG_INFO("Using CMSIS-DAPv2 interface with VID:PID=0x%04x:0x%04x, serial=%s",
346 dev_desc.idVendor, dev_desc.idProduct, dev_serial);
347
348 int current_config;
349 err = libusb_get_configuration(dev_handle, &current_config);
350 if (err) {
351 LOG_ERROR("could not find current configuration: %s", libusb_strerror(err));
352 libusb_close(dev_handle);
353 libusb_exit(ctx);
354 return ERROR_FAIL;
355 }
356
357 if (config_num != current_config) {
358 err = libusb_set_configuration(dev_handle, config_num);
359 if (err) {
360 LOG_ERROR("could not set configuration: %s", libusb_strerror(err));
361 libusb_close(dev_handle);
362 libusb_exit(ctx);
363 return ERROR_FAIL;
364 }
365 }
366
367 err = libusb_claim_interface(dev_handle, interface_num);
368 if (err)
369 LOG_WARNING("could not claim interface: %s", libusb_strerror(err));
370
371 dap->bdata = malloc(sizeof(struct cmsis_dap_backend_data));
372 if (!dap->bdata) {
373 LOG_ERROR("unable to allocate memory");
374 libusb_release_interface(dev_handle, interface_num);
375 libusb_close(dev_handle);
376 libusb_exit(ctx);
377 return ERROR_FAIL;
378 }
379
380 dap->bdata->usb_ctx = ctx;
381 dap->bdata->dev_handle = dev_handle;
382 dap->bdata->ep_out = ep_out;
383 dap->bdata->ep_in = ep_in;
384 dap->bdata->interface = interface_num;
385
386 for (unsigned int idx = 0; idx < MAX_PENDING_REQUESTS; idx++) {
387 dap->bdata->command_transfers[idx].status = CMSIS_DAP_TRANSFER_IDLE;
388 dap->bdata->command_transfers[idx].transfer = libusb_alloc_transfer(0);
389 if (!dap->bdata->command_transfers[idx].transfer) {
390 LOG_ERROR("unable to allocate USB transfer");
391 cmsis_dap_usb_close(dap);
392 return ERROR_FAIL;
393 }
394
395 dap->bdata->response_transfers[idx].status = CMSIS_DAP_TRANSFER_IDLE;
396 dap->bdata->response_transfers[idx].transfer = libusb_alloc_transfer(0);
397 if (!dap->bdata->response_transfers[idx].transfer) {
398 LOG_ERROR("unable to allocate USB transfer");
399 cmsis_dap_usb_close(dap);
400 return ERROR_FAIL;
401 }
402 }
403
404 err = cmsis_dap_usb_alloc(dap, packet_size);
405 if (err != ERROR_OK)
406 cmsis_dap_usb_close(dap);
407
408 return err;
409 }
410
411 libusb_close(dev_handle);
412 }
413
414 libusb_free_device_list(device_list, true);
415
416 libusb_exit(ctx);
417 return ERROR_FAIL;
418 }
419
420 static void cmsis_dap_usb_close(struct cmsis_dap *dap)
421 {
422 for (unsigned int i = 0; i < MAX_PENDING_REQUESTS; i++) {
423 libusb_free_transfer(dap->bdata->command_transfers[i].transfer);
424 libusb_free_transfer(dap->bdata->response_transfers[i].transfer);
425 }
426 cmsis_dap_usb_free(dap);
427 libusb_release_interface(dap->bdata->dev_handle, dap->bdata->interface);
428 libusb_close(dap->bdata->dev_handle);
429 libusb_exit(dap->bdata->usb_ctx);
430 free(dap->bdata);
431 dap->bdata = NULL;
432 }
433
434 static void LIBUSB_CALL cmsis_dap_usb_callback(struct libusb_transfer *transfer)
435 {
436 struct cmsis_dap_bulk_transfer *tr;
437
438 tr = (struct cmsis_dap_bulk_transfer *)transfer->user_data;
439 if (transfer->status == LIBUSB_TRANSFER_COMPLETED) {
440 tr->status = CMSIS_DAP_TRANSFER_COMPLETED;
441 tr->transferred = transfer->actual_length;
442 } else if (transfer->status == LIBUSB_TRANSFER_TIMED_OUT) {
443 tr->status = ERROR_TIMEOUT_REACHED;
444 } else {
445 tr->status = ERROR_JTAG_DEVICE_ERROR;
446 }
447 }
448
449 static int cmsis_dap_usb_read(struct cmsis_dap *dap, int transfer_timeout_ms,
450 struct timeval *wait_timeout)
451 {
452 int transferred = 0;
453 int err;
454 struct cmsis_dap_bulk_transfer *tr;
455 tr = &dap->bdata->response_transfers[dap->pending_fifo_get_idx];
456
457 if (tr->status == CMSIS_DAP_TRANSFER_IDLE) {
458 libusb_fill_bulk_transfer(tr->transfer,
459 dap->bdata->dev_handle, dap->bdata->ep_in,
460 tr->buffer, dap->packet_size,
461 &cmsis_dap_usb_callback, tr,
462 transfer_timeout_ms);
463 LOG_DEBUG_IO("submit read @ %u", dap->pending_fifo_get_idx);
464 tr->status = CMSIS_DAP_TRANSFER_PENDING;
465 err = libusb_submit_transfer(tr->transfer);
466 if (err) {
467 tr->status = CMSIS_DAP_TRANSFER_IDLE;
468 LOG_ERROR("error submitting USB read: %s", libusb_strerror(err));
469 return ERROR_FAIL;
470 }
471 }
472
473 struct timeval tv = {
474 .tv_sec = transfer_timeout_ms / 1000,
475 .tv_usec = transfer_timeout_ms % 1000 * 1000
476 };
477
478 while (tr->status == CMSIS_DAP_TRANSFER_PENDING) {
479 err = libusb_handle_events_timeout_completed(dap->bdata->usb_ctx,
480 wait_timeout ? wait_timeout : &tv,
481 &tr->status);
482 if (err) {
483 LOG_ERROR("error handling USB events: %s", libusb_strerror(err));
484 return ERROR_FAIL;
485 }
486 if (wait_timeout)
487 break;
488 }
489
490 if (tr->status < 0 || tr->status == CMSIS_DAP_TRANSFER_COMPLETED) {
491 /* Check related command request for an error */
492 struct cmsis_dap_bulk_transfer *tr_cmd;
493 tr_cmd = &dap->bdata->command_transfers[dap->pending_fifo_get_idx];
494 if (tr_cmd->status < 0) {
495 err = tr_cmd->status;
496 tr_cmd->status = CMSIS_DAP_TRANSFER_IDLE;
497 if (err != ERROR_TIMEOUT_REACHED)
498 LOG_ERROR("error writing USB data");
499 else
500 LOG_DEBUG("command write USB timeout @ %u", dap->pending_fifo_get_idx);
501
502 return err;
503 }
504 if (tr_cmd->status == CMSIS_DAP_TRANSFER_COMPLETED)
505 tr_cmd->status = CMSIS_DAP_TRANSFER_IDLE;
506 }
507
508 if (tr->status < 0) {
509 err = tr->status;
510 tr->status = CMSIS_DAP_TRANSFER_IDLE;
511 if (err != ERROR_TIMEOUT_REACHED)
512 LOG_ERROR("error reading USB data");
513 else
514 LOG_DEBUG("USB timeout @ %u", dap->pending_fifo_get_idx);
515
516 return err;
517 }
518
519 if (tr->status == CMSIS_DAP_TRANSFER_COMPLETED) {
520 transferred = tr->transferred;
521 LOG_DEBUG_IO("completed read @ %u, transferred %i",
522 dap->pending_fifo_get_idx, transferred);
523 memcpy(dap->packet_buffer, tr->buffer, transferred);
524 memset(&dap->packet_buffer[transferred], 0, dap->packet_buffer_size - transferred);
525 tr->status = CMSIS_DAP_TRANSFER_IDLE;
526 }
527
528 return transferred;
529 }
530
531 static int cmsis_dap_usb_write(struct cmsis_dap *dap, int txlen, int timeout_ms)
532 {
533 int err;
534 struct cmsis_dap_bulk_transfer *tr;
535 tr = &dap->bdata->command_transfers[dap->pending_fifo_put_idx];
536
537 if (tr->status == CMSIS_DAP_TRANSFER_PENDING) {
538 LOG_ERROR("busy command USB transfer at %u", dap->pending_fifo_put_idx);
539 struct timeval tv = {
540 .tv_sec = timeout_ms / 1000,
541 .tv_usec = timeout_ms % 1000 * 1000
542 };
543 libusb_handle_events_timeout_completed(dap->bdata->usb_ctx, &tv, &tr->status);
544 }
545 if (tr->status < 0) {
546 if (tr->status != ERROR_TIMEOUT_REACHED)
547 LOG_ERROR("error writing USB data, late detect");
548 else
549 LOG_DEBUG("USB write timeout @ %u, late detect", dap->pending_fifo_get_idx);
550 tr->status = CMSIS_DAP_TRANSFER_IDLE;
551 }
552 if (tr->status == CMSIS_DAP_TRANSFER_COMPLETED) {
553 LOG_ERROR("USB write: late transfer competed");
554 tr->status = CMSIS_DAP_TRANSFER_IDLE;
555 }
556 if (tr->status != CMSIS_DAP_TRANSFER_IDLE) {
557 libusb_cancel_transfer(tr->transfer);
558 /* TODO: switch to less verbose errors and wait for USB working again */
559 return ERROR_JTAG_DEVICE_ERROR;
560 }
561
562 memcpy(tr->buffer, dap->packet_buffer, txlen);
563
564 libusb_fill_bulk_transfer(tr->transfer,
565 dap->bdata->dev_handle, dap->bdata->ep_out,
566 tr->buffer, txlen,
567 &cmsis_dap_usb_callback, tr,
568 timeout_ms);
569
570 LOG_DEBUG_IO("submit write @ %u", dap->pending_fifo_put_idx);
571 tr->status = CMSIS_DAP_TRANSFER_PENDING;
572 err = libusb_submit_transfer(tr->transfer);
573 if (err) {
574 if (err == LIBUSB_ERROR_BUSY)
575 libusb_cancel_transfer(tr->transfer);
576 else
577 tr->status = CMSIS_DAP_TRANSFER_IDLE;
578
579 LOG_ERROR("error submitting USB write: %s", libusb_strerror(err));
580 return ERROR_FAIL;
581 }
582
583 return ERROR_OK;
584 }
585
586 static int cmsis_dap_usb_alloc(struct cmsis_dap *dap, unsigned int pkt_sz)
587 {
588 dap->packet_buffer = malloc(pkt_sz);
589 if (!dap->packet_buffer) {
590 LOG_ERROR("unable to allocate CMSIS-DAP packet buffer");
591 return ERROR_FAIL;
592 }
593
594 dap->packet_size = pkt_sz;
595 dap->packet_buffer_size = pkt_sz;
596 /* Prevent sending zero size USB packets */
597 dap->packet_usable_size = pkt_sz - 1;
598
599 dap->command = dap->packet_buffer;
600 dap->response = dap->packet_buffer;
601
602 for (unsigned int i = 0; i < MAX_PENDING_REQUESTS; i++) {
603 dap->bdata->command_transfers[i].buffer =
604 libusb_dev_mem_alloc(dap->bdata->dev_handle, pkt_sz);
605 if (!dap->bdata->command_transfers[i].buffer) {
606 LOG_ERROR("unable to allocate CMSIS-DAP packet buffer");
607 return ERROR_FAIL;
608 }
609 dap->bdata->response_transfers[i].buffer =
610 libusb_dev_mem_alloc(dap->bdata->dev_handle, pkt_sz);
611 if (!dap->bdata->response_transfers[i].buffer) {
612 LOG_ERROR("unable to allocate CMSIS-DAP packet buffer");
613 return ERROR_FAIL;
614 }
615 }
616
617 return ERROR_OK;
618 }
619
620 static void cmsis_dap_usb_free(struct cmsis_dap *dap)
621 {
622 for (unsigned int i = 0; i < MAX_PENDING_REQUESTS; i++) {
623 libusb_dev_mem_free(dap->bdata->dev_handle,
624 dap->bdata->command_transfers[i].buffer, dap->packet_size);
625 dap->bdata->command_transfers[i].buffer = NULL;
626 libusb_dev_mem_free(dap->bdata->dev_handle,
627 dap->bdata->response_transfers[i].buffer, dap->packet_size);
628 dap->bdata->response_transfers[i].buffer = NULL;
629 }
630
631 free(dap->packet_buffer);
632 dap->packet_buffer = NULL;
633 dap->command = NULL;
634 dap->response = NULL;
635 }
636
637 static void cmsis_dap_usb_cancel_all(struct cmsis_dap *dap)
638 {
639 for (unsigned int i = 0; i < MAX_PENDING_REQUESTS; i++) {
640 if (dap->bdata->command_transfers[i].status == CMSIS_DAP_TRANSFER_PENDING)
641 libusb_cancel_transfer(dap->bdata->command_transfers[i].transfer);
642 if (dap->bdata->response_transfers[i].status == CMSIS_DAP_TRANSFER_PENDING)
643 libusb_cancel_transfer(dap->bdata->response_transfers[i].transfer);
644
645 dap->bdata->command_transfers[i].status = CMSIS_DAP_TRANSFER_IDLE;
646 dap->bdata->response_transfers[i].status = CMSIS_DAP_TRANSFER_IDLE;
647 }
648 }
649
650 COMMAND_HANDLER(cmsis_dap_handle_usb_interface_command)
651 {
652 if (CMD_ARGC == 1)
653 COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], cmsis_dap_usb_interface);
654 else
655 LOG_ERROR("expected exactly one argument to cmsis_dap_usb_interface <interface_number>");
656
657 return ERROR_OK;
658 }
659
660 const struct command_registration cmsis_dap_usb_subcommand_handlers[] = {
661 {
662 .name = "interface",
663 .handler = &cmsis_dap_handle_usb_interface_command,
664 .mode = COMMAND_CONFIG,
665 .help = "set the USB interface number to use (for USB bulk backend only)",
666 .usage = "<interface_number>",
667 },
668 COMMAND_REGISTRATION_DONE
669 };
670
671 const struct cmsis_dap_backend cmsis_dap_usb_backend = {
672 .name = "usb_bulk",
673 .open = cmsis_dap_usb_open,
674 .close = cmsis_dap_usb_close,
675 .read = cmsis_dap_usb_read,
676 .write = cmsis_dap_usb_write,
677 .packet_buffer_alloc = cmsis_dap_usb_alloc,
678 .packet_buffer_free = cmsis_dap_usb_free,
679 .cancel_all = cmsis_dap_usb_cancel_all,
680 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)