]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/linux/linux-4.14-Revert-usb-dwc2-Fix-DMA-alignment.patch
e4c8b99824bb3f3f16d121af301f16ce1759d136
[people/pmueller/ipfire-2.x.git] / src / patches / linux / linux-4.14-Revert-usb-dwc2-Fix-DMA-alignment.patch
1 From a44147a09baf8c46cc0b02332df3a4656e0659d5 Mon Sep 17 00:00:00 2001
2 From: Arne Fitzenreiter <arne_f@ipfire.org>
3 Date: Mon, 10 Dec 2018 13:12:00 +0100
4 Subject: [PATCH] Revert "usb: dwc2: Fix DMA alignment to start at allocated
5 boundary"
6
7 This reverts commit 68fc92a0f3913d539d1ac68a861f895e34099e46.
8 ---
9 drivers/usb/dwc2/hcd.c | 44 +++++++++++++++++++++-----------------------
10 1 file changed, 21 insertions(+), 23 deletions(-)
11
12 diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
13 index fa20ec4..4b81d08 100644
14 --- a/drivers/usb/dwc2/hcd.c
15 +++ b/drivers/usb/dwc2/hcd.c
16 @@ -2644,29 +2644,34 @@ static int dwc2_alloc_split_dma_aligned_buf(struct dwc2_hsotg *hsotg,
17
18 #define DWC2_USB_DMA_ALIGN 4
19
20 +struct dma_aligned_buffer {
21 + void *kmalloc_ptr;
22 + void *old_xfer_buffer;
23 + u8 data[0];
24 +};
25 +
26 static void dwc2_free_dma_aligned_buffer(struct urb *urb)
27 {
28 - void *stored_xfer_buffer;
29 + struct dma_aligned_buffer *temp;
30
31 if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER))
32 return;
33
34 - /* Restore urb->transfer_buffer from the end of the allocated area */
35 - memcpy(&stored_xfer_buffer, urb->transfer_buffer +
36 - urb->transfer_buffer_length, sizeof(urb->transfer_buffer));
37 + temp = container_of(urb->transfer_buffer,
38 + struct dma_aligned_buffer, data);
39
40 if (usb_urb_dir_in(urb))
41 - memcpy(stored_xfer_buffer, urb->transfer_buffer,
42 + memcpy(temp->old_xfer_buffer, temp->data,
43 urb->transfer_buffer_length);
44 - kfree(urb->transfer_buffer);
45 - urb->transfer_buffer = stored_xfer_buffer;
46 + urb->transfer_buffer = temp->old_xfer_buffer;
47 + kfree(temp->kmalloc_ptr);
48
49 urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER;
50 }
51
52 static int dwc2_alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags)
53 {
54 - void *kmalloc_ptr;
55 + struct dma_aligned_buffer *temp, *kmalloc_ptr;
56 size_t kmalloc_size;
57
58 if (urb->num_sgs || urb->sg ||
59 @@ -2674,29 +2679,22 @@ static int dwc2_alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags)
60 !((uintptr_t)urb->transfer_buffer & (DWC2_USB_DMA_ALIGN - 1)))
61 return 0;
62
63 - /*
64 - * Allocate a buffer with enough padding for original transfer_buffer
65 - * pointer. This allocation is guaranteed to be aligned properly for
66 - * DMA
67 - */
68 + /* Allocate a buffer with enough padding for alignment */
69 kmalloc_size = urb->transfer_buffer_length +
70 - sizeof(urb->transfer_buffer);
71 + sizeof(struct dma_aligned_buffer) + DWC2_USB_DMA_ALIGN - 1;
72
73 kmalloc_ptr = kmalloc(kmalloc_size, mem_flags);
74 if (!kmalloc_ptr)
75 return -ENOMEM;
76
77 - /*
78 - * Position value of original urb->transfer_buffer pointer to the end
79 - * of allocation for later referencing
80 - */
81 - memcpy(kmalloc_ptr + urb->transfer_buffer_length,
82 - &urb->transfer_buffer, sizeof(urb->transfer_buffer));
83 -
84 + /* Position our struct dma_aligned_buffer such that data is aligned */
85 + temp = PTR_ALIGN(kmalloc_ptr + 1, DWC2_USB_DMA_ALIGN) - 1;
86 + temp->kmalloc_ptr = kmalloc_ptr;
87 + temp->old_xfer_buffer = urb->transfer_buffer;
88 if (usb_urb_dir_out(urb))
89 - memcpy(kmalloc_ptr, urb->transfer_buffer,
90 + memcpy(temp->data, urb->transfer_buffer,
91 urb->transfer_buffer_length);
92 - urb->transfer_buffer = kmalloc_ptr;
93 + urb->transfer_buffer = temp->data;
94
95 urb->transfer_flags |= URB_ALIGNED_TEMP_BUFFER;
96
97 --
98 2.7.4
99