From 51dd4ce6bbc3c6f200001640f2cb1638b5185cb7 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Wed, 5 Feb 2020 16:07:48 +0100 Subject: drivers: Rename 'libusb1_common' to 'libusb_helper' The name 'common' does not make sense anymore. While at it, remove some unnecessary #includes. Change-Id: If9798a5cce179438d89428a598d8ca05c8e5f20c Signed-off-by: Marc Schink Reviewed-on: http://openocd.zylin.com/5434 Tested-by: jenkins Reviewed-by: Oleksij Rempel --- src/jtag/aice/aice_interface.c | 1 - src/jtag/aice/aice_usb.c | 2 +- src/jtag/drivers/Makefile.am | 5 +- src/jtag/drivers/ft232r.c | 2 +- src/jtag/drivers/kitprog.c | 2 +- src/jtag/drivers/libusb1_common.c | 331 --------------------- src/jtag/drivers/libusb1_common.h | 58 ---- src/jtag/drivers/libusb_common.h | 25 -- src/jtag/drivers/libusb_helper.c | 331 +++++++++++++++++++++ src/jtag/drivers/libusb_helper.h | 58 ++++ src/jtag/drivers/opendous.c | 2 +- src/jtag/drivers/openjtag.c | 2 +- src/jtag/drivers/osbdm.c | 2 +- src/jtag/drivers/stlink_usb.c | 2 +- .../drivers/usb_blaster/ublast2_access_libusb.c | 2 +- src/jtag/drivers/usb_blaster/ublast_access.h | 2 - 16 files changed, 399 insertions(+), 428 deletions(-) delete mode 100644 src/jtag/drivers/libusb1_common.c delete mode 100644 src/jtag/drivers/libusb1_common.h delete mode 100644 src/jtag/drivers/libusb_common.h create mode 100644 src/jtag/drivers/libusb_helper.c create mode 100644 src/jtag/drivers/libusb_helper.h diff --git a/src/jtag/aice/aice_interface.c b/src/jtag/aice/aice_interface.c index f9bd87e..90871a1 100644 --- a/src/jtag/aice/aice_interface.c +++ b/src/jtag/aice/aice_interface.c @@ -25,7 +25,6 @@ #include #include #include -#include #include "aice_usb.h" #define AICE_KHZ_TO_SPEED_MAP_SIZE 16 diff --git a/src/jtag/aice/aice_usb.c b/src/jtag/aice/aice_usb.c index 8c3a629..5fefdd0 100644 --- a/src/jtag/aice/aice_usb.c +++ b/src/jtag/aice/aice_usb.c @@ -19,7 +19,7 @@ #include "config.h" #endif -#include +#include #include #include #include diff --git a/src/jtag/drivers/Makefile.am b/src/jtag/drivers/Makefile.am index 47b1947..aea09b3 100644 --- a/src/jtag/drivers/Makefile.am +++ b/src/jtag/drivers/Makefile.am @@ -22,7 +22,7 @@ DRIVERFILES += %D%/driver.c DRIVERFILES += %D%/jtag_usb_common.c if USE_LIBUSB1 -DRIVERFILES += %D%/libusb1_common.c +DRIVERFILES += %D%/libusb_helper.c %C%_libocdjtagdrivers_la_CPPFLAGS += $(LIBUSB1_CFLAGS) %C%_libocdjtagdrivers_la_LIBADD += $(LIBUSB1_LIBS) endif @@ -168,8 +168,7 @@ DRIVERHEADERS = \ %D%/bitbang.h \ %D%/bitq.h \ %D%/jtag_usb_common.h \ - %D%/libusb1_common.h \ - %D%/libusb_common.h \ + %D%/libusb_helper.h \ %D%/minidriver_imp.h \ %D%/mpsse.h \ %D%/rlink.h \ diff --git a/src/jtag/drivers/ft232r.c b/src/jtag/drivers/ft232r.c index 8fe63bb..4812362 100644 --- a/src/jtag/drivers/ft232r.c +++ b/src/jtag/drivers/ft232r.c @@ -29,7 +29,7 @@ #include #include #include -#include "libusb1_common.h" +#include "libusb_helper.h" /* system includes */ #include diff --git a/src/jtag/drivers/kitprog.c b/src/jtag/drivers/kitprog.c index e26f5aa..0c1e74c 100644 --- a/src/jtag/drivers/kitprog.c +++ b/src/jtag/drivers/kitprog.c @@ -43,7 +43,7 @@ #include #include -#include "libusb_common.h" +#include "libusb_helper.h" #define VID 0x04b4 #define PID 0xf139 diff --git a/src/jtag/drivers/libusb1_common.c b/src/jtag/drivers/libusb1_common.c deleted file mode 100644 index 607b6d4..0000000 --- a/src/jtag/drivers/libusb1_common.c +++ /dev/null @@ -1,331 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Zachary T Welch * - * * - * Copyright (C) 2011 by Mauro Gamba * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include -#include "libusb1_common.h" -#include "log.h" - -/* - * comment from libusb: - * As per the USB 3.0 specs, the current maximum limit for the depth is 7. - */ -#define MAX_USB_PORTS 7 - -static struct libusb_context *jtag_libusb_context; /**< Libusb context **/ -static libusb_device **devs; /**< The usb device list **/ - -static int jtag_libusb_error(int err) -{ - switch (err) { - case LIBUSB_SUCCESS: - return ERROR_OK; - case LIBUSB_ERROR_TIMEOUT: - return ERROR_TIMEOUT_REACHED; - case LIBUSB_ERROR_IO: - case LIBUSB_ERROR_INVALID_PARAM: - case LIBUSB_ERROR_ACCESS: - case LIBUSB_ERROR_NO_DEVICE: - case LIBUSB_ERROR_NOT_FOUND: - case LIBUSB_ERROR_BUSY: - case LIBUSB_ERROR_OVERFLOW: - case LIBUSB_ERROR_PIPE: - case LIBUSB_ERROR_INTERRUPTED: - case LIBUSB_ERROR_NO_MEM: - case LIBUSB_ERROR_NOT_SUPPORTED: - case LIBUSB_ERROR_OTHER: - return ERROR_FAIL; - default: - return ERROR_FAIL; - } -} - -static bool jtag_libusb_match(struct libusb_device_descriptor *dev_desc, - const uint16_t vids[], const uint16_t pids[]) -{ - for (unsigned i = 0; vids[i]; i++) { - if (dev_desc->idVendor == vids[i] && - dev_desc->idProduct == pids[i]) { - return true; - } - } - return false; -} - -#ifdef HAVE_LIBUSB_GET_PORT_NUMBERS -static bool jtag_libusb_location_equal(libusb_device *device) -{ - uint8_t port_path[MAX_USB_PORTS]; - uint8_t dev_bus; - int path_len; - - path_len = libusb_get_port_numbers(device, port_path, MAX_USB_PORTS); - if (path_len == LIBUSB_ERROR_OVERFLOW) { - LOG_WARNING("cannot determine path to usb device! (more than %i ports in path)\n", - MAX_USB_PORTS); - return false; - } - dev_bus = libusb_get_bus_number(device); - - return jtag_usb_location_equal(dev_bus, port_path, path_len); -} -#else /* HAVE_LIBUSB_GET_PORT_NUMBERS */ -static bool jtag_libusb_location_equal(libusb_device *device) -{ - return true; -} -#endif /* HAVE_LIBUSB_GET_PORT_NUMBERS */ - - -/* Returns true if the string descriptor indexed by str_index in device matches string */ -static bool string_descriptor_equal(libusb_device_handle *device, uint8_t str_index, - const char *string) -{ - int retval; - bool matched; - char desc_string[256+1]; /* Max size of string descriptor */ - - if (str_index == 0) - return false; - - retval = libusb_get_string_descriptor_ascii(device, str_index, - (unsigned char *)desc_string, sizeof(desc_string)-1); - if (retval < 0) { - LOG_ERROR("libusb_get_string_descriptor_ascii() failed with %d", retval); - return false; - } - - /* Null terminate descriptor string in case it needs to be logged. */ - desc_string[sizeof(desc_string)-1] = '\0'; - - matched = strncmp(string, desc_string, sizeof(desc_string)) == 0; - if (!matched) - LOG_DEBUG("Device serial number '%s' doesn't match requested serial '%s'", - desc_string, string); - return matched; -} - -int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], - const char *serial, - struct libusb_device_handle **out) -{ - int cnt, idx, errCode; - int retval = ERROR_FAIL; - bool serial_mismatch = false; - struct libusb_device_handle *libusb_handle = NULL; - - if (libusb_init(&jtag_libusb_context) < 0) - return ERROR_FAIL; - - cnt = libusb_get_device_list(jtag_libusb_context, &devs); - - for (idx = 0; idx < cnt; idx++) { - struct libusb_device_descriptor dev_desc; - - if (libusb_get_device_descriptor(devs[idx], &dev_desc) != 0) - continue; - - if (!jtag_libusb_match(&dev_desc, vids, pids)) - continue; - - if (jtag_usb_get_location() && !jtag_libusb_location_equal(devs[idx])) - continue; - - errCode = libusb_open(devs[idx], &libusb_handle); - - if (errCode) { - LOG_ERROR("libusb_open() failed with %s", - libusb_error_name(errCode)); - continue; - } - - /* Device must be open to use libusb_get_string_descriptor_ascii. */ - if (serial != NULL && - !string_descriptor_equal(libusb_handle, dev_desc.iSerialNumber, serial)) { - serial_mismatch = true; - libusb_close(libusb_handle); - continue; - } - - /* Success. */ - *out = libusb_handle; - retval = ERROR_OK; - serial_mismatch = false; - break; - } - if (cnt >= 0) - libusb_free_device_list(devs, 1); - - if (serial_mismatch) - LOG_INFO("No device matches the serial string"); - - return retval; -} - -void jtag_libusb_close(struct libusb_device_handle *dev) -{ - /* Close device */ - libusb_close(dev); - - libusb_exit(jtag_libusb_context); -} - -int jtag_libusb_control_transfer(struct libusb_device_handle *dev, uint8_t requestType, - uint8_t request, uint16_t wValue, uint16_t wIndex, char *bytes, - uint16_t size, unsigned int timeout) -{ - int transferred = 0; - - transferred = libusb_control_transfer(dev, requestType, request, wValue, wIndex, - (unsigned char *)bytes, size, timeout); - - if (transferred < 0) - transferred = 0; - - return transferred; -} - -int jtag_libusb_bulk_write(struct libusb_device_handle *dev, int ep, char *bytes, - int size, int timeout, int *transferred) -{ - int ret; - - *transferred = 0; - - ret = libusb_bulk_transfer(dev, ep, (unsigned char *)bytes, size, - transferred, timeout); - if (ret != LIBUSB_SUCCESS) { - LOG_ERROR("libusb_bulk_write error: %s", libusb_error_name(ret)); - return jtag_libusb_error(ret); - } - - return ERROR_OK; -} - -int jtag_libusb_bulk_read(struct libusb_device_handle *dev, int ep, char *bytes, - int size, int timeout, int *transferred) -{ - int ret; - - *transferred = 0; - - ret = libusb_bulk_transfer(dev, ep, (unsigned char *)bytes, size, - transferred, timeout); - if (ret != LIBUSB_SUCCESS) { - LOG_ERROR("libusb_bulk_read error: %s", libusb_error_name(ret)); - return jtag_libusb_error(ret); - } - - return ERROR_OK; -} - -int jtag_libusb_set_configuration(struct libusb_device_handle *devh, - int configuration) -{ - struct libusb_device *udev = libusb_get_device(devh); - int retCode = -99; - - struct libusb_config_descriptor *config = NULL; - int current_config = -1; - - retCode = libusb_get_configuration(devh, ¤t_config); - if (retCode != 0) - return retCode; - - retCode = libusb_get_config_descriptor(udev, configuration, &config); - if (retCode != 0 || config == NULL) - return retCode; - - /* Only change the configuration if it is not already set to the - same one. Otherwise this issues a lightweight reset and hangs - LPC-Link2 with JLink firmware. */ - if (current_config != config->bConfigurationValue) - retCode = libusb_set_configuration(devh, config->bConfigurationValue); - - libusb_free_config_descriptor(config); - - return retCode; -} - -int jtag_libusb_choose_interface(struct libusb_device_handle *devh, - unsigned int *usb_read_ep, - unsigned int *usb_write_ep, - int bclass, int subclass, int protocol, int trans_type) -{ - struct libusb_device *udev = libusb_get_device(devh); - const struct libusb_interface *inter; - const struct libusb_interface_descriptor *interdesc; - const struct libusb_endpoint_descriptor *epdesc; - struct libusb_config_descriptor *config; - - *usb_read_ep = *usb_write_ep = 0; - - libusb_get_config_descriptor(udev, 0, &config); - for (int i = 0; i < (int)config->bNumInterfaces; i++) { - inter = &config->interface[i]; - - interdesc = &inter->altsetting[0]; - for (int k = 0; - k < (int)interdesc->bNumEndpoints; k++) { - if ((bclass > 0 && interdesc->bInterfaceClass != bclass) || - (subclass > 0 && interdesc->bInterfaceSubClass != subclass) || - (protocol > 0 && interdesc->bInterfaceProtocol != protocol)) - continue; - - epdesc = &interdesc->endpoint[k]; - if (trans_type > 0 && (epdesc->bmAttributes & 0x3) != trans_type) - continue; - - uint8_t epnum = epdesc->bEndpointAddress; - bool is_input = epnum & 0x80; - LOG_DEBUG("usb ep %s %02x", - is_input ? "in" : "out", epnum); - - if (is_input) - *usb_read_ep = epnum; - else - *usb_write_ep = epnum; - - if (*usb_read_ep && *usb_write_ep) { - LOG_DEBUG("Claiming interface %d", (int)interdesc->bInterfaceNumber); - libusb_claim_interface(devh, (int)interdesc->bInterfaceNumber); - libusb_free_config_descriptor(config); - return ERROR_OK; - } - } - } - libusb_free_config_descriptor(config); - - return ERROR_FAIL; -} - -int jtag_libusb_get_pid(struct libusb_device *dev, uint16_t *pid) -{ - struct libusb_device_descriptor dev_desc; - - if (libusb_get_device_descriptor(dev, &dev_desc) == 0) { - *pid = dev_desc.idProduct; - - return ERROR_OK; - } - - return ERROR_FAIL; -} diff --git a/src/jtag/drivers/libusb1_common.h b/src/jtag/drivers/libusb1_common.h deleted file mode 100644 index b132e26..0000000 --- a/src/jtag/drivers/libusb1_common.h +++ /dev/null @@ -1,58 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Zachary T Welch * - * * - * Copyright (C) 2011 by Mauro Gamba * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_JTAG_DRIVERS_LIBUSB1_COMMON_H -#define OPENOCD_JTAG_DRIVERS_LIBUSB1_COMMON_H - -#include - -int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], - const char *serial, - struct libusb_device_handle **out); -void jtag_libusb_close(struct libusb_device_handle *dev); -int jtag_libusb_control_transfer(struct libusb_device_handle *dev, - uint8_t requestType, uint8_t request, uint16_t wValue, - uint16_t wIndex, char *bytes, uint16_t size, unsigned int timeout); -int jtag_libusb_bulk_write(struct libusb_device_handle *dev, int ep, - char *bytes, int size, int timeout, int *transferred); -int jtag_libusb_bulk_read(struct libusb_device_handle *dev, int ep, - char *bytes, int size, int timeout, int *transferred); -int jtag_libusb_set_configuration(struct libusb_device_handle *devh, - int configuration); -/** - * Find the first interface optionally matching class, subclass and - * protocol and claim it. - * @param devh _libusb_ device handle. - * @param usb_read_ep A pointer to a variable where the _IN_ endpoint - * number will be stored. - * @param usb_write_ep A pointer to a variable where the _OUT_ endpoint - * number will be stored. - * @param bclass `bInterfaceClass` to match, or -1 to ignore this field. - * @param subclass `bInterfaceSubClass` to match, or -1 to ignore this field. - * @param protocol `bInterfaceProtocol` to match, or -1 to ignore this field. - * @param trans_type `bmAttributes Bits 0..1 Transfer type` to match, or -1 to ignore this field. - * @returns Returns ERROR_OK on success, ERROR_FAIL otherwise. - */ -int jtag_libusb_choose_interface(struct libusb_device_handle *devh, - unsigned int *usb_read_ep, - unsigned int *usb_write_ep, - int bclass, int subclass, int protocol, int trans_type); -int jtag_libusb_get_pid(struct libusb_device *dev, uint16_t *pid); - -#endif /* OPENOCD_JTAG_DRIVERS_LIBUSB1_COMMON_H */ diff --git a/src/jtag/drivers/libusb_common.h b/src/jtag/drivers/libusb_common.h deleted file mode 100644 index 47aca5d..0000000 --- a/src/jtag/drivers/libusb_common.h +++ /dev/null @@ -1,25 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Mauro Gamba * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see . * - ***************************************************************************/ - -#ifndef OPENOCD_JTAG_DRIVERS_LIBUSB_COMMON_H -#define OPENOCD_JTAG_DRIVERS_LIBUSB_COMMON_H - -#ifdef HAVE_LIBUSB1 -#include "libusb1_common.h" -#endif - -#endif /* OPENOCD_JTAG_DRIVERS_LIBUSB_COMMON_H */ diff --git a/src/jtag/drivers/libusb_helper.c b/src/jtag/drivers/libusb_helper.c new file mode 100644 index 0000000..5a8129c --- /dev/null +++ b/src/jtag/drivers/libusb_helper.c @@ -0,0 +1,331 @@ +/*************************************************************************** + * Copyright (C) 2009 by Zachary T Welch * + * * + * Copyright (C) 2011 by Mauro Gamba * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include +#include "libusb_helper.h" +#include "log.h" + +/* + * comment from libusb: + * As per the USB 3.0 specs, the current maximum limit for the depth is 7. + */ +#define MAX_USB_PORTS 7 + +static struct libusb_context *jtag_libusb_context; /**< Libusb context **/ +static libusb_device **devs; /**< The usb device list **/ + +static int jtag_libusb_error(int err) +{ + switch (err) { + case LIBUSB_SUCCESS: + return ERROR_OK; + case LIBUSB_ERROR_TIMEOUT: + return ERROR_TIMEOUT_REACHED; + case LIBUSB_ERROR_IO: + case LIBUSB_ERROR_INVALID_PARAM: + case LIBUSB_ERROR_ACCESS: + case LIBUSB_ERROR_NO_DEVICE: + case LIBUSB_ERROR_NOT_FOUND: + case LIBUSB_ERROR_BUSY: + case LIBUSB_ERROR_OVERFLOW: + case LIBUSB_ERROR_PIPE: + case LIBUSB_ERROR_INTERRUPTED: + case LIBUSB_ERROR_NO_MEM: + case LIBUSB_ERROR_NOT_SUPPORTED: + case LIBUSB_ERROR_OTHER: + return ERROR_FAIL; + default: + return ERROR_FAIL; + } +} + +static bool jtag_libusb_match(struct libusb_device_descriptor *dev_desc, + const uint16_t vids[], const uint16_t pids[]) +{ + for (unsigned i = 0; vids[i]; i++) { + if (dev_desc->idVendor == vids[i] && + dev_desc->idProduct == pids[i]) { + return true; + } + } + return false; +} + +#ifdef HAVE_LIBUSB_GET_PORT_NUMBERS +static bool jtag_libusb_location_equal(libusb_device *device) +{ + uint8_t port_path[MAX_USB_PORTS]; + uint8_t dev_bus; + int path_len; + + path_len = libusb_get_port_numbers(device, port_path, MAX_USB_PORTS); + if (path_len == LIBUSB_ERROR_OVERFLOW) { + LOG_WARNING("cannot determine path to usb device! (more than %i ports in path)\n", + MAX_USB_PORTS); + return false; + } + dev_bus = libusb_get_bus_number(device); + + return jtag_usb_location_equal(dev_bus, port_path, path_len); +} +#else /* HAVE_LIBUSB_GET_PORT_NUMBERS */ +static bool jtag_libusb_location_equal(libusb_device *device) +{ + return true; +} +#endif /* HAVE_LIBUSB_GET_PORT_NUMBERS */ + + +/* Returns true if the string descriptor indexed by str_index in device matches string */ +static bool string_descriptor_equal(libusb_device_handle *device, uint8_t str_index, + const char *string) +{ + int retval; + bool matched; + char desc_string[256+1]; /* Max size of string descriptor */ + + if (str_index == 0) + return false; + + retval = libusb_get_string_descriptor_ascii(device, str_index, + (unsigned char *)desc_string, sizeof(desc_string)-1); + if (retval < 0) { + LOG_ERROR("libusb_get_string_descriptor_ascii() failed with %d", retval); + return false; + } + + /* Null terminate descriptor string in case it needs to be logged. */ + desc_string[sizeof(desc_string)-1] = '\0'; + + matched = strncmp(string, desc_string, sizeof(desc_string)) == 0; + if (!matched) + LOG_DEBUG("Device serial number '%s' doesn't match requested serial '%s'", + desc_string, string); + return matched; +} + +int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], + const char *serial, + struct libusb_device_handle **out) +{ + int cnt, idx, errCode; + int retval = ERROR_FAIL; + bool serial_mismatch = false; + struct libusb_device_handle *libusb_handle = NULL; + + if (libusb_init(&jtag_libusb_context) < 0) + return ERROR_FAIL; + + cnt = libusb_get_device_list(jtag_libusb_context, &devs); + + for (idx = 0; idx < cnt; idx++) { + struct libusb_device_descriptor dev_desc; + + if (libusb_get_device_descriptor(devs[idx], &dev_desc) != 0) + continue; + + if (!jtag_libusb_match(&dev_desc, vids, pids)) + continue; + + if (jtag_usb_get_location() && !jtag_libusb_location_equal(devs[idx])) + continue; + + errCode = libusb_open(devs[idx], &libusb_handle); + + if (errCode) { + LOG_ERROR("libusb_open() failed with %s", + libusb_error_name(errCode)); + continue; + } + + /* Device must be open to use libusb_get_string_descriptor_ascii. */ + if (serial != NULL && + !string_descriptor_equal(libusb_handle, dev_desc.iSerialNumber, serial)) { + serial_mismatch = true; + libusb_close(libusb_handle); + continue; + } + + /* Success. */ + *out = libusb_handle; + retval = ERROR_OK; + serial_mismatch = false; + break; + } + if (cnt >= 0) + libusb_free_device_list(devs, 1); + + if (serial_mismatch) + LOG_INFO("No device matches the serial string"); + + return retval; +} + +void jtag_libusb_close(struct libusb_device_handle *dev) +{ + /* Close device */ + libusb_close(dev); + + libusb_exit(jtag_libusb_context); +} + +int jtag_libusb_control_transfer(struct libusb_device_handle *dev, uint8_t requestType, + uint8_t request, uint16_t wValue, uint16_t wIndex, char *bytes, + uint16_t size, unsigned int timeout) +{ + int transferred = 0; + + transferred = libusb_control_transfer(dev, requestType, request, wValue, wIndex, + (unsigned char *)bytes, size, timeout); + + if (transferred < 0) + transferred = 0; + + return transferred; +} + +int jtag_libusb_bulk_write(struct libusb_device_handle *dev, int ep, char *bytes, + int size, int timeout, int *transferred) +{ + int ret; + + *transferred = 0; + + ret = libusb_bulk_transfer(dev, ep, (unsigned char *)bytes, size, + transferred, timeout); + if (ret != LIBUSB_SUCCESS) { + LOG_ERROR("libusb_bulk_write error: %s", libusb_error_name(ret)); + return jtag_libusb_error(ret); + } + + return ERROR_OK; +} + +int jtag_libusb_bulk_read(struct libusb_device_handle *dev, int ep, char *bytes, + int size, int timeout, int *transferred) +{ + int ret; + + *transferred = 0; + + ret = libusb_bulk_transfer(dev, ep, (unsigned char *)bytes, size, + transferred, timeout); + if (ret != LIBUSB_SUCCESS) { + LOG_ERROR("libusb_bulk_read error: %s", libusb_error_name(ret)); + return jtag_libusb_error(ret); + } + + return ERROR_OK; +} + +int jtag_libusb_set_configuration(struct libusb_device_handle *devh, + int configuration) +{ + struct libusb_device *udev = libusb_get_device(devh); + int retCode = -99; + + struct libusb_config_descriptor *config = NULL; + int current_config = -1; + + retCode = libusb_get_configuration(devh, ¤t_config); + if (retCode != 0) + return retCode; + + retCode = libusb_get_config_descriptor(udev, configuration, &config); + if (retCode != 0 || config == NULL) + return retCode; + + /* Only change the configuration if it is not already set to the + same one. Otherwise this issues a lightweight reset and hangs + LPC-Link2 with JLink firmware. */ + if (current_config != config->bConfigurationValue) + retCode = libusb_set_configuration(devh, config->bConfigurationValue); + + libusb_free_config_descriptor(config); + + return retCode; +} + +int jtag_libusb_choose_interface(struct libusb_device_handle *devh, + unsigned int *usb_read_ep, + unsigned int *usb_write_ep, + int bclass, int subclass, int protocol, int trans_type) +{ + struct libusb_device *udev = libusb_get_device(devh); + const struct libusb_interface *inter; + const struct libusb_interface_descriptor *interdesc; + const struct libusb_endpoint_descriptor *epdesc; + struct libusb_config_descriptor *config; + + *usb_read_ep = *usb_write_ep = 0; + + libusb_get_config_descriptor(udev, 0, &config); + for (int i = 0; i < (int)config->bNumInterfaces; i++) { + inter = &config->interface[i]; + + interdesc = &inter->altsetting[0]; + for (int k = 0; + k < (int)interdesc->bNumEndpoints; k++) { + if ((bclass > 0 && interdesc->bInterfaceClass != bclass) || + (subclass > 0 && interdesc->bInterfaceSubClass != subclass) || + (protocol > 0 && interdesc->bInterfaceProtocol != protocol)) + continue; + + epdesc = &interdesc->endpoint[k]; + if (trans_type > 0 && (epdesc->bmAttributes & 0x3) != trans_type) + continue; + + uint8_t epnum = epdesc->bEndpointAddress; + bool is_input = epnum & 0x80; + LOG_DEBUG("usb ep %s %02x", + is_input ? "in" : "out", epnum); + + if (is_input) + *usb_read_ep = epnum; + else + *usb_write_ep = epnum; + + if (*usb_read_ep && *usb_write_ep) { + LOG_DEBUG("Claiming interface %d", (int)interdesc->bInterfaceNumber); + libusb_claim_interface(devh, (int)interdesc->bInterfaceNumber); + libusb_free_config_descriptor(config); + return ERROR_OK; + } + } + } + libusb_free_config_descriptor(config); + + return ERROR_FAIL; +} + +int jtag_libusb_get_pid(struct libusb_device *dev, uint16_t *pid) +{ + struct libusb_device_descriptor dev_desc; + + if (libusb_get_device_descriptor(dev, &dev_desc) == 0) { + *pid = dev_desc.idProduct; + + return ERROR_OK; + } + + return ERROR_FAIL; +} diff --git a/src/jtag/drivers/libusb_helper.h b/src/jtag/drivers/libusb_helper.h new file mode 100644 index 0000000..46e4954 --- /dev/null +++ b/src/jtag/drivers/libusb_helper.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * Copyright (C) 2009 by Zachary T Welch * + * * + * Copyright (C) 2011 by Mauro Gamba * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + ***************************************************************************/ + +#ifndef OPENOCD_JTAG_DRIVERS_LIBUSB_HELPER_H +#define OPENOCD_JTAG_DRIVERS_LIBUSB_HELPER_H + +#include + +int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], + const char *serial, + struct libusb_device_handle **out); +void jtag_libusb_close(struct libusb_device_handle *dev); +int jtag_libusb_control_transfer(struct libusb_device_handle *dev, + uint8_t requestType, uint8_t request, uint16_t wValue, + uint16_t wIndex, char *bytes, uint16_t size, unsigned int timeout); +int jtag_libusb_bulk_write(struct libusb_device_handle *dev, int ep, + char *bytes, int size, int timeout, int *transferred); +int jtag_libusb_bulk_read(struct libusb_device_handle *dev, int ep, + char *bytes, int size, int timeout, int *transferred); +int jtag_libusb_set_configuration(struct libusb_device_handle *devh, + int configuration); +/** + * Find the first interface optionally matching class, subclass and + * protocol and claim it. + * @param devh _libusb_ device handle. + * @param usb_read_ep A pointer to a variable where the _IN_ endpoint + * number will be stored. + * @param usb_write_ep A pointer to a variable where the _OUT_ endpoint + * number will be stored. + * @param bclass `bInterfaceClass` to match, or -1 to ignore this field. + * @param subclass `bInterfaceSubClass` to match, or -1 to ignore this field. + * @param protocol `bInterfaceProtocol` to match, or -1 to ignore this field. + * @param trans_type `bmAttributes Bits 0..1 Transfer type` to match, or -1 to ignore this field. + * @returns Returns ERROR_OK on success, ERROR_FAIL otherwise. + */ +int jtag_libusb_choose_interface(struct libusb_device_handle *devh, + unsigned int *usb_read_ep, + unsigned int *usb_write_ep, + int bclass, int subclass, int protocol, int trans_type); +int jtag_libusb_get_pid(struct libusb_device *dev, uint16_t *pid); + +#endif /* OPENOCD_JTAG_DRIVERS_LIBUSB_HELPER_H */ diff --git a/src/jtag/drivers/opendous.c b/src/jtag/drivers/opendous.c index 18d9543..7298a2a 100644 --- a/src/jtag/drivers/opendous.c +++ b/src/jtag/drivers/opendous.c @@ -32,7 +32,7 @@ #include #include -#include "libusb_common.h" +#include "libusb_helper.h" #include #include diff --git a/src/jtag/drivers/openjtag.c b/src/jtag/drivers/openjtag.c index 3bfcccf..7b07813 100644 --- a/src/jtag/drivers/openjtag.c +++ b/src/jtag/drivers/openjtag.c @@ -45,7 +45,7 @@ #include #include -#include "libusb_common.h" +#include "libusb_helper.h" static enum { OPENJTAG_VARIANT_STANDARD, diff --git a/src/jtag/drivers/osbdm.c b/src/jtag/drivers/osbdm.c index 30c4623..aea126d 100644 --- a/src/jtag/drivers/osbdm.c +++ b/src/jtag/drivers/osbdm.c @@ -23,7 +23,7 @@ #include #include #include -#include "libusb_common.h" +#include "libusb_helper.h" struct sequence { int len; diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index a186dfd..ca7a4df 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -41,7 +41,7 @@ #include -#include "libusb_common.h" +#include "libusb_helper.h" #ifdef HAVE_LIBUSB1 #define USE_LIBUSB_ASYNCIO diff --git a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c b/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c index 34fbb89..4f7ee63 100644 --- a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c +++ b/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c @@ -23,7 +23,7 @@ #endif #include #include -#include +#include #include #include "ublast_access.h" diff --git a/src/jtag/drivers/usb_blaster/ublast_access.h b/src/jtag/drivers/usb_blaster/ublast_access.h index 5178ae1..ad20d65 100644 --- a/src/jtag/drivers/usb_blaster/ublast_access.h +++ b/src/jtag/drivers/usb_blaster/ublast_access.h @@ -28,8 +28,6 @@ #ifndef OPENOCD_JTAG_DRIVERS_USB_BLASTER_UBLAST_ACCESS_H #define OPENOCD_JTAG_DRIVERS_USB_BLASTER_UBLAST_ACCESS_H -#include - /* Low level flags */ #define COPY_TDO_BUFFER (1 << 0) -- cgit v1.1