From: Andreas Fritiofson Date: Sun, 14 Aug 2016 13:15:27 +0000 (+0200) Subject: ftdi: don't wait forever if we fail X-Git-Tag: v0.10.0-rc1~98 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=db6c6f5da4deaffc548122703e6951d0b1710603;p=openocd 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 Signed-off-by: Andreas Fritiofson Reviewed-on: http://openocd.zylin.com/3419 Reviewed-by: Andreas Färber Tested-by: jenkins --- 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;