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/+/8044
-- gerrit commit 08858ebb6dab470dffdbca4307bd03645901c8e9 Author: Tomas Vanek <van...@fbl.cz> Date: Sun Dec 10 11:58:43 2023 +0100 jtag/drivers/cmsis_dap: use malloc() when libusb_dev_mem_alloc() fails On some systems (at least Windows/CYGWIN and macOS) libusb_dev_mem_alloc() simply returns NULL. Use malloc() as a fallback to allocate CMSIS-DAP pending command/response buffers. Fixes: fd75e9e54270 (jtag/drivers/cmsis_dap_bulk: use asynchronous libusb transfer) Signed-off-by: Tomas Vanek <van...@fbl.cz> Change-Id: I89660f6747ad9d494b8192711cbbee5764e058fa diff --git a/src/jtag/drivers/cmsis_dap_usb_bulk.c b/src/jtag/drivers/cmsis_dap_usb_bulk.c index 17e490f05a..504c668dfc 100644 --- a/src/jtag/drivers/cmsis_dap_usb_bulk.c +++ b/src/jtag/drivers/cmsis_dap_usb_bulk.c @@ -33,8 +33,7 @@ #include "cmsis_dap.h" #include "libusb_helper.h" -#if !defined(LIBUSB_API_VERSION) || (LIBUSB_API_VERSION < 0x01000105) \ - || defined(_WIN32) || defined(__CYGWIN__) +#if !defined(LIBUSB_API_VERSION) || (LIBUSB_API_VERSION < 0x01000105) #define libusb_dev_mem_alloc(dev, sz) malloc(sz) #define libusb_dev_mem_free(dev, buffer, sz) free(buffer) #endif @@ -58,6 +57,8 @@ struct cmsis_dap_backend_data { unsigned int ep_out; unsigned int ep_in; int interface; + bool malloc_fallback; /* buffers was allocated by malloc() because + * libusb_dev_mem_alloc() fails */ struct cmsis_dap_bulk_transfer command_transfers[MAX_PENDING_REQUESTS]; struct cmsis_dap_bulk_transfer response_transfers[MAX_PENDING_REQUESTS]; @@ -382,6 +383,7 @@ static int cmsis_dap_usb_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t p dap->bdata->ep_out = ep_out; dap->bdata->ep_in = ep_in; dap->bdata->interface = interface_num; + dap->bdata->malloc_fallback = false; for (unsigned int idx = 0; idx < MAX_PENDING_REQUESTS; idx++) { dap->bdata->command_transfers[idx].status = CMSIS_DAP_TRANSFER_IDLE; @@ -583,6 +585,33 @@ static int cmsis_dap_usb_write(struct cmsis_dap *dap, int txlen, int timeout_ms) return ERROR_OK; } +static int cmsis_dap_usb_cmd_resp_alloc(struct cmsis_dap_backend_data *bdata, unsigned int pkt_sz) +{ + for (unsigned int i = 0; i < MAX_PENDING_REQUESTS; i++) { + if (bdata->malloc_fallback) { + bdata->command_transfers[i].buffer = malloc(pkt_sz); + bdata->response_transfers[i].buffer = malloc(pkt_sz); + } else { + bdata->command_transfers[i].buffer = + libusb_dev_mem_alloc(bdata->dev_handle, pkt_sz); + + /* On Windows and macOS libusb_dev_mem_alloc() simply returns NULL. */ + if (i == 0 && !bdata->command_transfers[i].buffer) + return ERROR_NOT_IMPLEMENTED; /* caller will try fallback */ + + bdata->response_transfers[i].buffer = + libusb_dev_mem_alloc(bdata->dev_handle, pkt_sz); + } + + if (!bdata->command_transfers[i].buffer + || !bdata->response_transfers[i].buffer) { + LOG_ERROR("unable to allocate CMSIS-DAP pending packet buffer"); + return ERROR_FAIL; + } + } + return ERROR_OK; +} + static int cmsis_dap_usb_alloc(struct cmsis_dap *dap, unsigned int pkt_sz) { dap->packet_buffer = malloc(pkt_sz); @@ -599,33 +628,31 @@ static int cmsis_dap_usb_alloc(struct cmsis_dap *dap, unsigned int pkt_sz) dap->command = dap->packet_buffer; dap->response = dap->packet_buffer; - for (unsigned int i = 0; i < MAX_PENDING_REQUESTS; i++) { - dap->bdata->command_transfers[i].buffer = - libusb_dev_mem_alloc(dap->bdata->dev_handle, pkt_sz); - if (!dap->bdata->command_transfers[i].buffer) { - LOG_ERROR("unable to allocate CMSIS-DAP packet buffer"); - return ERROR_FAIL; - } - dap->bdata->response_transfers[i].buffer = - libusb_dev_mem_alloc(dap->bdata->dev_handle, pkt_sz); - if (!dap->bdata->response_transfers[i].buffer) { - LOG_ERROR("unable to allocate CMSIS-DAP packet buffer"); - return ERROR_FAIL; - } + int retval = cmsis_dap_usb_cmd_resp_alloc(dap->bdata, pkt_sz); + if (retval == ERROR_NOT_IMPLEMENTED) { + LOG_DEBUG("Falling back to malloc() for CMSIS-DAP pending packet buffers"); + dap->bdata->malloc_fallback = true; + retval = cmsis_dap_usb_cmd_resp_alloc(dap->bdata, pkt_sz); } - - return ERROR_OK; + return retval; } static void cmsis_dap_usb_free(struct cmsis_dap *dap) { + struct cmsis_dap_backend_data *bdata = dap->bdata; + for (unsigned int i = 0; i < MAX_PENDING_REQUESTS; i++) { - libusb_dev_mem_free(dap->bdata->dev_handle, - dap->bdata->command_transfers[i].buffer, dap->packet_size); - dap->bdata->command_transfers[i].buffer = NULL; - libusb_dev_mem_free(dap->bdata->dev_handle, - dap->bdata->response_transfers[i].buffer, dap->packet_size); - dap->bdata->response_transfers[i].buffer = NULL; + if (bdata->malloc_fallback) { + free(bdata->command_transfers[i].buffer); + free(bdata->response_transfers[i].buffer); + } else { + libusb_dev_mem_free(bdata->dev_handle, + bdata->command_transfers[i].buffer, dap->packet_size); + libusb_dev_mem_free(bdata->dev_handle, + bdata->response_transfers[i].buffer, dap->packet_size); + } + bdata->command_transfers[i].buffer = NULL; + bdata->response_transfers[i].buffer = NULL; } free(dap->packet_buffer); --