diff options
author | Andreas Fritiofson <andreas.fritiofson@gmail.com> | 2016-08-14 15:15:27 +0200 |
---|---|---|
committer | Spencer Oliver <spen@spen-soft.co.uk> | 2016-10-04 11:51:31 +0100 |
commit | db6c6f5da4deaffc548122703e6951d0b1710603 (patch) | |
tree | 2462093d33964a6a17127324b3abee21f49a95fe | |
parent | 5fd5699859db4be2dadef69c85adbb0acda36e84 (diff) |
ftdi: don't wait forever if we fail
Currently if ftdi device is removed, OpenOCD will stall forever.
Only kill -9 will help in this case.
This patch makes use of libusb timeout functions and
trying to break out of while loop if some error is detected.
[andreas.fritiofson@gmail.com]: Add missing retval check
Change-Id: I97506190e376026705f14ef9fe37dc811b99b3ac
Signed-off-by: Oleksij Rempel <linux@rempel-privat.de>
Signed-off-by: Andreas Fritiofson <andreas.fritiofson@gmail.com>
Reviewed-on: http://openocd.zylin.com/3419
Reviewed-by: Andreas Färber <afaerber@suse.de>
Tested-by: jenkins
-rw-r--r-- | src/jtag/drivers/mpsse.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/src/jtag/drivers/mpsse.c b/src/jtag/drivers/mpsse.c index 0ef88ba2..3c1c97cd 100644 --- a/src/jtag/drivers/mpsse.c +++ b/src/jtag/drivers/mpsse.c @@ -872,6 +872,8 @@ int mpsse_flush(struct mpsse_ctx *ctx) libusb_fill_bulk_transfer(write_transfer, ctx->usb_dev, ctx->out_ep, ctx->write_buffer, ctx->write_count, write_cb, &write_result, ctx->usb_write_timeout); retval = libusb_submit_transfer(write_transfer); + if (retval != LIBUSB_SUCCESS) + goto error_check; if (ctx->read_count) { read_transfer = libusb_alloc_transfer(0); @@ -879,22 +881,36 @@ int mpsse_flush(struct mpsse_ctx *ctx) ctx->read_chunk_size, read_cb, &read_result, ctx->usb_read_timeout); retval = libusb_submit_transfer(read_transfer); + if (retval != LIBUSB_SUCCESS) + goto error_check; } /* Polling loop, more or less taken from libftdi */ while (!write_result.done || !read_result.done) { - retval = libusb_handle_events(ctx->usb_ctx); + struct timeval timeout_usb; + + timeout_usb.tv_sec = 1; + timeout_usb.tv_usec = 0; + + retval = libusb_handle_events_timeout_completed(ctx->usb_ctx, &timeout_usb, NULL); keep_alive(); - if (retval != LIBUSB_SUCCESS && retval != LIBUSB_ERROR_INTERRUPTED) { + if (retval == LIBUSB_ERROR_NO_DEVICE || retval == LIBUSB_ERROR_INTERRUPTED) + break; + + if (retval != LIBUSB_SUCCESS) { libusb_cancel_transfer(write_transfer); if (read_transfer) libusb_cancel_transfer(read_transfer); - while (!write_result.done || !read_result.done) - if (libusb_handle_events(ctx->usb_ctx) != LIBUSB_SUCCESS) + while (!write_result.done || !read_result.done) { + retval = libusb_handle_events_timeout_completed(ctx->usb_ctx, + &timeout_usb, NULL); + if (retval != LIBUSB_SUCCESS) break; + } } } +error_check: if (retval != LIBUSB_SUCCESS) { LOG_ERROR("libusb_handle_events() failed with %s", libusb_error_name(retval)); retval = ERROR_FAIL; |