Fix: Error while reading from USB endpoint
[fw/openocd] / src / jtag / drivers / jlink.c
index adaa64090353e53d1ea7aceffd46275d2029e550..33b15d29525b28cb352ddd89d8dcb48748644eab 100644 (file)
 
 #include <jtag/interface.h>
 #include <jtag/commands.h>
-#include "usb_common.h"
+#include "libusb_common.h"
 
 /* See Segger's public documentation:
- *     Reference manual for J-Link USB Protocol
- *     Document RM08001-R6 Date: June 16, 2009
- *      (Or newer, with some SWD information).
-http://www.segger.com/cms/admin/uploads/productDocs/RM08001_JLinkUSBProtocol.pdf
+ * Reference manual for J-Link USB Protocol
+ * Document RM08001-R6 Date: June 16, 2009
+ * (Or newer, with some SWD information).
+ * http://www.segger.com/cms/admin/uploads/productDocs/RM08001_JLinkUSBProtocol.pdf
  */
 
 /*
@@ -46,6 +45,7 @@ http://www.segger.com/cms/admin/uploads/productDocs/RM08001_JLinkUSBProtocol.pdf
  *
  * pid = ( usb_address > 0x4) ? 0x0101 : (0x101 + usb_address)
  */
+
 #define VID 0x1366, 0x1366, 0x1366, 0x1366
 #define PID 0x0101, 0x0102, 0x0103, 0x0104
 
@@ -56,16 +56,16 @@ static unsigned int jlink_write_ep = JLINK_WRITE_ENDPOINT;
 static unsigned int jlink_read_ep = JLINK_READ_ENDPOINT;
 static unsigned int jlink_hw_jtag_version = 2;
 
-#define JLINK_USB_TIMEOUT              1000
+#define JLINK_USB_TIMEOUT 1000
 
-// See Section 3.3.2 of the Segger JLink USB protocol manual
+/* See Section 3.3.2 of the Segger JLink USB protocol manual */
 /* 2048 is the max value we can use here */
 #define JLINK_TAP_BUFFER_SIZE 2048
-//#define JLINK_TAP_BUFFER_SIZE 256
-//#define JLINK_TAP_BUFFER_SIZE 384
+/*#define JLINK_TAP_BUFFER_SIZE 256*/
+/*#define JLINK_TAP_BUFFER_SIZE 384*/
 
 #define JLINK_IN_BUFFER_SIZE                   2048
-#define JLINK_OUT_BUFFER_SIZE                  2*2048 + 4
+#define JLINK_OUT_BUFFER_SIZE                  (2*2048 + 4)
 #define JLINK_EMU_RESULT_BUFFER_SIZE   64
 
 /* Global USB buffers */
@@ -75,22 +75,45 @@ static uint8_t usb_emu_result_buffer[JLINK_EMU_RESULT_BUFFER_SIZE];
 
 /* Constants for JLink command */
 #define EMU_CMD_VERSION                        0x01
+#define EMU_CMD_RESET_TRST             0x02
+#define EMU_CMD_RESET_TARGET   0x03
 #define EMU_CMD_SET_SPEED              0x05
 #define EMU_CMD_GET_STATE              0x07
+#define EMU_CMD_SET_KS_POWER   0x08
+#define EMU_CMD_GET_SPEEDS             0xc0
+#define EMU_CMD_GET_HW_INFO            0xc1
+#define EMU_CMD_GET_COUNTERS   0xc2
+#define EMU_CMD_SELECT_IF              0xc7
 #define EMU_CMD_HW_CLOCK               0xc8
 #define EMU_CMD_HW_TMS0                        0xc9
 #define EMU_CMD_HW_TMS1                        0xca
+#define EMU_CMD_HW_DATA0               0xcb
+#define EMU_CMD_HW_DATA1               0xcc
+#define EMU_CMD_HW_JTAG                        0xcd
 #define EMU_CMD_HW_JTAG2               0xce
 #define EMU_CMD_HW_JTAG3               0xcf
+#define EMU_CMD_HW_RELEASE_RESET_STOP_EX 0xd0
+#define EMU_CMD_HW_RELEASE_RESET_STOP_TIMED 0xd1
 #define EMU_CMD_GET_MAX_MEM_BLOCK      0xd4
+#define EMU_CMD_HW_JTAG_WRITE          0xd5
+#define EMU_CMD_HW_JTAG_GET_RESULT     0xd6
 #define EMU_CMD_HW_RESET0              0xdc
 #define EMU_CMD_HW_RESET1              0xdd
 #define EMU_CMD_HW_TRST0               0xde
 #define EMU_CMD_HW_TRST1               0xdf
 #define EMU_CMD_GET_CAPS               0xe8
+#define EMU_CMD_GET_CPU_CAPS   0xe9
+#define EMU_CMD_EXEC_CPU_CMD   0xea
+#define EMU_CMD_GET_CAPS_EX            0xed
 #define EMU_CMD_GET_HW_VERSION 0xf0
+#define EMU_CMD_WRITE_DCC              0xf1
 #define EMU_CMD_READ_CONFIG            0xf2
 #define EMU_CMD_WRITE_CONFIG           0xf3
+#define EMU_CMD_WRITE_MEM                      0xf4
+#define EMU_CMD_READ_MEM                       0xf5
+#define EMU_CMD_MEASURE_RTCK_REACT     0xf6
+#define EMU_CMD_WRITE_MEM_ARM79                0xf7
+#define EMU_CMD_READ_MEM_ARM79         0xf8
 
 /* bits return from EMU_CMD_GET_CAPS */
 #define EMU_CAP_RESERVED_1             0
@@ -199,12 +222,13 @@ static void jlink_tap_append_scan(int length, uint8_t *buffer,
 
 /* Jlink lowlevel functions */
 struct jlink {
-       struct usb_dev_handle* usb_handle;
+       struct jtag_libusb_device_handle *usb_handle;
 };
 
 static struct jlink *jlink_usb_open(void);
 static void jlink_usb_close(struct jlink *jlink);
 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);
@@ -222,7 +246,7 @@ static inline void jlink_debug_buffer(uint8_t *buffer, int length)
 
 static enum tap_state jlink_last_state = TAP_RESET;
 
-static struct jlinkjlink_handle;
+static struct jlink *jlink_handle;
 
 /* pid could be specified at runtime */
 static uint16_t vids[] = { VID, 0 };
@@ -320,17 +344,28 @@ static void jlink_execute_sleep(struct jtag_command *cmd)
 
 static void jlink_execute_command(struct jtag_command *cmd)
 {
-       switch (cmd->type)
-       {
-       case JTAG_RUNTEST:   jlink_execute_runtest(cmd); break;
-       case JTAG_TLR_RESET: jlink_execute_statemove(cmd); break;
-       case JTAG_PATHMOVE:  jlink_execute_pathmove(cmd); break;
-       case JTAG_SCAN:      jlink_execute_scan(cmd); break;
-       case JTAG_RESET:     jlink_execute_reset(cmd); break;
-       case JTAG_SLEEP:     jlink_execute_sleep(cmd); break;
-       default:
-               LOG_ERROR("BUG: unknown JTAG command type encountered");
-               exit(-1);
+       switch (cmd->type) {
+               case JTAG_RUNTEST:
+                       jlink_execute_runtest(cmd);
+                       break;
+               case JTAG_TLR_RESET:
+                       jlink_execute_statemove(cmd);
+                       break;
+               case JTAG_PATHMOVE:
+                       jlink_execute_pathmove(cmd);
+                       break;
+               case JTAG_SCAN:
+                       jlink_execute_scan(cmd);
+                       break;
+               case JTAG_RESET:
+                       jlink_execute_reset(cmd);
+                       break;
+               case JTAG_SLEEP:
+                       jlink_execute_sleep(cmd);
+                       break;
+               default:
+                       LOG_ERROR("BUG: unknown JTAG command type encountered");
+                       exit(-1);
        }
 }
 
@@ -338,8 +373,7 @@ static int jlink_execute_queue(void)
 {
        struct jtag_command *cmd = jtag_command_queue;
 
-       while (cmd != NULL)
-       {
+       while (cmd != NULL) {
                jlink_execute_command(cmd);
                cmd = cmd->next;
        }
@@ -352,8 +386,7 @@ static int jlink_speed(int speed)
 {
        int result;
 
-       if (speed > JLINK_MAX_SPEED)
-       {
+       if (speed > JLINK_MAX_SPEED) {
                LOG_INFO("reduce speed request: %dkHz to %dkHz maximum",
                                speed, JLINK_MAX_SPEED);
                speed = JLINK_MAX_SPEED;
@@ -368,8 +401,7 @@ static int jlink_speed(int speed)
        usb_out_buffer[2] = (speed >> 8) & 0xff;
 
        result = jlink_usb_write(jlink_handle, 3);
-       if (result != 3)
-       {
+       if (result != 3) {
                LOG_ERROR("J-Link setting speed failed (%d)", result);
                return ERROR_JTAG_DEVICE_ERROR;
        }
@@ -377,7 +409,7 @@ static int jlink_speed(int speed)
        return ERROR_OK;
 }
 
-static int jlink_speed_div(int speed, intkhz)
+static int jlink_speed_div(int speed, int *khz)
 {
        *khz = speed;
 
@@ -391,14 +423,74 @@ static int jlink_khz(int khz, int *jtag_speed)
        return ERROR_OK;
 }
 
+/*
+ * select transport interface
+ *
+ * @param      iface [0..31] currently: 0=JTAG, 1=SWD
+ * @returns    ERROR_OK or ERROR_ code
+ *
+ * @pre jlink_handle must be opened
+ * @pre function may be called only for devices, that have
+ *             EMU_CAP_SELECT_IF capability enabled
+ */
+static int jlink_select_interface(int iface)
+{
+       /* According to Segger's document RM08001-R7 Date: October 8, 2010,
+        * http://www.segger.com/admin/uploads/productDocs/RM08001_JLinkUSBProtocol.pdf
+        * section 5.5.3 EMU_CMD_SELECT_IF
+        * > SubCmd 1..31 to select interface (0..31)
+        *
+        * The table below states:
+        *  0 TIF_JTAG
+        *  1 TIF_SWD
+        *
+        * This obviosly means that to select TIF_JTAG one should write SubCmd = 1.
+        *
+        * In fact, JTAG interface operates when SubCmd=0
+        *
+        * It looks like a typo in documentation, because interfaces 0..31 could not
+        * be selected by 1..31 range command.
+        */
+       assert(iface >= 0 && iface < 32);
+       int result;
+
+       /* get available interfaces */
+       usb_out_buffer[0] = EMU_CMD_SELECT_IF;
+       usb_out_buffer[1] = 0xff;
+
+       result = jlink_usb_io(jlink_handle, 2, 4);
+       if (result != ERROR_OK) {
+               LOG_ERROR("J-Link query interface failed (%d)", result);
+               return ERROR_JTAG_DEVICE_ERROR;
+       }
+
+       uint32_t iface_mask = buf_get_u32(usb_in_buffer, 0, 32);
+
+       if (!(iface_mask & (1<<iface))) {
+               LOG_ERROR("J-Link requesting to select unsupported interface (%x)", iface_mask);
+               return ERROR_JTAG_DEVICE_ERROR;
+       }
+
+       /* Select interface */
+       usb_out_buffer[0] = EMU_CMD_SELECT_IF;
+       usb_out_buffer[1] = iface;
+
+       result = jlink_usb_io(jlink_handle, 2, 4);
+       if (result != ERROR_OK) {
+               LOG_ERROR("J-Link interface select failed (%d)", result);
+               return ERROR_JTAG_DEVICE_ERROR;
+       }
+
+       return ERROR_OK;
+}
+
 static int jlink_init(void)
 {
        int i;
 
        jlink_handle = jlink_usb_open();
 
-       if (jlink_handle == 0)
-       {
+       if (jlink_handle == 0) {
                LOG_ERROR("Cannot find jlink Interface! Please check "
                                "connection and permissions.");
                return ERROR_JTAG_INIT_FAILED;
@@ -428,12 +520,22 @@ static int jlink_init(void)
 
        jlink_hw_jtag_version = 2;
 
-       if (jlink_get_version_info() == ERROR_OK)
-       {
+       if (jlink_get_version_info() == ERROR_OK) {
                /* attempt to get status */
                jlink_get_status();
        }
 
+       /*
+        * Some versions of Segger's software do not select JTAG interface by default.
+        *
+        * Segger recommends to select interface necessarily as a part of init process,
+        * in case any previous session leaves improper interface selected.
+        *
+        * Until SWD implemented, select only JTAG interface here.
+        */
+       if (jlink_caps & (1<<EMU_CAP_SELECT_IF))
+               jlink_select_interface(0);
+
        LOG_INFO("J-Link JTAG Interface ready");
 
        jlink_reset(0, 0);
@@ -442,9 +544,8 @@ static int jlink_init(void)
 
        /* v5/6 jlink seems to have an issue if the first tap move
         * is not divisible by 8, so we send a TLR on first power up */
-       for (i = 0; i < 8; i++) {
+       for (i = 0; i < 8; i++)
                jlink_tap_append_step(1, 0);
-       }
        jlink_tap_execute();
 
        return ERROR_OK;
@@ -462,11 +563,8 @@ static int jlink_quit(void)
 static void jlink_end_state(tap_state_t state)
 {
        if (tap_is_state_stable(state))
-       {
                tap_set_end_state(state);
-       }
-       else
-       {
+       else {
                LOG_ERROR("BUG: %i is not a valid end state", state);
                exit(-1);
        }
@@ -480,8 +578,7 @@ static void jlink_state_move(void)
        uint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());
        uint8_t tms_scan_bits = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());
 
-       for (i = 0; i < tms_scan_bits; i++)
-       {
+       for (i = 0; i < tms_scan_bits; i++) {
                tms = (tms_scan >> i) & 1;
                jlink_tap_append_step(tms, 0);
        }
@@ -493,18 +590,12 @@ static void jlink_path_move(int num_states, tap_state_t *path)
 {
        int i;
 
-       for (i = 0; i < num_states; i++)
-       {
+       for (i = 0; i < num_states; i++) {
                if (path[i] == tap_state_transition(tap_get_state(), false))
-               {
                        jlink_tap_append_step(0, 0);
-               }
                else if (path[i] == tap_state_transition(tap_get_state(), true))
-               {
                        jlink_tap_append_step(1, 0);
-               }
-               else
-               {
+               else {
                        LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition",
                                        tap_state_name(tap_get_state()), tap_state_name(path[i]));
                        exit(-1);
@@ -522,28 +613,23 @@ static void jlink_runtest(int num_cycles)
 
        tap_state_t saved_end_state = tap_get_end_state();
 
-       jlink_tap_ensure_space(1,num_cycles + 16);
+       jlink_tap_ensure_space(1, num_cycles + 16);
 
        /* only do a state_move when we're not already in IDLE */
-       if (tap_get_state() != TAP_IDLE)
-       {
+       if (tap_get_state() != TAP_IDLE) {
                jlink_end_state(TAP_IDLE);
                jlink_state_move();
-//             num_cycles--;
+               /* num_cycles--; */
        }
 
        /* execute num_cycles */
        for (i = 0; i < num_cycles; i++)
-       {
                jlink_tap_append_step(0, 0);
-       }
 
        /* finish in end_state */
        jlink_end_state(saved_end_state);
        if (tap_get_state() != tap_get_end_state())
-       {
                jlink_state_move();
-       }
 }
 
 static void jlink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer,
@@ -573,9 +659,7 @@ static void jlink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer,
        tap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE);
 
        if (tap_get_state() != tap_get_end_state())
-       {
                jlink_state_move();
-       }
 }
 
 static void jlink_reset(int trst, int srst)
@@ -584,23 +668,16 @@ static void jlink_reset(int trst, int srst)
 
        /* Signals are active low */
        if (srst == 0)
-       {
                jlink_simple_command(EMU_CMD_HW_RESET1);
-       }
+
        if (srst == 1)
-       {
                jlink_simple_command(EMU_CMD_HW_RESET0);
-       }
 
        if (trst == 1)
-       {
                jlink_simple_command(EMU_CMD_HW_TRST0);
-       }
 
        if (trst == 0)
-       {
                jlink_simple_command(EMU_CMD_HW_TRST1);
-       }
 }
 
 static void jlink_simple_command(uint8_t command)
@@ -613,9 +690,7 @@ static void jlink_simple_command(uint8_t command)
        result = jlink_usb_write(jlink_handle, 1);
 
        if (result != 1)
-       {
                LOG_ERROR("J-Link command 0x%02x failed (%d)", command, result);
-       }
 }
 
 static int jlink_get_status(void)
@@ -625,8 +700,7 @@ static int jlink_get_status(void)
        jlink_simple_command(EMU_CMD_GET_STATE);
 
        result = jlink_usb_read(jlink_handle, 8);
-       if (result != 8)
-       {
+       if (result != 8) {
                LOG_ERROR("J-Link command EMU_CMD_GET_STATE failed (%d)", result);
                return ERROR_JTAG_DEVICE_ERROR;
        }
@@ -643,14 +717,13 @@ static int jlink_get_status(void)
        return ERROR_OK;
 }
 
-#define jlink_dump_printf(context, expr ...)   \
-       do {                                    \
-       if (context)                            \
-               command_print(context, expr);   \
-       else                                    \
-               LOG_INFO(expr);                 \
-       } while(0);
-
+#define jlink_dump_printf(context, expr ...) \
+       do { \
+               if (context) \
+                       command_print(context, expr); \
+                       else \
+                       LOG_INFO(expr); \
+       } while (0);
 
 static void jlink_caps_dump(struct command_context *ctx)
 {
@@ -713,8 +786,7 @@ static void jlink_config_dump(struct command_context *ctx, struct jlink_config *
        jlink_config_usb_address_dump(ctx, cfg);
        jlink_config_kickstart_dump(ctx, cfg);
 
-       if (jlink_hw_type == JLINK_HW_TYPE_JLINK_PRO)
-       {
+       if (jlink_hw_type == JLINK_HW_TYPE_JLINK_PRO) {
                jlink_config_ip_dump(ctx, cfg);
                jlink_config_mac_address_dump(ctx, cfg);
        }
@@ -725,23 +797,15 @@ static int jlink_get_config(struct jlink_config *cfg)
        int result;
        int size = sizeof(struct jlink_config);
 
-       jlink_simple_command(EMU_CMD_READ_CONFIG);
+       usb_out_buffer[0] = EMU_CMD_READ_CONFIG;
+       result = jlink_usb_io(jlink_handle, 1, size);
 
-       result = jlink_usb_read(jlink_handle, size);
-       if (size != result)
-       {
+       if (result != ERROR_OK) {
                LOG_ERROR("jlink_usb_read failed (requested=%d, result=%d)", size, result);
                return ERROR_FAIL;
        }
 
        memcpy(cfg, usb_in_buffer, size);
-
-       /*
-        * Section 4.2.4 IN-transaction
-        * read dummy 0-byte packet
-        */
-       jlink_usb_read(jlink_handle, 1);
-
        return ERROR_OK;
 }
 
@@ -755,8 +819,7 @@ static int jlink_set_config(struct jlink_config *cfg)
        memcpy(usb_out_buffer, cfg, size);
 
        result = jlink_usb_write(jlink_handle, size);
-       if (result != size)
-       {
+       if (result != size) {
                LOG_ERROR("jlink_usb_write failed (requested=%d, result=%d)", 256, result);
                return ERROR_FAIL;
        }
@@ -764,6 +827,40 @@ static int jlink_set_config(struct jlink_config *cfg)
        return ERROR_OK;
 }
 
+/*
+ * List of unsupported version string markers.
+ *
+ * The firmware versions does not correspond directly with
+ * "Software and documentation pack for Windows", it may be
+ * distinguished by the "compile" date in the information string.
+ *
+ * For example, version string is:
+ *   "J-Link ARM V8 compiled May  3 2012 18:36:22"
+ * Marker sould be:
+ *   "May  3 2012"
+ *
+ * The list must be terminated by NULL string.
+ */
+static const char * const unsupported_versions[] = {
+       "Jan 31 2011",
+       "JAN 31 2011",
+       NULL                    /* End of list */
+};
+
+static void jlink_check_supported(const char *str)
+{
+       const char * const *p = unsupported_versions;
+       while (*p) {
+               if (NULL != strstr(str, *p)) {
+                       LOG_WARNING(
+                       "Unsupported J-Link firmware version.\n"
+                       "       Please check http://www.segger.com/j-link-older-versions.html for updates");
+                       return;
+               }
+               p++;
+       }
+}
+
 static int jlink_get_version_info(void)
 {
        int result;
@@ -774,35 +871,32 @@ static int jlink_get_version_info(void)
        jlink_simple_command(EMU_CMD_VERSION);
 
        result = jlink_usb_read(jlink_handle, 2);
-       if (2 != result)
-       {
+       if (2 != result) {
                LOG_ERROR("J-Link command EMU_CMD_VERSION failed (%d)", result);
                return ERROR_JTAG_DEVICE_ERROR;
        }
 
        len = buf_get_u32(usb_in_buffer, 0, 16);
-       if (len > JLINK_IN_BUFFER_SIZE)
-       {
+       if (len > JLINK_IN_BUFFER_SIZE) {
                LOG_ERROR("J-Link command EMU_CMD_VERSION impossible return length 0x%0x", len);
                len = JLINK_IN_BUFFER_SIZE;
        }
 
        result = jlink_usb_read(jlink_handle, len);
-       if (result != len)
-       {
+       if (result != len) {
                LOG_ERROR("J-Link command EMU_CMD_VERSION failed (%d)", result);
                return ERROR_JTAG_DEVICE_ERROR;
        }
 
        usb_in_buffer[result] = 0;
        LOG_INFO("%s", (char *)usb_in_buffer);
+       jlink_check_supported((char *)usb_in_buffer);
 
        /* query hardware capabilities */
        jlink_simple_command(EMU_CMD_GET_CAPS);
 
        result = jlink_usb_read(jlink_handle, 4);
-       if (4 != result)
-       {
+       if (4 != result) {
                LOG_ERROR("J-Link command EMU_CMD_GET_CAPS failed (%d)", result);
                return ERROR_JTAG_DEVICE_ERROR;
        }
@@ -810,14 +904,12 @@ static int jlink_get_version_info(void)
        jlink_caps = buf_get_u32(usb_in_buffer, 0, 32);
        LOG_INFO("J-Link caps 0x%x", (unsigned)jlink_caps);
 
-       if (jlink_caps & (1 << EMU_CAP_GET_HW_VERSION))
-       {
+       if (jlink_caps & (1 << EMU_CAP_GET_HW_VERSION)) {
                /* query hardware version */
                jlink_simple_command(EMU_CMD_GET_HW_VERSION);
 
                result = jlink_usb_read(jlink_handle, 4);
-               if (4 != result)
-               {
+               if (4 != result) {
                        LOG_ERROR("J-Link command EMU_CMD_GET_HW_VERSION failed (%d)", result);
                        return ERROR_JTAG_DEVICE_ERROR;
                }
@@ -836,14 +928,12 @@ static int jlink_get_version_info(void)
                        LOG_INFO("J-Link hw type %s", jlink_hw_type_str[jlink_hw_type]);
        }
 
-       if (jlink_caps & (1 << EMU_CAP_GET_MAX_BLOCK_SIZE))
-       {
+       if (jlink_caps & (1 << EMU_CAP_GET_MAX_BLOCK_SIZE)) {
                /* query hardware maximum memory block */
                jlink_simple_command(EMU_CMD_GET_MAX_MEM_BLOCK);
 
                result = jlink_usb_read(jlink_handle, 4);
-               if (4 != result)
-               {
+               if (4 != result) {
                        LOG_ERROR("J-Link command EMU_CMD_GET_MAX_MEM_BLOCK failed (%d)", result);
                        return ERROR_JTAG_DEVICE_ERROR;
                }
@@ -852,8 +942,7 @@ static int jlink_get_version_info(void)
                LOG_INFO("J-Link max mem block %i", (int)jlink_max_size);
        }
 
-       if (jlink_caps & (1 << EMU_CAP_READ_CONFIG))
-       {
+       if (jlink_caps & (1 << EMU_CAP_READ_CONFIG)) {
                if (jlink_get_config(&jlink_cfg) != ERROR_OK)
                        return ERROR_JTAG_DEVICE_ERROR;
 
@@ -865,8 +954,7 @@ static int jlink_get_version_info(void)
 
 COMMAND_HANDLER(jlink_pid_command)
 {
-       if (CMD_ARGC != 1)
-       {
+       if (CMD_ARGC != 1) {
                LOG_ERROR("Need exactly one argument to jlink_pid");
                return ERROR_FAIL;
        }
@@ -880,8 +968,7 @@ COMMAND_HANDLER(jlink_pid_command)
 
 COMMAND_HANDLER(jlink_handle_jlink_info_command)
 {
-       if (jlink_get_version_info() == ERROR_OK)
-       {
+       if (jlink_get_version_info() == ERROR_OK) {
                /* attempt to get status */
                jlink_get_status();
        }
@@ -899,22 +986,23 @@ COMMAND_HANDLER(jlink_handle_jlink_caps_command)
 COMMAND_HANDLER(jlink_handle_jlink_hw_jtag_command)
 {
        switch (CMD_ARGC) {
-       case 0:
-               command_print(CMD_CTX, "J-Link hw jtag  %i", jlink_hw_jtag_version);
-               break;
-       case 1: {
-               int request_version = atoi(CMD_ARGV[0]);
-               switch (request_version) {
-               case 2: case 3:
-                       jlink_hw_jtag_version = request_version;
+               case 0:
+                       command_print(CMD_CTX, "J-Link hw jtag  %i", jlink_hw_jtag_version);
+                       break;
+               case 1: {
+                       int request_version = atoi(CMD_ARGV[0]);
+                       switch (request_version) {
+                               case 2:
+                               case 3:
+                                       jlink_hw_jtag_version = request_version;
+                                       break;
+                               default:
+                                       return ERROR_COMMAND_SYNTAX_ERROR;
+                       }
                        break;
+               }
                default:
                        return ERROR_COMMAND_SYNTAX_ERROR;
-               }
-               break;
-       }
-       default:
-               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        return ERROR_OK;
@@ -924,8 +1012,7 @@ COMMAND_HANDLER(jlink_handle_jlink_kickstart_command)
 {
        uint32_t kickstart;
 
-       if (CMD_ARGC < 1)
-       {
+       if (CMD_ARGC < 1) {
                jlink_config_kickstart_dump(CMD_CTX, &jlink_cfg);
                return ERROR_OK;
        }
@@ -943,8 +1030,7 @@ COMMAND_HANDLER(jlink_handle_jlink_mac_address_command)
        char *e;
        const char *str;
 
-       if (CMD_ARGC < 1)
-       {
+       if (CMD_ARGC < 1) {
                jlink_config_mac_address_dump(CMD_CTX, &jlink_cfg);
                return ERROR_OK;
        }
@@ -952,26 +1038,22 @@ COMMAND_HANDLER(jlink_handle_jlink_mac_address_command)
        str = CMD_ARGV[0];
 
        if ((strlen(str) != 17) || (str[2] != ':' || str[5] != ':' || str[8] != ':' ||
-               str[11] != ':' || str[14] != ':'))
-       {
+               str[11] != ':' || str[14] != ':')) {
                command_print(CMD_CTX, "ethaddr miss format ff:ff:ff:ff:ff:ff");
                return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
-       for (i = 5; i >= 0; i--)
-       {
+       for (i = 5; i >= 0; i--) {
                addr[i] = strtoul(str, &e, 16);
                str = e + 1;
        }
 
-       if (!(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]))
-       {
+       if (!(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5])) {
                command_print(CMD_CTX, "invalid it's zero mac_address");
                return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
-       if (!(0x01 & addr[0]))
-       {
+       if (!(0x01 & addr[0])) {
                command_print(CMD_CTX, "invalid it's a multicat mac_address");
                return ERROR_COMMAND_SYNTAX_ERROR;
        }
@@ -1022,13 +1104,12 @@ COMMAND_HANDLER(jlink_handle_jlink_ip_command)
        int ret;
        uint8_t subnet_bits = 24;
 
-       if (CMD_ARGC < 1)
-       {
+       if (CMD_ARGC < 1) {
                jlink_config_ip_dump(CMD_CTX, &jlink_cfg);
                return ERROR_OK;
        }
 
-       ret = string_to_ip(CMD_ARGV[0], (uint8_t*)&ip_address, &i);
+       ret = string_to_ip(CMD_ARGV[0], (uint8_t *)&ip_address, &i);
        if (ret != ERROR_OK)
                return ret;
 
@@ -1036,18 +1117,14 @@ COMMAND_HANDLER(jlink_handle_jlink_ip_command)
 
        /* check for this format A.B.C.D/E */
 
-       if (i < len)
-       {
+       if (i < len) {
                if (CMD_ARGV[0][i] != '/')
                        return ERROR_COMMAND_SYNTAX_ERROR;
 
                COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0] + i + 1, subnet_bits);
-       }
-       else
-       {
-               if (CMD_ARGC > 1)
-               {
-                       ret = string_to_ip(CMD_ARGV[1], (uint8_t*)&subnet_mask, &i);
+       } else {
+               if (CMD_ARGC > 1) {
+                       ret = string_to_ip(CMD_ARGV[1], (uint8_t *)&subnet_mask, &i);
                        if (ret != ERROR_OK)
                                return ret;
                }
@@ -1055,10 +1132,10 @@ COMMAND_HANDLER(jlink_handle_jlink_ip_command)
 
        if (!subnet_mask)
                subnet_mask = (uint32_t)(subnet_bits < 32 ?
-                               ((1ULL << subnet_bits) -1) : 0xffffffff);
+                               ((1ULL << subnet_bits) - 1) : 0xffffffff);
 
-       cpy_ip(jlink_cfg.ip_address, (uint8_t*)&ip_address);
-       cpy_ip(jlink_cfg.subnet_mask, (uint8_t*)&subnet_mask);
+       cpy_ip(jlink_cfg.ip_address, (uint8_t *)&ip_address);
+       cpy_ip(jlink_cfg.subnet_mask, (uint8_t *)&subnet_mask);
 
        return ERROR_OK;
 }
@@ -1071,8 +1148,7 @@ COMMAND_HANDLER(jlink_handle_jlink_reset_command)
 
 COMMAND_HANDLER(jlink_handle_jlink_save_command)
 {
-       if (!(jlink_caps & (1 << EMU_CAP_WRITE_CONFIG)))
-       {
+       if (!(jlink_caps & (1 << EMU_CAP_WRITE_CONFIG))) {
                command_print(CMD_CTX, "J-Link write emulator configuration not supported");
                return ERROR_OK;
        }
@@ -1085,16 +1161,14 @@ COMMAND_HANDLER(jlink_handle_jlink_usb_address_command)
 {
        uint32_t address;
 
-       if (CMD_ARGC < 1)
-       {
+       if (CMD_ARGC < 1) {
                jlink_config_usb_address_dump(CMD_CTX, &jlink_cfg);
                return ERROR_OK;
        }
 
        COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
 
-       if (address > 0x3 && address != 0xff)
-       {
+       if (address > 0x3 && address != 0xff) {
                command_print(CMD_CTX, "USB Address must be between 0x00 and 0x03 or 0xff");
                return ERROR_COMMAND_SYNTAX_ERROR;
        }
@@ -1108,17 +1182,15 @@ COMMAND_HANDLER(jlink_handle_jlink_config_command)
        struct jlink_config cfg;
        int ret = ERROR_OK;
 
-       if (CMD_ARGC == 0)
-       {
-               if (!(jlink_caps & (1 << EMU_CAP_READ_CONFIG)))
-               {
+       if (CMD_ARGC == 0) {
+               if (!(jlink_caps & (1 << EMU_CAP_READ_CONFIG))) {
                        command_print(CMD_CTX, "J-Link read emulator configuration not supported");
                        goto exit;
                }
 
                ret = jlink_get_config(&cfg);
 
-               if ( ret != ERROR_OK)
+               if (ret != ERROR_OK)
                        command_print(CMD_CTX, "J-Link read emulator configuration failled");
                else
                        jlink_config_dump(CMD_CTX, &jlink_cfg);
@@ -1226,6 +1298,7 @@ static const struct command_registration jlink_command_handlers[] = {
 struct jtag_interface jlink_interface = {
        .name = "jlink",
        .commands = jlink_command_handlers,
+       .transports = jtag_only,
 
        .execute_queue = jlink_execute_queue,
        .speed = jlink_speed,
@@ -1239,7 +1312,7 @@ struct jtag_interface jlink_interface = {
 /* J-Link tap functions */
 
 
-static unsigned tap_length = 0;
+static unsigned tap_length;
 static uint8_t tms_buffer[JLINK_TAP_BUFFER_SIZE];
 static uint8_t tdi_buffer[JLINK_TAP_BUFFER_SIZE];
 static uint8_t tdo_buffer[JLINK_TAP_BUFFER_SIZE];
@@ -1268,17 +1341,14 @@ static void jlink_tap_ensure_space(int scans, int bits)
        int available_bits = JLINK_TAP_BUFFER_SIZE * 8 - tap_length - 32;
 
        if (scans > available_scans || bits > available_bits)
-       {
                jlink_tap_execute();
-       }
 }
 
 static void jlink_tap_append_step(int tms, int tdi)
 {
        int index_var = tap_length / 8;
 
-       if (index_var >= JLINK_TAP_BUFFER_SIZE)
-       {
+       if (index_var >= JLINK_TAP_BUFFER_SIZE) {
                LOG_ERROR("jlink_tap_append_step: overflow");
                *(uint32_t *)0xFFFFFFFF = 0;
                exit(-1);
@@ -1287,11 +1357,9 @@ static void jlink_tap_append_step(int tms, int tdi)
        int bit_index = tap_length % 8;
        uint8_t bit = 1 << bit_index;
 
-       // we do not pad TMS, so be sure to initialize all bits
+       /* we do not pad TMS, so be sure to initialize all bits */
        if (0 == bit_index)
-       {
                tms_buffer[index_var] = tdi_buffer[index_var] = 0;
-       }
 
        if (tms)
                tms_buffer[index_var] |= bit;
@@ -1318,8 +1386,7 @@ static void jlink_tap_append_scan(int length, uint8_t *buffer,
        pending_scan_result->command = command;
        pending_scan_result->buffer = buffer;
 
-       for (i = 0; i < length; i++)
-       {
+       for (i = 0; i < length; i++) {
                int tms = (i < (length - 1)) ? 0 : 1;
                int tdi = (buffer[i / 8] & (1 << (i % 8))) != 0;
                jlink_tap_append_step(tms, tdi);
@@ -1342,11 +1409,9 @@ static int jlink_tap_execute(void)
         * message is a multiple of 64, creates problems with USB comms.
         * WARNING: This will interfere with tap state counting. */
        while ((DIV_ROUND_UP(tap_length, 8) % 64) == 0)
-       {
                jlink_tap_append_step((tap_get_state() == TAP_RESET) ? 1 : 0, 0);
-       }
 
-       // number of full bytes (plus one if some would be left over)
+       /* number of full bytes (plus one if some would be left over) */
        byte_length = DIV_ROUND_UP(tap_length, 8);
 
        bool use_jtag3 = jlink_hw_jtag_version >= 3;
@@ -1361,8 +1426,7 @@ static int jlink_tap_execute(void)
                        tap_length, jlink_last_state);
 
        result = jlink_usb_message(jlink_handle, 4 + 2 * byte_length, byte_length);
-       if (result != byte_length)
-       {
+       if (result != byte_length) {
                LOG_ERROR("jlink_tap_execute, wrong result %d (expected %d)",
                                result, byte_length);
                jlink_tap_init();
@@ -1371,8 +1435,7 @@ static int jlink_tap_execute(void)
 
        memcpy(tdo_buffer, usb_in_buffer, byte_length);
 
-       for (i = 0; i < pending_scan_results_length; i++)
-       {
+       for (i = 0; i < pending_scan_results_length; i++) {
                struct pending_scan_result *pending_scan_result = &pending_scan_results_buffer[i];
                uint8_t *buffer = pending_scan_result->buffer;
                int length = pending_scan_result->length;
@@ -1386,16 +1449,13 @@ static int jlink_tap_execute(void)
 
                jlink_debug_buffer(buffer, DIV_ROUND_UP(length, 8));
 
-               if (jtag_read_buffer(buffer, command) != ERROR_OK)
-               {
+               if (jtag_read_buffer(buffer, command) != ERROR_OK) {
                        jlink_tap_init();
                        return ERROR_JTAG_QUEUE_FAILED;
                }
 
                if (pending_scan_result->buffer != NULL)
-               {
                        free(pending_scan_result->buffer);
-               }
        }
 
        jlink_tap_init();
@@ -1405,12 +1465,10 @@ static int jlink_tap_execute(void)
 /*****************************************************************************/
 /* JLink USB low-level functions */
 
-static struct jlinkjlink_usb_open()
+static struct jlink *jlink_usb_open()
 {
-       usb_init();
-
-       struct usb_dev_handle *dev;
-       if (jtag_usb_open(vids, pids, &dev) != ERROR_OK)
+       struct jtag_libusb_device_handle *devh;
+       if (jtag_libusb_open(vids, pids, &devh) != ERROR_OK)
                return NULL;
 
        /* BE ***VERY CAREFUL*** ABOUT MAKING CHANGES IN THIS
@@ -1426,7 +1484,7 @@ static struct jlink* jlink_usb_open()
 
 #if IS_WIN32 == 0
 
-       usb_reset(dev);
+       jtag_libusb_reset_device(devh);
 
 #if IS_DARWIN == 0
 
@@ -1434,13 +1492,11 @@ static struct jlink* jlink_usb_open()
        /* reopen jlink after usb_reset
         * on win32 this may take a second or two to re-enumerate */
        int retval;
-       while ((retval = jtag_usb_open(vids, pids, &dev)) != ERROR_OK)
-       {
+       while ((retval = jtag_libusb_open(vids, pids, &devh)) != ERROR_OK) {
                usleep(1000);
                timeout--;
-               if (!timeout) {
+               if (!timeout)
                        break;
-               }
        }
        if (ERROR_OK != retval)
                return NULL;
@@ -1449,9 +1505,9 @@ static struct jlink* jlink_usb_open()
 #endif
 
        /* usb_set_configuration required under win32 */
-       struct usb_device *udev = usb_device(dev);
-       usb_set_configuration(dev, udev->config[0].bConfigurationValue);
-       usb_claim_interface(dev, 0);
+       struct jtag_libusb_device *udev = jtag_libusb_get_device(devh);
+       jtag_libusb_set_configuration(devh, 0);
+       jtag_libusb_claim_interface(devh, 0);
 
 #if 0
        /*
@@ -1460,27 +1516,17 @@ static struct jlink* jlink_usb_open()
         */
        usb_set_altinterface(result->usb_handle, 0);
 #endif
-       struct usb_interface *iface = udev->config->interface;
-       struct usb_interface_descriptor *desc = iface->altsetting;
-       for (int i = 0; i < desc->bNumEndpoints; i++)
-       {
-               uint8_t epnum = desc->endpoint[i].bEndpointAddress;
-               bool is_input = epnum & 0x80;
-               LOG_DEBUG("usb ep %s %02x", is_input ? "in" : "out", epnum);
-               if (is_input)
-                       jlink_read_ep = epnum;
-               else
-                       jlink_write_ep = epnum;
-       }
+
+       jtag_libusb_get_endpoints(udev, &jlink_read_ep, &jlink_write_ep);
 
        struct jlink *result = malloc(sizeof(struct jlink));
-       result->usb_handle = dev;
+       result->usb_handle = devh;
        return result;
 }
 
 static void jlink_usb_close(struct jlink *jlink)
 {
-       usb_close(jlink->usb_handle);
+       jtag_libusb_close(jlink->usb_handle);
        free(jlink);
 }
 
@@ -1490,16 +1536,14 @@ static int jlink_usb_message(struct jlink *jlink, int out_length, int in_length)
        int result;
 
        result = jlink_usb_write(jlink, out_length);
-       if (result != out_length)
-       {
+       if (result != out_length) {
                LOG_ERROR("usb_bulk_write failed (requested=%d, result=%d)",
                                out_length, result);
                return ERROR_JTAG_DEVICE_ERROR;
        }
 
        result = jlink_usb_read(jlink, in_length);
-       if ((result != in_length) && (result != (in_length + 1)))
-       {
+       if ((result != in_length) && (result != (in_length + 1))) {
                LOG_ERROR("usb_bulk_read failed (requested=%d, result=%d)",
                                in_length, result);
                return ERROR_JTAG_DEVICE_ERROR;
@@ -1509,18 +1553,15 @@ static int jlink_usb_message(struct jlink *jlink, int out_length, int in_length)
                return result;
 
        int result2 = ERROR_OK;
-       if (result == in_length)
-       {
+       if (result == in_length) {
                /* Must read the result from the EMU too */
                result2 = jlink_usb_read_emu_result(jlink);
-               if (1 != result2)
-               {
+               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)
-                       {
+                       if (1 != result2) {
                                LOG_ERROR("jlink_usb_read_emu_result failed "
                                        "(requested = 1, result=%d)", result2);
                                return ERROR_JTAG_DEVICE_ERROR;
@@ -1529,15 +1570,12 @@ static int jlink_usb_message(struct jlink *jlink, int out_length, int in_length)
 
                /* Check the result itself */
                result2 = usb_emu_result_buffer[0];
-       }
-       else
-       {
+       } else {
                /* Save the result, then remove it from return value */
                result2 = usb_in_buffer[result--];
        }
 
-       if (result2)
-       {
+       if (result2) {
                LOG_ERROR("jlink_usb_message failed with result=%d)", result2);
                return ERROR_JTAG_DEVICE_ERROR;
        }
@@ -1548,14 +1586,13 @@ static int jlink_usb_message(struct jlink *jlink, int out_length, int in_length)
 /* calls the given usb_bulk_* function, allowing for the data to
  * trickle in with some timeouts  */
 static int usb_bulk_with_retries(
-               int (*f)(usb_dev_handle *, int, char *, int, int),
-               usb_dev_handle *dev, int ep,
+               int (*f)(jtag_libusb_device_handle *, int, char *, int, int),
+               jtag_libusb_device_handle *dev, int ep,
                char *bytes, int size, int timeout)
 {
        int tries = 3, count = 0;
 
-       while (tries && (count < size))
-       {
+       while (tries && (count < size)) {
                int result = f(dev, ep, bytes + count, size - count, timeout);
                if (result > 0)
                        count += result;
@@ -1565,24 +1602,24 @@ static int usb_bulk_with_retries(
        return count;
 }
 
-static int wrap_usb_bulk_write(usb_dev_handle *dev, int ep,
-                              char *buff, int size, int timeout)
+static int wrap_usb_bulk_write(jtag_libusb_device_handle *dev, int ep,
+               char *buff, int size, int timeout)
 {
        /* usb_bulk_write() takes const char *buff */
-       return usb_bulk_write(dev, ep, buff, size, timeout);
+       return jtag_libusb_bulk_write(dev, ep, buff, size, timeout);
 }
 
-static inline int usb_bulk_write_ex(usb_dev_handle *dev, int ep,
+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);
 }
 
-static inline int usb_bulk_read_ex(usb_dev_handle *dev, int ep,
+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(&usb_bulk_read,
+       return usb_bulk_with_retries(&jtag_libusb_bulk_read,
                        dev, ep, bytes, size, timeout);
 }
 
@@ -1591,8 +1628,7 @@ static int jlink_usb_write(struct jlink *jlink, int out_length)
 {
        int result;
 
-       if (out_length > JLINK_OUT_BUFFER_SIZE)
-       {
+       if (out_length > JLINK_OUT_BUFFER_SIZE) {
                LOG_ERROR("jlink_write illegal out_length=%d (max=%d)",
                                out_length, JLINK_OUT_BUFFER_SIZE);
                return -1;
@@ -1633,6 +1669,48 @@ static int jlink_usb_read_emu_result(struct jlink *jlink)
        return result;
 }
 
+/*
+ * Send a message and receive the reply - simple messages.
+ *
+ * @param jlink pointer to driver data
+ * @param out_length data length in @c usb_out_buffer
+ * @param in_length data length to be read to @c usb_in_buffer
+ */
+static int jlink_usb_io(struct jlink *jlink, int out_length, int in_length)
+{
+       int result;
+
+       result = jlink_usb_write(jlink, out_length);
+       if (result != out_length) {
+               LOG_ERROR("usb_bulk_write failed (requested=%d, result=%d)",
+                               out_length, result);
+               return ERROR_JTAG_DEVICE_ERROR;
+       }
+
+       result = jlink_usb_read(jlink, in_length);
+       if (result != in_length) {
+               LOG_ERROR("usb_bulk_read failed (requested=%d, result=%d)",
+                               in_length, result);
+               return ERROR_JTAG_DEVICE_ERROR;
+       }
+
+       /*
+        * Section 4.2.4 IN-transaction:
+        * read dummy 0-byte packet if transaction size is
+        * multiple of 64 bytes but not max. size of 0x8000
+        */
+       if ((in_length % 64) == 0 && in_length != 0x8000) {
+               char dummy_buffer;
+               result = usb_bulk_read_ex(jlink->usb_handle, jlink_read_ep,
+                       &dummy_buffer, 1, JLINK_USB_TIMEOUT);
+               if (result != 0) {
+                       LOG_ERROR("dummy byte read failed");
+                       return ERROR_JTAG_DEVICE_ERROR;
+               }
+       }
+       return ERROR_OK;
+}
+
 #ifdef _DEBUG_USB_COMMS_
 #define BYTES_PER_LINE  16
 
@@ -1643,11 +1721,9 @@ static void jlink_debug_buffer(uint8_t *buffer, int length)
        int i;
        int j;
 
-       for (i = 0; i < length; i += BYTES_PER_LINE)
-       {
+       for (i = 0; i < length; i += BYTES_PER_LINE) {
                snprintf(line, 5, "%04x", i);
-               for (j = i; j < i + BYTES_PER_LINE && j < length; j++)
-               {
+               for (j = i; j < i + BYTES_PER_LINE && j < length; j++) {
                        snprintf(s, 4, " %02x", buffer[j]);
                        strcat(line, s);
                }