lpc3180_nand_controller: use register_commands()
[fw/openocd] / src / jtag / jlink.c
index 27d400d4d58bedb30ce73b757109c96ce16681bd..9b2326bdb0918a9f3c7614b136bdcf0ea6ccef0c 100644 (file)
@@ -27,8 +27,7 @@
 
 #include "interface.h"
 #include "commands.h"
-
-#include <usb.h>
+#include "usb_common.h"
 
 
 #define VID 0x1366
@@ -82,19 +81,6 @@ static uint8_t usb_emu_result_buffer[JLINK_EMU_RESULT_BUFFER_SIZE];
 /* max speed 12MHz v5.0 jlink */
 #define JLINK_MAX_SPEED 12000
 
-/* External interface functions */
-static int jlink_execute_queue(void);
-static int jlink_speed(int speed);
-static int jlink_speed_div(int speed, int* khz);
-static int jlink_khz(int khz, int *jtag_speed);
-static int jlink_register_commands(struct command_context *cmd_ctx);
-static int jlink_init(void);
-static int jlink_quit(void);
-
-/* CLI command handler functions */
-static int jlink_handle_jlink_info_command(struct command_context *cmd_ctx, char *cmd, char **args, int argc);
-static int jlink_handle_jlink_hw_jtag_command(struct command_context *cmd_ctx, char *cmd, char **args, int argc);
-
 /* Queue command functions */
 static void jlink_end_state(tap_state_t state);
 static void jlink_state_move(void);
@@ -138,18 +124,6 @@ static struct jlink* jlink_handle;
 /***************************************************************************/
 /* External interface implementation */
 
-struct jtag_interface jlink_interface =
-{
-       .name = "jlink",
-       .execute_queue = jlink_execute_queue,
-       .speed = jlink_speed,
-       .speed_div = jlink_speed_div,
-       .khz = jlink_khz,
-       .register_commands = jlink_register_commands,
-       .init = jlink_init,
-       .quit = jlink_quit
-};
-
 static void jlink_execute_runtest(struct jtag_command *cmd)
 {
        DEBUG_JTAG_IO("runtest %i cycles, end in %i",
@@ -290,18 +264,6 @@ static int jlink_khz(int khz, int *jtag_speed)
        return ERROR_OK;
 }
 
-static int jlink_register_commands(struct command_context *cmd_ctx)
-{
-
-       register_command(cmd_ctx, NULL, "jlink_info",
-               &jlink_handle_jlink_info_command, COMMAND_EXEC,
-               "query jlink info");
-       register_command(cmd_ctx, NULL, "jlink_hw_jtag",
-               &jlink_handle_jlink_hw_jtag_command, COMMAND_EXEC,
-               "set/get jlink hw jtag command version [2 | 3]");
-       return ERROR_OK;
-}
-
 static int jlink_init(void)
 {
        int i;
@@ -630,7 +592,7 @@ static int jlink_get_version_info(void)
        return ERROR_OK;
 }
 
-static int jlink_handle_jlink_info_command(struct command_context *cmd_ctx, char *cmd, char **args, int argc)
+COMMAND_HANDLER(jlink_handle_jlink_info_command)
 {
        if (jlink_get_version_info() == ERROR_OK)
        {
@@ -641,14 +603,14 @@ static int jlink_handle_jlink_info_command(struct command_context *cmd_ctx, char
        return ERROR_OK;
 }
 
-static int jlink_handle_jlink_hw_jtag_command(struct command_context *cmd_ctx, char *cmd, char **args, int argc)
+COMMAND_HANDLER(jlink_handle_jlink_hw_jtag_command)
 {
-       switch (argc) {
+       switch (CMD_ARGC) {
        case 0:
-               command_print(cmd_ctx, "jlink hw jtag  %i", jlink_hw_jtag_version);
+               command_print(CMD_CTX, "jlink hw jtag  %i", jlink_hw_jtag_version);
                break;
        case 1: {
-               int request_version = atoi(args[0]);
+               int request_version = atoi(CMD_ARGV[0]);
                switch (request_version) {
                case 2: case 3:
                        jlink_hw_jtag_version = request_version;
@@ -665,6 +627,37 @@ static int jlink_handle_jlink_hw_jtag_command(struct command_context *cmd_ctx, c
        return ERROR_OK;
 }
 
+static const struct command_registration jlink_command_handlers[] = {
+       {
+               .name = "jlink_info",
+               .handler = &jlink_handle_jlink_info_command,
+               .mode = COMMAND_EXEC,
+               .help = "show jlink info",
+       },
+       {
+               .name = "jlink_hw_jtag",
+               .handler = &jlink_handle_jlink_hw_jtag_command,
+               .mode = COMMAND_EXEC,
+               .help = "access J-Link HW JTAG command version",
+               .usage = "[2|3]",
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+struct jtag_interface jlink_interface = {
+               .name = "jlink",
+
+               .commands = jlink_command_handlers,
+
+               .execute_queue = &jlink_execute_queue,
+               .speed = &jlink_speed,
+               .speed_div = &jlink_speed_div,
+               .khz = &jlink_khz,
+
+               .init = &jlink_init,
+               .quit = &jlink_quit,
+       };
+
 /***************************************************************************/
 /* J-Link tap functions */
 
@@ -767,15 +760,16 @@ static int jlink_tap_execute(void)
        if (!tap_length)
                return ERROR_OK;
 
-       /* JLink returns an extra NULL in packet when size of in message is a multiple of 64, creates problems with usb comms */
-       /* WARNING This will interfere with tap state counting */
-       while ((TAP_SCAN_BYTES(tap_length)%64) == 0)
+       /* JLink returns an extra NULL in packet when size of incoming
+        * 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)
-       byte_length = TAP_SCAN_BYTES(tap_length);
+       byte_length = DIV_ROUND_UP(tap_length, 8);
 
        bool use_jtag3 = jlink_hw_jtag_version >= 3;
        usb_out_buffer[0] = use_jtag3 ? EMU_CMD_HW_JTAG3 : EMU_CMD_HW_JTAG2;
@@ -812,7 +806,7 @@ static int jlink_tap_execute(void)
                DEBUG_JTAG_IO("pending scan result, length = %d", length);
 
 #ifdef _DEBUG_USB_COMMS_
-               jlink_debug_buffer(buffer, TAP_SCAN_BYTES(length));
+               jlink_debug_buffer(buffer, DIV_ROUND_UP(length, 8));
 #endif
 
                if (jtag_read_buffer(buffer, command) != ERROR_OK)
@@ -831,124 +825,82 @@ static int jlink_tap_execute(void)
        return ERROR_OK;
 }
 
-static struct usb_device* find_jlink_device(void)
-{
-       struct usb_bus *busses;
-       struct usb_bus *bus;
-       struct usb_device *dev;
-
-       usb_find_busses();
-       usb_find_devices();
-
-       busses = usb_get_busses();
-
-       /* find jlink device in usb bus */
-
-       for (bus = busses; bus; bus = bus->next)
-       {
-               for (dev = bus->devices; dev; dev = dev->next)
-               {
-                       if ((dev->descriptor.idVendor == VID) && (dev->descriptor.idProduct == PID)) {
-                               return dev;
-                       }
-               }
-       }
-
-       return NULL;
-}
-
 /*****************************************************************************/
 /* JLink USB low-level functions */
 
 static struct jlink* jlink_usb_open()
 {
-       struct usb_device *dev;
-
-       struct jlink *result;
-
-       result = (struct jlink*) malloc(sizeof(struct jlink));
-
        usb_init();
 
-       if ((dev = find_jlink_device()) == NULL) {
-               free(result);
+       const uint16_t vids[] = { VID, 0 };
+       const uint16_t pids[] = { PID, 0 };
+       struct usb_dev_handle *dev;
+       if (jtag_usb_open(vids, pids, &dev) != ERROR_OK)
                return NULL;
-       }
-
-       result->usb_handle = usb_open(dev);
-
-       if (result->usb_handle)
-       {
 
-               /* BE ***VERY CAREFUL*** ABOUT MAKING CHANGES IN THIS AREA!!!!!!!!!!!
-                * The behavior of libusb is not completely consistent across Windows, Linux, and Mac OS X platforms.  The actions taken
-                * in the following compiler conditionals may not agree with published documentation for libusb, but were found
-                * to be necessary through trials and tribulations.  Even little tweaks can break one or more platforms, so if you do make changes
-                * test them carefully on all platforms before committing them!
-                */
+       /* BE ***VERY CAREFUL*** ABOUT MAKING CHANGES IN THIS
+        * AREA!!!!!!!!!!!  The behavior of libusb is not completely
+        * consistent across Windows, Linux, and Mac OS X platforms.
+        * The actions taken in the following compiler conditionals may
+        * not agree with published documentation for libusb, but were
+        * found to be necessary through trials and tribulations.  Even
+        * little tweaks can break one or more platforms, so if you do
+        * make changes test them carefully on all platforms before
+        * committing them!
+        */
 
 #if IS_WIN32 == 0
 
-               usb_reset(result->usb_handle);
+       usb_reset(dev);
 
 #if IS_DARWIN == 0
 
-               int timeout = 5;
-
-               /* reopen jlink after usb_reset
-                * on win32 this may take a second or two to re-enumerate */
-               while ((dev = find_jlink_device()) == NULL)
-               {
-                       usleep(1000);
-                       timeout--;
-                       if (!timeout) {
-                               break;
-                       }
-               }
-
-               if (dev == NULL)
-               {
-                       free(result);
-                       return NULL;
+       int timeout = 5;
+       /* 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)
+       {
+               usleep(1000);
+               timeout--;
+               if (!timeout) {
+                       break;
                }
-
-               result->usb_handle = usb_open(dev);
+       }
+       if (ERROR_OK != retval)
+               return NULL;
 #endif
 
 #endif
 
-               if (result->usb_handle)
-               {
-                       /* usb_set_configuration required under win32 */
-                       usb_set_configuration(result->usb_handle, dev->config[0].bConfigurationValue);
-                       usb_claim_interface(result->usb_handle, 0);
+       /* 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);
 
 #if 0
-                       /*
-                        * This makes problems under Mac OS X. And is not needed
-                        * under Windows. Hopefully this will not break a linux build
-                        */
-                       usb_set_altinterface(result->usb_handle, 0);
+       /*
+        * This makes problems under Mac OS X. And is not needed
+        * under Windows. Hopefully this will not break a linux build
+        */
+       usb_set_altinterface(result->usb_handle, 0);
 #endif
-                       struct usb_interface *iface = dev->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;
-                       }
-
-                       return result;
-               }
+       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;
        }
 
-       free(result);
-       return NULL;
+       struct jlink *result = malloc(sizeof(struct jlink));
+       result->usb_handle = dev;
+       return result;
 }
 
 static void jlink_usb_close(struct jlink *jlink)