Commit 22bc5194 authored by drath's avatar drath
Browse files

- added support for error handlers to JTAG scan commands (jtag_[plain_][ir|dr]_scan)

- catch apparently broken JTAG IR scan after ARM926EJ-S CP15 operations
- added "arm7_9 dump_etb" command


git-svn-id: svn://svn.berlios.de/openocd/trunk@142 b42882b7-edfa-0310-969c-e2dbd0fdcd60
parent 04dc9891
...@@ -357,6 +357,10 @@ int command_run_line(command_context_t *context, char *line) ...@@ -357,6 +357,10 @@ int command_run_line(command_context_t *context, char *line)
if (!*line) if (!*line)
return ERROR_OK; return ERROR_OK;
/* ignore comments */
if (*line && (line[0] == '#'))
return ERROR_OK;
if (context->echo) if (context->echo)
{ {
command_print(context, "%s", line); command_print(context, "%s", line);
......
...@@ -331,6 +331,12 @@ int amt_jtagaccel_execute_queue(void) ...@@ -331,6 +331,12 @@ int amt_jtagaccel_execute_queue(void)
int scan_size; int scan_size;
enum scan_type type; enum scan_type type;
u8 *buffer; u8 *buffer;
int retval;
/* return ERROR_OK, unless a jtag_read_buffer returns a failed check
* that wasn't handled by a caller-provided error handler
*/
retval = ERROR_OK;
while (cmd) while (cmd)
{ {
...@@ -379,7 +385,7 @@ int amt_jtagaccel_execute_queue(void) ...@@ -379,7 +385,7 @@ int amt_jtagaccel_execute_queue(void)
type = jtag_scan_type(cmd->cmd.scan); type = jtag_scan_type(cmd->cmd.scan);
amt_jtagaccel_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size); amt_jtagaccel_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK) if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
return ERROR_JTAG_QUEUE_FAILED; retval = ERROR_JTAG_QUEUE_FAILED;
if (buffer) if (buffer)
free(buffer); free(buffer);
break; break;
...@@ -396,7 +402,7 @@ int amt_jtagaccel_execute_queue(void) ...@@ -396,7 +402,7 @@ int amt_jtagaccel_execute_queue(void)
cmd = cmd->next; cmd = cmd->next;
} }
return ERROR_OK; return retval;
} }
#if PARPORT_USE_GIVEIO == 1 #if PARPORT_USE_GIVEIO == 1
......
...@@ -182,12 +182,18 @@ int bitbang_execute_queue(void) ...@@ -182,12 +182,18 @@ int bitbang_execute_queue(void)
int scan_size; int scan_size;
enum scan_type type; enum scan_type type;
u8 *buffer; u8 *buffer;
int retval;
if (!bitbang_interface) if (!bitbang_interface)
{ {
ERROR("BUG: Bitbang interface called, but not yet initialized"); ERROR("BUG: Bitbang interface called, but not yet initialized");
exit(-1); exit(-1);
} }
/* return ERROR_OK, unless a jtag_read_buffer returns a failed check
* that wasn't handled by a caller-provided error handler
*/
retval = ERROR_OK;
while (cmd) while (cmd)
{ {
...@@ -234,7 +240,7 @@ int bitbang_execute_queue(void) ...@@ -234,7 +240,7 @@ int bitbang_execute_queue(void)
break; break;
case JTAG_SCAN: case JTAG_SCAN:
#ifdef _DEBUG_JTAG_IO_ #ifdef _DEBUG_JTAG_IO_
DEBUG("scan end in %i", cmd->cmd.scan->end_state); DEBUG("%s scan end in %i", (cmd->cmd.scan->ir_scan) ? "IR" : "DR", cmd->cmd.scan->end_state);
#endif #endif
if (cmd->cmd.scan->end_state != -1) if (cmd->cmd.scan->end_state != -1)
bitbang_end_state(cmd->cmd.scan->end_state); bitbang_end_state(cmd->cmd.scan->end_state);
...@@ -242,7 +248,7 @@ int bitbang_execute_queue(void) ...@@ -242,7 +248,7 @@ int bitbang_execute_queue(void)
type = jtag_scan_type(cmd->cmd.scan); type = jtag_scan_type(cmd->cmd.scan);
bitbang_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size); bitbang_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK) if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
return ERROR_JTAG_QUEUE_FAILED; retval = ERROR_JTAG_QUEUE_FAILED;
if (buffer) if (buffer)
free(buffer); free(buffer);
break; break;
...@@ -259,6 +265,6 @@ int bitbang_execute_queue(void) ...@@ -259,6 +265,6 @@ int bitbang_execute_queue(void)
cmd = cmd->next; cmd = cmd->next;
} }
return ERROR_OK; return retval;
} }
...@@ -402,7 +402,12 @@ int ft2232_send_and_recv(jtag_command_t *first, jtag_command_t *last) ...@@ -402,7 +402,12 @@ int ft2232_send_and_recv(jtag_command_t *first, jtag_command_t *last)
ft2232_expect_read = 0; ft2232_expect_read = 0;
ft2232_read_pointer = 0; ft2232_read_pointer = 0;
/* return ERROR_OK, unless a jtag_read_buffer returns a failed check
* that wasn't handled by a caller-provided error handler
*/
retval = ERROR_OK;
cmd = first; cmd = first;
while (cmd != last) while (cmd != last)
{ {
...@@ -415,7 +420,8 @@ int ft2232_send_and_recv(jtag_command_t *first, jtag_command_t *last) ...@@ -415,7 +420,8 @@ int ft2232_send_and_recv(jtag_command_t *first, jtag_command_t *last)
scan_size = jtag_scan_size(cmd->cmd.scan); scan_size = jtag_scan_size(cmd->cmd.scan);
buffer = calloc(CEIL(scan_size, 8), 1); buffer = calloc(CEIL(scan_size, 8), 1);
ft2232_read_scan(type, buffer, scan_size); ft2232_read_scan(type, buffer, scan_size);
jtag_read_buffer(buffer, cmd->cmd.scan); if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
retval = ERROR_JTAG_QUEUE_FAILED;
free(buffer); free(buffer);
} }
break; break;
...@@ -427,7 +433,7 @@ int ft2232_send_and_recv(jtag_command_t *first, jtag_command_t *last) ...@@ -427,7 +433,7 @@ int ft2232_send_and_recv(jtag_command_t *first, jtag_command_t *last)
ft2232_buffer_size = 0; ft2232_buffer_size = 0;
return ERROR_OK; return retval;
} }
void ft2232_add_pathmove(pathmove_command_t *cmd) void ft2232_add_pathmove(pathmove_command_t *cmd)
...@@ -1039,6 +1045,12 @@ int ft2232_execute_queue() ...@@ -1039,6 +1045,12 @@ int ft2232_execute_queue()
int i; int i;
int predicted_size = 0; int predicted_size = 0;
int require_send = 0; int require_send = 0;
int retval;
/* return ERROR_OK, unless ft2232_send_and_recv reports a failed check
* that wasn't handled by a caller-provided error handler
*/
retval = ERROR_OK;
ft2232_buffer_size = 0; ft2232_buffer_size = 0;
ft2232_expect_read = 0; ft2232_expect_read = 0;
...@@ -1060,7 +1072,8 @@ int ft2232_execute_queue() ...@@ -1060,7 +1072,8 @@ int ft2232_execute_queue()
predicted_size = 3; predicted_size = 3;
if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE) if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
{ {
ft2232_send_and_recv(first_unsent, cmd); if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
retval = ERROR_JTAG_QUEUE_FAILED;
require_send = 0; require_send = 0;
first_unsent = cmd; first_unsent = cmd;
} }
...@@ -1084,7 +1097,8 @@ int ft2232_execute_queue() ...@@ -1084,7 +1097,8 @@ int ft2232_execute_queue()
predicted_size += 3; predicted_size += 3;
if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE) if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
{ {
ft2232_send_and_recv(first_unsent, cmd); if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
retval = ERROR_JTAG_QUEUE_FAILED;
require_send = 0; require_send = 0;
first_unsent = cmd; first_unsent = cmd;
} }
...@@ -1135,7 +1149,8 @@ int ft2232_execute_queue() ...@@ -1135,7 +1149,8 @@ int ft2232_execute_queue()
predicted_size = 3; predicted_size = 3;
if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE) if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
{ {
ft2232_send_and_recv(first_unsent, cmd); if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
retval = ERROR_JTAG_QUEUE_FAILED;
require_send = 0; require_send = 0;
first_unsent = cmd; first_unsent = cmd;
} }
...@@ -1159,7 +1174,8 @@ int ft2232_execute_queue() ...@@ -1159,7 +1174,8 @@ int ft2232_execute_queue()
predicted_size = 3 * CEIL(cmd->cmd.pathmove->num_states, 7); predicted_size = 3 * CEIL(cmd->cmd.pathmove->num_states, 7);
if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE) if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
{ {
ft2232_send_and_recv(first_unsent, cmd); if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
retval = ERROR_JTAG_QUEUE_FAILED;
require_send = 0; require_send = 0;
first_unsent = cmd; first_unsent = cmd;
} }
...@@ -1178,7 +1194,8 @@ int ft2232_execute_queue() ...@@ -1178,7 +1194,8 @@ int ft2232_execute_queue()
DEBUG("oversized ft2232 scan (predicted_size > FT2232_BUFFER_SIZE)"); DEBUG("oversized ft2232 scan (predicted_size > FT2232_BUFFER_SIZE)");
/* unsent commands before this */ /* unsent commands before this */
if (first_unsent != cmd) if (first_unsent != cmd)
ft2232_send_and_recv(first_unsent, cmd); if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
retval = ERROR_JTAG_QUEUE_FAILED;
/* current command */ /* current command */
if (cmd->cmd.scan->end_state != -1) if (cmd->cmd.scan->end_state != -1)
...@@ -1193,7 +1210,8 @@ int ft2232_execute_queue() ...@@ -1193,7 +1210,8 @@ int ft2232_execute_queue()
else if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE) else if (ft2232_buffer_size + predicted_size + 1 > FT2232_BUFFER_SIZE)
{ {
DEBUG("ft2232 buffer size reached, sending queued commands (first_unsent: %p, cmd: %p)", first_unsent, cmd); DEBUG("ft2232 buffer size reached, sending queued commands (first_unsent: %p, cmd: %p)", first_unsent, cmd);
ft2232_send_and_recv(first_unsent, cmd); if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
retval = ERROR_JTAG_QUEUE_FAILED;
require_send = 0; require_send = 0;
first_unsent = cmd; first_unsent = cmd;
} }
...@@ -1210,7 +1228,8 @@ int ft2232_execute_queue() ...@@ -1210,7 +1228,8 @@ int ft2232_execute_queue()
#endif #endif
break; break;
case JTAG_SLEEP: case JTAG_SLEEP:
ft2232_send_and_recv(first_unsent, cmd); if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
retval = ERROR_JTAG_QUEUE_FAILED;
first_unsent = cmd->next; first_unsent = cmd->next;
jtag_sleep(cmd->cmd.sleep->us); jtag_sleep(cmd->cmd.sleep->us);
#ifdef _DEBUG_JTAG_IO_ #ifdef _DEBUG_JTAG_IO_
...@@ -1225,9 +1244,10 @@ int ft2232_execute_queue() ...@@ -1225,9 +1244,10 @@ int ft2232_execute_queue()
} }
if (require_send > 0) if (require_send > 0)
ft2232_send_and_recv(first_unsent, cmd); if (ft2232_send_and_recv(first_unsent, cmd) != ERROR_OK)
retval = ERROR_JTAG_QUEUE_FAILED;
return ERROR_OK; return retval;
} }
#if BUILD_FT2232_FTD2XX == 1 #if BUILD_FT2232_FTD2XX == 1
......
...@@ -360,6 +360,12 @@ int gw16012_execute_queue(void) ...@@ -360,6 +360,12 @@ int gw16012_execute_queue(void)
int scan_size; int scan_size;
enum scan_type type; enum scan_type type;
u8 *buffer; u8 *buffer;
int retval;
/* return ERROR_OK, unless a jtag_read_buffer returns a failed check
* that wasn't handled by a caller-provided error handler
*/
retval = ERROR_OK;
while (cmd) while (cmd)
{ {
...@@ -415,7 +421,7 @@ int gw16012_execute_queue(void) ...@@ -415,7 +421,7 @@ int gw16012_execute_queue(void)
#endif #endif
gw16012_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size); gw16012_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK) if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
return ERROR_JTAG_QUEUE_FAILED; retval = ERROR_JTAG_QUEUE_FAILED;
if (buffer) if (buffer)
free(buffer); free(buffer);
break; break;
...@@ -432,7 +438,7 @@ int gw16012_execute_queue(void) ...@@ -432,7 +438,7 @@ int gw16012_execute_queue(void)
cmd = cmd->next; cmd = cmd->next;
} }
return ERROR_OK; return retval;
} }
#if PARPORT_USE_GIVEIO == 1 #if PARPORT_USE_GIVEIO == 1
......
...@@ -191,11 +191,12 @@ jtag_interface_t *jtag = NULL; ...@@ -191,11 +191,12 @@ jtag_interface_t *jtag = NULL;
char* jtag_interface = NULL; char* jtag_interface = NULL;
int jtag_speed = -1; int jtag_speed = -1;
/* forward declarations */ /* forward declarations */
int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state endstate); 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); 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); 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); 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_statemove(enum tap_state endstate);
int jtag_add_pathmove(int num_states, enum tap_state *path); int jtag_add_pathmove(int num_states, enum tap_state *path);
int jtag_add_runtest(int num_cycles, enum tap_state endstate); int jtag_add_runtest(int num_cycles, enum tap_state endstate);
...@@ -364,13 +365,12 @@ void cmd_queue_free() ...@@ -364,13 +365,12 @@ void cmd_queue_free()
cmd_queue_pages = NULL; cmd_queue_pages = NULL;
} }
int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state) int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state, error_handler_t *error_handler)
{ {
jtag_command_t **last_cmd; jtag_command_t **last_cmd;
jtag_device_t *device; jtag_device_t *device;
int i, j; int i, j;
int scan_size = 0; int scan_size = 0;
/* int changed = 0; */
if (jtag_trst == 1) if (jtag_trst == 1)
{ {
...@@ -378,26 +378,6 @@ int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state) ...@@ -378,26 +378,6 @@ int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state)
return ERROR_JTAG_TRST_ASSERTED; return ERROR_JTAG_TRST_ASSERTED;
} }
/*
for (i=0; i<num_fields; i++)
{
device = jtag_get_device(fields[i].device);
if (device)
{
if (buf_cmp(device->cur_instr, fields[i].out_value, device->ir_length))
changed = 1;
}
else
{
ERROR("inexistant device specified for ir scan");
return ERROR_INVALID_ARGUMENTS;
}
}
if (!changed)
return ERROR_OK;
*/
last_cmd = jtag_get_last_command_p(); last_cmd = jtag_get_last_command_p();
/* allocate memory for a new list member */ /* allocate memory for a new list member */
...@@ -412,7 +392,16 @@ int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state) ...@@ -412,7 +392,16 @@ 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->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->fields = cmd_queue_alloc(jtag_num_devices * sizeof(scan_field_t));
(*last_cmd)->cmd.scan->end_state = state; (*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) if (state != -1)
cmd_queue_end_state = state; cmd_queue_end_state = state;
...@@ -441,7 +430,7 @@ int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state) ...@@ -441,7 +430,7 @@ int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state)
{ {
(*last_cmd)->cmd.scan->fields[i].in_check_value = NULL; (*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_check_mask = NULL;
} }
(*last_cmd)->cmd.scan->fields[i].in_handler = 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_priv = NULL;
...@@ -475,7 +464,7 @@ int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state) ...@@ -475,7 +464,7 @@ int jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state)
return ERROR_OK; return ERROR_OK;
} }
int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state) int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state, error_handler_t *error_handler)
{ {
jtag_command_t **last_cmd; jtag_command_t **last_cmd;
int i; int i;
...@@ -500,6 +489,15 @@ int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state ...@@ -500,6 +489,15 @@ 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->num_fields = num_fields;
(*last_cmd)->cmd.scan->fields = cmd_queue_alloc(num_fields * sizeof(scan_field_t)); (*last_cmd)->cmd.scan->fields = cmd_queue_alloc(num_fields * sizeof(scan_field_t));
(*last_cmd)->cmd.scan->end_state = state; (*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) if (state != -1)
cmd_queue_end_state = state; cmd_queue_end_state = state;
...@@ -529,7 +527,7 @@ int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state ...@@ -529,7 +527,7 @@ int jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state
return ERROR_OK; return ERROR_OK;
} }
int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state) int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state, error_handler_t *error_handler)
{ {
int i, j; int i, j;
int bypass_devices = 0; int bypass_devices = 0;
...@@ -564,7 +562,16 @@ int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state) ...@@ -564,7 +562,16 @@ 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->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->fields = cmd_queue_alloc((num_fields + bypass_devices) * sizeof(scan_field_t));
(*last_cmd)->cmd.scan->end_state = state; (*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) if (state != -1)
cmd_queue_end_state = state; cmd_queue_end_state = state;
...@@ -628,7 +635,7 @@ int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state) ...@@ -628,7 +635,7 @@ int jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state)
return ERROR_OK; return ERROR_OK;
} }
int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state) int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state, error_handler_t *error_handler)
{ {
int i; int i;
jtag_command_t **last_cmd = jtag_get_last_command_p(); jtag_command_t **last_cmd = jtag_get_last_command_p();
...@@ -651,7 +658,16 @@ int jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state ...@@ -651,7 +658,16 @@ 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->num_fields = num_fields;
(*last_cmd)->cmd.scan->fields = cmd_queue_alloc(num_fields * sizeof(scan_field_t)); (*last_cmd)->cmd.scan->fields = cmd_queue_alloc(num_fields * sizeof(scan_field_t));
(*last_cmd)->cmd.scan->end_state = state; (*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) if (state != -1)
cmd_queue_end_state = state; cmd_queue_end_state = state;
...@@ -1009,8 +1025,11 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd) ...@@ -1009,8 +1025,11 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
{ {
int i; int i;
int bit_count = 0; int bit_count = 0;
int retval = ERROR_OK; int retval;
/* 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, in_check_value nor in_handler
...@@ -1027,7 +1046,6 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd) ...@@ -1027,7 +1046,6 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
DEBUG("fields[%i].in_value: 0x%s", i, char_buf); DEBUG("fields[%i].in_value: 0x%s", i, char_buf);
free(char_buf); free(char_buf);
#endif #endif
if (cmd->fields[i].in_value) if (cmd->fields[i].in_value)
{ {
...@@ -1037,7 +1055,6 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd) ...@@ -1037,7 +1055,6 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
{ {
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) != ERROR_OK)
{ {
/* TODO: error reporting */
WARNING("in_handler reported a failed check"); WARNING("in_handler reported a failed check");
retval = ERROR_JTAG_QUEUE_FAILED; retval = ERROR_JTAG_QUEUE_FAILED;
} }
...@@ -1049,27 +1066,63 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd) ...@@ -1049,27 +1066,63 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd)
{ {
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) != ERROR_OK)