From: OpenOCD-Gerrit <ope...@us...> - 2020-03-22 08:17:59
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 4b4389a2d69d96e08d2b417e47c24cad6b50a5c5 (commit) via 6ecccc88955ead6283bfa9da123e120a73d4cab8 (commit) from 1891c2d26e240a76b2a5a1761ff0da7693d89901 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4b4389a2d69d96e08d2b417e47c24cad6b50a5c5 Author: Tarek BOCHKATI <tar...@gm...> Date: Sat Mar 7 17:20:24 2020 +0100 stlink: workaround serial bug with old ST-Link DFU Old ST-LINK DFU returns an incorrect serial in the USB descriptor example for the following serial "57FF72067265575742132067" - the correct descriptor serial is: 0x32, 0x03, 0x35, 0x00, 0x37, 0x00, 0x46, 0x00, 0x46, 0x00 ... this contains the length (0x32 = 50), the type (0x3 = DT_STRING) and the serial in unicode format. the serial part is: 0x0035, 0x0037, 0x0046, 0x0046 ... >> 57FF ... this format could be read correctly by 'libusb_get_string_descriptor_ascii' so this case is managed by libusb_helper::string_descriptor_equal - the buggy DFU is not doing any unicode conversion and returns a raw serial data in the descriptor: 0x1a, 0x03, 0x57, 0x00, 0xFF, 0x00, 0x72, 0x00 ... >> 57 FF 72 ... based on the length (0x1a = 26) we could easily decide if we have to fixup the serial and then we have just to convert the raw data into printable characters using sprintf example for an old ST-LINK/V2 standalone: before : 'W?rreWWB g' after : '57FF72067265575742132067' => same as the displayed value in STM32CubeProgrammer tested using these commands using the buggy serial -c "hla_serial \x57\x3f\x72\x06\x72\x65\x57\x57\x42\x13\x20\x67" using the computed serial -c "hla_serial 57FF72067265575742132067" Change-Id: I1213818257663eeb8e76f419087d3127d0524842 Signed-off-by: Tarek BOCHKATI <tar...@gm...> Reviewed-on: http://openocd.zylin.com/5396 Reviewed-by: Oleksij Rempel <li...@re...> Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index d8d8d67e3..6ab979f1c 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -47,6 +47,8 @@ #define USE_LIBUSB_ASYNCIO #endif +#define STLINK_SERIAL_LEN 24 + #define ENDPOINT_IN 0x80 #define ENDPOINT_OUT 0x00 @@ -2745,6 +2747,85 @@ static int stlink_usb_close(void *handle) return ERROR_OK; } +/* Compute ST-Link serial number from the device descriptor + * this function will help to work-around a bug in old ST-Link/V2 DFU + * the buggy DFU returns an incorrect serial in the USB descriptor + * example for the following serial "57FF72067265575742132067" + * - the correct descriptor serial is: + * 0x32, 0x03, 0x35, 0x00, 0x37, 0x00, 0x46, 0x00, 0x46, 0x00, 0x37, 0x00, 0x32, 0x00 ... + * this contains the length (0x32 = 50), the type (0x3 = DT_STRING) and the serial in unicode format + * the serial part is: 0x0035, 0x0037, 0x0046, 0x0046, 0x0037, 0x0032 ... >> 57FF72 ... + * this format could be read correctly by 'libusb_get_string_descriptor_ascii' + * so this case is managed by libusb_helper::string_descriptor_equal + * - the buggy DFU is not doing any unicode conversion and returns a raw serial data in the descriptor + * 0x1a, 0x03, 0x57, 0x00, 0xFF, 0x00, 0x72, 0x00 ... + * >> 57 FF 72 ... + * based on the length (0x1a = 26) we could easily decide if we have to fixup the serial + * and then we have just to convert the raw data into printable characters using sprintf + */ +char *stlink_usb_get_alternate_serial(libusb_device_handle *device, + struct libusb_device_descriptor *dev_desc) +{ + int usb_retval; + unsigned char desc_serial[(STLINK_SERIAL_LEN + 1) * 2]; + + if (dev_desc->iSerialNumber == 0) + return NULL; + + /* get the LANGID from String Descriptor Zero */ + usb_retval = libusb_get_string_descriptor(device, 0, 0, desc_serial, + sizeof(desc_serial)); + + if (usb_retval < LIBUSB_SUCCESS) { + LOG_ERROR("libusb_get_string_descriptor() failed: %s(%d)", + libusb_error_name(usb_retval), usb_retval); + return NULL; + } else if (usb_retval < 4) { + /* the size should be least 4 bytes to contain a minimum of 1 supported LANGID */ + LOG_ERROR("could not get the LANGID"); + return NULL; + } + + uint32_t langid = desc_serial[2] | (desc_serial[3] << 8); + + /* get the serial */ + usb_retval = libusb_get_string_descriptor(device, dev_desc->iSerialNumber, + langid, desc_serial, sizeof(desc_serial)); + + unsigned char len = desc_serial[0]; + + if (usb_retval < LIBUSB_SUCCESS) { + LOG_ERROR("libusb_get_string_descriptor() failed: %s(%d)", + libusb_error_name(usb_retval), usb_retval); + return NULL; + } else if (desc_serial[1] != LIBUSB_DT_STRING || len > usb_retval) { + LOG_ERROR("invalid string in ST-LINK USB serial descriptor"); + return NULL; + } + + if (len == ((STLINK_SERIAL_LEN + 1) * 2)) { + /* good ST-Link adapter, this case is managed by + * libusb::libusb_get_string_descriptor_ascii */ + return NULL; + } else if (len != ((STLINK_SERIAL_LEN / 2 + 1) * 2)) { + LOG_ERROR("unexpected serial length (%d) in descriptor", len); + return NULL; + } + + /* else (len == 26) => buggy ST-Link */ + + char *alternate_serial = malloc((STLINK_SERIAL_LEN + 1) * sizeof(char)); + if (alternate_serial == NULL) + return NULL; + + for (unsigned int i = 0; i < STLINK_SERIAL_LEN; i += 2) + sprintf(alternate_serial + i, "%02X", desc_serial[i + 2]); + + alternate_serial[STLINK_SERIAL_LEN] = '\0'; + + return alternate_serial; +} + /** */ static int stlink_usb_open(struct hl_interface_param_s *param, void **fd) { @@ -2779,7 +2860,7 @@ static int stlink_usb_open(struct hl_interface_param_s *param, void **fd) */ do { if (jtag_libusb_open(param->vid, param->pid, param->serial, - &h->fd, NULL) != ERROR_OK) { + &h->fd, stlink_usb_get_alternate_serial) != ERROR_OK) { LOG_ERROR("open failed"); goto error_open; } commit 6ecccc88955ead6283bfa9da123e120a73d4cab8 Author: Tarek BOCHKATI <tar...@gm...> Date: Fri Mar 6 13:52:23 2020 +0100 jtag/libusb_helper: permit adapters to compute their custom serials introduce a callback function that could be passed to jtag_libusb_open to permit adapters to compute their custom/exotic serials. the callback should return a non NULL value only when the serial could not be retrieved by the standard 'libusb_get_string_descriptor_ascii' Change-Id: Ib95d6bdfc4ee655eda538fba8becfa183c3b0059 Signed-off-by: Tarek BOCHKATI <tar...@gm...> Reviewed-on: http://openocd.zylin.com/5496 Reviewed-by: Antonio Borneo <bor...@gm...> Tested-by: jenkins Reviewed-by: Oleksij Rempel <li...@re...> diff --git a/src/jtag/aice/aice_usb.c b/src/jtag/aice/aice_usb.c index a5cccfef4..442754209 100644 --- a/src/jtag/aice/aice_usb.c +++ b/src/jtag/aice/aice_usb.c @@ -2111,7 +2111,7 @@ static int aice_usb_open(struct aice_port_param_s *param) const uint16_t pids[] = { param->pid, 0 }; struct libusb_device_handle *devh; - if (jtag_libusb_open(vids, pids, NULL, &devh) != ERROR_OK) + if (jtag_libusb_open(vids, pids, NULL, &devh, NULL) != ERROR_OK) return ERROR_FAIL; /* BE ***VERY CAREFUL*** ABOUT MAKING CHANGES IN THIS @@ -2135,7 +2135,7 @@ static int aice_usb_open(struct aice_port_param_s *param) /* reopen jlink after usb_reset * on win32 this may take a second or two to re-enumerate */ int retval; - while ((retval = jtag_libusb_open(vids, pids, NULL, &devh)) != ERROR_OK) { + while ((retval = jtag_libusb_open(vids, pids, NULL, &devh, NULL)) != ERROR_OK) { usleep(1000); timeout--; if (!timeout) diff --git a/src/jtag/drivers/ft232r.c b/src/jtag/drivers/ft232r.c index 4812362a3..c9ed304a8 100644 --- a/src/jtag/drivers/ft232r.c +++ b/src/jtag/drivers/ft232r.c @@ -257,7 +257,7 @@ static int ft232r_init(void) { uint16_t avids[] = {ft232r_vid, 0}; uint16_t apids[] = {ft232r_pid, 0}; - if (jtag_libusb_open(avids, apids, ft232r_serial_desc, &adapter)) { + if (jtag_libusb_open(avids, apids, ft232r_serial_desc, &adapter, NULL)) { LOG_ERROR("ft232r not found: vid=%04x, pid=%04x, serial=%s\n", ft232r_vid, ft232r_pid, (ft232r_serial_desc == NULL) ? "[any]" : ft232r_serial_desc); return ERROR_JTAG_INIT_FAILED; diff --git a/src/jtag/drivers/kitprog.c b/src/jtag/drivers/kitprog.c index 0c1e74c42..28ed7ac61 100644 --- a/src/jtag/drivers/kitprog.c +++ b/src/jtag/drivers/kitprog.c @@ -280,7 +280,7 @@ static int kitprog_usb_open(void) const uint16_t pids[] = { PID, 0 }; if (jtag_libusb_open(vids, pids, kitprog_serial, - &kitprog_handle->usb_handle) != ERROR_OK) { + &kitprog_handle->usb_handle, NULL) != ERROR_OK) { LOG_ERROR("Failed to open or find the device"); return ERROR_FAIL; } diff --git a/src/jtag/drivers/libusb_helper.c b/src/jtag/drivers/libusb_helper.c index 5a8129cb9..fbbfb4114 100644 --- a/src/jtag/drivers/libusb_helper.c +++ b/src/jtag/drivers/libusb_helper.c @@ -58,7 +58,7 @@ static int jtag_libusb_error(int err) } } -static bool jtag_libusb_match(struct libusb_device_descriptor *dev_desc, +static bool jtag_libusb_match_ids(struct libusb_device_descriptor *dev_desc, const uint16_t vids[], const uint16_t pids[]) { for (unsigned i = 0; vids[i]; i++) { @@ -123,9 +123,40 @@ static bool string_descriptor_equal(libusb_device_handle *device, uint8_t str_in return matched; } +static bool jtag_libusb_match_serial(libusb_device_handle *device, + struct libusb_device_descriptor *dev_desc, const char *serial, + adapter_get_alternate_serial_fn adapter_get_alternate_serial) +{ + if (string_descriptor_equal(device, dev_desc->iSerialNumber, serial)) + return true; + + /* check the alternate serial helper */ + if (!adapter_get_alternate_serial) + return false; + + /* get the alternate serial */ + char *alternate_serial = adapter_get_alternate_serial(device, dev_desc); + + /* check possible failures */ + if (alternate_serial == NULL) + return false; + + /* then compare and free the alternate serial */ + bool match = false; + if (strcmp(serial, alternate_serial) == 0) + match = true; + else + LOG_DEBUG("Device alternate serial number '%s' doesn't match requested serial '%s'", + alternate_serial, serial); + + free(alternate_serial); + return match; +} + int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], const char *serial, - struct libusb_device_handle **out) + struct libusb_device_handle **out, + adapter_get_alternate_serial_fn adapter_get_alternate_serial) { int cnt, idx, errCode; int retval = ERROR_FAIL; @@ -143,7 +174,7 @@ int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], if (libusb_get_device_descriptor(devs[idx], &dev_desc) != 0) continue; - if (!jtag_libusb_match(&dev_desc, vids, pids)) + if (!jtag_libusb_match_ids(&dev_desc, vids, pids)) continue; if (jtag_usb_get_location() && !jtag_libusb_location_equal(devs[idx])) @@ -159,7 +190,7 @@ int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], /* Device must be open to use libusb_get_string_descriptor_ascii. */ if (serial != NULL && - !string_descriptor_equal(libusb_handle, dev_desc.iSerialNumber, serial)) { + !jtag_libusb_match_serial(libusb_handle, &dev_desc, serial, adapter_get_alternate_serial)) { serial_mismatch = true; libusb_close(libusb_handle); continue; diff --git a/src/jtag/drivers/libusb_helper.h b/src/jtag/drivers/libusb_helper.h index 46e4954e7..74bb23c52 100644 --- a/src/jtag/drivers/libusb_helper.h +++ b/src/jtag/drivers/libusb_helper.h @@ -22,9 +22,15 @@ #include <libusb.h> +/* this callback should return a non NULL value only when the serial could not + * be retrieved by the standard 'libusb_get_string_descriptor_ascii' */ +typedef char * (*adapter_get_alternate_serial_fn)(libusb_device_handle *device, + struct libusb_device_descriptor *dev_desc); + int jtag_libusb_open(const uint16_t vids[], const uint16_t pids[], const char *serial, - struct libusb_device_handle **out); + struct libusb_device_handle **out, + adapter_get_alternate_serial_fn adapter_get_alternate_serial); 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, diff --git a/src/jtag/drivers/opendous.c b/src/jtag/drivers/opendous.c index 7298a2a10..6812ef649 100644 --- a/src/jtag/drivers/opendous.c +++ b/src/jtag/drivers/opendous.c @@ -715,7 +715,7 @@ struct opendous_jtag *opendous_usb_open(void) struct opendous_jtag *result; struct libusb_device_handle *devh; - if (jtag_libusb_open(opendous_probe->VID, opendous_probe->PID, NULL, &devh) != ERROR_OK) + if (jtag_libusb_open(opendous_probe->VID, opendous_probe->PID, NULL, &devh, NULL) != ERROR_OK) return NULL; jtag_libusb_set_configuration(devh, 0); diff --git a/src/jtag/drivers/openjtag.c b/src/jtag/drivers/openjtag.c index 6131df914..7eab5c130 100644 --- a/src/jtag/drivers/openjtag.c +++ b/src/jtag/drivers/openjtag.c @@ -449,7 +449,7 @@ static int openjtag_init_cy7c65215(void) int ret; usbh = NULL; - ret = jtag_libusb_open(cy7c65215_vids, cy7c65215_pids, NULL, &usbh); + ret = jtag_libusb_open(cy7c65215_vids, cy7c65215_pids, NULL, &usbh, NULL); if (ret != ERROR_OK) { LOG_ERROR("unable to open cy7c65215 device"); goto err; diff --git a/src/jtag/drivers/osbdm.c b/src/jtag/drivers/osbdm.c index aea126d0d..dc236660e 100644 --- a/src/jtag/drivers/osbdm.c +++ b/src/jtag/drivers/osbdm.c @@ -374,7 +374,7 @@ static int osbdm_flush(struct osbdm *osbdm, struct queue *queue) static int osbdm_open(struct osbdm *osbdm) { (void)memset(osbdm, 0, sizeof(*osbdm)); - if (jtag_libusb_open(osbdm_vid, osbdm_pid, NULL, &osbdm->devh) != ERROR_OK) + if (jtag_libusb_open(osbdm_vid, osbdm_pid, NULL, &osbdm->devh, NULL) != ERROR_OK) return ERROR_FAIL; if (libusb_claim_interface(osbdm->devh, 0) != ERROR_OK) diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index ca7a4df4e..d8d8d67e3 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -2778,7 +2778,8 @@ static int stlink_usb_open(struct hl_interface_param_s *param, void **fd) in order to become operational. */ do { - if (jtag_libusb_open(param->vid, param->pid, param->serial, &h->fd) != ERROR_OK) { + if (jtag_libusb_open(param->vid, param->pid, param->serial, + &h->fd, NULL) != ERROR_OK) { LOG_ERROR("open failed"); goto error_open; } diff --git a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c b/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c index 4f7ee6300..b406c0321 100644 --- a/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c +++ b/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c @@ -195,7 +195,7 @@ static int ublast2_libusb_init(struct ublast_lowlevel *low) bool renumeration = false; int ret; - if (jtag_libusb_open(vids, pids, NULL, &temp) == ERROR_OK) { + if (jtag_libusb_open(vids, pids, NULL, &temp, NULL) == ERROR_OK) { LOG_INFO("Altera USB-Blaster II (uninitialized) found"); LOG_INFO("Loading firmware..."); ret = load_usb_blaster_firmware(temp, low); @@ -209,13 +209,15 @@ static int ublast2_libusb_init(struct ublast_lowlevel *low) const uint16_t pids_renum[] = { low->ublast_pid, 0 }; if (renumeration == false) { - if (jtag_libusb_open(vids_renum, pids_renum, NULL, &low->libusb_dev) != ERROR_OK) { + if (jtag_libusb_open(vids_renum, pids_renum, NULL, + &low->libusb_dev, NULL) != ERROR_OK) { LOG_ERROR("Altera USB-Blaster II not found"); return ERROR_FAIL; } } else { int retry = 10; - while (jtag_libusb_open(vids_renum, pids_renum, NULL, &low->libusb_dev) != ERROR_OK && retry--) { + while (jtag_libusb_open(vids_renum, pids_renum, NULL, + &low->libusb_dev, NULL) != ERROR_OK && retry--) { usleep(1000000); LOG_INFO("Waiting for renumerate..."); } ----------------------------------------------------------------------- Summary of changes: src/jtag/aice/aice_usb.c | 4 +- src/jtag/drivers/ft232r.c | 2 +- src/jtag/drivers/kitprog.c | 2 +- src/jtag/drivers/libusb_helper.c | 39 ++++++++-- src/jtag/drivers/libusb_helper.h | 8 ++- src/jtag/drivers/opendous.c | 2 +- src/jtag/drivers/openjtag.c | 2 +- src/jtag/drivers/osbdm.c | 2 +- src/jtag/drivers/stlink_usb.c | 84 +++++++++++++++++++++- .../drivers/usb_blaster/ublast2_access_libusb.c | 8 ++- 10 files changed, 137 insertions(+), 16 deletions(-) hooks/post-receive -- Main OpenOCD repository |