This is an automated email from Gerrit.

"Tomas Vanek <van...@fbl.cz>" just uploaded a new patch set to Gerrit, which 
you can find at https://review.openocd.org/c/openocd/+/7366

-- gerrit

commit a44d2e1bce08d9a42279af3c5d89a0ded85885f2
Author: Tomas Vanek <van...@fbl.cz>
Date:   Sun Nov 20 21:01:17 2022 +0100

    jtag/drivers/cmsis_dap: implement canceling of pending USB requests
    
    Use it when commands and responses get out of sync.
    
    Signed-off-by: Tomas Vanek <van...@fbl.cz>
    Change-Id: Ie36fa760c1643ae10be0e87fc633068965a72242

diff --git a/src/jtag/drivers/cmsis_dap.c b/src/jtag/drivers/cmsis_dap.c
index 1ce1e3638b..c32744874f 100644
--- a/src/jtag/drivers/cmsis_dap.c
+++ b/src/jtag/drivers/cmsis_dap.c
@@ -360,6 +360,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;
        }
@@ -753,6 +754,19 @@ static int cmsis_dap_cmd_dap_swo_data(
        return ERROR_OK;
 }
 
+static void cmsis_dap_swd_cancel_transfers(struct cmsis_dap *dap)
+{
+       dap->backend->cancel_all(dap);
+       cmsis_dap_flush_read(dap);
+
+       for (unsigned int i = 0; i < MAX_PENDING_REQUESTS; i++)
+               dap->pending_fifo[i].transfer_count = 0;
+
+       dap->pending_fifo_put_idx = 0;
+       dap->pending_fifo_get_idx = 0;
+       dap->pending_fifo_block_count = 0;
+}
+
 static void cmsis_dap_swd_write_from_queue(struct cmsis_dap *dap)
 {
        uint8_t *command = dap->command;
@@ -862,8 +876,7 @@ static void cmsis_dap_swd_read_process(struct cmsis_dap 
*dap, enum cmsis_dap_blo
        if (resp[0] != CMD_DAP_TFER) {
                LOG_ERROR("CMSIS-DAP command mismatch. Expected 0x%x received 
0x%" PRIx8,
                        CMD_DAP_TFER, resp[0]);
-               queued_retval = ERROR_FAIL;
-               goto skip;
+               goto mismatch_err;
        }
 
        uint8_t transfer_count = resp[1];
@@ -881,9 +894,14 @@ 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);
+mismatch_err:
+               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,
diff --git a/src/jtag/drivers/cmsis_dap.h b/src/jtag/drivers/cmsis_dap.h
index 8c8146d1c8..78ce2d102d 100644
--- a/src/jtag/drivers/cmsis_dap.h
+++ b/src/jtag/drivers/cmsis_dap.h
@@ -53,6 +53,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;
diff --git a/src/jtag/drivers/cmsis_dap_usb_bulk.c 
b/src/jtag/drivers/cmsis_dap_usb_bulk.c
index 63b6c4fc58..5b5468881b 100644
--- a/src/jtag/drivers/cmsis_dap_usb_bulk.c
+++ b/src/jtag/drivers/cmsis_dap_usb_bulk.c
@@ -605,6 +605,19 @@ static void cmsis_dap_usb_free(struct cmsis_dap *dap)
        dap->packet_buffer = 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)
@@ -634,4 +647,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,
 };
diff --git a/src/jtag/drivers/cmsis_dap_usb_hid.c 
b/src/jtag/drivers/cmsis_dap_usb_hid.c
index 6338886c84..1decc7156d 100644
--- a/src/jtag/drivers/cmsis_dap_usb_hid.c
+++ b/src/jtag/drivers/cmsis_dap_usb_hid.c
@@ -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,
 };

-- 

Reply via email to