jtag/mpsse: mpsse_flush should not treat LIBUSB_ERROR_INTERRUPTED as an error

LIBUSB_ERROR_INTERRUPTED can happen when (among other things) OpenOCD
process receives a signal like SIGHUP or SIGINT during a call to libusb.
Such situations are expected and should not be treated as an error - the
affected request should just be restarted.

Without this patch applied if a signal arrives during FTDI initialization
procedure we can easily end up (if JTAG speed is low) in situations like
https://review.openocd.org/c/openocd/+/4767. This happens because
fpsse_flush fails due to LIBUSB_ERROR_INTERRUPTED .

It should be noted that the current usage of mpsse_flush should be
revised since it seems that we don't always process error codes returned
by the function.

Change-Id: Ifa063ce828068f8d0371e1c2a864bb6174649848
Signed-off-by: Parshintsev Anatoly <anatoly.parshintsev@syntacore.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/7769
Reviewed-by: Tim Newsome <tim@sifive.com>
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
Tested-by: jenkins
This commit is contained in:
Parshintsev Anatoly 2023-07-10 16:30:07 +03:00 committed by Antonio Borneo
parent 3b5ef1726a
commit 50be4bd267
1 changed files with 9 additions and 14 deletions

View File

@ -880,20 +880,6 @@ int mpsse_flush(struct mpsse_ctx *ctx)
retval = libusb_handle_events_timeout_completed(ctx->usb_ctx, &timeout_usb, NULL);
keep_alive();
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) {
retval = libusb_handle_events_timeout_completed(ctx->usb_ctx,
&timeout_usb, NULL);
if (retval != LIBUSB_SUCCESS)
break;
}
}
int64_t now = timeval_ms();
if (now - start > warn_after) {
@ -901,6 +887,15 @@ int mpsse_flush(struct mpsse_ctx *ctx)
"ms.", now - start);
warn_after *= 2;
}
if (retval == LIBUSB_ERROR_INTERRUPTED)
continue;
if (retval != LIBUSB_SUCCESS) {
libusb_cancel_transfer(write_transfer);
if (read_transfer)
libusb_cancel_transfer(read_transfer);
}
}
error_check: