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);

-- 

Reply via email to