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>
This commit is contained in:
parent
ec28cf03ae
commit
ed00ee9ce0
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue