X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fjtag%2Fdrivers%2Flibusb1_common.c;h=607b6d4aa907b14359c51c1537d7d0461f8b9633;hp=ec52a1bce272464b68c86405301efbf608620062;hb=93c6bf2cce5f23e37d4a1dd5136a40e74c69285c;hpb=3792f3c114ee22eabe202427e948053828ca28a5 diff --git a/src/jtag/drivers/libusb1_common.c b/src/jtag/drivers/libusb1_common.c index ec52a1bce2..607b6d4aa9 100644 --- a/src/jtag/drivers/libusb1_common.c +++ b/src/jtag/drivers/libusb1_common.c @@ -20,12 +20,44 @@ #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include "log.h" +#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[]) { @@ -38,6 +70,31 @@ static bool jtag_libusb_match(struct libusb_device_descriptor *dev_desc, 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) @@ -68,12 +125,12 @@ static bool string_descriptor_equal(libusb_device_handle *device, uint8_t str_in int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], const char *serial, - struct jtag_libusb_device_handle **out) + struct libusb_device_handle **out) { int cnt, idx, errCode; int retval = ERROR_FAIL; bool serial_mismatch = false; - struct jtag_libusb_device_handle *libusb_handle = NULL; + struct libusb_device_handle *libusb_handle = NULL; if (libusb_init(&jtag_libusb_context) < 0) return ERROR_FAIL; @@ -89,6 +146,9 @@ int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], 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) { @@ -120,7 +180,7 @@ int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], return retval; } -void jtag_libusb_close(jtag_libusb_device_handle *dev) +void jtag_libusb_close(struct libusb_device_handle *dev) { /* Close device */ libusb_close(dev); @@ -128,7 +188,7 @@ void jtag_libusb_close(jtag_libusb_device_handle *dev) libusb_exit(jtag_libusb_context); } -int jtag_libusb_control_transfer(jtag_libusb_device_handle *dev, uint8_t requestType, +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) { @@ -143,30 +203,44 @@ int jtag_libusb_control_transfer(jtag_libusb_device_handle *dev, uint8_t request return transferred; } -int jtag_libusb_bulk_write(jtag_libusb_device_handle *dev, int ep, char *bytes, - int size, int timeout) +int jtag_libusb_bulk_write(struct libusb_device_handle *dev, int ep, char *bytes, + int size, int timeout, int *transferred) { - int transferred = 0; + int ret; - libusb_bulk_transfer(dev, ep, (unsigned char *)bytes, size, - &transferred, timeout); - return transferred; + *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(jtag_libusb_device_handle *dev, int ep, char *bytes, - int size, int timeout) +int jtag_libusb_bulk_read(struct libusb_device_handle *dev, int ep, char *bytes, + int size, int timeout, int *transferred) { - int transferred = 0; + int ret; - libusb_bulk_transfer(dev, ep, (unsigned char *)bytes, size, - &transferred, timeout); - return transferred; + *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(jtag_libusb_device_handle *devh, +int jtag_libusb_set_configuration(struct libusb_device_handle *devh, int configuration) { - struct jtag_libusb_device *udev = jtag_libusb_get_device(devh); + struct libusb_device *udev = libusb_get_device(devh); int retCode = -99; struct libusb_config_descriptor *config = NULL; @@ -191,12 +265,12 @@ int jtag_libusb_set_configuration(jtag_libusb_device_handle *devh, return retCode; } -int jtag_libusb_choose_interface(struct jtag_libusb_device_handle *devh, +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 jtag_libusb_device *udev = jtag_libusb_get_device(devh); + 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; @@ -243,7 +317,7 @@ int jtag_libusb_choose_interface(struct jtag_libusb_device_handle *devh, return ERROR_FAIL; } -int jtag_libusb_get_pid(struct jtag_libusb_device *dev, uint16_t *pid) +int jtag_libusb_get_pid(struct libusb_device *dev, uint16_t *pid) { struct libusb_device_descriptor dev_desc;