]>
Commit | Line | Data |
---|---|---|
c448474f AF |
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 |