1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* |
3 | * Copyright (c) 2001 by David Brownell |
4 | */ |
5 | |
6 | /* this file is part of ehci-hcd.c */ |
7 | |
8 | /*-------------------------------------------------------------------------*/ |
9 | |
10 | /* |
11 | * There's basically three types of memory: |
12 | * - data used only by the HCD ... kmalloc is fine |
13 | * - async and periodic schedules, shared by HC and HCD ... these |
14 | * need to use dma_pool or dma_alloc_coherent |
15 | * - driver buffers, read/written by HC ... single shot DMA mapped |
16 | * |
17 | * There's also "register" data (e.g. PCI or SOC), which is memory mapped. |
18 | * No memory seen by this driver is pageable. |
19 | */ |
20 | |
21 | /*-------------------------------------------------------------------------*/ |
22 | |
23 | /* Allocate the key transfer structures from the previously allocated pool */ |
24 | |
25 | static inline void ehci_qtd_init(struct ehci_hcd *ehci, struct ehci_qtd *qtd, |
26 | dma_addr_t dma) |
27 | { |
28 | memset (qtd, 0, sizeof *qtd); |
29 | qtd->qtd_dma = dma; |
30 | qtd->hw_token = cpu_to_hc32(ehci, QTD_STS_HALT); |
31 | qtd->hw_next = EHCI_LIST_END(ehci); |
32 | qtd->hw_alt_next = EHCI_LIST_END(ehci); |
33 | INIT_LIST_HEAD (list: &qtd->qtd_list); |
34 | } |
35 | |
36 | static struct ehci_qtd *ehci_qtd_alloc (struct ehci_hcd *ehci, gfp_t flags) |
37 | { |
38 | struct ehci_qtd *qtd; |
39 | dma_addr_t dma; |
40 | |
41 | qtd = dma_pool_alloc (pool: ehci->qtd_pool, mem_flags: flags, handle: &dma); |
42 | if (qtd != NULL) { |
43 | ehci_qtd_init(ehci, qtd, dma); |
44 | } |
45 | return qtd; |
46 | } |
47 | |
48 | static inline void ehci_qtd_free (struct ehci_hcd *ehci, struct ehci_qtd *qtd) |
49 | { |
50 | dma_pool_free (pool: ehci->qtd_pool, vaddr: qtd, addr: qtd->qtd_dma); |
51 | } |
52 | |
53 | |
54 | static void qh_destroy(struct ehci_hcd *ehci, struct ehci_qh *qh) |
55 | { |
56 | /* clean qtds first, and know this is not linked */ |
57 | if (!list_empty (head: &qh->qtd_list) || qh->qh_next.ptr) { |
58 | ehci_dbg (ehci, "unused qh not empty!\n" ); |
59 | BUG (); |
60 | } |
61 | if (qh->dummy) |
62 | ehci_qtd_free (ehci, qtd: qh->dummy); |
63 | dma_pool_free(pool: ehci->qh_pool, vaddr: qh->hw, addr: qh->qh_dma); |
64 | kfree(objp: qh); |
65 | } |
66 | |
67 | static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags) |
68 | { |
69 | struct ehci_qh *qh; |
70 | dma_addr_t dma; |
71 | |
72 | qh = kzalloc(size: sizeof *qh, GFP_ATOMIC); |
73 | if (!qh) |
74 | goto done; |
75 | qh->hw = (struct ehci_qh_hw *) |
76 | dma_pool_zalloc(pool: ehci->qh_pool, mem_flags: flags, handle: &dma); |
77 | if (!qh->hw) |
78 | goto fail; |
79 | qh->qh_dma = dma; |
80 | // INIT_LIST_HEAD (&qh->qh_list); |
81 | INIT_LIST_HEAD (list: &qh->qtd_list); |
82 | INIT_LIST_HEAD(list: &qh->unlink_node); |
83 | |
84 | /* dummy td enables safe urb queuing */ |
85 | qh->dummy = ehci_qtd_alloc (ehci, flags); |
86 | if (qh->dummy == NULL) { |
87 | ehci_dbg (ehci, "no dummy td\n" ); |
88 | goto fail1; |
89 | } |
90 | done: |
91 | return qh; |
92 | fail1: |
93 | dma_pool_free(pool: ehci->qh_pool, vaddr: qh->hw, addr: qh->qh_dma); |
94 | fail: |
95 | kfree(objp: qh); |
96 | return NULL; |
97 | } |
98 | |
99 | /*-------------------------------------------------------------------------*/ |
100 | |
101 | /* The queue heads and transfer descriptors are managed from pools tied |
102 | * to each of the "per device" structures. |
103 | * This is the initialisation and cleanup code. |
104 | */ |
105 | |
106 | static void ehci_mem_cleanup (struct ehci_hcd *ehci) |
107 | { |
108 | if (ehci->async) |
109 | qh_destroy(ehci, qh: ehci->async); |
110 | ehci->async = NULL; |
111 | |
112 | if (ehci->dummy) |
113 | qh_destroy(ehci, qh: ehci->dummy); |
114 | ehci->dummy = NULL; |
115 | |
116 | /* DMA consistent memory and pools */ |
117 | dma_pool_destroy(pool: ehci->qtd_pool); |
118 | ehci->qtd_pool = NULL; |
119 | dma_pool_destroy(pool: ehci->qh_pool); |
120 | ehci->qh_pool = NULL; |
121 | dma_pool_destroy(pool: ehci->itd_pool); |
122 | ehci->itd_pool = NULL; |
123 | dma_pool_destroy(pool: ehci->sitd_pool); |
124 | ehci->sitd_pool = NULL; |
125 | |
126 | if (ehci->periodic) |
127 | dma_free_coherent(dev: ehci_to_hcd(ehci)->self.sysdev, |
128 | size: ehci->periodic_size * sizeof (u32), |
129 | cpu_addr: ehci->periodic, dma_handle: ehci->periodic_dma); |
130 | ehci->periodic = NULL; |
131 | |
132 | /* shadow periodic table */ |
133 | kfree(objp: ehci->pshadow); |
134 | ehci->pshadow = NULL; |
135 | } |
136 | |
137 | /* remember to add cleanup code (above) if you add anything here */ |
138 | static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags) |
139 | { |
140 | int i; |
141 | |
142 | /* QTDs for control/bulk/intr transfers */ |
143 | ehci->qtd_pool = dma_pool_create (name: "ehci_qtd" , |
144 | dev: ehci_to_hcd(ehci)->self.sysdev, |
145 | size: sizeof (struct ehci_qtd), |
146 | align: 32 /* byte alignment (for hw parts) */, |
147 | allocation: 4096 /* can't cross 4K */); |
148 | if (!ehci->qtd_pool) { |
149 | goto fail; |
150 | } |
151 | |
152 | /* QHs for control/bulk/intr transfers */ |
153 | ehci->qh_pool = dma_pool_create (name: "ehci_qh" , |
154 | dev: ehci_to_hcd(ehci)->self.sysdev, |
155 | size: sizeof(struct ehci_qh_hw), |
156 | align: 32 /* byte alignment (for hw parts) */, |
157 | allocation: 4096 /* can't cross 4K */); |
158 | if (!ehci->qh_pool) { |
159 | goto fail; |
160 | } |
161 | ehci->async = ehci_qh_alloc (ehci, flags); |
162 | if (!ehci->async) { |
163 | goto fail; |
164 | } |
165 | |
166 | /* ITD for high speed ISO transfers */ |
167 | ehci->itd_pool = dma_pool_create (name: "ehci_itd" , |
168 | dev: ehci_to_hcd(ehci)->self.sysdev, |
169 | size: sizeof (struct ehci_itd), |
170 | align: 32 /* byte alignment (for hw parts) */, |
171 | allocation: 4096 /* can't cross 4K */); |
172 | if (!ehci->itd_pool) { |
173 | goto fail; |
174 | } |
175 | |
176 | /* SITD for full/low speed split ISO transfers */ |
177 | ehci->sitd_pool = dma_pool_create (name: "ehci_sitd" , |
178 | dev: ehci_to_hcd(ehci)->self.sysdev, |
179 | size: sizeof (struct ehci_sitd), |
180 | align: 32 /* byte alignment (for hw parts) */, |
181 | allocation: 4096 /* can't cross 4K */); |
182 | if (!ehci->sitd_pool) { |
183 | goto fail; |
184 | } |
185 | |
186 | /* Hardware periodic table */ |
187 | ehci->periodic = (__le32 *) |
188 | dma_alloc_coherent(dev: ehci_to_hcd(ehci)->self.sysdev, |
189 | size: ehci->periodic_size * sizeof(__le32), |
190 | dma_handle: &ehci->periodic_dma, gfp: flags); |
191 | if (ehci->periodic == NULL) { |
192 | goto fail; |
193 | } |
194 | |
195 | if (ehci->use_dummy_qh) { |
196 | struct ehci_qh_hw *hw; |
197 | ehci->dummy = ehci_qh_alloc(ehci, flags); |
198 | if (!ehci->dummy) |
199 | goto fail; |
200 | |
201 | hw = ehci->dummy->hw; |
202 | hw->hw_next = EHCI_LIST_END(ehci); |
203 | hw->hw_qtd_next = EHCI_LIST_END(ehci); |
204 | hw->hw_alt_next = EHCI_LIST_END(ehci); |
205 | ehci->dummy->hw = hw; |
206 | |
207 | for (i = 0; i < ehci->periodic_size; i++) |
208 | ehci->periodic[i] = cpu_to_hc32(ehci, |
209 | x: ehci->dummy->qh_dma); |
210 | } else { |
211 | for (i = 0; i < ehci->periodic_size; i++) |
212 | ehci->periodic[i] = EHCI_LIST_END(ehci); |
213 | } |
214 | |
215 | /* software shadow of hardware table */ |
216 | ehci->pshadow = kcalloc(n: ehci->periodic_size, size: sizeof(void *), flags); |
217 | if (ehci->pshadow != NULL) |
218 | return 0; |
219 | |
220 | fail: |
221 | ehci_dbg (ehci, "couldn't init memory\n" ); |
222 | ehci_mem_cleanup (ehci); |
223 | return -ENOMEM; |
224 | } |
225 | |