diff options
author | Adrian Negreanu <adrian.negreanu@nxp.com> | 2020-11-06 11:57:04 +0200 |
---|---|---|
committer | Tomas Vanek <vanekt@fbl.cz> | 2021-04-10 20:51:30 +0100 |
commit | fed42ccfd3dff0c3dcfa7f017bbd26eff3d4f15c (patch) | |
tree | 2eec34af583550b812f3ebb8dec260846a335e20 /src/jtag/drivers/cmsis_dap_usb_hid.c | |
parent | 68e50415a115f3b80b7d1a1b580287745b281a5c (diff) | |
download | riscv-openocd-fed42ccfd3dff0c3dcfa7f017bbd26eff3d4f15c.zip riscv-openocd-fed42ccfd3dff0c3dcfa7f017bbd26eff3d4f15c.tar.gz riscv-openocd-fed42ccfd3dff0c3dcfa7f017bbd26eff3d4f15c.tar.bz2 |
cmsis-dap: don't update the packet size across backends.
The hidapi cmsis-dap backend is using a packet_size of
64+1: 64 is the bMaxPacketSize0 and 1 is the hid Report-Id.
In hidapi::hid_write(), the packet_size is decremented by 1 and
stored for the next transfer.
The packet_size is now valid bMaxPacketSize0=64,
so when hid_read() is called, libusb_bulk_transfer() finishes w/o timeout.
For the libusb bulk backend, the same packet_size of 64+1 is used,
but there's no hid_write() to decrement and store it for the next read.
So the next time a read is done, it will try to read 64+1 bytes.
Fix this by putting the packet logic within each backend.
Use calloc() to allocate the struct cmsis_dap to be on safer side.
Change-Id: I0c450adbc7674d5fcd8208dd23062d5cdd209efd
Signed-off-by: Adrian Negreanu <adrian.negreanu@nxp.com>
Reviewed-on: http://openocd.zylin.com/5920
Tested-by: jenkins
Reviewed-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com>
Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
Diffstat (limited to 'src/jtag/drivers/cmsis_dap_usb_hid.c')
-rw-r--r-- | src/jtag/drivers/cmsis_dap_usb_hid.c | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/src/jtag/drivers/cmsis_dap_usb_hid.c b/src/jtag/drivers/cmsis_dap_usb_hid.c index 681aef1..b290d6f 100644 --- a/src/jtag/drivers/cmsis_dap_usb_hid.c +++ b/src/jtag/drivers/cmsis_dap_usb_hid.c @@ -40,12 +40,13 @@ #include "cmsis_dap.h" -#define PACKET_SIZE (64 + 1) /* 64 bytes plus report id */ - struct cmsis_dap_backend_data { hid_device *dev_handle; }; +static void cmsis_dap_hid_close(struct cmsis_dap *dap); +static int cmsis_dap_hid_alloc(struct cmsis_dap *dap, unsigned int pkt_sz); + static int cmsis_dap_hid_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t pids[], char *serial) { hid_device *dev = NULL; @@ -145,7 +146,7 @@ static int cmsis_dap_hid_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t p * without this info we cannot communicate with the adapter. * For the moment we have to hard code the packet size */ - dap->packet_size = PACKET_SIZE; + unsigned int packet_size = 64; /* atmel cmsis-dap uses 512 byte reports */ /* except when it doesn't e.g. with mEDBG on SAMD10 Xplained @@ -153,10 +154,16 @@ static int cmsis_dap_hid_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t p /* TODO: HID report descriptor should be parsed instead of * hardcoding a match by VID */ if (target_vid == 0x03eb && target_pid != 0x2145 && target_pid != 0x2175) - dap->packet_size = 512 + 1; + packet_size = 512; dap->bdata->dev_handle = dev; + int retval = cmsis_dap_hid_alloc(dap, packet_size); + if (retval != ERROR_OK) { + cmsis_dap_hid_close(dap); + return ERROR_FAIL; + } + return ERROR_OK; } @@ -166,11 +173,13 @@ static void cmsis_dap_hid_close(struct cmsis_dap *dap) hid_exit(); free(dap->bdata); dap->bdata = NULL; + free(dap->packet_buffer); + dap->packet_buffer = NULL; } static int cmsis_dap_hid_read(struct cmsis_dap *dap, int timeout_ms) { - int retval = hid_read_timeout(dap->bdata->dev_handle, dap->packet_buffer, dap->packet_size, timeout_ms); + int retval = hid_read_timeout(dap->bdata->dev_handle, dap->packet_buffer, dap->packet_buffer_size, timeout_ms); if (retval == 0) { return ERROR_TIMEOUT_REACHED; @@ -187,10 +196,10 @@ static int cmsis_dap_hid_write(struct cmsis_dap *dap, int txlen, int timeout_ms) (void) timeout_ms; /* Pad the rest of the TX buffer with 0's */ - memset(dap->packet_buffer + txlen, 0, dap->packet_size - txlen); + memset(dap->packet_buffer + txlen, 0, dap->packet_buffer_size - txlen); /* write data to device */ - int retval = hid_write(dap->bdata->dev_handle, dap->packet_buffer, dap->packet_size); + int retval = hid_write(dap->bdata->dev_handle, dap->packet_buffer, dap->packet_buffer_size); if (retval == -1) { LOG_ERROR("error writing data: %ls", hid_error(dap->bdata->dev_handle)); return ERROR_FAIL; @@ -199,10 +208,27 @@ static int cmsis_dap_hid_write(struct cmsis_dap *dap, int txlen, int timeout_ms) return retval; } +static int cmsis_dap_hid_alloc(struct cmsis_dap *dap, unsigned int pkt_sz) +{ + unsigned int packet_buffer_size = pkt_sz + REPORT_ID_SIZE; + uint8_t *buf = malloc(packet_buffer_size); + if (buf == NULL) { + LOG_ERROR("unable to allocate CMSIS-DAP packet buffer"); + return ERROR_FAIL; + } + + dap->packet_buffer = buf; + dap->packet_size = pkt_sz; + dap->packet_buffer_size = packet_buffer_size; + + return ERROR_OK; +} + const struct cmsis_dap_backend cmsis_dap_hid_backend = { .name = "hid", .open = cmsis_dap_hid_open, .close = cmsis_dap_hid_close, .read = cmsis_dap_hid_read, .write = cmsis_dap_hid_write, + .packet_buffer_alloc = cmsis_dap_hid_alloc, }; |