aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Fritiofson <andreas.fritiofson@gmail.com>2016-08-14 15:15:27 +0200
committerSpencer Oliver <spen@spen-soft.co.uk>2016-10-04 11:51:31 +0100
commitdb6c6f5da4deaffc548122703e6951d0b1710603 (patch)
tree2462093d33964a6a17127324b3abee21f49a95fe
parent5fd5699859db4be2dadef69c85adbb0acda36e84 (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.c24
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;