From: Tomas Vanek Date: Wed, 21 Feb 2018 21:19:58 +0000 (+0100) Subject: drivers/kitprog: workaround KitProg firmware bug of missing ZLP X-Git-Tag: v0.11.0-rc1~1149 X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=commitdiff_plain;h=7829bb701f1d9b294c627142911529ca34a1120b drivers/kitprog: workaround KitProg firmware bug of missing ZLP KitProg firmware does not send a zero length packet at the end of the bulk-in transmission of a length divisible by a bulk packet size. This is inconsistent with the USB specification and results in jtag_libusb_bulk_read() waits forever when a transmission of specific size is received. Limit bulk read size to expected number of bytes for problematic tranfer sizes. Use 1 second timeout as the last resort. Change-Id: Ice80306424afd76e9fbc6851911ffd5109c84501 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/4426 Tested-by: jenkins Reviewed-by: Bohdan Tymkiv --- diff --git a/src/jtag/drivers/kitprog.c b/src/jtag/drivers/kitprog.c index db5b62e2e5..522eb17bb7 100644 --- a/src/jtag/drivers/kitprog.c +++ b/src/jtag/drivers/kitprog.c @@ -741,12 +741,22 @@ static int kitprog_swd_run_queue(void) break; } - /* We use the maximum buffer size here because the KitProg sometimes - * doesn't like bulk reads of fewer than 62 bytes. (?!?!) + /* KitProg firmware does not send a zero length packet + * after the bulk-in transmission of a length divisible by bulk packet + * size (64 bytes) as required by the USB specification. + * Therefore libusb would wait for continuation of transmission. + * Workaround: Limit bulk read size to expected number of bytes + * for problematic tranfer sizes. Otherwise use the maximum buffer + * size here because the KitProg sometimes doesn't like bulk reads + * of fewer than 62 bytes. (?!?!) */ + size_t read_count_workaround = SWD_MAX_BUFFER_LENGTH; + if (read_count % 64 == 0) + read_count_workaround = read_count; + ret = jtag_libusb_bulk_read(kitprog_handle->usb_handle, BULK_EP_IN | LIBUSB_ENDPOINT_IN, (char *)buffer, - SWD_MAX_BUFFER_LENGTH, 0); + read_count_workaround, 1000); if (ret > 0) { /* Handle garbage data by offsetting the initial read index */ if ((unsigned int)ret > read_count)