1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2018 by Mickaƫl Thomas *
7 * Copyright (C) 2016 by Maksym Hilliaka *
8 * oter@frozen-team.com *
10 * Copyright (C) 2016 by Phillip Pearson *
13 * Copyright (C) 2014 by Paul Fertser *
14 * fercerpav@gmail.com *
16 * Copyright (C) 2013 by mike brown *
17 * mike@theshedworks.org.uk *
19 * Copyright (C) 2013 by Spencer Oliver *
20 * spen@spen-soft.co.uk *
21 ***************************************************************************/
27 #include <helper/system.h>
29 #include <helper/log.h>
30 #include <helper/replacements.h>
31 #include <jtag/jtag.h> /* ERROR_JTAG_DEVICE_ERROR only */
33 #include "cmsis_dap.h"
34 #include "libusb_helper.h"
37 CMSIS_DAP_TRANSFER_PENDING
= 0, /* must be 0, used in libusb_handle_events_completed */
38 CMSIS_DAP_TRANSFER_IDLE
,
39 CMSIS_DAP_TRANSFER_COMPLETED
42 struct cmsis_dap_bulk_transfer
{
43 struct libusb_transfer
*transfer
;
45 int status
; /* either CMSIS_DAP_TRANSFER_ enum or error code */
49 struct cmsis_dap_backend_data
{
50 struct libusb_context
*usb_ctx
;
51 struct libusb_device_handle
*dev_handle
;
56 struct cmsis_dap_bulk_transfer command_transfers
[MAX_PENDING_REQUESTS
];
57 struct cmsis_dap_bulk_transfer response_transfers
[MAX_PENDING_REQUESTS
];
60 static int cmsis_dap_usb_interface
= -1;
62 static void cmsis_dap_usb_close(struct cmsis_dap
*dap
);
63 static int cmsis_dap_usb_alloc(struct cmsis_dap
*dap
, unsigned int pkt_sz
);
64 static void cmsis_dap_usb_free(struct cmsis_dap
*dap
);
66 static int cmsis_dap_usb_open(struct cmsis_dap
*dap
, uint16_t vids
[], uint16_t pids
[], const char *serial
)
69 struct libusb_context
*ctx
;
70 struct libusb_device
**device_list
;
72 err
= libusb_init(&ctx
);
74 LOG_ERROR("libusb initialization failed: %s", libusb_strerror(err
));
78 int num_devices
= libusb_get_device_list(ctx
, &device_list
);
79 if (num_devices
< 0) {
80 LOG_ERROR("could not enumerate USB devices: %s", libusb_strerror(num_devices
));
85 for (int i
= 0; i
< num_devices
; i
++) {
86 struct libusb_device
*dev
= device_list
[i
];
87 struct libusb_device_descriptor dev_desc
;
89 err
= libusb_get_device_descriptor(dev
, &dev_desc
);
91 LOG_ERROR("could not get device descriptor for device %d: %s", i
, libusb_strerror(err
));
97 bool id_match
= false;
98 bool id_filter
= vids
[0] || pids
[0];
99 for (int id
= 0; vids
[id
] || pids
[id
]; id
++) {
100 id_match
= !vids
[id
] || dev_desc
.idVendor
== vids
[id
];
101 id_match
&= !pids
[id
] || dev_desc
.idProduct
== pids
[id
];
107 if (id_filter
&& !id_match
)
110 /* Don't continue if we asked for a serial number and the device doesn't have one */
111 if (dev_desc
.iSerialNumber
== 0 && serial
&& serial
[0])
114 struct libusb_device_handle
*dev_handle
= NULL
;
115 err
= libusb_open(dev
, &dev_handle
);
117 /* It's to be expected that most USB devices can't be opened
118 * so only report an error if it was explicitly selected
121 LOG_ERROR("could not open device 0x%04x:0x%04x: %s",
122 dev_desc
.idVendor
, dev_desc
.idProduct
, libusb_strerror(err
));
124 LOG_DEBUG("could not open device 0x%04x:0x%04x: %s",
125 dev_desc
.idVendor
, dev_desc
.idProduct
, libusb_strerror(err
));
130 /* Match serial number */
132 bool serial_match
= false;
133 char dev_serial
[256] = {0};
134 if (dev_desc
.iSerialNumber
> 0) {
135 err
= libusb_get_string_descriptor_ascii(
136 dev_handle
, dev_desc
.iSerialNumber
,
137 (uint8_t *)dev_serial
, sizeof(dev_serial
));
140 const char *msg
= "could not read serial number for device 0x%04x:0x%04x: %s";
142 LOG_WARNING(msg
, dev_desc
.idVendor
, dev_desc
.idProduct
,
143 libusb_strerror(err
));
145 LOG_DEBUG(msg
, dev_desc
.idVendor
, dev_desc
.idProduct
,
146 libusb_strerror(err
));
147 } else if (serial
&& strncmp(dev_serial
, serial
, sizeof(dev_serial
)) == 0) {
152 if (serial
&& !serial_match
) {
153 libusb_close(dev_handle
);
157 /* Find the CMSIS-DAP string in product string */
159 bool cmsis_dap_in_product_str
= false;
160 char product_string
[256] = {0};
161 if (dev_desc
.iProduct
> 0) {
162 err
= libusb_get_string_descriptor_ascii(
163 dev_handle
, dev_desc
.iProduct
,
164 (uint8_t *)product_string
, sizeof(product_string
));
166 LOG_WARNING("could not read product string for device 0x%04x:0x%04x: %s",
167 dev_desc
.idVendor
, dev_desc
.idProduct
, libusb_strerror(err
));
168 } else if (strstr(product_string
, "CMSIS-DAP")) {
169 LOG_DEBUG("found product string of 0x%04x:0x%04x '%s'",
170 dev_desc
.idVendor
, dev_desc
.idProduct
, product_string
);
171 cmsis_dap_in_product_str
= true;
175 bool device_identified_reliably
= cmsis_dap_in_product_str
176 || serial_match
|| id_match
;
178 /* Find the CMSIS-DAP interface */
180 for (int config
= 0; config
< dev_desc
.bNumConfigurations
; config
++) {
181 struct libusb_config_descriptor
*config_desc
;
182 err
= libusb_get_config_descriptor(dev
, config
, &config_desc
);
184 LOG_ERROR("could not get configuration descriptor %d for device 0x%04x:0x%04x: %s",
185 config
, dev_desc
.idVendor
, dev_desc
.idProduct
, libusb_strerror(err
));
189 LOG_DEBUG("enumerating interfaces of 0x%04x:0x%04x",
190 dev_desc
.idVendor
, dev_desc
.idProduct
);
191 int config_num
= config_desc
->bConfigurationValue
;
192 const struct libusb_interface_descriptor
*intf_desc_candidate
= NULL
;
193 const struct libusb_interface_descriptor
*intf_desc_found
= NULL
;
195 for (int interface
= 0; interface
< config_desc
->bNumInterfaces
; interface
++) {
196 const struct libusb_interface_descriptor
*intf_desc
= &config_desc
->interface
[interface
].altsetting
[0];
197 int interface_num
= intf_desc
->bInterfaceNumber
;
199 /* Skip this interface if another one was requested explicitly */
200 if (cmsis_dap_usb_interface
!= -1 && cmsis_dap_usb_interface
!= interface_num
)
203 /* CMSIS-DAP v2 spec says:
205 * CMSIS-DAP with default V2 configuration uses WinUSB and is therefore faster.
206 * Optionally support for streaming SWO trace is provided via an additional USB endpoint.
208 * The WinUSB configuration requires custom class support with the interface setting
209 * Class Code: 0xFF (Vendor specific)
211 * Protocol code: 0x00
213 * Depending on the configuration it uses the following USB endpoints which should be configured
214 * in the interface descriptor in this order:
215 * - Endpoint 1: Bulk Out ā used for commands received from host PC.
216 * - Endpoint 2: Bulk In ā used for responses send to host PC.
217 * - Endpoint 3: Bulk In (optional) ā used for streaming SWO trace (if enabled with SWO_STREAM).
220 /* Search for "CMSIS-DAP" in the interface string */
221 bool cmsis_dap_in_interface_str
= false;
222 if (intf_desc
->iInterface
!= 0) {
224 char interface_str
[256] = {0};
226 err
= libusb_get_string_descriptor_ascii(
227 dev_handle
, intf_desc
->iInterface
,
228 (uint8_t *)interface_str
, sizeof(interface_str
));
230 LOG_DEBUG("could not read interface string %d for device 0x%04x:0x%04x: %s",
231 intf_desc
->iInterface
,
232 dev_desc
.idVendor
, dev_desc
.idProduct
,
233 libusb_strerror(err
));
234 } else if (strstr(interface_str
, "CMSIS-DAP")) {
235 cmsis_dap_in_interface_str
= true;
236 LOG_DEBUG("found interface %d string '%s'",
237 interface_num
, interface_str
);
241 /* Bypass the following check if this interface was explicitly requested. */
242 if (cmsis_dap_usb_interface
== -1) {
243 if (!cmsis_dap_in_product_str
&& !cmsis_dap_in_interface_str
)
247 /* check endpoints */
248 if (intf_desc
->bNumEndpoints
< 2) {
249 LOG_DEBUG("skipping interface %d, has only %d endpoints",
250 interface_num
, intf_desc
->bNumEndpoints
);
254 if ((intf_desc
->endpoint
[0].bmAttributes
& 3) != LIBUSB_TRANSFER_TYPE_BULK
||
255 (intf_desc
->endpoint
[0].bEndpointAddress
& 0x80) != LIBUSB_ENDPOINT_OUT
) {
256 LOG_DEBUG("skipping interface %d, endpoint[0] is not bulk out",
261 if ((intf_desc
->endpoint
[1].bmAttributes
& 3) != LIBUSB_TRANSFER_TYPE_BULK
||
262 (intf_desc
->endpoint
[1].bEndpointAddress
& 0x80) != LIBUSB_ENDPOINT_IN
) {
263 LOG_DEBUG("skipping interface %d, endpoint[1] is not bulk in",
268 /* We can rely on the interface is really CMSIS-DAP if
269 * - we've seen CMSIS-DAP in the interface string
270 * - config asked explicitly for an interface number
271 * - the device has only one interface
272 * The later two cases should be honored only if we know
273 * we are on the right device */
274 bool intf_identified_reliably
= cmsis_dap_in_interface_str
275 || (device_identified_reliably
&&
276 (cmsis_dap_usb_interface
!= -1
277 || config_desc
->bNumInterfaces
== 1));
279 if (intf_desc
->bInterfaceClass
!= LIBUSB_CLASS_VENDOR_SPEC
||
280 intf_desc
->bInterfaceSubClass
!= 0 || intf_desc
->bInterfaceProtocol
!= 0) {
281 /* If the interface is reliably identified
282 * then we need not insist on setting USB class, subclass and protocol
283 * exactly as the specification requires.
284 * Just filter out the well known classes, mainly CDC and MSC.
285 * At least KitProg3 uses class 0 contrary to the specification */
286 if (intf_identified_reliably
&&
287 (intf_desc
->bInterfaceClass
== 0 || intf_desc
->bInterfaceClass
> 0x12)) {
288 LOG_WARNING("Using CMSIS-DAPv2 interface %d with wrong class %" PRId8
289 " subclass %" PRId8
" or protocol %" PRId8
,
291 intf_desc
->bInterfaceClass
,
292 intf_desc
->bInterfaceSubClass
,
293 intf_desc
->bInterfaceProtocol
);
295 LOG_DEBUG("skipping interface %d, class %" PRId8
296 " subclass %" PRId8
" protocol %" PRId8
,
298 intf_desc
->bInterfaceClass
,
299 intf_desc
->bInterfaceSubClass
,
300 intf_desc
->bInterfaceProtocol
);
306 if (intf_identified_reliably
) {
307 /* That's the one! */
308 intf_desc_found
= intf_desc
;
312 if (!intf_desc_candidate
&& device_identified_reliably
) {
313 /* This interface looks suitable for CMSIS-DAP. Store the pointer to it
314 * and keep searching for another one with CMSIS-DAP in interface string */
315 intf_desc_candidate
= intf_desc
;
319 if (!intf_desc_found
) {
320 /* We were not able to identify reliably which interface is CMSIS-DAP.
321 * Let's use the first suitable if we found one */
322 intf_desc_found
= intf_desc_candidate
;
325 if (!intf_desc_found
) {
326 libusb_free_config_descriptor(config_desc
);
330 /* We've chosen an interface, connect to it */
331 int interface_num
= intf_desc_found
->bInterfaceNumber
;
332 int packet_size
= intf_desc_found
->endpoint
[0].wMaxPacketSize
;
333 int ep_out
= intf_desc_found
->endpoint
[0].bEndpointAddress
;
334 int ep_in
= intf_desc_found
->endpoint
[1].bEndpointAddress
;
336 libusb_free_config_descriptor(config_desc
);
337 libusb_free_device_list(device_list
, true);
339 LOG_INFO("Using CMSIS-DAPv2 interface with VID:PID=0x%04x:0x%04x, serial=%s",
340 dev_desc
.idVendor
, dev_desc
.idProduct
, dev_serial
);
343 err
= libusb_get_configuration(dev_handle
, ¤t_config
);
345 LOG_ERROR("could not find current configuration: %s", libusb_strerror(err
));
346 libusb_close(dev_handle
);
351 if (config_num
!= current_config
) {
352 err
= libusb_set_configuration(dev_handle
, config_num
);
354 LOG_ERROR("could not set configuration: %s", libusb_strerror(err
));
355 libusb_close(dev_handle
);
361 err
= libusb_claim_interface(dev_handle
, interface_num
);
363 LOG_WARNING("could not claim interface: %s", libusb_strerror(err
));
365 dap
->bdata
= calloc(1, sizeof(struct cmsis_dap_backend_data
));
367 LOG_ERROR("unable to allocate memory");
368 libusb_release_interface(dev_handle
, interface_num
);
369 libusb_close(dev_handle
);
374 dap
->bdata
->usb_ctx
= ctx
;
375 dap
->bdata
->dev_handle
= dev_handle
;
376 dap
->bdata
->ep_out
= ep_out
;
377 dap
->bdata
->ep_in
= ep_in
;
378 dap
->bdata
->interface
= interface_num
;
380 for (unsigned int idx
= 0; idx
< MAX_PENDING_REQUESTS
; idx
++) {
381 dap
->bdata
->command_transfers
[idx
].status
= CMSIS_DAP_TRANSFER_IDLE
;
382 dap
->bdata
->command_transfers
[idx
].transfer
= libusb_alloc_transfer(0);
383 if (!dap
->bdata
->command_transfers
[idx
].transfer
) {
384 LOG_ERROR("unable to allocate USB transfer");
385 cmsis_dap_usb_close(dap
);
389 dap
->bdata
->response_transfers
[idx
].status
= CMSIS_DAP_TRANSFER_IDLE
;
390 dap
->bdata
->response_transfers
[idx
].transfer
= libusb_alloc_transfer(0);
391 if (!dap
->bdata
->response_transfers
[idx
].transfer
) {
392 LOG_ERROR("unable to allocate USB transfer");
393 cmsis_dap_usb_close(dap
);
398 err
= cmsis_dap_usb_alloc(dap
, packet_size
);
400 cmsis_dap_usb_close(dap
);
405 libusb_close(dev_handle
);
408 libusb_free_device_list(device_list
, true);
414 static void cmsis_dap_usb_close(struct cmsis_dap
*dap
)
416 for (unsigned int i
= 0; i
< MAX_PENDING_REQUESTS
; i
++) {
417 libusb_free_transfer(dap
->bdata
->command_transfers
[i
].transfer
);
418 libusb_free_transfer(dap
->bdata
->response_transfers
[i
].transfer
);
420 cmsis_dap_usb_free(dap
);
421 libusb_release_interface(dap
->bdata
->dev_handle
, dap
->bdata
->interface
);
422 libusb_close(dap
->bdata
->dev_handle
);
423 libusb_exit(dap
->bdata
->usb_ctx
);
428 static void LIBUSB_CALL
cmsis_dap_usb_callback(struct libusb_transfer
*transfer
)
430 struct cmsis_dap_bulk_transfer
*tr
;
432 tr
= (struct cmsis_dap_bulk_transfer
*)transfer
->user_data
;
433 if (transfer
->status
== LIBUSB_TRANSFER_COMPLETED
) {
434 tr
->status
= CMSIS_DAP_TRANSFER_COMPLETED
;
435 tr
->transferred
= transfer
->actual_length
;
436 } else if (transfer
->status
== LIBUSB_TRANSFER_TIMED_OUT
) {
437 tr
->status
= ERROR_TIMEOUT_REACHED
;
439 tr
->status
= ERROR_JTAG_DEVICE_ERROR
;
443 static int cmsis_dap_usb_read(struct cmsis_dap
*dap
, int transfer_timeout_ms
,
444 struct timeval
*wait_timeout
)
448 struct cmsis_dap_bulk_transfer
*tr
;
449 tr
= &dap
->bdata
->response_transfers
[dap
->pending_fifo_get_idx
];
451 if (tr
->status
== CMSIS_DAP_TRANSFER_IDLE
) {
452 libusb_fill_bulk_transfer(tr
->transfer
,
453 dap
->bdata
->dev_handle
, dap
->bdata
->ep_in
,
454 tr
->buffer
, dap
->packet_size
,
455 &cmsis_dap_usb_callback
, tr
,
456 transfer_timeout_ms
);
457 LOG_DEBUG_IO("submit read @ %u", dap
->pending_fifo_get_idx
);
458 tr
->status
= CMSIS_DAP_TRANSFER_PENDING
;
459 err
= libusb_submit_transfer(tr
->transfer
);
461 tr
->status
= CMSIS_DAP_TRANSFER_IDLE
;
462 LOG_ERROR("error submitting USB read: %s", libusb_strerror(err
));
467 struct timeval tv
= {
468 .tv_sec
= transfer_timeout_ms
/ 1000,
469 .tv_usec
= transfer_timeout_ms
% 1000 * 1000
472 while (tr
->status
== CMSIS_DAP_TRANSFER_PENDING
) {
473 err
= libusb_handle_events_timeout_completed(dap
->bdata
->usb_ctx
,
474 wait_timeout
? wait_timeout
: &tv
,
477 LOG_ERROR("error handling USB events: %s", libusb_strerror(err
));
484 if (tr
->status
< 0 || tr
->status
== CMSIS_DAP_TRANSFER_COMPLETED
) {
485 /* Check related command request for an error */
486 struct cmsis_dap_bulk_transfer
*tr_cmd
;
487 tr_cmd
= &dap
->bdata
->command_transfers
[dap
->pending_fifo_get_idx
];
488 if (tr_cmd
->status
< 0) {
489 err
= tr_cmd
->status
;
490 tr_cmd
->status
= CMSIS_DAP_TRANSFER_IDLE
;
491 if (err
!= ERROR_TIMEOUT_REACHED
)
492 LOG_ERROR("error writing USB data");
494 LOG_DEBUG("command write USB timeout @ %u", dap
->pending_fifo_get_idx
);
498 if (tr_cmd
->status
== CMSIS_DAP_TRANSFER_COMPLETED
)
499 tr_cmd
->status
= CMSIS_DAP_TRANSFER_IDLE
;
502 if (tr
->status
< 0) {
504 tr
->status
= CMSIS_DAP_TRANSFER_IDLE
;
505 if (err
!= ERROR_TIMEOUT_REACHED
)
506 LOG_ERROR("error reading USB data");
508 LOG_DEBUG("USB timeout @ %u", dap
->pending_fifo_get_idx
);
513 if (tr
->status
== CMSIS_DAP_TRANSFER_COMPLETED
) {
514 transferred
= tr
->transferred
;
515 LOG_DEBUG_IO("completed read @ %u, transferred %i",
516 dap
->pending_fifo_get_idx
, transferred
);
517 memcpy(dap
->packet_buffer
, tr
->buffer
, transferred
);
518 memset(&dap
->packet_buffer
[transferred
], 0, dap
->packet_buffer_size
- transferred
);
519 tr
->status
= CMSIS_DAP_TRANSFER_IDLE
;
525 static int cmsis_dap_usb_write(struct cmsis_dap
*dap
, int txlen
, int timeout_ms
)
528 struct cmsis_dap_bulk_transfer
*tr
;
529 tr
= &dap
->bdata
->command_transfers
[dap
->pending_fifo_put_idx
];
531 if (tr
->status
== CMSIS_DAP_TRANSFER_PENDING
) {
532 LOG_ERROR("busy command USB transfer at %u", dap
->pending_fifo_put_idx
);
533 struct timeval tv
= {
534 .tv_sec
= timeout_ms
/ 1000,
535 .tv_usec
= timeout_ms
% 1000 * 1000
537 libusb_handle_events_timeout_completed(dap
->bdata
->usb_ctx
, &tv
, &tr
->status
);
539 if (tr
->status
< 0) {
540 if (tr
->status
!= ERROR_TIMEOUT_REACHED
)
541 LOG_ERROR("error writing USB data, late detect");
543 LOG_DEBUG("USB write timeout @ %u, late detect", dap
->pending_fifo_get_idx
);
544 tr
->status
= CMSIS_DAP_TRANSFER_IDLE
;
546 if (tr
->status
== CMSIS_DAP_TRANSFER_COMPLETED
) {
547 LOG_ERROR("USB write: late transfer competed");
548 tr
->status
= CMSIS_DAP_TRANSFER_IDLE
;
550 if (tr
->status
!= CMSIS_DAP_TRANSFER_IDLE
) {
551 libusb_cancel_transfer(tr
->transfer
);
552 /* TODO: switch to less verbose errors and wait for USB working again */
553 return ERROR_JTAG_DEVICE_ERROR
;
556 memcpy(tr
->buffer
, dap
->packet_buffer
, txlen
);
558 libusb_fill_bulk_transfer(tr
->transfer
,
559 dap
->bdata
->dev_handle
, dap
->bdata
->ep_out
,
561 &cmsis_dap_usb_callback
, tr
,
564 LOG_DEBUG_IO("submit write @ %u", dap
->pending_fifo_put_idx
);
565 tr
->status
= CMSIS_DAP_TRANSFER_PENDING
;
566 err
= libusb_submit_transfer(tr
->transfer
);
568 if (err
== LIBUSB_ERROR_BUSY
)
569 libusb_cancel_transfer(tr
->transfer
);
571 tr
->status
= CMSIS_DAP_TRANSFER_IDLE
;
573 LOG_ERROR("error submitting USB write: %s", libusb_strerror(err
));
580 static int cmsis_dap_usb_alloc(struct cmsis_dap
*dap
, unsigned int pkt_sz
)
582 dap
->packet_buffer
= malloc(pkt_sz
);
583 if (!dap
->packet_buffer
) {
584 LOG_ERROR("unable to allocate CMSIS-DAP packet buffer");
588 dap
->packet_size
= pkt_sz
;
589 dap
->packet_buffer_size
= pkt_sz
;
590 /* Prevent sending zero size USB packets */
591 dap
->packet_usable_size
= pkt_sz
- 1;
593 dap
->command
= dap
->packet_buffer
;
594 dap
->response
= dap
->packet_buffer
;
596 struct cmsis_dap_backend_data
*bdata
= dap
->bdata
;
597 for (unsigned int i
= 0; i
< MAX_PENDING_REQUESTS
; i
++) {
598 bdata
->command_transfers
[i
].buffer
=
599 oocd_libusb_dev_mem_alloc(bdata
->dev_handle
, pkt_sz
);
601 bdata
->response_transfers
[i
].buffer
=
602 oocd_libusb_dev_mem_alloc(bdata
->dev_handle
, pkt_sz
);
604 if (!bdata
->command_transfers
[i
].buffer
605 || !bdata
->response_transfers
[i
].buffer
) {
606 LOG_ERROR("unable to allocate CMSIS-DAP pending packet buffer");
613 static void cmsis_dap_usb_free(struct cmsis_dap
*dap
)
615 struct cmsis_dap_backend_data
*bdata
= dap
->bdata
;
617 for (unsigned int i
= 0; i
< MAX_PENDING_REQUESTS
; i
++) {
618 oocd_libusb_dev_mem_free(bdata
->dev_handle
,
619 bdata
->command_transfers
[i
].buffer
, dap
->packet_size
);
620 oocd_libusb_dev_mem_free(bdata
->dev_handle
,
621 bdata
->response_transfers
[i
].buffer
, dap
->packet_size
);
622 bdata
->command_transfers
[i
].buffer
= NULL
;
623 bdata
->response_transfers
[i
].buffer
= NULL
;
626 free(dap
->packet_buffer
);
627 dap
->packet_buffer
= NULL
;
629 dap
->response
= NULL
;
632 static void cmsis_dap_usb_cancel_all(struct cmsis_dap
*dap
)
634 for (unsigned int i
= 0; i
< MAX_PENDING_REQUESTS
; i
++) {
635 if (dap
->bdata
->command_transfers
[i
].status
== CMSIS_DAP_TRANSFER_PENDING
)
636 libusb_cancel_transfer(dap
->bdata
->command_transfers
[i
].transfer
);
637 if (dap
->bdata
->response_transfers
[i
].status
== CMSIS_DAP_TRANSFER_PENDING
)
638 libusb_cancel_transfer(dap
->bdata
->response_transfers
[i
].transfer
);
640 dap
->bdata
->command_transfers
[i
].status
= CMSIS_DAP_TRANSFER_IDLE
;
641 dap
->bdata
->response_transfers
[i
].status
= CMSIS_DAP_TRANSFER_IDLE
;
645 COMMAND_HANDLER(cmsis_dap_handle_usb_interface_command
)
648 COMMAND_PARSE_NUMBER(int, CMD_ARGV
[0], cmsis_dap_usb_interface
);
650 LOG_ERROR("expected exactly one argument to cmsis_dap_usb_interface <interface_number>");
655 const struct command_registration cmsis_dap_usb_subcommand_handlers
[] = {
658 .handler
= &cmsis_dap_handle_usb_interface_command
,
659 .mode
= COMMAND_CONFIG
,
660 .help
= "set the USB interface number to use (for USB bulk backend only)",
661 .usage
= "<interface_number>",
663 COMMAND_REGISTRATION_DONE
666 const struct cmsis_dap_backend cmsis_dap_usb_backend
= {
668 .open
= cmsis_dap_usb_open
,
669 .close
= cmsis_dap_usb_close
,
670 .read
= cmsis_dap_usb_read
,
671 .write
= cmsis_dap_usb_write
,
672 .packet_buffer_alloc
= cmsis_dap_usb_alloc
,
673 .packet_buffer_free
= cmsis_dap_usb_free
,
674 .cancel_all
= cmsis_dap_usb_cancel_all
,
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)