@@ -22,6 +22,9 @@ static void urb_destroy(struct kref *kref)
if (urb->transfer_flags & URB_FREE_BUFFER)
kfree(urb->transfer_buffer);
+ else if (urb->transfer_flags & URB_FREE_COHERENT)
+ usb_free_coherent(urb->dev, urb->transfer_buffer_length,
+ urb->transfer_buffer, urb->transfer_dma);
kfree(urb);
}
@@ -1328,9 +1328,10 @@ extern int usb_disabled(void);
#define URB_NO_INTERRUPT 0x0080 /* HINT: no non-error interrupt
* needed */
#define URB_FREE_BUFFER 0x0100 /* Free transfer buffer with the URB */
+#define URB_FREE_COHERENT 0x0200 /* Free DMA memory of transfer buffer */
/* The following flags are used internally by usbcore and HCDs */
-#define URB_DIR_IN 0x0200 /* Transfer from device to host */
+#define URB_DIR_IN 0x0400 /* Transfer from device to host */
#define URB_DIR_OUT 0
#define URB_DIR_MASK URB_DIR_IN
When allocating URB memory with kmalloc(), drivers can simply set the URB_FREE_BUFFER flag in urb::transfer_flags and that way, the memory will be freed in the background when killing the URB (for example with usb_kill_anchored_urbs()). However, there are no equivalent mechanism when allocating DMA memory (with usb_alloc_coherent()). This patch adds a new flag: URB_FREE_COHERENT. Setting this flag will cause the kernel to automatically call usb_free_coherent() on the transfer buffer when the URB is killed, similarly to how URB_FREE_BUFFER triggers a call to kfree(). In order to have all the flags in numerical order, URB_DIR_IN is renumbered from 0x0200 to 0x0400 so that URB_FREE_COHERENT can reuse value 0x0200. CC: Alan Stern <stern@rowland.harvard.edu> CC: Rhett Aultman <rhett.aultman@samsara.com> Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr> --- Hi Rhett Aultman, I put the code snippet I previously sent into a patch. It is not tested (this is why I post it as RFC). Please feel free to add this to your series. ** Changelog ** v1 -> v2: * Renumber URB_DIR_IN for 0x0200 to 0x0400 in order to keep all the flags in numerical order. --- drivers/usb/core/urb.c | 3 +++ include/linux/usb.h | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-)