diff options
author | Tomas Vanek <vanekt@fbl.cz> | 2023-12-20 13:20:27 +0100 |
---|---|---|
committer | Tomas Vanek <vanekt@fbl.cz> | 2024-01-12 07:12:32 +0000 |
commit | 15f74c2595fe20235b27ce079a35e066d6b6611c (patch) | |
tree | 1aad4d74bf148e0c45c470544bc3e9c0c09e0f64 /src/jtag | |
parent | adcc8ef87bc1ed47c95f1f2d23072b2b916e1555 (diff) | |
download | riscv-openocd-15f74c2595fe20235b27ce079a35e066d6b6611c.zip riscv-openocd-15f74c2595fe20235b27ce079a35e066d6b6611c.tar.gz riscv-openocd-15f74c2595fe20235b27ce079a35e066d6b6611c.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>
Diffstat (limited to 'src/jtag')
-rw-r--r-- | src/jtag/drivers/libusb_helper.c | 56 | ||||
-rw-r--r-- | src/jtag/drivers/libusb_helper.h | 23 |
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 */ |