aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Vanek <vanekt@fbl.cz>2023-12-20 13:20:27 +0100
committerEvgeniy Naydanov <109669442+en-sc@users.noreply.github.com>2024-01-29 13:36:27 +0300
commited00ee9ce0094e354e09209a94f08f9818f8954a (patch)
tree38057cd3fddcd47313e49d400dbad622016b13f2
parentec28cf03aef7539ff8c02db4a9ac558545d4e7c6 (diff)
downloadriscv-openocd-ed00ee9ce0094e354e09209a94f08f9818f8954a.zip
riscv-openocd-ed00ee9ce0094e354e09209a94f08f9818f8954a.tar.gz
riscv-openocd-ed00ee9ce0094e354e09209a94f08f9818f8954a.tar.bz2
drivers/libusb_helper: introduce oocd_libusb_dev_mem_alloc() helper
On some systems (at least Windows/CYGWIN and macOS) libusb_dev_mem_alloc() simply returns NULL. Use the result of the very first libusb_dev_mem_alloc() call to decide if the underlining system supports dev mem allocation or we should fall-back to plain heap malloc(). From the decision time on, keep using the selected type of memory allocator and deallocator. Signed-off-by: Tomas Vanek <vanekt@fbl.cz> Change-Id: Ia1f0965cea44b4bb6d936b02ec43f5a16a46f080 Reviewed-on: https://review.openocd.org/c/openocd/+/8059 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
-rw-r--r--src/jtag/drivers/libusb_helper.c56
-rw-r--r--src/jtag/drivers/libusb_helper.h23
2 files changed, 79 insertions, 0 deletions
diff --git a/src/jtag/drivers/libusb_helper.c b/src/jtag/drivers/libusb_helper.c
index 9d788ee..57ea8cd 100644
--- a/src/jtag/drivers/libusb_helper.c
+++ b/src/jtag/drivers/libusb_helper.c
@@ -377,3 +377,59 @@ int jtag_libusb_handle_events_completed(int *completed)
{
return libusb_handle_events_completed(jtag_libusb_context, completed);
}
+
+static enum {
+ DEV_MEM_NOT_YET_DECIDED,
+ DEV_MEM_AVAILABLE,
+ DEV_MEM_FALLBACK_MALLOC
+} dev_mem_allocation;
+
+/* Older libusb does not implement following API calls - define stubs instead */
+#if !defined(LIBUSB_API_VERSION) || (LIBUSB_API_VERSION < 0x01000105)
+static uint8_t *libusb_dev_mem_alloc(libusb_device_handle *devh, size_t length)
+{
+ return NULL;
+}
+
+static int libusb_dev_mem_free(libusb_device_handle *devh,
+ uint8_t *buffer, size_t length)
+{
+ return LIBUSB_ERROR_NOT_SUPPORTED;
+}
+#endif
+
+uint8_t *oocd_libusb_dev_mem_alloc(libusb_device_handle *devh,
+ size_t length)
+{
+ uint8_t *buffer = NULL;
+ if (dev_mem_allocation != DEV_MEM_FALLBACK_MALLOC)
+ buffer = libusb_dev_mem_alloc(devh, length);
+
+ if (dev_mem_allocation == DEV_MEM_NOT_YET_DECIDED)
+ dev_mem_allocation = buffer ? DEV_MEM_AVAILABLE : DEV_MEM_FALLBACK_MALLOC;
+
+ if (dev_mem_allocation == DEV_MEM_FALLBACK_MALLOC)
+ buffer = malloc(length);
+
+ return buffer;
+}
+
+int oocd_libusb_dev_mem_free(libusb_device_handle *devh,
+ uint8_t *buffer, size_t length)
+{
+ if (!buffer)
+ return ERROR_OK;
+
+ switch (dev_mem_allocation) {
+ case DEV_MEM_AVAILABLE:
+ return jtag_libusb_error(libusb_dev_mem_free(devh, buffer, length));
+
+ case DEV_MEM_FALLBACK_MALLOC:
+ free(buffer);
+ return ERROR_OK;
+
+ case DEV_MEM_NOT_YET_DECIDED:
+ return ERROR_FAIL;
+ }
+ return ERROR_FAIL;
+}
diff --git a/src/jtag/drivers/libusb_helper.h b/src/jtag/drivers/libusb_helper.h
index 09309b4..3cd83c6 100644
--- a/src/jtag/drivers/libusb_helper.h
+++ b/src/jtag/drivers/libusb_helper.h
@@ -67,4 +67,27 @@ int jtag_libusb_choose_interface(struct libusb_device_handle *devh,
int jtag_libusb_get_pid(struct libusb_device *dev, uint16_t *pid);
int jtag_libusb_handle_events_completed(int *completed);
+/**
+ * Attempts to allocate a block of persistent DMA memory suitable for transfers
+ * against the USB device. Fall-back to the ordinary heap malloc()
+ * if the first libusb_dev_mem_alloc() call fails.
+ * @param devh _libusb_ device handle.
+ * @param length size of desired data buffer
+ * @returns a pointer to the newly allocated memory, or NULL on failure
+ */
+uint8_t *oocd_libusb_dev_mem_alloc(libusb_device_handle *devh,
+ size_t length);
+
+/**
+ * Free device memory allocated with oocd_libusb_dev_mem_alloc().
+ * Uses either libusb_dev_mem_free() or free() consistently with
+ * the used method of allocation.
+ * @param devh _libusb_ device handle.
+ * @param buffer pointer to the previously allocated memory
+ * @param length size of desired data buffer
+ * @returns Returns ERROR_OK on success, ERROR_FAIL otherwise.
+ */
+int oocd_libusb_dev_mem_free(libusb_device_handle *devh,
+ uint8_t *buffer, size_t length);
+
#endif /* OPENOCD_JTAG_DRIVERS_LIBUSB_HELPER_H */