aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPhilip Craig <phil@blackmoth.com.au>2013-06-17 13:56:33 +1000
committerSpencer Oliver <spen@spen-soft.co.uk>2013-09-25 15:28:07 +0000
commitff120440d66962b33fc84b2363d2197172fd2a6e (patch)
tree484a02b5e150f56de00af3c73d7037f724b354f3 /src
parent322f7dcceab2b1a7363c722d80571a5fd8637328 (diff)
jlink: improve USB read during jlink_tap_execute
Previously, when doing EMU_CMD_HW_JTAG3 commands we would do two reads, one to read the data, and one to read the result. However, we can just do a single larger read instead. The motivation for this change is a weird problem. If I run the Segger software before running OpenOCD, then the first read always fails: Error: usb_bulk_read failed (requested=1, result=0) Error: jlink_tap_execute, wrong result -107 (expected 1) Sniffing the USB traffic shows that the J-Link is returning an overflow error, meaning it is expecting to return the full result in a single read. Change-Id: I75e020d3b3732c9a74ee3d31838fdf17a7fac24c Signed-off-by: Philip Craig <phil@blackmoth.com.au> Reviewed-on: http://openocd.zylin.com/1447 Tested-by: jenkins Reviewed-by: Xiaofan <xiaofanc@gmail.com> Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
Diffstat (limited to 'src')
-rw-r--r--src/jtag/drivers/jlink.c69
1 files changed, 14 insertions, 55 deletions
diff --git a/src/jtag/drivers/jlink.c b/src/jtag/drivers/jlink.c
index edf97257..ae80eb89 100644
--- a/src/jtag/drivers/jlink.c
+++ b/src/jtag/drivers/jlink.c
@@ -64,14 +64,12 @@ static unsigned int jlink_hw_jtag_version = 2;
/*#define JLINK_TAP_BUFFER_SIZE 256*/
/*#define JLINK_TAP_BUFFER_SIZE 384*/
-#define JLINK_IN_BUFFER_SIZE 2048
+#define JLINK_IN_BUFFER_SIZE (2048 + 1)
#define JLINK_OUT_BUFFER_SIZE (2*2048 + 4)
-#define JLINK_EMU_RESULT_BUFFER_SIZE 64
/* Global USB buffers */
static uint8_t usb_in_buffer[JLINK_IN_BUFFER_SIZE];
static uint8_t usb_out_buffer[JLINK_OUT_BUFFER_SIZE];
-static uint8_t usb_emu_result_buffer[JLINK_EMU_RESULT_BUFFER_SIZE];
/* Constants for JLink command */
#define EMU_CMD_VERSION 0x01
@@ -231,7 +229,6 @@ static int jlink_usb_message(struct jlink *jlink, int out_length, int in_length)
static int jlink_usb_io(struct jlink *jlink, int out_length, int in_length);
static int jlink_usb_write(struct jlink *jlink, int out_length);
static int jlink_usb_read(struct jlink *jlink, int expected_size);
-static int jlink_usb_read_emu_result(struct jlink *jlink);
/* helper functions */
static int jlink_get_version_info(void);
@@ -1421,10 +1418,17 @@ static int jlink_tap_execute(void)
jlink_last_state = jtag_debug_state_machine(tms_buffer, tdi_buffer,
tap_length, jlink_last_state);
- result = jlink_usb_message(jlink_handle, 4 + 2 * byte_length, byte_length);
- if (result != byte_length) {
- LOG_ERROR("jlink_tap_execute, wrong result %d (expected %d)",
- result, byte_length);
+ result = jlink_usb_message(jlink_handle, 4 + 2 * byte_length,
+ use_jtag3 ? byte_length + 1 : byte_length);
+ if (result != ERROR_OK) {
+ LOG_ERROR("jlink_tap_execute failed USB io (%d)", result);
+ jlink_tap_init();
+ return ERROR_JTAG_QUEUE_FAILED;
+ }
+
+ result = use_jtag3 ? usb_in_buffer[byte_length] : 0;
+ if (result != 0) {
+ LOG_ERROR("jlink_tap_execute failed, result %d", result);
jlink_tap_init();
return ERROR_JTAG_QUEUE_FAILED;
}
@@ -1539,44 +1543,12 @@ static int jlink_usb_message(struct jlink *jlink, int out_length, int in_length)
}
result = jlink_usb_read(jlink, in_length);
- if ((result != in_length) && (result != (in_length + 1))) {
+ if (result != in_length) {
LOG_ERROR("usb_bulk_read failed (requested=%d, result=%d)",
in_length, result);
return ERROR_JTAG_DEVICE_ERROR;
}
-
- if (jlink_hw_jtag_version < 3)
- return result;
-
- int result2 = ERROR_OK;
- if (result == in_length) {
- /* Must read the result from the EMU too */
- result2 = jlink_usb_read_emu_result(jlink);
- if (1 != result2) {
- LOG_ERROR("jlink_usb_read_emu_result retried requested = 1, "
- "result=%d, in_length=%i", result2, in_length);
- /* Try again once, should only happen if (in_length%64 == 0) */
- result2 = jlink_usb_read_emu_result(jlink);
- if (1 != result2) {
- LOG_ERROR("jlink_usb_read_emu_result failed "
- "(requested = 1, result=%d)", result2);
- return ERROR_JTAG_DEVICE_ERROR;
- }
- }
-
- /* Check the result itself */
- result2 = usb_emu_result_buffer[0];
- } else {
- /* Save the result, then remove it from return value */
- result2 = usb_in_buffer[result--];
- }
-
- if (result2) {
- LOG_ERROR("jlink_usb_message failed with result=%d)", result2);
- return ERROR_JTAG_DEVICE_ERROR;
- }
-
- return result;
+ return ERROR_OK;
}
/* calls the given usb_bulk_* function, allowing for the data to
@@ -1652,19 +1624,6 @@ static int jlink_usb_read(struct jlink *jlink, int expected_size)
return result;
}
-/* Read the result from the previous EMU cmd into result_buffer. */
-static int jlink_usb_read_emu_result(struct jlink *jlink)
-{
- int result = usb_bulk_read_ex(jlink->usb_handle, jlink_read_ep,
- (char *)usb_emu_result_buffer, 1 /* JLINK_EMU_RESULT_BUFFER_SIZE */,
- JLINK_USB_TIMEOUT);
-
- DEBUG_JTAG_IO("jlink_usb_read_result, result = %d", result);
-
- jlink_debug_buffer(usb_emu_result_buffer, result);
- return result;
-}
-
/*
* Send a message and receive the reply - simple messages.
*