jtag/drivers/cmsis_dap: implement canceling of pending USB requests
Use it whenever an out-of-sync response is detected to clean USB bulk transfer state. USB hidapi does not offer any means to cancel a pending request, therefore cmsis_dap_hid_cancel_all() does nothing. Signed-off-by: Tomas Vanek <vanekt@fbl.cz> Change-Id: Ie36fa760c1643ae10be0e87fc633068965a72242 Reviewed-on: https://review.openocd.org/c/openocd/+/7366 Tested-by: jenkins Reviewed-by: zapb <dev@zapb.de>
This commit is contained in:
parent
fd75e9e542
commit
66391d2837
|
@ -365,6 +365,7 @@ static int cmsis_dap_xfer(struct cmsis_dap *dap, int txlen)
|
|||
LOG_ERROR("CMSIS-DAP command mismatch. Sent 0x%" PRIx8
|
||||
" received 0x%" PRIx8, current_cmd, resp[0]);
|
||||
|
||||
dap->backend->cancel_all(dap);
|
||||
cmsis_dap_flush_read(dap);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
@ -758,7 +759,6 @@ static int cmsis_dap_cmd_dap_swo_data(
|
|||
return ERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
static void cmsis_dap_swd_discard_all_pending(struct cmsis_dap *dap)
|
||||
{
|
||||
for (unsigned int i = 0; i < MAX_PENDING_REQUESTS; i++)
|
||||
|
@ -769,6 +769,13 @@ static void cmsis_dap_swd_discard_all_pending(struct cmsis_dap *dap)
|
|||
dap->pending_fifo_block_count = 0;
|
||||
}
|
||||
|
||||
static void cmsis_dap_swd_cancel_transfers(struct cmsis_dap *dap)
|
||||
{
|
||||
dap->backend->cancel_all(dap);
|
||||
cmsis_dap_flush_read(dap);
|
||||
cmsis_dap_swd_discard_all_pending(dap);
|
||||
}
|
||||
|
||||
static void cmsis_dap_swd_write_from_queue(struct cmsis_dap *dap)
|
||||
{
|
||||
uint8_t *command = dap->command;
|
||||
|
@ -913,8 +920,9 @@ static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, enum cmsis_dap_blo
|
|||
if (resp[0] != block->command) {
|
||||
LOG_ERROR("CMSIS-DAP command mismatch. Expected 0x%x received 0x%" PRIx8,
|
||||
block->command, resp[0]);
|
||||
cmsis_dap_swd_cancel_transfers(dap);
|
||||
queued_retval = ERROR_FAIL;
|
||||
goto skip;
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int transfer_count;
|
||||
|
@ -940,9 +948,13 @@ static void cmsis_dap_swd_read_process(struct cmsis_dap *dap, enum cmsis_dap_blo
|
|||
goto skip;
|
||||
}
|
||||
|
||||
if (block->transfer_count != transfer_count)
|
||||
if (block->transfer_count != transfer_count) {
|
||||
LOG_ERROR("CMSIS-DAP transfer count mismatch: expected %d, got %d",
|
||||
block->transfer_count, transfer_count);
|
||||
cmsis_dap_swd_cancel_transfers(dap);
|
||||
queued_retval = ERROR_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_DEBUG_IO("Received results of %d queued transactions FIFO index %u, %s mode",
|
||||
transfer_count, dap->pending_fifo_get_idx,
|
||||
|
|
|
@ -66,6 +66,7 @@ struct cmsis_dap_backend {
|
|||
int (*write)(struct cmsis_dap *dap, int len, int timeout_ms);
|
||||
int (*packet_buffer_alloc)(struct cmsis_dap *dap, unsigned int pkt_sz);
|
||||
void (*packet_buffer_free)(struct cmsis_dap *dap);
|
||||
void (*cancel_all)(struct cmsis_dap *dap);
|
||||
};
|
||||
|
||||
extern const struct cmsis_dap_backend cmsis_dap_hid_backend;
|
||||
|
|
|
@ -634,6 +634,19 @@ static void cmsis_dap_usb_free(struct cmsis_dap *dap)
|
|||
dap->response = NULL;
|
||||
}
|
||||
|
||||
static void cmsis_dap_usb_cancel_all(struct cmsis_dap *dap)
|
||||
{
|
||||
for (unsigned int i = 0; i < MAX_PENDING_REQUESTS; i++) {
|
||||
if (dap->bdata->command_transfers[i].status == CMSIS_DAP_TRANSFER_PENDING)
|
||||
libusb_cancel_transfer(dap->bdata->command_transfers[i].transfer);
|
||||
if (dap->bdata->response_transfers[i].status == CMSIS_DAP_TRANSFER_PENDING)
|
||||
libusb_cancel_transfer(dap->bdata->response_transfers[i].transfer);
|
||||
|
||||
dap->bdata->command_transfers[i].status = CMSIS_DAP_TRANSFER_IDLE;
|
||||
dap->bdata->response_transfers[i].status = CMSIS_DAP_TRANSFER_IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
COMMAND_HANDLER(cmsis_dap_handle_usb_interface_command)
|
||||
{
|
||||
if (CMD_ARGC == 1)
|
||||
|
@ -663,4 +676,5 @@ const struct cmsis_dap_backend cmsis_dap_usb_backend = {
|
|||
.write = cmsis_dap_usb_write,
|
||||
.packet_buffer_alloc = cmsis_dap_usb_alloc,
|
||||
.packet_buffer_free = cmsis_dap_usb_free,
|
||||
.cancel_all = cmsis_dap_usb_cancel_all,
|
||||
};
|
||||
|
|
|
@ -236,6 +236,10 @@ static void cmsis_dap_hid_free(struct cmsis_dap *dap)
|
|||
dap->packet_buffer = NULL;
|
||||
}
|
||||
|
||||
static void cmsis_dap_hid_cancel_all(struct cmsis_dap *dap)
|
||||
{
|
||||
}
|
||||
|
||||
const struct cmsis_dap_backend cmsis_dap_hid_backend = {
|
||||
.name = "hid",
|
||||
.open = cmsis_dap_hid_open,
|
||||
|
@ -244,4 +248,5 @@ const struct cmsis_dap_backend cmsis_dap_hid_backend = {
|
|||
.write = cmsis_dap_hid_write,
|
||||
.packet_buffer_alloc = cmsis_dap_hid_alloc,
|
||||
.packet_buffer_free = cmsis_dap_hid_free,
|
||||
.cancel_all = cmsis_dap_hid_cancel_all,
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue