- rename log functions to stop conflicts under win32 (wingdi)
[fw/openocd] / src / jtag / jtag.c
index 7ea40edb0e190ff3c06c9dac849a9a1b8d0dfafa..463a1720e47322970ee59b3bd0232fc40b4de3eb 100644 (file)
 #include "string.h"
 #include <unistd.h>
 
+
+/* note that this is not marked as static as it must be available from outside jtag.c for those 
+   that implement the jtag_xxx() minidriver layer 
+*/
+int jtag_error=ERROR_OK; 
+
+
 char* tap_state_strings[16] =
 {
        "tlr", 
@@ -58,6 +65,8 @@ static cmd_queue_page_t *cmd_queue_pages = NULL;
  * 3: Pause-DR
  * 4: Shift-IR
  * 5: Pause-IR
+ * 
+ * SD->SD and SI->SI have to be caught in interface specific code
  */
 u8 tap_move[6][6] =
 {
@@ -97,10 +106,7 @@ tap_transition_t tap_transitions[16] =
 
 char* jtag_event_strings[] =
 {
-       "SRST asserted",
-       "TRST asserted",
-       "SRST released",
-       "TRST released"
+       "JTAG controller reset(tms or TRST)"
 };
 
 enum tap_state end_state = TAP_TLR;
@@ -132,6 +138,11 @@ jtag_event_callback_t *jtag_event_callbacks;
 
 /* jtag interfaces (parport, FTDI-USB, TI-USB, ...)
  */
+#if BUILD_ECOSBOARD == 1
+       extern jtag_interface_t eCosBoard_interface;
+#endif
 #if BUILD_PARPORT == 1
        extern jtag_interface_t parport_interface;
 #endif
@@ -160,7 +171,18 @@ jtag_event_callback_t *jtag_event_callbacks;
        extern jtag_interface_t gw16012_interface;
 #endif
 
+#if BUILD_PRESTO_LIBFTDI == 1 || BUILD_PRESTO_FTD2XX == 1
+       extern jtag_interface_t presto_interface;
+#endif
+
+#if BUILD_USBPROG == 1
+       extern jtag_interface_t usbprog_interface;
+#endif
+
 jtag_interface_t *jtag_interfaces[] = {
+#if BUILD_ECOSBOARD == 1
+       &eCosBoard_interface,
+#endif
 #if BUILD_PARPORT == 1
        &parport_interface,
 #endif
@@ -181,6 +203,12 @@ jtag_interface_t *jtag_interfaces[] = {
 #endif
 #if BUILD_GW16012 == 1
        &gw16012_interface,
+#endif
+#if BUILD_PRESTO_LIBFTDI == 1 || BUILD_PRESTO_FTD2XX == 1
+       &presto_interface,
+#endif
+#if BUILD_USBPROG == 1
+       &usbprog_interface,
 #endif
        NULL,
 };
@@ -188,27 +216,25 @@ jtag_interface_t *jtag_interfaces[] = {
 jtag_interface_t *jtag = NULL;
 
 /* configuration */
-char* jtag_interface = NULL;
-int jtag_speed = -1;
+jtag_interface_t *jtag_interface = NULL;
+int jtag_speed = 0;
+int jtag_speed_post_reset = 0;
 
 
 /* forward declarations */
-int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state endstate, error_handler_t *error_handler);
-int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state endstate, error_handler_t *error_handler);
-int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state endstate, error_handler_t *error_handler);
-int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state endstate, error_handler_t *error_handler);
-int jtag_add_statemove(enum tap_state endstate);
-int jtag_add_pathmove(int num_states, enum tap_state *path);
-int jtag_add_runtest(int num_cycles, enum tap_state endstate);
+void jtag_add_statemove(enum tap_state endstate);
+void jtag_add_pathmove(int num_states, enum tap_state *path);
+void jtag_add_runtest(int num_cycles, enum tap_state endstate);
 int jtag_add_reset(int trst, int srst);
-int jtag_add_end_state(enum tap_state endstate);
-int jtag_add_sleep(u32 us);
+void jtag_add_end_state(enum tap_state endstate);
+void jtag_add_sleep(u32 us);
 int jtag_execute_queue(void);
 int jtag_cancel_queue(void);
 
 /* jtag commands */
 int handle_interface_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 int handle_jtag_speed_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+int handle_jtag_khz_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 int handle_jtag_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 int handle_reset_config_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 int handle_jtag_nsrst_delay_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
@@ -276,7 +302,7 @@ int jtag_call_event_callbacks(enum jtag_event event)
 {
        jtag_event_callback_t *callback = jtag_event_callbacks;
        
-       DEBUG("jtag event: %s", jtag_event_strings[event]);
+       LOG_DEBUG("jtag event: %s", jtag_event_strings[event]);
        
        while (callback)
        {
@@ -319,8 +345,9 @@ jtag_device_t* jtag_get_device(int num)
                device = device->next;
                i++;
        }
-
-       return NULL;
+       
+       LOG_ERROR("jtag device number %d not defined", num);
+       exit(-1);
 }
 
 void* cmd_queue_alloc(size_t size)
@@ -347,7 +374,8 @@ void* cmd_queue_alloc(size_t size)
        offset = (*p_page)->used;
        (*p_page)->used += size;
        
-       return ((*p_page)->address) + offset;
+       u8 *t=(u8 *)((*p_page)->address);
+       return t + offset;
 }
 
 void cmd_queue_free()
@@ -365,18 +393,45 @@ void cmd_queue_free()
        cmd_queue_pages = NULL;
 }
 
-int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state, error_handler_t *error_handler)
+static void jtag_prelude1()
+{
+       if (jtag_trst == 1)
+       {
+               LOG_WARNING("JTAG command queued, while TRST is low (TAP in reset)");
+               jtag_error=ERROR_JTAG_TRST_ASSERTED;
+               return;
+       }
+
+       if (cmd_queue_end_state == TAP_TLR)
+               jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
+}
+
+static void jtag_prelude(enum tap_state state)
 {
+       jtag_prelude1();
+       
+       if (state != -1)
+               cmd_queue_end_state = state;
+
+       cmd_queue_cur_state = cmd_queue_end_state;
+}
+
+void jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state)
+{
+       jtag_prelude(state);
+       
+       int retval=interface_jtag_add_ir_scan(num_fields, fields, cmd_queue_end_state);
+       if (retval!=ERROR_OK)
+               jtag_error=retval;
+}
+
+int MINIDRIVER(interface_jtag_add_ir_scan)(int num_fields, scan_field_t *fields, enum tap_state state)
+{      
        jtag_command_t **last_cmd;
        jtag_device_t *device;
        int i, j;
        int scan_size = 0;
 
-       if (jtag_trst == 1)
-       {
-               WARNING("JTAG command queued, while TRST is low (TAP in reset)");
-               return ERROR_JTAG_TRST_ASSERTED;
-       }
 
        last_cmd = jtag_get_last_command_p();
        
@@ -392,28 +447,8 @@ int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state,
        (*last_cmd)->cmd.scan->num_fields = jtag_num_devices;   /* one field per device */
        (*last_cmd)->cmd.scan->fields = cmd_queue_alloc(jtag_num_devices * sizeof(scan_field_t));
        (*last_cmd)->cmd.scan->end_state = state;
-       if (error_handler)
-       {
-               (*last_cmd)->cmd.scan->error_handler = cmd_queue_alloc(sizeof(error_handler_t));
-               *(*last_cmd)->cmd.scan->error_handler = *error_handler;
-       }
-       else
-       {
-               (*last_cmd)->cmd.scan->error_handler = NULL;
-       }
-               
-       if (state != -1)
-               cmd_queue_end_state = state;
 
-       if (cmd_queue_cur_state == TAP_TLR && cmd_queue_end_state != TAP_TLR)
-               jtag_call_event_callbacks(JTAG_TRST_RELEASED);
-       
-       if (cmd_queue_end_state == TAP_TLR)
-               jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
-       
-       cmd_queue_cur_state = cmd_queue_end_state;
-               
-       for (i=0; i < jtag_num_devices; i++)
+       for (i = 0; i < jtag_num_devices; i++)
        {
                int found = 0;
                device = jtag_get_device(i);
@@ -421,27 +456,30 @@ int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state,
                (*last_cmd)->cmd.scan->fields[i].device = i;
                (*last_cmd)->cmd.scan->fields[i].num_bits = scan_size;
                (*last_cmd)->cmd.scan->fields[i].in_value = NULL;
-               if (jtag_verify_capture_ir)
-               {
-                       (*last_cmd)->cmd.scan->fields[i].in_check_value = buf_cpy(device->expected, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
-                       (*last_cmd)->cmd.scan->fields[i].in_check_mask = buf_cpy(device->expected_mask, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
-               }
-               else
-               {
-                       (*last_cmd)->cmd.scan->fields[i].in_check_value = NULL;
-                       (*last_cmd)->cmd.scan->fields[i].in_check_mask = NULL;
-               }
-               (*last_cmd)->cmd.scan->fields[i].in_handler = NULL;
-               (*last_cmd)->cmd.scan->fields[i].in_handler_priv = NULL;
+               (*last_cmd)->cmd.scan->fields[i].in_handler = NULL;     /* disable verification by default */
 
                /* search the list */
-               for (j=0; j < num_fields; j++)
+               for (j = 0; j < num_fields; j++)
                {
                        if (i == fields[j].device)
                        {
                                found = 1;
                                (*last_cmd)->cmd.scan->fields[i].out_value = buf_cpy(fields[j].out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
                                (*last_cmd)->cmd.scan->fields[i].out_mask = buf_cpy(fields[j].out_mask, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
+                       
+                               if (jtag_verify_capture_ir)
+                               {
+                                       if (fields[j].in_handler==NULL)
+                                       {
+                                               jtag_set_check_value((*last_cmd)->cmd.scan->fields+i, device->expected, device->expected_mask, NULL);
+                                       } else
+                                       {
+                                               (*last_cmd)->cmd.scan->fields[i].in_handler = fields[j].in_handler;
+                                               (*last_cmd)->cmd.scan->fields[i].in_handler_priv = fields[j].in_handler_priv;
+                                               (*last_cmd)->cmd.scan->fields[i].in_check_value = device->expected; 
+                                               (*last_cmd)->cmd.scan->fields[i].in_check_mask = device->expected_mask;
+                                       }
+                               }
                                
                                device->bypass = 0;
                                break;
@@ -454,7 +492,7 @@ int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state,
                        (*last_cmd)->cmd.scan->fields[i].out_value = buf_set_ones(cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
                        (*last_cmd)->cmd.scan->fields[i].out_mask = NULL;
                        device->bypass = 1;
-               
+                       
                }
                
                /* update device information */
@@ -464,17 +502,20 @@ int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state,
        return ERROR_OK;
 }
 
-int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state, error_handler_t *error_handler)
+void jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state)
 {
-       jtag_command_t **last_cmd;
-       int i;
-
-       if (jtag_trst == 1)
-       {
-               WARNING("JTAG command queued, while TRST is low (TAP in reset)");
-               return ERROR_JTAG_TRST_ASSERTED;
-       }
+       jtag_prelude(state);
+       
+       int retval=interface_jtag_add_plain_ir_scan(num_fields, fields, cmd_queue_end_state);
+       if (retval!=ERROR_OK)
+               jtag_error=retval;
+}
 
+int MINIDRIVER(interface_jtag_add_plain_ir_scan)(int num_fields, scan_field_t *fields, enum tap_state state)
+{
+       int i;
+       jtag_command_t **last_cmd;
+       
        last_cmd = jtag_get_last_command_p();
        
        /* allocate memory for a new list member */
@@ -489,27 +530,7 @@ int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state
        (*last_cmd)->cmd.scan->num_fields = num_fields;
        (*last_cmd)->cmd.scan->fields = cmd_queue_alloc(num_fields * sizeof(scan_field_t));
        (*last_cmd)->cmd.scan->end_state = state;
-       if (error_handler)
-       {
-               (*last_cmd)->cmd.scan->error_handler = cmd_queue_alloc(sizeof(error_handler_t));
-               *(*last_cmd)->cmd.scan->error_handler = *error_handler;
-       }
-       else
-       {
-               (*last_cmd)->cmd.scan->error_handler = NULL;
-       }
-
-       if (state != -1)
-               cmd_queue_end_state = state;
 
-       if (cmd_queue_cur_state == TAP_TLR && cmd_queue_end_state != TAP_TLR)
-               jtag_call_event_callbacks(JTAG_TRST_RELEASED);
-       
-       if (cmd_queue_end_state == TAP_TLR)
-               jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
-               
-       cmd_queue_cur_state = cmd_queue_end_state;
-       
        for (i = 0; i < num_fields; i++)
        {
                int num_bits = fields[i].num_bits;
@@ -519,28 +540,32 @@ int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state
                (*last_cmd)->cmd.scan->fields[i].out_value = buf_cpy(fields[i].out_value, cmd_queue_alloc(num_bytes), num_bits);
                (*last_cmd)->cmd.scan->fields[i].out_mask = buf_cpy(fields[i].out_mask, cmd_queue_alloc(num_bytes), num_bits);
                (*last_cmd)->cmd.scan->fields[i].in_value = fields[i].in_value;
-               (*last_cmd)->cmd.scan->fields[i].in_check_value = buf_cpy(fields[i].in_check_value, cmd_queue_alloc(num_bytes), num_bits);
-               (*last_cmd)->cmd.scan->fields[i].in_check_mask = buf_cpy(fields[i].in_check_mask, cmd_queue_alloc(num_bytes), num_bits);
+               (*last_cmd)->cmd.scan->fields[i].in_check_value = fields[i].in_check_value;
+               (*last_cmd)->cmd.scan->fields[i].in_check_mask = fields[i].in_check_mask;
                (*last_cmd)->cmd.scan->fields[i].in_handler = NULL;
                (*last_cmd)->cmd.scan->fields[i].in_handler_priv = NULL;
        }
        return ERROR_OK;
 }
 
-int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state, error_handler_t *error_handler)
+void jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state)
+{
+       jtag_prelude(state);
+
+       int retval=interface_jtag_add_dr_scan(num_fields, fields, cmd_queue_end_state);
+       if (retval!=ERROR_OK)
+               jtag_error=retval;
+}
+
+int MINIDRIVER(interface_jtag_add_dr_scan)(int num_fields, scan_field_t *fields, enum tap_state state)
 {
        int i, j;
        int bypass_devices = 0;
        int field_count = 0;
-       jtag_command_t **last_cmd = jtag_get_last_command_p();
-       jtag_device_t *device = jtag_devices;
        int scan_size;
 
-       if (jtag_trst == 1)
-       {
-               WARNING("JTAG command queued, while TRST is low (TAP in reset)");
-               return ERROR_JTAG_TRST_ASSERTED;
-       }
+       jtag_command_t **last_cmd = jtag_get_last_command_p();
+       jtag_device_t *device = jtag_devices;
 
        /* count devices in bypass */
        while (device)
@@ -562,33 +587,13 @@ int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state,
        (*last_cmd)->cmd.scan->num_fields = num_fields + bypass_devices;
        (*last_cmd)->cmd.scan->fields = cmd_queue_alloc((num_fields + bypass_devices) * sizeof(scan_field_t));
        (*last_cmd)->cmd.scan->end_state = state;
-       if (error_handler)
-       {
-               (*last_cmd)->cmd.scan->error_handler = cmd_queue_alloc(sizeof(error_handler_t));
-               *(*last_cmd)->cmd.scan->error_handler = *error_handler;
-       }
-       else
-       {
-               (*last_cmd)->cmd.scan->error_handler = NULL;
-       }
        
-       if (state != -1)
-               cmd_queue_end_state = state;
-
-       if (cmd_queue_cur_state == TAP_TLR && cmd_queue_end_state != TAP_TLR)
-               jtag_call_event_callbacks(JTAG_TRST_RELEASED);
-       
-       if (cmd_queue_end_state == TAP_TLR)
-               jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
-                       
-       cmd_queue_cur_state = cmd_queue_end_state;
-       
-       for (i=0; i < jtag_num_devices; i++)
+       for (i = 0; i < jtag_num_devices; i++)
        {
                int found = 0;
                (*last_cmd)->cmd.scan->fields[field_count].device = i;
        
-               for (j=0; j < num_fields; j++)
+               for (j = 0; j < num_fields; j++)
                {
                        if (i == fields[j].device)
                        {
@@ -598,21 +603,22 @@ int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state,
                                (*last_cmd)->cmd.scan->fields[field_count].out_value = buf_cpy(fields[j].out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
                                (*last_cmd)->cmd.scan->fields[field_count].out_mask = buf_cpy(fields[j].out_mask, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
                                (*last_cmd)->cmd.scan->fields[field_count].in_value = fields[j].in_value;
-                               (*last_cmd)->cmd.scan->fields[field_count].in_check_value = buf_cpy(fields[j].in_check_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
-                               (*last_cmd)->cmd.scan->fields[field_count].in_check_mask = buf_cpy(fields[j].in_check_mask, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
+                               (*last_cmd)->cmd.scan->fields[field_count].in_check_value = fields[j].in_check_value;
+                               (*last_cmd)->cmd.scan->fields[field_count].in_check_mask = fields[j].in_check_mask;
                                (*last_cmd)->cmd.scan->fields[field_count].in_handler = fields[j].in_handler;
                                (*last_cmd)->cmd.scan->fields[field_count++].in_handler_priv = fields[j].in_handler_priv;
                        }
                }
                if (!found)
                {
+#ifdef _DEBUG_JTAG_IO_
                        /* if a device isn't listed, the BYPASS register should be selected */
                        if (!jtag_get_device(i)->bypass)
                        {
-                               ERROR("BUG: no scan data for a device not in BYPASS");
+                               LOG_ERROR("BUG: no scan data for a device not in BYPASS");
                                exit(-1);
                        }
-       
+#endif 
                        /* program the scan field to 1 bit length, and ignore it's value */
                        (*last_cmd)->cmd.scan->fields[field_count].num_bits = 1;
                        (*last_cmd)->cmd.scan->fields[field_count].out_value = NULL;
@@ -625,27 +631,122 @@ int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state,
                }
                else
                {
+#ifdef _DEBUG_JTAG_IO_
                        /* if a device is listed, the BYPASS register must not be selected */
                        if (jtag_get_device(i)->bypass)
                        {
-                               WARNING("scan data for a device in BYPASS");
+                               LOG_ERROR("BUG: scan data for a device in BYPASS");
+                               exit(-1);
                        }
+#endif
                }
        }
        return ERROR_OK;
 }
 
-int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state, error_handler_t *error_handler)
+void MINIDRIVER(interface_jtag_add_dr_out)(int device_num, 
+               int num_fields,
+               int *num_bits,
+               u32 *value,
+               enum tap_state end_state)
 {
        int i;
+       int field_count = 0;
+       int scan_size;
+       int bypass_devices = 0;
+
        jtag_command_t **last_cmd = jtag_get_last_command_p();
+       jtag_device_t *device = jtag_devices;
+       /* count devices in bypass */
+       while (device)
+       {
+               if (device->bypass)
+                       bypass_devices++;
+               device = device->next;
+       }
        
-       if (jtag_trst == 1)
+       /* allocate memory for a new list member */
+       *last_cmd = cmd_queue_alloc(sizeof(jtag_command_t));
+       last_comand_pointer = &((*last_cmd)->next);
+       (*last_cmd)->next = NULL;
+       (*last_cmd)->type = JTAG_SCAN;
+
+       /* allocate memory for dr scan command */
+       (*last_cmd)->cmd.scan = cmd_queue_alloc(sizeof(scan_command_t));
+       (*last_cmd)->cmd.scan->ir_scan = 0;
+       (*last_cmd)->cmd.scan->num_fields = num_fields + bypass_devices;
+       (*last_cmd)->cmd.scan->fields = cmd_queue_alloc((num_fields + bypass_devices) * sizeof(scan_field_t));
+       (*last_cmd)->cmd.scan->end_state = end_state;
+       
+       for (i = 0; i < jtag_num_devices; i++)
        {
-               WARNING("JTAG command queued, while TRST is low (TAP in reset)");
-               return ERROR_JTAG_TRST_ASSERTED;
+               (*last_cmd)->cmd.scan->fields[field_count].device = i;
+       
+               if (i == device_num)
+               {
+                       int j;
+#ifdef _DEBUG_JTAG_IO_
+                       /* if a device is listed, the BYPASS register must not be selected */
+                       if (jtag_get_device(i)->bypass)
+                       {
+                               LOG_ERROR("BUG: scan data for a device in BYPASS");
+                               exit(-1);
+                       }
+#endif
+                       for (j = 0; j < num_fields; j++)
+                       {
+                               u8 out_value[4];
+                               scan_size = num_bits[j];
+                               buf_set_u32(out_value, 0, scan_size, value[j]);
+                               (*last_cmd)->cmd.scan->fields[field_count].num_bits = scan_size;
+                               (*last_cmd)->cmd.scan->fields[field_count].out_value = buf_cpy(out_value, cmd_queue_alloc(CEIL(scan_size, 8)), scan_size);
+                               (*last_cmd)->cmd.scan->fields[field_count].out_mask = NULL;
+                               (*last_cmd)->cmd.scan->fields[field_count].in_value = NULL;
+                               (*last_cmd)->cmd.scan->fields[field_count].in_check_value = NULL;
+                               (*last_cmd)->cmd.scan->fields[field_count].in_check_mask = NULL;
+                               (*last_cmd)->cmd.scan->fields[field_count].in_handler = NULL;
+                               (*last_cmd)->cmd.scan->fields[field_count++].in_handler_priv = NULL;
+                       }
+               } else
+               {
+#ifdef _DEBUG_JTAG_IO_
+                       /* if a device isn't listed, the BYPASS register should be selected */
+                       if (!jtag_get_device(i)->bypass)
+                       {
+                               LOG_ERROR("BUG: no scan data for a device not in BYPASS");
+                               exit(-1);
+                       }
+#endif 
+                       /* program the scan field to 1 bit length, and ignore it's value */
+                       (*last_cmd)->cmd.scan->fields[field_count].num_bits = 1;
+                       (*last_cmd)->cmd.scan->fields[field_count].out_value = NULL;
+                       (*last_cmd)->cmd.scan->fields[field_count].out_mask = NULL;
+                       (*last_cmd)->cmd.scan->fields[field_count].in_value = NULL;
+                       (*last_cmd)->cmd.scan->fields[field_count].in_check_value = NULL;
+                       (*last_cmd)->cmd.scan->fields[field_count].in_check_mask = NULL;
+                       (*last_cmd)->cmd.scan->fields[field_count].in_handler = NULL;
+                       (*last_cmd)->cmd.scan->fields[field_count++].in_handler_priv = NULL;
+               }
        }
+}
 
+
+
+
+void jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state)
+{
+       jtag_prelude(state);
+
+       int retval=interface_jtag_add_plain_dr_scan(num_fields, fields, cmd_queue_end_state);
+       if (retval!=ERROR_OK)
+               jtag_error=retval;
+}
+
+int MINIDRIVER(interface_jtag_add_plain_dr_scan)(int num_fields, scan_field_t *fields, enum tap_state state)
+{
+       int i;
+       jtag_command_t **last_cmd = jtag_get_last_command_p();
+       
        /* allocate memory for a new list member */
        *last_cmd = cmd_queue_alloc(sizeof(jtag_command_t));
        last_comand_pointer = &((*last_cmd)->next);
@@ -658,26 +759,6 @@ int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state
        (*last_cmd)->cmd.scan->num_fields = num_fields;
        (*last_cmd)->cmd.scan->fields = cmd_queue_alloc(num_fields * sizeof(scan_field_t));
        (*last_cmd)->cmd.scan->end_state = state;
-       if (error_handler)
-       {
-               (*last_cmd)->cmd.scan->error_handler = cmd_queue_alloc(sizeof(error_handler_t));
-               *(*last_cmd)->cmd.scan->error_handler = *error_handler;
-       }
-       else
-       {
-               (*last_cmd)->cmd.scan->error_handler = NULL;
-       }
-               
-       if (state != -1)
-               cmd_queue_end_state = state;
-
-       if (cmd_queue_cur_state == TAP_TLR && cmd_queue_end_state != TAP_TLR)
-               jtag_call_event_callbacks(JTAG_TRST_RELEASED);
-       
-       if (cmd_queue_end_state == TAP_TLR)
-               jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
-                       
-       cmd_queue_cur_state = cmd_queue_end_state;
        
        for (i = 0; i < num_fields; i++)
        {
@@ -688,24 +769,28 @@ int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state
                (*last_cmd)->cmd.scan->fields[i].out_value = buf_cpy(fields[i].out_value, cmd_queue_alloc(num_bytes), num_bits);
                (*last_cmd)->cmd.scan->fields[i].out_mask = buf_cpy(fields[i].out_mask, cmd_queue_alloc(num_bytes), num_bits);
                (*last_cmd)->cmd.scan->fields[i].in_value = fields[i].in_value;
-               (*last_cmd)->cmd.scan->fields[i].in_check_value = buf_cpy(fields[i].in_check_value, cmd_queue_alloc(num_bytes), num_bits);
-               (*last_cmd)->cmd.scan->fields[i].in_check_mask = buf_cpy(fields[i].in_check_mask, cmd_queue_alloc(num_bytes), num_bits);
+               (*last_cmd)->cmd.scan->fields[i].in_check_value = fields[i].in_check_value;
+               (*last_cmd)->cmd.scan->fields[i].in_check_mask = fields[i].in_check_mask;
                (*last_cmd)->cmd.scan->fields[i].in_handler = fields[i].in_handler;
                (*last_cmd)->cmd.scan->fields[i].in_handler_priv = fields[i].in_handler_priv;
        }
 
        return ERROR_OK;
 }
-int jtag_add_statemove(enum tap_state state)
+void jtag_add_statemove(enum tap_state state)
+{
+       jtag_prelude(state);
+
+       int retval;
+       retval=interface_jtag_add_statemove(cmd_queue_end_state);
+       if (retval!=ERROR_OK)
+               jtag_error=retval;
+}
+
+int MINIDRIVER(interface_jtag_add_statemove)(enum tap_state state)
 {
        jtag_command_t **last_cmd = jtag_get_last_command_p();
        
-       if (jtag_trst == 1)
-       {
-               WARNING("JTAG command queued, while TRST is low (TAP in reset)");
-               return ERROR_JTAG_TRST_ASSERTED;
-       }
-
        /* allocate memory for a new list member */
        *last_cmd = cmd_queue_alloc(sizeof(jtag_command_t));
        last_comand_pointer = &((*last_cmd)->next);
@@ -715,106 +800,67 @@ int jtag_add_statemove(enum tap_state state)
        (*last_cmd)->cmd.statemove = cmd_queue_alloc(sizeof(statemove_command_t));
        (*last_cmd)->cmd.statemove->end_state = state;
        
-       if (state != -1)
-               cmd_queue_end_state = state;
-
-       if (cmd_queue_cur_state == TAP_TLR && cmd_queue_end_state != TAP_TLR)
-               jtag_call_event_callbacks(JTAG_TRST_RELEASED);
-       
-       if (cmd_queue_end_state == TAP_TLR)
-               jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
-                       
-       cmd_queue_cur_state = cmd_queue_end_state;
        
        return ERROR_OK;
 }
 
-int jtag_add_pathmove(int num_states, enum tap_state *path)
+void jtag_add_pathmove(int num_states, enum tap_state *path)
 {
-       jtag_command_t **last_cmd = jtag_get_last_command_p();
-       int i;
-       
-       if (jtag_trst == 1)
-       {
-               WARNING("JTAG command queued, while TRST is low (TAP in reset)");
-               return ERROR_JTAG_TRST_ASSERTED;
-       }
-       
        /* the last state has to be a stable state */
        if (tap_move_map[path[num_states - 1]] == -1)
        {
-               ERROR("TAP path doesn't finish in a stable state");
-               return ERROR_JTAG_NOT_IMPLEMENTED;
-       }
-       
-       if (jtag->support_pathmove)
-       {
-               /* allocate memory for a new list member */
-               *last_cmd = cmd_queue_alloc(sizeof(jtag_command_t));
-               last_comand_pointer = &((*last_cmd)->next);
-               (*last_cmd)->next = NULL;
-               (*last_cmd)->type = JTAG_PATHMOVE;
-       
-               (*last_cmd)->cmd.pathmove = cmd_queue_alloc(sizeof(pathmove_command_t));
-               (*last_cmd)->cmd.pathmove->num_states = num_states;
-               (*last_cmd)->cmd.pathmove->path = cmd_queue_alloc(sizeof(enum tap_state) * num_states);
-               
-               for (i = 0; i < num_states; i++)
-                       (*last_cmd)->cmd.pathmove->path[i] = path[i];
+               LOG_ERROR("BUG: TAP path doesn't finish in a stable state");
+               exit(-1);
        }
-       else
+
+       enum tap_state cur_state=cmd_queue_cur_state;
+       int i;
+       for (i=0; i<num_states; i++)
        {
-               /* validate the desired path, and see if it fits a default path */
-               int begin = 0;
-               int end = 0;
-               int j;
-               
-               for (i = 0; i < num_states; i++)
+               if ((tap_transitions[cur_state].low != path[i])&&
+                               (tap_transitions[cur_state].high != path[i]))
                {
-                       for (j = i; j < num_states; j++)
-                       {
-                               if (tap_move_map[path[j]] != -1)
-                               {       
-                                       end = j;
-                                       break;
-                               }
-                       }
-                       
-                       if (begin - end <= 7)   /* a default path spans no more than 7 states */
-                       {
-                               jtag_add_statemove(path[end]);
-                       }
-                       else
-                       {
-                               ERROR("encountered a TAP path that can't be fulfilled by default paths");       
-                               return ERROR_JTAG_NOT_IMPLEMENTED;
-                       }
-                       
-                       i = end;
+                       LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[path[i]]);
+                       exit(-1);
                }
+               cur_state = path[i];
        }
-
-       if (cmd_queue_cur_state == TAP_TLR && cmd_queue_end_state != TAP_TLR)
-               jtag_call_event_callbacks(JTAG_TRST_RELEASED);
        
-       if (cmd_queue_end_state == TAP_TLR)
-               jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
+       jtag_prelude1();
        
        cmd_queue_cur_state = path[num_states - 1];
-       
-       return ERROR_OK;
+
+       int retval=interface_jtag_add_pathmove(num_states, path);
+       if (retval!=ERROR_OK)
+               jtag_error=retval;
 }
 
-int jtag_add_runtest(int num_cycles, enum tap_state state)
+
+int MINIDRIVER(interface_jtag_add_pathmove)(int num_states, enum tap_state *path)
 {
        jtag_command_t **last_cmd = jtag_get_last_command_p();
+       int i;
        
-       if (jtag_trst == 1)
-       {
-               WARNING("JTAG command queued, while TRST is low (TAP in reset)");
-               return ERROR_JTAG_TRST_ASSERTED;
-       }
+       /* allocate memory for a new list member */
+       *last_cmd = cmd_queue_alloc(sizeof(jtag_command_t));
+       last_comand_pointer = &((*last_cmd)->next);
+       (*last_cmd)->next = NULL;
+       (*last_cmd)->type = JTAG_PATHMOVE;
+
+       (*last_cmd)->cmd.pathmove = cmd_queue_alloc(sizeof(pathmove_command_t));
+       (*last_cmd)->cmd.pathmove->num_states = num_states;
+       (*last_cmd)->cmd.pathmove->path = cmd_queue_alloc(sizeof(enum tap_state) * num_states);
+       
+       for (i = 0; i < num_states; i++)
+               (*last_cmd)->cmd.pathmove->path[i] = path[i];
+       
+       return ERROR_OK;
+}
 
+int MINIDRIVER(interface_jtag_add_runtest)(int num_cycles, enum tap_state state)
+{
+       jtag_command_t **last_cmd = jtag_get_last_command_p();
+       
        /* allocate memory for a new list member */
        *last_cmd = cmd_queue_alloc(sizeof(jtag_command_t));
        (*last_cmd)->next = NULL;
@@ -825,25 +871,23 @@ int jtag_add_runtest(int num_cycles, enum tap_state state)
        (*last_cmd)->cmd.runtest->num_cycles = num_cycles;
        (*last_cmd)->cmd.runtest->end_state = state;
        
-       if (state != -1)
-               cmd_queue_end_state = state;
+       return ERROR_OK;
+}
 
-       if (cmd_queue_cur_state == TAP_TLR && cmd_queue_end_state != TAP_TLR)
-               jtag_call_event_callbacks(JTAG_TRST_RELEASED);
-       
-       if (cmd_queue_end_state == TAP_TLR)
-               jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
-                       
-       cmd_queue_cur_state = cmd_queue_end_state;
+void jtag_add_runtest(int num_cycles, enum tap_state state)
+{
+       jtag_prelude(state);
        
-       return ERROR_OK;
+       /* executed by sw or hw fifo */
+       int retval=interface_jtag_add_runtest(num_cycles, cmd_queue_end_state);
+       if (retval!=ERROR_OK)
+               jtag_error=retval;
 }
 
 int jtag_add_reset(int req_trst, int req_srst)
 {
        int trst_with_tms = 0;
-       
-       jtag_command_t **last_cmd = jtag_get_last_command_p();
+       int retval;
        
        if (req_trst == -1)
                req_trst = jtag_trst;
@@ -854,7 +898,10 @@ int jtag_add_reset(int req_trst, int req_srst)
        /* Make sure that jtag_reset_config allows the requested reset */
        /* if SRST pulls TRST, we can't fulfill srst == 1 with trst == 0 */
        if (((jtag_reset_config & RESET_SRST_PULLS_TRST) && (req_srst == 1)) && (req_trst == 0))
+       {
+               LOG_WARNING("requested reset would assert trst");
                return ERROR_JTAG_RESET_WOULD_ASSERT_TRST;
+       }
                
        /* if TRST pulls SRST, we reset with TAP T-L-R */
        if (((jtag_reset_config & RESET_TRST_PULLS_SRST) && (req_trst == 1)) && (req_srst == 0))
@@ -865,7 +912,7 @@ int jtag_add_reset(int req_trst, int req_srst)
        
        if (req_srst && !(jtag_reset_config & RESET_HAS_SRST))
        {
-               ERROR("requested nSRST assertion, but the current configuration doesn't support this");
+               LOG_WARNING("requested nSRST assertion, but the current configuration doesn't support this");
                return ERROR_JTAG_RESET_CANT_SRST;
        }
        
@@ -874,93 +921,82 @@ int jtag_add_reset(int req_trst, int req_srst)
                req_trst = 0;
                trst_with_tms = 1;
        }
-       
-       /* allocate memory for a new list member */
-       *last_cmd = cmd_queue_alloc(sizeof(jtag_command_t));
-       (*last_cmd)->next = NULL;
-       last_comand_pointer = &((*last_cmd)->next);
-       (*last_cmd)->type = JTAG_RESET;
-
-       (*last_cmd)->cmd.reset = cmd_queue_alloc(sizeof(reset_command_t));
-       (*last_cmd)->cmd.reset->trst = req_trst;
-       (*last_cmd)->cmd.reset->srst = req_srst;
 
        jtag_trst = req_trst;
        jtag_srst = req_srst;
 
+       retval = interface_jtag_add_reset(req_trst, req_srst);
+       if (retval!=ERROR_OK)
+       {
+               jtag_error=retval;
+               return retval;
+       }
+
        if (jtag_srst)
        {
-               jtag_call_event_callbacks(JTAG_SRST_ASSERTED);
+               LOG_DEBUG("SRST line asserted");
        }
        else
        {
-               jtag_call_event_callbacks(JTAG_SRST_RELEASED);
+               LOG_DEBUG("SRST line released");
                if (jtag_nsrst_delay)
                        jtag_add_sleep(jtag_nsrst_delay * 1000);
        }
        
        if (trst_with_tms)
        {
-               last_cmd = &((*last_cmd)->next);
-               
-               /* allocate memory for a new list member */
-               *last_cmd = cmd_queue_alloc(sizeof(jtag_command_t));
-               (*last_cmd)->next = NULL;
-               last_comand_pointer = &((*last_cmd)->next);
-               (*last_cmd)->type = JTAG_STATEMOVE;
-
-               (*last_cmd)->cmd.statemove = cmd_queue_alloc(sizeof(statemove_command_t));
-               (*last_cmd)->cmd.statemove->end_state = TAP_TLR;
-               
+               LOG_DEBUG("JTAG reset with tms instead of TRST");
+               jtag_add_end_state(TAP_TLR);
+               jtag_add_statemove(TAP_TLR);
                jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
-               cmd_queue_cur_state = TAP_TLR;
-               cmd_queue_end_state = TAP_TLR;
-               
                return ERROR_OK;
        }
+       
+       if (jtag_trst)
+       {
+               /* we just asserted nTRST, so we're now in Test-Logic-Reset,
+                * and inform possible listeners about this
+                */
+               LOG_DEBUG("TRST line asserted");
+               cmd_queue_cur_state = TAP_TLR;
+               jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
+       }
        else
        {
-               if (jtag_trst)
-               {
-                       /* we just asserted nTRST, so we're now in Test-Logic-Reset,
-                        * and inform possible listeners about this
-                        */
-                       cmd_queue_cur_state = TAP_TLR;
-                       jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
-               }
-               else
-               {
-                       /* the nTRST line got deasserted, so we're still in Test-Logic-Reset,
-                        * but we might want to add a delay to give the TAP time to settle
-                        */
-                       if (jtag_ntrst_delay)
-                               jtag_add_sleep(jtag_ntrst_delay * 1000);
-               }
+               /* the nTRST line got deasserted, so we're still in Test-Logic-Reset,
+                * but we might want to add a delay to give the TAP time to settle
+                */
+               LOG_DEBUG("Now in TAP_TLR - Test-Logic-Reset(either due to TRST line asserted or tms reset)");
+               if (jtag_ntrst_delay)
+                       jtag_add_sleep(jtag_ntrst_delay * 1000);
        }
-
        return ERROR_OK;
 }
 
-int jtag_add_end_state(enum tap_state state)
+int MINIDRIVER(interface_jtag_add_reset)(int req_trst, int req_srst)
 {
        jtag_command_t **last_cmd = jtag_get_last_command_p();
-       
+
        /* allocate memory for a new list member */
        *last_cmd = cmd_queue_alloc(sizeof(jtag_command_t));
        (*last_cmd)->next = NULL;
        last_comand_pointer = &((*last_cmd)->next);
-       (*last_cmd)->type = JTAG_END_STATE;
+       (*last_cmd)->type = JTAG_RESET;
 
-       (*last_cmd)->cmd.end_state = cmd_queue_alloc(sizeof(end_state_command_t));
-       (*last_cmd)->cmd.end_state->end_state = state;
+       (*last_cmd)->cmd.reset = cmd_queue_alloc(sizeof(reset_command_t));
+       (*last_cmd)->cmd.reset->trst = req_trst;
+       (*last_cmd)->cmd.reset->srst = req_srst;
 
-       if (state != -1)
-               cmd_queue_end_state = state;
        
        return ERROR_OK;
 }
 
-int jtag_add_sleep(u32 us)
+void jtag_add_end_state(enum tap_state state)
+{
+       cmd_queue_end_state = state;
+}
+
+int MINIDRIVER(interface_jtag_add_sleep)(u32 us)
 {
        jtag_command_t **last_cmd = jtag_get_last_command_p();
        
@@ -976,13 +1012,21 @@ int jtag_add_sleep(u32 us)
        return ERROR_OK;
 }
 
+void jtag_add_sleep(u32 us)
+{
+       int retval=interface_jtag_add_sleep(us);
+       if (retval!=ERROR_OK)
+               jtag_error=retval;
+       return;
+}
+
 int jtag_scan_size(scan_command_t *cmd)
 {
        int bit_count = 0;
        int i;
 
        /* count bits in scan command */
-       for (i=0; i<cmd->num_fields; i++)
+       for (i = 0; i < cmd->num_fields; i++)
        {
                bit_count += cmd->fields[i].num_bits;
        }
@@ -1009,7 +1053,7 @@ int jtag_build_buffer(scan_command_t *cmd, u8 **buffer)
 #endif
                        buf_set_buf(cmd->fields[i].out_value, 0, *buffer, bit_count, cmd->fields[i].num_bits);
 #ifdef _DEBUG_JTAG_IO_
-                       DEBUG("fields[%i].out_value: 0x%s", i, char_buf);
+                       LOG_DEBUG("fields[%i].out_value: 0x%s", i, char_buf);
                        free(char_buf);
 #endif
                }
@@ -1030,22 +1074,23 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
        /* we return ERROR_OK, unless a check fails, or a handler reports a problem */
        retval = ERROR_OK;
        
-       for (i=0; i < cmd->num_fields; i++)
+       for (i = 0; i < cmd->num_fields; i++)
        {
-               /* if neither in_value, in_check_value nor in_handler
+               /* if neither in_value nor in_handler
                 * are specified we don't have to examine this field
                 */
-               if (cmd->fields[i].in_value || cmd->fields[i].in_check_value || cmd->fields[i].in_handler)
+               if (cmd->fields[i].in_value || cmd->fields[i].in_handler)
                {
                        int num_bits = cmd->fields[i].num_bits;
                        u8 *captured = buf_set_buf(buffer, bit_count, malloc(CEIL(num_bits, 8)), 0, num_bits);
-                       #ifdef _DEBUG_JTAG_IO_
-                               char *char_buf;
+                       
+#ifdef _DEBUG_JTAG_IO_
+                       char *char_buf;
 
-                               char_buf = buf_to_str(captured, (num_bits > 64) ? 64 : num_bits, 16);
-                               DEBUG("fields[%i].in_value: 0x%s", i, char_buf);
-                               free(char_buf);
-                       #endif
+                       char_buf = buf_to_str(captured, (num_bits > 64) ? 64 : num_bits, 16);
+                       LOG_DEBUG("fields[%i].in_value: 0x%s", i, char_buf);
+                       free(char_buf);
+#endif
                        
                        if (cmd->fields[i].in_value)
                        {
@@ -1053,9 +1098,9 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
                                
                                if (cmd->fields[i].in_handler)
                                {
-                                       if (cmd->fields[i].in_handler(cmd->fields[i].in_value, cmd->fields[i].in_handler_priv) != ERROR_OK)
+                                       if (cmd->fields[i].in_handler(cmd->fields[i].in_value, cmd->fields[i].in_handler_priv, cmd->fields+i) != ERROR_OK)
                                        {
-                                               WARNING("in_handler reported a failed check");
+                                               LOG_WARNING("in_handler reported a failed check");
                                                retval = ERROR_JTAG_QUEUE_FAILED;
                                        }
                                }
@@ -1064,67 +1109,16 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
                        /* no in_value specified, but a handler takes care of the scanned data */
                        if (cmd->fields[i].in_handler && (!cmd->fields[i].in_value))
                        {
-                               if (cmd->fields[i].in_handler(captured, cmd->fields[i].in_handler_priv) != ERROR_OK)
+                               if (cmd->fields[i].in_handler(captured, cmd->fields[i].in_handler_priv, cmd->fields+i) != ERROR_OK)
                                {
                                        /* We're going to call the error:handler later, but if the in_handler
                                         * reported an error we report this failure upstream
                                         */
-                                       WARNING("in_handler reported a failed check");
+                                       LOG_WARNING("in_handler reported a failed check");
                                        retval = ERROR_JTAG_QUEUE_FAILED;
                                }
                        }
 
-                       if (cmd->fields[i].in_check_value)
-                       {
-                               int compare_failed = 0;
-                               
-                               if (cmd->fields[i].in_check_mask)
-                                       compare_failed = buf_cmp_mask(captured, cmd->fields[i].in_check_value, cmd->fields[i].in_check_mask, num_bits);
-                               else
-                                       compare_failed = buf_cmp(captured, cmd->fields[i].in_check_value, num_bits);
-                               
-                               if (compare_failed)
-                               {
-                                       char *captured_char = buf_to_str(captured, (num_bits > 64) ? 64 : num_bits, 16);
-                                       char *in_check_value_char = buf_to_str(cmd->fields[i].in_check_value, (num_bits > 64) ? 64 : num_bits, 16);
-
-                                       if (cmd->error_handler)
-                                       {
-                                               /* ask the error handler if once has been specified if this is a real problem */ 
-                                               if (cmd->error_handler->error_handler(captured, cmd->error_handler->error_handler_priv) != ERROR_OK)
-                                                       retval = ERROR_JTAG_QUEUE_FAILED;
-                                               else
-                                                       compare_failed = 0;
-                                       }
-                                       else
-                                       {
-                                               /* if there wasn't a handler specified, we report a failure */
-                                               retval = ERROR_JTAG_QUEUE_FAILED;
-                                       }
-                                       
-                                       /* An error handler could have caught the failing check
-                                        * only report a problem when there wasn't a handler, or if the handler
-                                        * acknowledged the error
-                                        */ 
-                                       if (compare_failed)
-                                       {
-                                               if (cmd->fields[i].in_check_mask)
-                                               {
-                                                       char *in_check_mask_char;
-                                                       in_check_mask_char = buf_to_str(cmd->fields[i].in_check_mask, (num_bits > 64) ? 64 : num_bits, 16);
-                                                       WARNING("value captured during scan didn't pass the requested check: captured: 0x%s check_value: 0x%s check_mask: 0x%s", captured_char, in_check_value_char, in_check_mask_char);
-                                                       free(in_check_mask_char);
-                                               }
-                                               else
-                                               {
-                                                       WARNING("value captured during scan didn't pass the requested check: captured: 0x%s check_value: 0x%s", captured_char, in_check_value_char);
-                                               }
-                                       }
-                                       
-                                       free(captured_char);
-                                       free(in_check_value_char);
-                               }
-                       }
                        free(captured);
                }
                bit_count += cmd->fields[i].num_bits;
@@ -1133,14 +1127,74 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
        return retval;
 }
 
+int jtag_check_value(u8 *captured, void *priv, scan_field_t *field)
+{
+       int retval = ERROR_OK;
+       int num_bits = field->num_bits;
+       
+       int compare_failed = 0;
+       
+       if (field->in_check_mask)
+               compare_failed = buf_cmp_mask(captured, field->in_check_value, field->in_check_mask, num_bits);
+       else
+               compare_failed = buf_cmp(captured, field->in_check_value, num_bits);
+       
+       if (compare_failed)
+               {
+               /* An error handler could have caught the failing check
+                * only report a problem when there wasn't a handler, or if the handler
+                * acknowledged the error
+                */ 
+               if (compare_failed)
+               {
+                       char *captured_char = buf_to_str(captured, (num_bits > 64) ? 64 : num_bits, 16);
+                       char *in_check_value_char = buf_to_str(field->in_check_value, (num_bits > 64) ? 64 : num_bits, 16);
+
+                       if (field->in_check_mask)
+                       {
+                               char *in_check_mask_char;
+                               in_check_mask_char = buf_to_str(field->in_check_mask, (num_bits > 64) ? 64 : num_bits, 16);
+                               LOG_WARNING("value captured during scan didn't pass the requested check: captured: 0x%s check_value: 0x%s check_mask: 0x%s", captured_char, in_check_value_char, in_check_mask_char);
+                               free(in_check_mask_char);
+                       }
+                       else
+                       {
+                               LOG_WARNING("value captured during scan didn't pass the requested check: captured: 0x%s check_value: 0x%s", captured_char, in_check_value_char);
+                       }
+
+                       free(captured_char);
+                       free(in_check_value_char);
+                       
+                       retval = ERROR_JTAG_QUEUE_FAILED;
+               }
+               
+       }
+       return retval;
+}
+
+/* 
+  set up checking of this field using the in_handler. The values passed in must be valid until
+  after jtag_execute() has completed.
+ */
+void jtag_set_check_value(scan_field_t *field, u8 *value, u8 *mask, error_handler_t *in_error_handler)
+{
+       if (value)
+               field->in_handler = jtag_check_value;
+       else
+               field->in_handler = NULL;       /* No check, e.g. embeddedice uses value==NULL to indicate no check */
+       field->in_handler_priv = NULL;  /* this will be filled in at the invocation site to point to the field duplicate */ 
+       field->in_check_value = value;
+       field->in_check_mask = mask;
+}
+
 enum scan_type jtag_scan_type(scan_command_t *cmd)
 {
        int i;
        int type = 0;
        
-       for (i=0; i < cmd->num_fields; i++)
+       for (i = 0; i < cmd->num_fields; i++)
        {
-               if (cmd->fields[i].in_check_value || cmd->fields[i].in_value || cmd->fields[i].in_handler)
+               if (cmd->fields[i].in_value || cmd->fields[i].in_handler)
                        type |= SCAN_IN;
                if (cmd->fields[i].out_value)
                        type |= SCAN_OUT;
@@ -1149,7 +1203,7 @@ enum scan_type jtag_scan_type(scan_command_t *cmd)
        return type;
 }
 
-int jtag_execute_queue(void)
+int MINIDRIVER(interface_jtag_execute_queue)(void)
 {
        int retval;
 
@@ -1163,20 +1217,22 @@ int jtag_execute_queue(void)
        return retval;
 }
 
-int jtag_cancel_queue(void)
+int jtag_execute_queue(void)
 {
-       cmd_queue_free();
-       jtag_command_queue = NULL;
-       last_comand_pointer = &jtag_command_queue;
-
-       return ERROR_OK;
+       int retval=interface_jtag_execute_queue();
+       if (retval==ERROR_OK)
+       {
+               retval=jtag_error;
+       }
+       jtag_error=ERROR_OK;
+       return retval;
 }
 
 int jtag_reset_callback(enum jtag_event event, void *priv)
 {
        jtag_device_t *device = priv;
 
-       DEBUG("-");
+       LOG_DEBUG("-");
        
        if (event == JTAG_TRST_ASSERTED)
        {
@@ -1217,10 +1273,10 @@ int jtag_examine_chain()
        
        for (i = 0; i < JTAG_MAX_CHAIN_SIZE; i++)
        {
-               buf_set_u32(idcode_buffer, 0, 32, 0x000000FF);
+               buf_set_u32(idcode_buffer, i * 32, 32, 0x000000FF);
        }
        
-       jtag_add_plain_dr_scan(1, &field, TAP_TLR, NULL);
+       jtag_add_plain_dr_scan(1, &field, TAP_TLR);
        jtag_execute_queue();
        
        for (i = 0; i < JTAG_MAX_CHAIN_SIZE * 4; i++)
@@ -1232,8 +1288,8 @@ int jtag_examine_chain()
        /* if there wasn't a single non-zero bit or if all bits were one, the scan isn't valid */
        if ((zero_check == 0x00) || (one_check == 0xff))
        {
-               ERROR("JTAG communication failure, check connection, JTAG interface, target power etc.");
-               exit(-1);
+               LOG_ERROR("JTAG communication failure, check connection, JTAG interface, target power etc.");
+               return ERROR_JTAG_INIT_FAILED;
        }
        
        for (bit_count = 0; bit_count < (JTAG_MAX_CHAIN_SIZE * 32) - 31;)
@@ -1269,7 +1325,7 @@ int jtag_examine_chain()
                        part = (idcode & 0xffff000) >> 12;
                        version = (idcode & 0xf0000000) >> 28;
 
-                       DEBUG("JTAG device found: 0x%8.8x (Manufacturer: 0x%3.3x, Part: 0x%4.4x, Version: 0x%1.1x", 
+                       LOG_INFO("JTAG device found: 0x%8.8x (Manufacturer: 0x%3.3x, Part: 0x%4.4x, Version: 0x%1.1x)", 
                                idcode, manufacturer, part, version);
                        
                        bit_count += 32;
@@ -1279,9 +1335,10 @@ int jtag_examine_chain()
        /* see if number of discovered devices matches configuration */
        if (device_count != jtag_num_devices)
        {
-               ERROR("number of discovered devices in JTAG chain (%i) doesn't match configuration (%i)", 
-                       device_count, jtag_num_devices);
-               exit(-1);
+               LOG_ERROR("number of discovered devices in JTAG chain (%i) doesn't match configuration (%i)", 
+                               device_count, jtag_num_devices);
+               LOG_ERROR("check the config file and ensure proper JTAG communication (connections, speed, ...)");
+               return ERROR_JTAG_INIT_FAILED;
        }
        
        return ERROR_OK;
@@ -1315,7 +1372,7 @@ int jtag_validate_chain()
        field.in_handler = NULL;
        field.in_handler_priv = NULL;
        
-       jtag_add_plain_ir_scan(1, &field, TAP_TLR, NULL);
+       jtag_add_plain_ir_scan(1, &field, TAP_TLR);
        jtag_execute_queue();
        
        device = jtag_devices;
@@ -1324,9 +1381,10 @@ int jtag_validate_chain()
                if (buf_get_u32(ir_test, chain_pos, 2) != 0x1)
                {
                        char *cbuf = buf_to_str(ir_test, total_ir_length, 16);
-                       ERROR("Error validating JTAG scan chain, IR mismatch, scan returned 0x%s", cbuf);
+                       LOG_ERROR("Error validating JTAG scan chain, IR mismatch, scan returned 0x%s", cbuf);
                        free(cbuf);
-                       exit(-1);
+                       free(ir_test);
+                       return ERROR_JTAG_INIT_FAILED;
                }
                chain_pos += device->ir_length;
                device = device->next;
@@ -1335,9 +1393,10 @@ int jtag_validate_chain()
        if (buf_get_u32(ir_test, chain_pos, 2) != 0x3)
        {
                char *cbuf = buf_to_str(ir_test, total_ir_length, 16);
-               ERROR("Error validating JTAG scan chain, IR mismatch, scan returned 0x%s", cbuf);
+               LOG_ERROR("Error validating JTAG scan chain, IR mismatch, scan returned 0x%s", cbuf);
                free(cbuf);
-               exit(-1);
+               free(ir_test);
+               return ERROR_JTAG_INIT_FAILED;
        }
        
        free(ir_test);
@@ -1350,9 +1409,11 @@ int jtag_register_commands(struct command_context_s *cmd_ctx)
        register_command(cmd_ctx, NULL, "interface", handle_interface_command,
                COMMAND_CONFIG, NULL);
        register_command(cmd_ctx, NULL, "jtag_speed", handle_jtag_speed_command,
-               COMMAND_ANY, "set jtag speed (if supported) <speed>");
+               COMMAND_ANY, "set jtag speed (if supported) <reset speed> [<post reset speed, default value is reset speed>]");
+       register_command(cmd_ctx, NULL, "jtag_khz", handle_jtag_khz_command,
+               COMMAND_ANY, "same as jtag_speed, except it takes maximum khz as arguments. 0 KHz = RTCK.");
        register_command(cmd_ctx, NULL, "jtag_device", handle_jtag_device_command,
-               COMMAND_CONFIG, NULL);
+               COMMAND_CONFIG, "jtag_device <ir_length> <ir_expected> <ir_mask>");
        register_command(cmd_ctx, NULL, "reset_config", handle_reset_config_command,
                COMMAND_CONFIG, NULL);
        register_command(cmd_ctx, NULL, "jtag_nsrst_delay", handle_jtag_nsrst_delay_command,
@@ -1381,91 +1442,117 @@ int jtag_register_commands(struct command_context_s *cmd_ctx)
        return ERROR_OK;
 }
 
+int jtag_interface_init(struct command_context_s *cmd_ctx)
+{
+       if (!jtag_interface)
+       {
+               /* nothing was previously specified by "interface" command */
+               LOG_ERROR("JTAG interface has to be specified, see \"interface\" command");
+               return ERROR_JTAG_INVALID_INTERFACE;
+       }
+
+       if (jtag_interface->init() != ERROR_OK)
+               return ERROR_JTAG_INIT_FAILED;
+
+       jtag = jtag_interface;
+       return ERROR_OK;
+}
+
 int jtag_init(struct command_context_s *cmd_ctx)
 {
-       int i;
-       
-       DEBUG("-");
+       int validate_tries = 0;
+       jtag_device_t *device;
 
-       if (jtag_speed == -1)
-               jtag_speed = 0;
+       LOG_DEBUG("-");
        
-       if (jtag_interface && (jtag_interface[0] != 0))
-               /* configuration var 'jtag_interface' is set, and not empty */
-               for (i = 0; jtag_interfaces[i]; i++)
-               {
-                       if (strcmp(jtag_interface, jtag_interfaces[i]->name) == 0)
-                       {
-                               jtag_device_t *device;
-                               device = jtag_devices;
-       
-                               if (jtag_interfaces[i]->init() != ERROR_OK)
-                                       return ERROR_JTAG_INIT_FAILED;
-                               jtag = jtag_interfaces[i];
+       if (!jtag && jtag_interface_init(cmd_ctx) != ERROR_OK)
+               return ERROR_JTAG_INIT_FAILED;
 
-                               jtag_ir_scan_size = 0;
-                               jtag_num_devices = 0;
-                               while (device != NULL)
-                               {
-                                       jtag_ir_scan_size += device->ir_length;
-                                       jtag_num_devices++;
-                                       device = device->next;
-                               }
-                               
-                               jtag_add_statemove(TAP_TLR);
-                               jtag_execute_queue();
-                               
-                               jtag_examine_chain();
-                               
-                               jtag_validate_chain();
-                               
-                               return ERROR_OK;
-                       }
-               }
+       device = jtag_devices;
+       jtag_ir_scan_size = 0;
+       jtag_num_devices = 0;
+       while (device != NULL)
+       {
+               jtag_ir_scan_size += device->ir_length;
+               jtag_num_devices++;
+               device = device->next;
+       }
        
-       /* no valid interface was found (i.e. the configuration option,
-        * didn't match one of the compiled-in interfaces
-        */
-       ERROR("No valid jtag interface found (%s)", jtag_interface);
-       ERROR("compiled-in jtag interfaces:");
-       for (i = 0; jtag_interfaces[i]; i++)
+       jtag_add_statemove(TAP_TLR);
+       jtag_execute_queue();
+
+       /* examine chain first, as this could discover the real chain layout */
+       if (jtag_examine_chain() != ERROR_OK)
        {
-               ERROR("%i: %s", i, jtag_interfaces[i]->name);
+               LOG_ERROR("trying to validate configured JTAG chain anyway...");
        }
        
-       jtag = NULL;
-       return ERROR_JTAG_INVALID_INTERFACE;
+       while (jtag_validate_chain() != ERROR_OK)
+       {
+               validate_tries++;
+               if (validate_tries > 5)
+               {
+                       LOG_ERROR("Could not validate JTAG chain, exit");
+                       return ERROR_JTAG_INVALID_INTERFACE;
+               }
+               usleep(10000);
+       }
+
+       return ERROR_OK;
+}
+
+
+static int default_khz(int khz, int *jtag_speed)
+{
+       LOG_ERROR("Translation from khz to jtag_speed not implemented");
+       return ERROR_FAIL;
 }
 
 int handle_interface_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
        int i;
-       
-       /* only if the configuration var isn't overwritten from cmdline */
-       if (!jtag_interface)
+
+       /* check whether the interface is already configured */
+       if (jtag_interface)
+       {
+               LOG_WARNING("Interface already configured, ignoring");
+               return ERROR_OK;
+       }
+
+       /* interface name is a mandatory argument */
+       if (argc < 1 || args[0][0] == '\0')
        {
-               if (args[0] && (args[0][0] != 0))
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       for (i=0; jtag_interfaces[i]; i++)
+       {
+               if (strcmp(args[0], jtag_interfaces[i]->name) == 0)
                {
-                       for (i=0; jtag_interfaces[i]; i++)
+                       if (jtag_interfaces[i]->register_commands(cmd_ctx) != ERROR_OK)
+                               exit(-1);
+
+                       jtag_interface = jtag_interfaces[i];
+                       
+                       if (jtag_interface->khz == NULL)
                        {
-                               if (strcmp(args[0], jtag_interfaces[i]->name) == 0)
-                               {
-                                       if (jtag_interfaces[i]->register_commands(cmd_ctx) != ERROR_OK)
-                                               exit(-1);
-                               
-                                       jtag_interface = jtag_interfaces[i]->name;
-               
-                                       return ERROR_OK;
-                               }
+                               jtag_interface->khz = default_khz;
                        }
+                       return ERROR_OK;
                }
-               
-               /* remember the requested interface name, so we can complain about it later */
-               jtag_interface = strdup(args[0]);
-               DEBUG("'interface' command didn't specify a valid interface");
        }
-       
-       return ERROR_OK;
+
+       /* no valid interface was found (i.e. the configuration option,
+        * didn't match one of the compiled-in interfaces
+        */
+       LOG_ERROR("No valid jtag interface found (%s)", args[0]);
+       LOG_ERROR("compiled-in jtag interfaces:");
+       for (i = 0; jtag_interfaces[i]; i++)
+       {
+               LOG_ERROR("%i: %s", i, jtag_interfaces[i]->name);
+       }
+
+       return ERROR_JTAG_INVALID_INTERFACE;
 }
 
 int handle_jtag_device_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
@@ -1499,7 +1586,7 @@ int handle_jtag_device_command(struct command_context_s *cmd_ctx, char *cmd, cha
        jtag_register_event_callback(jtag_reset_callback, (*last_device_p));
        
        jtag_num_devices++;
-
+       
        return ERROR_OK;
 }
 
@@ -1536,8 +1623,9 @@ int handle_reset_config_command(struct command_context_s *cmd_ctx, char *cmd, ch
                        jtag_reset_config = RESET_TRST_AND_SRST;
                else
                {
-                       ERROR("invalid reset_config argument");
-                       exit(-1);
+                       LOG_ERROR("invalid reset_config argument, defaulting to none");
+                       jtag_reset_config = RESET_NONE;
+                       return ERROR_INVALID_ARGUMENTS;
                }
        }
        
@@ -1553,8 +1641,9 @@ int handle_reset_config_command(struct command_context_s *cmd_ctx, char *cmd, ch
                        jtag_reset_config &= ~(RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST);
                else
                {
-                       ERROR("invalid reset_config argument");
-                       exit(-1);
+                       LOG_ERROR("invalid reset_config argument, defaulting to none");
+                       jtag_reset_config = RESET_NONE;
+                       return ERROR_INVALID_ARGUMENTS;
                }
        }
        
@@ -1566,8 +1655,9 @@ int handle_reset_config_command(struct command_context_s *cmd_ctx, char *cmd, ch
                        jtag_reset_config &= ~RESET_TRST_OPEN_DRAIN;
                else
                {
-                       ERROR("invalid reset_config argument");
-                       exit(-1);
+                       LOG_ERROR("invalid reset_config argument, defaulting to none");
+                       jtag_reset_config = RESET_NONE;
+                       return ERROR_INVALID_ARGUMENTS;
                }
        }
 
@@ -1579,8 +1669,9 @@ int handle_reset_config_command(struct command_context_s *cmd_ctx, char *cmd, ch
                        jtag_reset_config &= ~RESET_SRST_PUSH_PULL;
                else
                {
-                       ERROR("invalid reset_config argument");
-                       exit(-1);
+                       LOG_ERROR("invalid reset_config argument, defaulting to none");
+                       jtag_reset_config = RESET_NONE;
+                       return ERROR_INVALID_ARGUMENTS;
                }
        }
        
@@ -1591,7 +1682,7 @@ int handle_jtag_nsrst_delay_command(struct command_context_s *cmd_ctx, char *cmd
 {
        if (argc < 1)
        {
-               ERROR("jtag_nsrst_delay <ms> command takes one required argument");
+               LOG_ERROR("jtag_nsrst_delay <ms> command takes one required argument");
                exit(-1);
        }
        else
@@ -1606,7 +1697,7 @@ int handle_jtag_ntrst_delay_command(struct command_context_s *cmd_ctx, char *cmd
 {
        if (argc < 1)
        {
-               ERROR("jtag_ntrst_delay <ms> command takes one required argument");
+               LOG_ERROR("jtag_ntrst_delay <ms> command takes one required argument");
                exit(-1);
        }
        else
@@ -1619,29 +1710,66 @@ int handle_jtag_ntrst_delay_command(struct command_context_s *cmd_ctx, char *cmd
 
 int handle_jtag_speed_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
-       if (argc == 0)
-               command_print(cmd_ctx, "jtag_speed: %i", jtag_speed);
+       int cur_speed = 0;
+       if ((argc<1) || (argc>2))
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       if (argc >= 1)
+               cur_speed = jtag_speed = jtag_speed_post_reset = strtoul(args[0], NULL, 0);
+       if (argc == 2)
+               cur_speed = jtag_speed_post_reset = strtoul(args[1], NULL, 0);
+               
+       /* this command can be called during CONFIG, 
+        * in which case jtag isn't initialized */
+       if (jtag)
+               jtag->speed(cur_speed);
+
+       return ERROR_OK;
+}
+
+int handle_jtag_khz_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       int cur_speed = 0;
+       int speed1, speed2;
+       if ((argc<1) || (argc>2))
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
-       if (argc > 0)
+       if (jtag == NULL)
        {
-               /* this command can be called during CONFIG, 
-                * in which case jtag isn't initialized */
-               if (jtag)
-                       jtag->speed(strtoul(args[0], NULL, 0));
-               else
-                       jtag_speed = strtoul(args[0], NULL, 0);
+               LOG_ERROR("Interface not selected yet");
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
+       
+       if (argc >= 1)
+               speed1 = strtoul(args[0], NULL, 0);
+       if (argc == 2)
+               speed2 = strtoul(args[1], NULL, 0);
+       
+       if (jtag->khz(speed1, &speed1)!=ERROR_OK)
+               return ERROR_OK;
+       
+       if (jtag->khz(speed2, &speed2)!=ERROR_OK)
+               return ERROR_OK;
+       
+       if (argc >= 1)
+               cur_speed = jtag_speed = jtag_speed_post_reset = speed1;
+       
+       if (argc == 2)
+               cur_speed = jtag_speed_post_reset = speed2;
+               
+       jtag->speed(cur_speed);
 
        return ERROR_OK;
 }
 
+
 int handle_endstate_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
        enum tap_state state;
 
        if (argc < 1)
        {
-               command_print(cmd_ctx, "usage: endstate <tap_state>");
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
        else
        {
@@ -1663,13 +1791,10 @@ int handle_jtag_reset_command(struct command_context_s *cmd_ctx, char *cmd, char
 {
        int trst = -1;
        int srst = -1;
-       char *usage = "usage: jtag_reset <trst> <srst>";
-       int retval;
        
-       if (argc < 1)
+       if (argc < 2)
        {
-               command_print(cmd_ctx, usage);
-               return ERROR_OK;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        if (args[0][0] == '1')
@@ -1678,8 +1803,7 @@ int handle_jtag_reset_command(struct command_context_s *cmd_ctx, char *cmd, char
                trst = 0;
        else
        {
-               command_print(cmd_ctx, usage);
-               return ERROR_OK;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        if (args[1][0] == '1')
@@ -1688,24 +1812,13 @@ int handle_jtag_reset_command(struct command_context_s *cmd_ctx, char *cmd, char
                srst = 0;
        else
        {
-               command_print(cmd_ctx, usage);
-               return ERROR_OK;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
-       if ((retval = jtag_add_reset(trst, srst)) != ERROR_OK)
-       {
-               switch (retval)
-               {
-                       case ERROR_JTAG_RESET_WOULD_ASSERT_TRST:
-                               command_print(cmd_ctx, "requested reset would assert trst\nif this is acceptable, use jtag_reset 1 %c", args[1][0]);
-                               break;
-                       case ERROR_JTAG_RESET_CANT_SRST:
-                               command_print(cmd_ctx, "can't assert srst because the current reset_config doesn't support it");
-                               break;
-                       default:
-                               command_print(cmd_ctx, "unknown error");
-               }
-       }
+       if (!jtag && jtag_interface_init(cmd_ctx) != ERROR_OK)
+               return ERROR_JTAG_INIT_FAILED;
+
+       jtag_add_reset(trst, srst);
        jtag_execute_queue();
 
        return ERROR_OK;
@@ -1715,8 +1828,7 @@ int handle_runtest_command(struct command_context_s *cmd_ctx, char *cmd, char **
 {
        if (argc < 1)
        {
-               command_print(cmd_ctx, "usage: runtest <num_cycles>");
-               return ERROR_OK;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        jtag_add_runtest(strtol(args[0], NULL, 0), -1);
@@ -1756,8 +1868,7 @@ int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, char **a
        
        if ((argc < 2) || (argc % 2))
        {
-               command_print(cmd_ctx, "usage: irscan <device> <instr> [dev2] [instr2] ...");
-               return ERROR_OK;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        fields = malloc(sizeof(scan_field_t) * argc / 2);
@@ -1776,7 +1887,7 @@ int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, char **a
                fields[i].in_handler_priv = NULL;
        }
 
-       jtag_add_ir_scan(argc / 2, fields, -1, NULL);
+       jtag_add_ir_scan(argc / 2, fields, -1);
        jtag_execute_queue();
 
        for (i = 0; i < argc / 2; i++)
@@ -1797,8 +1908,7 @@ int handle_drscan_command(struct command_context_s *cmd_ctx, char *cmd, char **a
        
        if ((argc < 2) || (argc % 2))
        {
-               command_print(cmd_ctx, "usage: drscan <device> <var> [dev2] [var2]");
-               return ERROR_OK;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        for (i = 0; i < argc; i+=2)
@@ -1836,7 +1946,7 @@ int handle_drscan_command(struct command_context_s *cmd_ctx, char *cmd, char **a
                }
        }
 
-       jtag_add_dr_scan(num_fields, fields, -1, NULL);
+       jtag_add_dr_scan(num_fields, fields, -1);
        jtag_execute_queue();
        
        for (i = 0; i < argc / 2; i++)
@@ -1849,20 +1959,25 @@ int handle_drscan_command(struct command_context_s *cmd_ctx, char *cmd, char **a
 
 int handle_verify_ircapture_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
-       if (argc == 0)
-       {
-               command_print(cmd_ctx, "verify Capture-IR is %s", (jtag_verify_capture_ir) ? "enabled": "disabled");
-               return ERROR_OK;
-       }
-       
-       if (strcmp(args[0], "enable") == 0)
+       if (argc == 1)
        {
-               jtag_verify_capture_ir = 1;
-       }
-       else if (strcmp(args[0], "disable") == 0)
+               if (strcmp(args[0], "enable") == 0)
+               {
+                       jtag_verify_capture_ir = 1;
+               }
+               else if (strcmp(args[0], "disable") == 0)
+               {
+                       jtag_verify_capture_ir = 0;
+               } else
+               {
+                       return ERROR_COMMAND_SYNTAX_ERROR;
+               }
+       } else if (argc != 0)
        {
-               jtag_verify_capture_ir = 0;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
        
+       command_print(cmd_ctx, "verify Capture-IR is %s", (jtag_verify_capture_ir) ? "enabled": "disabled");
+       
        return ERROR_OK;
 }