Rev 846 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1049 | mauro | 1 | /* |
2 | * Copyright (c) 2001 by David Brownell |
||
3 | * |
||
4 | * This program is free software; you can redistribute it and/or modify it |
||
5 | * under the terms of the GNU General Public License as published by the |
||
6 | * Free Software Foundation; either version 2 of the License, or (at your |
||
7 | * option) any later version. |
||
8 | * |
||
9 | * This program is distributed in the hope that it will be useful, but |
||
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
||
11 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
||
12 | * for more details. |
||
13 | * |
||
14 | * You should have received a copy of the GNU General Public License |
||
15 | * along with this program; if not, write to the Free Software Foundation, |
||
16 | * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
||
17 | */ |
||
18 | |||
19 | /* this file is part of ehci-hcd.c */ |
||
20 | |||
21 | /*-------------------------------------------------------------------------*/ |
||
22 | |||
23 | /* |
||
24 | * There's basically three types of memory: |
||
25 | * - data used only by the HCD ... kmalloc is fine |
||
26 | * - async and periodic schedules, shared by HC and HCD ... these |
||
27 | * need to use pci_pool or pci_alloc_consistent_usb |
||
28 | * - driver buffers, read/written by HC ... single shot DMA mapped |
||
29 | * |
||
30 | * There's also PCI "register" data, which is memory mapped. |
||
31 | * No memory seen by this driver is pagable. |
||
32 | */ |
||
33 | |||
34 | /*-------------------------------------------------------------------------*/ |
||
35 | /* |
||
36 | * Allocator / cleanup for the per device structure |
||
37 | * Called by hcd init / removal code |
||
38 | */ |
||
39 | static struct usb_hcd *ehci_hcd_alloc (void) |
||
40 | { |
||
41 | struct ehci_hcd *ehci; |
||
42 | |||
43 | ehci = (struct ehci_hcd *) |
||
44 | kmalloc (sizeof (struct ehci_hcd), GFP_KERNEL); |
||
45 | if (ehci != 0) { |
||
46 | memset (ehci, 0, sizeof (struct ehci_hcd)); |
||
47 | ehci->hcd.product_desc = "EHCI Host Controller"; |
||
48 | return &ehci->hcd; |
||
49 | } |
||
50 | return 0; |
||
51 | } |
||
52 | |||
53 | static void ehci_hcd_free (struct usb_hcd *hcd) |
||
54 | { |
||
55 | kfree (hcd_to_ehci (hcd)); |
||
56 | } |
||
57 | |||
58 | /*-------------------------------------------------------------------------*/ |
||
59 | |||
60 | /* Allocate the key transfer structures from the previously allocated pool */ |
||
61 | |||
62 | static inline void ehci_qtd_init (struct ehci_qtd *qtd, dma_addr_t dma) |
||
63 | { |
||
64 | memset (qtd, 0, sizeof *qtd); |
||
65 | qtd->qtd_dma = dma; |
||
66 | qtd->hw_token = cpu_to_le32 (QTD_STS_HALT); |
||
67 | qtd->hw_next = EHCI_LIST_END; |
||
68 | qtd->hw_alt_next = EHCI_LIST_END; |
||
69 | INIT_LIST_HEAD (&qtd->qtd_list); |
||
70 | } |
||
71 | |||
72 | static struct ehci_qtd *ehci_qtd_alloc (struct ehci_hcd *ehci, int flags) |
||
73 | { |
||
74 | struct ehci_qtd *qtd; |
||
75 | dma_addr_t dma; |
||
76 | |||
77 | qtd = pci_pool_alloc_usb (ehci->qtd_pool, flags, &dma); |
||
78 | if (qtd != 0) { |
||
79 | ehci_qtd_init (qtd, dma); |
||
80 | } |
||
81 | return qtd; |
||
82 | } |
||
83 | |||
84 | static inline void ehci_qtd_free (struct ehci_hcd *ehci, struct ehci_qtd *qtd) |
||
85 | { |
||
86 | pci_pool_free (ehci->qtd_pool, qtd, qtd->qtd_dma); |
||
87 | } |
||
88 | |||
89 | |||
90 | static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, int flags) |
||
91 | { |
||
92 | struct ehci_qh *qh; |
||
93 | dma_addr_t dma; |
||
94 | |||
95 | qh = (struct ehci_qh *) |
||
96 | pci_pool_alloc_usb (ehci->qh_pool, flags, &dma); |
||
97 | if (!qh) |
||
98 | return qh; |
||
99 | |||
100 | memset (qh, 0, sizeof *qh); |
||
101 | atomic_set (&qh->refcount, 1); |
||
102 | qh->qh_dma = dma; |
||
103 | // INIT_LIST_HEAD (&qh->qh_list); |
||
104 | INIT_LIST_HEAD (&qh->qtd_list); |
||
105 | |||
106 | /* dummy td enables safe urb queuing */ |
||
107 | qh->dummy = ehci_qtd_alloc (ehci, flags); |
||
108 | if (qh->dummy == 0) { |
||
109 | ehci_dbg (ehci, "no dummy td\n"); |
||
110 | pci_pool_free (ehci->qh_pool, qh, qh->qh_dma); |
||
111 | qh = 0; |
||
112 | } |
||
113 | return qh; |
||
114 | } |
||
115 | |||
116 | /* to share a qh (cpu threads, or hc) */ |
||
117 | static inline struct ehci_qh *qh_get (/* ehci, */ struct ehci_qh *qh) |
||
118 | { |
||
119 | atomic_inc (&qh->refcount); |
||
120 | return qh; |
||
121 | } |
||
122 | |||
123 | static void qh_put (struct ehci_hcd *ehci, struct ehci_qh *qh) |
||
124 | { |
||
125 | if (!atomic_dec_and_test (&qh->refcount)) |
||
126 | return; |
||
127 | /* clean qtds first, and know this is not linked */ |
||
128 | if (!list_empty (&qh->qtd_list) || qh->qh_next.ptr) { |
||
129 | ehci_dbg (ehci, "unused qh not empty!\n"); |
||
130 | BUG (); |
||
131 | } |
||
132 | if (qh->dummy) |
||
133 | ehci_qtd_free (ehci, qh->dummy); |
||
134 | pci_pool_free (ehci->qh_pool, qh, qh->qh_dma); |
||
135 | } |
||
136 | |||
137 | /*-------------------------------------------------------------------------*/ |
||
138 | |||
139 | /* The queue heads and transfer descriptors are managed from pools tied |
||
140 | * to each of the "per device" structures. |
||
141 | * This is the initialisation and cleanup code. |
||
142 | */ |
||
143 | |||
144 | static void ehci_mem_cleanup (struct ehci_hcd *ehci) |
||
145 | { |
||
146 | if (ehci->async) |
||
147 | qh_put (ehci, ehci->async); |
||
148 | ehci->async = 0; |
||
149 | |||
150 | /* PCI consistent memory and pools */ |
||
151 | if (ehci->qtd_pool) |
||
152 | pci_pool_destroy (ehci->qtd_pool); |
||
153 | ehci->qtd_pool = 0; |
||
154 | |||
155 | if (ehci->qh_pool) { |
||
156 | pci_pool_destroy (ehci->qh_pool); |
||
157 | ehci->qh_pool = 0; |
||
158 | } |
||
159 | |||
160 | if (ehci->itd_pool) |
||
161 | pci_pool_destroy (ehci->itd_pool); |
||
162 | ehci->itd_pool = 0; |
||
163 | |||
164 | if (ehci->sitd_pool) |
||
165 | pci_pool_destroy (ehci->sitd_pool); |
||
166 | ehci->sitd_pool = 0; |
||
167 | |||
168 | if (ehci->periodic) |
||
169 | pci_free_consistent (ehci->hcd.pdev, |
||
170 | ehci->periodic_size * sizeof (u32), |
||
171 | ehci->periodic, ehci->periodic_dma); |
||
172 | ehci->periodic = 0; |
||
173 | |||
174 | /* shadow periodic table */ |
||
175 | if (ehci->pshadow) |
||
176 | kfree (ehci->pshadow); |
||
177 | ehci->pshadow = 0; |
||
178 | } |
||
179 | |||
180 | /* remember to add cleanup code (above) if you add anything here */ |
||
181 | static int ehci_mem_init (struct ehci_hcd *ehci, int flags) |
||
182 | { |
||
183 | int i; |
||
184 | |||
185 | /* QTDs for control/bulk/intr transfers */ |
||
186 | ehci->qtd_pool = pci_pool_create ("ehci_qtd", ehci->hcd.pdev, |
||
187 | sizeof (struct ehci_qtd), |
||
188 | 32 /* byte alignment (for hw parts) */, |
||
189 | 4096 /* can't cross 4K */); |
||
190 | if (!ehci->qtd_pool) { |
||
191 | goto fail; |
||
192 | } |
||
193 | |||
194 | /* QHs for control/bulk/intr transfers */ |
||
195 | ehci->qh_pool = pci_pool_create ("ehci_qh", ehci->hcd.pdev, |
||
196 | sizeof (struct ehci_qh), |
||
197 | 32 /* byte alignment (for hw parts) */, |
||
198 | 4096 /* can't cross 4K */); |
||
199 | if (!ehci->qh_pool) { |
||
200 | goto fail; |
||
201 | } |
||
202 | ehci->async = ehci_qh_alloc (ehci, flags); |
||
203 | if (!ehci->async) { |
||
204 | goto fail; |
||
205 | } |
||
206 | |||
207 | /* ITD for high speed ISO transfers */ |
||
208 | ehci->itd_pool = pci_pool_create ("ehci_itd", ehci->hcd.pdev, |
||
209 | sizeof (struct ehci_itd), |
||
210 | 32 /* byte alignment (for hw parts) */, |
||
211 | 4096 /* can't cross 4K */); |
||
212 | if (!ehci->itd_pool) { |
||
213 | goto fail; |
||
214 | } |
||
215 | |||
216 | /* SITD for full/low speed split ISO transfers */ |
||
217 | ehci->sitd_pool = pci_pool_create ("ehci_sitd", ehci->hcd.pdev, |
||
218 | sizeof (struct ehci_sitd), |
||
219 | 32 /* byte alignment (for hw parts) */, |
||
220 | 4096 /* can't cross 4K */); |
||
221 | if (!ehci->sitd_pool) { |
||
222 | goto fail; |
||
223 | } |
||
224 | |||
225 | /* Hardware periodic table */ |
||
226 | ehci->periodic = (u32 *) |
||
227 | pci_alloc_consistent_usb (ehci->hcd.pdev, |
||
228 | ehci->periodic_size * sizeof (u32), |
||
229 | &ehci->periodic_dma); |
||
230 | if (ehci->periodic == 0) { |
||
231 | goto fail; |
||
232 | } |
||
233 | for (i = 0; i < ehci->periodic_size; i++) |
||
234 | ehci->periodic [i] = EHCI_LIST_END; |
||
235 | |||
236 | /* software shadow of hardware table */ |
||
237 | ehci->pshadow = kmalloc (ehci->periodic_size * sizeof (void *), flags); |
||
238 | if (ehci->pshadow == 0) { |
||
239 | goto fail; |
||
240 | } |
||
241 | memset (ehci->pshadow, 0, ehci->periodic_size * sizeof (void *)); |
||
242 | |||
243 | return 0; |
||
244 | |||
245 | fail: |
||
246 | ehci_dbg (ehci, "couldn't init memory\n"); |
||
247 | ehci_mem_cleanup (ehci); |
||
248 | return -ENOMEM; |
||
249 | } |