From 4315ede4d1a843ea5c09ea9146b57da4f984f761 Mon Sep 17 00:00:00 2001 From: ALTracer Date: Sun, 5 Nov 2023 06:49:42 +0300 Subject: [PATCH] hosted/jlink: Expect the last byte for JTAG3 result in a single packet * Asking for 1 byte less raises a libusb OVERFLOW error when using JLink V8 and newer with BMDA on Linux hosts after the proprietary software stack touches the adapter (but not before). * libusb docs recommend receiving into a bigger buffer (1028=512*2+4) and checking whether all of expected data got indeed received. * For firmwares which send that transaction-error byte in a separate packet, keep the second read call (V5 ones do this regardless). --- src/platforms/hosted/jlink.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/platforms/hosted/jlink.c b/src/platforms/hosted/jlink.c index 3ff5cb864c1..0e624b4626d 100644 --- a/src/platforms/hosted/jlink.c +++ b/src/platforms/hosted/jlink.c @@ -137,10 +137,17 @@ bool jlink_transfer(const uint16_t clock_cycles, const uint8_t *const tms, const /* Copy in the TDI values to transmit (if present) */ if (tdi) memcpy(buffer + 4U + byte_count, tdi, byte_count); - /* Send the resulting transaction and try to read back the response data */ - if (bmda_usb_transfer(bmda_probe_info.usb_link, buffer, sizeof(*header) + (byte_count * 2U), buffer, byte_count, - JLINK_USB_TIMEOUT) < 0 || - /* Try to read back the transaction return code */ + /* + * Send the resulting transaction and try to read back the response data (including the response code first try), + * because V8 and newer adapters, once touched by libjlinkarm.so (via Commander or else) on Linux hosts, + * start returning the transaction status code *in the same packet*. + */ + const ssize_t bytes_received = bmda_usb_transfer(bmda_probe_info.usb_link, buffer, + sizeof(*header) + (byte_count * 2U), buffer, byte_count + 1U, JLINK_USB_TIMEOUT); + if (bytes_received < 0) + return false; + /* If the first read didn't return the transaction return code, try to read it back separately */ + if (bytes_received < (ssize_t)byte_count + 1 && bmda_usb_transfer(bmda_probe_info.usb_link, NULL, 0, buffer + byte_count, 1U, JLINK_USB_TIMEOUT) < 0) return false; /* Copy out the response into the TDO buffer (if present) */