- adds two speeds to jtag_speed. reset and post reset speed. Default
[fw/openocd] / src / jtag / jtag.c
index 48cd0595646eafdebcb545da92105388f7079464..c2db331d267203e929d4fbf3da4533cd31365922 100644 (file)
 #include "command.h"
 #include "log.h"
 #include "interpreter.h"
-#include "target.h"
 
 #include "stdlib.h"
 #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 
 */
@@ -108,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;
@@ -143,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
@@ -180,6 +180,9 @@ jtag_event_callback_t *jtag_event_callbacks;
 #endif
 
 jtag_interface_t *jtag_interfaces[] = {
+#if BUILD_ECOSBOARD == 1
+       &eCosBoard_interface,
+#endif
 #if BUILD_PARPORT == 1
        &parport_interface,
 #endif
@@ -215,15 +218,16 @@ jtag_interface_t *jtag = NULL;
 /* configuration */
 jtag_interface_t *jtag_interface = NULL;
 int jtag_speed = 0;
+int jtag_speed_post_reset = 0;
 
 
 /* forward declarations */
-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);
 
@@ -388,30 +392,36 @@ void cmd_queue_free()
        cmd_queue_pages = NULL;
 }
 
-int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state)
+static void jtag_prelude1()
 {
        if (jtag_trst == 1)
        {
                WARNING("JTAG command queued, while TRST is low (TAP in reset)");
                jtag_error=ERROR_JTAG_TRST_ASSERTED;
-               return ERROR_JTAG_TRST_ASSERTED;
+               return;
        }
 
-       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);
+}
+
+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;
-       return retval;
 }
 
 int MINIDRIVER(interface_jtag_add_ir_scan)(int num_fields, scan_field_t *fields, enum tap_state state)
@@ -481,7 +491,7 @@ int MINIDRIVER(interface_jtag_add_ir_scan)(int num_fields, scan_field_t *fields,
                        (*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 */
@@ -491,26 +501,13 @@ int MINIDRIVER(interface_jtag_add_ir_scan)(int num_fields, scan_field_t *fields,
        return ERROR_OK;
 }
 
-int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state)
+void jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state)
 {
-       if (jtag_trst == 1)
-       {
-               WARNING("JTAG command queued, while TRST is low (TAP in reset)");
-               return jtag_error=ERROR_JTAG_TRST_ASSERTED;
-       }
-
-       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;
+       jtag_prelude(state);
        
-       return interface_jtag_add_plain_ir_scan(num_fields, fields, cmd_queue_end_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)
@@ -550,26 +547,13 @@ int MINIDRIVER(interface_jtag_add_plain_ir_scan)(int num_fields, scan_field_t *f
        return ERROR_OK;
 }
 
-int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state)
+void jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state)
 {
-       if (jtag_trst == 1)
-       {
-               WARNING("JTAG command queued, while TRST is low (TAP in reset)");
-               return jtag_error=ERROR_JTAG_TRST_ASSERTED;
-       }
+       jtag_prelude(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 interface_jtag_add_dr_scan(num_fields, fields, cmd_queue_end_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)
@@ -692,11 +676,11 @@ void MINIDRIVER(interface_jtag_add_dr_out)(int device_num,
        (*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++)
        {
                (*last_cmd)->cmd.scan->fields[field_count].device = i;
-
+       
                if (i == device_num)
                {
                        int j;
@@ -748,26 +732,13 @@ void MINIDRIVER(interface_jtag_add_dr_out)(int device_num,
 
 
 
-int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state)
+void jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state)
 {
-       if (jtag_trst == 1)
-       {
-               WARNING("JTAG command queued, while TRST is low (TAP in reset)");
-               return jtag_error=ERROR_JTAG_TRST_ASSERTED;
-       }
+       jtag_prelude(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 interface_jtag_add_plain_dr_scan(num_fields, fields, cmd_queue_end_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)
@@ -805,26 +776,14 @@ int MINIDRIVER(interface_jtag_add_plain_dr_scan)(int num_fields, scan_field_t *f
 
        return ERROR_OK;
 }
-int jtag_add_statemove(enum tap_state state)
+void jtag_add_statemove(enum tap_state state)
 {
-       if (jtag_trst == 1)
-       {
-               WARNING("JTAG command queued, while TRST is low (TAP in reset)");
-               return jtag_error=ERROR_JTAG_TRST_ASSERTED;
-       }
-
-       if (state != -1)
-               cmd_queue_end_state = state;
+       jtag_prelude(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 interface_jtag_add_statemove(cmd_queue_end_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)
@@ -844,27 +803,14 @@ int MINIDRIVER(interface_jtag_add_statemove)(enum tap_state 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)
 {
-       if (jtag_trst == 1)
-       {
-               WARNING("JTAG command queued, while TRST is low (TAP in reset)");
-               return jtag_error=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 jtag_error=ERROR_JTAG_NOT_IMPLEMENTED;
+               ERROR("BUG: TAP path doesn't finish in a stable state");
+               exit(-1);
        }
-       
-       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);
-       
 
        enum tap_state cur_state=cmd_queue_cur_state;
        int i;
@@ -879,9 +825,13 @@ int jtag_add_pathmove(int num_states, enum tap_state *path)
                cur_state = path[i];
        }
        
+       jtag_prelude1();
+       
        cmd_queue_cur_state = path[num_states - 1];
 
-       return interface_jtag_add_pathmove(num_states, path);
+       int retval=interface_jtag_add_pathmove(num_states, path);
+       if (retval!=ERROR_OK)
+               jtag_error=retval;
 }
 
 
@@ -923,28 +873,14 @@ int MINIDRIVER(interface_jtag_add_runtest)(int num_cycles, enum tap_state state)
        return ERROR_OK;
 }
 
-int jtag_add_runtest(int num_cycles, enum tap_state state)
+void jtag_add_runtest(int num_cycles, enum tap_state state)
 {
-       if (jtag_trst == 1)
-       {
-               jtag_error=ERROR_JTAG_QUEUE_FAILED;
-               WARNING("JTAG command queued, while TRST is low (TAP in reset)");
-               return ERROR_JTAG_TRST_ASSERTED;
-       }
-       
-       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;
+       jtag_prelude(state);
        
        /* executed by sw or hw fifo */
-       return interface_jtag_add_runtest(num_cycles, cmd_queue_end_state);
+       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)
@@ -962,7 +898,8 @@ int jtag_add_reset(int req_trst, int req_srst)
        /* 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))
        {
-               return jtag_error=ERROR_JTAG_RESET_WOULD_ASSERT_TRST;
+               ERROR("requested reset would assert trst");
+               return ERROR_JTAG_RESET_WOULD_ASSERT_TRST;
        }
                
        /* if TRST pulls SRST, we reset with TAP T-L-R */
@@ -975,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");
-               return jtag_error=ERROR_JTAG_RESET_CANT_SRST;
+               return ERROR_JTAG_RESET_CANT_SRST;
        }
        
        if (req_trst && !(jtag_reset_config & RESET_HAS_TRST))
@@ -996,21 +933,21 @@ int jtag_add_reset(int req_trst, int req_srst)
 
        if (jtag_srst)
        {
-               jtag_call_event_callbacks(JTAG_SRST_ASSERTED);
+               DEBUG("SRST line asserted");
        }
        else
        {
-               jtag_call_event_callbacks(JTAG_SRST_RELEASED);
+               DEBUG("SRST line released");
                if (jtag_nsrst_delay)
                        jtag_add_sleep(jtag_nsrst_delay * 1000);
        }
        
        if (trst_with_tms)
        {
-               jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
+               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);
                return ERROR_OK;
        }
        
@@ -1019,6 +956,7 @@ int jtag_add_reset(int req_trst, int req_srst)
                /* we just asserted nTRST, so we're now in Test-Logic-Reset,
                 * and inform possible listeners about this
                 */
+               DEBUG("TRST line asserted");
                cmd_queue_cur_state = TAP_TLR;
                jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
        }
@@ -1027,12 +965,11 @@ int jtag_add_reset(int req_trst, int req_srst)
                /* 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
                 */
+               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 retval;
-       
+       return ERROR_OK;
 }
 
 int MINIDRIVER(interface_jtag_add_reset)(int req_trst, int req_srst)
@@ -1053,28 +990,9 @@ int MINIDRIVER(interface_jtag_add_reset)(int req_trst, int req_srst)
        return ERROR_OK;
 }
 
-int MINIDRIVER(interface_jtag_add_end_state)(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;
-       last_comand_pointer = &((*last_cmd)->next);
-       (*last_cmd)->type = JTAG_END_STATE;
-
-       (*last_cmd)->cmd.end_state = cmd_queue_alloc(sizeof(end_state_command_t));
-       (*last_cmd)->cmd.end_state->end_state = state;
-
-       return ERROR_OK;
-}
-
-int jtag_add_end_state(enum tap_state state)
+void jtag_add_end_state(enum tap_state state)
 {
-       if (state != -1)
-               cmd_queue_end_state = state;
-       int retval = interface_jtag_add_end_state(cmd_queue_end_state);
-       return retval;
+       cmd_queue_end_state = state;
 }
 
 int MINIDRIVER(interface_jtag_add_sleep)(u32 us)
@@ -1093,9 +1011,12 @@ int MINIDRIVER(interface_jtag_add_sleep)(u32 us)
        return ERROR_OK;
 }
 
-int jtag_add_sleep(u32 us)
+void jtag_add_sleep(u32 us)
 {
-       return interface_jtag_add_sleep(us); 
+       int retval=interface_jtag_add_sleep(us);
+       if (retval!=ERROR_OK)
+               jtag_error=retval;
+       return;
 }
 
 int jtag_scan_size(scan_command_t *cmd)
@@ -1300,7 +1221,7 @@ int jtag_execute_queue(void)
        int retval=interface_jtag_execute_queue();
        if (retval==ERROR_OK)
        {
-       retval=jtag_error;
+               retval=jtag_error;
        }
        jtag_error=ERROR_OK;
        return retval;
@@ -1328,10 +1249,11 @@ void jtag_sleep(u32 us)
 
 /* Try to examine chain layout according to IEEE 1149.1 ยง12
  */
-int jtag_examine_chain(u8 idcode_buffer[JTAG_MAX_CHAIN_SIZE * 4] )
+int jtag_examine_chain()
 {
        jtag_device_t *device = jtag_devices;
        scan_field_t field;
+       u8 idcode_buffer[JTAG_MAX_CHAIN_SIZE * 4];
        int i;
        int bit_count;
        int device_count = 0;
@@ -1413,7 +1335,7 @@ int jtag_examine_chain(u8 idcode_buffer[JTAG_MAX_CHAIN_SIZE * 4] )
        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);
+                               device_count, jtag_num_devices);
                ERROR("check the config file and ensure proper JTAG communication (connections, speed, ...)");
                return ERROR_JTAG_INIT_FAILED;
        }
@@ -1486,7 +1408,7 @@ 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_device", handle_jtag_device_command,
                COMMAND_CONFIG, "jtag_device <ir_length> <ir_expected> <ir_mask>");
        register_command(cmd_ctx, NULL, "reset_config", handle_reset_config_command,
@@ -1533,36 +1455,9 @@ int jtag_interface_init(struct command_context_s *cmd_ctx)
        return ERROR_OK;
 }
 
-extern int jtag_init_chain(struct command_context_s *cmd_ctx);
-
-static int jtag_sense_handler(void *priv)
-{
-       struct command_context_s *cmd_ctx;
-       cmd_ctx=(struct command_context_s *)priv;
-
-       static int scan_complete = 0;
-       if (!scan_complete)
-       {
-               if (jtag_init_chain(cmd_ctx)==ERROR_OK)
-               {
-                       scan_complete = 1;
-               }
-               return ERROR_OK;
-       }
-       
-       return ERROR_OK;
-}
-
-/* OpenOCD will start telnet/gdb servers before the JTAG chain has
- * been enumerated. This is to allow e.g. GDB init script to
- * run monitor commands to initialize the target so jtag_init_chain()
- * will succeed.
- * 
- * A timer callback is added where sensing is retried once every second
- * until it succeeds.
- */
 int jtag_init(struct command_context_s *cmd_ctx)
 {
+       int validate_tries = 0;
        jtag_device_t *device;
 
        DEBUG("-");
@@ -1583,78 +1478,27 @@ int jtag_init(struct command_context_s *cmd_ctx)
        jtag_add_statemove(TAP_TLR);
        jtag_execute_queue();
 
-       target_register_timer_callback(jtag_sense_handler, 1000, 1, cmd_ctx);
-       
-       return ERROR_OK;
-       }
-       
-static int jtag_test_chain(u8 idcode_buffer[JTAG_MAX_CHAIN_SIZE * 4])
-{
-       jtag_add_statemove(TAP_TLR);
-       jtag_execute_queue();
-
        /* examine chain first, as this could discover the real chain layout */
-       if (jtag_examine_chain(idcode_buffer)!=ERROR_OK)
+       if (jtag_examine_chain() != ERROR_OK)
        {
-               WARNING("trying to validate configured JTAG chain anyway...");
+               ERROR("trying to validate configured JTAG chain anyway...");
        }
        
-       return jtag_validate_chain();
-}
-
-/* Unless we can do this successfully 10 times, we're not
- * satisfied with the quality of the JTAG communication.
- * 
- * Since we're continously repeating this operation, be a bit
- * wary of filling the log with megabytes of data.
- * 
- * Keep increasing the jtag_divisor until we've got a solid
- * result.
- */
-int jtag_init_chain(struct command_context_s *cmd_ctx)
-{
-       int i, j;
-       int retval;
-       for (i=jtag_speed; i<64; i++)
-               {
-               u8 idcode_buffer[JTAG_MAX_CHAIN_SIZE * 4];
-               jtag_speed=i;
-               if ((retval=jtag->speed(jtag_speed))!=ERROR_OK)
-                       continue;
-               for (j=0; j<10; j++)
-               {
-                       u8 idcode_current[JTAG_MAX_CHAIN_SIZE * 4];
-                       enum log_levels save_log_level=debug_level;
-                       /* avoid spamming log */
-                       debug_level=LOG_SILENT;
-                       retval=jtag_test_chain(idcode_current);
-                       if (retval==ERROR_OK)
-                       {
-                               if (j==0)
-                               {
-                                       memcpy(idcode_buffer, idcode_current, sizeof(idcode_buffer));
-                               } else
-                               {
-                                       retval=(memcmp(idcode_buffer, idcode_current, sizeof(idcode_buffer))==0)?ERROR_OK:ERROR_JTAG_INIT_FAILED;
-                               }
-                       }
-                       debug_level = save_log_level;
-                       if (retval!=ERROR_OK)
-                       {
-                               break;
-                       }
-               }
-               if (retval==ERROR_OK)
+       while (jtag_validate_chain() != ERROR_OK)
+       {
+               validate_tries++;
+               if (validate_tries > 5)
                {
-                       /* Print out result  */
-                       INFO("Succeeded jtag chain test jtag_speed=%d", jtag_speed);
-                       return jtag_test_chain(idcode_buffer);
+                       ERROR("Could not validate JTAG chain, exit");
+                       return ERROR_JTAG_INVALID_INTERFACE;
                }
-               DEBUG("Failed jtag chain test, dropping clock rate. Trying jtag_speed=%d\n", i+1);
+               usleep(10000);
        }
-       return retval;
+
+       return ERROR_OK;
 }
 
+
 int handle_interface_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
        int i;
@@ -1728,7 +1572,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;
 }
 
@@ -1852,17 +1696,19 @@ 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 > 0)
-       {
-               jtag_speed = strtoul(args[0], NULL, 0);
-               /* this command can be called during CONFIG, 
-                * in which case jtag isn't initialized */
-               if (jtag)
-                       jtag->speed(jtag_speed);
-       }
+       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;
 }
@@ -1895,12 +1741,10 @@ int handle_jtag_reset_command(struct command_context_s *cmd_ctx, char *cmd, char
 {
        int trst = -1;
        int srst = -1;
-       int retval;
        
        if (argc < 2)
        {
                return ERROR_COMMAND_SYNTAX_ERROR;
-
        }
 
        if (args[0][0] == '1')
@@ -1924,20 +1768,7 @@ int handle_jtag_reset_command(struct command_context_s *cmd_ctx, char *cmd, char
        if (!jtag && jtag_interface_init(cmd_ctx) != ERROR_OK)
                return ERROR_JTAG_INIT_FAILED;
 
-       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");
-               }
-       }
+       jtag_add_reset(trst, srst);
        jtag_execute_queue();
 
        return ERROR_OK;
@@ -2072,7 +1903,7 @@ int handle_drscan_command(struct command_context_s *cmd_ctx, char *cmd, char **a
                free(fields[i].out_value);
 
        free(fields);
-       
+
        return ERROR_OK;
 }