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)
 
  114         struct libusb_device_handle *dev_handle = 
NULL;
 
  115         err = libusb_open(dev, &dev_handle);
 
  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));
 
  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);
 
  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;
 
  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;
 
  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);
 
  243                     if (!cmsis_dap_in_product_str && !cmsis_dap_in_interface_str)
 
  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",
 
  274                 bool intf_identified_reliably = cmsis_dap_in_interface_str
 
  275                             || (device_identified_reliably &&
 
  277                                      || config_desc->bNumInterfaces == 1));
 
  279                 if (intf_desc->bInterfaceClass != LIBUSB_CLASS_VENDOR_SPEC ||
 
  280                         intf_desc->bInterfaceSubClass != 0 || intf_desc->bInterfaceProtocol != 0) {
 
  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) {
 
  308                     intf_desc_found = intf_desc;
 
  312                 if (!intf_desc_candidate && device_identified_reliably) {
 
  315                     intf_desc_candidate = intf_desc;
 
  319             if (!intf_desc_found) {
 
  322                 intf_desc_found = intf_desc_candidate;
 
  325             if (!intf_desc_found) {
 
  326                 libusb_free_config_descriptor(config_desc);
 
  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));
 
  368                 libusb_release_interface(dev_handle, interface_num);
 
  369                 libusb_close(dev_handle);
 
  384                     LOG_ERROR(
"unable to allocate USB transfer");
 
  392                     LOG_ERROR(
"unable to allocate USB transfer");
 
  405         libusb_close(dev_handle);
 
  408     libusb_free_device_list(device_list, 
true);
 
  424             int res = libusb_handle_events_timeout_completed(dap->
bdata->
usb_ctx, &tv, 
NULL);
 
  445     if (
transfer->status == LIBUSB_TRANSFER_COMPLETED) {
 
  448     } 
else if (
transfer->status == LIBUSB_TRANSFER_TIMED_OUT) {
 
  464         libusb_fill_bulk_transfer(tr->
transfer,
 
  468                                   transfer_timeout_ms);
 
  471         err = libusb_submit_transfer(tr->
transfer);
 
  474             LOG_ERROR(
"error submitting USB read: %s", libusb_strerror(err));
 
  484         tv.
tv_sec = transfer_timeout_ms / 1000;
 
  485         tv.
tv_usec = transfer_timeout_ms % 1000 * 1000;
 
  489         err = libusb_handle_events_timeout_completed(dap->
bdata->
usb_ctx, &tv,
 
  492             LOG_ERROR(
"error handling USB events: %s", libusb_strerror(err));
 
  549             .
tv_sec = timeout_ms / 1000,
 
  550             .tv_usec = timeout_ms % 1000 * 1000
 
  556             LOG_ERROR(
"error writing USB data, late detect");
 
  566         libusb_cancel_transfer(tr->
transfer);
 
  573     libusb_fill_bulk_transfer(tr->
transfer,
 
  581     err = libusb_submit_transfer(tr->
transfer);
 
  583         if (err == LIBUSB_ERROR_BUSY)
 
  584             libusb_cancel_transfer(tr->
transfer);
 
  588         LOG_ERROR(
"error submitting USB write: %s", libusb_strerror(err));
 
  599         LOG_ERROR(
"unable to allocate CMSIS-DAP packet buffer");
 
  621             LOG_ERROR(
"unable to allocate CMSIS-DAP pending packet buffer");
 
  673         .handler = &cmsis_dap_handle_usb_interface_command,
 
  675         .help = 
"set the USB interface number to use (for USB bulk backend only)",
 
#define MAX_PENDING_REQUESTS
COMMAND_HANDLER(cmsis_dap_handle_usb_interface_command)
static int cmsis_dap_usb_write(struct cmsis_dap *dap, int txlen, int timeout_ms)
const struct cmsis_dap_backend cmsis_dap_usb_backend
static void LIBUSB_CALL cmsis_dap_usb_callback(struct libusb_transfer *transfer)
@ CMSIS_DAP_TRANSFER_COMPLETED
@ CMSIS_DAP_TRANSFER_PENDING
@ CMSIS_DAP_TRANSFER_IDLE
static int cmsis_dap_usb_alloc(struct cmsis_dap *dap, unsigned int pkt_sz)
static int cmsis_dap_usb_read(struct cmsis_dap *dap, int transfer_timeout_ms, enum cmsis_dap_blocking blocking)
static void cmsis_dap_usb_cancel_all(struct cmsis_dap *dap)
static void cmsis_dap_usb_free(struct cmsis_dap *dap)
const struct command_registration cmsis_dap_usb_subcommand_handlers[]
static int cmsis_dap_usb_interface
static int cmsis_dap_usb_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t pids[], const char *serial)
static void cmsis_dap_usb_close(struct cmsis_dap *dap)
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
#define ERROR_COMMAND_SYNTAX_ERROR
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
#define COMMAND_PARSE_NUMBER(type, in, out)
parses the string in into out as a type, or prints a command error and passes the error code to the c...
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
static struct device_config config
The JTAG interface can be implemented with a software or hardware fifo.
#define ERROR_JTAG_DEVICE_ERROR
uint8_t * oocd_libusb_dev_mem_alloc(libusb_device_handle *devh, size_t length)
Attempts to allocate a block of persistent DMA memory suitable for transfers against the USB device.
int oocd_libusb_dev_mem_free(libusb_device_handle *devh, uint8_t *buffer, size_t length)
Free device memory allocated with oocd_libusb_dev_mem_alloc().
#define LOG_DEBUG_IO(expr ...)
#define LOG_WARNING(expr ...)
#define LOG_ERROR(expr ...)
#define ERROR_TIMEOUT_REACHED
#define LOG_INFO(expr ...)
#define LOG_DEBUG(expr ...)
static unsigned int ep_out
static unsigned int ep_in
char id[RTT_CB_MAX_ID_LENGTH]
Control block identifier.
struct libusb_context * usb_ctx
struct libusb_device_handle * dev_handle
struct cmsis_dap_bulk_transfer response_transfers[MAX_PENDING_REQUESTS]
struct cmsis_dap_bulk_transfer command_transfers[MAX_PENDING_REQUESTS]
struct libusb_transfer * transfer
unsigned int packet_buffer_size
unsigned int packet_usable_size
unsigned int pending_fifo_put_idx
struct cmsis_dap_backend_data * bdata
unsigned int pending_fifo_get_idx