aboutsummaryrefslogtreecommitdiff
path: root/src/jtag/aice
diff options
context:
space:
mode:
authorOleksij Rempel <o.rempel@pengutronix.de>2018-07-05 13:42:14 +0200
committerOleksij Rempel <linux@rempel-privat.de>2020-01-22 05:33:31 +0000
commitd612baacaa3fef549c446053089867d7b134ccfd (patch)
treeef772f2e9454d1330b1429a9826993f5f0339782 /src/jtag/aice
parentf98099507f509db9a18c70365490a6b9f67108db (diff)
downloadriscv-openocd-d612baacaa3fef549c446053089867d7b134ccfd.zip
riscv-openocd-d612baacaa3fef549c446053089867d7b134ccfd.tar.gz
riscv-openocd-d612baacaa3fef549c446053089867d7b134ccfd.tar.bz2
jtag_libusb_bulk_read|write: return error code instead of size
A USB bulk write/read operation may fail with different errors: LIBUSB_ERROR_TIMEOUT if the transfer timed out (and populates transferred) LIBUSB_ERROR_PIPE if the endpoint halted LIBUSB_ERROR_OVERFLOW if the device offered more data, see Packets and overflows LIBUSB_ERROR_NO_DEVICE if the device has been disconnected another LIBUSB_ERROR code on other failures Current OpenOCD code is using the transfer size based error detection. Which may not always work. For example for LIBUSB_ERROR_OVERFLOW as libusb documentation says: "Problems may occur if the device attempts to send more data than can fit in the buffer. libusb reports LIBUSB_TRANSFER_OVERFLOW for this condition but other behaviour is largely undefined: actual_length may or may not be accurate, the chunk of data that can fit in the buffer (before overflow) may or may not have been transferred." This patch is refactoring code to use actual error return value for error detection instead of size. Change-Id: Iec0798438ca7b5c76e2e2912af21d9aa76ee0217 Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de> Reviewed-on: http://openocd.zylin.com/4590 Tested-by: jenkins Reviewed-by: Oleksij Rempel <linux@rempel-privat.de>
Diffstat (limited to 'src/jtag/aice')
-rw-r--r--src/jtag/aice/aice_usb.c38
1 files changed, 25 insertions, 13 deletions
diff --git a/src/jtag/aice/aice_usb.c b/src/jtag/aice/aice_usb.c
index 324ec7c..9e47413 100644
--- a/src/jtag/aice/aice_usb.c
+++ b/src/jtag/aice/aice_usb.c
@@ -349,41 +349,53 @@ static void aice_unpack_dthmb(uint8_t *cmd_ack_code, uint8_t *target_id,
/* calls the given usb_bulk_* function, allowing for the data to
* trickle in with some timeouts */
static int usb_bulk_with_retries(
- int (*f)(jtag_libusb_device_handle *, int, char *, int, int),
+ int (*f)(jtag_libusb_device_handle *, int, char *, int, int, int *),
jtag_libusb_device_handle *dev, int ep,
- char *bytes, int size, int timeout)
+ char *bytes, int size, int timeout, int *transferred)
{
int tries = 3, count = 0;
while (tries && (count < size)) {
- int result = f(dev, ep, bytes + count, size - count, timeout);
- if (result > 0)
+ int result, ret;
+
+ ret = f(dev, ep, bytes + count, size - count, timeout, &result);
+ if (ERROR_OK == ret)
count += result;
- else if ((-ETIMEDOUT != result) || !--tries)
- return result;
+ else if ((ERROR_TIMEOUT_REACHED != ret) || !--tries)
+ return ret;
}
- return count;
+
+ *transferred = count;
+ return ERROR_OK;
}
static int wrap_usb_bulk_write(jtag_libusb_device_handle *dev, int ep,
- char *buff, int size, int timeout)
+ char *buff, int size, int timeout, int *transferred)
{
+
/* usb_bulk_write() takes const char *buff */
- return jtag_libusb_bulk_write(dev, ep, buff, size, timeout);
+ jtag_libusb_bulk_write(dev, ep, buff, size, timeout, transferred);
+
+ return 0;
}
static inline int usb_bulk_write_ex(jtag_libusb_device_handle *dev, int ep,
char *bytes, int size, int timeout)
{
- return usb_bulk_with_retries(&wrap_usb_bulk_write,
- dev, ep, bytes, size, timeout);
+ int tr = 0;
+
+ usb_bulk_with_retries(&wrap_usb_bulk_write,
+ dev, ep, bytes, size, timeout, &tr);
+ return tr;
}
static inline int usb_bulk_read_ex(jtag_libusb_device_handle *dev, int ep,
char *bytes, int size, int timeout)
{
- return usb_bulk_with_retries(&jtag_libusb_bulk_read,
- dev, ep, bytes, size, timeout);
+ int tr = 0;
+ usb_bulk_with_retries(&jtag_libusb_bulk_read,
+ dev, ep, bytes, size, timeout, &tr);
+ return tr;
}
/* Write data from out_buffer to USB. */