cosmetic fixes to debug output + phasing out printf() in favour of logging system...
authoroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Sun, 24 Feb 2008 17:10:48 +0000 (17:10 +0000)
committeroharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Sun, 24 Feb 2008 17:10:48 +0000 (17:10 +0000)
git-svn-id: svn://svn.berlios.de/openocd/trunk@326 b42882b7-edfa-0310-969c-e2dbd0fdcd60

src/flash/s3c2440_nand.c
src/helper/log.c
src/jtag/ep93xx.c
src/jtag/ft2232.c
src/xsvf/xsvf.c

index fd1971950137a75416bca72f009a15654d82832d..1390a3fb7a7c7de92081bcf4f33247887f5448a1 100644 (file)
-/* src/flash/s3c2440_nand.c
- *
- * S3C2440 OpenOCD NAND Flash controller support.
- *
- * Copyright 2007,2008 Ben Dooks <ben@fluff.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Many thanks to Simtec Electronics for sponsoring this work.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "replacements.h"
-#include "log.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "nand.h"
-#include "s3c24xx_nand.h"
-#include "target.h"
-
-int s3c2440_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct nand_device_s *device);
-int s3c2440_init(struct nand_device_s *device);
-int s3c2440_nand_ready(struct nand_device_s *device, int timeout);
-
-nand_flash_controller_t s3c2440_nand_controller =
-{
-       .name                   = "s3c2440",
-       .nand_device_command    = s3c2440_nand_device_command,
-       .register_commands      = s3c24xx_register_commands,
-       .init                   = s3c2440_init,
-       .reset                  = s3c24xx_reset,
-       .command                = s3c24xx_command,
-       .address                = s3c24xx_address,
-       .write_data             = s3c24xx_write_data,
-       .read_data              = s3c24xx_read_data,
-       .write_page             = s3c24xx_write_page,
-       .read_page              = s3c24xx_read_page,
-       .write_block_data       = s3c2440_write_block_data,
-       .read_block_data        = s3c2440_read_block_data,
-       .controller_ready       = s3c24xx_controller_ready,
-       .nand_ready             = s3c2440_nand_ready,
-};
-
-int s3c2440_nand_device_command(struct command_context_s *cmd_ctx, char *cmd,
-                               char **args, int argc,
-                               struct nand_device_s *device)
-{
-       s3c24xx_nand_controller_t *info;
-       
-       info = s3c24xx_nand_device_command(cmd_ctx, cmd, args, argc, device);
-       if (info == NULL) {
-               return ERROR_NAND_DEVICE_INVALID;
-       }
-
-       /* fill in the address fields for the core device */
-       info->cmd = S3C2440_NFCMD;
-       info->addr = S3C2440_NFADDR;
-       info->data = S3C2440_NFDATA;
-       info->nfstat = S3C2440_NFSTAT;
-               
-       return ERROR_OK;
-}
-
-int s3c2440_init(struct nand_device_s *device)
-{
-       s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
-       target_t *target = s3c24xx_info->target;
-       u32 version;
-
-       target_write_u32(target, S3C2410_NFCONF,
-                        S3C2440_NFCONF_TACLS(3) |
-                        S3C2440_NFCONF_TWRPH0(7) |
-                        S3C2440_NFCONF_TWRPH1(7));
-
-       target_write_u32(target, S3C2440_NFCONT,
-                        S3C2440_NFCONT_INITECC | S3C2440_NFCONT_ENABLE);
-
-       return ERROR_OK;
-}
-
-int s3c2440_nand_ready(struct nand_device_s *device, int timeout)
-{
-       s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
-       target_t *target = s3c24xx_info->target;
-       u8 status;
-
-       if (target->state != TARGET_HALTED) {
-               ERROR("target must be halted to use S3C24XX NAND flash controller");
-               return ERROR_NAND_OPERATION_FAILED;
-       }
-       
-       do {            
-               target_read_u8(target, s3c24xx_info->nfstat, &status);
-               
-               if (status & S3C2440_NFSTAT_READY)
-                       return 1;
-
-               usleep(1000);
-       } while (timeout-- > 0);
-
-
-       return 0;
-}
-
-/* use the fact we can read/write 4 bytes in one go via a single 32bit op */
-
-int s3c2440_read_block_data(struct nand_device_s *device, u8 *data, int data_size)
-{
-       s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
-       target_t *target = s3c24xx_info->target;
-       u32 nfdata = s3c24xx_info->data;
-       u32 tmp;
-
-       printf("%s: reading data: %p, %p, %d\n", __func__, device, data, data_size);
-
-       if (target->state != TARGET_HALTED) {
-               ERROR("target must be halted to use S3C24XX NAND flash controller");
-               return ERROR_NAND_OPERATION_FAILED;
-       }
-
-       while (data_size >= 4) {          
-               target_read_u32(target, nfdata, &tmp);
-
-               data[0] = tmp;
-               data[1] = tmp >> 8;
-               data[2] = tmp >> 16;
-               data[3] = tmp >> 24;
-
-               data_size -= 4;
-               data += 4;
-       }
-
-       while (data_size > 0) {
-               target_read_u8(target, nfdata, data);
-
-               data_size -= 1;
-               data += 1;
-       }
-
-       return ERROR_OK;
-}
-
-int s3c2440_write_block_data(struct nand_device_s *device, u8 *data, int data_size)
-{
-       s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;
-       target_t *target = s3c24xx_info->target;
-       u32 nfdata = s3c24xx_info->data;
-       u32 tmp;
-
-       if (target->state != TARGET_HALTED) {
-               ERROR("target must be halted to use S3C24XX NAND flash controller");
-               return ERROR_NAND_OPERATION_FAILED;
-       }
-
-       while (data_size >= 4) {          
-               tmp = le_to_h_u32(data);
-               target_write_u32(target, nfdata, tmp);
-
-               data_size -= 4;
-               data += 4;
-       }
-
-       while (data_size > 0) {
-               target_write_u8(target, nfdata, *data);
-
-               data_size -= 1;
-               data += 1;
-       }
-
-       return ERROR_OK;
-}
+/* src/flash/s3c2440_nand.c\r
+ *\r
+ * S3C2440 OpenOCD NAND Flash controller support.\r
+ *\r
+ * Copyright 2007,2008 Ben Dooks <ben@fluff.org>\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * Many thanks to Simtec Electronics for sponsoring this work.\r
+ */\r
+\r
+#ifdef HAVE_CONFIG_H\r
+#include "config.h"\r
+#endif\r
+\r
+#include "replacements.h"\r
+#include "log.h"\r
+\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+#include "nand.h"\r
+#include "s3c24xx_nand.h"\r
+#include "target.h"\r
+\r
+int s3c2440_nand_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct nand_device_s *device);\r
+int s3c2440_init(struct nand_device_s *device);\r
+int s3c2440_nand_ready(struct nand_device_s *device, int timeout);\r
+\r
+nand_flash_controller_t s3c2440_nand_controller =\r
+{\r
+       .name                   = "s3c2440",\r
+       .nand_device_command    = s3c2440_nand_device_command,\r
+       .register_commands      = s3c24xx_register_commands,\r
+       .init                   = s3c2440_init,\r
+       .reset                  = s3c24xx_reset,\r
+       .command                = s3c24xx_command,\r
+       .address                = s3c24xx_address,\r
+       .write_data             = s3c24xx_write_data,\r
+       .read_data              = s3c24xx_read_data,\r
+       .write_page             = s3c24xx_write_page,\r
+       .read_page              = s3c24xx_read_page,\r
+       .write_block_data       = s3c2440_write_block_data,\r
+       .read_block_data        = s3c2440_read_block_data,\r
+       .controller_ready       = s3c24xx_controller_ready,\r
+       .nand_ready             = s3c2440_nand_ready,\r
+};\r
+\r
+int s3c2440_nand_device_command(struct command_context_s *cmd_ctx, char *cmd,\r
+                               char **args, int argc,\r
+                               struct nand_device_s *device)\r
+{\r
+       s3c24xx_nand_controller_t *info;\r
+       \r
+       info = s3c24xx_nand_device_command(cmd_ctx, cmd, args, argc, device);\r
+       if (info == NULL) {\r
+               return ERROR_NAND_DEVICE_INVALID;\r
+       }\r
+\r
+       /* fill in the address fields for the core device */\r
+       info->cmd = S3C2440_NFCMD;\r
+       info->addr = S3C2440_NFADDR;\r
+       info->data = S3C2440_NFDATA;\r
+       info->nfstat = S3C2440_NFSTAT;\r
+               \r
+       return ERROR_OK;\r
+}\r
+\r
+int s3c2440_init(struct nand_device_s *device)\r
+{\r
+       s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;\r
+       target_t *target = s3c24xx_info->target;\r
+       u32 version;\r
+\r
+       target_write_u32(target, S3C2410_NFCONF,\r
+                        S3C2440_NFCONF_TACLS(3) |\r
+                        S3C2440_NFCONF_TWRPH0(7) |\r
+                        S3C2440_NFCONF_TWRPH1(7));\r
+\r
+       target_write_u32(target, S3C2440_NFCONT,\r
+                        S3C2440_NFCONT_INITECC | S3C2440_NFCONT_ENABLE);\r
+\r
+       return ERROR_OK;\r
+}\r
+\r
+int s3c2440_nand_ready(struct nand_device_s *device, int timeout)\r
+{\r
+       s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;\r
+       target_t *target = s3c24xx_info->target;\r
+       u8 status;\r
+\r
+       if (target->state != TARGET_HALTED) {\r
+               ERROR("target must be halted to use S3C24XX NAND flash controller");\r
+               return ERROR_NAND_OPERATION_FAILED;\r
+       }\r
+       \r
+       do {            \r
+               target_read_u8(target, s3c24xx_info->nfstat, &status);\r
+               \r
+               if (status & S3C2440_NFSTAT_READY)\r
+                       return 1;\r
+\r
+               usleep(1000);\r
+       } while (timeout-- > 0);\r
+\r
+\r
+       return 0;\r
+}\r
+\r
+/* use the fact we can read/write 4 bytes in one go via a single 32bit op */\r
+\r
+int s3c2440_read_block_data(struct nand_device_s *device, u8 *data, int data_size)\r
+{\r
+       s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;\r
+       target_t *target = s3c24xx_info->target;\r
+       u32 nfdata = s3c24xx_info->data;\r
+       u32 tmp;\r
+\r
+       INFO("%s: reading data: %p, %p, %d\n", __func__, device, data, data_size);\r
+\r
+       if (target->state != TARGET_HALTED) {\r
+               ERROR("target must be halted to use S3C24XX NAND flash controller");\r
+               return ERROR_NAND_OPERATION_FAILED;\r
+       }\r
+\r
+       while (data_size >= 4) {          \r
+               target_read_u32(target, nfdata, &tmp);\r
+\r
+               data[0] = tmp;\r
+               data[1] = tmp >> 8;\r
+               data[2] = tmp >> 16;\r
+               data[3] = tmp >> 24;\r
+\r
+               data_size -= 4;\r
+               data += 4;\r
+       }\r
+\r
+       while (data_size > 0) {\r
+               target_read_u8(target, nfdata, data);\r
+\r
+               data_size -= 1;\r
+               data += 1;\r
+       }\r
+\r
+       return ERROR_OK;\r
+}\r
+\r
+int s3c2440_write_block_data(struct nand_device_s *device, u8 *data, int data_size)\r
+{\r
+       s3c24xx_nand_controller_t *s3c24xx_info = device->controller_priv;\r
+       target_t *target = s3c24xx_info->target;\r
+       u32 nfdata = s3c24xx_info->data;\r
+       u32 tmp;\r
+\r
+       if (target->state != TARGET_HALTED) {\r
+               ERROR("target must be halted to use S3C24XX NAND flash controller");\r
+               return ERROR_NAND_OPERATION_FAILED;\r
+       }\r
+\r
+       while (data_size >= 4) {          \r
+               tmp = le_to_h_u32(data);\r
+               target_write_u32(target, nfdata, tmp);\r
+\r
+               data_size -= 4;\r
+               data += 4;\r
+       }\r
+\r
+       while (data_size > 0) {\r
+               target_write_u8(target, nfdata, *data);\r
+\r
+               data_size -= 1;\r
+               data += 1;\r
+       }\r
+\r
+       return ERROR_OK;\r
+}\r
index b2f31dc2b87c7eb8086edd57ff999fb7ce41a59f..7b7c914431c7543d826cd4b7fa30ed47efc68e0a 100644 (file)
-/***************************************************************************
- *   Copyright (C) 2005 by Dominic Rath                                    *
- *   Dominic.Rath@gmx.de                                                   *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "log.h"
-#include "configuration.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <time.h>
-
-int debug_level = -1;
-
-static FILE* log_output;
-
-static void *privData;
-static logCallback callback;
-
-void log_setCallback(logCallback c, void *p)
-{
-       callback = c;
-       privData = p;
-}
-
-static char *log_strings[5] = 
-{
-       "User:  ",
-       "Error:  ",
-       "Warning:",
-       "Info:   ",
-       "Debug:  "
-};
-
-void log_printf(enum log_levels level, const char *file, int line, const char *function, const char *format, ...)
-{
-       static int count = 0;
-       count++;
-       va_list args;
-       char buffer[512];
-
-       if (level > debug_level)
-               return;
-
-       va_start(args, format);
-       vsnprintf(buffer, 512, format, args);
-
-       char *f = strrchr(file, '/');
-       if (f != NULL)
-               file = f + 1;
-
-       if (debug_level >= LOG_DEBUG)
-       {
-               /* print with count and time information */
-               fprintf(log_output, "%s %d %ld %s:%d %s(): %s\n", log_strings[level+1], count, time(NULL), file, line, function, buffer);
-       }
-       else
-       {
-               /* do not print count and time */
-               fprintf(log_output, "%s %s:%d %s(): %s\n", log_strings[level+1], file, line, function, buffer);
-       }
-
-       fflush(log_output);
-       
-       va_end(args);
-
-       /* Never forward LOG_DEBUG, too verbose and they can be found in the log if need be */
-       if (callback && (level <= LOG_INFO))
-       {
-               va_start(args, format);
-               callback(privData, file, line, function, format, args);
-               va_end(args);
-       }
-}
-
-/* change the current debug level on the fly
- * 0: only ERRORS
- * 1: + WARNINGS
- * 2: + INFORMATIONAL MSGS
- * 3: + DEBUG MSGS
- */
-int handle_debug_level_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       if (argc == 0)
-               command_print(cmd_ctx, "debug_level: %i", debug_level);
-
-       if (argc > 0)
-               debug_level = strtoul(args[0], NULL, 0);
-
-       if (debug_level < 0)
-               debug_level = 0;
-
-       if (debug_level > 3)
-               debug_level = 3;
-
-       return ERROR_OK;
-}
-
-int handle_log_output_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       if (argc == 1)
-       {
-               FILE* file = fopen(args[0], "w");
-               
-               if (file)
-               {
-                       log_output = file;
-               }
-       }
-
-       return ERROR_OK;
-}
-
-int log_register_commands(struct command_context_s *cmd_ctx)
-{
-       register_command(cmd_ctx, NULL, "log_output", handle_log_output_command,
-               COMMAND_ANY, "redirect logging to <file> (default: stderr)");
-       register_command(cmd_ctx, NULL, "debug_level", handle_debug_level_command,
-               COMMAND_ANY, "adjust debug level <0-3>");
-
-       return ERROR_OK;
-}
-
-int log_init(struct command_context_s *cmd_ctx)
-{
-       /* set defaults for daemon configuration, if not set by cmdline or cfgfile */
-       if (debug_level == -1)
-               debug_level = LOG_INFO;
-       
-       if (log_output == NULL)
-       {
-               log_output = stderr;
-       }
-       
-       return ERROR_OK;
-}
-       
-int set_log_output(struct command_context_s *cmd_ctx, FILE *output)
-{
-       log_output = output;
-       return ERROR_OK;
-}
-
-/* return allocated string w/printf() result */
-char *allocPrintf(const char *fmt, va_list ap)
-{
-       char *string = NULL;
-       
-       /* start by 0 to exercise all the code paths. Need minimum 2 bytes to
-        * fit 1 char and 0 terminator. */
-       int size = 0;
-       int first = 1;
-       for (;;)
-       {
-               if ((string == NULL) || (!first))
-               {
-                       size = size * 2 + 2;
-                       char *t = string;
-                       string = realloc(string, size);
-                       if (string == NULL)
-                       {
-                               if (t != NULL)
-                                       free(t);
-                               return NULL;
-                       }
-               }
-       
-           int ret;
-           ret = vsnprintf(string, size, fmt, ap);
-           /* NB! The result of the vsnprintf() might be an *EMPTY* string! */
-           if ((ret >= 0) && ((ret + 1) < size))
-           {
-               return string;
-           }
-           /* there was just enough or not enough space, allocate more. */
-           first = 0;
-       }
-}
+/***************************************************************************\r
+ *   Copyright (C) 2005 by Dominic Rath                                    *\r
+ *   Dominic.Rath@gmx.de                                                   *\r
+ *                                                                         *\r
+ *   This program is free software; you can redistribute it and/or modify  *\r
+ *   it under the terms of the GNU General Public License as published by  *\r
+ *   the Free Software Foundation; either version 2 of the License, or     *\r
+ *   (at your option) any later version.                                   *\r
+ *                                                                         *\r
+ *   This program is distributed in the hope that it will be useful,       *\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\r
+ *   GNU General Public License for more details.                          *\r
+ *                                                                         *\r
+ *   You should have received a copy of the GNU General Public License     *\r
+ *   along with this program; if not, write to the                         *\r
+ *   Free Software Foundation, Inc.,                                       *\r
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *\r
+ ***************************************************************************/\r
+#ifdef HAVE_CONFIG_H\r
+#include "config.h"\r
+#endif\r
+\r
+#include "log.h"\r
+#include "configuration.h"\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <stdarg.h>\r
+#include <time.h>\r
+\r
+int debug_level = -1;\r
+\r
+static FILE* log_output;\r
+\r
+static void *privData;\r
+static logCallback callback;\r
+\r
+void log_setCallback(logCallback c, void *p)\r
+{\r
+       callback = c;\r
+       privData = p;\r
+}\r
+\r
+static char *log_strings[5] = \r
+{\r
+       "User:   ",\r
+       "Error:  ",\r
+       "Warning:",\r
+       "Info:   ",\r
+       "Debug:  "\r
+};\r
+\r
+void log_printf(enum log_levels level, const char *file, int line, const char *function, const char *format, ...)\r
+{\r
+       static int count = 0;\r
+       count++;\r
+       va_list args;\r
+       char buffer[512];\r
+\r
+       if (level > debug_level)\r
+               return;\r
+\r
+       va_start(args, format);\r
+       vsnprintf(buffer, 512, format, args);\r
+\r
+       char *f = strrchr(file, '/');\r
+       if (f != NULL)\r
+               file = f + 1;\r
+\r
+       if (debug_level >= LOG_DEBUG)\r
+       {\r
+               /* print with count and time information */\r
+               fprintf(log_output, "%s %d %ld %s:%d %s(): %s\n", log_strings[level+1], count, time(NULL), file, line, function, buffer);\r
+       }\r
+       else\r
+       {\r
+               /* do not print count and time */\r
+               fprintf(log_output, "%s %s:%d %s(): %s\n", log_strings[level+1], file, line, function, buffer);\r
+       }\r
+\r
+       fflush(log_output);\r
+       \r
+       va_end(args);\r
+\r
+       /* Never forward LOG_DEBUG, too verbose and they can be found in the log if need be */\r
+       if (callback && (level <= LOG_INFO))\r
+       {\r
+               va_start(args, format);\r
+               callback(privData, file, line, function, format, args);\r
+               va_end(args);\r
+       }\r
+}\r
+\r
+/* change the current debug level on the fly\r
+ * 0: only ERRORS\r
+ * 1: + WARNINGS\r
+ * 2: + INFORMATIONAL MSGS\r
+ * 3: + DEBUG MSGS\r
+ */\r
+int handle_debug_level_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       if (argc == 0)\r
+               command_print(cmd_ctx, "debug_level: %i", debug_level);\r
+\r
+       if (argc > 0)\r
+               debug_level = strtoul(args[0], NULL, 0);\r
+\r
+       if (debug_level < 0)\r
+               debug_level = 0;\r
+\r
+       if (debug_level > 3)\r
+               debug_level = 3;\r
+\r
+       return ERROR_OK;\r
+}\r
+\r
+int handle_log_output_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       if (argc == 1)\r
+       {\r
+               FILE* file = fopen(args[0], "w");\r
+               \r
+               if (file)\r
+               {\r
+                       log_output = file;\r
+               }\r
+       }\r
+\r
+       return ERROR_OK;\r
+}\r
+\r
+int log_register_commands(struct command_context_s *cmd_ctx)\r
+{\r
+       register_command(cmd_ctx, NULL, "log_output", handle_log_output_command,\r
+               COMMAND_ANY, "redirect logging to <file> (default: stderr)");\r
+       register_command(cmd_ctx, NULL, "debug_level", handle_debug_level_command,\r
+               COMMAND_ANY, "adjust debug level <0-3>");\r
+\r
+       return ERROR_OK;\r
+}\r
+\r
+int log_init(struct command_context_s *cmd_ctx)\r
+{\r
+       /* set defaults for daemon configuration, if not set by cmdline or cfgfile */\r
+       if (debug_level == -1)\r
+               debug_level = LOG_INFO;\r
+       \r
+       if (log_output == NULL)\r
+       {\r
+               log_output = stderr;\r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+       \r
+int set_log_output(struct command_context_s *cmd_ctx, FILE *output)\r
+{\r
+       log_output = output;\r
+       return ERROR_OK;\r
+}\r
+\r
+/* return allocated string w/printf() result */\r
+char *allocPrintf(const char *fmt, va_list ap)\r
+{\r
+       char *string = NULL;\r
+       \r
+       /* start by 0 to exercise all the code paths. Need minimum 2 bytes to\r
+        * fit 1 char and 0 terminator. */\r
+       int size = 0;\r
+       int first = 1;\r
+       for (;;)\r
+       {\r
+               if ((string == NULL) || (!first))\r
+               {\r
+                       size = size * 2 + 2;\r
+                       char *t = string;\r
+                       string = realloc(string, size);\r
+                       if (string == NULL)\r
+                       {\r
+                               if (t != NULL)\r
+                                       free(t);\r
+                               return NULL;\r
+                       }\r
+               }\r
+       \r
+           int ret;\r
+           ret = vsnprintf(string, size, fmt, ap);\r
+           /* NB! The result of the vsnprintf() might be an *EMPTY* string! */\r
+           if ((ret >= 0) && ((ret + 1) < size))\r
+           {\r
+               return string;\r
+           }\r
+           /* there was just enough or not enough space, allocate more. */\r
+           first = 0;\r
+       }\r
+}\r
index f2e176fd33ce45770753c92a65835ec00fac3f55..ebedfdfec0314bbfadb40532d3ddeee3f143ce42 100644 (file)
-/***************************************************************************
- *   Copyright (C) 2005 by Dominic Rath                                    *
- *   Dominic.Rath@gmx.de                                                   *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "log.h"
-#include "jtag.h"
-#include "bitbang.h"
-
-#define TDO_BIT                1
-#define TDI_BIT                2
-#define TCK_BIT                4
-#define TMS_BIT                8
-#define TRST_BIT       16
-#define SRST_BIT       32
-#define VCC_BIT                64
-
-/* system includes */
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/mman.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-static u8 output_value = 0x0;
-static int dev_mem_fd;
-static void *gpio_controller;
-static volatile u8 *gpio_data_register;
-static volatile u8 *gpio_data_direction_register;
-
-/* low level command set
- */
-int ep93xx_read(void);
-void ep93xx_write(int tck, int tms, int tdi);
-void ep93xx_reset(int trst, int srst);
-
-int ep93xx_speed(int speed);
-int ep93xx_register_commands(struct command_context_s *cmd_ctx);
-int ep93xx_init(void);
-int ep93xx_quit(void);
-
-struct timespec ep93xx_zzzz;
-
-jtag_interface_t ep93xx_interface = 
-{
-       .name = "ep93xx",
-       
-       .execute_queue = bitbang_execute_queue,
-
-       .speed = ep93xx_speed,  
-       .register_commands = ep93xx_register_commands,
-       .init = ep93xx_init,
-       .quit = ep93xx_quit,
-};
-
-bitbang_interface_t ep93xx_bitbang =
-{
-       .read = ep93xx_read,
-       .write = ep93xx_write,
-       .reset = ep93xx_reset,
-       .blink = 0;
-};
-
-int ep93xx_read(void)
-{
-       return !!(*gpio_data_register & TDO_BIT);
-}
-
-void ep93xx_write(int tck, int tms, int tdi)
-{
-       if (tck)
-               output_value |= TCK_BIT;
-       else
-               output_value &= TCK_BIT;
-       
-       if (tms)
-               output_value |= TMS_BIT;
-       else
-               output_value &= TMS_BIT;
-       
-       if (tdi)
-               output_value |= TDI_BIT;
-       else
-               output_value &= TDI_BIT;
-
-       *gpio_data_register = output_value;
-       nanosleep(ep93xx_zzzz);
-}
-
-/* (1) assert or (0) deassert reset lines */
-void ep93xx_reset(int trst, int srst)
-{
-       if (trst == 0)
-               output_value |= TRST_BIT;
-       else if (trst == 1)
-               output_value &= TRST_BIT;
-
-       if (srst == 0)
-               output_value |= SRST_BIT;
-       else if (srst == 1)
-               output_value &= SRST_BIT;
-       
-       *gpio_data_register = output_value;
-       nanosleep(ep93xx_zzzz);
-}
-
-int ep93xx_speed(int speed)
-{
-       
-       return ERROR_OK;
-}
-
-int ep93xx_register_commands(struct command_context_s *cmd_ctx)
-{
-
-       return ERROR_OK;
-}
-
-static int set_gonk_mode(void)
-{
-       void *syscon;
-       u32 devicecfg;
-
-       syscon = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
-                       MAP_SHARED, dev_mem_fd, 0x80930000);
-       if (syscon == MAP_FAILED) {
-               perror("mmap");
-               return ERROR_JTAG_INIT_FAILED;
-       }
-
-       devicecfg = *((volatile int *)(syscon + 0x80));
-       *((volatile int *)(syscon + 0xc0)) = 0xaa;
-       *((volatile int *)(syscon + 0x80)) = devicecfg | 0x08000000;
-
-       munmap(syscon, 4096);
-
-       return ERROR_OK;
-}
-
-int ep93xx_init(void)
-{
-       int ret;
-
-       bitbang_interface = &ep93xx_bitbang;    
-
-       ep93xx_zzzz.tv_sec = 0;
-       ep93xx_zzzz.tv_nsec = 10000000;
-
-       dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
-       if (dev_mem_fd < 0) {
-               perror("open");
-               return ERROR_JTAG_INIT_FAILED;
-       }
-
-       gpio_controller = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
-                               MAP_SHARED, dev_mem_fd, 0x80840000);
-       if (gpio_controller == MAP_FAILED) {
-               perror("mmap");
-               close(dev_mem_fd);
-               return ERROR_JTAG_INIT_FAILED;
-       }
-
-       ret = set_gonk_mode();
-       if (ret != ERROR_OK) {
-               munmap(gpio_controller, 4096);
-               close(dev_mem_fd);
-               return ret;
-       }
-
-#if 0
-       /* Use GPIO port A.  */
-       gpio_data_register = gpio_controller + 0x00;
-       gpio_data_direction_register = gpio_controller + 0x10;
-
-
-       /* Use GPIO port B.  */
-       gpio_data_register = gpio_controller + 0x04;
-       gpio_data_direction_register = gpio_controller + 0x14;
-
-       /* Use GPIO port C.  */
-       gpio_data_register = gpio_controller + 0x08;
-       gpio_data_direction_register = gpio_controller + 0x18;
-
-       /* Use GPIO port D.  */
-       gpio_data_register = gpio_controller + 0x0c;
-       gpio_data_direction_register = gpio_controller + 0x1c;
-#endif
-
-       /* Use GPIO port C.  */
-       gpio_data_register = gpio_controller + 0x08;
-       gpio_data_direction_register = gpio_controller + 0x18;
-
-       printf("gpio_data_register      = %p\n", gpio_data_register);
-        printf("gpio_data_direction_reg = %p\n", gpio_data_direction_register); 
-       /*
-        * Configure bit 0 (TDO) as an input, and bits 1-5 (TDI, TCK
-        * TMS, TRST, SRST) as outputs.  Drive TDI and TCK low, and
-        * TMS/TRST/SRST high.
-        */
-       output_value = TMS_BIT | TRST_BIT | SRST_BIT | VCC_BIT;
-       *gpio_data_register = output_value;
-       nanosleep(ep93xx_zzzz);
-
-       /*
-        * Configure the direction register.  1 = output, 0 = input.
-        */
-       *gpio_data_direction_register =
-               TDI_BIT | TCK_BIT | TMS_BIT | TRST_BIT | SRST_BIT | VCC_BIT;
-
-       nanosleep(ep93xx_zzzz);
-       return ERROR_OK;
-}
-
-int ep93xx_quit(void)
-{
-
-       return ERROR_OK;
-}
+/***************************************************************************\r
+ *   Copyright (C) 2005 by Dominic Rath                                    *\r
+ *   Dominic.Rath@gmx.de                                                   *\r
+ *                                                                         *\r
+ *   This program is free software; you can redistribute it and/or modify  *\r
+ *   it under the terms of the GNU General Public License as published by  *\r
+ *   the Free Software Foundation; either version 2 of the License, or     *\r
+ *   (at your option) any later version.                                   *\r
+ *                                                                         *\r
+ *   This program is distributed in the hope that it will be useful,       *\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\r
+ *   GNU General Public License for more details.                          *\r
+ *                                                                         *\r
+ *   You should have received a copy of the GNU General Public License     *\r
+ *   along with this program; if not, write to the                         *\r
+ *   Free Software Foundation, Inc.,                                       *\r
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *\r
+ ***************************************************************************/\r
+#ifdef HAVE_CONFIG_H\r
+#include "config.h"\r
+#endif\r
+\r
+#include "log.h"\r
+#include "jtag.h"\r
+#include "bitbang.h"\r
+\r
+#define TDO_BIT                1\r
+#define TDI_BIT                2\r
+#define TCK_BIT                4\r
+#define TMS_BIT                8\r
+#define TRST_BIT       16\r
+#define SRST_BIT       32\r
+#define VCC_BIT                64\r
+\r
+/* system includes */\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <sys/mman.h>\r
+#include <unistd.h>\r
+#include <fcntl.h>\r
+\r
+static u8 output_value = 0x0;\r
+static int dev_mem_fd;\r
+static void *gpio_controller;\r
+static volatile u8 *gpio_data_register;\r
+static volatile u8 *gpio_data_direction_register;\r
+\r
+/* low level command set\r
+ */\r
+int ep93xx_read(void);\r
+void ep93xx_write(int tck, int tms, int tdi);\r
+void ep93xx_reset(int trst, int srst);\r
+\r
+int ep93xx_speed(int speed);\r
+int ep93xx_register_commands(struct command_context_s *cmd_ctx);\r
+int ep93xx_init(void);\r
+int ep93xx_quit(void);\r
+\r
+struct timespec ep93xx_zzzz;\r
+\r
+jtag_interface_t ep93xx_interface = \r
+{\r
+       .name = "ep93xx",\r
+       \r
+       .execute_queue = bitbang_execute_queue,\r
+\r
+       .speed = ep93xx_speed,  \r
+       .register_commands = ep93xx_register_commands,\r
+       .init = ep93xx_init,\r
+       .quit = ep93xx_quit,\r
+};\r
+\r
+bitbang_interface_t ep93xx_bitbang =\r
+{\r
+       .read = ep93xx_read,\r
+       .write = ep93xx_write,\r
+       .reset = ep93xx_reset,\r
+       .blink = 0;\r
+};\r
+\r
+int ep93xx_read(void)\r
+{\r
+       return !!(*gpio_data_register & TDO_BIT);\r
+}\r
+\r
+void ep93xx_write(int tck, int tms, int tdi)\r
+{\r
+       if (tck)\r
+               output_value |= TCK_BIT;\r
+       else\r
+               output_value &= TCK_BIT;\r
+       \r
+       if (tms)\r
+               output_value |= TMS_BIT;\r
+       else\r
+               output_value &= TMS_BIT;\r
+       \r
+       if (tdi)\r
+               output_value |= TDI_BIT;\r
+       else\r
+               output_value &= TDI_BIT;\r
+\r
+       *gpio_data_register = output_value;\r
+       nanosleep(ep93xx_zzzz);\r
+}\r
+\r
+/* (1) assert or (0) deassert reset lines */\r
+void ep93xx_reset(int trst, int srst)\r
+{\r
+       if (trst == 0)\r
+               output_value |= TRST_BIT;\r
+       else if (trst == 1)\r
+               output_value &= TRST_BIT;\r
+\r
+       if (srst == 0)\r
+               output_value |= SRST_BIT;\r
+       else if (srst == 1)\r
+               output_value &= SRST_BIT;\r
+       \r
+       *gpio_data_register = output_value;\r
+       nanosleep(ep93xx_zzzz);\r
+}\r
+\r
+int ep93xx_speed(int speed)\r
+{\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int ep93xx_register_commands(struct command_context_s *cmd_ctx)\r
+{\r
+\r
+       return ERROR_OK;\r
+}\r
+\r
+static int set_gonk_mode(void)\r
+{\r
+       void *syscon;\r
+       u32 devicecfg;\r
+\r
+       syscon = mmap(NULL, 4096, PROT_READ | PROT_WRITE,\r
+                       MAP_SHARED, dev_mem_fd, 0x80930000);\r
+       if (syscon == MAP_FAILED) {\r
+               perror("mmap");\r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+\r
+       devicecfg = *((volatile int *)(syscon + 0x80));\r
+       *((volatile int *)(syscon + 0xc0)) = 0xaa;\r
+       *((volatile int *)(syscon + 0x80)) = devicecfg | 0x08000000;\r
+\r
+       munmap(syscon, 4096);\r
+\r
+       return ERROR_OK;\r
+}\r
+\r
+int ep93xx_init(void)\r
+{\r
+       int ret;\r
+\r
+       bitbang_interface = &ep93xx_bitbang;    \r
+\r
+       ep93xx_zzzz.tv_sec = 0;\r
+       ep93xx_zzzz.tv_nsec = 10000000;\r
+\r
+       dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC);\r
+       if (dev_mem_fd < 0) {\r
+               perror("open");\r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+\r
+       gpio_controller = mmap(NULL, 4096, PROT_READ | PROT_WRITE,\r
+                               MAP_SHARED, dev_mem_fd, 0x80840000);\r
+       if (gpio_controller == MAP_FAILED) {\r
+               perror("mmap");\r
+               close(dev_mem_fd);\r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+\r
+       ret = set_gonk_mode();\r
+       if (ret != ERROR_OK) {\r
+               munmap(gpio_controller, 4096);\r
+               close(dev_mem_fd);\r
+               return ret;\r
+       }\r
+\r
+#if 0\r
+       /* Use GPIO port A.  */\r
+       gpio_data_register = gpio_controller + 0x00;\r
+       gpio_data_direction_register = gpio_controller + 0x10;\r
+\r
+\r
+       /* Use GPIO port B.  */\r
+       gpio_data_register = gpio_controller + 0x04;\r
+       gpio_data_direction_register = gpio_controller + 0x14;\r
+\r
+       /* Use GPIO port C.  */\r
+       gpio_data_register = gpio_controller + 0x08;\r
+       gpio_data_direction_register = gpio_controller + 0x18;\r
+\r
+       /* Use GPIO port D.  */\r
+       gpio_data_register = gpio_controller + 0x0c;\r
+       gpio_data_direction_register = gpio_controller + 0x1c;\r
+#endif\r
+\r
+       /* Use GPIO port C.  */\r
+       gpio_data_register = gpio_controller + 0x08;\r
+       gpio_data_direction_register = gpio_controller + 0x18;\r
+\r
+       INFO("gpio_data_register      = %p\n", gpio_data_register);\r
+       INFO("gpio_data_direction_reg = %p\n", gpio_data_direction_register); \r
+       /*\r
+        * Configure bit 0 (TDO) as an input, and bits 1-5 (TDI, TCK\r
+        * TMS, TRST, SRST) as outputs.  Drive TDI and TCK low, and\r
+        * TMS/TRST/SRST high.\r
+        */\r
+       output_value = TMS_BIT | TRST_BIT | SRST_BIT | VCC_BIT;\r
+       *gpio_data_register = output_value;\r
+       nanosleep(ep93xx_zzzz);\r
+\r
+       /*\r
+        * Configure the direction register.  1 = output, 0 = input.\r
+        */\r
+       *gpio_data_direction_register =\r
+               TDI_BIT | TCK_BIT | TMS_BIT | TRST_BIT | SRST_BIT | VCC_BIT;\r
+\r
+       nanosleep(ep93xx_zzzz);\r
+       return ERROR_OK;\r
+}\r
+\r
+int ep93xx_quit(void)\r
+{\r
+\r
+       return ERROR_OK;\r
+}\r
index 76741d9e5ad1b1b90c8097514165c8fbe805da2b..011eead1ea2adb9734c09841553776d4fb8d237a 100644 (file)
-/***************************************************************************
- *   Copyright (C) 2004, 2006 by Dominic Rath                              *
- *   Dominic.Rath@gmx.de                                                   *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#if IS_CYGWIN == 1
-#include "windows.h"
-#undef ERROR
-#endif
-
-#include "replacements.h"
-
-/* project specific includes */
-#include "log.h"
-#include "types.h"
-#include "jtag.h"
-#include "configuration.h"
-#include "time_support.h"
-
-/* system includes */
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-/* FT2232 access library includes */
-#if BUILD_FT2232_FTD2XX == 1
-#include <ftd2xx.h>
-#elif BUILD_FT2232_LIBFTDI == 1
-#include <ftdi.h>
-#endif
-
-#include <sys/time.h>
-#include <time.h>
-
-/* enable this to debug io latency
- */
-#if 0
-#define _DEBUG_USB_IO_
-#endif
-
-/* enable this to debug communication
- */
-#if 0
-#define _DEBUG_USB_COMMS_
-#endif
-
-int ft2232_execute_queue(void);
-
-int ft2232_speed(int speed);
-int ft2232_register_commands(struct command_context_s *cmd_ctx);
-int ft2232_init(void);
-int ft2232_quit(void);
-
-int ft2232_handle_device_desc_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int ft2232_handle_serial_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int ft2232_handle_layout_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int ft2232_handle_vid_pid_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-int ft2232_handle_latency_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-
-char *ft2232_device_desc = NULL;
-char *ft2232_serial = NULL;
-char *ft2232_layout = NULL;
-unsigned char ft2232_latency = 2;
-
-#define MAX_USB_IDS    8
-/* vid = pid = 0 marks the end of the list */
-static u16 ft2232_vid[MAX_USB_IDS+1] = { 0x0403, 0 };
-static u16 ft2232_pid[MAX_USB_IDS+1] = { 0x6010, 0 };
-
-typedef struct ft2232_layout_s
-{
-       char* name;
-       int(*init)(void);
-       void(*reset)(int trst, int srst);
-       void(*blink)(void);
-} ft2232_layout_t;
-
-/* init procedures for supported layouts */
-int usbjtag_init(void);
-int jtagkey_init(void);
-int olimex_jtag_init(void);
-int flyswatter_init(void);
-int turtle_init(void);
-int comstick_init(void);
-int stm32stick_init(void);
-
-/* reset procedures for supported layouts */
-void usbjtag_reset(int trst, int srst);
-void jtagkey_reset(int trst, int srst);
-void olimex_jtag_reset(int trst, int srst);
-void flyswatter_reset(int trst, int srst);
-void turtle_reset(int trst, int srst);
-void comstick_reset(int trst, int srst);
-void stm32stick_reset(int trst, int srst);
-
-/* blink procedures for layouts that support a blinking led */
-void olimex_jtag_blink(void);
-void turtle_jtag_blink(void);
-
-ft2232_layout_t ft2232_layouts[] =
-{
-       {"usbjtag", usbjtag_init, usbjtag_reset, NULL},
-       {"jtagkey", jtagkey_init, jtagkey_reset, NULL},
-       {"jtagkey_prototype_v1", jtagkey_init, jtagkey_reset, NULL},
-       {"oocdlink", jtagkey_init, jtagkey_reset, NULL},
-       {"signalyzer", usbjtag_init, usbjtag_reset, NULL},
-       {"evb_lm3s811", usbjtag_init, usbjtag_reset, NULL},
-       {"olimex-jtag", olimex_jtag_init, olimex_jtag_reset, olimex_jtag_blink},
-       {"flyswatter", flyswatter_init, flyswatter_reset, NULL},
-       {"turtelizer2", turtle_init, turtle_reset, turtle_jtag_blink},
-       {"comstick", comstick_init, comstick_reset, NULL},
-       {"stm32stick", stm32stick_init, stm32stick_reset, NULL},
-       {NULL, NULL, NULL},
-};
-
-static u8 nTRST, nTRSTnOE, nSRST, nSRSTnOE;
-
-static ft2232_layout_t *layout;
-static u8 low_output = 0x0;
-static u8 low_direction = 0x0;
-static u8 high_output = 0x0;
-static u8 high_direction = 0x0;
-
-#if BUILD_FT2232_FTD2XX == 1
-static FT_HANDLE ftdih = NULL;
-#elif BUILD_FT2232_LIBFTDI == 1
-static struct ftdi_context ftdic;
-#endif
-
-static u8 *ft2232_buffer = NULL;
-static int ft2232_buffer_size = 0;
-static int ft2232_read_pointer = 0;
-static int ft2232_expect_read = 0;
-#define FT2232_BUFFER_SIZE     131072
-#define BUFFER_ADD ft2232_buffer[ft2232_buffer_size++]
-#define BUFFER_READ ft2232_buffer[ft2232_read_pointer++]
-
-jtag_interface_t ft2232_interface = 
-{
-       
-       .name = "ft2232",
-       
-       .execute_queue = ft2232_execute_queue,
-       
-       .speed = ft2232_speed,
-       .register_commands = ft2232_register_commands,
-       .init = ft2232_init,
-       .quit = ft2232_quit,
-};
-
-int ft2232_write(u8 *buf, int size, u32* bytes_written)
-{
-#if BUILD_FT2232_FTD2XX == 1
-       FT_STATUS status;
-       DWORD dw_bytes_written;
-       if ((status = FT_Write(ftdih, buf, size, &dw_bytes_written)) != FT_OK)
-       {
-               *bytes_written = dw_bytes_written;
-               ERROR("FT_Write returned: %lu", status);
-               return ERROR_JTAG_DEVICE_ERROR;
-       }
-       else
-       {
-               *bytes_written = dw_bytes_written;
-               return ERROR_OK;        
-       }
-#elif BUILD_FT2232_LIBFTDI == 1
-       int retval;
-       if ((retval = ftdi_write_data(&ftdic, buf, size)) < 0)
-       {
-               *bytes_written = 0;
-               ERROR("ftdi_write_data: %s", ftdi_get_error_string(&ftdic));
-               return ERROR_JTAG_DEVICE_ERROR;
-       }
-       else
-       {
-               *bytes_written = retval;
-               return ERROR_OK;        
-       }
-#endif
-}
-
-int ft2232_read(u8* buf, int size, u32* bytes_read)
-{
-#if BUILD_FT2232_FTD2XX == 1
-       DWORD dw_bytes_read;
-       FT_STATUS status;
-       int timeout = 5;
-       *bytes_read = 0;
-
-       while ((*bytes_read < size) && timeout--)
-       {
-               if ((status = FT_Read(ftdih, buf + *bytes_read, size - 
-                       *bytes_read, &dw_bytes_read)) != FT_OK)         
-               {
-                       *bytes_read = 0; 
-                       ERROR("FT_Read returned: %lu", status);
-                       return ERROR_JTAG_DEVICE_ERROR;
-               }
-               *bytes_read += dw_bytes_read; 
-       }
-#elif BUILD_FT2232_LIBFTDI == 1
-       int retval;
-       int timeout = 100;
-       *bytes_read = 0;
-       
-       while ((*bytes_read < size) && timeout--)
-       {
-               if ((retval = ftdi_read_data(&ftdic, buf + *bytes_read, size - *bytes_read)) < 0)
-               {
-                       *bytes_read = 0;
-                       ERROR("ftdi_read_data: %s", ftdi_get_error_string(&ftdic));
-                       return ERROR_JTAG_DEVICE_ERROR;
-               }
-               *bytes_read += retval;
-       }
-#endif
-
-       if (*bytes_read < size)
-       {
-               ERROR("couldn't read the requested number of bytes from FT2232 device (%i < %i)", *bytes_read, size);
-               return ERROR_JTAG_DEVICE_ERROR;
-       }
-       
-       return ERROR_OK;
-}
-
-int ft2232_speed(int speed)
-{
-       u8 buf[3];
-       int retval;
-       u32 bytes_written;
-
-       buf[0] = 0x86; /* command "set divisor" */
-       buf[1] = speed & 0xff; /* valueL (0=6MHz, 1=3MHz, 2=2.0MHz, ...*/
-       buf[2] = (speed >> 8) & 0xff; /* valueH */
-       
-       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
-       if (((retval = ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
-       {
-               ERROR("couldn't set FT2232 TCK speed");
-               return retval;
-       }
-
-       jtag_speed = speed;
-       
-       return ERROR_OK;
-}
-
-int ft2232_register_commands(struct command_context_s *cmd_ctx)
-{
-       register_command(cmd_ctx, NULL, "ft2232_device_desc", ft2232_handle_device_desc_command,
-               COMMAND_CONFIG, NULL);
-       register_command(cmd_ctx, NULL, "ft2232_serial", ft2232_handle_serial_command,
-               COMMAND_CONFIG, NULL);
-       register_command(cmd_ctx, NULL, "ft2232_layout", ft2232_handle_layout_command,
-               COMMAND_CONFIG, NULL);
-       register_command(cmd_ctx, NULL, "ft2232_vid_pid", ft2232_handle_vid_pid_command,
-                                        COMMAND_CONFIG, NULL);
-       register_command(cmd_ctx, NULL, "ft2232_latency", ft2232_handle_latency_command,
-                                        COMMAND_CONFIG, NULL);
-       return ERROR_OK;
-}
-
-void ft2232_end_state(enum tap_state state)
-{
-       if (tap_move_map[state] != -1)
-               end_state = state;
-       else
-       {
-               ERROR("BUG: %i is not a valid end state", state);
-               exit(-1);
-       }
-}
-
-void ft2232_read_scan(enum scan_type type, u8* buffer, int scan_size)
-{
-       int num_bytes = ((scan_size + 7) / 8);
-       int bits_left = scan_size;
-       int cur_byte = 0;
-
-       while(num_bytes-- > 1)
-       {
-               buffer[cur_byte] = BUFFER_READ;
-               cur_byte++;
-               bits_left -= 8;
-       }
-
-       buffer[cur_byte] = 0x0;
-
-       if (bits_left > 1)
-       {
-               buffer[cur_byte] = BUFFER_READ >> 1;
-       }
-
-       buffer[cur_byte] = (buffer[cur_byte] | ((BUFFER_READ & 0x02) << 6)) >> (8 - bits_left);
-
-}
-
-void ft2232_debug_dump_buffer(void)
-{
-       int i;
-       char line[256];
-       char *line_p = line;
-       
-       for (i = 0; i < ft2232_buffer_size; i++)
-       {
-               line_p += snprintf(line_p, 256 - (line_p - line), "%2.2x ", ft2232_buffer[i]);
-               if (i % 16 == 15)
-               {
-                       DEBUG("%s", line);
-                       line_p = line;
-               }
-       }
-       
-       if (line_p != line)
-               DEBUG("%s", line);
-}
-
-int ft2232_send_and_recv(jtag_command_t *first, jtag_command_t *last)
-{
-       jtag_command_t *cmd;
-       u8 *buffer;
-       int scan_size;
-       enum scan_type type;
-       int retval;
-       u32 bytes_written;
-       u32 bytes_read;
-       
-#ifdef _DEBUG_USB_IO_
-       struct timeval start, inter, inter2, end;
-       struct timeval d_inter, d_inter2, d_end;
-#endif
-
-#ifdef _DEBUG_USB_COMMS_
-       DEBUG("write buffer (size %i):", ft2232_buffer_size);
-       ft2232_debug_dump_buffer();
-#endif
-
-#ifdef _DEBUG_USB_IO_
-       gettimeofday(&start, NULL);     
-#endif
-
-       if ((retval = ft2232_write(ft2232_buffer, ft2232_buffer_size, &bytes_written)) != ERROR_OK)
-       {
-               ERROR("couldn't write MPSSE commands to FT2232");
-               exit(-1);
-       }
-       
-#ifdef _DEBUG_USB_IO_
-       gettimeofday(&inter, NULL);     
-#endif
-       
-       if (ft2232_expect_read)
-       {
-               int timeout = 100;
-               ft2232_buffer_size = 0;
-               
-#ifdef _DEBUG_USB_IO_
-               gettimeofday(&inter2, NULL);    
-#endif
-               
-               if ((retval = ft2232_read(ft2232_buffer, ft2232_expect_read, &bytes_read)) != ERROR_OK)
-               {
-                       ERROR("couldn't read from FT2232");
-                       exit(-1);
-               }
-               
-#ifdef _DEBUG_USB_IO_
-               gettimeofday(&end, NULL);       
-
-               timeval_subtract(&d_inter, &inter, &start);
-               timeval_subtract(&d_inter2, &inter2, &start);
-               timeval_subtract(&d_end, &end, &start);
-
-               INFO("inter: %i.%i, inter2: %i.%i end: %i.%i", d_inter.tv_sec, d_inter.tv_usec, d_inter2.tv_sec, d_inter2.tv_usec, d_end.tv_sec, d_end.tv_usec);
-#endif
-       
-               
-               ft2232_buffer_size = bytes_read;
-               
-               if (ft2232_expect_read != ft2232_buffer_size)
-               {
-                       ERROR("ft2232_expect_read (%i) != ft2232_buffer_size (%i) (%i retries)", ft2232_expect_read, ft2232_buffer_size, 100 - timeout);
-                       ft2232_debug_dump_buffer();     
-
-                       exit(-1);
-               }
-
-#ifdef _DEBUG_USB_COMMS_
-               DEBUG("read buffer (%i retries): %i bytes", 100 - timeout, ft2232_buffer_size);
-               ft2232_debug_dump_buffer();
-#endif
-       }
-
-       ft2232_expect_read = 0;
-       ft2232_read_pointer = 0;
-       
-       /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
-        * that wasn't handled by a caller-provided error handler
-        */ 
-       retval = ERROR_OK;
-       
-       cmd = first;
-       while (cmd != last)
-       {
-               switch (cmd->type)
-               {
-                       case JTAG_SCAN:
-                               type = jtag_scan_type(cmd->cmd.scan);
-                               if (type != SCAN_OUT)
-                               {
-                                       scan_size = jtag_scan_size(cmd->cmd.scan);
-                                       buffer = calloc(CEIL(scan_size, 8), 1);
-                                       ft2232_read_scan(type, buffer, scan_size);
-                                       if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
-                                               retval = ERROR_JTAG_QUEUE_FAILED;
-                                       free(buffer);
-                               }
-                               break;
-                       default:
-                               break;
-               }
-               cmd = cmd->next;
-       }
-       
-       ft2232_buffer_size = 0;
-
-       return retval;
-}
-
-void ft2232_add_pathmove(pathmove_command_t *cmd)
-{
-       int num_states = cmd->num_states;
-       u8 tms_byte;
-       int state_count;
-
-       state_count = 0;
-       while (num_states)
-       {
-               tms_byte = 0x0;
-               int bit_count = 0;
-               
-               /* command "Clock Data to TMS/CS Pin (no Read)" */
-               BUFFER_ADD = 0x4b;
-               /* number of states remaining */
-               BUFFER_ADD = (num_states % 7) - 1;
-               
-               while (num_states % 7)
-               {
-                       if (tap_transitions[cur_state].low == cmd->path[state_count])
-                               buf_set_u32(&tms_byte, bit_count++, 1, 0x0);
-                       else if (tap_transitions[cur_state].high == cmd->path[state_count])
-                               buf_set_u32(&tms_byte, bit_count++, 1, 0x1);
-                       else
-                       {
-                               ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[cmd->path[state_count]]);
-                               exit(-1);
-                       }
-
-                       cur_state = cmd->path[state_count];
-                       state_count++;
-                       num_states--;
-               }
-               
-               BUFFER_ADD = tms_byte;
-       }
-       
-       end_state = cur_state;
-}
-
-void ft2232_add_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size)
-{
-       int num_bytes = (scan_size + 7) / 8;
-       int bits_left = scan_size;
-       int cur_byte = 0;
-       int last_bit;
-
-       if (!((!ir_scan && (cur_state == TAP_SD)) || (ir_scan && (cur_state == TAP_SI))))
-       {
-               /* command "Clock Data to TMS/CS Pin (no Read)" */
-               BUFFER_ADD = 0x4b;
-               /* scan 7 bit */
-               BUFFER_ADD = 0x6;
-               /* TMS data bits */
-               if (ir_scan)
-               {
-                       BUFFER_ADD = TAP_MOVE(cur_state, TAP_SI);
-                       cur_state = TAP_SI;
-               }
-               else
-               {
-                       BUFFER_ADD = TAP_MOVE(cur_state, TAP_SD);
-                       cur_state = TAP_SD;
-               }
-               //DEBUG("added TMS scan (no read)");
-       }
-       
-       /* add command for complete bytes */
-       while (num_bytes > 1)
-       {
-               int thisrun_bytes;
-               if (type == SCAN_IO)
-               {
-                       /* Clock Data Bytes In and Out LSB First */
-                       BUFFER_ADD = 0x39;
-                       //DEBUG("added TDI bytes (io %i)", num_bytes);
-               }
-               else if (type == SCAN_OUT)
-               {
-                       /* Clock Data Bytes Out on -ve Clock Edge LSB First (no Read) */
-                       BUFFER_ADD = 0x19;
-                       //DEBUG("added TDI bytes (o)");
-               }
-               else if (type == SCAN_IN)
-               {
-                       /* Clock Data Bytes In on +ve Clock Edge LSB First (no Write) */
-                       BUFFER_ADD = 0x28;
-                       //DEBUG("added TDI bytes (i %i)", num_bytes);
-               }
-               thisrun_bytes = (num_bytes > 65537) ? 65536 : (num_bytes - 1);
-               num_bytes -= thisrun_bytes;
-               BUFFER_ADD = (thisrun_bytes - 1) & 0xff;
-               BUFFER_ADD = ((thisrun_bytes - 1) >> 8) & 0xff;
-               if (type != SCAN_IN)
-               {
-                       /* add complete bytes */
-                       while(thisrun_bytes-- > 0)
-                       {
-                               BUFFER_ADD = buffer[cur_byte];
-                               cur_byte++;
-                               bits_left -= 8;
-                       }
-               }
-               else /* (type == SCAN_IN) */
-               {
-                       bits_left -= 8 * (thisrun_bytes);
-               }
-       }
-       
-       /* the most signifcant bit is scanned during TAP movement */
-       if (type != SCAN_IN)
-               last_bit = (buffer[cur_byte] >> (bits_left - 1)) & 0x1;
-       else
-               last_bit = 0;
-
-       /* process remaining bits but the last one */
-       if (bits_left > 1)
-       {
-               if (type == SCAN_IO)
-               {
-                       /* Clock Data Bits In and Out LSB First */
-                       BUFFER_ADD = 0x3b;
-                       //DEBUG("added TDI bits (io) %i", bits_left - 1);
-               }
-               else if (type == SCAN_OUT)
-               {
-                       /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */
-                       BUFFER_ADD = 0x1b;
-                       //DEBUG("added TDI bits (o)");
-               }
-               else if (type == SCAN_IN)
-               {
-                       /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */
-                       BUFFER_ADD = 0x2a;
-                       //DEBUG("added TDI bits (i %i)", bits_left - 1);
-               }
-               BUFFER_ADD = bits_left - 2;
-               if (type != SCAN_IN)
-                       BUFFER_ADD = buffer[cur_byte];
-       }
-
-       if ((ir_scan && (end_state == TAP_SI)) ||
-               (!ir_scan && (end_state == TAP_SD)))
-       {
-               if (type == SCAN_IO)
-               {
-                       /* Clock Data Bits In and Out LSB First */
-                       BUFFER_ADD = 0x3b;
-                       //DEBUG("added TDI bits (io) %i", bits_left - 1);
-               }
-               else if (type == SCAN_OUT)
-               {
-                       /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */
-                       BUFFER_ADD = 0x1b;
-                       //DEBUG("added TDI bits (o)");
-               }
-               else if (type == SCAN_IN)
-               {
-                       /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */
-                       BUFFER_ADD = 0x2a;
-                       //DEBUG("added TDI bits (i %i)", bits_left - 1);
-               }
-               BUFFER_ADD = 0x0;
-               BUFFER_ADD = last_bit;
-       }
-       else
-       {
-               /* move from Shift-IR/DR to end state */
-               if (type != SCAN_OUT)
-               {
-                       /* Clock Data to TMS/CS Pin with Read */
-                       BUFFER_ADD = 0x6b;
-                       //DEBUG("added TMS scan (read)");
-               }
-               else
-               {
-                       /* Clock Data to TMS/CS Pin (no Read) */
-                       BUFFER_ADD = 0x4b;
-                       //DEBUG("added TMS scan (no read)");
-               }
-               BUFFER_ADD = 0x6;
-               BUFFER_ADD = TAP_MOVE(cur_state, end_state) | (last_bit << 7);
-               cur_state = end_state;
-       }
-}
-
-int ft2232_large_scan(scan_command_t *cmd, enum scan_type type, u8 *buffer, int scan_size)
-{
-       int num_bytes = (scan_size + 7) / 8;
-       int bits_left = scan_size;
-       int cur_byte = 0;
-       int last_bit;
-       u8 *receive_buffer = malloc(CEIL(scan_size, 8));
-       u8 *receive_pointer = receive_buffer;
-       u32 bytes_written;
-       u32 bytes_read;
-       int retval;
-       int thisrun_read = 0;
-       
-       if (cmd->ir_scan)
-       {
-               ERROR("BUG: large IR scans are not supported");
-               exit(-1);
-       }
-
-       if (cur_state != TAP_SD)
-       {
-               /* command "Clock Data to TMS/CS Pin (no Read)" */
-               BUFFER_ADD = 0x4b;
-               /* scan 7 bit */
-               BUFFER_ADD = 0x6;
-               /* TMS data bits */
-               BUFFER_ADD = TAP_MOVE(cur_state, TAP_SD);
-               cur_state = TAP_SD;
-       }
-       
-       if ((retval = ft2232_write(ft2232_buffer, ft2232_buffer_size, &bytes_written)) != ERROR_OK)
-       {
-               ERROR("couldn't write MPSSE commands to FT2232");
-               exit(-1);
-       }
-       DEBUG("ft2232_buffer_size: %i, bytes_written: %i", ft2232_buffer_size, bytes_written);
-       ft2232_buffer_size = 0;
-       
-       /* add command for complete bytes */
-       while (num_bytes > 1)
-       {
-               int thisrun_bytes;
-               
-               if (type == SCAN_IO)
-               {
-                       /* Clock Data Bytes In and Out LSB First */
-                       BUFFER_ADD = 0x39;
-                       //DEBUG("added TDI bytes (io %i)", num_bytes);
-               }
-               else if (type == SCAN_OUT)
-               {
-                       /* Clock Data Bytes Out on -ve Clock Edge LSB First (no Read) */
-                       BUFFER_ADD = 0x19;
-                       //DEBUG("added TDI bytes (o)");
-               }
-               else if (type == SCAN_IN)
-               {
-                       /* Clock Data Bytes In on +ve Clock Edge LSB First (no Write) */
-                       BUFFER_ADD = 0x28;
-                       //DEBUG("added TDI bytes (i %i)", num_bytes);
-               }
-               thisrun_bytes = (num_bytes > 65537) ? 65536 : (num_bytes - 1);
-               thisrun_read = thisrun_bytes;
-               num_bytes -= thisrun_bytes;
-               BUFFER_ADD = (thisrun_bytes - 1) & 0xff;
-               BUFFER_ADD = ((thisrun_bytes - 1) >> 8) & 0xff;
-               if (type != SCAN_IN)
-               {
-                       /* add complete bytes */
-                       while(thisrun_bytes-- > 0)
-                       {
-                               BUFFER_ADD = buffer[cur_byte];
-                               cur_byte++;
-                               bits_left -= 8;
-                       }
-               }
-               else /* (type == SCAN_IN) */
-               {
-                       bits_left -= 8 * (thisrun_bytes);
-               }
-
-               if ((retval = ft2232_write(ft2232_buffer, ft2232_buffer_size, &bytes_written)) != ERROR_OK)
-               {
-                       ERROR("couldn't write MPSSE commands to FT2232");
-                       exit(-1);
-               }
-               DEBUG("ft2232_buffer_size: %i, bytes_written: %i", ft2232_buffer_size, bytes_written);
-               ft2232_buffer_size = 0;
-               
-               if (type != SCAN_OUT)
-               {
-                       if ((retval = ft2232_read(receive_pointer, thisrun_read, &bytes_read)) != ERROR_OK)
-                       {
-                               ERROR("couldn't read from FT2232");
-                               exit(-1);
-                       }
-                       DEBUG("thisrun_read: %i, bytes_read: %i", thisrun_read, bytes_read);
-                       receive_pointer += bytes_read;
-               }
-       }
-       
-       thisrun_read = 0;
-       
-       /* the most signifcant bit is scanned during TAP movement */
-       if (type != SCAN_IN)
-               last_bit = (buffer[cur_byte] >> (bits_left - 1)) & 0x1;
-       else
-               last_bit = 0;
-
-       /* process remaining bits but the last one */
-       if (bits_left > 1)
-       {
-               if (type == SCAN_IO)
-               {
-                       /* Clock Data Bits In and Out LSB First */
-                       BUFFER_ADD = 0x3b;
-                       //DEBUG("added TDI bits (io) %i", bits_left - 1);
-               }
-               else if (type == SCAN_OUT)
-               {
-                       /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */
-                       BUFFER_ADD = 0x1b;
-                       //DEBUG("added TDI bits (o)");
-               }
-               else if (type == SCAN_IN)
-               {
-                       /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */
-                       BUFFER_ADD = 0x2a;
-                       //DEBUG("added TDI bits (i %i)", bits_left - 1);
-               }
-               BUFFER_ADD = bits_left - 2;
-               if (type != SCAN_IN)
-                       BUFFER_ADD = buffer[cur_byte];
-                       
-               if (type != SCAN_OUT)
-                       thisrun_read += 2;
-       }
-
-       if (end_state == TAP_SD)
-       {
-               if (type == SCAN_IO)
-               {
-                       /* Clock Data Bits In and Out LSB First */
-                       BUFFER_ADD = 0x3b;
-                       //DEBUG("added TDI bits (io) %i", bits_left - 1);
-               }
-               else if (type == SCAN_OUT)
-               {
-                       /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */
-                       BUFFER_ADD = 0x1b;
-                       //DEBUG("added TDI bits (o)");
-               }
-               else if (type == SCAN_IN)
-               {
-                       /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */
-                       BUFFER_ADD = 0x2a;
-                       //DEBUG("added TDI bits (i %i)", bits_left - 1);
-               }
-               BUFFER_ADD = 0x0;
-               BUFFER_ADD = last_bit;
-       }
-       else
-       {
-               /* move from Shift-IR/DR to end state */
-               if (type != SCAN_OUT)
-               {
-                       /* Clock Data to TMS/CS Pin with Read */
-                       BUFFER_ADD = 0x6b;
-                       //DEBUG("added TMS scan (read)");
-               }
-               else
-               {
-                       /* Clock Data to TMS/CS Pin (no Read) */
-                       BUFFER_ADD = 0x4b;
-                       //DEBUG("added TMS scan (no read)");
-               }
-               BUFFER_ADD = 0x6;
-               BUFFER_ADD = TAP_MOVE(cur_state, end_state) | (last_bit << 7);
-               cur_state = end_state;
-       }
-       
-       if (type != SCAN_OUT)
-               thisrun_read += 1;
-       
-       if ((retval = ft2232_write(ft2232_buffer, ft2232_buffer_size, &bytes_written)) != ERROR_OK)
-       {
-               ERROR("couldn't write MPSSE commands to FT2232");
-               exit(-1);
-       }
-       DEBUG("ft2232_buffer_size: %i, bytes_written: %i", ft2232_buffer_size, bytes_written);
-       ft2232_buffer_size = 0;
-       
-       if (type != SCAN_OUT)
-       {
-               if ((retval = ft2232_read(receive_pointer, thisrun_read, &bytes_read)) != ERROR_OK)
-               {
-                       ERROR("couldn't read from FT2232");
-                       exit(-1);
-               }
-               DEBUG("thisrun_read: %i, bytes_read: %i", thisrun_read, bytes_read);
-               receive_pointer += bytes_read;
-       }
-       
-       return ERROR_OK;
-}
-
-int ft2232_predict_scan_out(int scan_size, enum scan_type type)
-{
-       int predicted_size = 3;
-       int num_bytes = (scan_size - 1) / 8;
-       
-       if (cur_state != TAP_SD)
-               predicted_size += 3;
-       
-       if (type == SCAN_IN)    /* only from device to host */
-       {
-               /* complete bytes */
-               predicted_size += (CEIL(num_bytes, 65536)) * 3;
-               /* remaining bits - 1 (up to 7) */
-               predicted_size += ((scan_size - 1) % 8) ? 2 : 0;
-       }
-       else                                    /* host to device, or bidirectional */
-       {
-               /* complete bytes */
-               predicted_size += num_bytes + (CEIL(num_bytes, 65536)) * 3;
-               /* remaining bits -1 (up to 7) */
-               predicted_size += ((scan_size - 1) % 8) ? 3 : 0;
-       }
-
-       return predicted_size;
-}
-
-int ft2232_predict_scan_in(int scan_size, enum scan_type type)
-{
-       int predicted_size = 0;
-       
-       if (type != SCAN_OUT)
-       {
-               /* complete bytes */
-               predicted_size += (CEIL(scan_size, 8) > 1) ? (CEIL(scan_size, 8) - 1) : 0;
-               /* remaining bits - 1 */
-               predicted_size += ((scan_size - 1) % 8) ? 1 : 0;
-               /* last bit (from TMS scan) */
-               predicted_size += 1;
-       }
-       
-       //DEBUG("scan_size: %i, predicted_size: %i", scan_size, predicted_size);
-
-       return predicted_size;
-}
-
-void usbjtag_reset(int trst, int srst)
-{
-       if (trst == 1)
-       {
-               cur_state = TAP_TLR;
-               if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
-                       low_direction |= nTRSTnOE;      /* switch to output pin (output is low) */
-               else
-                       low_output &= ~nTRST;   /* switch output low */
-       }
-       else if (trst == 0)
-       {
-               if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
-                       low_direction &= ~nTRSTnOE; /* switch to input pin (high-Z + internal and external pullup) */
-               else
-                       low_output |= nTRST; /* switch output high */
-       }
-
-       if (srst == 1)
-       {
-               if (jtag_reset_config & RESET_SRST_PUSH_PULL)
-                       low_output &= ~nSRST;   /* switch output low */
-               else
-                       low_direction |= nSRSTnOE;      /* switch to output pin (output is low) */
-       }
-       else if (srst == 0)
-       {
-               if (jtag_reset_config & RESET_SRST_PUSH_PULL)
-                       low_output |= nSRST;    /* switch output high */
-               else
-                       low_direction &= ~nSRSTnOE;     /* switch to input pin (high-Z) */
-       }
-       
-       /* command "set data bits low byte" */
-       BUFFER_ADD = 0x80;
-       BUFFER_ADD = low_output;
-       BUFFER_ADD = low_direction;
-
-}
-
-void jtagkey_reset(int trst, int srst)
-{
-       if (trst == 1)
-       {
-               cur_state = TAP_TLR;
-               if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
-                       high_output &= ~nTRSTnOE;
-               else
-                       high_output &= ~nTRST;
-       }
-       else if (trst == 0)
-       {
-               if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
-                       high_output |= nTRSTnOE;
-               else
-                       high_output |= nTRST;
-       }
-
-       if (srst == 1)
-       {
-               if (jtag_reset_config & RESET_SRST_PUSH_PULL)
-                       high_output &= ~nSRST;
-               else
-                       high_output &= ~nSRSTnOE;
-       }
-       else if (srst == 0)
-       {
-               if (jtag_reset_config & RESET_SRST_PUSH_PULL)
-                       high_output |= nSRST;
-               else
-                       high_output |= nSRSTnOE;
-       }
-       
-       /* command "set data bits high byte" */
-       BUFFER_ADD = 0x82;
-       BUFFER_ADD = high_output;
-       BUFFER_ADD = high_direction;
-       DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output, high_direction);
-}
-
-void olimex_jtag_reset(int trst, int srst)
-{
-       if (trst == 1)
-       {
-               cur_state = TAP_TLR;
-               if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
-                       high_output &= ~nTRSTnOE;
-               else
-                       high_output &= ~nTRST;
-       }
-       else if (trst == 0)
-       {
-               if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
-                       high_output |= nTRSTnOE;
-               else
-                       high_output |= nTRST;
-       }
-
-    if (srst == 1)
-    {
-        high_output |= nSRST;
-    }
-    else if (srst == 0)
-    {
-        high_output &= ~nSRST;
-    }
-
-    /* command "set data bits high byte" */
-    BUFFER_ADD = 0x82;
-    BUFFER_ADD = high_output;
-    BUFFER_ADD = high_direction;
-    DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output, high_direction);
-}
-
-void flyswatter_reset(int trst, int srst)
-{
-       if (trst == 1)
-       {
-               cur_state = TAP_TLR;
-               low_output &= ~nTRST;
-       }
-       else if (trst == 0)
-       {
-               low_output |= nTRST;
-       }
-
-    if (srst == 1)
-    {
-        low_output |= nSRST;
-    }
-    else if (srst == 0)
-    {
-        low_output &= ~nSRST;
-    }
-
-    /* command "set data bits low byte" */
-    BUFFER_ADD = 0x80;
-    BUFFER_ADD = low_output;
-    BUFFER_ADD = low_direction;
-    DEBUG("trst: %i, srst: %i, low_output: 0x%2.2x, low_direction: 0x%2.2x", trst, srst, low_output, low_direction);
-}
-
-void turtle_reset(int trst, int srst)
-{
-       trst = trst;
-       
-       if (srst == 1)
-       {
-               low_output |= nSRST;
-       }
-       else if (srst == 0)
-       {
-               low_output &= ~nSRST;
-       }
-       
-       /* command "set data bits low byte" */
-       BUFFER_ADD = 0x80;
-       BUFFER_ADD = low_output;
-       BUFFER_ADD = low_direction;
-       DEBUG("srst: %i, low_output: 0x%2.2x, low_direction: 0x%2.2x", srst, low_output, low_direction);
-}
-
-void comstick_reset(int trst, int srst)
-{
-       if (trst == 1)
-       {
-               cur_state = TAP_TLR;
-               high_output &= ~nTRST;
-       }
-       else if (trst == 0)
-       {
-               high_output |= nTRST;
-       }
-
-    if (srst == 1)
-    {
-        high_output &= ~nSRST;
-    }
-    else if (srst == 0)
-    {
-        high_output |= nSRST;
-    }
-       
-       /* command "set data bits high byte" */
-       BUFFER_ADD = 0x82;
-       BUFFER_ADD = high_output;
-       BUFFER_ADD = high_direction;
-       DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output, high_direction);
-}
-
-void stm32stick_reset(int trst, int srst)
-{
-       if (trst == 1)
-       {
-               cur_state = TAP_TLR;
-               high_output &= ~nTRST;
-       }
-       else if (trst == 0)
-       {
-               high_output |= nTRST;
-       }
-
-    if (srst == 1)
-    {
-        low_output &= ~nSRST;
-    }
-    else if (srst == 0)
-    {
-        low_output |= nSRST;
-    }
-       
-       /* command "set data bits low byte" */
-       BUFFER_ADD = 0x80;
-       BUFFER_ADD = low_output;
-       BUFFER_ADD = low_direction;
-       
-       /* command "set data bits high byte" */
-       BUFFER_ADD = 0x82;
-       BUFFER_ADD = high_output;
-       BUFFER_ADD = high_direction;
-       DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output, high_direction);
-}
-
-int ft2232_execute_queue()
-{
-       jtag_command_t *cmd = jtag_command_queue; /* currently processed command */
-       jtag_command_t *first_unsent = cmd;     /* next command that has to be sent */
-       u8 *buffer;
-       int scan_size;  /* size of IR or DR scan */
-       enum scan_type type;
-       int i;
-       int predicted_size = 0;
-       int require_send = 0;
-       int retval;
-       
-       /* return ERROR_OK, unless ft2232_send_and_recv reports a failed check
-        * that wasn't handled by a caller-provided error handler
-        */ 
-       retval = ERROR_OK;
-
-       ft2232_buffer_size = 0;
-       ft2232_expect_read = 0;
-       
-       /* blink, if the current layout has that feature */
-       if (layout->blink)
-               layout->blink();
-
-       while (cmd)
-       {
-               switch(cmd->type)
-               {
-                       case JTAG_END_STATE:
-                               if (cmd->cmd.end_state->end_state != -1)
-                                       ft2232_end_state(cmd->cmd.end_state->end_state);
-                               break;
-                       case JTAG_RESET:
-                               /* only send the maximum buffer size that FT2232C can handle */
-                               predicted_size = 3;
-                               if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
-                               {
-                                       if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
-                                               retval = ERROR_JTAG_QUEUE_FAILED;
-                                       require_send = 0;
-                                       first_unsent = cmd;
-                               }
-
-                               layout->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
-                               require_send = 1;
-                               
-#ifdef _DEBUG_JTAG_IO_                         
-                               DEBUG("trst: %i, srst: %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
-#endif
-                               break;
-                       case JTAG_RUNTEST:
-                               /* only send the maximum buffer size that FT2232C can handle */
-                               predicted_size = 0;
-                               if (cur_state != TAP_RTI)
-                                       predicted_size += 3;
-                               predicted_size += 3 * CEIL(cmd->cmd.runtest->num_cycles, 7);
-                               if ((cmd->cmd.runtest->end_state != -1) && (cmd->cmd.runtest->end_state != TAP_RTI))
-                                       predicted_size += 3;
-                               if ((cmd->cmd.runtest->end_state == -1) && (end_state != TAP_RTI))
-                                       predicted_size += 3;
-                               if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
-                               {
-                                       if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
-                                               retval = ERROR_JTAG_QUEUE_FAILED;
-                                       require_send = 0;
-                                       first_unsent = cmd;
-                               }
-                               if (cur_state != TAP_RTI)
-                               {
-                                       /* command "Clock Data to TMS/CS Pin (no Read)" */
-                                       BUFFER_ADD = 0x4b;
-                                       /* scan 7 bit */
-                                       BUFFER_ADD = 0x6;
-                                       /* TMS data bits */
-                                       BUFFER_ADD = TAP_MOVE(cur_state, TAP_RTI);
-                                       cur_state = TAP_RTI;
-                                       require_send = 1;
-                               }
-                               i = cmd->cmd.runtest->num_cycles;
-                               while (i > 0)
-                               {
-                                       /* command "Clock Data to TMS/CS Pin (no Read)" */
-                                       BUFFER_ADD = 0x4b;
-                                       /* scan 7 bit */
-                                       BUFFER_ADD = (i > 7) ? 6 : (i - 1);
-                                       /* TMS data bits */
-                                       BUFFER_ADD = 0x0;
-                                       cur_state = TAP_RTI;
-                                       i -= (i > 7) ? 7 : i;
-                                       //DEBUG("added TMS scan (no read)");
-                               }
-                               if (cmd->cmd.runtest->end_state != -1)
-                                       ft2232_end_state(cmd->cmd.runtest->end_state);
-                               if (cur_state != end_state)
-                               {
-                                       /* command "Clock Data to TMS/CS Pin (no Read)" */
-                                       BUFFER_ADD = 0x4b;
-                                       /* scan 7 bit */
-                                       BUFFER_ADD = 0x6;
-                                       /* TMS data bits */
-                                       BUFFER_ADD = TAP_MOVE(cur_state, end_state);
-                                       cur_state = end_state;
-                                       //DEBUG("added TMS scan (no read)");
-                               }
-                               require_send = 1;
-#ifdef _DEBUG_JTAG_IO_                         
-                               DEBUG("runtest: %i, end in %i", cmd->cmd.runtest->num_cycles, end_state);
-#endif
-                               break;
-                       case JTAG_STATEMOVE:
-                               /* only send the maximum buffer size that FT2232C can handle */
-                               predicted_size = 3;
-                               if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
-                               {
-                                       if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
-                                               retval = ERROR_JTAG_QUEUE_FAILED;
-                                       require_send = 0;
-                                       first_unsent = cmd;
-                               }
-                               if (cmd->cmd.statemove->end_state != -1)
-                                       ft2232_end_state(cmd->cmd.statemove->end_state);
-                               /* command "Clock Data to TMS/CS Pin (no Read)" */
-                               BUFFER_ADD = 0x4b;
-                               /* scan 7 bit */
-                               BUFFER_ADD = 0x6;
-                               /* TMS data bits */
-                               BUFFER_ADD = TAP_MOVE(cur_state, end_state);
-                               //DEBUG("added TMS scan (no read)");
-                               cur_state = end_state;
-                               require_send = 1;
-#ifdef _DEBUG_JTAG_IO_                         
-                               DEBUG("statemove: %i", end_state);
-#endif
-                               break;
-                       case JTAG_PATHMOVE:
-                               /* only send the maximum buffer size that FT2232C can handle */
-                               predicted_size = 3 * CEIL(cmd->cmd.pathmove->num_states, 7);
-                               if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
-                               {
-                                       if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
-                                               retval = ERROR_JTAG_QUEUE_FAILED;
-                                       require_send = 0;
-                                       first_unsent = cmd;
-                               }
-                               ft2232_add_pathmove(cmd->cmd.pathmove);
-                               require_send = 1;
-#ifdef _DEBUG_JTAG_IO_                         
-                               DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
-#endif
-                               break;
-                       case JTAG_SCAN:
-                               scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
-                               type = jtag_scan_type(cmd->cmd.scan);
-                               predicted_size = ft2232_predict_scan_out(scan_size, type);
-                               if ((predicted_size + 1) > FT2232_BUFFER_SIZE)
-                               {
-                                       DEBUG("oversized ft2232 scan (predicted_size > FT2232_BUFFER_SIZE)");
-                                       /* unsent commands before this */
-                                       if (first_unsent != cmd)
-                                               if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
-                                                       retval = ERROR_JTAG_QUEUE_FAILED;
-                                       
-                                       /* current command */
-                                       if (cmd->cmd.scan->end_state != -1)
-                                               ft2232_end_state(cmd->cmd.scan->end_state);
-                                       ft2232_large_scan(cmd->cmd.scan, type, buffer, scan_size);
-                                       require_send = 0;
-                                       first_unsent = cmd->next;
-                                       if (buffer)
-                                               free(buffer);
-                                       break;
-                               }
-                               else if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
-                               {
-                                       DEBUG("ft2232 buffer size reached, sending queued commands (first_unsent: %p, cmd: %p)", first_unsent, cmd);
-                                       if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
-                                               retval = ERROR_JTAG_QUEUE_FAILED;
-                                       require_send = 0;
-                                       first_unsent = cmd;
-                               }
-                               ft2232_expect_read += ft2232_predict_scan_in(scan_size, type);
-                               //DEBUG("new read size: %i", ft2232_expect_read);
-                               if (cmd->cmd.scan->end_state != -1)
-                                       ft2232_end_state(cmd->cmd.scan->end_state);
-                               ft2232_add_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
-                               require_send = 1;
-                               if (buffer)
-                                       free(buffer);
-#ifdef _DEBUG_JTAG_IO_                         
-                               DEBUG("%s scan, %i bit, end in %i", (cmd->cmd.scan->ir_scan) ? "IR" : "DR", scan_size, end_state);
-#endif
-                               break;
-                       case JTAG_SLEEP:
-                               if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
-                                       retval = ERROR_JTAG_QUEUE_FAILED;
-                               first_unsent = cmd->next;
-                               jtag_sleep(cmd->cmd.sleep->us);
-#ifdef _DEBUG_JTAG_IO_                         
-                               DEBUG("sleep %i usec", cmd->cmd.sleep->us);
-#endif
-                               break;
-                       default:
-                               ERROR("BUG: unknown JTAG command type encountered");
-                               exit(-1);
-               }
-               cmd = cmd->next;
-       }
-
-       if (require_send > 0)
-               if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
-                       retval = ERROR_JTAG_QUEUE_FAILED;
-
-       return retval;
-}
-
-#if BUILD_FT2232_FTD2XX == 1
-static int ft2232_init_ftd2xx(u16 vid, u16 pid, int more, int *try_more)
-{
-       FT_STATUS status;
-       DWORD openex_flags = 0;
-       char *openex_string = NULL;
-       u8 latency_timer;
-
-       DEBUG("'ft2232' interface using FTD2XX with '%s' layout (%4.4x:%4.4x)",
-           ft2232_layout, vid, pid);
-
-#if IS_WIN32 == 0
-       /* Add non-standard Vid/Pid to the linux driver */
-       if ((status = FT_SetVIDPID(vid, pid)) != FT_OK)
-       {
-               WARNING("couldn't add %4.4x:%4.4x",
-                   vid, pid);
-       }
-#endif
-
-       if (ft2232_device_desc && ft2232_serial)
-       {
-               WARNING("can't open by device description and serial number, giving precedence to serial");
-               ft2232_device_desc = NULL;
-       }
-       
-       if (ft2232_device_desc)
-       {
-               openex_string = ft2232_device_desc;
-               openex_flags = FT_OPEN_BY_DESCRIPTION;
-       }
-       else if (ft2232_serial)
-       {
-               openex_string = ft2232_serial;
-               openex_flags = FT_OPEN_BY_SERIAL_NUMBER;
-       }
-       else
-       {
-               ERROR("neither device description nor serial number specified");
-               ERROR("please add \"ft2232_device_desc <string>\" or \"ft2232_serial <string>\" to your .cfg file");
-               
-               return ERROR_JTAG_INIT_FAILED;  
-       }
-
-       if ((status = FT_OpenEx(openex_string, openex_flags, &ftdih)) != FT_OK)
-       {
-               DWORD num_devices;
-               
-               if (more) {
-                       WARNING("unable to open ftdi device (trying more): %lu",
-                           status);
-                       *try_more = 1;
-                       return ERROR_JTAG_INIT_FAILED;
-               }
-               ERROR("unable to open ftdi device: %lu", status);
-               status = FT_ListDevices(&num_devices, NULL, FT_LIST_NUMBER_ONLY);
-               if (status == FT_OK)
-               {
-                       char **desc_array = malloc(sizeof(char*) * (num_devices + 1));
-                       int i;
-
-                       for (i = 0; i < num_devices; i++)
-                               desc_array[i] = malloc(64);
-                       desc_array[num_devices] = NULL;
-
-                       status = FT_ListDevices(desc_array, &num_devices, FT_LIST_ALL | openex_flags);
-
-                       if (status == FT_OK)
-                       {
-                               ERROR("ListDevices: %lu\n", num_devices);
-                               for (i = 0; i < num_devices; i++)
-                                       ERROR("%i: %s", i, desc_array[i]);
-                       }
-                       
-                       for (i = 0; i < num_devices; i++)
-                               free(desc_array[i]);
-                       free(desc_array);
-               }
-               else
-               {
-                       printf("ListDevices: NONE\n");
-               }
-               return ERROR_JTAG_INIT_FAILED;
-       }
-
-       if ((status = FT_SetLatencyTimer(ftdih, ft2232_latency)) != FT_OK)
-       {
-               ERROR("unable to set latency timer: %lu", status);
-               return ERROR_JTAG_INIT_FAILED;
-       }
-       
-       if ((status = FT_GetLatencyTimer(ftdih, &latency_timer)) != FT_OK)
-       {
-               ERROR("unable to get latency timer: %lu", status);
-               return ERROR_JTAG_INIT_FAILED;
-       }
-       else
-       {
-               DEBUG("current latency timer: %i", latency_timer);
-       }
-       
-       if ((status = FT_SetTimeouts(ftdih, 5000, 5000)) != FT_OK)
-       {
-               ERROR("unable to set timeouts: %lu", status);
-               return ERROR_JTAG_INIT_FAILED;
-       }
-
-       if ((status = FT_SetBitMode(ftdih, 0x0b, 2)) != FT_OK)
-       {
-               ERROR("unable to enable bit i/o mode: %lu", status);
-               return ERROR_JTAG_INIT_FAILED;
-       }
-
-       return ERROR_OK;
-}
-
-static int ft2232_purge_ftd2xx(void)
-{
-       FT_STATUS status;
-
-       if ((status = FT_Purge(ftdih, FT_PURGE_RX | FT_PURGE_TX)) != FT_OK)
-       {
-               ERROR("error purging ftd2xx device: %lu", status);
-               return ERROR_JTAG_INIT_FAILED;
-       }
-
-       return ERROR_OK;
-}
-#endif /* BUILD_FT2232_FTD2XX == 1 */
-
-#if BUILD_FT2232_LIBFTDI == 1
-static int ft2232_init_libftdi(u16 vid, u16 pid, int more, int *try_more)
-{
-       u8 latency_timer;
-
-       DEBUG("'ft2232' interface using libftdi with '%s' layout (%4.4x:%4.4x)",
-           ft2232_layout, vid, pid);
-
-       if (ftdi_init(&ftdic) < 0)
-               return ERROR_JTAG_INIT_FAILED;
-
-       /* context, vendor id, product id */
-       if (ftdi_usb_open_desc(&ftdic, vid, pid, ft2232_device_desc,
-           ft2232_serial) < 0) {
-               if (more)
-                       WARNING("unable to open ftdi device (trying more): %s",
-                            ftdic.error_str);
-               else
-                       ERROR("unable to open ftdi device: %s", ftdic.error_str);
-               *try_more = 1;
-               return ERROR_JTAG_INIT_FAILED;
-       }
-
-       if (ftdi_set_interface(&ftdic, INTERFACE_A) < 0)
-       {
-               ERROR("unable to select FT2232 channel A: %s", ftdic.error_str);
-               return ERROR_JTAG_INIT_FAILED;
-       }
-
-       if (ftdi_usb_reset(&ftdic) < 0)
-       {
-               ERROR("unable to reset ftdi device");
-               return ERROR_JTAG_INIT_FAILED;
-       }
-
-       if (ftdi_set_latency_timer(&ftdic, ft2232_latency) < 0)
-       {
-               ERROR("unable to set latency timer");
-               return ERROR_JTAG_INIT_FAILED;
-       }
-       
-       if (ftdi_get_latency_timer(&ftdic, &latency_timer) < 0)
-       {
-               ERROR("unable to get latency timer");
-               return ERROR_JTAG_INIT_FAILED;
-       }
-       else
-       {
-               DEBUG("current latency timer: %i", latency_timer);
-       }
-
-       ftdi_set_bitmode(&ftdic, 0x0b, 2); /* ctx, JTAG I/O mask */
-
-       return ERROR_OK;
-}
-
-static int ft2232_purge_libftdi(void)
-{
-       if (ftdi_usb_purge_buffers(&ftdic) < 0)
-       {
-               ERROR("ftdi_purge_buffers: %s", ftdic.error_str);
-               return ERROR_JTAG_INIT_FAILED;
-       }
-
-       return ERROR_OK;
-}
-#endif /* BUILD_FT2232_LIBFTDI == 1 */
-
-int ft2232_init(void)
-{
-       u8 buf[1];
-       int retval;
-       u32 bytes_written;
-       ft2232_layout_t *cur_layout = ft2232_layouts;
-       int i;
-       
-       if ((ft2232_layout == NULL) || (ft2232_layout[0] == 0))
-       {
-               ft2232_layout = "usbjtag";
-               WARNING("No ft2232 layout specified, using default 'usbjtag'");
-       }
-       
-       while (cur_layout->name)
-       {
-               if (strcmp(cur_layout->name, ft2232_layout) == 0)
-               {
-                       layout = cur_layout;
-                       break;
-               }
-               cur_layout++;
-       }
-
-       if (!layout)
-       {
-               ERROR("No matching layout found for %s", ft2232_layout);
-               return ERROR_JTAG_INIT_FAILED;
-       }
-       
-       for (i = 0; 1; i++) {
-               /*
-                * "more indicates that there are more IDs to try, so we should
-                * not print an error for an ID mismatch (but for anything
-                * else, we should).
-                *
-                * try_more indicates that the error code returned indicates an
-                * ID mismatch (and nothing else) and that we should proceeed
-                * with the next ID pair.
-                */
-               int more = ft2232_vid[i+1] || ft2232_pid[i+1];
-               int try_more = 0;
-
-#if BUILD_FT2232_FTD2XX == 1
-               retval = ft2232_init_ftd2xx(ft2232_vid[i], ft2232_pid[i],
-                   more, &try_more);
-#elif BUILD_FT2232_LIBFTDI == 1
-               retval = ft2232_init_libftdi(ft2232_vid[i], ft2232_pid[i],
-                   more, &try_more);
-#endif 
-               if (retval >= 0)
-                       break;
-               if (!more || !try_more)
-                       return retval;
-       }
-
-       ft2232_buffer_size = 0;
-       ft2232_buffer = malloc(FT2232_BUFFER_SIZE);
-
-       if (layout->init() != ERROR_OK)
-               return ERROR_JTAG_INIT_FAILED;
-
-       ft2232_speed(jtag_speed);
-
-       buf[0] = 0x85; /* Disconnect TDI/DO to TDO/DI for Loopback */
-       if (((retval = ft2232_write(buf, 1, &bytes_written)) != ERROR_OK) || (bytes_written != 1))
-       {
-               ERROR("couldn't write to FT2232 to disable loopback");
-               return ERROR_JTAG_INIT_FAILED;
-       }
-
-#if BUILD_FT2232_FTD2XX == 1
-       return ft2232_purge_ftd2xx();
-#elif BUILD_FT2232_LIBFTDI == 1
-       return ft2232_purge_libftdi();
-#endif 
-
-       return ERROR_OK;
-}
-
-int usbjtag_init(void)
-{
-       u8 buf[3];
-       u32 bytes_written;
-       
-       low_output = 0x08;
-       low_direction = 0x0b;
-       
-       if (strcmp(ft2232_layout, "usbjtag") == 0)
-       {
-               nTRST = 0x10;
-               nTRSTnOE = 0x10;
-               nSRST = 0x40;
-               nSRSTnOE = 0x40;
-       }
-       else if (strcmp(ft2232_layout, "signalyzer") == 0)
-       {
-               nTRST = 0x10;
-               nTRSTnOE = 0x10;
-               nSRST = 0x20;
-               nSRSTnOE = 0x20;
-       }
-       else if (strcmp(ft2232_layout, "evb_lm3s811") == 0)
-       {
-               nTRST = 0x0;
-               nTRSTnOE = 0x00;
-               nSRST = 0x20;
-               nSRSTnOE = 0x20;
-               low_output = 0x88;
-               low_direction = 0x8b;
-       }
-       else
-       {
-               ERROR("BUG: usbjtag_init called for unknown layout '%s'", ft2232_layout);
-               return ERROR_JTAG_INIT_FAILED;  
-       }
-       
-       if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
-       {
-               low_direction &= ~nTRSTnOE; /* nTRST input */
-               low_output &= ~nTRST; /* nTRST = 0 */
-       }
-       else
-       {
-               low_direction |= nTRSTnOE; /* nTRST output */
-               low_output |= nTRST; /* nTRST = 1 */
-       }
-       
-       if (jtag_reset_config & RESET_SRST_PUSH_PULL)
-       {
-               low_direction |= nSRSTnOE; /* nSRST output */
-               low_output |= nSRST; /* nSRST = 1 */
-       }
-       else
-       {
-               low_direction &= ~nSRSTnOE; /* nSRST input */
-               low_output &= ~nSRST; /* nSRST = 0 */
-       }
-       
-       /* initialize low byte for jtag */
-       buf[0] = 0x80; /* command "set data bits low byte" */
-       buf[1] = low_output; /* value (TMS=1,TCK=0, TDI=0, xRST high) */
-       buf[2] = low_direction; /* dir (output=1), TCK/TDI/TMS=out, TDO=in */
-       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
-       
-       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
-       {
-               ERROR("couldn't initialize FT2232 with 'USBJTAG' layout"); 
-               return ERROR_JTAG_INIT_FAILED;
-       }
-
-       return ERROR_OK;
-}
-
-int jtagkey_init(void)
-{
-       u8 buf[3];
-       u32 bytes_written;
-       
-       low_output = 0x08;
-       low_direction = 0x1b;
-       
-       /* initialize low byte for jtag */
-       buf[0] = 0x80; /* command "set data bits low byte" */
-       buf[1] = low_output; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */
-       buf[2] = low_direction; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */
-       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
-       
-       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
-       {
-               ERROR("couldn't initialize FT2232 with 'JTAGkey' layout"); 
-               return ERROR_JTAG_INIT_FAILED;
-       }
-       
-       if (strcmp(layout->name, "jtagkey") == 0)
-       {
-               nTRST = 0x01;
-               nTRSTnOE = 0x4;
-               nSRST = 0x02;
-               nSRSTnOE = 0x08;
-       }
-       else if ((strcmp(layout->name, "jtagkey_prototype_v1") == 0) ||
-               (strcmp(layout->name, "oocdlink") == 0))
-       {
-               nTRST = 0x02;
-               nTRSTnOE = 0x1;
-               nSRST = 0x08;
-               nSRSTnOE = 0x04;
-       }
-       else
-       {
-               ERROR("BUG: jtagkey_init called for non jtagkey layout");
-               exit(-1);
-       }
-       
-       high_output = 0x0;
-       high_direction = 0x0f;
-
-       if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
-       {
-               high_output |= nTRSTnOE;
-               high_output &= ~nTRST;
-       }
-       else
-       {
-               high_output &= ~nTRSTnOE;
-               high_output |= nTRST;
-       }
-       
-       if (jtag_reset_config & RESET_SRST_PUSH_PULL)
-       {
-               high_output &= ~nSRSTnOE;
-               high_output |= nSRST;
-       }
-       else
-       {
-               high_output |= nSRSTnOE;
-               high_output &= ~nSRST;
-       }
-       
-       /* initialize high port */
-       buf[0] = 0x82; /* command "set data bits high byte" */
-       buf[1] = high_output; /* value */
-       buf[2] = high_direction;   /* all outputs (xRST and xRSTnOE) */
-       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
-       
-       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
-       {
-               ERROR("couldn't initialize FT2232 with 'JTAGkey' layout"); 
-               return ERROR_JTAG_INIT_FAILED;
-       }
-       
-       return ERROR_OK;
-}
-
-int olimex_jtag_init(void)
-{
-       u8 buf[3];
-       u32 bytes_written;
-       
-       low_output = 0x08;
-       low_direction = 0x1b;
-       
-       /* initialize low byte for jtag */
-       buf[0] = 0x80; /* command "set data bits low byte" */
-       buf[1] = low_output; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */
-       buf[2] = low_direction; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */
-       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
-       
-       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
-       {
-               ERROR("couldn't initialize FT2232 with 'JTAGkey' layout"); 
-               return ERROR_JTAG_INIT_FAILED;
-       }
-       
-       nTRST = 0x01;
-       nTRSTnOE = 0x4;
-       nSRST = 0x02;
-       nSRSTnOE = 0x00; /* no output enable for nSRST */
-
-       high_output = 0x0;
-       high_direction = 0x0f;
-
-       if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)
-       {
-               high_output |= nTRSTnOE;
-               high_output &= ~nTRST;
-       }
-       else
-       {
-               high_output &= ~nTRSTnOE;
-               high_output |= nTRST;
-       }
-       
-       if (jtag_reset_config & RESET_SRST_PUSH_PULL)
-       {
-               ERROR("can't set nSRST to push-pull on the Olimex ARM-USB-OCD");
-       }
-       else
-       {
-               high_output &= ~nSRST;
-       }
-       
-       /* turn red LED on */
-       high_output |= 0x08;
-       
-       /* initialize high port */
-       buf[0] = 0x82; /* command "set data bits high byte" */
-       buf[1] = high_output; /* value */
-       buf[2] = high_direction;   /* all outputs (xRST and xRSTnOE) */
-       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
-       
-       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
-       {
-               ERROR("couldn't initialize FT2232 with 'JTAGkey' layout"); 
-               return ERROR_JTAG_INIT_FAILED;
-       }
-       
-       return ERROR_OK;
-}
-
-int flyswatter_init(void)
-{
-       u8 buf[3];
-       u32 bytes_written;
-       
-       low_output = 0x18;
-       low_direction = 0xfb;
-       
-       /* initialize low byte for jtag */
-       buf[0] = 0x80; /* command "set data bits low byte" */
-       buf[1] = low_output; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */
-       buf[2] = low_direction; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE[12]=out, n[ST]srst=out */
-       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
-       
-       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
-       {
-               ERROR("couldn't initialize FT2232 with 'flyswatter' layout"); 
-               return ERROR_JTAG_INIT_FAILED;
-       }
-       
-       nTRST = 0x10;
-       nTRSTnOE = 0x0; /* not output enable for nTRST */
-       nSRST = 0x20;
-       nSRSTnOE = 0x00; /* no output enable for nSRST */
-
-       high_output = 0x00;
-       high_direction = 0x0c;
-
-       /* turn red LED1 on, LED2 off */
-       high_output |= 0x08;
-       
-       /* initialize high port */
-       buf[0] = 0x82; /* command "set data bits high byte" */
-       buf[1] = high_output; /* value */
-       buf[2] = high_direction;   /* all outputs (xRST and xRSTnOE) */
-       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
-       
-       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
-       {
-               ERROR("couldn't initialize FT2232 with 'flyswatter' layout"); 
-               return ERROR_JTAG_INIT_FAILED;
-       }
-       
-       return ERROR_OK;
-}
-
-int turtle_init(void)
-{
-       u8 buf[3];
-       u32 bytes_written;
-       
-       low_output = 0x08;
-       low_direction = 0x5b;
-       
-       /* initialize low byte for jtag */
-       buf[0] = 0x80; /* command "set data bits low byte" */
-       buf[1] = low_output; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */
-       buf[2] = low_direction; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */
-       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
-       
-       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
-       {
-               ERROR("couldn't initialize FT2232 with 'turtelizer2' layout"); 
-               return ERROR_JTAG_INIT_FAILED;
-       }
-       
-       nSRST = 0x40;
-       
-       high_output = 0x00;
-       high_direction = 0x0C;
-       
-       /* initialize high port */
-       buf[0] = 0x82; /* command "set data bits high byte" */
-       buf[1] = high_output;
-       buf[2] = high_direction;
-       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
-       
-       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
-       {
-               ERROR("couldn't initialize FT2232 with 'turtelizer2' layout"); 
-               return ERROR_JTAG_INIT_FAILED;
-       }
-       
-       return ERROR_OK;
-}
-
-int comstick_init(void)
-{
-       u8 buf[3];
-       u32 bytes_written;
-       
-       low_output = 0x08;
-       low_direction = 0x0b;
-       
-       /* initialize low byte for jtag */
-       buf[0] = 0x80; /* command "set data bits low byte" */
-       buf[1] = low_output; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */
-       buf[2] = low_direction; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */
-       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
-       
-       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
-       {
-               ERROR("couldn't initialize FT2232 with 'comstick' layout"); 
-               return ERROR_JTAG_INIT_FAILED;
-       }
-       
-       nTRST = 0x01;
-       nTRSTnOE = 0x00; /* no output enable for nTRST */
-       nSRST = 0x02;
-       nSRSTnOE = 0x00; /* no output enable for nSRST */
-       
-       high_output = 0x03;
-       high_direction = 0x03;
-       
-       /* initialize high port */
-       buf[0] = 0x82; /* command "set data bits high byte" */
-       buf[1] = high_output;
-       buf[2] = high_direction;
-       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
-       
-       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
-       {
-               ERROR("couldn't initialize FT2232 with 'comstick' layout"); 
-               return ERROR_JTAG_INIT_FAILED;
-       }
-       
-       return ERROR_OK;
-}
-
-int stm32stick_init(void)
-{
-       u8 buf[3];
-       u32 bytes_written;
-       
-       low_output = 0x88;
-       low_direction = 0x8b;
-       
-       /* initialize low byte for jtag */
-       buf[0] = 0x80; /* command "set data bits low byte" */
-       buf[1] = low_output; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */
-       buf[2] = low_direction; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */
-       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
-       
-       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
-       {
-               ERROR("couldn't initialize FT2232 with 'stm32stick' layout"); 
-               return ERROR_JTAG_INIT_FAILED;
-       }
-               
-       nTRST = 0x01;
-       nTRSTnOE = 0x00; /* no output enable for nTRST */
-       nSRST = 0x80;
-       nSRSTnOE = 0x00; /* no output enable for nSRST */
-       
-       high_output = 0x01;
-       high_direction = 0x03;
-       
-       /* initialize high port */
-       buf[0] = 0x82; /* command "set data bits high byte" */
-       buf[1] = high_output;
-       buf[2] = high_direction;
-       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);
-       
-       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))
-       {
-               ERROR("couldn't initialize FT2232 with 'stm32stick' layout"); 
-               return ERROR_JTAG_INIT_FAILED;
-       }
-       
-       return ERROR_OK;
-}
-
-void olimex_jtag_blink(void)
-{
-       /* Olimex ARM-USB-OCD has a LED connected to ACBUS3
-        * ACBUS3 is bit 3 of the GPIOH port
-        */
-       if (high_output & 0x08)
-       {
-               /* set port pin high */
-               high_output &= 0x07;
-       }
-       else
-       {
-               /* set port pin low */
-               high_output |= 0x08;
-       }
-       
-       BUFFER_ADD = 0x82;
-       BUFFER_ADD = high_output;
-       BUFFER_ADD = high_direction;
-}
-
-void turtle_jtag_blink(void)
-{
-       /* 
-   * Turtelizer2 has two LEDs connected to ACBUS2 and ACBUS3
-        */
-       if (high_output & 0x08)
-       {
-               high_output = 0x04;
-       }
-       else
-       {
-               high_output = 0x08;
-       }
-       
-       BUFFER_ADD = 0x82;
-       BUFFER_ADD = high_output;
-       BUFFER_ADD = high_direction;
-}
-
-
-int ft2232_quit(void)
-{
-#if BUILD_FT2232_FTD2XX == 1
-       FT_STATUS status;
-
-       status = FT_Close(ftdih);
-#elif BUILD_FT2232_LIBFTDI == 1
-       ftdi_disable_bitbang(&ftdic);
-       
-       ftdi_usb_close(&ftdic);
-       
-       ftdi_deinit(&ftdic);
-#endif
-
-       free(ft2232_buffer);
-       ft2232_buffer = NULL;
-
-       return ERROR_OK;
-}
-
-int ft2232_handle_device_desc_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       if (argc == 1)
-       {
-               ft2232_device_desc = strdup(args[0]);
-       }
-       else
-       {
-               ERROR("expected exactly one argument to ft2232_device_desc <description>");
-       }
-       
-       return ERROR_OK;
-}
-
-int ft2232_handle_serial_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       if (argc == 1)
-       {
-               ft2232_serial = strdup(args[0]);
-       }
-       else
-       {
-               ERROR("expected exactly one argument to ft2232_serial <serial-number>");
-       }
-       
-       return ERROR_OK;
-}
-
-int ft2232_handle_layout_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       if (argc == 0)
-               return ERROR_OK;
-
-       ft2232_layout = malloc(strlen(args[0]) + 1);
-       strcpy(ft2232_layout, args[0]);
-
-       return ERROR_OK;
-}
-
-int ft2232_handle_vid_pid_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       int i;
-
-       if (argc > MAX_USB_IDS*2) {
-               WARNING("ignoring extra IDs in ft2232_vid_pid "
-                   "(maximum is %d pairs)", MAX_USB_IDS);
-               argc = MAX_USB_IDS*2;
-       }
-       if (argc < 2 || (argc & 1))
-       {
-               WARNING("incomplete ft2232_vid_pid configuration directive");
-               if (argc < 2)
-                       return ERROR_OK;
-       }
-
-       for (i = 0; i+1 < argc; i += 2) {
-               ft2232_vid[i >> 1] = strtol(args[i], NULL, 0);
-               ft2232_pid[i >> 1] = strtol(args[i+1], NULL, 0);
-       }
-       /*
-        * Explicitly terminate, in case there are multiples instances of
-        * ft2232_vid_pid.
-        */
-       ft2232_vid[i >> 1] = ft2232_pid[i >> 1] = 0;
-
-       return ERROR_OK;
-}
-
-int ft2232_handle_latency_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       if (argc == 1)
-       {
-               ft2232_latency = atoi(args[0]);
-       }
-       else
-       {
-               ERROR("expected exactly one argument to ft2232_latency <ms>");
-       }
-       
-       return ERROR_OK;
-}
-
-
+/***************************************************************************\r
+ *   Copyright (C) 2004, 2006 by Dominic Rath                              *\r
+ *   Dominic.Rath@gmx.de                                                   *\r
+ *                                                                         *\r
+ *   This program is free software; you can redistribute it and/or modify  *\r
+ *   it under the terms of the GNU General Public License as published by  *\r
+ *   the Free Software Foundation; either version 2 of the License, or     *\r
+ *   (at your option) any later version.                                   *\r
+ *                                                                         *\r
+ *   This program is distributed in the hope that it will be useful,       *\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\r
+ *   GNU General Public License for more details.                          *\r
+ *                                                                         *\r
+ *   You should have received a copy of the GNU General Public License     *\r
+ *   along with this program; if not, write to the                         *\r
+ *   Free Software Foundation, Inc.,                                       *\r
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *\r
+ ***************************************************************************/\r
+#ifdef HAVE_CONFIG_H\r
+#include "config.h"\r
+#endif\r
+\r
+#if IS_CYGWIN == 1\r
+#include "windows.h"\r
+#undef ERROR\r
+#endif\r
+\r
+#include "replacements.h"\r
+\r
+/* project specific includes */\r
+#include "log.h"\r
+#include "types.h"\r
+#include "jtag.h"\r
+#include "configuration.h"\r
+#include "time_support.h"\r
+\r
+/* system includes */\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <unistd.h>\r
+\r
+/* FT2232 access library includes */\r
+#if BUILD_FT2232_FTD2XX == 1\r
+#include <ftd2xx.h>\r
+#elif BUILD_FT2232_LIBFTDI == 1\r
+#include <ftdi.h>\r
+#endif\r
+\r
+#include <sys/time.h>\r
+#include <time.h>\r
+\r
+/* enable this to debug io latency\r
+ */\r
+#if 0\r
+#define _DEBUG_USB_IO_\r
+#endif\r
+\r
+/* enable this to debug communication\r
+ */\r
+#if 0\r
+#define _DEBUG_USB_COMMS_\r
+#endif\r
+\r
+int ft2232_execute_queue(void);\r
+\r
+int ft2232_speed(int speed);\r
+int ft2232_register_commands(struct command_context_s *cmd_ctx);\r
+int ft2232_init(void);\r
+int ft2232_quit(void);\r
+\r
+int ft2232_handle_device_desc_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+int ft2232_handle_serial_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+int ft2232_handle_layout_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+int ft2232_handle_vid_pid_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+int ft2232_handle_latency_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+\r
+char *ft2232_device_desc = NULL;\r
+char *ft2232_serial = NULL;\r
+char *ft2232_layout = NULL;\r
+unsigned char ft2232_latency = 2;\r
+\r
+#define MAX_USB_IDS    8\r
+/* vid = pid = 0 marks the end of the list */\r
+static u16 ft2232_vid[MAX_USB_IDS+1] = { 0x0403, 0 };\r
+static u16 ft2232_pid[MAX_USB_IDS+1] = { 0x6010, 0 };\r
+\r
+typedef struct ft2232_layout_s\r
+{\r
+       char* name;\r
+       int(*init)(void);\r
+       void(*reset)(int trst, int srst);\r
+       void(*blink)(void);\r
+} ft2232_layout_t;\r
+\r
+/* init procedures for supported layouts */\r
+int usbjtag_init(void);\r
+int jtagkey_init(void);\r
+int olimex_jtag_init(void);\r
+int flyswatter_init(void);\r
+int turtle_init(void);\r
+int comstick_init(void);\r
+int stm32stick_init(void);\r
+\r
+/* reset procedures for supported layouts */\r
+void usbjtag_reset(int trst, int srst);\r
+void jtagkey_reset(int trst, int srst);\r
+void olimex_jtag_reset(int trst, int srst);\r
+void flyswatter_reset(int trst, int srst);\r
+void turtle_reset(int trst, int srst);\r
+void comstick_reset(int trst, int srst);\r
+void stm32stick_reset(int trst, int srst);\r
+\r
+/* blink procedures for layouts that support a blinking led */\r
+void olimex_jtag_blink(void);\r
+void turtle_jtag_blink(void);\r
+\r
+ft2232_layout_t ft2232_layouts[] =\r
+{\r
+       {"usbjtag", usbjtag_init, usbjtag_reset, NULL},\r
+       {"jtagkey", jtagkey_init, jtagkey_reset, NULL},\r
+       {"jtagkey_prototype_v1", jtagkey_init, jtagkey_reset, NULL},\r
+       {"oocdlink", jtagkey_init, jtagkey_reset, NULL},\r
+       {"signalyzer", usbjtag_init, usbjtag_reset, NULL},\r
+       {"evb_lm3s811", usbjtag_init, usbjtag_reset, NULL},\r
+       {"olimex-jtag", olimex_jtag_init, olimex_jtag_reset, olimex_jtag_blink},\r
+       {"flyswatter", flyswatter_init, flyswatter_reset, NULL},\r
+       {"turtelizer2", turtle_init, turtle_reset, turtle_jtag_blink},\r
+       {"comstick", comstick_init, comstick_reset, NULL},\r
+       {"stm32stick", stm32stick_init, stm32stick_reset, NULL},\r
+       {NULL, NULL, NULL},\r
+};\r
+\r
+static u8 nTRST, nTRSTnOE, nSRST, nSRSTnOE;\r
+\r
+static ft2232_layout_t *layout;\r
+static u8 low_output = 0x0;\r
+static u8 low_direction = 0x0;\r
+static u8 high_output = 0x0;\r
+static u8 high_direction = 0x0;\r
+\r
+#if BUILD_FT2232_FTD2XX == 1\r
+static FT_HANDLE ftdih = NULL;\r
+#elif BUILD_FT2232_LIBFTDI == 1\r
+static struct ftdi_context ftdic;\r
+#endif\r
+\r
+static u8 *ft2232_buffer = NULL;\r
+static int ft2232_buffer_size = 0;\r
+static int ft2232_read_pointer = 0;\r
+static int ft2232_expect_read = 0;\r
+#define FT2232_BUFFER_SIZE     131072\r
+#define BUFFER_ADD ft2232_buffer[ft2232_buffer_size++]\r
+#define BUFFER_READ ft2232_buffer[ft2232_read_pointer++]\r
+\r
+jtag_interface_t ft2232_interface = \r
+{\r
+       \r
+       .name = "ft2232",\r
+       \r
+       .execute_queue = ft2232_execute_queue,\r
+       \r
+       .speed = ft2232_speed,\r
+       .register_commands = ft2232_register_commands,\r
+       .init = ft2232_init,\r
+       .quit = ft2232_quit,\r
+};\r
+\r
+int ft2232_write(u8 *buf, int size, u32* bytes_written)\r
+{\r
+#if BUILD_FT2232_FTD2XX == 1\r
+       FT_STATUS status;\r
+       DWORD dw_bytes_written;\r
+       if ((status = FT_Write(ftdih, buf, size, &dw_bytes_written)) != FT_OK)\r
+       {\r
+               *bytes_written = dw_bytes_written;\r
+               ERROR("FT_Write returned: %lu", status);\r
+               return ERROR_JTAG_DEVICE_ERROR;\r
+       }\r
+       else\r
+       {\r
+               *bytes_written = dw_bytes_written;\r
+               return ERROR_OK;        \r
+       }\r
+#elif BUILD_FT2232_LIBFTDI == 1\r
+       int retval;\r
+       if ((retval = ftdi_write_data(&ftdic, buf, size)) < 0)\r
+       {\r
+               *bytes_written = 0;\r
+               ERROR("ftdi_write_data: %s", ftdi_get_error_string(&ftdic));\r
+               return ERROR_JTAG_DEVICE_ERROR;\r
+       }\r
+       else\r
+       {\r
+               *bytes_written = retval;\r
+               return ERROR_OK;        \r
+       }\r
+#endif\r
+}\r
+\r
+int ft2232_read(u8* buf, int size, u32* bytes_read)\r
+{\r
+#if BUILD_FT2232_FTD2XX == 1\r
+       DWORD dw_bytes_read;\r
+       FT_STATUS status;\r
+       int timeout = 5;\r
+       *bytes_read = 0;\r
+\r
+       while ((*bytes_read < size) && timeout--)\r
+       {\r
+               if ((status = FT_Read(ftdih, buf + *bytes_read, size - \r
+                       *bytes_read, &dw_bytes_read)) != FT_OK)         \r
+               {\r
+                       *bytes_read = 0; \r
+                       ERROR("FT_Read returned: %lu", status);\r
+                       return ERROR_JTAG_DEVICE_ERROR;\r
+               }\r
+               *bytes_read += dw_bytes_read; \r
+       }\r
+#elif BUILD_FT2232_LIBFTDI == 1\r
+       int retval;\r
+       int timeout = 100;\r
+       *bytes_read = 0;\r
+       \r
+       while ((*bytes_read < size) && timeout--)\r
+       {\r
+               if ((retval = ftdi_read_data(&ftdic, buf + *bytes_read, size - *bytes_read)) < 0)\r
+               {\r
+                       *bytes_read = 0;\r
+                       ERROR("ftdi_read_data: %s", ftdi_get_error_string(&ftdic));\r
+                       return ERROR_JTAG_DEVICE_ERROR;\r
+               }\r
+               *bytes_read += retval;\r
+       }\r
+#endif\r
+\r
+       if (*bytes_read < size)\r
+       {\r
+               ERROR("couldn't read the requested number of bytes from FT2232 device (%i < %i)", *bytes_read, size);\r
+               return ERROR_JTAG_DEVICE_ERROR;\r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int ft2232_speed(int speed)\r
+{\r
+       u8 buf[3];\r
+       int retval;\r
+       u32 bytes_written;\r
+\r
+       buf[0] = 0x86; /* command "set divisor" */\r
+       buf[1] = speed & 0xff; /* valueL (0=6MHz, 1=3MHz, 2=2.0MHz, ...*/\r
+       buf[2] = (speed >> 8) & 0xff; /* valueH */\r
+       \r
+       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
+       if (((retval = ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
+       {\r
+               ERROR("couldn't set FT2232 TCK speed");\r
+               return retval;\r
+       }\r
+\r
+       jtag_speed = speed;\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int ft2232_register_commands(struct command_context_s *cmd_ctx)\r
+{\r
+       register_command(cmd_ctx, NULL, "ft2232_device_desc", ft2232_handle_device_desc_command,\r
+               COMMAND_CONFIG, NULL);\r
+       register_command(cmd_ctx, NULL, "ft2232_serial", ft2232_handle_serial_command,\r
+               COMMAND_CONFIG, NULL);\r
+       register_command(cmd_ctx, NULL, "ft2232_layout", ft2232_handle_layout_command,\r
+               COMMAND_CONFIG, NULL);\r
+       register_command(cmd_ctx, NULL, "ft2232_vid_pid", ft2232_handle_vid_pid_command,\r
+                                        COMMAND_CONFIG, NULL);\r
+       register_command(cmd_ctx, NULL, "ft2232_latency", ft2232_handle_latency_command,\r
+                                        COMMAND_CONFIG, NULL);\r
+       return ERROR_OK;\r
+}\r
+\r
+void ft2232_end_state(enum tap_state state)\r
+{\r
+       if (tap_move_map[state] != -1)\r
+               end_state = state;\r
+       else\r
+       {\r
+               ERROR("BUG: %i is not a valid end state", state);\r
+               exit(-1);\r
+       }\r
+}\r
+\r
+void ft2232_read_scan(enum scan_type type, u8* buffer, int scan_size)\r
+{\r
+       int num_bytes = ((scan_size + 7) / 8);\r
+       int bits_left = scan_size;\r
+       int cur_byte = 0;\r
+\r
+       while(num_bytes-- > 1)\r
+       {\r
+               buffer[cur_byte] = BUFFER_READ;\r
+               cur_byte++;\r
+               bits_left -= 8;\r
+       }\r
+\r
+       buffer[cur_byte] = 0x0;\r
+\r
+       if (bits_left > 1)\r
+       {\r
+               buffer[cur_byte] = BUFFER_READ >> 1;\r
+       }\r
+\r
+       buffer[cur_byte] = (buffer[cur_byte] | ((BUFFER_READ & 0x02) << 6)) >> (8 - bits_left);\r
+\r
+}\r
+\r
+void ft2232_debug_dump_buffer(void)\r
+{\r
+       int i;\r
+       char line[256];\r
+       char *line_p = line;\r
+       \r
+       for (i = 0; i < ft2232_buffer_size; i++)\r
+       {\r
+               line_p += snprintf(line_p, 256 - (line_p - line), "%2.2x ", ft2232_buffer[i]);\r
+               if (i % 16 == 15)\r
+               {\r
+                       DEBUG("%s", line);\r
+                       line_p = line;\r
+               }\r
+       }\r
+       \r
+       if (line_p != line)\r
+               DEBUG("%s", line);\r
+}\r
+\r
+int ft2232_send_and_recv(jtag_command_t *first, jtag_command_t *last)\r
+{\r
+       jtag_command_t *cmd;\r
+       u8 *buffer;\r
+       int scan_size;\r
+       enum scan_type type;\r
+       int retval;\r
+       u32 bytes_written;\r
+       u32 bytes_read;\r
+       \r
+#ifdef _DEBUG_USB_IO_\r
+       struct timeval start, inter, inter2, end;\r
+       struct timeval d_inter, d_inter2, d_end;\r
+#endif\r
+\r
+#ifdef _DEBUG_USB_COMMS_\r
+       DEBUG("write buffer (size %i):", ft2232_buffer_size);\r
+       ft2232_debug_dump_buffer();\r
+#endif\r
+\r
+#ifdef _DEBUG_USB_IO_\r
+       gettimeofday(&start, NULL);     \r
+#endif\r
+\r
+       if ((retval = ft2232_write(ft2232_buffer, ft2232_buffer_size, &bytes_written)) != ERROR_OK)\r
+       {\r
+               ERROR("couldn't write MPSSE commands to FT2232");\r
+               exit(-1);\r
+       }\r
+       \r
+#ifdef _DEBUG_USB_IO_\r
+       gettimeofday(&inter, NULL);     \r
+#endif\r
+       \r
+       if (ft2232_expect_read)\r
+       {\r
+               int timeout = 100;\r
+               ft2232_buffer_size = 0;\r
+               \r
+#ifdef _DEBUG_USB_IO_\r
+               gettimeofday(&inter2, NULL);    \r
+#endif\r
+               \r
+               if ((retval = ft2232_read(ft2232_buffer, ft2232_expect_read, &bytes_read)) != ERROR_OK)\r
+               {\r
+                       ERROR("couldn't read from FT2232");\r
+                       exit(-1);\r
+               }\r
+               \r
+#ifdef _DEBUG_USB_IO_\r
+               gettimeofday(&end, NULL);       \r
+\r
+               timeval_subtract(&d_inter, &inter, &start);\r
+               timeval_subtract(&d_inter2, &inter2, &start);\r
+               timeval_subtract(&d_end, &end, &start);\r
+\r
+               INFO("inter: %i.%i, inter2: %i.%i end: %i.%i", d_inter.tv_sec, d_inter.tv_usec, d_inter2.tv_sec, d_inter2.tv_usec, d_end.tv_sec, d_end.tv_usec);\r
+#endif\r
+       \r
+               \r
+               ft2232_buffer_size = bytes_read;\r
+               \r
+               if (ft2232_expect_read != ft2232_buffer_size)\r
+               {\r
+                       ERROR("ft2232_expect_read (%i) != ft2232_buffer_size (%i) (%i retries)", ft2232_expect_read, ft2232_buffer_size, 100 - timeout);\r
+                       ft2232_debug_dump_buffer();     \r
+\r
+                       exit(-1);\r
+               }\r
+\r
+#ifdef _DEBUG_USB_COMMS_\r
+               DEBUG("read buffer (%i retries): %i bytes", 100 - timeout, ft2232_buffer_size);\r
+               ft2232_debug_dump_buffer();\r
+#endif\r
+       }\r
+\r
+       ft2232_expect_read = 0;\r
+       ft2232_read_pointer = 0;\r
+       \r
+       /* return ERROR_OK, unless a jtag_read_buffer returns a failed check\r
+        * that wasn't handled by a caller-provided error handler\r
+        */ \r
+       retval = ERROR_OK;\r
+       \r
+       cmd = first;\r
+       while (cmd != last)\r
+       {\r
+               switch (cmd->type)\r
+               {\r
+                       case JTAG_SCAN:\r
+                               type = jtag_scan_type(cmd->cmd.scan);\r
+                               if (type != SCAN_OUT)\r
+                               {\r
+                                       scan_size = jtag_scan_size(cmd->cmd.scan);\r
+                                       buffer = calloc(CEIL(scan_size, 8), 1);\r
+                                       ft2232_read_scan(type, buffer, scan_size);\r
+                                       if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)\r
+                                               retval = ERROR_JTAG_QUEUE_FAILED;\r
+                                       free(buffer);\r
+                               }\r
+                               break;\r
+                       default:\r
+                               break;\r
+               }\r
+               cmd = cmd->next;\r
+       }\r
+       \r
+       ft2232_buffer_size = 0;\r
+\r
+       return retval;\r
+}\r
+\r
+void ft2232_add_pathmove(pathmove_command_t *cmd)\r
+{\r
+       int num_states = cmd->num_states;\r
+       u8 tms_byte;\r
+       int state_count;\r
+\r
+       state_count = 0;\r
+       while (num_states)\r
+       {\r
+               tms_byte = 0x0;\r
+               int bit_count = 0;\r
+               \r
+               /* command "Clock Data to TMS/CS Pin (no Read)" */\r
+               BUFFER_ADD = 0x4b;\r
+               /* number of states remaining */\r
+               BUFFER_ADD = (num_states % 7) - 1;\r
+               \r
+               while (num_states % 7)\r
+               {\r
+                       if (tap_transitions[cur_state].low == cmd->path[state_count])\r
+                               buf_set_u32(&tms_byte, bit_count++, 1, 0x0);\r
+                       else if (tap_transitions[cur_state].high == cmd->path[state_count])\r
+                               buf_set_u32(&tms_byte, bit_count++, 1, 0x1);\r
+                       else\r
+                       {\r
+                               ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[cmd->path[state_count]]);\r
+                               exit(-1);\r
+                       }\r
+\r
+                       cur_state = cmd->path[state_count];\r
+                       state_count++;\r
+                       num_states--;\r
+               }\r
+               \r
+               BUFFER_ADD = tms_byte;\r
+       }\r
+       \r
+       end_state = cur_state;\r
+}\r
+\r
+void ft2232_add_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size)\r
+{\r
+       int num_bytes = (scan_size + 7) / 8;\r
+       int bits_left = scan_size;\r
+       int cur_byte = 0;\r
+       int last_bit;\r
+\r
+       if (!((!ir_scan && (cur_state == TAP_SD)) || (ir_scan && (cur_state == TAP_SI))))\r
+       {\r
+               /* command "Clock Data to TMS/CS Pin (no Read)" */\r
+               BUFFER_ADD = 0x4b;\r
+               /* scan 7 bit */\r
+               BUFFER_ADD = 0x6;\r
+               /* TMS data bits */\r
+               if (ir_scan)\r
+               {\r
+                       BUFFER_ADD = TAP_MOVE(cur_state, TAP_SI);\r
+                       cur_state = TAP_SI;\r
+               }\r
+               else\r
+               {\r
+                       BUFFER_ADD = TAP_MOVE(cur_state, TAP_SD);\r
+                       cur_state = TAP_SD;\r
+               }\r
+               //DEBUG("added TMS scan (no read)");\r
+       }\r
+       \r
+       /* add command for complete bytes */\r
+       while (num_bytes > 1)\r
+       {\r
+               int thisrun_bytes;\r
+               if (type == SCAN_IO)\r
+               {\r
+                       /* Clock Data Bytes In and Out LSB First */\r
+                       BUFFER_ADD = 0x39;\r
+                       //DEBUG("added TDI bytes (io %i)", num_bytes);\r
+               }\r
+               else if (type == SCAN_OUT)\r
+               {\r
+                       /* Clock Data Bytes Out on -ve Clock Edge LSB First (no Read) */\r
+                       BUFFER_ADD = 0x19;\r
+                       //DEBUG("added TDI bytes (o)");\r
+               }\r
+               else if (type == SCAN_IN)\r
+               {\r
+                       /* Clock Data Bytes In on +ve Clock Edge LSB First (no Write) */\r
+                       BUFFER_ADD = 0x28;\r
+                       //DEBUG("added TDI bytes (i %i)", num_bytes);\r
+               }\r
+               thisrun_bytes = (num_bytes > 65537) ? 65536 : (num_bytes - 1);\r
+               num_bytes -= thisrun_bytes;\r
+               BUFFER_ADD = (thisrun_bytes - 1) & 0xff;\r
+               BUFFER_ADD = ((thisrun_bytes - 1) >> 8) & 0xff;\r
+               if (type != SCAN_IN)\r
+               {\r
+                       /* add complete bytes */\r
+                       while(thisrun_bytes-- > 0)\r
+                       {\r
+                               BUFFER_ADD = buffer[cur_byte];\r
+                               cur_byte++;\r
+                               bits_left -= 8;\r
+                       }\r
+               }\r
+               else /* (type == SCAN_IN) */\r
+               {\r
+                       bits_left -= 8 * (thisrun_bytes);\r
+               }\r
+       }\r
+       \r
+       /* the most signifcant bit is scanned during TAP movement */\r
+       if (type != SCAN_IN)\r
+               last_bit = (buffer[cur_byte] >> (bits_left - 1)) & 0x1;\r
+       else\r
+               last_bit = 0;\r
+\r
+       /* process remaining bits but the last one */\r
+       if (bits_left > 1)\r
+       {\r
+               if (type == SCAN_IO)\r
+               {\r
+                       /* Clock Data Bits In and Out LSB First */\r
+                       BUFFER_ADD = 0x3b;\r
+                       //DEBUG("added TDI bits (io) %i", bits_left - 1);\r
+               }\r
+               else if (type == SCAN_OUT)\r
+               {\r
+                       /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */\r
+                       BUFFER_ADD = 0x1b;\r
+                       //DEBUG("added TDI bits (o)");\r
+               }\r
+               else if (type == SCAN_IN)\r
+               {\r
+                       /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */\r
+                       BUFFER_ADD = 0x2a;\r
+                       //DEBUG("added TDI bits (i %i)", bits_left - 1);\r
+               }\r
+               BUFFER_ADD = bits_left - 2;\r
+               if (type != SCAN_IN)\r
+                       BUFFER_ADD = buffer[cur_byte];\r
+       }\r
+\r
+       if ((ir_scan && (end_state == TAP_SI)) ||\r
+               (!ir_scan && (end_state == TAP_SD)))\r
+       {\r
+               if (type == SCAN_IO)\r
+               {\r
+                       /* Clock Data Bits In and Out LSB First */\r
+                       BUFFER_ADD = 0x3b;\r
+                       //DEBUG("added TDI bits (io) %i", bits_left - 1);\r
+               }\r
+               else if (type == SCAN_OUT)\r
+               {\r
+                       /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */\r
+                       BUFFER_ADD = 0x1b;\r
+                       //DEBUG("added TDI bits (o)");\r
+               }\r
+               else if (type == SCAN_IN)\r
+               {\r
+                       /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */\r
+                       BUFFER_ADD = 0x2a;\r
+                       //DEBUG("added TDI bits (i %i)", bits_left - 1);\r
+               }\r
+               BUFFER_ADD = 0x0;\r
+               BUFFER_ADD = last_bit;\r
+       }\r
+       else\r
+       {\r
+               /* move from Shift-IR/DR to end state */\r
+               if (type != SCAN_OUT)\r
+               {\r
+                       /* Clock Data to TMS/CS Pin with Read */\r
+                       BUFFER_ADD = 0x6b;\r
+                       //DEBUG("added TMS scan (read)");\r
+               }\r
+               else\r
+               {\r
+                       /* Clock Data to TMS/CS Pin (no Read) */\r
+                       BUFFER_ADD = 0x4b;\r
+                       //DEBUG("added TMS scan (no read)");\r
+               }\r
+               BUFFER_ADD = 0x6;\r
+               BUFFER_ADD = TAP_MOVE(cur_state, end_state) | (last_bit << 7);\r
+               cur_state = end_state;\r
+       }\r
+}\r
+\r
+int ft2232_large_scan(scan_command_t *cmd, enum scan_type type, u8 *buffer, int scan_size)\r
+{\r
+       int num_bytes = (scan_size + 7) / 8;\r
+       int bits_left = scan_size;\r
+       int cur_byte = 0;\r
+       int last_bit;\r
+       u8 *receive_buffer = malloc(CEIL(scan_size, 8));\r
+       u8 *receive_pointer = receive_buffer;\r
+       u32 bytes_written;\r
+       u32 bytes_read;\r
+       int retval;\r
+       int thisrun_read = 0;\r
+       \r
+       if (cmd->ir_scan)\r
+       {\r
+               ERROR("BUG: large IR scans are not supported");\r
+               exit(-1);\r
+       }\r
+\r
+       if (cur_state != TAP_SD)\r
+       {\r
+               /* command "Clock Data to TMS/CS Pin (no Read)" */\r
+               BUFFER_ADD = 0x4b;\r
+               /* scan 7 bit */\r
+               BUFFER_ADD = 0x6;\r
+               /* TMS data bits */\r
+               BUFFER_ADD = TAP_MOVE(cur_state, TAP_SD);\r
+               cur_state = TAP_SD;\r
+       }\r
+       \r
+       if ((retval = ft2232_write(ft2232_buffer, ft2232_buffer_size, &bytes_written)) != ERROR_OK)\r
+       {\r
+               ERROR("couldn't write MPSSE commands to FT2232");\r
+               exit(-1);\r
+       }\r
+       DEBUG("ft2232_buffer_size: %i, bytes_written: %i", ft2232_buffer_size, bytes_written);\r
+       ft2232_buffer_size = 0;\r
+       \r
+       /* add command for complete bytes */\r
+       while (num_bytes > 1)\r
+       {\r
+               int thisrun_bytes;\r
+               \r
+               if (type == SCAN_IO)\r
+               {\r
+                       /* Clock Data Bytes In and Out LSB First */\r
+                       BUFFER_ADD = 0x39;\r
+                       //DEBUG("added TDI bytes (io %i)", num_bytes);\r
+               }\r
+               else if (type == SCAN_OUT)\r
+               {\r
+                       /* Clock Data Bytes Out on -ve Clock Edge LSB First (no Read) */\r
+                       BUFFER_ADD = 0x19;\r
+                       //DEBUG("added TDI bytes (o)");\r
+               }\r
+               else if (type == SCAN_IN)\r
+               {\r
+                       /* Clock Data Bytes In on +ve Clock Edge LSB First (no Write) */\r
+                       BUFFER_ADD = 0x28;\r
+                       //DEBUG("added TDI bytes (i %i)", num_bytes);\r
+               }\r
+               thisrun_bytes = (num_bytes > 65537) ? 65536 : (num_bytes - 1);\r
+               thisrun_read = thisrun_bytes;\r
+               num_bytes -= thisrun_bytes;\r
+               BUFFER_ADD = (thisrun_bytes - 1) & 0xff;\r
+               BUFFER_ADD = ((thisrun_bytes - 1) >> 8) & 0xff;\r
+               if (type != SCAN_IN)\r
+               {\r
+                       /* add complete bytes */\r
+                       while(thisrun_bytes-- > 0)\r
+                       {\r
+                               BUFFER_ADD = buffer[cur_byte];\r
+                               cur_byte++;\r
+                               bits_left -= 8;\r
+                       }\r
+               }\r
+               else /* (type == SCAN_IN) */\r
+               {\r
+                       bits_left -= 8 * (thisrun_bytes);\r
+               }\r
+\r
+               if ((retval = ft2232_write(ft2232_buffer, ft2232_buffer_size, &bytes_written)) != ERROR_OK)\r
+               {\r
+                       ERROR("couldn't write MPSSE commands to FT2232");\r
+                       exit(-1);\r
+               }\r
+               DEBUG("ft2232_buffer_size: %i, bytes_written: %i", ft2232_buffer_size, bytes_written);\r
+               ft2232_buffer_size = 0;\r
+               \r
+               if (type != SCAN_OUT)\r
+               {\r
+                       if ((retval = ft2232_read(receive_pointer, thisrun_read, &bytes_read)) != ERROR_OK)\r
+                       {\r
+                               ERROR("couldn't read from FT2232");\r
+                               exit(-1);\r
+                       }\r
+                       DEBUG("thisrun_read: %i, bytes_read: %i", thisrun_read, bytes_read);\r
+                       receive_pointer += bytes_read;\r
+               }\r
+       }\r
+       \r
+       thisrun_read = 0;\r
+       \r
+       /* the most signifcant bit is scanned during TAP movement */\r
+       if (type != SCAN_IN)\r
+               last_bit = (buffer[cur_byte] >> (bits_left - 1)) & 0x1;\r
+       else\r
+               last_bit = 0;\r
+\r
+       /* process remaining bits but the last one */\r
+       if (bits_left > 1)\r
+       {\r
+               if (type == SCAN_IO)\r
+               {\r
+                       /* Clock Data Bits In and Out LSB First */\r
+                       BUFFER_ADD = 0x3b;\r
+                       //DEBUG("added TDI bits (io) %i", bits_left - 1);\r
+               }\r
+               else if (type == SCAN_OUT)\r
+               {\r
+                       /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */\r
+                       BUFFER_ADD = 0x1b;\r
+                       //DEBUG("added TDI bits (o)");\r
+               }\r
+               else if (type == SCAN_IN)\r
+               {\r
+                       /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */\r
+                       BUFFER_ADD = 0x2a;\r
+                       //DEBUG("added TDI bits (i %i)", bits_left - 1);\r
+               }\r
+               BUFFER_ADD = bits_left - 2;\r
+               if (type != SCAN_IN)\r
+                       BUFFER_ADD = buffer[cur_byte];\r
+                       \r
+               if (type != SCAN_OUT)\r
+                       thisrun_read += 2;\r
+       }\r
+\r
+       if (end_state == TAP_SD)\r
+       {\r
+               if (type == SCAN_IO)\r
+               {\r
+                       /* Clock Data Bits In and Out LSB First */\r
+                       BUFFER_ADD = 0x3b;\r
+                       //DEBUG("added TDI bits (io) %i", bits_left - 1);\r
+               }\r
+               else if (type == SCAN_OUT)\r
+               {\r
+                       /* Clock Data Bits Out on -ve Clock Edge LSB First (no Read) */\r
+                       BUFFER_ADD = 0x1b;\r
+                       //DEBUG("added TDI bits (o)");\r
+               }\r
+               else if (type == SCAN_IN)\r
+               {\r
+                       /* Clock Data Bits In on +ve Clock Edge LSB First (no Write) */\r
+                       BUFFER_ADD = 0x2a;\r
+                       //DEBUG("added TDI bits (i %i)", bits_left - 1);\r
+               }\r
+               BUFFER_ADD = 0x0;\r
+               BUFFER_ADD = last_bit;\r
+       }\r
+       else\r
+       {\r
+               /* move from Shift-IR/DR to end state */\r
+               if (type != SCAN_OUT)\r
+               {\r
+                       /* Clock Data to TMS/CS Pin with Read */\r
+                       BUFFER_ADD = 0x6b;\r
+                       //DEBUG("added TMS scan (read)");\r
+               }\r
+               else\r
+               {\r
+                       /* Clock Data to TMS/CS Pin (no Read) */\r
+                       BUFFER_ADD = 0x4b;\r
+                       //DEBUG("added TMS scan (no read)");\r
+               }\r
+               BUFFER_ADD = 0x6;\r
+               BUFFER_ADD = TAP_MOVE(cur_state, end_state) | (last_bit << 7);\r
+               cur_state = end_state;\r
+       }\r
+       \r
+       if (type != SCAN_OUT)\r
+               thisrun_read += 1;\r
+       \r
+       if ((retval = ft2232_write(ft2232_buffer, ft2232_buffer_size, &bytes_written)) != ERROR_OK)\r
+       {\r
+               ERROR("couldn't write MPSSE commands to FT2232");\r
+               exit(-1);\r
+       }\r
+       DEBUG("ft2232_buffer_size: %i, bytes_written: %i", ft2232_buffer_size, bytes_written);\r
+       ft2232_buffer_size = 0;\r
+       \r
+       if (type != SCAN_OUT)\r
+       {\r
+               if ((retval = ft2232_read(receive_pointer, thisrun_read, &bytes_read)) != ERROR_OK)\r
+               {\r
+                       ERROR("couldn't read from FT2232");\r
+                       exit(-1);\r
+               }\r
+               DEBUG("thisrun_read: %i, bytes_read: %i", thisrun_read, bytes_read);\r
+               receive_pointer += bytes_read;\r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int ft2232_predict_scan_out(int scan_size, enum scan_type type)\r
+{\r
+       int predicted_size = 3;\r
+       int num_bytes = (scan_size - 1) / 8;\r
+       \r
+       if (cur_state != TAP_SD)\r
+               predicted_size += 3;\r
+       \r
+       if (type == SCAN_IN)    /* only from device to host */\r
+       {\r
+               /* complete bytes */\r
+               predicted_size += (CEIL(num_bytes, 65536)) * 3;\r
+               /* remaining bits - 1 (up to 7) */\r
+               predicted_size += ((scan_size - 1) % 8) ? 2 : 0;\r
+       }\r
+       else                                    /* host to device, or bidirectional */\r
+       {\r
+               /* complete bytes */\r
+               predicted_size += num_bytes + (CEIL(num_bytes, 65536)) * 3;\r
+               /* remaining bits -1 (up to 7) */\r
+               predicted_size += ((scan_size - 1) % 8) ? 3 : 0;\r
+       }\r
+\r
+       return predicted_size;\r
+}\r
+\r
+int ft2232_predict_scan_in(int scan_size, enum scan_type type)\r
+{\r
+       int predicted_size = 0;\r
+       \r
+       if (type != SCAN_OUT)\r
+       {\r
+               /* complete bytes */\r
+               predicted_size += (CEIL(scan_size, 8) > 1) ? (CEIL(scan_size, 8) - 1) : 0;\r
+               /* remaining bits - 1 */\r
+               predicted_size += ((scan_size - 1) % 8) ? 1 : 0;\r
+               /* last bit (from TMS scan) */\r
+               predicted_size += 1;\r
+       }\r
+       \r
+       //DEBUG("scan_size: %i, predicted_size: %i", scan_size, predicted_size);\r
+\r
+       return predicted_size;\r
+}\r
+\r
+void usbjtag_reset(int trst, int srst)\r
+{\r
+       if (trst == 1)\r
+       {\r
+               cur_state = TAP_TLR;\r
+               if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)\r
+                       low_direction |= nTRSTnOE;      /* switch to output pin (output is low) */\r
+               else\r
+                       low_output &= ~nTRST;   /* switch output low */\r
+       }\r
+       else if (trst == 0)\r
+       {\r
+               if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)\r
+                       low_direction &= ~nTRSTnOE; /* switch to input pin (high-Z + internal and external pullup) */\r
+               else\r
+                       low_output |= nTRST; /* switch output high */\r
+       }\r
+\r
+       if (srst == 1)\r
+       {\r
+               if (jtag_reset_config & RESET_SRST_PUSH_PULL)\r
+                       low_output &= ~nSRST;   /* switch output low */\r
+               else\r
+                       low_direction |= nSRSTnOE;      /* switch to output pin (output is low) */\r
+       }\r
+       else if (srst == 0)\r
+       {\r
+               if (jtag_reset_config & RESET_SRST_PUSH_PULL)\r
+                       low_output |= nSRST;    /* switch output high */\r
+               else\r
+                       low_direction &= ~nSRSTnOE;     /* switch to input pin (high-Z) */\r
+       }\r
+       \r
+       /* command "set data bits low byte" */\r
+       BUFFER_ADD = 0x80;\r
+       BUFFER_ADD = low_output;\r
+       BUFFER_ADD = low_direction;\r
+\r
+}\r
+\r
+void jtagkey_reset(int trst, int srst)\r
+{\r
+       if (trst == 1)\r
+       {\r
+               cur_state = TAP_TLR;\r
+               if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)\r
+                       high_output &= ~nTRSTnOE;\r
+               else\r
+                       high_output &= ~nTRST;\r
+       }\r
+       else if (trst == 0)\r
+       {\r
+               if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)\r
+                       high_output |= nTRSTnOE;\r
+               else\r
+                       high_output |= nTRST;\r
+       }\r
+\r
+       if (srst == 1)\r
+       {\r
+               if (jtag_reset_config & RESET_SRST_PUSH_PULL)\r
+                       high_output &= ~nSRST;\r
+               else\r
+                       high_output &= ~nSRSTnOE;\r
+       }\r
+       else if (srst == 0)\r
+       {\r
+               if (jtag_reset_config & RESET_SRST_PUSH_PULL)\r
+                       high_output |= nSRST;\r
+               else\r
+                       high_output |= nSRSTnOE;\r
+       }\r
+       \r
+       /* command "set data bits high byte" */\r
+       BUFFER_ADD = 0x82;\r
+       BUFFER_ADD = high_output;\r
+       BUFFER_ADD = high_direction;\r
+       DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output, high_direction);\r
+}\r
+\r
+void olimex_jtag_reset(int trst, int srst)\r
+{\r
+       if (trst == 1)\r
+       {\r
+               cur_state = TAP_TLR;\r
+               if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)\r
+                       high_output &= ~nTRSTnOE;\r
+               else\r
+                       high_output &= ~nTRST;\r
+       }\r
+       else if (trst == 0)\r
+       {\r
+               if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)\r
+                       high_output |= nTRSTnOE;\r
+               else\r
+                       high_output |= nTRST;\r
+       }\r
+\r
+    if (srst == 1)\r
+    {\r
+        high_output |= nSRST;\r
+    }\r
+    else if (srst == 0)\r
+    {\r
+        high_output &= ~nSRST;\r
+    }\r
+\r
+    /* command "set data bits high byte" */\r
+    BUFFER_ADD = 0x82;\r
+    BUFFER_ADD = high_output;\r
+    BUFFER_ADD = high_direction;\r
+    DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output, high_direction);\r
+}\r
+\r
+void flyswatter_reset(int trst, int srst)\r
+{\r
+       if (trst == 1)\r
+       {\r
+               cur_state = TAP_TLR;\r
+               low_output &= ~nTRST;\r
+       }\r
+       else if (trst == 0)\r
+       {\r
+               low_output |= nTRST;\r
+       }\r
+\r
+    if (srst == 1)\r
+    {\r
+        low_output |= nSRST;\r
+    }\r
+    else if (srst == 0)\r
+    {\r
+        low_output &= ~nSRST;\r
+    }\r
+\r
+    /* command "set data bits low byte" */\r
+    BUFFER_ADD = 0x80;\r
+    BUFFER_ADD = low_output;\r
+    BUFFER_ADD = low_direction;\r
+    DEBUG("trst: %i, srst: %i, low_output: 0x%2.2x, low_direction: 0x%2.2x", trst, srst, low_output, low_direction);\r
+}\r
+\r
+void turtle_reset(int trst, int srst)\r
+{\r
+       trst = trst;\r
+       \r
+       if (srst == 1)\r
+       {\r
+               low_output |= nSRST;\r
+       }\r
+       else if (srst == 0)\r
+       {\r
+               low_output &= ~nSRST;\r
+       }\r
+       \r
+       /* command "set data bits low byte" */\r
+       BUFFER_ADD = 0x80;\r
+       BUFFER_ADD = low_output;\r
+       BUFFER_ADD = low_direction;\r
+       DEBUG("srst: %i, low_output: 0x%2.2x, low_direction: 0x%2.2x", srst, low_output, low_direction);\r
+}\r
+\r
+void comstick_reset(int trst, int srst)\r
+{\r
+       if (trst == 1)\r
+       {\r
+               cur_state = TAP_TLR;\r
+               high_output &= ~nTRST;\r
+       }\r
+       else if (trst == 0)\r
+       {\r
+               high_output |= nTRST;\r
+       }\r
+\r
+    if (srst == 1)\r
+    {\r
+        high_output &= ~nSRST;\r
+    }\r
+    else if (srst == 0)\r
+    {\r
+        high_output |= nSRST;\r
+    }\r
+       \r
+       /* command "set data bits high byte" */\r
+       BUFFER_ADD = 0x82;\r
+       BUFFER_ADD = high_output;\r
+       BUFFER_ADD = high_direction;\r
+       DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output, high_direction);\r
+}\r
+\r
+void stm32stick_reset(int trst, int srst)\r
+{\r
+       if (trst == 1)\r
+       {\r
+               cur_state = TAP_TLR;\r
+               high_output &= ~nTRST;\r
+       }\r
+       else if (trst == 0)\r
+       {\r
+               high_output |= nTRST;\r
+       }\r
+\r
+    if (srst == 1)\r
+    {\r
+        low_output &= ~nSRST;\r
+    }\r
+    else if (srst == 0)\r
+    {\r
+        low_output |= nSRST;\r
+    }\r
+       \r
+       /* command "set data bits low byte" */\r
+       BUFFER_ADD = 0x80;\r
+       BUFFER_ADD = low_output;\r
+       BUFFER_ADD = low_direction;\r
+       \r
+       /* command "set data bits high byte" */\r
+       BUFFER_ADD = 0x82;\r
+       BUFFER_ADD = high_output;\r
+       BUFFER_ADD = high_direction;\r
+       DEBUG("trst: %i, srst: %i, high_output: 0x%2.2x, high_direction: 0x%2.2x", trst, srst, high_output, high_direction);\r
+}\r
+\r
+int ft2232_execute_queue()\r
+{\r
+       jtag_command_t *cmd = jtag_command_queue; /* currently processed command */\r
+       jtag_command_t *first_unsent = cmd;     /* next command that has to be sent */\r
+       u8 *buffer;\r
+       int scan_size;  /* size of IR or DR scan */\r
+       enum scan_type type;\r
+       int i;\r
+       int predicted_size = 0;\r
+       int require_send = 0;\r
+       int retval;\r
+       \r
+       /* return ERROR_OK, unless ft2232_send_and_recv reports a failed check\r
+        * that wasn't handled by a caller-provided error handler\r
+        */ \r
+       retval = ERROR_OK;\r
+\r
+       ft2232_buffer_size = 0;\r
+       ft2232_expect_read = 0;\r
+       \r
+       /* blink, if the current layout has that feature */\r
+       if (layout->blink)\r
+               layout->blink();\r
+\r
+       while (cmd)\r
+       {\r
+               switch(cmd->type)\r
+               {\r
+                       case JTAG_END_STATE:\r
+                               if (cmd->cmd.end_state->end_state != -1)\r
+                                       ft2232_end_state(cmd->cmd.end_state->end_state);\r
+                               break;\r
+                       case JTAG_RESET:\r
+                               /* only send the maximum buffer size that FT2232C can handle */\r
+                               predicted_size = 3;\r
+                               if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)\r
+                               {\r
+                                       if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)\r
+                                               retval = ERROR_JTAG_QUEUE_FAILED;\r
+                                       require_send = 0;\r
+                                       first_unsent = cmd;\r
+                               }\r
+\r
+                               layout->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);\r
+                               require_send = 1;\r
+                               \r
+#ifdef _DEBUG_JTAG_IO_                         \r
+                               DEBUG("trst: %i, srst: %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);\r
+#endif\r
+                               break;\r
+                       case JTAG_RUNTEST:\r
+                               /* only send the maximum buffer size that FT2232C can handle */\r
+                               predicted_size = 0;\r
+                               if (cur_state != TAP_RTI)\r
+                                       predicted_size += 3;\r
+                               predicted_size += 3 * CEIL(cmd->cmd.runtest->num_cycles, 7);\r
+                               if ((cmd->cmd.runtest->end_state != -1) && (cmd->cmd.runtest->end_state != TAP_RTI))\r
+                                       predicted_size += 3;\r
+                               if ((cmd->cmd.runtest->end_state == -1) && (end_state != TAP_RTI))\r
+                                       predicted_size += 3;\r
+                               if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)\r
+                               {\r
+                                       if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)\r
+                                               retval = ERROR_JTAG_QUEUE_FAILED;\r
+                                       require_send = 0;\r
+                                       first_unsent = cmd;\r
+                               }\r
+                               if (cur_state != TAP_RTI)\r
+                               {\r
+                                       /* command "Clock Data to TMS/CS Pin (no Read)" */\r
+                                       BUFFER_ADD = 0x4b;\r
+                                       /* scan 7 bit */\r
+                                       BUFFER_ADD = 0x6;\r
+                                       /* TMS data bits */\r
+                                       BUFFER_ADD = TAP_MOVE(cur_state, TAP_RTI);\r
+                                       cur_state = TAP_RTI;\r
+                                       require_send = 1;\r
+                               }\r
+                               i = cmd->cmd.runtest->num_cycles;\r
+                               while (i > 0)\r
+                               {\r
+                                       /* command "Clock Data to TMS/CS Pin (no Read)" */\r
+                                       BUFFER_ADD = 0x4b;\r
+                                       /* scan 7 bit */\r
+                                       BUFFER_ADD = (i > 7) ? 6 : (i - 1);\r
+                                       /* TMS data bits */\r
+                                       BUFFER_ADD = 0x0;\r
+                                       cur_state = TAP_RTI;\r
+                                       i -= (i > 7) ? 7 : i;\r
+                                       //DEBUG("added TMS scan (no read)");\r
+                               }\r
+                               if (cmd->cmd.runtest->end_state != -1)\r
+                                       ft2232_end_state(cmd->cmd.runtest->end_state);\r
+                               if (cur_state != end_state)\r
+                               {\r
+                                       /* command "Clock Data to TMS/CS Pin (no Read)" */\r
+                                       BUFFER_ADD = 0x4b;\r
+                                       /* scan 7 bit */\r
+                                       BUFFER_ADD = 0x6;\r
+                                       /* TMS data bits */\r
+                                       BUFFER_ADD = TAP_MOVE(cur_state, end_state);\r
+                                       cur_state = end_state;\r
+                                       //DEBUG("added TMS scan (no read)");\r
+                               }\r
+                               require_send = 1;\r
+#ifdef _DEBUG_JTAG_IO_                         \r
+                               DEBUG("runtest: %i, end in %i", cmd->cmd.runtest->num_cycles, end_state);\r
+#endif\r
+                               break;\r
+                       case JTAG_STATEMOVE:\r
+                               /* only send the maximum buffer size that FT2232C can handle */\r
+                               predicted_size = 3;\r
+                               if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)\r
+                               {\r
+                                       if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)\r
+                                               retval = ERROR_JTAG_QUEUE_FAILED;\r
+                                       require_send = 0;\r
+                                       first_unsent = cmd;\r
+                               }\r
+                               if (cmd->cmd.statemove->end_state != -1)\r
+                                       ft2232_end_state(cmd->cmd.statemove->end_state);\r
+                               /* command "Clock Data to TMS/CS Pin (no Read)" */\r
+                               BUFFER_ADD = 0x4b;\r
+                               /* scan 7 bit */\r
+                               BUFFER_ADD = 0x6;\r
+                               /* TMS data bits */\r
+                               BUFFER_ADD = TAP_MOVE(cur_state, end_state);\r
+                               //DEBUG("added TMS scan (no read)");\r
+                               cur_state = end_state;\r
+                               require_send = 1;\r
+#ifdef _DEBUG_JTAG_IO_                         \r
+                               DEBUG("statemove: %i", end_state);\r
+#endif\r
+                               break;\r
+                       case JTAG_PATHMOVE:\r
+                               /* only send the maximum buffer size that FT2232C can handle */\r
+                               predicted_size = 3 * CEIL(cmd->cmd.pathmove->num_states, 7);\r
+                               if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)\r
+                               {\r
+                                       if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)\r
+                                               retval = ERROR_JTAG_QUEUE_FAILED;\r
+                                       require_send = 0;\r
+                                       first_unsent = cmd;\r
+                               }\r
+                               ft2232_add_pathmove(cmd->cmd.pathmove);\r
+                               require_send = 1;\r
+#ifdef _DEBUG_JTAG_IO_                         \r
+                               DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);\r
+#endif\r
+                               break;\r
+                       case JTAG_SCAN:\r
+                               scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);\r
+                               type = jtag_scan_type(cmd->cmd.scan);\r
+                               predicted_size = ft2232_predict_scan_out(scan_size, type);\r
+                               if ((predicted_size + 1) > FT2232_BUFFER_SIZE)\r
+                               {\r
+                                       DEBUG("oversized ft2232 scan (predicted_size > FT2232_BUFFER_SIZE)");\r
+                                       /* unsent commands before this */\r
+                                       if (first_unsent != cmd)\r
+                                               if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)\r
+                                                       retval = ERROR_JTAG_QUEUE_FAILED;\r
+                                       \r
+                                       /* current command */\r
+                                       if (cmd->cmd.scan->end_state != -1)\r
+                                               ft2232_end_state(cmd->cmd.scan->end_state);\r
+                                       ft2232_large_scan(cmd->cmd.scan, type, buffer, scan_size);\r
+                                       require_send = 0;\r
+                                       first_unsent = cmd->next;\r
+                                       if (buffer)\r
+                                               free(buffer);\r
+                                       break;\r
+                               }\r
+                               else if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)\r
+                               {\r
+                                       DEBUG("ft2232 buffer size reached, sending queued commands (first_unsent: %p, cmd: %p)", first_unsent, cmd);\r
+                                       if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)\r
+                                               retval = ERROR_JTAG_QUEUE_FAILED;\r
+                                       require_send = 0;\r
+                                       first_unsent = cmd;\r
+                               }\r
+                               ft2232_expect_read += ft2232_predict_scan_in(scan_size, type);\r
+                               //DEBUG("new read size: %i", ft2232_expect_read);\r
+                               if (cmd->cmd.scan->end_state != -1)\r
+                                       ft2232_end_state(cmd->cmd.scan->end_state);\r
+                               ft2232_add_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);\r
+                               require_send = 1;\r
+                               if (buffer)\r
+                                       free(buffer);\r
+#ifdef _DEBUG_JTAG_IO_                         \r
+                               DEBUG("%s scan, %i bit, end in %i", (cmd->cmd.scan->ir_scan) ? "IR" : "DR", scan_size, end_state);\r
+#endif\r
+                               break;\r
+                       case JTAG_SLEEP:\r
+                               if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)\r
+                                       retval = ERROR_JTAG_QUEUE_FAILED;\r
+                               first_unsent = cmd->next;\r
+                               jtag_sleep(cmd->cmd.sleep->us);\r
+#ifdef _DEBUG_JTAG_IO_                         \r
+                               DEBUG("sleep %i usec", cmd->cmd.sleep->us);\r
+#endif\r
+                               break;\r
+                       default:\r
+                               ERROR("BUG: unknown JTAG command type encountered");\r
+                               exit(-1);\r
+               }\r
+               cmd = cmd->next;\r
+       }\r
+\r
+       if (require_send > 0)\r
+               if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)\r
+                       retval = ERROR_JTAG_QUEUE_FAILED;\r
+\r
+       return retval;\r
+}\r
+\r
+#if BUILD_FT2232_FTD2XX == 1\r
+static int ft2232_init_ftd2xx(u16 vid, u16 pid, int more, int *try_more)\r
+{\r
+       FT_STATUS status;\r
+       DWORD openex_flags = 0;\r
+       char *openex_string = NULL;\r
+       u8 latency_timer;\r
+\r
+       DEBUG("'ft2232' interface using FTD2XX with '%s' layout (%4.4x:%4.4x)",\r
+           ft2232_layout, vid, pid);\r
+\r
+#if IS_WIN32 == 0\r
+       /* Add non-standard Vid/Pid to the linux driver */\r
+       if ((status = FT_SetVIDPID(vid, pid)) != FT_OK)\r
+       {\r
+               WARNING("couldn't add %4.4x:%4.4x",\r
+                   vid, pid);\r
+       }\r
+#endif\r
+\r
+       if (ft2232_device_desc && ft2232_serial)\r
+       {\r
+               WARNING("can't open by device description and serial number, giving precedence to serial");\r
+               ft2232_device_desc = NULL;\r
+       }\r
+       \r
+       if (ft2232_device_desc)\r
+       {\r
+               openex_string = ft2232_device_desc;\r
+               openex_flags = FT_OPEN_BY_DESCRIPTION;\r
+       }\r
+       else if (ft2232_serial)\r
+       {\r
+               openex_string = ft2232_serial;\r
+               openex_flags = FT_OPEN_BY_SERIAL_NUMBER;\r
+       }\r
+       else\r
+       {\r
+               ERROR("neither device description nor serial number specified");\r
+               ERROR("please add \"ft2232_device_desc <string>\" or \"ft2232_serial <string>\" to your .cfg file");\r
+               \r
+               return ERROR_JTAG_INIT_FAILED;  \r
+       }\r
+\r
+       if ((status = FT_OpenEx(openex_string, openex_flags, &ftdih)) != FT_OK)\r
+       {\r
+               DWORD num_devices;\r
+               \r
+               if (more) {\r
+                       WARNING("unable to open ftdi device (trying more): %lu",\r
+                           status);\r
+                       *try_more = 1;\r
+                       return ERROR_JTAG_INIT_FAILED;\r
+               }\r
+               ERROR("unable to open ftdi device: %lu", status);\r
+               status = FT_ListDevices(&num_devices, NULL, FT_LIST_NUMBER_ONLY);\r
+               if (status == FT_OK)\r
+               {\r
+                       char **desc_array = malloc(sizeof(char*) * (num_devices + 1));\r
+                       int i;\r
+\r
+                       for (i = 0; i < num_devices; i++)\r
+                               desc_array[i] = malloc(64);\r
+                       desc_array[num_devices] = NULL;\r
+\r
+                       status = FT_ListDevices(desc_array, &num_devices, FT_LIST_ALL | openex_flags);\r
+\r
+                       if (status == FT_OK)\r
+                       {\r
+                               ERROR("ListDevices: %lu\n", num_devices);\r
+                               for (i = 0; i < num_devices; i++)\r
+                                       ERROR("%i: %s", i, desc_array[i]);\r
+                       }\r
+                       \r
+                       for (i = 0; i < num_devices; i++)\r
+                               free(desc_array[i]);\r
+                       free(desc_array);\r
+               }\r
+               else\r
+               {\r
+                       ERROR("ListDevices: NONE\n");\r
+               }\r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+\r
+       if ((status = FT_SetLatencyTimer(ftdih, ft2232_latency)) != FT_OK)\r
+       {\r
+               ERROR("unable to set latency timer: %lu", status);\r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+       \r
+       if ((status = FT_GetLatencyTimer(ftdih, &latency_timer)) != FT_OK)\r
+       {\r
+               ERROR("unable to get latency timer: %lu", status);\r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+       else\r
+       {\r
+               DEBUG("current latency timer: %i", latency_timer);\r
+       }\r
+       \r
+       if ((status = FT_SetTimeouts(ftdih, 5000, 5000)) != FT_OK)\r
+       {\r
+               ERROR("unable to set timeouts: %lu", status);\r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+\r
+       if ((status = FT_SetBitMode(ftdih, 0x0b, 2)) != FT_OK)\r
+       {\r
+               ERROR("unable to enable bit i/o mode: %lu", status);\r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+\r
+       return ERROR_OK;\r
+}\r
+\r
+static int ft2232_purge_ftd2xx(void)\r
+{\r
+       FT_STATUS status;\r
+\r
+       if ((status = FT_Purge(ftdih, FT_PURGE_RX | FT_PURGE_TX)) != FT_OK)\r
+       {\r
+               ERROR("error purging ftd2xx device: %lu", status);\r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+\r
+       return ERROR_OK;\r
+}\r
+#endif /* BUILD_FT2232_FTD2XX == 1 */\r
+\r
+#if BUILD_FT2232_LIBFTDI == 1\r
+static int ft2232_init_libftdi(u16 vid, u16 pid, int more, int *try_more)\r
+{\r
+       u8 latency_timer;\r
+\r
+       DEBUG("'ft2232' interface using libftdi with '%s' layout (%4.4x:%4.4x)",\r
+           ft2232_layout, vid, pid);\r
+\r
+       if (ftdi_init(&ftdic) < 0)\r
+               return ERROR_JTAG_INIT_FAILED;\r
+\r
+       /* context, vendor id, product id */\r
+       if (ftdi_usb_open_desc(&ftdic, vid, pid, ft2232_device_desc,\r
+           ft2232_serial) < 0) {\r
+               if (more)\r
+                       WARNING("unable to open ftdi device (trying more): %s",\r
+                            ftdic.error_str);\r
+               else\r
+                       ERROR("unable to open ftdi device: %s", ftdic.error_str);\r
+               *try_more = 1;\r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+\r
+       if (ftdi_set_interface(&ftdic, INTERFACE_A) < 0)\r
+       {\r
+               ERROR("unable to select FT2232 channel A: %s", ftdic.error_str);\r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+\r
+       if (ftdi_usb_reset(&ftdic) < 0)\r
+       {\r
+               ERROR("unable to reset ftdi device");\r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+\r
+       if (ftdi_set_latency_timer(&ftdic, ft2232_latency) < 0)\r
+       {\r
+               ERROR("unable to set latency timer");\r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+       \r
+       if (ftdi_get_latency_timer(&ftdic, &latency_timer) < 0)\r
+       {\r
+               ERROR("unable to get latency timer");\r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+       else\r
+       {\r
+               DEBUG("current latency timer: %i", latency_timer);\r
+       }\r
+\r
+       ftdi_set_bitmode(&ftdic, 0x0b, 2); /* ctx, JTAG I/O mask */\r
+\r
+       return ERROR_OK;\r
+}\r
+\r
+static int ft2232_purge_libftdi(void)\r
+{\r
+       if (ftdi_usb_purge_buffers(&ftdic) < 0)\r
+       {\r
+               ERROR("ftdi_purge_buffers: %s", ftdic.error_str);\r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+\r
+       return ERROR_OK;\r
+}\r
+#endif /* BUILD_FT2232_LIBFTDI == 1 */\r
+\r
+int ft2232_init(void)\r
+{\r
+       u8 buf[1];\r
+       int retval;\r
+       u32 bytes_written;\r
+       ft2232_layout_t *cur_layout = ft2232_layouts;\r
+       int i;\r
+       \r
+       if ((ft2232_layout == NULL) || (ft2232_layout[0] == 0))\r
+       {\r
+               ft2232_layout = "usbjtag";\r
+               WARNING("No ft2232 layout specified, using default 'usbjtag'");\r
+       }\r
+       \r
+       while (cur_layout->name)\r
+       {\r
+               if (strcmp(cur_layout->name, ft2232_layout) == 0)\r
+               {\r
+                       layout = cur_layout;\r
+                       break;\r
+               }\r
+               cur_layout++;\r
+       }\r
+\r
+       if (!layout)\r
+       {\r
+               ERROR("No matching layout found for %s", ft2232_layout);\r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+       \r
+       for (i = 0; 1; i++) {\r
+               /*\r
+                * "more indicates that there are more IDs to try, so we should\r
+                * not print an error for an ID mismatch (but for anything\r
+                * else, we should).\r
+                *\r
+                * try_more indicates that the error code returned indicates an\r
+                * ID mismatch (and nothing else) and that we should proceeed\r
+                * with the next ID pair.\r
+                */\r
+               int more = ft2232_vid[i+1] || ft2232_pid[i+1];\r
+               int try_more = 0;\r
+\r
+#if BUILD_FT2232_FTD2XX == 1\r
+               retval = ft2232_init_ftd2xx(ft2232_vid[i], ft2232_pid[i],\r
+                   more, &try_more);\r
+#elif BUILD_FT2232_LIBFTDI == 1\r
+               retval = ft2232_init_libftdi(ft2232_vid[i], ft2232_pid[i],\r
+                   more, &try_more);\r
+#endif \r
+               if (retval >= 0)\r
+                       break;\r
+               if (!more || !try_more)\r
+                       return retval;\r
+       }\r
+\r
+       ft2232_buffer_size = 0;\r
+       ft2232_buffer = malloc(FT2232_BUFFER_SIZE);\r
+\r
+       if (layout->init() != ERROR_OK)\r
+               return ERROR_JTAG_INIT_FAILED;\r
+\r
+       ft2232_speed(jtag_speed);\r
+\r
+       buf[0] = 0x85; /* Disconnect TDI/DO to TDO/DI for Loopback */\r
+       if (((retval = ft2232_write(buf, 1, &bytes_written)) != ERROR_OK) || (bytes_written != 1))\r
+       {\r
+               ERROR("couldn't write to FT2232 to disable loopback");\r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+\r
+#if BUILD_FT2232_FTD2XX == 1\r
+       return ft2232_purge_ftd2xx();\r
+#elif BUILD_FT2232_LIBFTDI == 1\r
+       return ft2232_purge_libftdi();\r
+#endif \r
+\r
+       return ERROR_OK;\r
+}\r
+\r
+int usbjtag_init(void)\r
+{\r
+       u8 buf[3];\r
+       u32 bytes_written;\r
+       \r
+       low_output = 0x08;\r
+       low_direction = 0x0b;\r
+       \r
+       if (strcmp(ft2232_layout, "usbjtag") == 0)\r
+       {\r
+               nTRST = 0x10;\r
+               nTRSTnOE = 0x10;\r
+               nSRST = 0x40;\r
+               nSRSTnOE = 0x40;\r
+       }\r
+       else if (strcmp(ft2232_layout, "signalyzer") == 0)\r
+       {\r
+               nTRST = 0x10;\r
+               nTRSTnOE = 0x10;\r
+               nSRST = 0x20;\r
+               nSRSTnOE = 0x20;\r
+       }\r
+       else if (strcmp(ft2232_layout, "evb_lm3s811") == 0)\r
+       {\r
+               nTRST = 0x0;\r
+               nTRSTnOE = 0x00;\r
+               nSRST = 0x20;\r
+               nSRSTnOE = 0x20;\r
+               low_output = 0x88;\r
+               low_direction = 0x8b;\r
+       }\r
+       else\r
+       {\r
+               ERROR("BUG: usbjtag_init called for unknown layout '%s'", ft2232_layout);\r
+               return ERROR_JTAG_INIT_FAILED;  \r
+       }\r
+       \r
+       if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)\r
+       {\r
+               low_direction &= ~nTRSTnOE; /* nTRST input */\r
+               low_output &= ~nTRST; /* nTRST = 0 */\r
+       }\r
+       else\r
+       {\r
+               low_direction |= nTRSTnOE; /* nTRST output */\r
+               low_output |= nTRST; /* nTRST = 1 */\r
+       }\r
+       \r
+       if (jtag_reset_config & RESET_SRST_PUSH_PULL)\r
+       {\r
+               low_direction |= nSRSTnOE; /* nSRST output */\r
+               low_output |= nSRST; /* nSRST = 1 */\r
+       }\r
+       else\r
+       {\r
+               low_direction &= ~nSRSTnOE; /* nSRST input */\r
+               low_output &= ~nSRST; /* nSRST = 0 */\r
+       }\r
+       \r
+       /* initialize low byte for jtag */\r
+       buf[0] = 0x80; /* command "set data bits low byte" */\r
+       buf[1] = low_output; /* value (TMS=1,TCK=0, TDI=0, xRST high) */\r
+       buf[2] = low_direction; /* dir (output=1), TCK/TDI/TMS=out, TDO=in */\r
+       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
+       \r
+       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
+       {\r
+               ERROR("couldn't initialize FT2232 with 'USBJTAG' layout"); \r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+\r
+       return ERROR_OK;\r
+}\r
+\r
+int jtagkey_init(void)\r
+{\r
+       u8 buf[3];\r
+       u32 bytes_written;\r
+       \r
+       low_output = 0x08;\r
+       low_direction = 0x1b;\r
+       \r
+       /* initialize low byte for jtag */\r
+       buf[0] = 0x80; /* command "set data bits low byte" */\r
+       buf[1] = low_output; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */\r
+       buf[2] = low_direction; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */\r
+       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
+       \r
+       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
+       {\r
+               ERROR("couldn't initialize FT2232 with 'JTAGkey' layout"); \r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+       \r
+       if (strcmp(layout->name, "jtagkey") == 0)\r
+       {\r
+               nTRST = 0x01;\r
+               nTRSTnOE = 0x4;\r
+               nSRST = 0x02;\r
+               nSRSTnOE = 0x08;\r
+       }\r
+       else if ((strcmp(layout->name, "jtagkey_prototype_v1") == 0) ||\r
+               (strcmp(layout->name, "oocdlink") == 0))\r
+       {\r
+               nTRST = 0x02;\r
+               nTRSTnOE = 0x1;\r
+               nSRST = 0x08;\r
+               nSRSTnOE = 0x04;\r
+       }\r
+       else\r
+       {\r
+               ERROR("BUG: jtagkey_init called for non jtagkey layout");\r
+               exit(-1);\r
+       }\r
+       \r
+       high_output = 0x0;\r
+       high_direction = 0x0f;\r
+\r
+       if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)\r
+       {\r
+               high_output |= nTRSTnOE;\r
+               high_output &= ~nTRST;\r
+       }\r
+       else\r
+       {\r
+               high_output &= ~nTRSTnOE;\r
+               high_output |= nTRST;\r
+       }\r
+       \r
+       if (jtag_reset_config & RESET_SRST_PUSH_PULL)\r
+       {\r
+               high_output &= ~nSRSTnOE;\r
+               high_output |= nSRST;\r
+       }\r
+       else\r
+       {\r
+               high_output |= nSRSTnOE;\r
+               high_output &= ~nSRST;\r
+       }\r
+       \r
+       /* initialize high port */\r
+       buf[0] = 0x82; /* command "set data bits high byte" */\r
+       buf[1] = high_output; /* value */\r
+       buf[2] = high_direction;   /* all outputs (xRST and xRSTnOE) */\r
+       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
+       \r
+       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
+       {\r
+               ERROR("couldn't initialize FT2232 with 'JTAGkey' layout"); \r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int olimex_jtag_init(void)\r
+{\r
+       u8 buf[3];\r
+       u32 bytes_written;\r
+       \r
+       low_output = 0x08;\r
+       low_direction = 0x1b;\r
+       \r
+       /* initialize low byte for jtag */\r
+       buf[0] = 0x80; /* command "set data bits low byte" */\r
+       buf[1] = low_output; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */\r
+       buf[2] = low_direction; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */\r
+       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
+       \r
+       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
+       {\r
+               ERROR("couldn't initialize FT2232 with 'JTAGkey' layout"); \r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+       \r
+       nTRST = 0x01;\r
+       nTRSTnOE = 0x4;\r
+       nSRST = 0x02;\r
+       nSRSTnOE = 0x00; /* no output enable for nSRST */\r
+\r
+       high_output = 0x0;\r
+       high_direction = 0x0f;\r
+\r
+       if (jtag_reset_config & RESET_TRST_OPEN_DRAIN)\r
+       {\r
+               high_output |= nTRSTnOE;\r
+               high_output &= ~nTRST;\r
+       }\r
+       else\r
+       {\r
+               high_output &= ~nTRSTnOE;\r
+               high_output |= nTRST;\r
+       }\r
+       \r
+       if (jtag_reset_config & RESET_SRST_PUSH_PULL)\r
+       {\r
+               ERROR("can't set nSRST to push-pull on the Olimex ARM-USB-OCD");\r
+       }\r
+       else\r
+       {\r
+               high_output &= ~nSRST;\r
+       }\r
+       \r
+       /* turn red LED on */\r
+       high_output |= 0x08;\r
+       \r
+       /* initialize high port */\r
+       buf[0] = 0x82; /* command "set data bits high byte" */\r
+       buf[1] = high_output; /* value */\r
+       buf[2] = high_direction;   /* all outputs (xRST and xRSTnOE) */\r
+       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
+       \r
+       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
+       {\r
+               ERROR("couldn't initialize FT2232 with 'JTAGkey' layout"); \r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int flyswatter_init(void)\r
+{\r
+       u8 buf[3];\r
+       u32 bytes_written;\r
+       \r
+       low_output = 0x18;\r
+       low_direction = 0xfb;\r
+       \r
+       /* initialize low byte for jtag */\r
+       buf[0] = 0x80; /* command "set data bits low byte" */\r
+       buf[1] = low_output; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */\r
+       buf[2] = low_direction; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE[12]=out, n[ST]srst=out */\r
+       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
+       \r
+       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
+       {\r
+               ERROR("couldn't initialize FT2232 with 'flyswatter' layout"); \r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+       \r
+       nTRST = 0x10;\r
+       nTRSTnOE = 0x0; /* not output enable for nTRST */\r
+       nSRST = 0x20;\r
+       nSRSTnOE = 0x00; /* no output enable for nSRST */\r
+\r
+       high_output = 0x00;\r
+       high_direction = 0x0c;\r
+\r
+       /* turn red LED1 on, LED2 off */\r
+       high_output |= 0x08;\r
+       \r
+       /* initialize high port */\r
+       buf[0] = 0x82; /* command "set data bits high byte" */\r
+       buf[1] = high_output; /* value */\r
+       buf[2] = high_direction;   /* all outputs (xRST and xRSTnOE) */\r
+       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
+       \r
+       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
+       {\r
+               ERROR("couldn't initialize FT2232 with 'flyswatter' layout"); \r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int turtle_init(void)\r
+{\r
+       u8 buf[3];\r
+       u32 bytes_written;\r
+       \r
+       low_output = 0x08;\r
+       low_direction = 0x5b;\r
+       \r
+       /* initialize low byte for jtag */\r
+       buf[0] = 0x80; /* command "set data bits low byte" */\r
+       buf[1] = low_output; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */\r
+       buf[2] = low_direction; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */\r
+       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
+       \r
+       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
+       {\r
+               ERROR("couldn't initialize FT2232 with 'turtelizer2' layout"); \r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+       \r
+       nSRST = 0x40;\r
+       \r
+       high_output = 0x00;\r
+       high_direction = 0x0C;\r
+       \r
+       /* initialize high port */\r
+       buf[0] = 0x82; /* command "set data bits high byte" */\r
+       buf[1] = high_output;\r
+       buf[2] = high_direction;\r
+       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
+       \r
+       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
+       {\r
+               ERROR("couldn't initialize FT2232 with 'turtelizer2' layout"); \r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int comstick_init(void)\r
+{\r
+       u8 buf[3];\r
+       u32 bytes_written;\r
+       \r
+       low_output = 0x08;\r
+       low_direction = 0x0b;\r
+       \r
+       /* initialize low byte for jtag */\r
+       buf[0] = 0x80; /* command "set data bits low byte" */\r
+       buf[1] = low_output; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */\r
+       buf[2] = low_direction; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */\r
+       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
+       \r
+       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
+       {\r
+               ERROR("couldn't initialize FT2232 with 'comstick' layout"); \r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+       \r
+       nTRST = 0x01;\r
+       nTRSTnOE = 0x00; /* no output enable for nTRST */\r
+       nSRST = 0x02;\r
+       nSRSTnOE = 0x00; /* no output enable for nSRST */\r
+       \r
+       high_output = 0x03;\r
+       high_direction = 0x03;\r
+       \r
+       /* initialize high port */\r
+       buf[0] = 0x82; /* command "set data bits high byte" */\r
+       buf[1] = high_output;\r
+       buf[2] = high_direction;\r
+       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
+       \r
+       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
+       {\r
+               ERROR("couldn't initialize FT2232 with 'comstick' layout"); \r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int stm32stick_init(void)\r
+{\r
+       u8 buf[3];\r
+       u32 bytes_written;\r
+       \r
+       low_output = 0x88;\r
+       low_direction = 0x8b;\r
+       \r
+       /* initialize low byte for jtag */\r
+       buf[0] = 0x80; /* command "set data bits low byte" */\r
+       buf[1] = low_output; /* value (TMS=1,TCK=0, TDI=0, nOE=0) */\r
+       buf[2] = low_direction; /* dir (output=1), TCK/TDI/TMS=out, TDO=in, nOE=out */\r
+       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
+       \r
+       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
+       {\r
+               ERROR("couldn't initialize FT2232 with 'stm32stick' layout"); \r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+               \r
+       nTRST = 0x01;\r
+       nTRSTnOE = 0x00; /* no output enable for nTRST */\r
+       nSRST = 0x80;\r
+       nSRSTnOE = 0x00; /* no output enable for nSRST */\r
+       \r
+       high_output = 0x01;\r
+       high_direction = 0x03;\r
+       \r
+       /* initialize high port */\r
+       buf[0] = 0x82; /* command "set data bits high byte" */\r
+       buf[1] = high_output;\r
+       buf[2] = high_direction;\r
+       DEBUG("%2.2x %2.2x %2.2x", buf[0], buf[1], buf[2]);\r
+       \r
+       if (((ft2232_write(buf, 3, &bytes_written)) != ERROR_OK) || (bytes_written != 3))\r
+       {\r
+               ERROR("couldn't initialize FT2232 with 'stm32stick' layout"); \r
+               return ERROR_JTAG_INIT_FAILED;\r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+void olimex_jtag_blink(void)\r
+{\r
+       /* Olimex ARM-USB-OCD has a LED connected to ACBUS3\r
+        * ACBUS3 is bit 3 of the GPIOH port\r
+        */\r
+       if (high_output & 0x08)\r
+       {\r
+               /* set port pin high */\r
+               high_output &= 0x07;\r
+       }\r
+       else\r
+       {\r
+               /* set port pin low */\r
+               high_output |= 0x08;\r
+       }\r
+       \r
+       BUFFER_ADD = 0x82;\r
+       BUFFER_ADD = high_output;\r
+       BUFFER_ADD = high_direction;\r
+}\r
+\r
+void turtle_jtag_blink(void)\r
+{\r
+       /* \r
+   * Turtelizer2 has two LEDs connected to ACBUS2 and ACBUS3\r
+        */\r
+       if (high_output & 0x08)\r
+       {\r
+               high_output = 0x04;\r
+       }\r
+       else\r
+       {\r
+               high_output = 0x08;\r
+       }\r
+       \r
+       BUFFER_ADD = 0x82;\r
+       BUFFER_ADD = high_output;\r
+       BUFFER_ADD = high_direction;\r
+}\r
+\r
+\r
+int ft2232_quit(void)\r
+{\r
+#if BUILD_FT2232_FTD2XX == 1\r
+       FT_STATUS status;\r
+\r
+       status = FT_Close(ftdih);\r
+#elif BUILD_FT2232_LIBFTDI == 1\r
+       ftdi_disable_bitbang(&ftdic);\r
+       \r
+       ftdi_usb_close(&ftdic);\r
+       \r
+       ftdi_deinit(&ftdic);\r
+#endif\r
+\r
+       free(ft2232_buffer);\r
+       ft2232_buffer = NULL;\r
+\r
+       return ERROR_OK;\r
+}\r
+\r
+int ft2232_handle_device_desc_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       if (argc == 1)\r
+       {\r
+               ft2232_device_desc = strdup(args[0]);\r
+       }\r
+       else\r
+       {\r
+               ERROR("expected exactly one argument to ft2232_device_desc <description>");\r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int ft2232_handle_serial_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       if (argc == 1)\r
+       {\r
+               ft2232_serial = strdup(args[0]);\r
+       }\r
+       else\r
+       {\r
+               ERROR("expected exactly one argument to ft2232_serial <serial-number>");\r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int ft2232_handle_layout_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       if (argc == 0)\r
+               return ERROR_OK;\r
+\r
+       ft2232_layout = malloc(strlen(args[0]) + 1);\r
+       strcpy(ft2232_layout, args[0]);\r
+\r
+       return ERROR_OK;\r
+}\r
+\r
+int ft2232_handle_vid_pid_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       int i;\r
+\r
+       if (argc > MAX_USB_IDS*2) {\r
+               WARNING("ignoring extra IDs in ft2232_vid_pid "\r
+                   "(maximum is %d pairs)", MAX_USB_IDS);\r
+               argc = MAX_USB_IDS*2;\r
+       }\r
+       if (argc < 2 || (argc & 1))\r
+       {\r
+               WARNING("incomplete ft2232_vid_pid configuration directive");\r
+               if (argc < 2)\r
+                       return ERROR_OK;\r
+       }\r
+\r
+       for (i = 0; i+1 < argc; i += 2) {\r
+               ft2232_vid[i >> 1] = strtol(args[i], NULL, 0);\r
+               ft2232_pid[i >> 1] = strtol(args[i+1], NULL, 0);\r
+       }\r
+       /*\r
+        * Explicitly terminate, in case there are multiples instances of\r
+        * ft2232_vid_pid.\r
+        */\r
+       ft2232_vid[i >> 1] = ft2232_pid[i >> 1] = 0;\r
+\r
+       return ERROR_OK;\r
+}\r
+\r
+int ft2232_handle_latency_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       if (argc == 1)\r
+       {\r
+               ft2232_latency = atoi(args[0]);\r
+       }\r
+       else\r
+       {\r
+               ERROR("expected exactly one argument to ft2232_latency <ms>");\r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+\r
index 16012887a88e7e760dfb669af46083bb4215f87d..f4c4dc4a60aa5157bface3caca6f2755de9b6354 100644 (file)
-/***************************************************************************
- *   Copyright (C) 2005 by Dominic Rath                                    *
- *   Dominic.Rath@gmx.de                                                   *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "xsvf.h"
-
-#include "jtag.h"
-#include "command.h"
-#include "log.h"
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <string.h>
-
-#include <sys/time.h>
-#include <time.h>
-
-#define XSTATE_MAX_PATH (12)
-
-int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
-
-int xsvf_fd = 0;
-
-u8 *dr_out_buf;        /* from host to device (TDI) */
-u8 *dr_in_buf; /* from device to host (TDO) */
-u8 *dr_in_mask;
-
-int xsdrsize = 0;
-int xruntest = 0;      /* number of TCK cycles / microseconds */
-int xrepeat = 0x20; /* number of XC9500 retries */
-
-int xendir = 0;
-int xenddr = 0;
-
-enum tap_state xsvf_to_tap[] =
-{
-       TAP_TLR, TAP_RTI,
-       TAP_SDS, TAP_CD, TAP_SD, TAP_E1D, TAP_PD, TAP_E2D, TAP_UD,
-       TAP_SIS, TAP_CI, TAP_SI, TAP_E1I, TAP_PI, TAP_E2I, TAP_UI,
-};
-
-int tap_to_xsvf[] =
-{
-       0x0, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x1, 0x9, 0xa, 0xb, 0xc, 0xe, 0xf
-};
-
-int xsvf_register_commands(struct command_context_s *cmd_ctx)
-{
-       register_command(cmd_ctx, NULL, "xsvf", handle_xsvf_command,
-               COMMAND_EXEC, "run xsvf <file>");
-
-       return ERROR_OK;
-}
-
-int xsvf_read_buffer(int num_bits, int fd, u8* buf)
-{
-       int num_bytes;
-
-       for (num_bytes = (num_bits + 7) / 8; num_bytes > 0; num_bytes--)
-       {
-               if (read(fd, buf + num_bytes - 1, 1) < 0)
-                       return ERROR_XSVF_EOF;
-       }
-
-       return ERROR_OK;
-}
-
-int xsvf_read_xstates(int fd, enum tap_state *path, int max_path, int *path_len)
-{
-       char c;
-       unsigned char uc;
-       
-       while ((read(fd, &c, 1) > 0) && (c == 0x12))
-       {
-               if (*path_len > max_path)
-               {
-                       WARNING("XSTATE path longer than max_path");
-                       break;
-               }
-               if (read(fd, &uc, 1) < 0)
-               {
-                       return ERROR_XSVF_EOF;
-               }
-               path[(*path_len)++] = xsvf_to_tap[uc];
-       }
-       
-       lseek(fd, -1, SEEK_CUR);
-       
-       return ERROR_OK;
-}
-
-int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       char c;
-       u8 buf4[4], buf2[2];
-       unsigned char uc, uc2;
-       unsigned int ui;
-       unsigned short us;
-
-       int do_abort = 0;
-       int unsupported = 0;
-       int tdo_mismatch = 0;
-       
-       int runtest_requires_tck = 0;
-       
-       int device = -1;        /* use -1 to indicate a "plain" xsvf file which accounts for additional devices in the scan chain, otherwise the device that should be affected */
-
-       if (argc < 2)
-       {
-               command_print(cmd_ctx, "usage: xsvf <device#|plain> <file> <variant>");
-               return ERROR_OK;
-       }
-
-       if (strcmp(args[0], "plain") != 0)
-       {
-               device = strtoul(args[0], NULL, 0);
-       }
-
-       if ((xsvf_fd = open(args[1], O_RDONLY)) < 0)
-       {
-               command_print(cmd_ctx, "file %s not found", args[0]);
-               return ERROR_OK;
-       }
-       
-       if ((argc > 2) && (strcmp(args[2], "virt2") == 0))
-       {
-               runtest_requires_tck = 1;
-       }
-
-       while (read(xsvf_fd, &c, 1) > 0)
-       {
-               switch (c)
-               {
-                       case 0x00:      /* XCOMPLETE */
-                               DEBUG("XCOMPLETE");
-                               if (jtag_execute_queue() != ERROR_OK)
-                               {
-                                       tdo_mismatch = 1;
-                                       break;  
-                               }
-                               break;
-                       case 0x01:      /* XTDOMASK */
-                               DEBUG("XTDOMASK");
-                               if (dr_in_mask && (xsvf_read_buffer(xsdrsize, xsvf_fd, dr_in_mask) != ERROR_OK))
-                                       do_abort = 1;
-                               break;
-                       case 0x02:      /* XSIR */
-                               DEBUG("XSIR");
-                               if (read(xsvf_fd, &c, 1) < 0)
-                                       do_abort = 1;
-                               else
-                               {
-                                       u8 *ir_buf = malloc((c + 7) / 8);
-                                       if (xsvf_read_buffer(c, xsvf_fd, ir_buf) != ERROR_OK)
-                                               do_abort = 1;
-                                       else
-                                       {
-                                               scan_field_t field;
-                                               field.device = device;
-                                               field.num_bits = c;
-                                               field.out_value = ir_buf;
-                                               field.out_mask = NULL;
-                                               field.in_value = NULL;
-                                               field.in_check_value = NULL;
-                                               field.in_check_mask = NULL;
-                                               field.in_handler = NULL;
-                                               field.in_handler_priv = NULL;
-                                               if (device == -1)
-                                                       jtag_add_plain_ir_scan(1, &field, TAP_PI, NULL);
-                                               else
-                                                       jtag_add_ir_scan(1, &field, TAP_PI, NULL);
-                                               if (jtag_execute_queue() != ERROR_OK)
-                                               {
-                                                       tdo_mismatch = 1;
-                                                       free(ir_buf);
-                                                       break;
-                                               }
-                                               if (xruntest)
-                                               {
-                                                       if (runtest_requires_tck)
-                                                               jtag_add_runtest(xruntest, xsvf_to_tap[xendir]);
-                                                       else
-                                                       {
-                                                               jtag_add_statemove(TAP_RTI);
-                                                               jtag_add_sleep(xruntest);
-                                                               jtag_add_statemove(xsvf_to_tap[xendir]);
-                                                       }
-                                               }
-                                               else if (xendir != 0xd) /* Pause-IR */
-                                                       jtag_add_statemove(xsvf_to_tap[xendir]);
-                                       }
-                                       free(ir_buf);
-                               }
-                               break;
-                       case 0x03:      /* XSDR */
-                               DEBUG("XSDR");
-                               if (xsvf_read_buffer(xsdrsize, xsvf_fd, dr_out_buf) != ERROR_OK)
-                                       do_abort = 1;
-                               else
-                               {
-                                       scan_field_t field;
-                                       field.device = device;
-                                       field.num_bits = xsdrsize;
-                                       field.out_value = dr_out_buf;
-                                       field.out_mask = NULL;
-                                       field.in_value = NULL;
-                                       jtag_set_check_value(&field, dr_in_buf, dr_in_mask, NULL);
-                                       if (device == -1)
-                                               jtag_add_plain_dr_scan(1, &field, TAP_PD, NULL);
-                                       else
-                                               jtag_add_dr_scan(1, &field, TAP_PD, NULL);
-                                       if (jtag_execute_queue() != ERROR_OK)
-                                       {
-                                               tdo_mismatch = 1;
-                                               break;  
-                                       }
-                                       if (xruntest)
-                                       {
-                                               if (runtest_requires_tck)
-                                                       jtag_add_runtest(xruntest, xsvf_to_tap[xenddr]);
-                                               else
-                                               {
-                                                       jtag_add_statemove(TAP_RTI);
-                                                       jtag_add_sleep(xruntest);
-                                                       jtag_add_statemove(xsvf_to_tap[xenddr]);
-                                               }
-                                       }
-                                       else if (xendir != 0x6) /* Pause-DR */
-                                               jtag_add_statemove(xsvf_to_tap[xenddr]);
-                               }
-                               break;
-                       case 0x04:      /* XRUNTEST */
-                               DEBUG("XRUNTEST");
-                               if (read(xsvf_fd, buf4, 4) < 0)
-                                       do_abort = 1;
-                               else
-                               {
-                                       xruntest = be_to_h_u32(buf4);
-                               }
-                               break;
-                       case 0x07:      /* XREPEAT */
-                               DEBUG("XREPEAT");
-                               if (read(xsvf_fd, &c, 1) < 0)
-                                       do_abort = 1;
-                               else
-                               {
-                                       xrepeat = c;
-                               }
-                               break;
-                       case 0x08:      /* XSDRSIZE */
-                               DEBUG("XSDRSIZE");
-                               if (read(xsvf_fd, buf4, 4) < 0)
-                                       do_abort = 1;
-                               else
-                               {
-                                       xsdrsize = be_to_h_u32(buf4);
-                                       free(dr_out_buf);
-                                       free(dr_in_buf);
-                                       free(dr_in_mask);
-                                       dr_out_buf = malloc((xsdrsize + 7) / 8);
-                                       dr_in_buf = malloc((xsdrsize + 7) / 8);
-                                       dr_in_mask = malloc((xsdrsize + 7) / 8);
-                               }
-                               break;
-                       case 0x09:      /* XSDRTDO */
-                               DEBUG("XSDRTDO");
-                               if (xsvf_read_buffer(xsdrsize, xsvf_fd, dr_out_buf) != ERROR_OK)
-                                       do_abort = 1;
-                               else
-                               {
-                                       if (xsvf_read_buffer(xsdrsize, xsvf_fd, dr_in_buf) != ERROR_OK)
-                                               do_abort = 1;
-                                       else
-                                       {
-                                               scan_field_t field;
-                                               field.device = device;
-                                               field.num_bits = xsdrsize;
-                                               field.out_value = dr_out_buf;
-                                               field.out_mask = NULL;
-                                               field.in_value = NULL;
-                                               jtag_set_check_value(&field, dr_in_buf, dr_in_mask, NULL);
-                                               if (device == -1)
-                                                       jtag_add_plain_dr_scan(1, &field, TAP_PD, NULL);
-                                               else
-                                                       jtag_add_dr_scan(1, &field, TAP_PD, NULL);
-                                               if (jtag_execute_queue() != ERROR_OK)
-                                               {
-                                                       tdo_mismatch = 1;
-                                                       break;  
-                                               }
-                                               if (xruntest)
-                                               {
-                                                       if (runtest_requires_tck)
-                                                               jtag_add_runtest(xruntest, xsvf_to_tap[xenddr]);
-                                                       else
-                                                       {
-                                                               jtag_add_statemove(TAP_RTI);
-                                                               jtag_add_sleep(xruntest);
-                                                               jtag_add_statemove(xsvf_to_tap[xenddr]);
-                                                       }
-                                               }
-                                               else if (xendir != 0x6) /* Pause-DR */
-                                                       jtag_add_statemove(xsvf_to_tap[xenddr]);
-                                       }
-                               }
-                               break;
-                       case 0x0a:      /* XSETDRMASKS */
-                               printf("unsupported XSETSDRMASKS\n");
-                               unsupported = 1;
-                               break;
-                       case 0x0b:      /* XSDRINC */
-                               printf("unsupported XSDRINC\n");
-                               unsupported = 1;
-                               break;
-                       case 0x0c:      /* XSDRB */
-                               unsupported = 1;
-                               break;
-                       case 0x0d:      /* XSDRC */
-                               unsupported = 1;
-                               break;
-                       case 0x0e:      /* XSDRE */
-                               unsupported = 1;
-                               break;
-                       case 0x0f:      /* XSDRTDOB */
-                               unsupported = 1;
-                               break;
-                       case 0x10:      /* XSDRTDOB */
-                               unsupported = 1;
-                               break;
-                       case 0x11:      /* XSDRTDOB */
-                               unsupported = 1;
-                               break;
-                       case 0x12:      /* XSTATE */
-                               DEBUG("XSTATE");
-                               if (read(xsvf_fd, &uc, 1) < 0)
-                                       do_abort = 1;
-                               else
-                               {
-                                       enum tap_state *path = calloc(XSTATE_MAX_PATH, 4);
-                                       int path_len = 1;
-                                       path[0] = xsvf_to_tap[uc];
-                                       if (xsvf_read_xstates(xsvf_fd, path, XSTATE_MAX_PATH, &path_len) != ERROR_OK)
-                                               do_abort = 1;
-                                       else
-                                       {
-                                               jtag_add_pathmove(path_len, path);
-                                       }
-                                       free(path);
-                               }
-                               break;
-                       case 0x13:      /* XENDIR */
-                               DEBUG("XENDIR");
-                               if (read(xsvf_fd, &c, 1) < 0)
-                                       do_abort = 1;
-                               else
-                               {
-                                       if (c == 0)
-                                               xendir = 1;
-                                       else if (c == 1)
-                                               xendir = 0xd;
-                                       else
-                                       {
-                                               ERROR("unknown XENDIR endstate");
-                                               unsupported = 1;
-                                       }
-                               }
-                               break;
-                       case 0x14:      /* XENDDR */
-                               DEBUG("XENDDR");
-                               if (read(xsvf_fd, &c, 1) < 0)
-                                       do_abort = 1;
-                               else
-                               {
-                                       if (c == 0)
-                                               xenddr = 1;
-                                       else if (c == 1)
-                                               xenddr = 0x6;
-                                       else
-                                       {
-                                               ERROR("unknown XENDDR endstate");
-                                               unsupported = 1;
-                                       }
-                               }
-                               break;
-                       case 0x15:      /* XSIR2 */
-                               DEBUG("XSIR2");
-                               if (read(xsvf_fd, buf2, 2) < 0)
-                                       do_abort = 1;
-                               else
-                               {
-                                       u8 *ir_buf;
-                                       us = be_to_h_u16(buf2);
-                                       ir_buf = malloc((us + 7) / 8);
-                                       if (xsvf_read_buffer(us, xsvf_fd, ir_buf) != ERROR_OK)
-                                               do_abort = 1;
-                                       else
-                                       {
-                                               scan_field_t field;
-                                               field.device = device;
-                                               field.num_bits = us;
-                                               field.out_value = ir_buf;
-                                               field.out_mask = NULL;
-                                               field.in_value = NULL;
-                                               field.in_check_value = NULL;
-                                               field.in_check_mask = NULL;
-                                               field.in_handler = NULL;
-                                               field.in_handler_priv = NULL;
-                                               if (device == -1)
-                                                       jtag_add_plain_ir_scan(1, &field, xsvf_to_tap[xendir], NULL);
-                                               else
-                                                       jtag_add_ir_scan(1, &field, xsvf_to_tap[xendir], NULL);
-                                       }
-                                       free(ir_buf);
-                               }
-                               break;
-                       case 0x16:      /* XCOMMENT */
-                               do
-                               {
-                                       if (read(xsvf_fd, &c, 1) < 0)
-                                       {
-                                               do_abort = 1;
-                                               break;
-                                       }
-                               } while (c != 0);
-                               break;
-                       case 0x17:      /* XWAIT */
-                               DEBUG("XWAIT");
-                               if ((read(xsvf_fd, &uc, 1) < 0) || (read(xsvf_fd, &uc2, 1) < 0) || (read(xsvf_fd, buf4, 4) < 0))
-                                       do_abort = 1;
-                               else
-                               {
-                                       jtag_add_statemove(xsvf_to_tap[uc]);
-                                       ui = be_to_h_u32(buf4);
-                                       jtag_add_sleep(ui);
-                                       jtag_add_statemove(xsvf_to_tap[uc2]);
-                               }
-                               break;
-                       default:
-                               printf("unknown xsvf command (0x%2.2x)\n", c);
-                               unsupported = 1;
-               }
-
-               if (do_abort || unsupported || tdo_mismatch)
-                       break;
-       }
-       
-       if (tdo_mismatch)
-       {
-               command_print(cmd_ctx, "TDO mismatch, aborting");
-               jtag_cancel_queue();
-               return ERROR_OK;
-       }
-
-       if (unsupported)
-       {
-               command_print(cmd_ctx, "unsupported xsvf command encountered, aborting");
-               jtag_cancel_queue();
-               return ERROR_OK;
-       }
-
-       if (do_abort)
-       {
-               command_print(cmd_ctx, "premature end detected, aborting");
-               jtag_cancel_queue();
-               return ERROR_OK;
-       }
-       
-       if (dr_out_buf)
-               free(dr_out_buf);
-       
-       if (dr_in_buf)
-               free(dr_in_buf);
-       
-       if (dr_in_mask)
-               free(dr_in_mask);
-
-       close(xsvf_fd);
-       
-       command_print(cmd_ctx, "XSVF file programmed successfully");
-
-       return ERROR_OK;
-}
+/***************************************************************************\r
+ *   Copyright (C) 2005 by Dominic Rath                                    *\r
+ *   Dominic.Rath@gmx.de                                                   *\r
+ *                                                                         *\r
+ *   This program is free software; you can redistribute it and/or modify  *\r
+ *   it under the terms of the GNU General Public License as published by  *\r
+ *   the Free Software Foundation; either version 2 of the License, or     *\r
+ *   (at your option) any later version.                                   *\r
+ *                                                                         *\r
+ *   This program is distributed in the hope that it will be useful,       *\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\r
+ *   GNU General Public License for more details.                          *\r
+ *                                                                         *\r
+ *   You should have received a copy of the GNU General Public License     *\r
+ *   along with this program; if not, write to the                         *\r
+ *   Free Software Foundation, Inc.,                                       *\r
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *\r
+ ***************************************************************************/\r
+#ifdef HAVE_CONFIG_H\r
+#include "config.h"\r
+#endif\r
+\r
+#include "xsvf.h"\r
+\r
+#include "jtag.h"\r
+#include "command.h"\r
+#include "log.h"\r
+\r
+#include <stdlib.h>\r
+#include <unistd.h>\r
+#include <sys/types.h>\r
+#include <sys/stat.h>\r
+#include <fcntl.h>\r
+#include <string.h>\r
+\r
+#include <sys/time.h>\r
+#include <time.h>\r
+\r
+#define XSTATE_MAX_PATH (12)\r
+\r
+int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);\r
+\r
+int xsvf_fd = 0;\r
+\r
+u8 *dr_out_buf;        /* from host to device (TDI) */\r
+u8 *dr_in_buf; /* from device to host (TDO) */\r
+u8 *dr_in_mask;\r
+\r
+int xsdrsize = 0;\r
+int xruntest = 0;      /* number of TCK cycles / microseconds */\r
+int xrepeat = 0x20; /* number of XC9500 retries */\r
+\r
+int xendir = 0;\r
+int xenddr = 0;\r
+\r
+enum tap_state xsvf_to_tap[] =\r
+{\r
+       TAP_TLR, TAP_RTI,\r
+       TAP_SDS, TAP_CD, TAP_SD, TAP_E1D, TAP_PD, TAP_E2D, TAP_UD,\r
+       TAP_SIS, TAP_CI, TAP_SI, TAP_E1I, TAP_PI, TAP_E2I, TAP_UI,\r
+};\r
+\r
+int tap_to_xsvf[] =\r
+{\r
+       0x0, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x1, 0x9, 0xa, 0xb, 0xc, 0xe, 0xf\r
+};\r
+\r
+int xsvf_register_commands(struct command_context_s *cmd_ctx)\r
+{\r
+       register_command(cmd_ctx, NULL, "xsvf", handle_xsvf_command,\r
+               COMMAND_EXEC, "run xsvf <file>");\r
+\r
+       return ERROR_OK;\r
+}\r
+\r
+int xsvf_read_buffer(int num_bits, int fd, u8* buf)\r
+{\r
+       int num_bytes;\r
+\r
+       for (num_bytes = (num_bits + 7) / 8; num_bytes > 0; num_bytes--)\r
+       {\r
+               if (read(fd, buf + num_bytes - 1, 1) < 0)\r
+                       return ERROR_XSVF_EOF;\r
+       }\r
+\r
+       return ERROR_OK;\r
+}\r
+\r
+int xsvf_read_xstates(int fd, enum tap_state *path, int max_path, int *path_len)\r
+{\r
+       char c;\r
+       unsigned char uc;\r
+       \r
+       while ((read(fd, &c, 1) > 0) && (c == 0x12))\r
+       {\r
+               if (*path_len > max_path)\r
+               {\r
+                       WARNING("XSTATE path longer than max_path");\r
+                       break;\r
+               }\r
+               if (read(fd, &uc, 1) < 0)\r
+               {\r
+                       return ERROR_XSVF_EOF;\r
+               }\r
+               path[(*path_len)++] = xsvf_to_tap[uc];\r
+       }\r
+       \r
+       lseek(fd, -1, SEEK_CUR);\r
+       \r
+       return ERROR_OK;\r
+}\r
+\r
+int handle_xsvf_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       char c;\r
+       u8 buf4[4], buf2[2];\r
+       unsigned char uc, uc2;\r
+       unsigned int ui;\r
+       unsigned short us;\r
+\r
+       int do_abort = 0;\r
+       int unsupported = 0;\r
+       int tdo_mismatch = 0;\r
+       \r
+       int runtest_requires_tck = 0;\r
+       \r
+       int device = -1;        /* use -1 to indicate a "plain" xsvf file which accounts for additional devices in the scan chain, otherwise the device that should be affected */\r
+\r
+       if (argc < 2)\r
+       {\r
+               command_print(cmd_ctx, "usage: xsvf <device#|plain> <file> <variant>");\r
+               return ERROR_OK;\r
+       }\r
+\r
+       if (strcmp(args[0], "plain") != 0)\r
+       {\r
+               device = strtoul(args[0], NULL, 0);\r
+       }\r
+\r
+       if ((xsvf_fd = open(args[1], O_RDONLY)) < 0)\r
+       {\r
+               command_print(cmd_ctx, "file %s not found", args[0]);\r
+               return ERROR_OK;\r
+       }\r
+       \r
+       if ((argc > 2) && (strcmp(args[2], "virt2") == 0))\r
+       {\r
+               runtest_requires_tck = 1;\r
+       }\r
+\r
+       while (read(xsvf_fd, &c, 1) > 0)\r
+       {\r
+               switch (c)\r
+               {\r
+                       case 0x00:      /* XCOMPLETE */\r
+                               DEBUG("XCOMPLETE");\r
+                               if (jtag_execute_queue() != ERROR_OK)\r
+                               {\r
+                                       tdo_mismatch = 1;\r
+                                       break;  \r
+                               }\r
+                               break;\r
+                       case 0x01:      /* XTDOMASK */\r
+                               DEBUG("XTDOMASK");\r
+                               if (dr_in_mask && (xsvf_read_buffer(xsdrsize, xsvf_fd, dr_in_mask) != ERROR_OK))\r
+                                       do_abort = 1;\r
+                               break;\r
+                       case 0x02:      /* XSIR */\r
+                               DEBUG("XSIR");\r
+                               if (read(xsvf_fd, &c, 1) < 0)\r
+                                       do_abort = 1;\r
+                               else\r
+                               {\r
+                                       u8 *ir_buf = malloc((c + 7) / 8);\r
+                                       if (xsvf_read_buffer(c, xsvf_fd, ir_buf) != ERROR_OK)\r
+                                               do_abort = 1;\r
+                                       else\r
+                                       {\r
+                                               scan_field_t field;\r
+                                               field.device = device;\r
+                                               field.num_bits = c;\r
+                                               field.out_value = ir_buf;\r
+                                               field.out_mask = NULL;\r
+                                               field.in_value = NULL;\r
+                                               field.in_check_value = NULL;\r
+                                               field.in_check_mask = NULL;\r
+                                               field.in_handler = NULL;\r
+                                               field.in_handler_priv = NULL;\r
+                                               if (device == -1)\r
+                                                       jtag_add_plain_ir_scan(1, &field, TAP_PI, NULL);\r
+                                               else\r
+                                                       jtag_add_ir_scan(1, &field, TAP_PI, NULL);\r
+                                               if (jtag_execute_queue() != ERROR_OK)\r
+                                               {\r
+                                                       tdo_mismatch = 1;\r
+                                                       free(ir_buf);\r
+                                                       break;\r
+                                               }\r
+                                               if (xruntest)\r
+                                               {\r
+                                                       if (runtest_requires_tck)\r
+                                                               jtag_add_runtest(xruntest, xsvf_to_tap[xendir]);\r
+                                                       else\r
+                                                       {\r
+                                                               jtag_add_statemove(TAP_RTI);\r
+                                                               jtag_add_sleep(xruntest);\r
+                                                               jtag_add_statemove(xsvf_to_tap[xendir]);\r
+                                                       }\r
+                                               }\r
+                                               else if (xendir != 0xd) /* Pause-IR */\r
+                                                       jtag_add_statemove(xsvf_to_tap[xendir]);\r
+                                       }\r
+                                       free(ir_buf);\r
+                               }\r
+                               break;\r
+                       case 0x03:      /* XSDR */\r
+                               DEBUG("XSDR");\r
+                               if (xsvf_read_buffer(xsdrsize, xsvf_fd, dr_out_buf) != ERROR_OK)\r
+                                       do_abort = 1;\r
+                               else\r
+                               {\r
+                                       scan_field_t field;\r
+                                       field.device = device;\r
+                                       field.num_bits = xsdrsize;\r
+                                       field.out_value = dr_out_buf;\r
+                                       field.out_mask = NULL;\r
+                                       field.in_value = NULL;\r
+                                       jtag_set_check_value(&field, dr_in_buf, dr_in_mask, NULL);\r
+                                       if (device == -1)\r
+                                               jtag_add_plain_dr_scan(1, &field, TAP_PD, NULL);\r
+                                       else\r
+                                               jtag_add_dr_scan(1, &field, TAP_PD, NULL);\r
+                                       if (jtag_execute_queue() != ERROR_OK)\r
+                                       {\r
+                                               tdo_mismatch = 1;\r
+                                               break;  \r
+                                       }\r
+                                       if (xruntest)\r
+                                       {\r
+                                               if (runtest_requires_tck)\r
+                                                       jtag_add_runtest(xruntest, xsvf_to_tap[xenddr]);\r
+                                               else\r
+                                               {\r
+                                                       jtag_add_statemove(TAP_RTI);\r
+                                                       jtag_add_sleep(xruntest);\r
+                                                       jtag_add_statemove(xsvf_to_tap[xenddr]);\r
+                                               }\r
+                                       }\r
+                                       else if (xendir != 0x6) /* Pause-DR */\r
+                                               jtag_add_statemove(xsvf_to_tap[xenddr]);\r
+                               }\r
+                               break;\r
+                       case 0x04:      /* XRUNTEST */\r
+                               DEBUG("XRUNTEST");\r
+                               if (read(xsvf_fd, buf4, 4) < 0)\r
+                                       do_abort = 1;\r
+                               else\r
+                               {\r
+                                       xruntest = be_to_h_u32(buf4);\r
+                               }\r
+                               break;\r
+                       case 0x07:      /* XREPEAT */\r
+                               DEBUG("XREPEAT");\r
+                               if (read(xsvf_fd, &c, 1) < 0)\r
+                                       do_abort = 1;\r
+                               else\r
+                               {\r
+                                       xrepeat = c;\r
+                               }\r
+                               break;\r
+                       case 0x08:      /* XSDRSIZE */\r
+                               DEBUG("XSDRSIZE");\r
+                               if (read(xsvf_fd, buf4, 4) < 0)\r
+                                       do_abort = 1;\r
+                               else\r
+                               {\r
+                                       xsdrsize = be_to_h_u32(buf4);\r
+                                       free(dr_out_buf);\r
+                                       free(dr_in_buf);\r
+                                       free(dr_in_mask);\r
+                                       dr_out_buf = malloc((xsdrsize + 7) / 8);\r
+                                       dr_in_buf = malloc((xsdrsize + 7) / 8);\r
+                                       dr_in_mask = malloc((xsdrsize + 7) / 8);\r
+                               }\r
+                               break;\r
+                       case 0x09:      /* XSDRTDO */\r
+                               DEBUG("XSDRTDO");\r
+                               if (xsvf_read_buffer(xsdrsize, xsvf_fd, dr_out_buf) != ERROR_OK)\r
+                                       do_abort = 1;\r
+                               else\r
+                               {\r
+                                       if (xsvf_read_buffer(xsdrsize, xsvf_fd, dr_in_buf) != ERROR_OK)\r
+                                               do_abort = 1;\r
+                                       else\r
+                                       {\r
+                                               scan_field_t field;\r
+                                               field.device = device;\r
+                                               field.num_bits = xsdrsize;\r
+                                               field.out_value = dr_out_buf;\r
+                                               field.out_mask = NULL;\r
+                                               field.in_value = NULL;\r
+                                               jtag_set_check_value(&field, dr_in_buf, dr_in_mask, NULL);\r
+                                               if (device == -1)\r
+                                                       jtag_add_plain_dr_scan(1, &field, TAP_PD, NULL);\r
+                                               else\r
+                                                       jtag_add_dr_scan(1, &field, TAP_PD, NULL);\r
+                                               if (jtag_execute_queue() != ERROR_OK)\r
+                                               {\r
+                                                       tdo_mismatch = 1;\r
+                                                       break;  \r
+                                               }\r
+                                               if (xruntest)\r
+                                               {\r
+                                                       if (runtest_requires_tck)\r
+                                                               jtag_add_runtest(xruntest, xsvf_to_tap[xenddr]);\r
+                                                       else\r
+                                                       {\r
+                                                               jtag_add_statemove(TAP_RTI);\r
+                                                               jtag_add_sleep(xruntest);\r
+                                                               jtag_add_statemove(xsvf_to_tap[xenddr]);\r
+                                                       }\r
+                                               }\r
+                                               else if (xendir != 0x6) /* Pause-DR */\r
+                                                       jtag_add_statemove(xsvf_to_tap[xenddr]);\r
+                                       }\r
+                               }\r
+                               break;\r
+                       case 0x0a:      /* XSETDRMASKS */\r
+                               ERROR("unsupported XSETSDRMASKS\n");\r
+                               unsupported = 1;\r
+                               break;\r
+                       case 0x0b:      /* XSDRINC */\r
+                               ERROR("unsupported XSDRINC\n");\r
+                               unsupported = 1;\r
+                               break;\r
+                       case 0x0c:      /* XSDRB */\r
+                               unsupported = 1;\r
+                               break;\r
+                       case 0x0d:      /* XSDRC */\r
+                               unsupported = 1;\r
+                               break;\r
+                       case 0x0e:      /* XSDRE */\r
+                               unsupported = 1;\r
+                               break;\r
+                       case 0x0f:      /* XSDRTDOB */\r
+                               unsupported = 1;\r
+                               break;\r
+                       case 0x10:      /* XSDRTDOB */\r
+                               unsupported = 1;\r
+                               break;\r
+                       case 0x11:      /* XSDRTDOB */\r
+                               unsupported = 1;\r
+                               break;\r
+                       case 0x12:      /* XSTATE */\r
+                               DEBUG("XSTATE");\r
+                               if (read(xsvf_fd, &uc, 1) < 0)\r
+                                       do_abort = 1;\r
+                               else\r
+                               {\r
+                                       enum tap_state *path = calloc(XSTATE_MAX_PATH, 4);\r
+                                       int path_len = 1;\r
+                                       path[0] = xsvf_to_tap[uc];\r
+                                       if (xsvf_read_xstates(xsvf_fd, path, XSTATE_MAX_PATH, &path_len) != ERROR_OK)\r
+                                               do_abort = 1;\r
+                                       else\r
+                                       {\r
+                                               jtag_add_pathmove(path_len, path);\r
+                                       }\r
+                                       free(path);\r
+                               }\r
+                               break;\r
+                       case 0x13:      /* XENDIR */\r
+                               DEBUG("XENDIR");\r
+                               if (read(xsvf_fd, &c, 1) < 0)\r
+                                       do_abort = 1;\r
+                               else\r
+                               {\r
+                                       if (c == 0)\r
+                                               xendir = 1;\r
+                                       else if (c == 1)\r
+                                               xendir = 0xd;\r
+                                       else\r
+                                       {\r
+                                               ERROR("unknown XENDIR endstate");\r
+                                               unsupported = 1;\r
+                                       }\r
+                               }\r
+                               break;\r
+                       case 0x14:      /* XENDDR */\r
+                               DEBUG("XENDDR");\r
+                               if (read(xsvf_fd, &c, 1) < 0)\r
+                                       do_abort = 1;\r
+                               else\r
+                               {\r
+                                       if (c == 0)\r
+                                               xenddr = 1;\r
+                                       else if (c == 1)\r
+                                               xenddr = 0x6;\r
+                                       else\r
+                                       {\r
+                                               ERROR("unknown XENDDR endstate");\r
+                                               unsupported = 1;\r
+                                       }\r
+                               }\r
+                               break;\r
+                       case 0x15:      /* XSIR2 */\r
+                               DEBUG("XSIR2");\r
+                               if (read(xsvf_fd, buf2, 2) < 0)\r
+                                       do_abort = 1;\r
+                               else\r
+                               {\r
+                                       u8 *ir_buf;\r
+                                       us = be_to_h_u16(buf2);\r
+                                       ir_buf = malloc((us + 7) / 8);\r
+                                       if (xsvf_read_buffer(us, xsvf_fd, ir_buf) != ERROR_OK)\r
+                                               do_abort = 1;\r
+                                       else\r
+                                       {\r
+                                               scan_field_t field;\r
+                                               field.device = device;\r
+                                               field.num_bits = us;\r
+                                               field.out_value = ir_buf;\r
+                                               field.out_mask = NULL;\r
+                                               field.in_value = NULL;\r
+                                               field.in_check_value = NULL;\r
+                                               field.in_check_mask = NULL;\r
+                                               field.in_handler = NULL;\r
+                                               field.in_handler_priv = NULL;\r
+                                               if (device == -1)\r
+                                                       jtag_add_plain_ir_scan(1, &field, xsvf_to_tap[xendir], NULL);\r
+                                               else\r
+                                                       jtag_add_ir_scan(1, &field, xsvf_to_tap[xendir], NULL);\r
+                                       }\r
+                                       free(ir_buf);\r
+                               }\r
+                               break;\r
+                       case 0x16:      /* XCOMMENT */\r
+                               do\r
+                               {\r
+                                       if (read(xsvf_fd, &c, 1) < 0)\r
+                                       {\r
+                                               do_abort = 1;\r
+                                               break;\r
+                                       }\r
+                               } while (c != 0);\r
+                               break;\r
+                       case 0x17:      /* XWAIT */\r
+                               DEBUG("XWAIT");\r
+                               if ((read(xsvf_fd, &uc, 1) < 0) || (read(xsvf_fd, &uc2, 1) < 0) || (read(xsvf_fd, buf4, 4) < 0))\r
+                                       do_abort = 1;\r
+                               else\r
+                               {\r
+                                       jtag_add_statemove(xsvf_to_tap[uc]);\r
+                                       ui = be_to_h_u32(buf4);\r
+                                       jtag_add_sleep(ui);\r
+                                       jtag_add_statemove(xsvf_to_tap[uc2]);\r
+                               }\r
+                               break;\r
+                       default:\r
+                               ERROR("unknown xsvf command (0x%2.2x)\n", c);\r
+                               unsupported = 1;\r
+               }\r
+\r
+               if (do_abort || unsupported || tdo_mismatch)\r
+                       break;\r
+       }\r
+       \r
+       if (tdo_mismatch)\r
+       {\r
+               command_print(cmd_ctx, "TDO mismatch, aborting");\r
+               jtag_cancel_queue();\r
+               return ERROR_OK;\r
+       }\r
+\r
+       if (unsupported)\r
+       {\r
+               command_print(cmd_ctx, "unsupported xsvf command encountered, aborting");\r
+               jtag_cancel_queue();\r
+               return ERROR_OK;\r
+       }\r
+\r
+       if (do_abort)\r
+       {\r
+               command_print(cmd_ctx, "premature end detected, aborting");\r
+               jtag_cancel_queue();\r
+               return ERROR_OK;\r
+       }\r
+       \r
+       if (dr_out_buf)\r
+               free(dr_out_buf);\r
+       \r
+       if (dr_in_buf)\r
+               free(dr_in_buf);\r
+       \r
+       if (dr_in_mask)\r
+               free(dr_in_mask);\r
+\r
+       close(xsvf_fd);\r
+       \r
+       command_print(cmd_ctx, "XSVF file programmed successfully");\r
+\r
+       return ERROR_OK;\r
+}\r

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)