diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 1a838c6d7d5af7..a029b72df899e7 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -2461,7 +2461,7 @@ static void dwc2_free_dma_aligned_buffer(struct urb *urb) /* Restore urb->transfer_buffer from the end of the allocated area */ memcpy(&stored_xfer_buffer, - PTR_ALIGN(urb->transfer_buffer + urb->transfer_buffer_length + DWC2_USB_DMA_ALIGN, + PTR_ALIGN(urb->transfer_buffer + urb->transfer_buffer_length, dma_get_cache_alignment()), sizeof(urb->transfer_buffer)); @@ -2484,36 +2484,17 @@ static int dwc2_alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags) void *kmalloc_ptr; size_t kmalloc_size; - if (urb->num_sgs || urb->sg || urb->transfer_buffer_length == 0) - return 0; - - /* - * Hardware bug: the core will only do DMA writes of full words - * in length, and DMA buffers must start at a word boundary. - * TODO: is this limited to BCM2835 and friends, or other core variants? - */ - if (!(usb_urb_dir_in(urb) && (urb->transfer_buffer_length & (DWC2_USB_DMA_ALIGN - 1))) && + if (urb->num_sgs || urb->sg || + urb->transfer_buffer_length == 0 || !((uintptr_t)urb->transfer_buffer & (DWC2_USB_DMA_ALIGN - 1))) return 0; - /* - * If the URB already has a DMA mapping, this alignment mechanism won't - * work - the replacement buffer won't be used by the core, as the HCD layer - * skips mapping. Mappings have the granularity of a page, so it's unlikely that the - * DMA length bug will cause data trampling. In any case, warn if there's a driver - * submitting unaligned mapped buffers. - */ - if (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) { - if (urb->transfer_dma & (DWC2_USB_DMA_ALIGN - 1)) - WARN_ONCE(1, "Unaligned DMA-mapped buffer"); - return 0; - } /* * Allocate a buffer with enough padding for original transfer_buffer * pointer. This allocation is guaranteed to be aligned properly for * DMA */ - kmalloc_size = urb->transfer_buffer_length + DWC2_USB_DMA_ALIGN + + kmalloc_size = urb->transfer_buffer_length + (dma_get_cache_alignment() - 1) + sizeof(urb->transfer_buffer); @@ -2525,7 +2506,7 @@ static int dwc2_alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags) * Position value of original urb->transfer_buffer pointer to the end * of allocation for later referencing */ - memcpy(PTR_ALIGN(kmalloc_ptr + urb->transfer_buffer_length + DWC2_USB_DMA_ALIGN, + memcpy(PTR_ALIGN(kmalloc_ptr + urb->transfer_buffer_length, dma_get_cache_alignment()), &urb->transfer_buffer, sizeof(urb->transfer_buffer));