From: Vincent Mailhol <mailhol.vincent@xxxxxxxxxx> 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. Co-developed-by: Vincent Mailhol <mailhol.vincent@xxxxxxxxxx> Signed-off-by: Vincent Mailhol <mailhol.vincent@xxxxxxxxxx> Co-developed-by: Rhett Aultman <rhett.aultman@xxxxxxxxxxx> Signed-off-by: Rhett Aultman <rhett.aultman@xxxxxxxxxxx> Reviewed-by: Vincent Mailhol <mailhol.vincent@xxxxxxxxxx> --- drivers/usb/core/urb.c | 5 ++++- include/linux/usb.h | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 33d62d7e3929..36c48fb196e0 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -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); } @@ -504,7 +507,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) /* Check against a simple/standard policy */ allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT | URB_DIR_MASK | - URB_FREE_BUFFER); + URB_FREE_BUFFER | URB_FREE_COHERENT); switch (xfertype) { case USB_ENDPOINT_XFER_BULK: case USB_ENDPOINT_XFER_INT: diff --git a/include/linux/usb.h b/include/linux/usb.h index 60bee864d897..945d68ea1d76 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -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 -- 2.30.2