ohci.c revision 1.182.12.2 1 1.182.12.1 itohy /* $NetBSD: ohci.c,v 1.182.12.2 2007/05/31 23:15:17 itohy Exp $ */
2 1.1 augustss
3 1.182.12.1 itohy /*-
4 1.182.12.1 itohy * Copyright (c) 1998, 2004, 2005, 2007 The NetBSD Foundation, Inc.
5 1.1 augustss * All rights reserved.
6 1.1 augustss *
7 1.11 augustss * This code is derived from software contributed to The NetBSD Foundation
8 1.89 augustss * by Lennart Augustsson (lennart (at) augustsson.net) at
9 1.11 augustss * Carlstedt Research & Technology.
10 1.157 mycroft * This code is derived from software contributed to The NetBSD Foundation
11 1.157 mycroft * by Charles M. Hannum.
12 1.1 augustss *
13 1.1 augustss * Redistribution and use in source and binary forms, with or without
14 1.1 augustss * modification, are permitted provided that the following conditions
15 1.1 augustss * are met:
16 1.1 augustss * 1. Redistributions of source code must retain the above copyright
17 1.1 augustss * notice, this list of conditions and the following disclaimer.
18 1.1 augustss * 2. Redistributions in binary form must reproduce the above copyright
19 1.1 augustss * notice, this list of conditions and the following disclaimer in the
20 1.1 augustss * documentation and/or other materials provided with the distribution.
21 1.1 augustss * 3. All advertising materials mentioning features or use of this software
22 1.1 augustss * must display the following acknowledgement:
23 1.1 augustss * This product includes software developed by the NetBSD
24 1.1 augustss * Foundation, Inc. and its contributors.
25 1.1 augustss * 4. Neither the name of The NetBSD Foundation nor the names of its
26 1.1 augustss * contributors may be used to endorse or promote products derived
27 1.1 augustss * from this software without specific prior written permission.
28 1.1 augustss *
29 1.1 augustss * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
30 1.1 augustss * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
31 1.1 augustss * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
32 1.1 augustss * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
33 1.1 augustss * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34 1.1 augustss * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 1.1 augustss * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36 1.1 augustss * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
37 1.1 augustss * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 1.1 augustss * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 1.1 augustss * POSSIBILITY OF SUCH DAMAGE.
40 1.1 augustss */
41 1.1 augustss
42 1.1 augustss /*
43 1.1 augustss * USB Open Host Controller driver.
44 1.1 augustss *
45 1.96 augustss * OHCI spec: http://www.compaq.com/productinfo/development/openhci.html
46 1.182.12.1 itohy * USB spec: http://www.usb.org/developers/docs/
47 1.1 augustss */
48 1.108 lukem
49 1.108 lukem #include <sys/cdefs.h>
50 1.182.12.1 itohy __KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.182.12.2 2007/05/31 23:15:17 itohy Exp $");
51 1.182.12.1 itohy /* __FBSDID("$FreeBSD: src/sys/dev/usb/ohci.c,v 1.167 2006/10/19 01:15:58 iedowse Exp $"); */
52 1.1 augustss
53 1.1 augustss #include <sys/param.h>
54 1.1 augustss #include <sys/systm.h>
55 1.1 augustss #include <sys/malloc.h>
56 1.55 augustss #include <sys/kernel.h>
57 1.182.12.1 itohy #if defined(__NetBSD__) || defined(__OpenBSD__)
58 1.1 augustss #include <sys/device.h>
59 1.55 augustss #include <sys/select.h>
60 1.153 fvdl #include <uvm/uvm_extern.h>
61 1.15 augustss #elif defined(__FreeBSD__)
62 1.182.12.1 itohy #include <sys/endian.h>
63 1.15 augustss #include <sys/module.h>
64 1.15 augustss #include <sys/bus.h>
65 1.55 augustss #if defined(DIAGNOSTIC) && defined(__i386__) && defined(__FreeBSD__)
66 1.55 augustss #include <machine/cpu.h>
67 1.55 augustss #endif
68 1.15 augustss #endif
69 1.1 augustss #include <sys/proc.h>
70 1.1 augustss #include <sys/queue.h>
71 1.1 augustss
72 1.4 augustss #include <machine/bus.h>
73 1.16 augustss #include <machine/endian.h>
74 1.4 augustss
75 1.1 augustss #include <dev/usb/usb.h>
76 1.1 augustss #include <dev/usb/usbdi.h>
77 1.1 augustss #include <dev/usb/usbdivar.h>
78 1.38 augustss #include <dev/usb/usb_mem.h>
79 1.1 augustss #include <dev/usb/usb_quirks.h>
80 1.1 augustss
81 1.1 augustss #include <dev/usb/ohcireg.h>
82 1.1 augustss #include <dev/usb/ohcivar.h>
83 1.1 augustss
84 1.15 augustss #if defined(__FreeBSD__)
85 1.182.12.1 itohy #include <sys/sysctl.h>
86 1.55 augustss
87 1.15 augustss #define delay(d) DELAY(d)
88 1.15 augustss #endif
89 1.1 augustss
90 1.36 augustss #if defined(__OpenBSD__)
91 1.36 augustss struct cfdriver ohci_cd = {
92 1.36 augustss NULL, "ohci", DV_DULL
93 1.36 augustss };
94 1.36 augustss #endif
95 1.36 augustss
96 1.182.12.1 itohy #ifdef USB_DEBUG
97 1.52 augustss #define DPRINTF(x) if (ohcidebug) logprintf x
98 1.52 augustss #define DPRINTFN(n,x) if (ohcidebug>(n)) logprintf x
99 1.52 augustss int ohcidebug = 0;
100 1.182.12.1 itohy #ifdef __FreeBSD__
101 1.182.12.1 itohy SYSCTL_NODE(_hw_usb, OID_AUTO, ohci, CTLFLAG_RW, 0, "USB ohci");
102 1.182.12.1 itohy SYSCTL_INT(_hw_usb_ohci, OID_AUTO, debug, CTLFLAG_RW,
103 1.182.12.1 itohy &ohcidebug, 0, "ohci debug level");
104 1.182.12.1 itohy #endif
105 1.92 tv #ifndef __NetBSD__
106 1.92 tv #define bitmask_snprintf(q,f,b,l) snprintf((b), (l), "%b", (q), (f))
107 1.92 tv #endif
108 1.52 augustss #else
109 1.52 augustss #define DPRINTF(x)
110 1.52 augustss #define DPRINTFN(n,x)
111 1.52 augustss #endif
112 1.52 augustss
113 1.182.12.1 itohy /*
114 1.182.12.1 itohy * The OHCI controller is either little endian or host endian,
115 1.182.12.1 itohy * so on big endian machines with little endian controller
116 1.182.12.1 itohy * the data strored in memory needs to be swapped.
117 1.182.12.1 itohy */
118 1.182.12.1 itohy #define O16TOH(val) (sc->sc_endian ? (val) : le16toh(val))
119 1.182.12.1 itohy #define O32TOH(val) (sc->sc_endian ? (val) : le32toh(val))
120 1.182.12.1 itohy #define HTOO16(val) (sc->sc_endian ? (val) : htole16(val))
121 1.182.12.1 itohy #define HTOO32(val) (sc->sc_endian ? (val) : htole32(val))
122 1.168 augustss
123 1.1 augustss struct ohci_pipe;
124 1.1 augustss
125 1.182.12.1 itohy Static void ohci_free_desc_chunks(ohci_softc_t *,
126 1.182.12.1 itohy struct ohci_mdescs *);
127 1.91 augustss Static ohci_soft_ed_t *ohci_alloc_sed(ohci_softc_t *);
128 1.91 augustss Static void ohci_free_sed(ohci_softc_t *, ohci_soft_ed_t *);
129 1.1 augustss
130 1.182.12.1 itohy Static usbd_status ohci_grow_std(ohci_softc_t *);
131 1.91 augustss Static ohci_soft_td_t *ohci_alloc_std(ohci_softc_t *);
132 1.182.12.1 itohy Static ohci_soft_td_t *ohci_alloc_std_norsv(ohci_softc_t *);
133 1.91 augustss Static void ohci_free_std(ohci_softc_t *, ohci_soft_td_t *);
134 1.182.12.1 itohy Static void ohci_free_std_norsv(ohci_softc_t *, ohci_soft_td_t *);
135 1.1 augustss
136 1.182.12.1 itohy Static usbd_status ohci_grow_sitd(ohci_softc_t *);
137 1.91 augustss Static ohci_soft_itd_t *ohci_alloc_sitd(ohci_softc_t *);
138 1.182.12.1 itohy Static ohci_soft_itd_t *ohci_alloc_sitd_norsv(ohci_softc_t *);
139 1.91 augustss Static void ohci_free_sitd(ohci_softc_t *,ohci_soft_itd_t *);
140 1.182.12.1 itohy Static void ohci_free_sitd_norsv(ohci_softc_t *,ohci_soft_itd_t *);
141 1.60 augustss
142 1.91 augustss Static void ohci_free_std_chain(ohci_softc_t *, ohci_soft_td_t *,
143 1.91 augustss ohci_soft_td_t *);
144 1.91 augustss Static usbd_status ohci_alloc_std_chain(struct ohci_pipe *,
145 1.77 augustss ohci_softc_t *, int, int, usbd_xfer_handle,
146 1.91 augustss ohci_soft_td_t *, ohci_soft_td_t **);
147 1.53 augustss
148 1.91 augustss Static usbd_status ohci_open(usbd_pipe_handle);
149 1.91 augustss Static void ohci_poll(struct usbd_bus *);
150 1.99 augustss Static void ohci_softintr(void *);
151 1.91 augustss Static void ohci_waitintr(ohci_softc_t *, usbd_xfer_handle);
152 1.91 augustss Static void ohci_rhsc(ohci_softc_t *, usbd_xfer_handle);
153 1.91 augustss
154 1.91 augustss Static usbd_status ohci_device_request(usbd_xfer_handle xfer);
155 1.168 augustss Static void ohci_add_ed(ohci_softc_t *, ohci_soft_ed_t *,
156 1.168 augustss ohci_soft_ed_t *);
157 1.168 augustss
158 1.91 augustss Static void ohci_rem_ed(ohci_soft_ed_t *, ohci_soft_ed_t *);
159 1.182.12.1 itohy Static ohci_soft_td_t *ohci_find_td(ohci_softc_t *, ohci_physaddr_t);
160 1.182.12.1 itohy Static ohci_soft_itd_t *ohci_find_itd(ohci_softc_t *, ohci_physaddr_t);
161 1.91 augustss
162 1.91 augustss Static usbd_status ohci_setup_isoc(usbd_pipe_handle pipe);
163 1.91 augustss Static void ohci_device_isoc_enter(usbd_xfer_handle);
164 1.91 augustss
165 1.182.12.1 itohy Static usbd_status ohci_prealloc(struct ohci_softc *,
166 1.182.12.1 itohy struct ohci_xfer *, size_t, int);
167 1.182.12.1 itohy Static usbd_status ohci_allocm(struct usbd_bus *, usbd_xfer_handle,
168 1.182.12.1 itohy void *buf, size_t);
169 1.182.12.1 itohy Static void ohci_freem(struct usbd_bus *, usbd_xfer_handle,
170 1.182.12.1 itohy enum usbd_waitflg);
171 1.182.12.1 itohy
172 1.182.12.1 itohy Static usbd_status ohci_map_alloc(usbd_xfer_handle);
173 1.182.12.1 itohy Static void ohci_map_free(usbd_xfer_handle);
174 1.182.12.1 itohy Static void ohci_mapm(usbd_xfer_handle, void *, size_t);
175 1.182.12.2 itohy Static usbd_status ohci_mapm_mbuf(usbd_xfer_handle, struct mbuf *);
176 1.182.12.1 itohy Static void ohci_unmapm(usbd_xfer_handle);
177 1.91 augustss
178 1.182.12.1 itohy Static usbd_xfer_handle ohci_allocx(struct usbd_bus *, usbd_pipe_handle,
179 1.182.12.1 itohy enum usbd_waitflg);
180 1.91 augustss Static void ohci_freex(struct usbd_bus *, usbd_xfer_handle);
181 1.91 augustss
182 1.91 augustss Static usbd_status ohci_root_ctrl_transfer(usbd_xfer_handle);
183 1.91 augustss Static usbd_status ohci_root_ctrl_start(usbd_xfer_handle);
184 1.91 augustss Static void ohci_root_ctrl_abort(usbd_xfer_handle);
185 1.91 augustss Static void ohci_root_ctrl_close(usbd_pipe_handle);
186 1.91 augustss Static void ohci_root_ctrl_done(usbd_xfer_handle);
187 1.91 augustss
188 1.91 augustss Static usbd_status ohci_root_intr_transfer(usbd_xfer_handle);
189 1.91 augustss Static usbd_status ohci_root_intr_start(usbd_xfer_handle);
190 1.91 augustss Static void ohci_root_intr_abort(usbd_xfer_handle);
191 1.91 augustss Static void ohci_root_intr_close(usbd_pipe_handle);
192 1.91 augustss Static void ohci_root_intr_done(usbd_xfer_handle);
193 1.91 augustss
194 1.91 augustss Static usbd_status ohci_device_ctrl_transfer(usbd_xfer_handle);
195 1.91 augustss Static usbd_status ohci_device_ctrl_start(usbd_xfer_handle);
196 1.91 augustss Static void ohci_device_ctrl_abort(usbd_xfer_handle);
197 1.91 augustss Static void ohci_device_ctrl_close(usbd_pipe_handle);
198 1.91 augustss Static void ohci_device_ctrl_done(usbd_xfer_handle);
199 1.91 augustss
200 1.91 augustss Static usbd_status ohci_device_bulk_transfer(usbd_xfer_handle);
201 1.91 augustss Static usbd_status ohci_device_bulk_start(usbd_xfer_handle);
202 1.91 augustss Static void ohci_device_bulk_abort(usbd_xfer_handle);
203 1.91 augustss Static void ohci_device_bulk_close(usbd_pipe_handle);
204 1.91 augustss Static void ohci_device_bulk_done(usbd_xfer_handle);
205 1.91 augustss
206 1.91 augustss Static usbd_status ohci_device_intr_transfer(usbd_xfer_handle);
207 1.91 augustss Static usbd_status ohci_device_intr_start(usbd_xfer_handle);
208 1.91 augustss Static void ohci_device_intr_abort(usbd_xfer_handle);
209 1.91 augustss Static void ohci_device_intr_close(usbd_pipe_handle);
210 1.91 augustss Static void ohci_device_intr_done(usbd_xfer_handle);
211 1.91 augustss
212 1.91 augustss Static usbd_status ohci_device_isoc_transfer(usbd_xfer_handle);
213 1.91 augustss Static usbd_status ohci_device_isoc_start(usbd_xfer_handle);
214 1.91 augustss Static void ohci_device_isoc_abort(usbd_xfer_handle);
215 1.91 augustss Static void ohci_device_isoc_close(usbd_pipe_handle);
216 1.91 augustss Static void ohci_device_isoc_done(usbd_xfer_handle);
217 1.91 augustss
218 1.120 augustss Static usbd_status ohci_device_setintr(ohci_softc_t *sc,
219 1.91 augustss struct ohci_pipe *pipe, int ival);
220 1.182.12.1 itohy Static usbd_status ohci_device_intr_insert(ohci_softc_t *sc,
221 1.182.12.1 itohy usbd_xfer_handle xfer);
222 1.91 augustss
223 1.120 augustss Static int ohci_str(usb_string_descriptor_t *, int, const char *);
224 1.91 augustss
225 1.91 augustss Static void ohci_timeout(void *);
226 1.114 augustss Static void ohci_timeout_task(void *);
227 1.104 augustss Static void ohci_rhsc_enable(void *);
228 1.91 augustss
229 1.91 augustss Static void ohci_close_pipe(usbd_pipe_handle, ohci_soft_ed_t *);
230 1.91 augustss Static void ohci_abort_xfer(usbd_xfer_handle, usbd_status);
231 1.53 augustss
232 1.91 augustss Static void ohci_device_clear_toggle(usbd_pipe_handle pipe);
233 1.91 augustss Static void ohci_noop(usbd_pipe_handle pipe);
234 1.37 augustss
235 1.182.12.1 itohy Static usbd_status ohci_controller_init(ohci_softc_t *sc);
236 1.182.12.1 itohy
237 1.182.12.1 itohy #ifdef USB_DEBUG
238 1.91 augustss Static void ohci_dumpregs(ohci_softc_t *);
239 1.168 augustss Static void ohci_dump_tds(ohci_softc_t *, ohci_soft_td_t *);
240 1.168 augustss Static void ohci_dump_td(ohci_softc_t *, ohci_soft_td_t *);
241 1.168 augustss Static void ohci_dump_ed(ohci_softc_t *, ohci_soft_ed_t *);
242 1.168 augustss Static void ohci_dump_itd(ohci_softc_t *, ohci_soft_itd_t *);
243 1.168 augustss Static void ohci_dump_itds(ohci_softc_t *, ohci_soft_itd_t *);
244 1.1 augustss #endif
245 1.1 augustss
246 1.88 augustss #define OBARR(sc) bus_space_barrier((sc)->iot, (sc)->ioh, 0, (sc)->sc_size, \
247 1.88 augustss BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE)
248 1.88 augustss #define OWRITE1(sc, r, x) \
249 1.88 augustss do { OBARR(sc); bus_space_write_1((sc)->iot, (sc)->ioh, (r), (x)); } while (0)
250 1.88 augustss #define OWRITE2(sc, r, x) \
251 1.88 augustss do { OBARR(sc); bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x)); } while (0)
252 1.88 augustss #define OWRITE4(sc, r, x) \
253 1.88 augustss do { OBARR(sc); bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x)); } while (0)
254 1.174 mrg static __inline uint8_t
255 1.174 mrg OREAD1(ohci_softc_t *sc, bus_size_t r)
256 1.174 mrg {
257 1.174 mrg
258 1.174 mrg OBARR(sc);
259 1.174 mrg return bus_space_read_1(sc->iot, sc->ioh, r);
260 1.174 mrg }
261 1.174 mrg
262 1.174 mrg static __inline uint16_t
263 1.174 mrg OREAD2(ohci_softc_t *sc, bus_size_t r)
264 1.174 mrg {
265 1.174 mrg
266 1.174 mrg OBARR(sc);
267 1.174 mrg return bus_space_read_2(sc->iot, sc->ioh, r);
268 1.174 mrg }
269 1.174 mrg
270 1.174 mrg static __inline uint32_t
271 1.174 mrg OREAD4(ohci_softc_t *sc, bus_size_t r)
272 1.174 mrg {
273 1.174 mrg
274 1.174 mrg OBARR(sc);
275 1.174 mrg return bus_space_read_4(sc->iot, sc->ioh, r);
276 1.174 mrg }
277 1.1 augustss
278 1.1 augustss /* Reverse the bits in a value 0 .. 31 */
279 1.120 augustss Static u_int8_t revbits[OHCI_NO_INTRS] =
280 1.1 augustss { 0x00, 0x10, 0x08, 0x18, 0x04, 0x14, 0x0c, 0x1c,
281 1.1 augustss 0x02, 0x12, 0x0a, 0x1a, 0x06, 0x16, 0x0e, 0x1e,
282 1.1 augustss 0x01, 0x11, 0x09, 0x19, 0x05, 0x15, 0x0d, 0x1d,
283 1.1 augustss 0x03, 0x13, 0x0b, 0x1b, 0x07, 0x17, 0x0f, 0x1f };
284 1.1 augustss
285 1.1 augustss struct ohci_pipe {
286 1.1 augustss struct usbd_pipe pipe;
287 1.1 augustss ohci_soft_ed_t *sed;
288 1.182.12.1 itohy u_int32_t aborting;
289 1.60 augustss union {
290 1.60 augustss ohci_soft_td_t *td;
291 1.60 augustss ohci_soft_itd_t *itd;
292 1.60 augustss } tail;
293 1.1 augustss /* Info needed for different pipe kinds. */
294 1.1 augustss union {
295 1.1 augustss /* Control pipe */
296 1.1 augustss struct {
297 1.4 augustss usb_dma_t reqdma;
298 1.1 augustss u_int length;
299 1.48 augustss ohci_soft_td_t *setup, *data, *stat;
300 1.1 augustss } ctl;
301 1.1 augustss /* Interrupt pipe */
302 1.1 augustss struct {
303 1.1 augustss int nslots;
304 1.1 augustss int pos;
305 1.1 augustss } intr;
306 1.3 augustss /* Bulk pipe */
307 1.3 augustss struct {
308 1.3 augustss u_int length;
309 1.32 augustss int isread;
310 1.3 augustss } bulk;
311 1.43 augustss /* Iso pipe */
312 1.43 augustss struct iso {
313 1.60 augustss int next, inuse;
314 1.43 augustss } iso;
315 1.1 augustss } u;
316 1.1 augustss };
317 1.1 augustss
318 1.1 augustss #define OHCI_INTR_ENDPT 1
319 1.1 augustss
320 1.182 drochner Static const struct usbd_bus_methods ohci_bus_methods = {
321 1.42 augustss ohci_open,
322 1.73 augustss ohci_softintr,
323 1.42 augustss ohci_poll,
324 1.42 augustss ohci_allocm,
325 1.42 augustss ohci_freem,
326 1.182.12.1 itohy ohci_map_alloc,
327 1.182.12.1 itohy ohci_map_free,
328 1.182.12.1 itohy ohci_mapm,
329 1.182.12.1 itohy ohci_mapm_mbuf,
330 1.182.12.1 itohy ohci_unmapm,
331 1.62 augustss ohci_allocx,
332 1.62 augustss ohci_freex,
333 1.42 augustss };
334 1.42 augustss
335 1.182 drochner Static const struct usbd_pipe_methods ohci_root_ctrl_methods = {
336 1.1 augustss ohci_root_ctrl_transfer,
337 1.17 augustss ohci_root_ctrl_start,
338 1.1 augustss ohci_root_ctrl_abort,
339 1.1 augustss ohci_root_ctrl_close,
340 1.37 augustss ohci_noop,
341 1.65 augustss ohci_root_ctrl_done,
342 1.1 augustss };
343 1.1 augustss
344 1.182 drochner Static const struct usbd_pipe_methods ohci_root_intr_methods = {
345 1.1 augustss ohci_root_intr_transfer,
346 1.17 augustss ohci_root_intr_start,
347 1.1 augustss ohci_root_intr_abort,
348 1.1 augustss ohci_root_intr_close,
349 1.37 augustss ohci_noop,
350 1.38 augustss ohci_root_intr_done,
351 1.1 augustss };
352 1.1 augustss
353 1.182 drochner Static const struct usbd_pipe_methods ohci_device_ctrl_methods = {
354 1.1 augustss ohci_device_ctrl_transfer,
355 1.17 augustss ohci_device_ctrl_start,
356 1.1 augustss ohci_device_ctrl_abort,
357 1.1 augustss ohci_device_ctrl_close,
358 1.37 augustss ohci_noop,
359 1.38 augustss ohci_device_ctrl_done,
360 1.1 augustss };
361 1.1 augustss
362 1.182 drochner Static const struct usbd_pipe_methods ohci_device_intr_methods = {
363 1.1 augustss ohci_device_intr_transfer,
364 1.17 augustss ohci_device_intr_start,
365 1.1 augustss ohci_device_intr_abort,
366 1.1 augustss ohci_device_intr_close,
367 1.37 augustss ohci_device_clear_toggle,
368 1.38 augustss ohci_device_intr_done,
369 1.1 augustss };
370 1.1 augustss
371 1.182 drochner Static const struct usbd_pipe_methods ohci_device_bulk_methods = {
372 1.3 augustss ohci_device_bulk_transfer,
373 1.17 augustss ohci_device_bulk_start,
374 1.3 augustss ohci_device_bulk_abort,
375 1.3 augustss ohci_device_bulk_close,
376 1.37 augustss ohci_device_clear_toggle,
377 1.38 augustss ohci_device_bulk_done,
378 1.3 augustss };
379 1.3 augustss
380 1.182 drochner Static const struct usbd_pipe_methods ohci_device_isoc_methods = {
381 1.43 augustss ohci_device_isoc_transfer,
382 1.43 augustss ohci_device_isoc_start,
383 1.43 augustss ohci_device_isoc_abort,
384 1.43 augustss ohci_device_isoc_close,
385 1.43 augustss ohci_noop,
386 1.43 augustss ohci_device_isoc_done,
387 1.43 augustss };
388 1.43 augustss
389 1.55 augustss #if defined(__NetBSD__) || defined(__OpenBSD__)
390 1.47 augustss int
391 1.182.12.1 itohy ohci_activate(device_t self, enum devact act)
392 1.47 augustss {
393 1.49 augustss struct ohci_softc *sc = (struct ohci_softc *)self;
394 1.47 augustss int rv = 0;
395 1.47 augustss
396 1.47 augustss switch (act) {
397 1.47 augustss case DVACT_ACTIVATE:
398 1.47 augustss return (EOPNOTSUPP);
399 1.47 augustss
400 1.47 augustss case DVACT_DEACTIVATE:
401 1.49 augustss if (sc->sc_child != NULL)
402 1.49 augustss rv = config_deactivate(sc->sc_child);
403 1.83 augustss sc->sc_dying = 1;
404 1.47 augustss break;
405 1.47 augustss }
406 1.47 augustss return (rv);
407 1.47 augustss }
408 1.182.12.1 itohy #endif
409 1.47 augustss
410 1.47 augustss int
411 1.91 augustss ohci_detach(struct ohci_softc *sc, int flags)
412 1.47 augustss {
413 1.47 augustss int rv = 0;
414 1.182.12.1 itohy usbd_xfer_handle xfer;
415 1.47 augustss
416 1.182.12.1 itohy sc->sc_dying = 1;
417 1.182.12.1 itohy
418 1.182.12.1 itohy #if defined(__NetBSD__) || defined(__OpenBSD__)
419 1.47 augustss if (sc->sc_child != NULL)
420 1.47 augustss rv = config_detach(sc->sc_child, flags);
421 1.120 augustss
422 1.47 augustss if (rv != 0)
423 1.47 augustss return (rv);
424 1.182.12.1 itohy #endif
425 1.182.12.1 itohy
426 1.182.12.1 itohy if (sc->sc_bus.methods == NULL)
427 1.182.12.1 itohy return (rv); /* attach has been aborted */
428 1.47 augustss
429 1.104 augustss usb_uncallout(sc->sc_tmo_rhsc, ohci_rhsc_enable, sc);
430 1.104 augustss
431 1.71 augustss #if defined(__NetBSD__) || defined(__OpenBSD__)
432 1.47 augustss powerhook_disestablish(sc->sc_powerhook);
433 1.59 augustss shutdownhook_disestablish(sc->sc_shutdownhook);
434 1.71 augustss #endif
435 1.59 augustss
436 1.182.12.1 itohy #if defined(__NetBSD__) || defined(__OpenBSD__)
437 1.182.12.1 itohy /* Don't touch hardware if it has already been gone. */
438 1.182.12.1 itohy if ((flags & DETACH_FORCE) == 0)
439 1.182.12.1 itohy #endif
440 1.182.12.1 itohy {
441 1.182.12.1 itohy OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS);
442 1.182.12.1 itohy OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
443 1.182.12.1 itohy }
444 1.182.12.1 itohy
445 1.116 augustss usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */
446 1.116 augustss
447 1.182.12.1 itohy #if 0 /* freed by ohci_free_desc_chunks(sc, &sc->sc_sed_chunks) below */
448 1.182.12.1 itohy for (i = 0; i < OHCI_NO_EDS; i++)
449 1.182.12.1 itohy ohci_free_sed(sc, sc->sc_eds[i]);
450 1.182.12.1 itohy ohci_free_sed(sc, sc->sc_isoc_head);
451 1.182.12.1 itohy ohci_free_sed(sc, sc->sc_bulk_head);
452 1.182.12.1 itohy ohci_free_sed(sc, sc->sc_ctrl_head);
453 1.182.12.1 itohy #endif
454 1.182.12.1 itohy usb_freemem(&sc->sc_dmatag, &sc->sc_hccadma);
455 1.182.12.1 itohy
456 1.182.12.1 itohy while ((xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers)) != NULL) {
457 1.182.12.1 itohy SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
458 1.182.12.1 itohy usb_clean_buffer_dma(&sc->sc_dmatag, &OXFER(xfer)->dmabuf);
459 1.182.12.1 itohy free(xfer, M_USB);
460 1.182.12.1 itohy }
461 1.182.12.1 itohy ohci_free_desc_chunks(sc, &sc->sc_sed_chunks);
462 1.182.12.1 itohy ohci_free_desc_chunks(sc, &sc->sc_std_chunks);
463 1.182.12.1 itohy ohci_free_desc_chunks(sc, &sc->sc_sitd_chunks);
464 1.182.12.1 itohy usb_dma_tag_finish(&sc->sc_dmatag);
465 1.47 augustss
466 1.47 augustss return (rv);
467 1.47 augustss }
468 1.182.12.1 itohy
469 1.182.12.1 itohy Static void
470 1.182.12.1 itohy ohci_free_desc_chunks(ohci_softc_t *sc, struct ohci_mdescs *c)
471 1.182.12.1 itohy {
472 1.182.12.1 itohy struct ohci_mem_desc *om;
473 1.182.12.1 itohy
474 1.182.12.1 itohy while ((om = SIMPLEQ_FIRST(c)) != NULL) {
475 1.182.12.1 itohy SIMPLEQ_REMOVE_HEAD(c, om_next);
476 1.182.12.1 itohy usb_freemem(&sc->sc_dmatag, &om->om_dma);
477 1.182.12.1 itohy }
478 1.182.12.1 itohy }
479 1.47 augustss
480 1.1 augustss ohci_soft_ed_t *
481 1.91 augustss ohci_alloc_sed(ohci_softc_t *sc)
482 1.1 augustss {
483 1.1 augustss ohci_soft_ed_t *sed;
484 1.53 augustss usbd_status err;
485 1.1 augustss int i, offs;
486 1.4 augustss usb_dma_t dma;
487 1.182.12.1 itohy struct ohci_mem_desc *om;
488 1.1 augustss
489 1.53 augustss if (sc->sc_freeeds == NULL) {
490 1.1 augustss DPRINTFN(2, ("ohci_alloc_sed: allocating chunk\n"));
491 1.182.12.1 itohy err = usb_allocmem(&sc->sc_dmatag,
492 1.182.12.1 itohy OHCI_SED_SIZE*OHCI_SED_CHUNK + sizeof(struct ohci_mem_desc),
493 1.182.12.1 itohy OHCI_ED_ALIGN, &dma);
494 1.53 augustss if (err)
495 1.182.12.1 itohy return (NULL);
496 1.182.12.1 itohy om = KERNADDR(&dma, OHCI_SED_SIZE * OHCI_SED_CHUNK);
497 1.182.12.1 itohy om->om_top = KERNADDR(&dma, 0);
498 1.182.12.1 itohy om->om_topdma = DMAADDR(&dma, 0);
499 1.182.12.1 itohy om->om_dma = dma;
500 1.182.12.1 itohy SIMPLEQ_INSERT_HEAD(&sc->sc_sed_chunks, om, om_next);
501 1.39 augustss for(i = 0; i < OHCI_SED_CHUNK; i++) {
502 1.39 augustss offs = i * OHCI_SED_SIZE;
503 1.123 augustss sed = KERNADDR(&dma, offs);
504 1.182.12.1 itohy sed->oe_mdesc = om;
505 1.1 augustss sed->next = sc->sc_freeeds;
506 1.1 augustss sc->sc_freeeds = sed;
507 1.1 augustss }
508 1.1 augustss }
509 1.1 augustss sed = sc->sc_freeeds;
510 1.1 augustss sc->sc_freeeds = sed->next;
511 1.39 augustss memset(&sed->ed, 0, sizeof(ohci_ed_t));
512 1.1 augustss sed->next = 0;
513 1.39 augustss return (sed);
514 1.1 augustss }
515 1.1 augustss
516 1.1 augustss void
517 1.91 augustss ohci_free_sed(ohci_softc_t *sc, ohci_soft_ed_t *sed)
518 1.1 augustss {
519 1.1 augustss sed->next = sc->sc_freeeds;
520 1.1 augustss sc->sc_freeeds = sed;
521 1.1 augustss }
522 1.1 augustss
523 1.182.12.1 itohy Static usbd_status
524 1.182.12.1 itohy ohci_grow_std(ohci_softc_t *sc)
525 1.1 augustss {
526 1.182.12.1 itohy usb_dma_t dma;
527 1.182.12.1 itohy struct ohci_mem_desc *om;
528 1.1 augustss ohci_soft_td_t *std;
529 1.53 augustss usbd_status err;
530 1.182.12.1 itohy int i, s, offs;
531 1.1 augustss
532 1.182.12.1 itohy DPRINTFN(2, ("ohci_grow_std: allocating chunk\n"));
533 1.182.12.1 itohy err = usb_allocmem(&sc->sc_dmatag,
534 1.182.12.1 itohy OHCI_STD_SIZE*OHCI_STD_CHUNK + sizeof(struct ohci_mem_desc),
535 1.182.12.1 itohy OHCI_TD_ALIGN, &dma);
536 1.182.12.1 itohy if (err)
537 1.182.12.1 itohy return (err);
538 1.182.12.1 itohy om = KERNADDR(&dma, OHCI_STD_SIZE * OHCI_STD_CHUNK);
539 1.182.12.1 itohy om->om_top = KERNADDR(&dma, 0);
540 1.182.12.1 itohy om->om_topdma = DMAADDR(&dma, 0);
541 1.182.12.1 itohy om->om_dma = dma;
542 1.182.12.1 itohy s = splusb();
543 1.182.12.1 itohy SIMPLEQ_INSERT_HEAD(&sc->sc_std_chunks, om, om_next);
544 1.182.12.1 itohy for(i = 0; i < OHCI_STD_CHUNK; i++) {
545 1.182.12.1 itohy offs = i * OHCI_STD_SIZE;
546 1.182.12.1 itohy std = KERNADDR(&dma, offs);
547 1.182.12.1 itohy std->ot_mdesc = om;
548 1.182.12.1 itohy std->nexttd = sc->sc_freetds;
549 1.182.12.1 itohy sc->sc_freetds = std;
550 1.182.12.1 itohy sc->sc_nfreetds++;
551 1.1 augustss }
552 1.182.12.1 itohy splx(s);
553 1.182.12.1 itohy
554 1.182.12.1 itohy return (USBD_NORMAL_COMPLETION);
555 1.182.12.1 itohy }
556 1.182.12.1 itohy
557 1.182.12.1 itohy ohci_soft_td_t *
558 1.182.12.1 itohy ohci_alloc_std(ohci_softc_t *sc)
559 1.182.12.1 itohy {
560 1.182.12.1 itohy ohci_soft_td_t *std;
561 1.182.12.1 itohy int s;
562 1.69 augustss
563 1.69 augustss s = splusb();
564 1.182.12.1 itohy
565 1.182.12.1 itohy #ifdef DIAGNOSTIC
566 1.182.12.1 itohy if (sc->sc_freetds == NULL)
567 1.182.12.1 itohy panic("ohci_alloc_std: %d", sc->sc_nfreetds);
568 1.182.12.1 itohy #endif
569 1.1 augustss std = sc->sc_freetds;
570 1.1 augustss sc->sc_freetds = std->nexttd;
571 1.182.12.1 itohy splx(s);
572 1.39 augustss memset(&std->td, 0, sizeof(ohci_td_t));
573 1.83 augustss std->nexttd = NULL;
574 1.83 augustss std->xfer = NULL;
575 1.182.12.1 itohy std->flags = 0;
576 1.69 augustss
577 1.1 augustss return (std);
578 1.1 augustss }
579 1.1 augustss
580 1.182.12.1 itohy Static ohci_soft_td_t *
581 1.182.12.1 itohy ohci_alloc_std_norsv(ohci_softc_t *sc)
582 1.182.12.1 itohy {
583 1.182.12.1 itohy int s;
584 1.182.12.1 itohy
585 1.182.12.1 itohy s = splusb();
586 1.182.12.1 itohy if (sc->sc_nfreetds < 1)
587 1.182.12.1 itohy if (ohci_grow_std(sc))
588 1.182.12.1 itohy return (NULL);
589 1.182.12.1 itohy sc->sc_nfreetds--;
590 1.182.12.1 itohy splx(s);
591 1.182.12.1 itohy return (ohci_alloc_std(sc));
592 1.182.12.1 itohy }
593 1.182.12.1 itohy
594 1.1 augustss void
595 1.91 augustss ohci_free_std(ohci_softc_t *sc, ohci_soft_td_t *std)
596 1.1 augustss {
597 1.69 augustss int s;
598 1.69 augustss
599 1.69 augustss s = splusb();
600 1.182.12.1 itohy std->flags = OHCI_TD_FREE;
601 1.1 augustss std->nexttd = sc->sc_freetds;
602 1.1 augustss sc->sc_freetds = std;
603 1.69 augustss splx(s);
604 1.1 augustss }
605 1.1 augustss
606 1.182.12.1 itohy Static void
607 1.182.12.1 itohy ohci_free_std_norsv(ohci_softc_t *sc, ohci_soft_td_t *std)
608 1.182.12.1 itohy {
609 1.182.12.1 itohy int s;
610 1.182.12.1 itohy
611 1.182.12.1 itohy ohci_free_std(sc, std);
612 1.182.12.1 itohy s = splusb();
613 1.182.12.1 itohy sc->sc_nfreetds++;
614 1.182.12.1 itohy splx(s);
615 1.182.12.1 itohy }
616 1.182.12.1 itohy
617 1.1 augustss usbd_status
618 1.91 augustss ohci_alloc_std_chain(struct ohci_pipe *opipe, ohci_softc_t *sc,
619 1.91 augustss int alen, int rd, usbd_xfer_handle xfer,
620 1.91 augustss ohci_soft_td_t *sp, ohci_soft_td_t **ep)
621 1.48 augustss {
622 1.182.12.1 itohy ohci_soft_td_t *next, *cur, *end;
623 1.182.12.1 itohy ohci_physaddr_t tddma, segdmaadr, dmaend;
624 1.77 augustss u_int32_t tdflags;
625 1.182.12.1 itohy int len, maxp, curlen, seg, seglen;
626 1.182.12.1 itohy struct usb_buffer_dma *ub = &OXFER(xfer)->dmabuf;
627 1.182.12.1 itohy bus_dma_segment_t *segs = USB_BUFFER_SEGS(ub);
628 1.182.12.1 itohy int nsegs = USB_BUFFER_NSEGS(ub);
629 1.77 augustss u_int16_t flags = xfer->flags;
630 1.48 augustss
631 1.75 augustss DPRINTFN(alen < 4096,("ohci_alloc_std_chain: start len=%d\n", alen));
632 1.75 augustss
633 1.75 augustss len = alen;
634 1.48 augustss cur = sp;
635 1.182.12.1 itohy end = NULL;
636 1.182.12.1 itohy
637 1.182.12.1 itohy maxp = UE_MAXPKTSZ(opipe->pipe.endpoint->edesc);
638 1.168 augustss tdflags = HTOO32(
639 1.120 augustss (rd ? OHCI_TD_IN : OHCI_TD_OUT) |
640 1.77 augustss (flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0) |
641 1.182.12.1 itohy OHCI_TD_NOCC | OHCI_TD_TOGGLE_CARRY | OHCI_TD_SET_DI(6));
642 1.182.12.1 itohy
643 1.182.12.1 itohy seg = 0;
644 1.182.12.1 itohy seglen = 0;
645 1.182.12.1 itohy segdmaadr = 0;
646 1.182.12.1 itohy while (len > 0) {
647 1.182.12.1 itohy /* sync last entry */
648 1.182.12.1 itohy if (end)
649 1.182.12.1 itohy OHCI_STD_SYNC(sc, end,
650 1.182.12.1 itohy BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
651 1.61 augustss
652 1.48 augustss next = ohci_alloc_std(sc);
653 1.75 augustss if (next == NULL)
654 1.61 augustss goto nomem;
655 1.48 augustss
656 1.182.12.1 itohy /*
657 1.182.12.1 itohy * The OHCI hardware can handle at most one 4K crossing.
658 1.182.12.1 itohy * The OHCI spec says: If during the data transfer the buffer
659 1.182.12.1 itohy * address contained in the HC's working copy of
660 1.182.12.1 itohy * CurrentBufferPointer crosses a 4K boundary, the upper 20
661 1.182.12.1 itohy * bits of Buffer End are copied to the working value of
662 1.182.12.1 itohy * CurrentBufferPointer causing the next buffer address to
663 1.182.12.1 itohy * be the 0th byte in the same 4K page that contains the
664 1.182.12.1 itohy * last byte of the buffer (the 4K boundary crossing may
665 1.182.12.1 itohy * occur within a data packet transfer.)
666 1.182.12.1 itohy */
667 1.182.12.1 itohy
668 1.182.12.1 itohy /* gather segments that are continuous in DMA address */
669 1.182.12.1 itohy /* XXX Does this make any sense? */
670 1.182.12.1 itohy if (seglen == 0) {
671 1.182.12.1 itohy USB_KASSERT2(seg < nsegs,
672 1.182.12.1 itohy ("ohci_alloc_std_chain: overrun"));
673 1.182.12.1 itohy segdmaadr = segs[seg].ds_addr;
674 1.182.12.1 itohy do {
675 1.182.12.1 itohy seglen += segs[seg].ds_len;
676 1.182.12.1 itohy } while (++seg < nsegs &&
677 1.182.12.1 itohy segdmaadr + seglen == segs[seg].ds_addr);
678 1.182.12.1 itohy
679 1.182.12.1 itohy if (seglen > len)
680 1.182.12.1 itohy seglen = len;
681 1.182.12.1 itohy }
682 1.182.12.1 itohy
683 1.182.12.1 itohy curlen = seglen;
684 1.182.12.1 itohy dmaend = segdmaadr + curlen;
685 1.182.12.1 itohy if ((sc->sc_flags & OHCI_FLAG_QUIRK_2ND_4KB) == 0)
686 1.182.12.1 itohy dmaend--;
687 1.182.12.1 itohy dmaend = OHCI_PAGE(dmaend);
688 1.182.12.1 itohy
689 1.182.12.1 itohy if (OHCI_PAGE(segdmaadr) != dmaend &&
690 1.182.12.1 itohy OHCI_PAGE(segdmaadr) + OHCI_PAGE_SIZE != dmaend) {
691 1.48 augustss /* must use multiple TDs, fill as much as possible. */
692 1.120 augustss curlen = 2 * OHCI_PAGE_SIZE -
693 1.182.12.1 itohy (segdmaadr & (OHCI_PAGE_SIZE-1));
694 1.182.12.1 itohy
695 1.182.12.1 itohy if (sc->sc_flags & OHCI_FLAG_QUIRK_2ND_4KB)
696 1.182.12.1 itohy curlen--;
697 1.182.12.1 itohy
698 1.78 augustss /* the length must be a multiple of the max size */
699 1.182.12.1 itohy if (curlen < len)
700 1.182.12.1 itohy curlen -= curlen % maxp;
701 1.182.12.1 itohy USB_KASSERT(curlen);
702 1.182.12.1 itohy USB_KASSERT2(curlen <= seglen,
703 1.182.12.1 itohy ("ohci_alloc_std_chain: curlen %d > seglen %d",
704 1.182.12.1 itohy curlen, len));
705 1.182.12.1 itohy }
706 1.182.12.1 itohy DPRINTFN(4,("ohci_alloc_std_chain: segdmaadr=0x%08x "
707 1.182.12.1 itohy "dmaend=0x%08x len=%d seglen=%d curlen=%d\n",
708 1.182.12.1 itohy segdmaadr, dmaend,
709 1.182.12.1 itohy len, seglen, curlen));
710 1.48 augustss len -= curlen;
711 1.48 augustss
712 1.77 augustss cur->td.td_flags = tdflags;
713 1.182.12.1 itohy cur->td.td_cbp = HTOO32(segdmaadr);
714 1.48 augustss cur->nexttd = next;
715 1.182.12.1 itohy tddma = OHCI_STD_DMAADDR(next);
716 1.182.12.1 itohy cur->td.td_nexttd = HTOO32(tddma);
717 1.182.12.1 itohy cur->td.td_be = HTOO32(segdmaadr + curlen - 1);
718 1.48 augustss cur->len = curlen;
719 1.48 augustss cur->flags = OHCI_ADD_LEN;
720 1.77 augustss cur->xfer = xfer;
721 1.48 augustss DPRINTFN(10,("ohci_alloc_std_chain: cbp=0x%08x be=0x%08x\n",
722 1.182.12.1 itohy segdmaadr, segdmaadr + curlen - 1));
723 1.48 augustss DPRINTFN(10,("ohci_alloc_std_chain: extend chain\n"));
724 1.182.12.1 itohy seglen -= curlen;
725 1.182.12.1 itohy segdmaadr += curlen;
726 1.182.12.1 itohy
727 1.182.12.1 itohy end = cur;
728 1.48 augustss cur = next;
729 1.48 augustss }
730 1.182.12.1 itohy if (((flags & USBD_FORCE_SHORT_XFER) || alen == 0) &&
731 1.182.12.1 itohy alen % maxp == 0) {
732 1.182.12.1 itohy if (end)
733 1.182.12.1 itohy OHCI_STD_SYNC(sc, end,
734 1.182.12.1 itohy BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
735 1.75 augustss
736 1.182.12.1 itohy /* Force a 0 length transfer at the end. */
737 1.61 augustss next = ohci_alloc_std(sc);
738 1.75 augustss if (next == NULL)
739 1.61 augustss goto nomem;
740 1.61 augustss
741 1.77 augustss cur->td.td_flags = tdflags;
742 1.61 augustss cur->td.td_cbp = 0; /* indicate 0 length packet */
743 1.61 augustss cur->nexttd = next;
744 1.182.12.1 itohy tddma = OHCI_STD_DMAADDR(next);
745 1.182.12.1 itohy cur->td.td_nexttd = HTOO32(tddma);
746 1.75 augustss cur->td.td_be = ~0;
747 1.61 augustss cur->len = 0;
748 1.61 augustss cur->flags = 0;
749 1.77 augustss cur->xfer = xfer;
750 1.61 augustss DPRINTFN(2,("ohci_alloc_std_chain: add 0 xfer\n"));
751 1.182.12.1 itohy end = cur;
752 1.61 augustss }
753 1.182.12.1 itohy *ep = end;
754 1.48 augustss
755 1.48 augustss return (USBD_NORMAL_COMPLETION);
756 1.61 augustss
757 1.61 augustss nomem:
758 1.182.12.1 itohy /* free chain */
759 1.182.12.1 itohy if (end)
760 1.182.12.1 itohy ohci_free_std_chain(sc, sp->nexttd, end);
761 1.61 augustss return (USBD_NOMEM);
762 1.48 augustss }
763 1.48 augustss
764 1.82 augustss Static void
765 1.120 augustss ohci_free_std_chain(ohci_softc_t *sc, ohci_soft_td_t *std,
766 1.91 augustss ohci_soft_td_t *stdend)
767 1.48 augustss {
768 1.48 augustss ohci_soft_td_t *p;
769 1.48 augustss
770 1.48 augustss for (; std != stdend; std = p) {
771 1.48 augustss p = std->nexttd;
772 1.48 augustss ohci_free_std(sc, std);
773 1.48 augustss }
774 1.182.12.1 itohy ohci_free_std(sc, stdend);
775 1.48 augustss }
776 1.48 augustss
777 1.182.12.1 itohy Static usbd_status
778 1.182.12.1 itohy ohci_grow_sitd(ohci_softc_t *sc)
779 1.60 augustss {
780 1.182.12.1 itohy usb_dma_t dma;
781 1.182.12.1 itohy struct ohci_mem_desc *om;
782 1.60 augustss ohci_soft_itd_t *sitd;
783 1.60 augustss usbd_status err;
784 1.83 augustss int i, s, offs;
785 1.60 augustss
786 1.182.12.1 itohy DPRINTFN(2, ("ohci_alloc_sitd: allocating chunk\n"));
787 1.182.12.1 itohy err = usb_allocmem(&sc->sc_dmatag,
788 1.182.12.1 itohy OHCI_SITD_SIZE*OHCI_SITD_CHUNK + sizeof(struct ohci_mem_desc),
789 1.182.12.1 itohy OHCI_ITD_ALIGN, &dma);
790 1.182.12.1 itohy if (err)
791 1.182.12.1 itohy return (err);
792 1.182.12.1 itohy om = KERNADDR(&dma, OHCI_SITD_SIZE * OHCI_SITD_CHUNK);
793 1.182.12.1 itohy om->om_top = KERNADDR(&dma, 0);
794 1.182.12.1 itohy om->om_topdma = DMAADDR(&dma, 0);
795 1.182.12.1 itohy om->om_dma = dma;
796 1.182.12.1 itohy s = splusb();
797 1.182.12.1 itohy SIMPLEQ_INSERT_HEAD(&sc->sc_sitd_chunks, om, om_next);
798 1.182.12.1 itohy for(i = 0; i < OHCI_SITD_CHUNK; i++) {
799 1.182.12.1 itohy offs = i * OHCI_SITD_SIZE;
800 1.182.12.1 itohy sitd = KERNADDR(&dma, offs);
801 1.182.12.1 itohy sitd->oit_mdesc = om;
802 1.182.12.1 itohy sitd->nextitd = sc->sc_freeitds;
803 1.182.12.1 itohy sc->sc_freeitds = sitd;
804 1.182.12.1 itohy sc->sc_nfreeitds++;
805 1.60 augustss }
806 1.182.12.1 itohy splx(s);
807 1.182.12.1 itohy
808 1.182.12.1 itohy return (USBD_NORMAL_COMPLETION);
809 1.182.12.1 itohy }
810 1.182.12.1 itohy
811 1.182.12.1 itohy ohci_soft_itd_t *
812 1.182.12.1 itohy ohci_alloc_sitd(ohci_softc_t *sc)
813 1.182.12.1 itohy {
814 1.182.12.1 itohy ohci_soft_itd_t *sitd;
815 1.182.12.1 itohy int s;
816 1.182.12.1 itohy
817 1.182.12.1 itohy #ifdef DIAGNOSTIC
818 1.182.12.1 itohy if (sc->sc_freeitds == NULL)
819 1.182.12.1 itohy panic("ohci_alloc_sitd: %d", sc->sc_nfreeitds);
820 1.182.12.1 itohy #endif
821 1.83 augustss
822 1.83 augustss s = splusb();
823 1.60 augustss sitd = sc->sc_freeitds;
824 1.60 augustss sc->sc_freeitds = sitd->nextitd;
825 1.60 augustss memset(&sitd->itd, 0, sizeof(ohci_itd_t));
826 1.83 augustss sitd->nextitd = NULL;
827 1.83 augustss sitd->xfer = NULL;
828 1.182.12.1 itohy sitd->flags = 0;
829 1.83 augustss splx(s);
830 1.83 augustss
831 1.83 augustss #ifdef DIAGNOSTIC
832 1.83 augustss sitd->isdone = 0;
833 1.83 augustss #endif
834 1.83 augustss
835 1.60 augustss return (sitd);
836 1.60 augustss }
837 1.60 augustss
838 1.182.12.1 itohy Static ohci_soft_itd_t *
839 1.182.12.1 itohy ohci_alloc_sitd_norsv(ohci_softc_t *sc)
840 1.182.12.1 itohy {
841 1.182.12.1 itohy int s;
842 1.182.12.1 itohy
843 1.182.12.1 itohy s = splusb();
844 1.182.12.1 itohy if (sc->sc_nfreeitds < 1)
845 1.182.12.1 itohy if (ohci_grow_sitd(sc))
846 1.182.12.1 itohy return (NULL);
847 1.182.12.1 itohy sc->sc_nfreeitds--;
848 1.182.12.1 itohy splx(s);
849 1.182.12.1 itohy return (ohci_alloc_sitd_norsv(sc));
850 1.182.12.1 itohy }
851 1.182.12.1 itohy
852 1.60 augustss void
853 1.91 augustss ohci_free_sitd(ohci_softc_t *sc, ohci_soft_itd_t *sitd)
854 1.60 augustss {
855 1.83 augustss int s;
856 1.83 augustss
857 1.83 augustss DPRINTFN(10,("ohci_free_sitd: sitd=%p\n", sitd));
858 1.83 augustss
859 1.83 augustss #ifdef DIAGNOSTIC
860 1.83 augustss if (!sitd->isdone) {
861 1.128 provos panic("ohci_free_sitd: sitd=%p not done", sitd);
862 1.83 augustss return;
863 1.83 augustss }
864 1.134 toshii /* Warn double free */
865 1.134 toshii sitd->isdone = 0;
866 1.83 augustss #endif
867 1.83 augustss
868 1.83 augustss s = splusb();
869 1.182.12.1 itohy sitd->flags = OHCI_ITD_FREE;
870 1.60 augustss sitd->nextitd = sc->sc_freeitds;
871 1.60 augustss sc->sc_freeitds = sitd;
872 1.83 augustss splx(s);
873 1.60 augustss }
874 1.60 augustss
875 1.182.12.1 itohy Static void
876 1.182.12.1 itohy ohci_free_sitd_norsv(ohci_softc_t *sc, ohci_soft_itd_t *sitd)
877 1.182.12.1 itohy {
878 1.182.12.1 itohy int s;
879 1.182.12.1 itohy
880 1.182.12.1 itohy ohci_free_sitd(sc, sitd);
881 1.182.12.1 itohy s = splusb();
882 1.182.12.1 itohy sc->sc_nfreeitds++;
883 1.182.12.1 itohy splx(s);
884 1.182.12.1 itohy }
885 1.182.12.1 itohy
886 1.48 augustss usbd_status
887 1.91 augustss ohci_init(ohci_softc_t *sc)
888 1.1 augustss {
889 1.1 augustss ohci_soft_ed_t *sed, *psed;
890 1.182.12.1 itohy ohci_physaddr_t eddma;
891 1.53 augustss usbd_status err;
892 1.1 augustss int i;
893 1.182.12.1 itohy u_int32_t rev;
894 1.16 augustss
895 1.1 augustss DPRINTF(("ohci_init: start\n"));
896 1.36 augustss #if defined(__OpenBSD__)
897 1.55 augustss printf(",");
898 1.36 augustss #else
899 1.55 augustss printf("%s:", USBDEVNAME(sc->sc_bus.bdev));
900 1.36 augustss #endif
901 1.56 augustss rev = OREAD4(sc, OHCI_REVISION);
902 1.55 augustss printf(" OHCI version %d.%d%s\n", OHCI_REV_HI(rev), OHCI_REV_LO(rev),
903 1.1 augustss OHCI_REV_LEGACY(rev) ? ", legacy support" : "");
904 1.55 augustss
905 1.1 augustss if (OHCI_REV_HI(rev) != 1 || OHCI_REV_LO(rev) != 0) {
906 1.120 augustss printf("%s: unsupported OHCI revision\n",
907 1.15 augustss USBDEVNAME(sc->sc_bus.bdev));
908 1.56 augustss sc->sc_bus.usbrev = USBREV_UNKNOWN;
909 1.1 augustss return (USBD_INVAL);
910 1.1 augustss }
911 1.56 augustss sc->sc_bus.usbrev = USBREV_1_0;
912 1.1 augustss
913 1.62 augustss SIMPLEQ_INIT(&sc->sc_free_xfers);
914 1.182.12.1 itohy SIMPLEQ_INIT(&sc->sc_sed_chunks);
915 1.182.12.1 itohy SIMPLEQ_INIT(&sc->sc_std_chunks);
916 1.182.12.1 itohy SIMPLEQ_INIT(&sc->sc_sitd_chunks);
917 1.62 augustss
918 1.182.12.1 itohy usb_dma_tag_init(&sc->sc_dmatag);
919 1.153 fvdl
920 1.73 augustss /* XXX determine alignment by R/W */
921 1.1 augustss /* Allocate the HCCA area. */
922 1.182.12.1 itohy err = usb_allocmem(&sc->sc_dmatag, OHCI_HCCA_SIZE,
923 1.4 augustss OHCI_HCCA_ALIGN, &sc->sc_hccadma);
924 1.53 augustss if (err)
925 1.182.12.1 itohy goto bad1;
926 1.123 augustss sc->sc_hcca = KERNADDR(&sc->sc_hccadma, 0);
927 1.1 augustss memset(sc->sc_hcca, 0, OHCI_HCCA_SIZE);
928 1.1 augustss
929 1.1 augustss sc->sc_eintrs = OHCI_NORMAL_INTRS;
930 1.1 augustss
931 1.60 augustss /* Allocate dummy ED that starts the control list. */
932 1.1 augustss sc->sc_ctrl_head = ohci_alloc_sed(sc);
933 1.53 augustss if (sc->sc_ctrl_head == NULL) {
934 1.53 augustss err = USBD_NOMEM;
935 1.182.12.1 itohy goto bad2;
936 1.1 augustss }
937 1.168 augustss sc->sc_ctrl_head->ed.ed_flags |= HTOO32(OHCI_ED_SKIP);
938 1.34 augustss
939 1.60 augustss /* Allocate dummy ED that starts the bulk list. */
940 1.1 augustss sc->sc_bulk_head = ohci_alloc_sed(sc);
941 1.53 augustss if (sc->sc_bulk_head == NULL) {
942 1.53 augustss err = USBD_NOMEM;
943 1.182.12.1 itohy goto bad3;
944 1.1 augustss }
945 1.168 augustss sc->sc_bulk_head->ed.ed_flags |= HTOO32(OHCI_ED_SKIP);
946 1.1 augustss
947 1.60 augustss /* Allocate dummy ED that starts the isochronous list. */
948 1.60 augustss sc->sc_isoc_head = ohci_alloc_sed(sc);
949 1.60 augustss if (sc->sc_isoc_head == NULL) {
950 1.60 augustss err = USBD_NOMEM;
951 1.60 augustss goto bad3;
952 1.60 augustss }
953 1.168 augustss sc->sc_isoc_head->ed.ed_flags |= HTOO32(OHCI_ED_SKIP);
954 1.60 augustss
955 1.1 augustss /* Allocate all the dummy EDs that make up the interrupt tree. */
956 1.1 augustss for (i = 0; i < OHCI_NO_EDS; i++) {
957 1.1 augustss sed = ohci_alloc_sed(sc);
958 1.53 augustss if (sed == NULL) {
959 1.1 augustss while (--i >= 0)
960 1.1 augustss ohci_free_sed(sc, sc->sc_eds[i]);
961 1.53 augustss err = USBD_NOMEM;
962 1.182.12.1 itohy goto bad3;
963 1.1 augustss }
964 1.1 augustss /* All ED fields are set to 0. */
965 1.1 augustss sc->sc_eds[i] = sed;
966 1.168 augustss sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP);
967 1.60 augustss if (i != 0)
968 1.1 augustss psed = sc->sc_eds[(i-1) / 2];
969 1.60 augustss else
970 1.182.12.1 itohy psed = sc->sc_isoc_head;
971 1.60 augustss sed->next = psed;
972 1.182.12.1 itohy eddma = OHCI_SED_DMAADDR(psed);
973 1.182.12.1 itohy sed->ed.ed_nexted = HTOO32(eddma);
974 1.1 augustss }
975 1.120 augustss /*
976 1.1 augustss * Fill HCCA interrupt table. The bit reversal is to get
977 1.1 augustss * the tree set up properly to spread the interrupts.
978 1.1 augustss */
979 1.182.12.1 itohy for (i = 0; i < OHCI_NO_INTRS; i++) {
980 1.182.12.1 itohy eddma = OHCI_SED_DMAADDR(sc->sc_eds[OHCI_NO_EDS-OHCI_NO_INTRS+i]);
981 1.182.12.1 itohy sc->sc_hcca->hcca_interrupt_table[revbits[i]] = HTOO32(eddma);
982 1.182.12.1 itohy }
983 1.1 augustss
984 1.182.12.1 itohy #ifdef USB_DEBUG
985 1.73 augustss if (ohcidebug > 15) {
986 1.73 augustss for (i = 0; i < OHCI_NO_EDS; i++) {
987 1.73 augustss printf("ed#%d ", i);
988 1.168 augustss ohci_dump_ed(sc, sc->sc_eds[i]);
989 1.73 augustss }
990 1.73 augustss printf("iso ");
991 1.168 augustss ohci_dump_ed(sc, sc->sc_isoc_head);
992 1.73 augustss }
993 1.73 augustss #endif
994 1.73 augustss
995 1.182.12.1 itohy err = ohci_controller_init(sc);
996 1.182.12.1 itohy if (err != USBD_NORMAL_COMPLETION)
997 1.182.12.1 itohy goto bad3;
998 1.182.12.1 itohy
999 1.182.12.1 itohy /* Set up the bus struct. */
1000 1.182.12.1 itohy sc->sc_bus.methods = &ohci_bus_methods;
1001 1.182.12.1 itohy sc->sc_bus.pipe_size = sizeof(struct ohci_pipe);
1002 1.182.12.1 itohy
1003 1.182.12.1 itohy #if defined(__NetBSD__) || defined(__OpenBSD__)
1004 1.182.12.1 itohy sc->sc_control = sc->sc_intre = 0;
1005 1.182.12.1 itohy sc->sc_powerhook = powerhook_establish(USBDEVNAME(sc->sc_bus.bdev),
1006 1.182.12.1 itohy ohci_power, sc);
1007 1.182.12.1 itohy sc->sc_shutdownhook = shutdownhook_establish(ohci_shutdown, sc);
1008 1.182.12.1 itohy #endif
1009 1.182.12.1 itohy
1010 1.182.12.1 itohy usb_callout_init(sc->sc_tmo_rhsc);
1011 1.182.12.1 itohy
1012 1.182.12.1 itohy /* Finally, turn on interrupts. */
1013 1.182.12.1 itohy DPRINTFN(1,("ohci_init: enabling\n"));
1014 1.182.12.1 itohy OWRITE4(sc, OHCI_INTERRUPT_ENABLE, sc->sc_eintrs | OHCI_MIE);
1015 1.182.12.1 itohy
1016 1.182.12.1 itohy return (USBD_NORMAL_COMPLETION);
1017 1.182.12.1 itohy
1018 1.182.12.1 itohy bad3:
1019 1.182.12.1 itohy ohci_free_desc_chunks(sc, &sc->sc_sed_chunks);
1020 1.182.12.1 itohy bad2:
1021 1.182.12.1 itohy usb_freemem(&sc->sc_dmatag, &sc->sc_hccadma);
1022 1.182.12.1 itohy bad1:
1023 1.182.12.1 itohy usb_dma_tag_finish(&sc->sc_dmatag);
1024 1.182.12.1 itohy return (err);
1025 1.182.12.1 itohy }
1026 1.182.12.1 itohy
1027 1.182.12.1 itohy Static usbd_status
1028 1.182.12.1 itohy ohci_controller_init(ohci_softc_t *sc)
1029 1.182.12.1 itohy {
1030 1.182.12.1 itohy int i;
1031 1.182.12.1 itohy u_int32_t s, ctl, rwc, ival, hcr, fm, per, desca, descb;
1032 1.182.12.1 itohy
1033 1.161 augustss /* Preserve values programmed by SMM/BIOS but lost over reset. */
1034 1.161 augustss ctl = OREAD4(sc, OHCI_CONTROL);
1035 1.161 augustss rwc = ctl & OHCI_RWC;
1036 1.161 augustss fm = OREAD4(sc, OHCI_FM_INTERVAL);
1037 1.161 augustss desca = OREAD4(sc, OHCI_RH_DESCRIPTOR_A);
1038 1.161 augustss descb = OREAD4(sc, OHCI_RH_DESCRIPTOR_B);
1039 1.161 augustss
1040 1.1 augustss /* Determine in what context we are running. */
1041 1.1 augustss if (ctl & OHCI_IR) {
1042 1.1 augustss /* SMM active, request change */
1043 1.1 augustss DPRINTF(("ohci_init: SMM active, request owner change\n"));
1044 1.160 augustss if ((sc->sc_intre & (OHCI_OC | OHCI_MIE)) ==
1045 1.160 augustss (OHCI_OC | OHCI_MIE))
1046 1.160 augustss OWRITE4(sc, OHCI_INTERRUPT_ENABLE, OHCI_MIE);
1047 1.1 augustss s = OREAD4(sc, OHCI_COMMAND_STATUS);
1048 1.1 augustss OWRITE4(sc, OHCI_COMMAND_STATUS, s | OHCI_OCR);
1049 1.1 augustss for (i = 0; i < 100 && (ctl & OHCI_IR); i++) {
1050 1.53 augustss usb_delay_ms(&sc->sc_bus, 1);
1051 1.1 augustss ctl = OREAD4(sc, OHCI_CONTROL);
1052 1.1 augustss }
1053 1.160 augustss OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_MIE);
1054 1.1 augustss if ((ctl & OHCI_IR) == 0) {
1055 1.15 augustss printf("%s: SMM does not respond, resetting\n",
1056 1.15 augustss USBDEVNAME(sc->sc_bus.bdev));
1057 1.161 augustss OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET | rwc);
1058 1.1 augustss goto reset;
1059 1.1 augustss }
1060 1.103 augustss #if 0
1061 1.103 augustss /* Don't bother trying to reuse the BIOS init, we'll reset it anyway. */
1062 1.1 augustss } else if ((ctl & OHCI_HCFS_MASK) != OHCI_HCFS_RESET) {
1063 1.1 augustss /* BIOS started controller. */
1064 1.1 augustss DPRINTF(("ohci_init: BIOS active\n"));
1065 1.1 augustss if ((ctl & OHCI_HCFS_MASK) != OHCI_HCFS_OPERATIONAL) {
1066 1.161 augustss OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_OPERATIONAL | rwc);
1067 1.53 augustss usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY);
1068 1.1 augustss }
1069 1.103 augustss #endif
1070 1.1 augustss } else {
1071 1.1 augustss DPRINTF(("ohci_init: cold started\n"));
1072 1.1 augustss reset:
1073 1.1 augustss /* Controller was cold started. */
1074 1.53 augustss usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY);
1075 1.1 augustss }
1076 1.1 augustss
1077 1.16 augustss /*
1078 1.25 augustss * This reset should not be necessary according to the OHCI spec, but
1079 1.25 augustss * without it some controllers do not start.
1080 1.16 augustss */
1081 1.16 augustss DPRINTF(("%s: resetting\n", USBDEVNAME(sc->sc_bus.bdev)));
1082 1.161 augustss OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET | rwc);
1083 1.55 augustss usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY);
1084 1.16 augustss
1085 1.1 augustss /* We now own the host controller and the bus has been reset. */
1086 1.1 augustss
1087 1.1 augustss OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_HCR); /* Reset HC */
1088 1.1 augustss /* Nominal time for a reset is 10 us. */
1089 1.1 augustss for (i = 0; i < 10; i++) {
1090 1.1 augustss delay(10);
1091 1.1 augustss hcr = OREAD4(sc, OHCI_COMMAND_STATUS) & OHCI_HCR;
1092 1.1 augustss if (!hcr)
1093 1.1 augustss break;
1094 1.1 augustss }
1095 1.1 augustss if (hcr) {
1096 1.15 augustss printf("%s: reset timeout\n", USBDEVNAME(sc->sc_bus.bdev));
1097 1.182.12.1 itohy return (USBD_IOERROR);
1098 1.1 augustss }
1099 1.182.12.1 itohy #ifdef USB_DEBUG
1100 1.1 augustss if (ohcidebug > 15)
1101 1.1 augustss ohci_dumpregs(sc);
1102 1.1 augustss #endif
1103 1.1 augustss
1104 1.60 augustss /* The controller is now in SUSPEND state, we have 2ms to finish. */
1105 1.1 augustss
1106 1.1 augustss /* Set up HC registers. */
1107 1.125 augustss OWRITE4(sc, OHCI_HCCA, DMAADDR(&sc->sc_hccadma, 0));
1108 1.182.12.1 itohy OWRITE4(sc, OHCI_CONTROL_HEAD_ED, OHCI_SED_DMAADDR(sc->sc_ctrl_head));
1109 1.182.12.1 itohy OWRITE4(sc, OHCI_BULK_HEAD_ED, OHCI_SED_DMAADDR(sc->sc_bulk_head));
1110 1.55 augustss /* disable all interrupts and then switch on all desired interrupts */
1111 1.1 augustss OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS);
1112 1.55 augustss /* switch on desired functional features */
1113 1.1 augustss ctl = OREAD4(sc, OHCI_CONTROL);
1114 1.1 augustss ctl &= ~(OHCI_CBSR_MASK | OHCI_LES | OHCI_HCFS_MASK | OHCI_IR);
1115 1.1 augustss ctl |= OHCI_PLE | OHCI_IE | OHCI_CLE | OHCI_BLE |
1116 1.161 augustss OHCI_RATIO_1_4 | OHCI_HCFS_OPERATIONAL | rwc;
1117 1.1 augustss /* And finally start it! */
1118 1.1 augustss OWRITE4(sc, OHCI_CONTROL, ctl);
1119 1.1 augustss
1120 1.1 augustss /*
1121 1.1 augustss * The controller is now OPERATIONAL. Set a some final
1122 1.1 augustss * registers that should be set earlier, but that the
1123 1.1 augustss * controller ignores when in the SUSPEND state.
1124 1.1 augustss */
1125 1.161 augustss ival = OHCI_GET_IVAL(fm);
1126 1.1 augustss fm = (OREAD4(sc, OHCI_FM_INTERVAL) & OHCI_FIT) ^ OHCI_FIT;
1127 1.1 augustss fm |= OHCI_FSMPS(ival) | ival;
1128 1.1 augustss OWRITE4(sc, OHCI_FM_INTERVAL, fm);
1129 1.1 augustss per = OHCI_PERIODIC(ival); /* 90% periodic */
1130 1.1 augustss OWRITE4(sc, OHCI_PERIODIC_START, per);
1131 1.1 augustss
1132 1.68 augustss /* Fiddle the No OverCurrent Protection bit to avoid chip bug. */
1133 1.68 augustss OWRITE4(sc, OHCI_RH_DESCRIPTOR_A, desca | OHCI_NOCP);
1134 1.68 augustss OWRITE4(sc, OHCI_RH_STATUS, OHCI_LPSC); /* Enable port power */
1135 1.85 augustss usb_delay_ms(&sc->sc_bus, OHCI_ENABLE_POWER_DELAY);
1136 1.68 augustss OWRITE4(sc, OHCI_RH_DESCRIPTOR_A, desca);
1137 1.1 augustss
1138 1.85 augustss /*
1139 1.85 augustss * The AMD756 requires a delay before re-reading the register,
1140 1.85 augustss * otherwise it will occasionally report 0 ports.
1141 1.85 augustss */
1142 1.145 augustss sc->sc_noport = 0;
1143 1.145 augustss for (i = 0; i < 10 && sc->sc_noport == 0; i++) {
1144 1.145 augustss usb_delay_ms(&sc->sc_bus, OHCI_READ_DESC_DELAY);
1145 1.145 augustss sc->sc_noport = OHCI_GET_NDP(OREAD4(sc, OHCI_RH_DESCRIPTOR_A));
1146 1.145 augustss }
1147 1.1 augustss
1148 1.182.12.1 itohy #ifdef USB_DEBUG
1149 1.1 augustss if (ohcidebug > 5)
1150 1.1 augustss ohci_dumpregs(sc);
1151 1.1 augustss #endif
1152 1.182.12.1 itohy return (USBD_NORMAL_COMPLETION);
1153 1.182.12.1 itohy }
1154 1.120 augustss
1155 1.182.12.1 itohy Static usbd_status
1156 1.182.12.1 itohy ohci_prealloc(struct ohci_softc *sc, struct ohci_xfer *oxfer,
1157 1.182.12.1 itohy size_t bufsize, int nseg)
1158 1.182.12.1 itohy {
1159 1.182.12.1 itohy struct usbd_pipe *pipe;
1160 1.182.12.1 itohy int maxseg, maxp;
1161 1.182.12.1 itohy int seglen, ntd;
1162 1.182.12.1 itohy int s;
1163 1.182.12.1 itohy int err;
1164 1.1 augustss
1165 1.182.12.1 itohy pipe = oxfer->xfer.pipe;
1166 1.182.12.1 itohy maxp = UE_MAXPKTSZ(pipe->endpoint->edesc);
1167 1.59 augustss
1168 1.182.12.1 itohy if (maxp == 0)
1169 1.182.12.1 itohy return (USBD_INVAL);
1170 1.104 augustss
1171 1.182.12.1 itohy /* (over) estimate needed number of TDs */
1172 1.182.12.1 itohy maxseg = (sc->sc_flags & OHCI_FLAG_QUIRK_2ND_4KB) ? 4096 : 8192;
1173 1.182.12.1 itohy seglen = maxseg - (maxseg % maxp);
1174 1.182.12.1 itohy ntd = bufsize / seglen + nseg;
1175 1.167 augustss
1176 1.182.12.1 itohy s = splusb();
1177 1.182.12.1 itohy if ((pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE) ==
1178 1.182.12.1 itohy UE_ISOCHRONOUS) {
1179 1.182.12.1 itohy /* pre-allocate ITDs */
1180 1.182.12.1 itohy while (sc->sc_nfreeitds < ntd) {
1181 1.182.12.1 itohy DPRINTF(("%s: ohci_prealloc: need %d ITD (%d cur)\n",
1182 1.182.12.1 itohy USBDEVNAME(sc->sc_bus.bdev),
1183 1.182.12.1 itohy ntd, sc->sc_nfreeitds));
1184 1.182.12.1 itohy if ((err = ohci_grow_sitd(sc))
1185 1.182.12.1 itohy != USBD_NORMAL_COMPLETION) {
1186 1.182.12.1 itohy splx(s);
1187 1.182.12.1 itohy return (err);
1188 1.182.12.1 itohy }
1189 1.182.12.1 itohy }
1190 1.182.12.1 itohy sc->sc_nfreeitds -= ntd;
1191 1.182.12.1 itohy } else {
1192 1.182.12.1 itohy /* pre-allocate TDs */
1193 1.182.12.1 itohy while (sc->sc_nfreetds < ntd) {
1194 1.182.12.1 itohy DPRINTF(("%s: ohci_prealloc: need %d TD (%d cur)\n",
1195 1.182.12.1 itohy USBDEVNAME(sc->sc_bus.bdev),
1196 1.182.12.1 itohy ntd, sc->sc_nfreetds));
1197 1.182.12.1 itohy if ((err = ohci_grow_std(sc))
1198 1.182.12.1 itohy != USBD_NORMAL_COMPLETION) {
1199 1.182.12.1 itohy splx(s);
1200 1.182.12.1 itohy return (err);
1201 1.182.12.1 itohy }
1202 1.182.12.1 itohy }
1203 1.182.12.1 itohy sc->sc_nfreetds -= ntd;
1204 1.182.12.1 itohy }
1205 1.182.12.1 itohy splx(s);
1206 1.1 augustss
1207 1.182.12.1 itohy oxfer->rsvd_tds = ntd;
1208 1.182.12.1 itohy
1209 1.182.12.1 itohy return (USBD_NORMAL_COMPLETION);
1210 1.1 augustss }
1211 1.1 augustss
1212 1.42 augustss usbd_status
1213 1.182.12.1 itohy ohci_allocm(struct usbd_bus *bus, usbd_xfer_handle xfer, void *buf, size_t size)
1214 1.42 augustss {
1215 1.42 augustss struct ohci_softc *sc = (struct ohci_softc *)bus;
1216 1.182.12.1 itohy struct ohci_xfer *oxfer = OXFER(xfer);
1217 1.182.12.1 itohy usbd_status err;
1218 1.182.12.1 itohy
1219 1.182.12.1 itohy if ((err = usb_alloc_buffer_dma(&sc->sc_dmatag, &oxfer->dmabuf,
1220 1.182.12.1 itohy buf, size, &xfer->hcbuffer)) == USBD_NORMAL_COMPLETION) {
1221 1.182.12.1 itohy if ((xfer->rqflags & URQ_DEV_MAP_PREPARED) == 0 &&
1222 1.182.12.1 itohy (err = ohci_prealloc(sc, oxfer, size,
1223 1.182.12.1 itohy USB_BUFFER_NSEGS(&oxfer->dmabuf)))
1224 1.182.12.1 itohy != USBD_NORMAL_COMPLETION) {
1225 1.182.12.1 itohy usb_free_buffer_dma(&sc->sc_dmatag, &oxfer->dmabuf,
1226 1.182.12.1 itohy U_WAITOK);
1227 1.182.12.1 itohy }
1228 1.182.12.1 itohy }
1229 1.182.12.1 itohy
1230 1.182.12.1 itohy return err;
1231 1.182.12.1 itohy }
1232 1.182.12.1 itohy
1233 1.182.12.1 itohy void
1234 1.182.12.1 itohy ohci_freem(struct usbd_bus *bus, usbd_xfer_handle xfer,
1235 1.182.12.1 itohy enum usbd_waitflg waitflg)
1236 1.182.12.1 itohy {
1237 1.182.12.1 itohy struct ohci_softc *sc = (struct ohci_softc *)bus;
1238 1.182.12.1 itohy struct ohci_xfer *oxfer = OXFER(xfer);
1239 1.182.12.1 itohy int s;
1240 1.182.12.1 itohy
1241 1.182.12.1 itohy usb_free_buffer_dma(&sc->sc_dmatag, &oxfer->dmabuf, waitflg);
1242 1.182.12.1 itohy
1243 1.182.12.1 itohy if ((xfer->rqflags & URQ_DEV_MAP_PREPARED) == 0) {
1244 1.182.12.1 itohy s = splusb();
1245 1.182.12.1 itohy if ((xfer->pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE) ==
1246 1.182.12.1 itohy UE_ISOCHRONOUS) {
1247 1.182.12.1 itohy sc->sc_nfreeitds += oxfer->rsvd_tds;
1248 1.182.12.1 itohy } else {
1249 1.182.12.1 itohy sc->sc_nfreetds += oxfer->rsvd_tds;
1250 1.182.12.1 itohy }
1251 1.182.12.1 itohy splx(s);
1252 1.182.12.1 itohy oxfer->rsvd_tds = 0;
1253 1.182.12.1 itohy }
1254 1.182.12.1 itohy }
1255 1.182.12.1 itohy
1256 1.182.12.1 itohy Static usbd_status
1257 1.182.12.1 itohy ohci_map_alloc(usbd_xfer_handle xfer)
1258 1.182.12.1 itohy {
1259 1.182.12.1 itohy struct ohci_softc *sc = (struct ohci_softc *)xfer->device->bus;
1260 1.182.12.1 itohy struct ohci_xfer *oxfer = OXFER(xfer);
1261 1.182.12.1 itohy usbd_status st;
1262 1.182.12.1 itohy
1263 1.182.12.1 itohy st = usb_alloc_dma_resources(&sc->sc_dmatag, &oxfer->dmabuf);
1264 1.182.12.1 itohy if (st)
1265 1.182.12.1 itohy return st;
1266 1.182.12.1 itohy
1267 1.182.12.1 itohy if ((st = ohci_prealloc(sc, oxfer, MAXPHYS, USB_DMA_NSEG))) {
1268 1.182.12.1 itohy usb_free_dma_resources(&sc->sc_dmatag, &oxfer->dmabuf);
1269 1.182.12.1 itohy }
1270 1.182.12.1 itohy
1271 1.182.12.1 itohy return st;
1272 1.182.12.1 itohy }
1273 1.182.12.1 itohy
1274 1.182.12.1 itohy Static void
1275 1.182.12.1 itohy ohci_map_free(usbd_xfer_handle xfer)
1276 1.182.12.1 itohy {
1277 1.182.12.1 itohy struct ohci_softc *sc = (struct ohci_softc *)xfer->device->bus;
1278 1.182.12.1 itohy struct ohci_xfer *oxfer = OXFER(xfer);
1279 1.182.12.1 itohy int s;
1280 1.182.12.1 itohy
1281 1.182.12.1 itohy USB_KASSERT(xfer->rqflags & URQ_DEV_MAP_PREPARED);
1282 1.182.12.1 itohy
1283 1.182.12.1 itohy usb_free_dma_resources(&sc->sc_dmatag, &oxfer->dmabuf);
1284 1.182.12.1 itohy
1285 1.182.12.1 itohy s = splusb();
1286 1.182.12.1 itohy if ((xfer->pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE) ==
1287 1.182.12.1 itohy UE_ISOCHRONOUS) {
1288 1.182.12.1 itohy sc->sc_nfreeitds += oxfer->rsvd_tds;
1289 1.182.12.1 itohy } else {
1290 1.182.12.1 itohy sc->sc_nfreetds += oxfer->rsvd_tds;
1291 1.182.12.1 itohy }
1292 1.182.12.1 itohy splx(s);
1293 1.182.12.1 itohy oxfer->rsvd_tds = 0;
1294 1.182.12.1 itohy }
1295 1.182.12.1 itohy
1296 1.182.12.1 itohy Static void
1297 1.182.12.1 itohy ohci_mapm(usbd_xfer_handle xfer, void *buf, size_t size)
1298 1.182.12.1 itohy {
1299 1.182.12.1 itohy struct ohci_softc *sc = (struct ohci_softc *)xfer->device->bus;
1300 1.182.12.1 itohy struct ohci_xfer *oxfer = OXFER(xfer);
1301 1.182.12.1 itohy
1302 1.182.12.1 itohy usb_map_dma(&sc->sc_dmatag, &oxfer->dmabuf, buf, size);
1303 1.182.12.1 itohy }
1304 1.182.12.1 itohy
1305 1.182.12.2 itohy Static usbd_status
1306 1.182.12.1 itohy ohci_mapm_mbuf(usbd_xfer_handle xfer, struct mbuf *chain)
1307 1.182.12.1 itohy {
1308 1.182.12.1 itohy struct ohci_softc *sc = (struct ohci_softc *)xfer->device->bus;
1309 1.182.12.1 itohy struct ohci_xfer *oxfer = OXFER(xfer);
1310 1.42 augustss
1311 1.182.12.2 itohy return (usb_map_mbuf_dma(&sc->sc_dmatag, &oxfer->dmabuf, chain));
1312 1.42 augustss }
1313 1.42 augustss
1314 1.182.12.1 itohy Static void
1315 1.182.12.1 itohy ohci_unmapm(usbd_xfer_handle xfer)
1316 1.42 augustss {
1317 1.182.12.1 itohy struct ohci_softc *sc = (struct ohci_softc *)xfer->device->bus;
1318 1.182.12.1 itohy struct ohci_xfer *oxfer = OXFER(xfer);
1319 1.182.12.1 itohy
1320 1.182.12.1 itohy usb_unmap_dma(&sc->sc_dmatag, &oxfer->dmabuf);
1321 1.62 augustss }
1322 1.62 augustss
1323 1.62 augustss usbd_xfer_handle
1324 1.182.12.1 itohy ohci_allocx(struct usbd_bus *bus, usbd_pipe_handle pipe,
1325 1.182.12.1 itohy enum usbd_waitflg waitflg)
1326 1.62 augustss {
1327 1.62 augustss struct ohci_softc *sc = (struct ohci_softc *)bus;
1328 1.62 augustss usbd_xfer_handle xfer;
1329 1.62 augustss
1330 1.62 augustss xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
1331 1.118 augustss if (xfer != NULL) {
1332 1.126 lukem SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
1333 1.118 augustss #ifdef DIAGNOSTIC
1334 1.118 augustss if (xfer->busy_free != XFER_FREE) {
1335 1.118 augustss printf("ohci_allocx: xfer=%p not free, 0x%08x\n", xfer,
1336 1.118 augustss xfer->busy_free);
1337 1.118 augustss }
1338 1.118 augustss #endif
1339 1.118 augustss } else {
1340 1.182.12.1 itohy xfer = malloc(sizeof(struct ohci_xfer), M_USB,
1341 1.182.12.1 itohy waitflg == U_WAITOK ? M_WAITOK : M_NOWAIT);
1342 1.118 augustss }
1343 1.118 augustss if (xfer != NULL) {
1344 1.114 augustss memset(xfer, 0, sizeof (struct ohci_xfer));
1345 1.182.12.1 itohy usb_init_task(&OXFER(xfer)->abort_task, ohci_timeout_task,
1346 1.182.12.1 itohy xfer);
1347 1.182.12.1 itohy OXFER(xfer)->ohci_xfer_flags = 0;
1348 1.182.12.1 itohy OXFER(xfer)->rsvd_tds = 0;
1349 1.118 augustss #ifdef DIAGNOSTIC
1350 1.118 augustss xfer->busy_free = XFER_BUSY;
1351 1.118 augustss #endif
1352 1.118 augustss }
1353 1.62 augustss return (xfer);
1354 1.62 augustss }
1355 1.62 augustss
1356 1.62 augustss void
1357 1.91 augustss ohci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer)
1358 1.62 augustss {
1359 1.62 augustss struct ohci_softc *sc = (struct ohci_softc *)bus;
1360 1.62 augustss
1361 1.118 augustss #ifdef DIAGNOSTIC
1362 1.118 augustss if (xfer->busy_free != XFER_BUSY) {
1363 1.118 augustss printf("ohci_freex: xfer=%p not busy, 0x%08x\n", xfer,
1364 1.118 augustss xfer->busy_free);
1365 1.118 augustss }
1366 1.118 augustss xfer->busy_free = XFER_FREE;
1367 1.118 augustss #endif
1368 1.62 augustss SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
1369 1.42 augustss }
1370 1.42 augustss
1371 1.59 augustss /*
1372 1.59 augustss * Shut down the controller when the system is going down.
1373 1.59 augustss */
1374 1.59 augustss void
1375 1.91 augustss ohci_shutdown(void *v)
1376 1.59 augustss {
1377 1.59 augustss ohci_softc_t *sc = v;
1378 1.59 augustss
1379 1.59 augustss DPRINTF(("ohci_shutdown: stopping the HC\n"));
1380 1.59 augustss OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
1381 1.59 augustss }
1382 1.59 augustss
1383 1.59 augustss /*
1384 1.59 augustss * Handle suspend/resume.
1385 1.59 augustss *
1386 1.59 augustss * We need to switch to polling mode here, because this routine is
1387 1.162 augustss * called from an interupt context. This is all right since we
1388 1.59 augustss * are almost suspended anyway.
1389 1.59 augustss */
1390 1.33 augustss void
1391 1.91 augustss ohci_power(int why, void *v)
1392 1.33 augustss {
1393 1.33 augustss ohci_softc_t *sc = v;
1394 1.97 augustss u_int32_t ctl;
1395 1.95 augustss int s;
1396 1.33 augustss
1397 1.182.12.1 itohy #ifdef USB_DEBUG
1398 1.41 augustss DPRINTF(("ohci_power: sc=%p, why=%d\n", sc, why));
1399 1.33 augustss ohci_dumpregs(sc);
1400 1.33 augustss #endif
1401 1.95 augustss
1402 1.98 augustss s = splhardusb();
1403 1.95 augustss switch (why) {
1404 1.182.12.1 itohy USB_PWR_CASE_SUSPEND:
1405 1.97 augustss sc->sc_bus.use_polling++;
1406 1.101 minoura ctl = OREAD4(sc, OHCI_CONTROL) & ~OHCI_HCFS_MASK;
1407 1.101 minoura if (sc->sc_control == 0) {
1408 1.101 minoura /*
1409 1.101 minoura * Preserve register values, in case that APM BIOS
1410 1.101 minoura * does not recover them.
1411 1.101 minoura */
1412 1.101 minoura sc->sc_control = ctl;
1413 1.101 minoura sc->sc_intre = OREAD4(sc, OHCI_INTERRUPT_ENABLE);
1414 1.101 minoura }
1415 1.101 minoura ctl |= OHCI_HCFS_SUSPEND;
1416 1.97 augustss OWRITE4(sc, OHCI_CONTROL, ctl);
1417 1.97 augustss usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
1418 1.97 augustss sc->sc_bus.use_polling--;
1419 1.95 augustss break;
1420 1.182.12.1 itohy
1421 1.182.12.1 itohy USB_PWR_CASE_RESUME:
1422 1.97 augustss sc->sc_bus.use_polling++;
1423 1.182.12.1 itohy
1424 1.182.12.1 itohy /* Some broken BIOSes never initialize Controller chip */
1425 1.182.12.1 itohy ohci_controller_init(sc);
1426 1.182.12.1 itohy
1427 1.101 minoura if (sc->sc_intre)
1428 1.101 minoura OWRITE4(sc, OHCI_INTERRUPT_ENABLE,
1429 1.101 minoura sc->sc_intre & (OHCI_ALL_INTRS | OHCI_MIE));
1430 1.101 minoura if (sc->sc_control)
1431 1.101 minoura ctl = sc->sc_control;
1432 1.101 minoura else
1433 1.101 minoura ctl = OREAD4(sc, OHCI_CONTROL);
1434 1.101 minoura ctl |= OHCI_HCFS_RESUME;
1435 1.97 augustss OWRITE4(sc, OHCI_CONTROL, ctl);
1436 1.97 augustss usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY);
1437 1.97 augustss ctl = (ctl & ~OHCI_HCFS_MASK) | OHCI_HCFS_OPERATIONAL;
1438 1.97 augustss OWRITE4(sc, OHCI_CONTROL, ctl);
1439 1.97 augustss usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY);
1440 1.101 minoura sc->sc_control = sc->sc_intre = 0;
1441 1.97 augustss sc->sc_bus.use_polling--;
1442 1.95 augustss break;
1443 1.182.12.1 itohy
1444 1.182.12.1 itohy default:
1445 1.95 augustss break;
1446 1.95 augustss }
1447 1.95 augustss splx(s);
1448 1.33 augustss }
1449 1.33 augustss
1450 1.182.12.1 itohy #ifdef USB_DEBUG
1451 1.1 augustss void
1452 1.91 augustss ohci_dumpregs(ohci_softc_t *sc)
1453 1.1 augustss {
1454 1.41 augustss DPRINTF(("ohci_dumpregs: rev=0x%08x control=0x%08x command=0x%08x\n",
1455 1.41 augustss OREAD4(sc, OHCI_REVISION),
1456 1.41 augustss OREAD4(sc, OHCI_CONTROL),
1457 1.41 augustss OREAD4(sc, OHCI_COMMAND_STATUS)));
1458 1.41 augustss DPRINTF((" intrstat=0x%08x intre=0x%08x intrd=0x%08x\n",
1459 1.41 augustss OREAD4(sc, OHCI_INTERRUPT_STATUS),
1460 1.41 augustss OREAD4(sc, OHCI_INTERRUPT_ENABLE),
1461 1.41 augustss OREAD4(sc, OHCI_INTERRUPT_DISABLE)));
1462 1.41 augustss DPRINTF((" hcca=0x%08x percur=0x%08x ctrlhd=0x%08x\n",
1463 1.41 augustss OREAD4(sc, OHCI_HCCA),
1464 1.41 augustss OREAD4(sc, OHCI_PERIOD_CURRENT_ED),
1465 1.41 augustss OREAD4(sc, OHCI_CONTROL_HEAD_ED)));
1466 1.41 augustss DPRINTF((" ctrlcur=0x%08x bulkhd=0x%08x bulkcur=0x%08x\n",
1467 1.41 augustss OREAD4(sc, OHCI_CONTROL_CURRENT_ED),
1468 1.41 augustss OREAD4(sc, OHCI_BULK_HEAD_ED),
1469 1.41 augustss OREAD4(sc, OHCI_BULK_CURRENT_ED)));
1470 1.41 augustss DPRINTF((" done=0x%08x fmival=0x%08x fmrem=0x%08x\n",
1471 1.41 augustss OREAD4(sc, OHCI_DONE_HEAD),
1472 1.41 augustss OREAD4(sc, OHCI_FM_INTERVAL),
1473 1.41 augustss OREAD4(sc, OHCI_FM_REMAINING)));
1474 1.41 augustss DPRINTF((" fmnum=0x%08x perst=0x%08x lsthrs=0x%08x\n",
1475 1.41 augustss OREAD4(sc, OHCI_FM_NUMBER),
1476 1.41 augustss OREAD4(sc, OHCI_PERIODIC_START),
1477 1.41 augustss OREAD4(sc, OHCI_LS_THRESHOLD)));
1478 1.41 augustss DPRINTF((" desca=0x%08x descb=0x%08x stat=0x%08x\n",
1479 1.41 augustss OREAD4(sc, OHCI_RH_DESCRIPTOR_A),
1480 1.41 augustss OREAD4(sc, OHCI_RH_DESCRIPTOR_B),
1481 1.41 augustss OREAD4(sc, OHCI_RH_STATUS)));
1482 1.41 augustss DPRINTF((" port1=0x%08x port2=0x%08x\n",
1483 1.41 augustss OREAD4(sc, OHCI_RH_PORT_STATUS(1)),
1484 1.41 augustss OREAD4(sc, OHCI_RH_PORT_STATUS(2))));
1485 1.41 augustss DPRINTF((" HCCA: frame_number=0x%04x done_head=0x%08x\n",
1486 1.168 augustss O32TOH(sc->sc_hcca->hcca_frame_number),
1487 1.168 augustss O32TOH(sc->sc_hcca->hcca_done_head)));
1488 1.1 augustss }
1489 1.1 augustss #endif
1490 1.1 augustss
1491 1.91 augustss Static int ohci_intr1(ohci_softc_t *);
1492 1.53 augustss
1493 1.182.12.1 itohy #if defined(__NetBSD__) || defined(__OpenBSD__)
1494 1.1 augustss int
1495 1.182.12.1 itohy #elif defined(__FreeBSD__)
1496 1.182.12.1 itohy void
1497 1.182.12.1 itohy #endif
1498 1.91 augustss ohci_intr(void *p)
1499 1.1 augustss {
1500 1.1 augustss ohci_softc_t *sc = p;
1501 1.111 augustss
1502 1.116 augustss if (sc == NULL || sc->sc_dying)
1503 1.182.12.1 itohy #if defined(__NetBSD__) || defined(__OpenBSD__)
1504 1.111 augustss return (0);
1505 1.182.12.1 itohy #elif defined(__FreeBSD__)
1506 1.182.12.1 itohy return;
1507 1.182.12.1 itohy #endif
1508 1.53 augustss
1509 1.53 augustss /* If we get an interrupt while polling, then just ignore it. */
1510 1.57 augustss if (sc->sc_bus.use_polling) {
1511 1.57 augustss #ifdef DIAGNOSTIC
1512 1.149 mycroft DPRINTFN(16, ("ohci_intr: ignored interrupt while polling\n"));
1513 1.57 augustss #endif
1514 1.154 joff /* for level triggered intrs, should do something to ack */
1515 1.155 perry OWRITE4(sc, OHCI_INTERRUPT_STATUS,
1516 1.154 joff OREAD4(sc, OHCI_INTERRUPT_STATUS));
1517 1.155 perry
1518 1.182.12.1 itohy #if defined(__NetBSD__) || defined(__OpenBSD__)
1519 1.53 augustss return (0);
1520 1.182.12.1 itohy #elif defined(__FreeBSD__)
1521 1.182.12.1 itohy return;
1522 1.182.12.1 itohy #endif
1523 1.57 augustss }
1524 1.53 augustss
1525 1.182.12.1 itohy #if defined(__NetBSD__) || defined(__OpenBSD__)
1526 1.182.12.1 itohy return
1527 1.182.12.1 itohy #endif
1528 1.182.12.1 itohy ohci_intr1(sc);
1529 1.53 augustss }
1530 1.53 augustss
1531 1.82 augustss Static int
1532 1.91 augustss ohci_intr1(ohci_softc_t *sc)
1533 1.53 augustss {
1534 1.1 augustss u_int32_t intrs, eintrs;
1535 1.1 augustss
1536 1.105 augustss DPRINTFN(14,("ohci_intr1: enter\n"));
1537 1.105 augustss
1538 1.15 augustss /* In case the interrupt occurs before initialization has completed. */
1539 1.34 augustss if (sc == NULL || sc->sc_hcca == NULL) {
1540 1.15 augustss #ifdef DIAGNOSTIC
1541 1.15 augustss printf("ohci_intr: sc->sc_hcca == NULL\n");
1542 1.15 augustss #endif
1543 1.15 augustss return (0);
1544 1.15 augustss }
1545 1.15 augustss
1546 1.157 mycroft intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS);
1547 1.182.12.1 itohy
1548 1.182.12.1 itohy if (intrs == 0) /* nothing to be done (PCI shared interrupt) */
1549 1.1 augustss return (0);
1550 1.55 augustss
1551 1.182.12.1 itohy /* Acknowledge */
1552 1.182.12.1 itohy OWRITE4(sc, OHCI_INTERRUPT_STATUS, intrs & ~(OHCI_MIE|OHCI_WDH));
1553 1.182.12.1 itohy
1554 1.1 augustss eintrs = intrs & sc->sc_eintrs;
1555 1.1 augustss if (!eintrs)
1556 1.1 augustss return (0);
1557 1.1 augustss
1558 1.45 augustss sc->sc_bus.intr_context++;
1559 1.44 augustss sc->sc_bus.no_intrs++;
1560 1.120 augustss DPRINTFN(7, ("ohci_intr: sc=%p intrs=0x%x(0x%x) eintrs=0x%x\n",
1561 1.1 augustss sc, (u_int)intrs, OREAD4(sc, OHCI_INTERRUPT_STATUS),
1562 1.1 augustss (u_int)eintrs));
1563 1.1 augustss
1564 1.1 augustss if (eintrs & OHCI_SO) {
1565 1.100 augustss sc->sc_overrun_cnt++;
1566 1.100 augustss if (usbd_ratecheck(&sc->sc_overrun_ntc)) {
1567 1.100 augustss printf("%s: %u scheduling overruns\n",
1568 1.100 augustss USBDEVNAME(sc->sc_bus.bdev), sc->sc_overrun_cnt);
1569 1.100 augustss sc->sc_overrun_cnt = 0;
1570 1.100 augustss }
1571 1.1 augustss /* XXX do what */
1572 1.106 augustss eintrs &= ~OHCI_SO;
1573 1.1 augustss }
1574 1.1 augustss if (eintrs & OHCI_WDH) {
1575 1.157 mycroft /*
1576 1.157 mycroft * We block the interrupt below, and reenable it later from
1577 1.157 mycroft * ohci_softintr().
1578 1.157 mycroft */
1579 1.72 augustss usb_schedsoftintr(&sc->sc_bus);
1580 1.1 augustss }
1581 1.1 augustss if (eintrs & OHCI_RD) {
1582 1.33 augustss printf("%s: resume detect\n", USBDEVNAME(sc->sc_bus.bdev));
1583 1.1 augustss /* XXX process resume detect */
1584 1.1 augustss }
1585 1.1 augustss if (eintrs & OHCI_UE) {
1586 1.15 augustss printf("%s: unrecoverable error, controller halted\n",
1587 1.15 augustss USBDEVNAME(sc->sc_bus.bdev));
1588 1.1 augustss OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
1589 1.1 augustss /* XXX what else */
1590 1.1 augustss }
1591 1.1 augustss if (eintrs & OHCI_RHSC) {
1592 1.120 augustss /*
1593 1.157 mycroft * We block the interrupt below, and reenable it later from
1594 1.157 mycroft * a timeout.
1595 1.1 augustss */
1596 1.157 mycroft ohci_rhsc(sc, sc->sc_intrxfer);
1597 1.104 augustss /* Do not allow RHSC interrupts > 1 per second */
1598 1.182.12.1 itohy usb_callout(sc->sc_tmo_rhsc, hz, ohci_rhsc_enable, sc);
1599 1.1 augustss }
1600 1.1 augustss
1601 1.45 augustss sc->sc_bus.intr_context--;
1602 1.44 augustss
1603 1.106 augustss if (eintrs != 0) {
1604 1.157 mycroft /* Block unprocessed interrupts. */
1605 1.106 augustss OWRITE4(sc, OHCI_INTERRUPT_DISABLE, eintrs);
1606 1.106 augustss sc->sc_eintrs &= ~eintrs;
1607 1.157 mycroft DPRINTFN(1, ("%s: blocking intrs 0x%x\n",
1608 1.157 mycroft USBDEVNAME(sc->sc_bus.bdev), eintrs));
1609 1.106 augustss }
1610 1.1 augustss
1611 1.1 augustss return (1);
1612 1.1 augustss }
1613 1.1 augustss
1614 1.1 augustss void
1615 1.104 augustss ohci_rhsc_enable(void *v_sc)
1616 1.104 augustss {
1617 1.104 augustss ohci_softc_t *sc = v_sc;
1618 1.129 augustss int s;
1619 1.104 augustss
1620 1.129 augustss s = splhardusb();
1621 1.157 mycroft sc->sc_eintrs |= OHCI_RHSC;
1622 1.157 mycroft OWRITE4(sc, OHCI_INTERRUPT_ENABLE, OHCI_RHSC);
1623 1.129 augustss splx(s);
1624 1.1 augustss }
1625 1.1 augustss
1626 1.182.12.1 itohy #ifdef USB_DEBUG
1627 1.166 drochner const char *ohci_cc_strs[] = {
1628 1.13 augustss "NO_ERROR",
1629 1.13 augustss "CRC",
1630 1.13 augustss "BIT_STUFFING",
1631 1.13 augustss "DATA_TOGGLE_MISMATCH",
1632 1.13 augustss "STALL",
1633 1.13 augustss "DEVICE_NOT_RESPONDING",
1634 1.13 augustss "PID_CHECK_FAILURE",
1635 1.13 augustss "UNEXPECTED_PID",
1636 1.13 augustss "DATA_OVERRUN",
1637 1.13 augustss "DATA_UNDERRUN",
1638 1.13 augustss "BUFFER_OVERRUN",
1639 1.13 augustss "BUFFER_UNDERRUN",
1640 1.67 augustss "reserved",
1641 1.67 augustss "reserved",
1642 1.67 augustss "NOT_ACCESSED",
1643 1.182.12.1 itohy "NOT_ACCESSED"
1644 1.13 augustss };
1645 1.13 augustss #endif
1646 1.13 augustss
1647 1.1 augustss void
1648 1.157 mycroft ohci_softintr(void *v)
1649 1.83 augustss {
1650 1.157 mycroft ohci_softc_t *sc = v;
1651 1.157 mycroft ohci_soft_itd_t *sitd, *sidone, *sitdnext;
1652 1.182.12.1 itohy ohci_soft_td_t *std, *sdone, *stdnext, *p, *n;
1653 1.157 mycroft usbd_xfer_handle xfer;
1654 1.157 mycroft struct ohci_pipe *opipe;
1655 1.157 mycroft int len, cc, s;
1656 1.182.12.1 itohy int i, j, iframes;
1657 1.157 mycroft ohci_physaddr_t done;
1658 1.182.12.1 itohy ohci_physaddr_t dmaadr;
1659 1.157 mycroft
1660 1.157 mycroft DPRINTFN(10,("ohci_softintr: enter\n"));
1661 1.157 mycroft
1662 1.157 mycroft sc->sc_bus.intr_context++;
1663 1.157 mycroft
1664 1.157 mycroft s = splhardusb();
1665 1.182.12.1 itohy USB_MEM_SYNC(&sc->sc_dmatag, &sc->sc_hccadma,
1666 1.182.12.1 itohy BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1667 1.168 augustss done = O32TOH(sc->sc_hcca->hcca_done_head) & ~OHCI_DONE_INTRS;
1668 1.157 mycroft sc->sc_hcca->hcca_done_head = 0;
1669 1.157 mycroft OWRITE4(sc, OHCI_INTERRUPT_STATUS, OHCI_WDH);
1670 1.157 mycroft sc->sc_eintrs |= OHCI_WDH;
1671 1.157 mycroft OWRITE4(sc, OHCI_INTERRUPT_ENABLE, OHCI_WDH);
1672 1.157 mycroft splx(s);
1673 1.83 augustss
1674 1.83 augustss /* Reverse the done list. */
1675 1.83 augustss for (sdone = NULL, sidone = NULL; done != 0; ) {
1676 1.182.12.1 itohy std = ohci_find_td(sc, done);
1677 1.83 augustss if (std != NULL) {
1678 1.182.12.1 itohy OHCI_STD_SYNC(sc, std,
1679 1.182.12.1 itohy BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1680 1.83 augustss std->dnext = sdone;
1681 1.168 augustss done = O32TOH(std->td.td_nexttd);
1682 1.83 augustss sdone = std;
1683 1.83 augustss DPRINTFN(10,("add TD %p\n", std));
1684 1.83 augustss continue;
1685 1.83 augustss }
1686 1.182.12.1 itohy sitd = ohci_find_itd(sc, done);
1687 1.83 augustss if (sitd != NULL) {
1688 1.182.12.1 itohy OHCI_SITD_SYNC(sc, sitd,
1689 1.182.12.1 itohy BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1690 1.83 augustss sitd->dnext = sidone;
1691 1.168 augustss done = O32TOH(sitd->itd.itd_nextitd);
1692 1.83 augustss sidone = sitd;
1693 1.83 augustss DPRINTFN(5,("add ITD %p\n", sitd));
1694 1.83 augustss continue;
1695 1.83 augustss }
1696 1.157 mycroft panic("ohci_softintr: addr 0x%08lx not found", (u_long)done);
1697 1.83 augustss }
1698 1.83 augustss
1699 1.105 augustss DPRINTFN(10,("ohci_softintr: sdone=%p sidone=%p\n", sdone, sidone));
1700 1.1 augustss
1701 1.182.12.1 itohy #ifdef USB_DEBUG
1702 1.1 augustss if (ohcidebug > 10) {
1703 1.41 augustss DPRINTF(("ohci_process_done: TD done:\n"));
1704 1.168 augustss ohci_dump_tds(sc, sdone);
1705 1.1 augustss }
1706 1.1 augustss #endif
1707 1.1 augustss
1708 1.48 augustss for (std = sdone; std; std = stdnext) {
1709 1.53 augustss xfer = std->xfer;
1710 1.48 augustss stdnext = std->dnext;
1711 1.53 augustss DPRINTFN(10, ("ohci_process_done: std=%p xfer=%p hcpriv=%p\n",
1712 1.182.12.1 itohy std, xfer, (xfer ? xfer->hcpriv : NULL)));
1713 1.71 augustss if (xfer == NULL) {
1714 1.117 augustss /*
1715 1.117 augustss * xfer == NULL: There seems to be no xfer associated
1716 1.71 augustss * with this TD. It is tailp that happened to end up on
1717 1.71 augustss * the done queue.
1718 1.71 augustss */
1719 1.71 augustss continue;
1720 1.71 augustss }
1721 1.53 augustss if (xfer->status == USBD_CANCELLED ||
1722 1.53 augustss xfer->status == USBD_TIMEOUT) {
1723 1.34 augustss DPRINTF(("ohci_process_done: cancel/timeout %p\n",
1724 1.53 augustss xfer));
1725 1.38 augustss /* Handled by abort routine. */
1726 1.83 augustss continue;
1727 1.83 augustss }
1728 1.141 mycroft
1729 1.141 mycroft len = std->len;
1730 1.141 mycroft if (std->td.td_cbp != 0)
1731 1.168 augustss len -= O32TOH(std->td.td_be) -
1732 1.168 augustss O32TOH(std->td.td_cbp) + 1;
1733 1.141 mycroft DPRINTFN(10, ("ohci_process_done: len=%d, flags=0x%x\n", len,
1734 1.141 mycroft std->flags));
1735 1.141 mycroft if (std->flags & OHCI_ADD_LEN)
1736 1.141 mycroft xfer->actlen += len;
1737 1.141 mycroft
1738 1.168 augustss cc = OHCI_TD_GET_CC(O32TOH(std->td.td_flags));
1739 1.182.12.1 itohy if (cc != OHCI_CC_NO_ERROR) {
1740 1.48 augustss /*
1741 1.48 augustss * Endpoint is halted. First unlink all the TDs
1742 1.48 augustss * belonging to the failed transfer, and then restart
1743 1.48 augustss * the endpoint.
1744 1.48 augustss */
1745 1.134 toshii opipe = (struct ohci_pipe *)xfer->pipe;
1746 1.48 augustss
1747 1.71 augustss DPRINTFN(15,("ohci_process_done: error cc=%d (%s)\n",
1748 1.168 augustss OHCI_TD_GET_CC(O32TOH(std->td.td_flags)),
1749 1.168 augustss ohci_cc_strs[OHCI_TD_GET_CC(O32TOH(std->td.td_flags))]));
1750 1.182.12.1 itohy usb_uncallout(xfer->timeout_handle, ohci_timeout, xfer);
1751 1.182.12.1 itohy usb_rem_task(OXFER(xfer)->xfer.pipe->device,
1752 1.182.12.1 itohy &OXFER(xfer)->abort_task);
1753 1.182.12.1 itohy
1754 1.182.12.1 itohy /* Remove all this xfer's TDs from the done queue. */
1755 1.182.12.1 itohy for (p = std; p->dnext != NULL; p = p->dnext) {
1756 1.182.12.1 itohy if (p->dnext->xfer != xfer)
1757 1.182.12.1 itohy continue;
1758 1.182.12.1 itohy p->dnext = p->dnext->dnext;
1759 1.182.12.1 itohy }
1760 1.182.12.1 itohy /* The next TD may have been removed. */
1761 1.182.12.1 itohy stdnext = std->dnext;
1762 1.48 augustss
1763 1.182.12.1 itohy /* Remove all TDs belonging to this xfer. */
1764 1.182.12.1 itohy for (p = xfer->hcpriv; p->xfer == xfer; p = n) {
1765 1.1 augustss n = p->nexttd;
1766 1.1 augustss ohci_free_std(sc, p);
1767 1.1 augustss }
1768 1.48 augustss
1769 1.16 augustss /* clear halt */
1770 1.182.12.1 itohy OHCI_SED_SYNC(sc, opipe->sed,
1771 1.182.12.1 itohy BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1772 1.182.12.1 itohy dmaadr = OHCI_STD_DMAADDR(p);
1773 1.182.12.1 itohy opipe->sed->ed.ed_headp = HTOO32(dmaadr);
1774 1.182.12.1 itohy OHCI_SED_SYNC(sc, opipe->sed,
1775 1.182.12.1 itohy BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1776 1.1 augustss OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
1777 1.48 augustss
1778 1.1 augustss if (cc == OHCI_CC_STALL)
1779 1.53 augustss xfer->status = USBD_STALLED;
1780 1.1 augustss else
1781 1.53 augustss xfer->status = USBD_IOERROR;
1782 1.133 toshii s = splusb();
1783 1.182.12.1 itohy usb_transfer_complete_dma(xfer, &sc->sc_dmatag,
1784 1.182.12.1 itohy &OXFER(xfer)->dmabuf);
1785 1.133 toshii splx(s);
1786 1.182.12.1 itohy continue;
1787 1.182.12.1 itohy }
1788 1.182.12.1 itohy /*
1789 1.182.12.1 itohy * Skip intermediate TDs. They remain linked from
1790 1.182.12.1 itohy * xfer->hcpriv and we free them when the transfer completes.
1791 1.182.12.1 itohy */
1792 1.182.12.1 itohy if ((std->flags & OHCI_CALL_DONE) == 0)
1793 1.182.12.1 itohy continue;
1794 1.182.12.1 itohy
1795 1.182.12.1 itohy /* Normal transfer completion */
1796 1.182.12.1 itohy usb_uncallout(xfer->timeout_handle, ohci_timeout, xfer);
1797 1.182.12.1 itohy usb_rem_task(OXFER(xfer)->xfer.pipe->device,
1798 1.182.12.1 itohy &OXFER(xfer)->abort_task);
1799 1.182.12.1 itohy for (p = xfer->hcpriv; p->xfer == xfer; p = n) {
1800 1.182.12.1 itohy n = p->nexttd;
1801 1.182.12.1 itohy ohci_free_std(sc, p);
1802 1.1 augustss }
1803 1.182.12.1 itohy xfer->status = USBD_NORMAL_COMPLETION;
1804 1.182.12.1 itohy xfer->hcpriv = NULL;
1805 1.182.12.1 itohy s = splusb();
1806 1.182.12.1 itohy usb_transfer_complete_dma(xfer, &sc->sc_dmatag,
1807 1.182.12.1 itohy &OXFER(xfer)->dmabuf);
1808 1.182.12.1 itohy splx(s);
1809 1.1 augustss }
1810 1.72 augustss
1811 1.182.12.1 itohy #ifdef USB_DEBUG
1812 1.83 augustss if (ohcidebug > 10) {
1813 1.105 augustss DPRINTF(("ohci_softintr: ITD done:\n"));
1814 1.168 augustss ohci_dump_itds(sc, sidone);
1815 1.83 augustss }
1816 1.83 augustss #endif
1817 1.83 augustss
1818 1.83 augustss for (sitd = sidone; sitd != NULL; sitd = sitdnext) {
1819 1.83 augustss xfer = sitd->xfer;
1820 1.83 augustss sitdnext = sitd->dnext;
1821 1.182.12.1 itohy sitd->flags |= OHCI_ITD_INTFIN;
1822 1.83 augustss DPRINTFN(1, ("ohci_process_done: sitd=%p xfer=%p hcpriv=%p\n",
1823 1.83 augustss sitd, xfer, xfer ? xfer->hcpriv : 0));
1824 1.83 augustss if (xfer == NULL)
1825 1.83 augustss continue;
1826 1.83 augustss if (xfer->status == USBD_CANCELLED ||
1827 1.83 augustss xfer->status == USBD_TIMEOUT) {
1828 1.83 augustss DPRINTF(("ohci_process_done: cancel/timeout %p\n",
1829 1.83 augustss xfer));
1830 1.83 augustss /* Handled by abort routine. */
1831 1.83 augustss continue;
1832 1.83 augustss }
1833 1.182.12.1 itohy if (xfer->pipe)
1834 1.182.12.1 itohy if (xfer->pipe->aborting)
1835 1.182.12.1 itohy continue; /*Ignore.*/
1836 1.83 augustss #ifdef DIAGNOSTIC
1837 1.83 augustss if (sitd->isdone)
1838 1.83 augustss printf("ohci_softintr: sitd=%p is done\n", sitd);
1839 1.83 augustss sitd->isdone = 1;
1840 1.83 augustss #endif
1841 1.182.12.1 itohy opipe = (struct ohci_pipe *)xfer->pipe;
1842 1.182.12.1 itohy if (opipe->aborting)
1843 1.182.12.1 itohy continue;
1844 1.182.12.1 itohy
1845 1.134 toshii if (sitd->flags & OHCI_CALL_DONE) {
1846 1.134 toshii ohci_soft_itd_t *next;
1847 1.134 toshii
1848 1.134 toshii opipe->u.iso.inuse -= xfer->nframes;
1849 1.134 toshii xfer->status = USBD_NORMAL_COMPLETION;
1850 1.182.12.1 itohy for (i = 0, sitd = xfer->hcpriv;;sitd = next) {
1851 1.134 toshii next = sitd->nextitd;
1852 1.182.12.1 itohy if (OHCI_ITD_GET_CC(sitd->itd.itd_flags) != OHCI_CC_NO_ERROR)
1853 1.134 toshii xfer->status = USBD_IOERROR;
1854 1.182.12.1 itohy
1855 1.182.12.1 itohy if (xfer->status == USBD_NORMAL_COMPLETION) {
1856 1.182.12.1 itohy iframes = OHCI_ITD_GET_FC(sitd->itd.itd_flags);
1857 1.134 toshii for (j = 0; j < iframes; i++, j++) {
1858 1.182.12.1 itohy len = O16TOH(sitd->itd.itd_offset[j]);
1859 1.182.12.1 itohy len =
1860 1.182.12.1 itohy ((OHCI_ITD_PSW_GET_CC(len) &
1861 1.158 toshii OHCI_CC_NOT_ACCESSED_MASK)
1862 1.182.12.1 itohy == OHCI_CC_NOT_ACCESSED) ?
1863 1.182.12.1 itohy 0 :
1864 1.182.12.1 itohy OHCI_ITD_PSW_LENGTH(len);
1865 1.134 toshii xfer->frlengths[i] = len;
1866 1.134 toshii }
1867 1.134 toshii }
1868 1.134 toshii if (sitd->flags & OHCI_CALL_DONE)
1869 1.134 toshii break;
1870 1.182.12.1 itohy }
1871 1.182.12.1 itohy for (sitd = xfer->hcpriv; sitd->xfer == xfer;
1872 1.182.12.1 itohy sitd = next) {
1873 1.182.12.1 itohy next = sitd->nextitd;
1874 1.134 toshii ohci_free_sitd(sc, sitd);
1875 1.83 augustss }
1876 1.134 toshii
1877 1.134 toshii s = splusb();
1878 1.182.12.1 itohy usb_transfer_complete_dma(xfer, &sc->sc_dmatag,
1879 1.182.12.1 itohy &OXFER(xfer)->dmabuf);
1880 1.134 toshii splx(s);
1881 1.83 augustss }
1882 1.83 augustss }
1883 1.83 augustss
1884 1.131 augustss #ifdef USB_USE_SOFTINTR
1885 1.119 augustss if (sc->sc_softwake) {
1886 1.119 augustss sc->sc_softwake = 0;
1887 1.119 augustss wakeup(&sc->sc_softwake);
1888 1.119 augustss }
1889 1.131 augustss #endif /* USB_USE_SOFTINTR */
1890 1.119 augustss
1891 1.72 augustss sc->sc_bus.intr_context--;
1892 1.105 augustss DPRINTFN(10,("ohci_softintr: done:\n"));
1893 1.1 augustss }
1894 1.1 augustss
1895 1.1 augustss void
1896 1.179 christos ohci_device_ctrl_done(usbd_xfer_handle xfer)
1897 1.1 augustss {
1898 1.140 gson DPRINTFN(10,("ohci_device_ctrl_done: xfer=%p\n", xfer));
1899 1.1 augustss
1900 1.38 augustss #ifdef DIAGNOSTIC
1901 1.53 augustss if (!(xfer->rqflags & URQ_REQUEST)) {
1902 1.140 gson panic("ohci_device_ctrl_done: not a request");
1903 1.1 augustss }
1904 1.38 augustss #endif
1905 1.1 augustss }
1906 1.1 augustss
1907 1.1 augustss void
1908 1.91 augustss ohci_device_intr_done(usbd_xfer_handle xfer)
1909 1.1 augustss {
1910 1.53 augustss struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
1911 1.38 augustss ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
1912 1.182.12.1 itohy usbd_status err;
1913 1.1 augustss
1914 1.140 gson DPRINTFN(10,("ohci_device_intr_done: xfer=%p, actlen=%d\n",
1915 1.53 augustss xfer, xfer->actlen));
1916 1.1 augustss
1917 1.53 augustss if (xfer->pipe->repeat) {
1918 1.182.12.1 itohy err = ohci_device_intr_insert(sc, xfer);
1919 1.182.12.1 itohy if (err) {
1920 1.182.12.1 itohy xfer->status = err;
1921 1.1 augustss return;
1922 1.1 augustss }
1923 1.1 augustss }
1924 1.1 augustss }
1925 1.1 augustss
1926 1.1 augustss void
1927 1.179 christos ohci_device_bulk_done(usbd_xfer_handle xfer)
1928 1.3 augustss {
1929 1.140 gson DPRINTFN(10,("ohci_device_bulk_done: xfer=%p, actlen=%d\n",
1930 1.53 augustss xfer, xfer->actlen));
1931 1.3 augustss }
1932 1.3 augustss
1933 1.3 augustss void
1934 1.91 augustss ohci_rhsc(ohci_softc_t *sc, usbd_xfer_handle xfer)
1935 1.1 augustss {
1936 1.1 augustss usbd_pipe_handle pipe;
1937 1.1 augustss u_char *p;
1938 1.1 augustss int i, m;
1939 1.1 augustss int hstatus;
1940 1.1 augustss
1941 1.1 augustss hstatus = OREAD4(sc, OHCI_RH_STATUS);
1942 1.120 augustss DPRINTF(("ohci_rhsc: sc=%p xfer=%p hstatus=0x%08x\n",
1943 1.53 augustss sc, xfer, hstatus));
1944 1.1 augustss
1945 1.53 augustss if (xfer == NULL) {
1946 1.1 augustss /* Just ignore the change. */
1947 1.1 augustss return;
1948 1.1 augustss }
1949 1.1 augustss
1950 1.53 augustss pipe = xfer->pipe;
1951 1.1 augustss
1952 1.182.12.1 itohy p = xfer->hcbuffer;
1953 1.53 augustss m = min(sc->sc_noport, xfer->length * 8 - 1);
1954 1.53 augustss memset(p, 0, xfer->length);
1955 1.1 augustss for (i = 1; i <= m; i++) {
1956 1.87 augustss /* Pick out CHANGE bits from the status reg. */
1957 1.1 augustss if (OREAD4(sc, OHCI_RH_PORT_STATUS(i)) >> 16)
1958 1.1 augustss p[i/8] |= 1 << (i%8);
1959 1.1 augustss }
1960 1.1 augustss DPRINTF(("ohci_rhsc: change=0x%02x\n", *p));
1961 1.53 augustss xfer->actlen = xfer->length;
1962 1.53 augustss xfer->status = USBD_NORMAL_COMPLETION;
1963 1.1 augustss
1964 1.182.12.1 itohy usb_transfer_complete_dma(xfer, &sc->sc_dmatag,
1965 1.182.12.1 itohy &OXFER(xfer)->dmabuf);
1966 1.38 augustss }
1967 1.38 augustss
1968 1.38 augustss void
1969 1.179 christos ohci_root_intr_done(usbd_xfer_handle xfer)
1970 1.65 augustss {
1971 1.65 augustss }
1972 1.65 augustss
1973 1.65 augustss void
1974 1.179 christos ohci_root_ctrl_done(usbd_xfer_handle xfer)
1975 1.38 augustss {
1976 1.1 augustss }
1977 1.1 augustss
1978 1.1 augustss /*
1979 1.1 augustss * Wait here until controller claims to have an interrupt.
1980 1.1 augustss * Then call ohci_intr and return. Use timeout to avoid waiting
1981 1.1 augustss * too long.
1982 1.1 augustss */
1983 1.1 augustss void
1984 1.91 augustss ohci_waitintr(ohci_softc_t *sc, usbd_xfer_handle xfer)
1985 1.1 augustss {
1986 1.163 augustss int timo;
1987 1.1 augustss u_int32_t intrs;
1988 1.1 augustss
1989 1.53 augustss xfer->status = USBD_IN_PROGRESS;
1990 1.163 augustss for (timo = xfer->timeout; timo >= 0; timo--) {
1991 1.20 augustss usb_delay_ms(&sc->sc_bus, 1);
1992 1.116 augustss if (sc->sc_dying)
1993 1.116 augustss break;
1994 1.1 augustss intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs;
1995 1.27 augustss DPRINTFN(15,("ohci_waitintr: 0x%04x\n", intrs));
1996 1.182.12.1 itohy #ifdef USB_DEBUG
1997 1.1 augustss if (ohcidebug > 15)
1998 1.1 augustss ohci_dumpregs(sc);
1999 1.1 augustss #endif
2000 1.1 augustss if (intrs) {
2001 1.53 augustss ohci_intr1(sc);
2002 1.53 augustss if (xfer->status != USBD_IN_PROGRESS)
2003 1.1 augustss return;
2004 1.1 augustss }
2005 1.1 augustss }
2006 1.15 augustss
2007 1.15 augustss /* Timeout */
2008 1.1 augustss DPRINTF(("ohci_waitintr: timeout\n"));
2009 1.53 augustss xfer->status = USBD_TIMEOUT;
2010 1.182.12.1 itohy usb_transfer_complete_dma(xfer, &sc->sc_dmatag,
2011 1.182.12.1 itohy &OXFER(xfer)->dmabuf);
2012 1.15 augustss /* XXX should free TD */
2013 1.5 augustss }
2014 1.5 augustss
2015 1.5 augustss void
2016 1.91 augustss ohci_poll(struct usbd_bus *bus)
2017 1.5 augustss {
2018 1.5 augustss ohci_softc_t *sc = (ohci_softc_t *)bus;
2019 1.182.12.1 itohy #ifdef USB_DEBUG
2020 1.105 augustss static int last;
2021 1.105 augustss int new;
2022 1.105 augustss new = OREAD4(sc, OHCI_INTERRUPT_STATUS);
2023 1.105 augustss if (new != last) {
2024 1.105 augustss DPRINTFN(10,("ohci_poll: intrs=0x%04x\n", new));
2025 1.105 augustss last = new;
2026 1.105 augustss }
2027 1.105 augustss #endif
2028 1.5 augustss
2029 1.5 augustss if (OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs)
2030 1.53 augustss ohci_intr1(sc);
2031 1.1 augustss }
2032 1.1 augustss
2033 1.1 augustss usbd_status
2034 1.91 augustss ohci_device_request(usbd_xfer_handle xfer)
2035 1.1 augustss {
2036 1.53 augustss struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
2037 1.53 augustss usb_device_request_t *req = &xfer->request;
2038 1.1 augustss usbd_device_handle dev = opipe->pipe.device;
2039 1.1 augustss ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
2040 1.77 augustss ohci_soft_td_t *setup, *stat, *next, *tail;
2041 1.1 augustss ohci_soft_ed_t *sed;
2042 1.1 augustss int isread;
2043 1.1 augustss int len;
2044 1.53 augustss usbd_status err;
2045 1.1 augustss int s;
2046 1.182.12.1 itohy ohci_physaddr_t dmaadr;
2047 1.1 augustss
2048 1.1 augustss isread = req->bmRequestType & UT_READ;
2049 1.1 augustss len = UGETW(req->wLength);
2050 1.1 augustss
2051 1.182.12.1 itohy DPRINTFN(3,("ohci_device_request: type=0x%02x, request=0x%02x, "
2052 1.14 augustss "wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n",
2053 1.1 augustss req->bmRequestType, req->bRequest, UGETW(req->wValue),
2054 1.182.12.1 itohy UGETW(req->wIndex), len, dev->address,
2055 1.1 augustss opipe->pipe.endpoint->edesc->bEndpointAddress));
2056 1.1 augustss
2057 1.60 augustss setup = opipe->tail.td;
2058 1.1 augustss stat = ohci_alloc_std(sc);
2059 1.53 augustss if (stat == NULL) {
2060 1.53 augustss err = USBD_NOMEM;
2061 1.1 augustss goto bad1;
2062 1.1 augustss }
2063 1.1 augustss tail = ohci_alloc_std(sc);
2064 1.53 augustss if (tail == NULL) {
2065 1.53 augustss err = USBD_NOMEM;
2066 1.1 augustss goto bad2;
2067 1.1 augustss }
2068 1.55 augustss tail->xfer = NULL;
2069 1.1 augustss
2070 1.1 augustss sed = opipe->sed;
2071 1.1 augustss opipe->u.ctl.length = len;
2072 1.77 augustss next = stat;
2073 1.77 augustss
2074 1.1 augustss /* Set up data transaction */
2075 1.1 augustss if (len != 0) {
2076 1.77 augustss ohci_soft_td_t *std = stat;
2077 1.77 augustss
2078 1.77 augustss err = ohci_alloc_std_chain(opipe, sc, len, isread, xfer,
2079 1.77 augustss std, &stat);
2080 1.77 augustss if (err)
2081 1.1 augustss goto bad3;
2082 1.182.12.1 itohy OHCI_STD_SYNC(sc, stat,
2083 1.182.12.1 itohy BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
2084 1.182.12.1 itohy stat = stat->nexttd; /* point at free TD */
2085 1.77 augustss /* Start toggle at 1 and then use the carried toggle. */
2086 1.168 augustss std->td.td_flags &= HTOO32(~OHCI_TD_TOGGLE_MASK);
2087 1.168 augustss std->td.td_flags |= HTOO32(OHCI_TD_TOGGLE_1);
2088 1.34 augustss }
2089 1.1 augustss
2090 1.123 augustss memcpy(KERNADDR(&opipe->u.ctl.reqdma, 0), req, sizeof *req);
2091 1.1 augustss
2092 1.168 augustss setup->td.td_flags = HTOO32(OHCI_TD_SETUP | OHCI_TD_NOCC |
2093 1.182.12.1 itohy OHCI_TD_TOGGLE_0 | OHCI_TD_SET_DI(6));
2094 1.168 augustss setup->td.td_cbp = HTOO32(DMAADDR(&opipe->u.ctl.reqdma, 0));
2095 1.1 augustss setup->nexttd = next;
2096 1.182.12.1 itohy dmaadr = OHCI_STD_DMAADDR(next);
2097 1.182.12.1 itohy setup->td.td_nexttd = HTOO32(dmaadr);
2098 1.168 augustss setup->td.td_be = HTOO32(O32TOH(setup->td.td_cbp) + sizeof *req - 1);
2099 1.77 augustss setup->len = 0;
2100 1.53 augustss setup->xfer = xfer;
2101 1.34 augustss setup->flags = 0;
2102 1.53 augustss xfer->hcpriv = setup;
2103 1.182.12.1 itohy OHCI_STD_SYNC(sc, setup, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
2104 1.1 augustss
2105 1.168 augustss stat->td.td_flags = HTOO32(
2106 1.77 augustss (isread ? OHCI_TD_OUT : OHCI_TD_IN) |
2107 1.77 augustss OHCI_TD_NOCC | OHCI_TD_TOGGLE_1 | OHCI_TD_SET_DI(1));
2108 1.39 augustss stat->td.td_cbp = 0;
2109 1.1 augustss stat->nexttd = tail;
2110 1.182.12.1 itohy dmaadr = OHCI_STD_DMAADDR(tail);
2111 1.182.12.1 itohy stat->td.td_nexttd = HTOO32(dmaadr);
2112 1.39 augustss stat->td.td_be = 0;
2113 1.77 augustss stat->flags = OHCI_CALL_DONE;
2114 1.1 augustss stat->len = 0;
2115 1.53 augustss stat->xfer = xfer;
2116 1.182.12.1 itohy OHCI_STD_SYNC(sc, stat, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
2117 1.1 augustss
2118 1.182.12.1 itohy #ifdef USB_DEBUG
2119 1.1 augustss if (ohcidebug > 5) {
2120 1.41 augustss DPRINTF(("ohci_device_request:\n"));
2121 1.168 augustss ohci_dump_ed(sc, sed);
2122 1.168 augustss ohci_dump_tds(sc, setup);
2123 1.1 augustss }
2124 1.1 augustss #endif
2125 1.1 augustss
2126 1.182.12.1 itohy USB_MEM_SYNC(&sc->sc_dmatag, &sc->sc_hccadma,
2127 1.182.12.1 itohy BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
2128 1.182.12.1 itohy
2129 1.1 augustss /* Insert ED in schedule */
2130 1.1 augustss s = splusb();
2131 1.182.12.1 itohy dmaadr = OHCI_STD_DMAADDR(tail);
2132 1.182.12.1 itohy sed->ed.ed_tailp = HTOO32(dmaadr);
2133 1.182.12.1 itohy OHCI_SED_SYNC(sc, sed, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
2134 1.60 augustss opipe->tail.td = tail;
2135 1.1 augustss OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
2136 1.53 augustss if (xfer->timeout && !sc->sc_bus.use_polling) {
2137 1.182.12.1 itohy usb_callout(xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
2138 1.80 augustss ohci_timeout, xfer);
2139 1.15 augustss }
2140 1.1 augustss splx(s);
2141 1.1 augustss
2142 1.182.12.1 itohy #ifdef USB_DEBUG
2143 1.113 augustss if (ohcidebug > 20) {
2144 1.77 augustss delay(10000);
2145 1.41 augustss DPRINTF(("ohci_device_request: status=%x\n",
2146 1.41 augustss OREAD4(sc, OHCI_COMMAND_STATUS)));
2147 1.113 augustss ohci_dumpregs(sc);
2148 1.113 augustss printf("ctrl head:\n");
2149 1.168 augustss ohci_dump_ed(sc, sc->sc_ctrl_head);
2150 1.113 augustss printf("sed:\n");
2151 1.168 augustss ohci_dump_ed(sc, sed);
2152 1.168 augustss ohci_dump_tds(sc, setup);
2153 1.1 augustss }
2154 1.1 augustss #endif
2155 1.1 augustss
2156 1.1 augustss return (USBD_NORMAL_COMPLETION);
2157 1.1 augustss
2158 1.1 augustss bad3:
2159 1.1 augustss ohci_free_std(sc, tail);
2160 1.1 augustss bad2:
2161 1.1 augustss ohci_free_std(sc, stat);
2162 1.1 augustss bad1:
2163 1.53 augustss return (err);
2164 1.1 augustss }
2165 1.1 augustss
2166 1.1 augustss /*
2167 1.1 augustss * Add an ED to the schedule. Called at splusb().
2168 1.1 augustss */
2169 1.1 augustss void
2170 1.168 augustss ohci_add_ed(ohci_softc_t *sc, ohci_soft_ed_t *sed, ohci_soft_ed_t *head)
2171 1.1 augustss {
2172 1.182.12.1 itohy ohci_physaddr_t dmaadr;
2173 1.182.12.1 itohy
2174 1.113 augustss DPRINTFN(8,("ohci_add_ed: sed=%p head=%p\n", sed, head));
2175 1.113 augustss
2176 1.46 augustss SPLUSBCHECK;
2177 1.1 augustss sed->next = head->next;
2178 1.39 augustss sed->ed.ed_nexted = head->ed.ed_nexted;
2179 1.1 augustss head->next = sed;
2180 1.182.12.1 itohy dmaadr = OHCI_SED_DMAADDR(sed);
2181 1.182.12.1 itohy head->ed.ed_nexted = HTOO32(dmaadr);
2182 1.1 augustss }
2183 1.1 augustss
2184 1.1 augustss /*
2185 1.3 augustss * Remove an ED from the schedule. Called at splusb().
2186 1.3 augustss */
2187 1.3 augustss void
2188 1.91 augustss ohci_rem_ed(ohci_soft_ed_t *sed, ohci_soft_ed_t *head)
2189 1.3 augustss {
2190 1.120 augustss ohci_soft_ed_t *p;
2191 1.3 augustss
2192 1.46 augustss SPLUSBCHECK;
2193 1.46 augustss
2194 1.3 augustss /* XXX */
2195 1.133 toshii for (p = head; p != NULL && p->next != sed; p = p->next)
2196 1.3 augustss ;
2197 1.55 augustss if (p == NULL)
2198 1.128 provos panic("ohci_rem_ed: ED not found");
2199 1.3 augustss p->next = sed->next;
2200 1.39 augustss p->ed.ed_nexted = sed->ed.ed_nexted;
2201 1.3 augustss }
2202 1.3 augustss
2203 1.3 augustss /*
2204 1.1 augustss * When a transfer is completed the TD is added to the done queue by
2205 1.1 augustss * the host controller. This queue is the processed by software.
2206 1.1 augustss * Unfortunately the queue contains the physical address of the TD
2207 1.9 augustss * and we have no simple way to translate this back to a kernel address.
2208 1.182.12.1 itohy * To make the translation possible (and fast) we use the chunk of
2209 1.182.12.1 itohy * TDs used for allocation.
2210 1.1 augustss */
2211 1.1 augustss
2212 1.1 augustss ohci_soft_td_t *
2213 1.182.12.1 itohy ohci_find_td(ohci_softc_t *sc, ohci_physaddr_t a)
2214 1.1 augustss {
2215 1.182.12.1 itohy struct ohci_mem_desc *om;
2216 1.1 augustss ohci_soft_td_t *std;
2217 1.182.12.1 itohy size_t off;
2218 1.1 augustss
2219 1.182.12.1 itohy /* if these are present they should be masked out at an earlier
2220 1.182.12.1 itohy * stage.
2221 1.182.12.1 itohy */
2222 1.182.12.1 itohy USB_KASSERT2((a&~OHCI_HEADMASK) == 0, ("%s: 0x%b has lower bits set\n",
2223 1.182.12.1 itohy USBDEVNAME(sc->sc_bus.bdev),
2224 1.182.12.1 itohy (int) a, "\20\1HALT\2TOGGLE"));
2225 1.182.12.1 itohy
2226 1.182.12.1 itohy SIMPLEQ_FOREACH(om, &sc->sc_std_chunks, om_next) {
2227 1.182.12.1 itohy if (a >= om->om_topdma &&
2228 1.182.12.1 itohy a < om->om_topdma + OHCI_STD_SIZE * OHCI_STD_CHUNK) {
2229 1.182.12.1 itohy off = a - om->om_topdma;
2230 1.182.12.1 itohy if (off % OHCI_STD_SIZE) {
2231 1.182.12.1 itohy #ifdef DIAGNOSTIC
2232 1.182.12.1 itohy printf("ohci_find_td: 0x%x bad address\n",
2233 1.182.12.1 itohy (unsigned)a);
2234 1.182.12.1 itohy #endif
2235 1.182.12.1 itohy break;
2236 1.182.12.1 itohy }
2237 1.182.12.1 itohy std = (ohci_soft_td_t *)(om->om_top + off);
2238 1.182.12.1 itohy if (std->flags & OHCI_TD_FREE) {
2239 1.182.12.1 itohy #ifdef DIAGNOSTIC
2240 1.182.12.1 itohy printf("ohci_find_td: 0x%x: free td\n",
2241 1.182.12.1 itohy (unsigned)OHCI_STD_DMAADDR(std));
2242 1.182.12.1 itohy #endif
2243 1.182.12.1 itohy break;
2244 1.182.12.1 itohy }
2245 1.182.12.1 itohy return std;
2246 1.182.12.1 itohy }
2247 1.182.12.1 itohy }
2248 1.83 augustss
2249 1.182.12.1 itohy DPRINTF(("%s: ohci_find_td: addr 0x%08lx not found\n",
2250 1.182.12.1 itohy USBDEVNAME(sc->sc_bus.bdev), (u_long) a));
2251 1.182.12.1 itohy return (NULL);
2252 1.83 augustss }
2253 1.83 augustss
2254 1.83 augustss ohci_soft_itd_t *
2255 1.182.12.1 itohy ohci_find_itd(ohci_softc_t *sc, ohci_physaddr_t a)
2256 1.83 augustss {
2257 1.182.12.1 itohy struct ohci_mem_desc *om;
2258 1.83 augustss ohci_soft_itd_t *sitd;
2259 1.182.12.1 itohy size_t off;
2260 1.83 augustss
2261 1.182.12.1 itohy SIMPLEQ_FOREACH(om, &sc->sc_sitd_chunks, om_next) {
2262 1.182.12.1 itohy if (a >= om->om_topdma &&
2263 1.182.12.1 itohy a < om->om_topdma + OHCI_SITD_SIZE * OHCI_SITD_CHUNK) {
2264 1.182.12.1 itohy off = a - om->om_topdma;
2265 1.182.12.1 itohy if (off % OHCI_SITD_SIZE) {
2266 1.182.12.1 itohy #ifdef DIAGNOSTIC
2267 1.182.12.1 itohy printf("ohci_find_itd: 0x%x bad address\n",
2268 1.182.12.1 itohy (unsigned)a);
2269 1.182.12.1 itohy #endif
2270 1.182.12.1 itohy break;
2271 1.182.12.1 itohy }
2272 1.182.12.1 itohy sitd = (ohci_soft_itd_t *)(om->om_top + off);
2273 1.182.12.1 itohy if (sitd->flags & OHCI_ITD_FREE) {
2274 1.182.12.1 itohy #ifdef DIAGNOSTIC
2275 1.182.12.1 itohy printf("ohci_find_itd: 0x%x: free itd\n",
2276 1.182.12.1 itohy (unsigned)OHCI_SITD_DMAADDR(sitd));
2277 1.182.12.1 itohy #endif
2278 1.182.12.1 itohy break;
2279 1.182.12.1 itohy }
2280 1.182.12.1 itohy return sitd;
2281 1.182.12.1 itohy }
2282 1.182.12.1 itohy }
2283 1.83 augustss return (NULL);
2284 1.1 augustss }
2285 1.1 augustss
2286 1.1 augustss void
2287 1.91 augustss ohci_timeout(void *addr)
2288 1.1 augustss {
2289 1.114 augustss struct ohci_xfer *oxfer = addr;
2290 1.116 augustss struct ohci_pipe *opipe = (struct ohci_pipe *)oxfer->xfer.pipe;
2291 1.116 augustss ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
2292 1.114 augustss
2293 1.114 augustss DPRINTF(("ohci_timeout: oxfer=%p\n", oxfer));
2294 1.114 augustss
2295 1.116 augustss if (sc->sc_dying) {
2296 1.116 augustss ohci_abort_xfer(&oxfer->xfer, USBD_TIMEOUT);
2297 1.116 augustss return;
2298 1.116 augustss }
2299 1.116 augustss
2300 1.114 augustss /* Execute the abort in a process context. */
2301 1.178 joerg usb_add_task(oxfer->xfer.pipe->device, &oxfer->abort_task,
2302 1.178 joerg USB_TASKQ_HC);
2303 1.114 augustss }
2304 1.114 augustss
2305 1.114 augustss void
2306 1.114 augustss ohci_timeout_task(void *addr)
2307 1.114 augustss {
2308 1.53 augustss usbd_xfer_handle xfer = addr;
2309 1.48 augustss int s;
2310 1.1 augustss
2311 1.114 augustss DPRINTF(("ohci_timeout_task: xfer=%p\n", xfer));
2312 1.45 augustss
2313 1.48 augustss s = splusb();
2314 1.54 augustss ohci_abort_xfer(xfer, USBD_TIMEOUT);
2315 1.48 augustss splx(s);
2316 1.1 augustss }
2317 1.1 augustss
2318 1.182.12.1 itohy #ifdef USB_DEBUG
2319 1.1 augustss void
2320 1.168 augustss ohci_dump_tds(ohci_softc_t *sc, ohci_soft_td_t *std)
2321 1.1 augustss {
2322 1.1 augustss for (; std; std = std->nexttd)
2323 1.168 augustss ohci_dump_td(sc, std);
2324 1.1 augustss }
2325 1.1 augustss
2326 1.1 augustss void
2327 1.168 augustss ohci_dump_td(ohci_softc_t *sc, ohci_soft_td_t *std)
2328 1.1 augustss {
2329 1.92 tv char sbuf[128];
2330 1.92 tv
2331 1.168 augustss bitmask_snprintf((u_int32_t)O32TOH(std->td.td_flags),
2332 1.92 tv "\20\23R\24OUT\25IN\31TOG1\32SETTOGGLE",
2333 1.92 tv sbuf, sizeof(sbuf));
2334 1.92 tv
2335 1.107 augustss printf("TD(%p) at %08lx: %s delay=%d ec=%d cc=%d\ncbp=0x%08lx "
2336 1.120 augustss "nexttd=0x%08lx be=0x%08lx\n",
2337 1.182.12.1 itohy std, (u_long)OHCI_STD_DMAADDR(std), sbuf,
2338 1.168 augustss OHCI_TD_GET_DI(O32TOH(std->td.td_flags)),
2339 1.168 augustss OHCI_TD_GET_EC(O32TOH(std->td.td_flags)),
2340 1.168 augustss OHCI_TD_GET_CC(O32TOH(std->td.td_flags)),
2341 1.168 augustss (u_long)O32TOH(std->td.td_cbp),
2342 1.168 augustss (u_long)O32TOH(std->td.td_nexttd),
2343 1.168 augustss (u_long)O32TOH(std->td.td_be));
2344 1.1 augustss }
2345 1.1 augustss
2346 1.1 augustss void
2347 1.168 augustss ohci_dump_itd(ohci_softc_t *sc, ohci_soft_itd_t *sitd)
2348 1.83 augustss {
2349 1.83 augustss int i;
2350 1.83 augustss
2351 1.107 augustss printf("ITD(%p) at %08lx: sf=%d di=%d fc=%d cc=%d\n"
2352 1.120 augustss "bp0=0x%08lx next=0x%08lx be=0x%08lx\n",
2353 1.182.12.1 itohy sitd, (u_long)OHCI_SITD_DMAADDR(sitd),
2354 1.168 augustss OHCI_ITD_GET_SF(O32TOH(sitd->itd.itd_flags)),
2355 1.168 augustss OHCI_ITD_GET_DI(O32TOH(sitd->itd.itd_flags)),
2356 1.168 augustss OHCI_ITD_GET_FC(O32TOH(sitd->itd.itd_flags)),
2357 1.168 augustss OHCI_ITD_GET_CC(O32TOH(sitd->itd.itd_flags)),
2358 1.168 augustss (u_long)O32TOH(sitd->itd.itd_bp0),
2359 1.168 augustss (u_long)O32TOH(sitd->itd.itd_nextitd),
2360 1.168 augustss (u_long)O32TOH(sitd->itd.itd_be));
2361 1.83 augustss for (i = 0; i < OHCI_ITD_NOFFSET; i++)
2362 1.107 augustss printf("offs[%d]=0x%04x ", i,
2363 1.168 augustss (u_int)O16TOH(sitd->itd.itd_offset[i]));
2364 1.107 augustss printf("\n");
2365 1.83 augustss }
2366 1.83 augustss
2367 1.83 augustss void
2368 1.168 augustss ohci_dump_itds(ohci_softc_t *sc, ohci_soft_itd_t *sitd)
2369 1.83 augustss {
2370 1.83 augustss for (; sitd; sitd = sitd->nextitd)
2371 1.168 augustss ohci_dump_itd(sc, sitd);
2372 1.83 augustss }
2373 1.83 augustss
2374 1.83 augustss void
2375 1.168 augustss ohci_dump_ed(ohci_softc_t *sc, ohci_soft_ed_t *sed)
2376 1.1 augustss {
2377 1.92 tv char sbuf[128], sbuf2[128];
2378 1.92 tv
2379 1.168 augustss bitmask_snprintf((u_int32_t)O32TOH(sed->ed.ed_flags),
2380 1.92 tv "\20\14OUT\15IN\16LOWSPEED\17SKIP\20ISO",
2381 1.92 tv sbuf, sizeof(sbuf));
2382 1.168 augustss bitmask_snprintf((u_int32_t)O32TOH(sed->ed.ed_headp),
2383 1.92 tv "\20\1HALT\2CARRY", sbuf2, sizeof(sbuf2));
2384 1.92 tv
2385 1.107 augustss printf("ED(%p) at 0x%08lx: addr=%d endpt=%d maxp=%d flags=%s\ntailp=0x%08lx "
2386 1.92 tv "headflags=%s headp=0x%08lx nexted=0x%08lx\n",
2387 1.182.12.1 itohy sed, (u_long)OHCI_SED_DMAADDR(sed),
2388 1.168 augustss OHCI_ED_GET_FA(O32TOH(sed->ed.ed_flags)),
2389 1.168 augustss OHCI_ED_GET_EN(O32TOH(sed->ed.ed_flags)),
2390 1.168 augustss OHCI_ED_GET_MAXP(O32TOH(sed->ed.ed_flags)), sbuf,
2391 1.168 augustss (u_long)O32TOH(sed->ed.ed_tailp), sbuf2,
2392 1.168 augustss (u_long)O32TOH(sed->ed.ed_headp),
2393 1.168 augustss (u_long)O32TOH(sed->ed.ed_nexted));
2394 1.1 augustss }
2395 1.1 augustss #endif
2396 1.1 augustss
2397 1.1 augustss usbd_status
2398 1.91 augustss ohci_open(usbd_pipe_handle pipe)
2399 1.1 augustss {
2400 1.1 augustss usbd_device_handle dev = pipe->device;
2401 1.1 augustss ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
2402 1.1 augustss usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
2403 1.1 augustss struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
2404 1.1 augustss u_int8_t addr = dev->address;
2405 1.60 augustss u_int8_t xfertype = ed->bmAttributes & UE_XFERTYPE;
2406 1.1 augustss ohci_soft_ed_t *sed;
2407 1.1 augustss ohci_soft_td_t *std;
2408 1.60 augustss ohci_soft_itd_t *sitd;
2409 1.60 augustss ohci_physaddr_t tdphys;
2410 1.60 augustss u_int32_t fmt;
2411 1.53 augustss usbd_status err;
2412 1.1 augustss int s;
2413 1.64 augustss int ival;
2414 1.1 augustss
2415 1.1 augustss DPRINTFN(1, ("ohci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
2416 1.1 augustss pipe, addr, ed->bEndpointAddress, sc->sc_addr));
2417 1.81 augustss
2418 1.116 augustss if (sc->sc_dying)
2419 1.116 augustss return (USBD_IOERROR);
2420 1.116 augustss
2421 1.90 thorpej std = NULL;
2422 1.90 thorpej sed = NULL;
2423 1.90 thorpej
2424 1.1 augustss if (addr == sc->sc_addr) {
2425 1.1 augustss switch (ed->bEndpointAddress) {
2426 1.1 augustss case USB_CONTROL_ENDPOINT:
2427 1.1 augustss pipe->methods = &ohci_root_ctrl_methods;
2428 1.1 augustss break;
2429 1.40 augustss case UE_DIR_IN | OHCI_INTR_ENDPT:
2430 1.1 augustss pipe->methods = &ohci_root_intr_methods;
2431 1.1 augustss break;
2432 1.1 augustss default:
2433 1.1 augustss return (USBD_INVAL);
2434 1.1 augustss }
2435 1.1 augustss } else {
2436 1.1 augustss sed = ohci_alloc_sed(sc);
2437 1.53 augustss if (sed == NULL)
2438 1.1 augustss goto bad0;
2439 1.1 augustss opipe->sed = sed;
2440 1.60 augustss if (xfertype == UE_ISOCHRONOUS) {
2441 1.182.12.1 itohy sitd = ohci_alloc_sitd_norsv(sc);
2442 1.127 augustss if (sitd == NULL)
2443 1.60 augustss goto bad1;
2444 1.60 augustss opipe->tail.itd = sitd;
2445 1.182.12.1 itohy opipe->aborting = 0;
2446 1.182.12.1 itohy tdphys = OHCI_SITD_DMAADDR(sitd);
2447 1.60 augustss fmt = OHCI_ED_FORMAT_ISO;
2448 1.83 augustss if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN)
2449 1.83 augustss fmt |= OHCI_ED_DIR_IN;
2450 1.83 augustss else
2451 1.83 augustss fmt |= OHCI_ED_DIR_OUT;
2452 1.60 augustss } else {
2453 1.182.12.1 itohy std = ohci_alloc_std_norsv(sc);
2454 1.127 augustss if (std == NULL)
2455 1.60 augustss goto bad1;
2456 1.60 augustss opipe->tail.td = std;
2457 1.182.12.1 itohy tdphys = OHCI_STD_DMAADDR(std);
2458 1.83 augustss fmt = OHCI_ED_FORMAT_GEN | OHCI_ED_DIR_TD;
2459 1.60 augustss }
2460 1.168 augustss sed->ed.ed_flags = HTOO32(
2461 1.120 augustss OHCI_ED_SET_FA(addr) |
2462 1.147 mycroft OHCI_ED_SET_EN(UE_GET_ADDR(ed->bEndpointAddress)) |
2463 1.109 augustss (dev->speed == USB_SPEED_LOW ? OHCI_ED_SPEED : 0) |
2464 1.109 augustss fmt |
2465 1.182.12.1 itohy OHCI_ED_SET_MAXP(UE_MAXPKTSZ(ed)));
2466 1.182.12.1 itohy sed->ed.ed_headp = HTOO32(tdphys |
2467 1.182.12.1 itohy (pipe->endpoint->savedtoggle ? OHCI_TOGGLECARRY : 0));
2468 1.182.12.1 itohy sed->ed.ed_tailp = HTOO32(tdphys);
2469 1.1 augustss
2470 1.60 augustss switch (xfertype) {
2471 1.1 augustss case UE_CONTROL:
2472 1.1 augustss pipe->methods = &ohci_device_ctrl_methods;
2473 1.182.12.1 itohy err = usb_allocmem(&sc->sc_dmatag,
2474 1.120 augustss sizeof(usb_device_request_t),
2475 1.53 augustss 0, &opipe->u.ctl.reqdma);
2476 1.53 augustss if (err)
2477 1.1 augustss goto bad;
2478 1.1 augustss s = splusb();
2479 1.168 augustss ohci_add_ed(sc, sed, sc->sc_ctrl_head);
2480 1.1 augustss splx(s);
2481 1.1 augustss break;
2482 1.1 augustss case UE_INTERRUPT:
2483 1.1 augustss pipe->methods = &ohci_device_intr_methods;
2484 1.64 augustss ival = pipe->interval;
2485 1.64 augustss if (ival == USBD_DEFAULT_INTERVAL)
2486 1.64 augustss ival = ed->bInterval;
2487 1.64 augustss return (ohci_device_setintr(sc, opipe, ival));
2488 1.1 augustss case UE_ISOCHRONOUS:
2489 1.60 augustss pipe->methods = &ohci_device_isoc_methods;
2490 1.60 augustss return (ohci_setup_isoc(pipe));
2491 1.1 augustss case UE_BULK:
2492 1.3 augustss pipe->methods = &ohci_device_bulk_methods;
2493 1.3 augustss s = splusb();
2494 1.168 augustss ohci_add_ed(sc, sed, sc->sc_bulk_head);
2495 1.3 augustss splx(s);
2496 1.3 augustss break;
2497 1.1 augustss }
2498 1.1 augustss }
2499 1.1 augustss return (USBD_NORMAL_COMPLETION);
2500 1.1 augustss
2501 1.1 augustss bad:
2502 1.90 thorpej if (std != NULL)
2503 1.90 thorpej ohci_free_std(sc, std);
2504 1.1 augustss bad1:
2505 1.90 thorpej if (sed != NULL)
2506 1.90 thorpej ohci_free_sed(sc, sed);
2507 1.1 augustss bad0:
2508 1.1 augustss return (USBD_NOMEM);
2509 1.120 augustss
2510 1.1 augustss }
2511 1.1 augustss
2512 1.1 augustss /*
2513 1.34 augustss * Close a reqular pipe.
2514 1.34 augustss * Assumes that there are no pending transactions.
2515 1.34 augustss */
2516 1.34 augustss void
2517 1.91 augustss ohci_close_pipe(usbd_pipe_handle pipe, ohci_soft_ed_t *head)
2518 1.34 augustss {
2519 1.34 augustss struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
2520 1.34 augustss ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
2521 1.34 augustss ohci_soft_ed_t *sed = opipe->sed;
2522 1.34 augustss int s;
2523 1.34 augustss
2524 1.34 augustss s = splusb();
2525 1.34 augustss #ifdef DIAGNOSTIC
2526 1.168 augustss sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP);
2527 1.168 augustss if ((O32TOH(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
2528 1.168 augustss (O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK)) {
2529 1.34 augustss ohci_soft_td_t *std;
2530 1.182.12.1 itohy std = ohci_find_td(sc, O32TOH(sed->ed.ed_headp));
2531 1.34 augustss printf("ohci_close_pipe: pipe not empty sed=%p hd=0x%x "
2532 1.34 augustss "tl=0x%x pipe=%p, std=%p\n", sed,
2533 1.168 augustss (int)O32TOH(sed->ed.ed_headp),
2534 1.168 augustss (int)O32TOH(sed->ed.ed_tailp),
2535 1.34 augustss pipe, std);
2536 1.107 augustss #ifdef USB_DEBUG
2537 1.107 augustss usbd_dump_pipe(&opipe->pipe);
2538 1.107 augustss #endif
2539 1.182.12.1 itohy #ifdef USB_DEBUG
2540 1.168 augustss ohci_dump_ed(sc, sed);
2541 1.106 augustss if (std)
2542 1.168 augustss ohci_dump_td(sc, std);
2543 1.106 augustss #endif
2544 1.34 augustss usb_delay_ms(&sc->sc_bus, 2);
2545 1.168 augustss if ((O32TOH(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
2546 1.168 augustss (O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK))
2547 1.34 augustss printf("ohci_close_pipe: pipe still not empty\n");
2548 1.34 augustss }
2549 1.34 augustss #endif
2550 1.34 augustss ohci_rem_ed(sed, head);
2551 1.133 toshii /* Make sure the host controller is not touching this ED */
2552 1.133 toshii usb_delay_ms(&sc->sc_bus, 1);
2553 1.34 augustss splx(s);
2554 1.182.12.1 itohy pipe->endpoint->savedtoggle =
2555 1.182.12.1 itohy (O32TOH(sed->ed.ed_headp) & OHCI_TOGGLECARRY) ? 1 : 0;
2556 1.34 augustss ohci_free_sed(sc, opipe->sed);
2557 1.34 augustss }
2558 1.34 augustss
2559 1.120 augustss /*
2560 1.34 augustss * Abort a device request.
2561 1.34 augustss * If this routine is called at splusb() it guarantees that the request
2562 1.34 augustss * will be removed from the hardware scheduling and that the callback
2563 1.34 augustss * for it will be called with USBD_CANCELLED status.
2564 1.34 augustss * It's impossible to guarantee that the requested transfer will not
2565 1.34 augustss * have happened since the hardware runs concurrently.
2566 1.34 augustss * If the transaction has already happened we rely on the ordinary
2567 1.34 augustss * interrupt processing to process it.
2568 1.34 augustss */
2569 1.34 augustss void
2570 1.91 augustss ohci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
2571 1.34 augustss {
2572 1.182.12.1 itohy struct ohci_xfer *oxfer = OXFER(xfer);
2573 1.53 augustss struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
2574 1.106 augustss ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
2575 1.106 augustss ohci_soft_ed_t *sed = opipe->sed;
2576 1.106 augustss ohci_soft_td_t *p, *n;
2577 1.106 augustss ohci_physaddr_t headp;
2578 1.182.12.1 itohy ohci_physaddr_t dmaadr;
2579 1.106 augustss int s, hit;
2580 1.159 augustss int wake;
2581 1.34 augustss
2582 1.106 augustss DPRINTF(("ohci_abort_xfer: xfer=%p pipe=%p sed=%p\n", xfer, opipe,sed));
2583 1.34 augustss
2584 1.116 augustss if (sc->sc_dying) {
2585 1.116 augustss /* If we're dying, just do the software part. */
2586 1.116 augustss s = splusb();
2587 1.116 augustss xfer->status = status; /* make software ignore it */
2588 1.121 tsutsui usb_uncallout(xfer->timeout_handle, ohci_timeout, xfer);
2589 1.182.12.1 itohy usb_rem_task(xfer->pipe->device, &oxfer->abort_task);
2590 1.182.12.1 itohy usb_transfer_complete_dma(xfer, &sc->sc_dmatag,
2591 1.182.12.1 itohy &oxfer->dmabuf);
2592 1.116 augustss splx(s);
2593 1.170 christos return;
2594 1.116 augustss }
2595 1.116 augustss
2596 1.106 augustss if (xfer->device->bus->intr_context || !curproc)
2597 1.128 provos panic("ohci_abort_xfer: not in process context");
2598 1.34 augustss
2599 1.106 augustss /*
2600 1.159 augustss * If an abort is already in progress then just wait for it to
2601 1.159 augustss * complete and return.
2602 1.159 augustss */
2603 1.182.12.1 itohy if (oxfer->ohci_xfer_flags & OHCI_XFER_ABORTING) {
2604 1.159 augustss DPRINTFN(2, ("ohci_abort_xfer: already aborting\n"));
2605 1.182.12.1 itohy /* No need to wait if we're aborting from a timeout. */
2606 1.159 augustss if (status == USBD_TIMEOUT)
2607 1.182.12.1 itohy return;
2608 1.159 augustss /* Override the status which might be USBD_TIMEOUT. */
2609 1.159 augustss xfer->status = status;
2610 1.159 augustss DPRINTFN(2, ("ohci_abort_xfer: waiting for abort to finish\n"));
2611 1.182.12.1 itohy oxfer->ohci_xfer_flags |= OHCI_XFER_ABORTWAIT;
2612 1.182.12.1 itohy while (oxfer->ohci_xfer_flags & OHCI_XFER_ABORTING)
2613 1.182.12.1 itohy tsleep(&oxfer->ohci_xfer_flags, PZERO, "ohciaw", 0);
2614 1.159 augustss return;
2615 1.159 augustss }
2616 1.159 augustss
2617 1.159 augustss /*
2618 1.106 augustss * Step 1: Make interrupt routine and hardware ignore xfer.
2619 1.106 augustss */
2620 1.106 augustss s = splusb();
2621 1.182.12.1 itohy oxfer->ohci_xfer_flags |= OHCI_XFER_ABORTING;
2622 1.106 augustss xfer->status = status; /* make software ignore it */
2623 1.81 augustss usb_uncallout(xfer->timeout_handle, ohci_timeout, xfer);
2624 1.182.12.1 itohy usb_rem_task(xfer->pipe->device, &oxfer->abort_task);
2625 1.106 augustss splx(s);
2626 1.54 augustss DPRINTFN(1,("ohci_abort_xfer: stop ed=%p\n", sed));
2627 1.168 augustss sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); /* force hardware skip */
2628 1.34 augustss
2629 1.120 augustss /*
2630 1.106 augustss * Step 2: Wait until we know hardware has finished any possible
2631 1.106 augustss * use of the xfer. Also make sure the soft interrupt routine
2632 1.106 augustss * has run.
2633 1.106 augustss */
2634 1.119 augustss usb_delay_ms(opipe->pipe.device->bus, 20); /* Hardware finishes in 1ms */
2635 1.119 augustss s = splusb();
2636 1.131 augustss #ifdef USB_USE_SOFTINTR
2637 1.119 augustss sc->sc_softwake = 1;
2638 1.131 augustss #endif /* USB_USE_SOFTINTR */
2639 1.119 augustss usb_schedsoftintr(&sc->sc_bus);
2640 1.131 augustss #ifdef USB_USE_SOFTINTR
2641 1.119 augustss tsleep(&sc->sc_softwake, PZERO, "ohciab", 0);
2642 1.131 augustss #endif /* USB_USE_SOFTINTR */
2643 1.119 augustss splx(s);
2644 1.119 augustss
2645 1.120 augustss /*
2646 1.106 augustss * Step 3: Remove any vestiges of the xfer from the hardware.
2647 1.106 augustss * The complication here is that the hardware may have executed
2648 1.106 augustss * beyond the xfer we're trying to abort. So as we're scanning
2649 1.106 augustss * the TDs of this xfer we check if the hardware points to
2650 1.106 augustss * any of them.
2651 1.106 augustss */
2652 1.106 augustss s = splusb(); /* XXX why? */
2653 1.53 augustss p = xfer->hcpriv;
2654 1.34 augustss #ifdef DIAGNOSTIC
2655 1.55 augustss if (p == NULL) {
2656 1.182.12.1 itohy oxfer->ohci_xfer_flags &= ~OHCI_XFER_ABORTING; /* XXX */
2657 1.102 augustss splx(s);
2658 1.106 augustss printf("ohci_abort_xfer: hcpriv is NULL\n");
2659 1.38 augustss return;
2660 1.38 augustss }
2661 1.34 augustss #endif
2662 1.182.12.1 itohy #ifdef USB_DEBUG
2663 1.106 augustss if (ohcidebug > 1) {
2664 1.106 augustss DPRINTF(("ohci_abort_xfer: sed=\n"));
2665 1.168 augustss ohci_dump_ed(sc, sed);
2666 1.168 augustss ohci_dump_tds(sc, p);
2667 1.106 augustss }
2668 1.106 augustss #endif
2669 1.168 augustss headp = O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK;
2670 1.106 augustss hit = 0;
2671 1.53 augustss for (; p->xfer == xfer; p = n) {
2672 1.182.12.1 itohy hit |= headp == OHCI_STD_DMAADDR(p);
2673 1.38 augustss n = p->nexttd;
2674 1.38 augustss ohci_free_std(sc, p);
2675 1.34 augustss }
2676 1.106 augustss /* Zap headp register if hardware pointed inside the xfer. */
2677 1.106 augustss if (hit) {
2678 1.150 mycroft DPRINTFN(1,("ohci_abort_xfer: set hd=0x%08x, tl=0x%08x\n",
2679 1.182.12.1 itohy (int)OHCI_STD_DMAADDR(p), (int)O32TOH(sed->ed.ed_tailp)));
2680 1.182.12.1 itohy dmaadr = OHCI_STD_DMAADDR(p);
2681 1.182.12.1 itohy sed->ed.ed_headp = HTOO32(dmaadr); /* unlink TDs */
2682 1.106 augustss } else {
2683 1.106 augustss DPRINTFN(1,("ohci_abort_xfer: no hit\n"));
2684 1.106 augustss }
2685 1.34 augustss
2686 1.106 augustss /*
2687 1.106 augustss * Step 4: Turn on hardware again.
2688 1.106 augustss */
2689 1.168 augustss sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); /* remove hardware skip */
2690 1.38 augustss
2691 1.106 augustss /*
2692 1.106 augustss * Step 5: Execute callback.
2693 1.106 augustss */
2694 1.182.12.1 itohy /* Do the wakeup first to avoid touching the xfer after the callback. */
2695 1.182.12.1 itohy wake = oxfer->ohci_xfer_flags & OHCI_XFER_ABORTWAIT;
2696 1.182.12.1 itohy oxfer->ohci_xfer_flags &= ~(OHCI_XFER_ABORTING | OHCI_XFER_ABORTWAIT);
2697 1.182.12.1 itohy usb_transfer_complete_dma(xfer, &sc->sc_dmatag, &oxfer->dmabuf);
2698 1.159 augustss if (wake)
2699 1.182.12.1 itohy wakeup(&oxfer->ohci_xfer_flags);
2700 1.38 augustss
2701 1.34 augustss splx(s);
2702 1.34 augustss }
2703 1.34 augustss
2704 1.34 augustss /*
2705 1.1 augustss * Data structures and routines to emulate the root hub.
2706 1.1 augustss */
2707 1.82 augustss Static usb_device_descriptor_t ohci_devd = {
2708 1.1 augustss USB_DEVICE_DESCRIPTOR_SIZE,
2709 1.1 augustss UDESC_DEVICE, /* type */
2710 1.1 augustss {0x00, 0x01}, /* USB version */
2711 1.74 augustss UDCLASS_HUB, /* class */
2712 1.74 augustss UDSUBCLASS_HUB, /* subclass */
2713 1.182.12.1 itohy UDPROTO_FSHUB, /* protocol */
2714 1.1 augustss 64, /* max packet */
2715 1.1 augustss {0},{0},{0x00,0x01}, /* device id */
2716 1.1 augustss 1,2,0, /* string indicies */
2717 1.1 augustss 1 /* # of configurations */
2718 1.1 augustss };
2719 1.1 augustss
2720 1.182.12.1 itohy Static usb_config_descriptor_t ohci_confd = {
2721 1.1 augustss USB_CONFIG_DESCRIPTOR_SIZE,
2722 1.1 augustss UDESC_CONFIG,
2723 1.1 augustss {USB_CONFIG_DESCRIPTOR_SIZE +
2724 1.1 augustss USB_INTERFACE_DESCRIPTOR_SIZE +
2725 1.1 augustss USB_ENDPOINT_DESCRIPTOR_SIZE},
2726 1.1 augustss 1,
2727 1.1 augustss 1,
2728 1.1 augustss 0,
2729 1.180 drochner UC_ATTR_MBO | UC_SELF_POWERED,
2730 1.1 augustss 0 /* max power */
2731 1.1 augustss };
2732 1.1 augustss
2733 1.182.12.1 itohy Static usb_interface_descriptor_t ohci_ifcd = {
2734 1.1 augustss USB_INTERFACE_DESCRIPTOR_SIZE,
2735 1.1 augustss UDESC_INTERFACE,
2736 1.1 augustss 0,
2737 1.1 augustss 0,
2738 1.1 augustss 1,
2739 1.74 augustss UICLASS_HUB,
2740 1.74 augustss UISUBCLASS_HUB,
2741 1.109 augustss UIPROTO_FSHUB,
2742 1.1 augustss 0
2743 1.1 augustss };
2744 1.1 augustss
2745 1.182.12.1 itohy Static usb_endpoint_descriptor_t ohci_endpd = {
2746 1.175 christos .bLength = USB_ENDPOINT_DESCRIPTOR_SIZE,
2747 1.175 christos .bDescriptorType = UDESC_ENDPOINT,
2748 1.175 christos .bEndpointAddress = UE_DIR_IN | OHCI_INTR_ENDPT,
2749 1.175 christos .bmAttributes = UE_INTERRUPT,
2750 1.175 christos .wMaxPacketSize = {8, 0}, /* max packet */
2751 1.175 christos .bInterval = 255,
2752 1.1 augustss };
2753 1.1 augustss
2754 1.182.12.1 itohy Static usb_hub_descriptor_t ohci_hubd = {
2755 1.175 christos .bDescLength = USB_HUB_DESCRIPTOR_SIZE,
2756 1.175 christos .bDescriptorType = UDESC_HUB,
2757 1.1 augustss };
2758 1.1 augustss
2759 1.82 augustss Static int
2760 1.120 augustss ohci_str(usb_string_descriptor_t *p, int l, const char *s)
2761 1.1 augustss {
2762 1.1 augustss int i;
2763 1.1 augustss
2764 1.1 augustss if (l == 0)
2765 1.1 augustss return (0);
2766 1.1 augustss p->bLength = 2 * strlen(s) + 2;
2767 1.1 augustss if (l == 1)
2768 1.1 augustss return (1);
2769 1.1 augustss p->bDescriptorType = UDESC_STRING;
2770 1.1 augustss l -= 2;
2771 1.1 augustss for (i = 0; s[i] && l > 1; i++, l -= 2)
2772 1.1 augustss USETW2(p->bString[i], 0, s[i]);
2773 1.1 augustss return (2*i+2);
2774 1.1 augustss }
2775 1.1 augustss
2776 1.1 augustss /*
2777 1.1 augustss * Simulate a hardware hub by handling all the necessary requests.
2778 1.1 augustss */
2779 1.82 augustss Static usbd_status
2780 1.91 augustss ohci_root_ctrl_transfer(usbd_xfer_handle xfer)
2781 1.1 augustss {
2782 1.53 augustss usbd_status err;
2783 1.17 augustss
2784 1.46 augustss /* Insert last in queue. */
2785 1.182.12.1 itohy #if 0 /* root ctrl doesn't do DMA */
2786 1.182.12.1 itohy err = usb_insert_transfer_dma(xfer, &sc->sc_dmatag,
2787 1.182.12.1 itohy &OXFER(xfer)->dmabuf);
2788 1.182.12.1 itohy #else
2789 1.53 augustss err = usb_insert_transfer(xfer);
2790 1.182.12.1 itohy #endif
2791 1.53 augustss if (err)
2792 1.53 augustss return (err);
2793 1.46 augustss
2794 1.46 augustss /* Pipe isn't running, start first */
2795 1.53 augustss return (ohci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
2796 1.17 augustss }
2797 1.17 augustss
2798 1.82 augustss Static usbd_status
2799 1.91 augustss ohci_root_ctrl_start(usbd_xfer_handle xfer)
2800 1.17 augustss {
2801 1.53 augustss ohci_softc_t *sc = (ohci_softc_t *)xfer->pipe->device->bus;
2802 1.1 augustss usb_device_request_t *req;
2803 1.52 augustss void *buf = NULL;
2804 1.1 augustss int port, i;
2805 1.46 augustss int s, len, value, index, l, totlen = 0;
2806 1.1 augustss usb_port_status_t ps;
2807 1.1 augustss usb_hub_descriptor_t hubd;
2808 1.53 augustss usbd_status err;
2809 1.1 augustss u_int32_t v;
2810 1.1 augustss
2811 1.83 augustss if (sc->sc_dying)
2812 1.83 augustss return (USBD_IOERROR);
2813 1.83 augustss
2814 1.42 augustss #ifdef DIAGNOSTIC
2815 1.53 augustss if (!(xfer->rqflags & URQ_REQUEST))
2816 1.1 augustss /* XXX panic */
2817 1.1 augustss return (USBD_INVAL);
2818 1.42 augustss #endif
2819 1.53 augustss req = &xfer->request;
2820 1.1 augustss
2821 1.182.12.1 itohy DPRINTFN(4,("ohci_root_ctrl_start: type=0x%02x request=%02x\n",
2822 1.1 augustss req->bmRequestType, req->bRequest));
2823 1.1 augustss
2824 1.1 augustss len = UGETW(req->wLength);
2825 1.1 augustss value = UGETW(req->wValue);
2826 1.1 augustss index = UGETW(req->wIndex);
2827 1.43 augustss
2828 1.182.12.2 itohy if (len != 0) {
2829 1.182.12.2 itohy /* mbuf transfer is not supported */
2830 1.182.12.2 itohy if (xfer->rqflags & URQ_DEV_MAP_MBUF)
2831 1.182.12.2 itohy return (USBD_INVAL);
2832 1.182.12.1 itohy buf = xfer->hcbuffer;
2833 1.182.12.2 itohy }
2834 1.43 augustss
2835 1.1 augustss #define C(x,y) ((x) | ((y) << 8))
2836 1.1 augustss switch(C(req->bRequest, req->bmRequestType)) {
2837 1.1 augustss case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
2838 1.1 augustss case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
2839 1.1 augustss case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
2840 1.120 augustss /*
2841 1.15 augustss * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
2842 1.1 augustss * for the integrated root hub.
2843 1.1 augustss */
2844 1.1 augustss break;
2845 1.1 augustss case C(UR_GET_CONFIG, UT_READ_DEVICE):
2846 1.1 augustss if (len > 0) {
2847 1.1 augustss *(u_int8_t *)buf = sc->sc_conf;
2848 1.1 augustss totlen = 1;
2849 1.1 augustss }
2850 1.1 augustss break;
2851 1.1 augustss case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
2852 1.1 augustss DPRINTFN(8,("ohci_root_ctrl_control wValue=0x%04x\n", value));
2853 1.171 christos if (len == 0)
2854 1.171 christos break;
2855 1.1 augustss switch(value >> 8) {
2856 1.1 augustss case UDESC_DEVICE:
2857 1.1 augustss if ((value & 0xff) != 0) {
2858 1.53 augustss err = USBD_IOERROR;
2859 1.1 augustss goto ret;
2860 1.1 augustss }
2861 1.1 augustss totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
2862 1.29 augustss USETW(ohci_devd.idVendor, sc->sc_id_vendor);
2863 1.1 augustss memcpy(buf, &ohci_devd, l);
2864 1.1 augustss break;
2865 1.1 augustss case UDESC_CONFIG:
2866 1.1 augustss if ((value & 0xff) != 0) {
2867 1.53 augustss err = USBD_IOERROR;
2868 1.1 augustss goto ret;
2869 1.1 augustss }
2870 1.1 augustss totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
2871 1.1 augustss memcpy(buf, &ohci_confd, l);
2872 1.1 augustss buf = (char *)buf + l;
2873 1.1 augustss len -= l;
2874 1.1 augustss l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
2875 1.1 augustss totlen += l;
2876 1.1 augustss memcpy(buf, &ohci_ifcd, l);
2877 1.1 augustss buf = (char *)buf + l;
2878 1.1 augustss len -= l;
2879 1.1 augustss l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
2880 1.1 augustss totlen += l;
2881 1.1 augustss memcpy(buf, &ohci_endpd, l);
2882 1.1 augustss break;
2883 1.1 augustss case UDESC_STRING:
2884 1.1 augustss *(u_int8_t *)buf = 0;
2885 1.1 augustss totlen = 1;
2886 1.1 augustss switch (value & 0xff) {
2887 1.152 augustss case 0: /* Language table */
2888 1.182 drochner if (len > 0)
2889 1.182 drochner *(u_int8_t *)buf = 4;
2890 1.182 drochner if (len >= 4) {
2891 1.182 drochner USETW(((usb_string_descriptor_t *)buf)->bString[0], 0x0409);
2892 1.182 drochner totlen = 4;
2893 1.182 drochner }
2894 1.152 augustss break;
2895 1.1 augustss case 1: /* Vendor */
2896 1.1 augustss totlen = ohci_str(buf, len, sc->sc_vendor);
2897 1.1 augustss break;
2898 1.1 augustss case 2: /* Product */
2899 1.1 augustss totlen = ohci_str(buf, len, "OHCI root hub");
2900 1.1 augustss break;
2901 1.1 augustss }
2902 1.1 augustss break;
2903 1.1 augustss default:
2904 1.53 augustss err = USBD_IOERROR;
2905 1.1 augustss goto ret;
2906 1.1 augustss }
2907 1.1 augustss break;
2908 1.1 augustss case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
2909 1.1 augustss if (len > 0) {
2910 1.1 augustss *(u_int8_t *)buf = 0;
2911 1.1 augustss totlen = 1;
2912 1.1 augustss }
2913 1.1 augustss break;
2914 1.1 augustss case C(UR_GET_STATUS, UT_READ_DEVICE):
2915 1.1 augustss if (len > 1) {
2916 1.1 augustss USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
2917 1.1 augustss totlen = 2;
2918 1.1 augustss }
2919 1.1 augustss break;
2920 1.1 augustss case C(UR_GET_STATUS, UT_READ_INTERFACE):
2921 1.1 augustss case C(UR_GET_STATUS, UT_READ_ENDPOINT):
2922 1.1 augustss if (len > 1) {
2923 1.1 augustss USETW(((usb_status_t *)buf)->wStatus, 0);
2924 1.1 augustss totlen = 2;
2925 1.1 augustss }
2926 1.1 augustss break;
2927 1.1 augustss case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
2928 1.1 augustss if (value >= USB_MAX_DEVICES) {
2929 1.53 augustss err = USBD_IOERROR;
2930 1.1 augustss goto ret;
2931 1.1 augustss }
2932 1.1 augustss sc->sc_addr = value;
2933 1.1 augustss break;
2934 1.1 augustss case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
2935 1.1 augustss if (value != 0 && value != 1) {
2936 1.53 augustss err = USBD_IOERROR;
2937 1.1 augustss goto ret;
2938 1.1 augustss }
2939 1.1 augustss sc->sc_conf = value;
2940 1.1 augustss break;
2941 1.1 augustss case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
2942 1.1 augustss break;
2943 1.1 augustss case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
2944 1.1 augustss case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
2945 1.1 augustss case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
2946 1.53 augustss err = USBD_IOERROR;
2947 1.1 augustss goto ret;
2948 1.1 augustss case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
2949 1.1 augustss break;
2950 1.1 augustss case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
2951 1.1 augustss break;
2952 1.1 augustss /* Hub requests */
2953 1.1 augustss case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
2954 1.1 augustss break;
2955 1.1 augustss case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
2956 1.182.12.1 itohy DPRINTFN(8, ("ohci_root_ctrl_start: UR_CLEAR_PORT_FEATURE "
2957 1.14 augustss "port=%d feature=%d\n",
2958 1.1 augustss index, value));
2959 1.1 augustss if (index < 1 || index > sc->sc_noport) {
2960 1.53 augustss err = USBD_IOERROR;
2961 1.1 augustss goto ret;
2962 1.1 augustss }
2963 1.1 augustss port = OHCI_RH_PORT_STATUS(index);
2964 1.1 augustss switch(value) {
2965 1.1 augustss case UHF_PORT_ENABLE:
2966 1.1 augustss OWRITE4(sc, port, UPS_CURRENT_CONNECT_STATUS);
2967 1.1 augustss break;
2968 1.1 augustss case UHF_PORT_SUSPEND:
2969 1.1 augustss OWRITE4(sc, port, UPS_OVERCURRENT_INDICATOR);
2970 1.1 augustss break;
2971 1.1 augustss case UHF_PORT_POWER:
2972 1.86 augustss /* Yes, writing to the LOW_SPEED bit clears power. */
2973 1.1 augustss OWRITE4(sc, port, UPS_LOW_SPEED);
2974 1.1 augustss break;
2975 1.1 augustss case UHF_C_PORT_CONNECTION:
2976 1.1 augustss OWRITE4(sc, port, UPS_C_CONNECT_STATUS << 16);
2977 1.1 augustss break;
2978 1.1 augustss case UHF_C_PORT_ENABLE:
2979 1.1 augustss OWRITE4(sc, port, UPS_C_PORT_ENABLED << 16);
2980 1.1 augustss break;
2981 1.1 augustss case UHF_C_PORT_SUSPEND:
2982 1.1 augustss OWRITE4(sc, port, UPS_C_SUSPEND << 16);
2983 1.1 augustss break;
2984 1.1 augustss case UHF_C_PORT_OVER_CURRENT:
2985 1.1 augustss OWRITE4(sc, port, UPS_C_OVERCURRENT_INDICATOR << 16);
2986 1.1 augustss break;
2987 1.1 augustss case UHF_C_PORT_RESET:
2988 1.1 augustss OWRITE4(sc, port, UPS_C_PORT_RESET << 16);
2989 1.1 augustss break;
2990 1.1 augustss default:
2991 1.53 augustss err = USBD_IOERROR;
2992 1.1 augustss goto ret;
2993 1.1 augustss }
2994 1.1 augustss switch(value) {
2995 1.1 augustss case UHF_C_PORT_CONNECTION:
2996 1.1 augustss case UHF_C_PORT_ENABLE:
2997 1.1 augustss case UHF_C_PORT_SUSPEND:
2998 1.1 augustss case UHF_C_PORT_OVER_CURRENT:
2999 1.1 augustss case UHF_C_PORT_RESET:
3000 1.1 augustss /* Enable RHSC interrupt if condition is cleared. */
3001 1.1 augustss if ((OREAD4(sc, port) >> 16) == 0)
3002 1.157 mycroft ohci_rhsc_enable(sc);
3003 1.1 augustss break;
3004 1.1 augustss default:
3005 1.1 augustss break;
3006 1.1 augustss }
3007 1.1 augustss break;
3008 1.1 augustss case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
3009 1.171 christos if (len == 0)
3010 1.171 christos break;
3011 1.146 toshii if ((value & 0xff) != 0) {
3012 1.53 augustss err = USBD_IOERROR;
3013 1.1 augustss goto ret;
3014 1.1 augustss }
3015 1.1 augustss v = OREAD4(sc, OHCI_RH_DESCRIPTOR_A);
3016 1.1 augustss hubd = ohci_hubd;
3017 1.1 augustss hubd.bNbrPorts = sc->sc_noport;
3018 1.15 augustss USETW(hubd.wHubCharacteristics,
3019 1.120 augustss (v & OHCI_NPS ? UHD_PWR_NO_SWITCH :
3020 1.1 augustss v & OHCI_PSM ? UHD_PWR_GANGED : UHD_PWR_INDIVIDUAL)
3021 1.1 augustss /* XXX overcurrent */
3022 1.1 augustss );
3023 1.1 augustss hubd.bPwrOn2PwrGood = OHCI_GET_POTPGT(v);
3024 1.1 augustss v = OREAD4(sc, OHCI_RH_DESCRIPTOR_B);
3025 1.120 augustss for (i = 0, l = sc->sc_noport; l > 0; i++, l -= 8, v >>= 8)
3026 1.15 augustss hubd.DeviceRemovable[i++] = (u_int8_t)v;
3027 1.15 augustss hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE + i;
3028 1.1 augustss l = min(len, hubd.bDescLength);
3029 1.1 augustss totlen = l;
3030 1.1 augustss memcpy(buf, &hubd, l);
3031 1.1 augustss break;
3032 1.1 augustss case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
3033 1.1 augustss if (len != 4) {
3034 1.53 augustss err = USBD_IOERROR;
3035 1.1 augustss goto ret;
3036 1.1 augustss }
3037 1.1 augustss memset(buf, 0, len); /* ? XXX */
3038 1.1 augustss totlen = len;
3039 1.1 augustss break;
3040 1.1 augustss case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
3041 1.1 augustss DPRINTFN(8,("ohci_root_ctrl_transfer: get port status i=%d\n",
3042 1.1 augustss index));
3043 1.1 augustss if (index < 1 || index > sc->sc_noport) {
3044 1.53 augustss err = USBD_IOERROR;
3045 1.1 augustss goto ret;
3046 1.1 augustss }
3047 1.1 augustss if (len != 4) {
3048 1.53 augustss err = USBD_IOERROR;
3049 1.1 augustss goto ret;
3050 1.1 augustss }
3051 1.1 augustss v = OREAD4(sc, OHCI_RH_PORT_STATUS(index));
3052 1.1 augustss DPRINTFN(8,("ohci_root_ctrl_transfer: port status=0x%04x\n",
3053 1.1 augustss v));
3054 1.1 augustss USETW(ps.wPortStatus, v);
3055 1.1 augustss USETW(ps.wPortChange, v >> 16);
3056 1.1 augustss l = min(len, sizeof ps);
3057 1.1 augustss memcpy(buf, &ps, l);
3058 1.1 augustss totlen = l;
3059 1.1 augustss break;
3060 1.1 augustss case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
3061 1.53 augustss err = USBD_IOERROR;
3062 1.1 augustss goto ret;
3063 1.1 augustss case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
3064 1.1 augustss break;
3065 1.1 augustss case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
3066 1.1 augustss if (index < 1 || index > sc->sc_noport) {
3067 1.53 augustss err = USBD_IOERROR;
3068 1.1 augustss goto ret;
3069 1.1 augustss }
3070 1.1 augustss port = OHCI_RH_PORT_STATUS(index);
3071 1.1 augustss switch(value) {
3072 1.1 augustss case UHF_PORT_ENABLE:
3073 1.1 augustss OWRITE4(sc, port, UPS_PORT_ENABLED);
3074 1.1 augustss break;
3075 1.1 augustss case UHF_PORT_SUSPEND:
3076 1.1 augustss OWRITE4(sc, port, UPS_SUSPEND);
3077 1.1 augustss break;
3078 1.1 augustss case UHF_PORT_RESET:
3079 1.14 augustss DPRINTFN(5,("ohci_root_ctrl_transfer: reset port %d\n",
3080 1.14 augustss index));
3081 1.1 augustss OWRITE4(sc, port, UPS_RESET);
3082 1.110 augustss for (i = 0; i < 5; i++) {
3083 1.110 augustss usb_delay_ms(&sc->sc_bus,
3084 1.110 augustss USB_PORT_ROOT_RESET_DELAY);
3085 1.116 augustss if (sc->sc_dying) {
3086 1.116 augustss err = USBD_IOERROR;
3087 1.116 augustss goto ret;
3088 1.116 augustss }
3089 1.1 augustss if ((OREAD4(sc, port) & UPS_RESET) == 0)
3090 1.1 augustss break;
3091 1.1 augustss }
3092 1.1 augustss DPRINTFN(8,("ohci port %d reset, status = 0x%04x\n",
3093 1.1 augustss index, OREAD4(sc, port)));
3094 1.1 augustss break;
3095 1.1 augustss case UHF_PORT_POWER:
3096 1.14 augustss DPRINTFN(2,("ohci_root_ctrl_transfer: set port power "
3097 1.14 augustss "%d\n", index));
3098 1.1 augustss OWRITE4(sc, port, UPS_PORT_POWER);
3099 1.1 augustss break;
3100 1.1 augustss default:
3101 1.53 augustss err = USBD_IOERROR;
3102 1.1 augustss goto ret;
3103 1.1 augustss }
3104 1.1 augustss break;
3105 1.1 augustss default:
3106 1.53 augustss err = USBD_IOERROR;
3107 1.1 augustss goto ret;
3108 1.1 augustss }
3109 1.53 augustss xfer->actlen = totlen;
3110 1.53 augustss err = USBD_NORMAL_COMPLETION;
3111 1.1 augustss ret:
3112 1.53 augustss xfer->status = err;
3113 1.46 augustss s = splusb();
3114 1.182.12.1 itohy #if 0 /* root ctrl doesn't do DMA */
3115 1.182.12.1 itohy usb_transfer_complete_dma(xfer, &sc->sc_dmatag, &OXFER(xfer)->dmabuf);
3116 1.182.12.1 itohy #else
3117 1.53 augustss usb_transfer_complete(xfer);
3118 1.182.12.1 itohy #endif
3119 1.46 augustss splx(s);
3120 1.1 augustss return (USBD_IN_PROGRESS);
3121 1.1 augustss }
3122 1.1 augustss
3123 1.1 augustss /* Abort a root control request. */
3124 1.82 augustss Static void
3125 1.179 christos ohci_root_ctrl_abort(usbd_xfer_handle xfer)
3126 1.1 augustss {
3127 1.9 augustss /* Nothing to do, all transfers are synchronous. */
3128 1.1 augustss }
3129 1.1 augustss
3130 1.1 augustss /* Close the root pipe. */
3131 1.82 augustss Static void
3132 1.179 christos ohci_root_ctrl_close(usbd_pipe_handle pipe)
3133 1.1 augustss {
3134 1.1 augustss DPRINTF(("ohci_root_ctrl_close\n"));
3135 1.34 augustss /* Nothing to do. */
3136 1.1 augustss }
3137 1.1 augustss
3138 1.82 augustss Static usbd_status
3139 1.91 augustss ohci_root_intr_transfer(usbd_xfer_handle xfer)
3140 1.1 augustss {
3141 1.182.12.1 itohy ohci_softc_t *sc = (ohci_softc_t *)xfer->pipe->device->bus;
3142 1.53 augustss usbd_status err;
3143 1.17 augustss
3144 1.46 augustss /* Insert last in queue. */
3145 1.182.12.1 itohy err = usb_insert_transfer_dma(xfer, &sc->sc_dmatag,
3146 1.182.12.1 itohy &OXFER(xfer)->dmabuf);
3147 1.53 augustss if (err)
3148 1.53 augustss return (err);
3149 1.46 augustss
3150 1.46 augustss /* Pipe isn't running, start first */
3151 1.53 augustss return (ohci_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
3152 1.17 augustss }
3153 1.17 augustss
3154 1.82 augustss Static usbd_status
3155 1.91 augustss ohci_root_intr_start(usbd_xfer_handle xfer)
3156 1.17 augustss {
3157 1.182.12.1 itohy ohci_softc_t *sc = (ohci_softc_t *)xfer->pipe->device->bus;
3158 1.1 augustss
3159 1.83 augustss if (sc->sc_dying)
3160 1.83 augustss return (USBD_IOERROR);
3161 1.182.12.2 itohy if (xfer->rqflags & URQ_DEV_MAP_MBUF)
3162 1.182.12.2 itohy return (USBD_INVAL); /* mbuf transfer is not supported */
3163 1.83 augustss
3164 1.53 augustss sc->sc_intrxfer = xfer;
3165 1.1 augustss
3166 1.1 augustss return (USBD_IN_PROGRESS);
3167 1.1 augustss }
3168 1.1 augustss
3169 1.3 augustss /* Abort a root interrupt request. */
3170 1.82 augustss Static void
3171 1.91 augustss ohci_root_intr_abort(usbd_xfer_handle xfer)
3172 1.1 augustss {
3173 1.182.12.1 itohy usbd_pipe_handle pipe = xfer->pipe;
3174 1.182.12.1 itohy ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
3175 1.53 augustss int s;
3176 1.53 augustss
3177 1.182.12.1 itohy if (pipe->intrxfer == xfer) {
3178 1.51 augustss DPRINTF(("ohci_root_intr_abort: remove\n"));
3179 1.182.12.1 itohy pipe->intrxfer = NULL;
3180 1.51 augustss }
3181 1.53 augustss xfer->status = USBD_CANCELLED;
3182 1.53 augustss s = splusb();
3183 1.182.12.1 itohy usb_transfer_complete_dma(xfer, &sc->sc_dmatag, &OXFER(xfer)->dmabuf);
3184 1.53 augustss splx(s);
3185 1.1 augustss }
3186 1.1 augustss
3187 1.1 augustss /* Close the root pipe. */
3188 1.82 augustss Static void
3189 1.91 augustss ohci_root_intr_close(usbd_pipe_handle pipe)
3190 1.1 augustss {
3191 1.1 augustss ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
3192 1.120 augustss
3193 1.1 augustss DPRINTF(("ohci_root_intr_close\n"));
3194 1.34 augustss
3195 1.53 augustss sc->sc_intrxfer = NULL;
3196 1.1 augustss }
3197 1.1 augustss
3198 1.1 augustss /************************/
3199 1.1 augustss
3200 1.82 augustss Static usbd_status
3201 1.91 augustss ohci_device_ctrl_transfer(usbd_xfer_handle xfer)
3202 1.1 augustss {
3203 1.182.12.1 itohy ohci_softc_t *sc = (ohci_softc_t *)xfer->pipe->device->bus;
3204 1.53 augustss usbd_status err;
3205 1.17 augustss
3206 1.46 augustss /* Insert last in queue. */
3207 1.182.12.1 itohy err = usb_insert_transfer_dma(xfer, &sc->sc_dmatag,
3208 1.182.12.1 itohy &OXFER(xfer)->dmabuf);
3209 1.53 augustss if (err)
3210 1.53 augustss return (err);
3211 1.46 augustss
3212 1.46 augustss /* Pipe isn't running, start first */
3213 1.53 augustss return (ohci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
3214 1.17 augustss }
3215 1.17 augustss
3216 1.82 augustss Static usbd_status
3217 1.91 augustss ohci_device_ctrl_start(usbd_xfer_handle xfer)
3218 1.17 augustss {
3219 1.53 augustss ohci_softc_t *sc = (ohci_softc_t *)xfer->pipe->device->bus;
3220 1.53 augustss usbd_status err;
3221 1.1 augustss
3222 1.83 augustss if (sc->sc_dying)
3223 1.83 augustss return (USBD_IOERROR);
3224 1.83 augustss
3225 1.42 augustss #ifdef DIAGNOSTIC
3226 1.53 augustss if (!(xfer->rqflags & URQ_REQUEST)) {
3227 1.1 augustss /* XXX panic */
3228 1.1 augustss printf("ohci_device_ctrl_transfer: not a request\n");
3229 1.1 augustss return (USBD_INVAL);
3230 1.1 augustss }
3231 1.42 augustss #endif
3232 1.1 augustss
3233 1.53 augustss err = ohci_device_request(xfer);
3234 1.53 augustss if (err)
3235 1.53 augustss return (err);
3236 1.1 augustss
3237 1.6 augustss if (sc->sc_bus.use_polling)
3238 1.53 augustss ohci_waitintr(sc, xfer);
3239 1.1 augustss return (USBD_IN_PROGRESS);
3240 1.1 augustss }
3241 1.1 augustss
3242 1.1 augustss /* Abort a device control request. */
3243 1.82 augustss Static void
3244 1.91 augustss ohci_device_ctrl_abort(usbd_xfer_handle xfer)
3245 1.1 augustss {
3246 1.53 augustss DPRINTF(("ohci_device_ctrl_abort: xfer=%p\n", xfer));
3247 1.54 augustss ohci_abort_xfer(xfer, USBD_CANCELLED);
3248 1.1 augustss }
3249 1.1 augustss
3250 1.1 augustss /* Close a device control pipe. */
3251 1.82 augustss Static void
3252 1.91 augustss ohci_device_ctrl_close(usbd_pipe_handle pipe)
3253 1.1 augustss {
3254 1.60 augustss struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
3255 1.1 augustss ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
3256 1.1 augustss
3257 1.34 augustss DPRINTF(("ohci_device_ctrl_close: pipe=%p\n", pipe));
3258 1.34 augustss ohci_close_pipe(pipe, sc->sc_ctrl_head);
3259 1.182.12.1 itohy ohci_free_std_norsv(sc, opipe->tail.td);
3260 1.182.12.1 itohy usb_freemem(&sc->sc_dmatag, &opipe->u.ctl.reqdma);
3261 1.3 augustss }
3262 1.3 augustss
3263 1.3 augustss /************************/
3264 1.37 augustss
3265 1.82 augustss Static void
3266 1.91 augustss ohci_device_clear_toggle(usbd_pipe_handle pipe)
3267 1.37 augustss {
3268 1.37 augustss struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
3269 1.168 augustss ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
3270 1.37 augustss
3271 1.168 augustss opipe->sed->ed.ed_headp &= HTOO32(~OHCI_TOGGLECARRY);
3272 1.37 augustss }
3273 1.37 augustss
3274 1.82 augustss Static void
3275 1.179 christos ohci_noop(usbd_pipe_handle pipe)
3276 1.37 augustss {
3277 1.37 augustss }
3278 1.3 augustss
3279 1.82 augustss Static usbd_status
3280 1.91 augustss ohci_device_bulk_transfer(usbd_xfer_handle xfer)
3281 1.3 augustss {
3282 1.182.12.1 itohy ohci_softc_t *sc = (ohci_softc_t *)xfer->pipe->device->bus;
3283 1.53 augustss usbd_status err;
3284 1.17 augustss
3285 1.46 augustss /* Insert last in queue. */
3286 1.182.12.1 itohy err = usb_insert_transfer_dma(xfer, &sc->sc_dmatag,
3287 1.182.12.1 itohy &OXFER(xfer)->dmabuf);
3288 1.53 augustss if (err)
3289 1.53 augustss return (err);
3290 1.46 augustss
3291 1.46 augustss /* Pipe isn't running, start first */
3292 1.53 augustss return (ohci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
3293 1.17 augustss }
3294 1.17 augustss
3295 1.82 augustss Static usbd_status
3296 1.91 augustss ohci_device_bulk_start(usbd_xfer_handle xfer)
3297 1.17 augustss {
3298 1.53 augustss struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
3299 1.3 augustss usbd_device_handle dev = opipe->pipe.device;
3300 1.3 augustss ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
3301 1.3 augustss int addr = dev->address;
3302 1.48 augustss ohci_soft_td_t *data, *tail, *tdp;
3303 1.3 augustss ohci_soft_ed_t *sed;
3304 1.182.12.1 itohy ohci_physaddr_t dmaadr;
3305 1.40 augustss int s, len, isread, endpt;
3306 1.53 augustss usbd_status err;
3307 1.3 augustss
3308 1.83 augustss if (sc->sc_dying)
3309 1.83 augustss return (USBD_IOERROR);
3310 1.83 augustss
3311 1.34 augustss #ifdef DIAGNOSTIC
3312 1.53 augustss if (xfer->rqflags & URQ_REQUEST) {
3313 1.3 augustss /* XXX panic */
3314 1.34 augustss printf("ohci_device_bulk_start: a request\n");
3315 1.3 augustss return (USBD_INVAL);
3316 1.3 augustss }
3317 1.34 augustss #endif
3318 1.3 augustss
3319 1.53 augustss len = xfer->length;
3320 1.53 augustss endpt = xfer->pipe->endpoint->edesc->bEndpointAddress;
3321 1.40 augustss isread = UE_GET_DIR(endpt) == UE_DIR_IN;
3322 1.3 augustss sed = opipe->sed;
3323 1.3 augustss
3324 1.53 augustss DPRINTFN(4,("ohci_device_bulk_start: xfer=%p len=%d isread=%d "
3325 1.53 augustss "flags=%d endpt=%d\n", xfer, len, isread, xfer->flags,
3326 1.40 augustss endpt));
3327 1.34 augustss
3328 1.32 augustss opipe->u.bulk.isread = isread;
3329 1.3 augustss opipe->u.bulk.length = len;
3330 1.3 augustss
3331 1.3 augustss /* Update device address */
3332 1.168 augustss sed->ed.ed_flags = HTOO32(
3333 1.168 augustss (O32TOH(sed->ed.ed_flags) & ~OHCI_ED_ADDRMASK) |
3334 1.16 augustss OHCI_ED_SET_FA(addr));
3335 1.3 augustss
3336 1.48 augustss /* Allocate a chain of new TDs (including a new tail). */
3337 1.60 augustss data = opipe->tail.td;
3338 1.77 augustss err = ohci_alloc_std_chain(opipe, sc, len, isread, xfer,
3339 1.77 augustss data, &tail);
3340 1.77 augustss /* We want interrupt at the end of the transfer. */
3341 1.168 augustss tail->td.td_flags &= HTOO32(~OHCI_TD_INTR_MASK);
3342 1.168 augustss tail->td.td_flags |= HTOO32(OHCI_TD_SET_DI(1));
3343 1.77 augustss tail->flags |= OHCI_CALL_DONE;
3344 1.182.12.1 itohy OHCI_STD_SYNC(sc, tail, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
3345 1.77 augustss tail = tail->nexttd; /* point at sentinel */
3346 1.53 augustss if (err)
3347 1.53 augustss return (err);
3348 1.48 augustss
3349 1.53 augustss tail->xfer = NULL;
3350 1.53 augustss xfer->hcpriv = data;
3351 1.3 augustss
3352 1.34 augustss DPRINTFN(4,("ohci_device_bulk_start: ed_flags=0x%08x td_flags=0x%08x "
3353 1.34 augustss "td_cbp=0x%08x td_be=0x%08x\n",
3354 1.168 augustss (int)O32TOH(sed->ed.ed_flags),
3355 1.168 augustss (int)O32TOH(data->td.td_flags),
3356 1.168 augustss (int)O32TOH(data->td.td_cbp),
3357 1.168 augustss (int)O32TOH(data->td.td_be)));
3358 1.34 augustss
3359 1.182.12.1 itohy #ifdef USB_DEBUG
3360 1.75 augustss if (ohcidebug > 5) {
3361 1.168 augustss ohci_dump_ed(sc, sed);
3362 1.168 augustss ohci_dump_tds(sc, data);
3363 1.34 augustss }
3364 1.34 augustss #endif
3365 1.34 augustss
3366 1.3 augustss /* Insert ED in schedule */
3367 1.3 augustss s = splusb();
3368 1.48 augustss for (tdp = data; tdp != tail; tdp = tdp->nexttd) {
3369 1.53 augustss tdp->xfer = xfer;
3370 1.48 augustss }
3371 1.182.12.1 itohy dmaadr = OHCI_STD_DMAADDR(tail);
3372 1.182.12.1 itohy sed->ed.ed_tailp = HTOO32(dmaadr);
3373 1.60 augustss opipe->tail.td = tail;
3374 1.168 augustss sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP);
3375 1.182.12.1 itohy OHCI_SED_SYNC(sc, sed, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
3376 1.3 augustss OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF);
3377 1.53 augustss if (xfer->timeout && !sc->sc_bus.use_polling) {
3378 1.182.12.1 itohy usb_callout(xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
3379 1.80 augustss ohci_timeout, xfer);
3380 1.15 augustss }
3381 1.34 augustss
3382 1.52 augustss #if 0
3383 1.52 augustss /* This goes wrong if we are too slow. */
3384 1.75 augustss if (ohcidebug > 10) {
3385 1.75 augustss delay(10000);
3386 1.41 augustss DPRINTF(("ohci_device_intr_transfer: status=%x\n",
3387 1.41 augustss OREAD4(sc, OHCI_COMMAND_STATUS)));
3388 1.168 augustss ohci_dump_ed(sc, sed);
3389 1.168 augustss ohci_dump_tds(sc, data);
3390 1.34 augustss }
3391 1.34 augustss #endif
3392 1.34 augustss
3393 1.3 augustss splx(s);
3394 1.3 augustss
3395 1.182.12.1 itohy if (sc->sc_bus.use_polling)
3396 1.182.12.1 itohy ohci_waitintr(sc, xfer);
3397 1.182.12.1 itohy
3398 1.3 augustss return (USBD_IN_PROGRESS);
3399 1.3 augustss }
3400 1.3 augustss
3401 1.82 augustss Static void
3402 1.91 augustss ohci_device_bulk_abort(usbd_xfer_handle xfer)
3403 1.3 augustss {
3404 1.53 augustss DPRINTF(("ohci_device_bulk_abort: xfer=%p\n", xfer));
3405 1.54 augustss ohci_abort_xfer(xfer, USBD_CANCELLED);
3406 1.3 augustss }
3407 1.3 augustss
3408 1.120 augustss /*
3409 1.34 augustss * Close a device bulk pipe.
3410 1.34 augustss */
3411 1.82 augustss Static void
3412 1.91 augustss ohci_device_bulk_close(usbd_pipe_handle pipe)
3413 1.3 augustss {
3414 1.60 augustss struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
3415 1.34 augustss ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
3416 1.3 augustss
3417 1.34 augustss DPRINTF(("ohci_device_bulk_close: pipe=%p\n", pipe));
3418 1.34 augustss ohci_close_pipe(pipe, sc->sc_bulk_head);
3419 1.182.12.1 itohy ohci_free_std_norsv(sc, opipe->tail.td);
3420 1.1 augustss }
3421 1.1 augustss
3422 1.1 augustss /************************/
3423 1.1 augustss
3424 1.82 augustss Static usbd_status
3425 1.91 augustss ohci_device_intr_transfer(usbd_xfer_handle xfer)
3426 1.17 augustss {
3427 1.182.12.1 itohy ohci_softc_t *sc = (ohci_softc_t *)xfer->pipe->device->bus;
3428 1.53 augustss usbd_status err;
3429 1.17 augustss
3430 1.46 augustss /* Insert last in queue. */
3431 1.182.12.1 itohy err = usb_insert_transfer_dma(xfer, &sc->sc_dmatag,
3432 1.182.12.1 itohy &OXFER(xfer)->dmabuf);
3433 1.53 augustss if (err)
3434 1.53 augustss return (err);
3435 1.46 augustss
3436 1.46 augustss /* Pipe isn't running, start first */
3437 1.53 augustss return (ohci_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
3438 1.17 augustss }
3439 1.17 augustss
3440 1.82 augustss Static usbd_status
3441 1.91 augustss ohci_device_intr_start(usbd_xfer_handle xfer)
3442 1.1 augustss {
3443 1.53 augustss struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
3444 1.182.12.1 itohy ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
3445 1.1 augustss ohci_soft_ed_t *sed = opipe->sed;
3446 1.182.12.1 itohy usbd_status err;
3447 1.1 augustss
3448 1.83 augustss if (sc->sc_dying)
3449 1.83 augustss return (USBD_IOERROR);
3450 1.83 augustss
3451 1.182.12.1 itohy DPRINTFN(3, ("ohci_device_intr_start: xfer=%p len=%d "
3452 1.14 augustss "flags=%d priv=%p\n",
3453 1.53 augustss xfer, xfer->length, xfer->flags, xfer->priv));
3454 1.1 augustss
3455 1.42 augustss #ifdef DIAGNOSTIC
3456 1.53 augustss if (xfer->rqflags & URQ_REQUEST)
3457 1.182.12.1 itohy panic("ohci_device_intr_start: a request");
3458 1.42 augustss #endif
3459 1.1 augustss
3460 1.182.12.1 itohy err = ohci_device_intr_insert(sc, xfer);
3461 1.182.12.1 itohy if (err)
3462 1.182.12.1 itohy return (err);
3463 1.182.12.1 itohy
3464 1.182.12.1 itohy sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP);
3465 1.182.12.1 itohy
3466 1.182.12.1 itohy return (USBD_IN_PROGRESS);
3467 1.182.12.1 itohy }
3468 1.182.12.1 itohy
3469 1.182.12.1 itohy /*
3470 1.182.12.1 itohy * Insert an interrupt transfer into an endpoint descriptor list
3471 1.182.12.1 itohy */
3472 1.182.12.1 itohy Static usbd_status
3473 1.182.12.1 itohy ohci_device_intr_insert(ohci_softc_t *sc, usbd_xfer_handle xfer)
3474 1.182.12.1 itohy {
3475 1.182.12.1 itohy struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
3476 1.182.12.1 itohy ohci_soft_ed_t *sed = opipe->sed;
3477 1.182.12.1 itohy ohci_soft_td_t *data, *tail;
3478 1.182.12.1 itohy ohci_physaddr_t dataphys, physend;
3479 1.182.12.1 itohy ohci_physaddr_t dmaadr;
3480 1.182.12.1 itohy int s, isread, endpt;
3481 1.182.12.1 itohy struct usb_buffer_dma *ub = &OXFER(xfer)->dmabuf;
3482 1.182.12.1 itohy bus_dma_segment_t *segs = USB_BUFFER_SEGS(ub);
3483 1.182.12.1 itohy int nsegs = USB_BUFFER_NSEGS(ub);
3484 1.182.12.1 itohy
3485 1.182.12.1 itohy DPRINTFN(4, ("ohci_device_intr_insert: xfer=%p", xfer));
3486 1.182.12.1 itohy
3487 1.165 skrll endpt = xfer->pipe->endpoint->edesc->bEndpointAddress;
3488 1.165 skrll isread = UE_GET_DIR(endpt) == UE_DIR_IN;
3489 1.1 augustss
3490 1.60 augustss data = opipe->tail.td;
3491 1.1 augustss tail = ohci_alloc_std(sc);
3492 1.55 augustss if (tail == NULL)
3493 1.43 augustss return (USBD_NOMEM);
3494 1.53 augustss tail->xfer = NULL;
3495 1.1 augustss
3496 1.168 augustss data->td.td_flags = HTOO32(
3497 1.165 skrll isread ? OHCI_TD_IN : OHCI_TD_OUT |
3498 1.165 skrll OHCI_TD_NOCC |
3499 1.16 augustss OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY);
3500 1.53 augustss if (xfer->flags & USBD_SHORT_XFER_OK)
3501 1.168 augustss data->td.td_flags |= HTOO32(OHCI_TD_R);
3502 1.182.12.1 itohy /*
3503 1.182.12.1 itohy * Assume a short mapping with no complications, which
3504 1.182.12.1 itohy * should always be true for <= 4k buffers in contiguous
3505 1.182.12.1 itohy * virtual memory. The data can take the following forms:
3506 1.182.12.1 itohy * 1 segment in 1 OHCI page
3507 1.182.12.1 itohy * 1 segment in 2 OHCI pages
3508 1.182.12.1 itohy * 2 segments in 2 OHCI pages
3509 1.182.12.1 itohy * (see comment in ohci_alloc_std_chain() for details)
3510 1.182.12.1 itohy */
3511 1.182.12.1 itohy USB_KASSERT2(xfer->length > 0 && xfer->length <= OHCI_PAGE_SIZE,
3512 1.182.12.1 itohy ("ohci_device_intr_insert: bad length %d", xfer->length));
3513 1.182.12.1 itohy dataphys = segs[0].ds_addr;
3514 1.182.12.1 itohy physend = dataphys + xfer->length - 1;
3515 1.182.12.1 itohy if (nsegs == 2) {
3516 1.182.12.1 itohy USB_KASSERT2(OHCI_PAGE_OFFSET(dataphys +
3517 1.182.12.1 itohy segs[0].ds_len) == 0,
3518 1.182.12.1 itohy ("ohci_device_intr_insert: bad seg 0 termination"));
3519 1.182.12.1 itohy physend = segs[1].ds_addr + xfer->length -
3520 1.182.12.1 itohy segs[0].ds_len - 1;
3521 1.182.12.1 itohy } else {
3522 1.182.12.1 itohy USB_KASSERT2(nsegs == 1,
3523 1.182.12.1 itohy ("ohci_device_intr_insert: bad seg count %d",
3524 1.182.12.1 itohy (u_int)nsegs));
3525 1.182.12.1 itohy }
3526 1.182.12.1 itohy data->td.td_cbp = HTOO32(dataphys);
3527 1.48 augustss data->nexttd = tail;
3528 1.182.12.1 itohy dmaadr = OHCI_STD_DMAADDR(tail);
3529 1.182.12.1 itohy data->td.td_nexttd = HTOO32(dmaadr);
3530 1.182.12.1 itohy data->td.td_be = HTOO32(physend);
3531 1.182.12.1 itohy data->len = xfer->length;
3532 1.53 augustss data->xfer = xfer;
3533 1.48 augustss data->flags = OHCI_CALL_DONE | OHCI_ADD_LEN;
3534 1.53 augustss xfer->hcpriv = data;
3535 1.182.12.1 itohy xfer->actlen = 0;
3536 1.182.12.1 itohy OHCI_STD_SYNC(sc, data, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
3537 1.1 augustss
3538 1.182.12.1 itohy #ifdef USB_DEBUG
3539 1.1 augustss if (ohcidebug > 5) {
3540 1.182.12.1 itohy DPRINTF(("ohci_device_intr_insert:\n"));
3541 1.168 augustss ohci_dump_ed(sc, sed);
3542 1.168 augustss ohci_dump_tds(sc, data);
3543 1.1 augustss }
3544 1.1 augustss #endif
3545 1.1 augustss
3546 1.1 augustss /* Insert ED in schedule */
3547 1.1 augustss s = splusb();
3548 1.182.12.1 itohy dmaadr = OHCI_STD_DMAADDR(tail);
3549 1.182.12.1 itohy sed->ed.ed_tailp = HTOO32(dmaadr);
3550 1.182.12.1 itohy OHCI_SED_SYNC(sc, sed, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
3551 1.60 augustss opipe->tail.td = tail;
3552 1.26 augustss splx(s);
3553 1.1 augustss
3554 1.182.12.1 itohy return (USBD_NORMAL_COMPLETION);
3555 1.1 augustss }
3556 1.1 augustss
3557 1.1 augustss /* Abort a device control request. */
3558 1.82 augustss Static void
3559 1.91 augustss ohci_device_intr_abort(usbd_xfer_handle xfer)
3560 1.1 augustss {
3561 1.53 augustss if (xfer->pipe->intrxfer == xfer) {
3562 1.1 augustss DPRINTF(("ohci_device_intr_abort: remove\n"));
3563 1.55 augustss xfer->pipe->intrxfer = NULL;
3564 1.1 augustss }
3565 1.54 augustss ohci_abort_xfer(xfer, USBD_CANCELLED);
3566 1.1 augustss }
3567 1.1 augustss
3568 1.1 augustss /* Close a device interrupt pipe. */
3569 1.82 augustss Static void
3570 1.91 augustss ohci_device_intr_close(usbd_pipe_handle pipe)
3571 1.1 augustss {
3572 1.1 augustss struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
3573 1.1 augustss ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
3574 1.1 augustss int nslots = opipe->u.intr.nslots;
3575 1.1 augustss int pos = opipe->u.intr.pos;
3576 1.1 augustss int j;
3577 1.1 augustss ohci_soft_ed_t *p, *sed = opipe->sed;
3578 1.1 augustss int s;
3579 1.1 augustss
3580 1.1 augustss DPRINTFN(1,("ohci_device_intr_close: pipe=%p nslots=%d pos=%d\n",
3581 1.1 augustss pipe, nslots, pos));
3582 1.1 augustss s = splusb();
3583 1.168 augustss sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP);
3584 1.168 augustss if ((O32TOH(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
3585 1.168 augustss (O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK))
3586 1.20 augustss usb_delay_ms(&sc->sc_bus, 2);
3587 1.182.12.1 itohy #ifdef DIAGNOSTIC
3588 1.182.12.1 itohy if ((O32TOH(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
3589 1.182.12.1 itohy (O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK))
3590 1.182.12.1 itohy panic("%s: Intr pipe %p still has TDs queued",
3591 1.182.12.1 itohy USBDEVNAME(sc->sc_bus.bdev), pipe);
3592 1.182.12.1 itohy #endif
3593 1.1 augustss
3594 1.1 augustss for (p = sc->sc_eds[pos]; p && p->next != sed; p = p->next)
3595 1.182.12.1 itohy ;
3596 1.53 augustss #ifdef DIAGNOSTIC
3597 1.173 christos if (p == NULL)
3598 1.128 provos panic("ohci_device_intr_close: ED not found");
3599 1.53 augustss #endif
3600 1.173 christos p->next = sed->next;
3601 1.173 christos p->ed.ed_nexted = sed->ed.ed_nexted;
3602 1.1 augustss splx(s);
3603 1.1 augustss
3604 1.1 augustss for (j = 0; j < nslots; j++)
3605 1.31 wrstuden --sc->sc_bws[(pos * nslots + j) % OHCI_NO_INTRS];
3606 1.1 augustss
3607 1.182.12.1 itohy ohci_free_std_norsv(sc, opipe->tail.td);
3608 1.1 augustss ohci_free_sed(sc, opipe->sed);
3609 1.1 augustss }
3610 1.1 augustss
3611 1.82 augustss Static usbd_status
3612 1.91 augustss ohci_device_setintr(ohci_softc_t *sc, struct ohci_pipe *opipe, int ival)
3613 1.1 augustss {
3614 1.1 augustss int i, j, s, best;
3615 1.1 augustss u_int npoll, slow, shigh, nslots;
3616 1.1 augustss u_int bestbw, bw;
3617 1.1 augustss ohci_soft_ed_t *hsed, *sed = opipe->sed;
3618 1.182.12.1 itohy ohci_physaddr_t dmaadr;
3619 1.1 augustss
3620 1.1 augustss DPRINTFN(2, ("ohci_setintr: pipe=%p\n", opipe));
3621 1.1 augustss if (ival == 0) {
3622 1.1 augustss printf("ohci_setintr: 0 interval\n");
3623 1.1 augustss return (USBD_INVAL);
3624 1.1 augustss }
3625 1.1 augustss
3626 1.1 augustss npoll = OHCI_NO_INTRS;
3627 1.1 augustss while (npoll > ival)
3628 1.1 augustss npoll /= 2;
3629 1.1 augustss DPRINTFN(2, ("ohci_setintr: ival=%d npoll=%d\n", ival, npoll));
3630 1.1 augustss
3631 1.1 augustss /*
3632 1.1 augustss * We now know which level in the tree the ED must go into.
3633 1.1 augustss * Figure out which slot has most bandwidth left over.
3634 1.1 augustss * Slots to examine:
3635 1.1 augustss * npoll
3636 1.1 augustss * 1 0
3637 1.1 augustss * 2 1 2
3638 1.1 augustss * 4 3 4 5 6
3639 1.1 augustss * 8 7 8 9 10 11 12 13 14
3640 1.1 augustss * N (N-1) .. (N-1+N-1)
3641 1.1 augustss */
3642 1.1 augustss slow = npoll-1;
3643 1.1 augustss shigh = slow + npoll;
3644 1.1 augustss nslots = OHCI_NO_INTRS / npoll;
3645 1.1 augustss for (best = i = slow, bestbw = ~0; i < shigh; i++) {
3646 1.1 augustss bw = 0;
3647 1.1 augustss for (j = 0; j < nslots; j++)
3648 1.28 augustss bw += sc->sc_bws[(i * nslots + j) % OHCI_NO_INTRS];
3649 1.1 augustss if (bw < bestbw) {
3650 1.1 augustss best = i;
3651 1.1 augustss bestbw = bw;
3652 1.1 augustss }
3653 1.1 augustss }
3654 1.120 augustss DPRINTFN(2, ("ohci_setintr: best=%d(%d..%d) bestbw=%d\n",
3655 1.1 augustss best, slow, shigh, bestbw));
3656 1.1 augustss
3657 1.1 augustss s = splusb();
3658 1.1 augustss hsed = sc->sc_eds[best];
3659 1.1 augustss sed->next = hsed->next;
3660 1.39 augustss sed->ed.ed_nexted = hsed->ed.ed_nexted;
3661 1.1 augustss hsed->next = sed;
3662 1.182.12.1 itohy dmaadr = OHCI_SED_DMAADDR(sed);
3663 1.182.12.1 itohy hsed->ed.ed_nexted = HTOO32(dmaadr);
3664 1.1 augustss splx(s);
3665 1.1 augustss
3666 1.1 augustss for (j = 0; j < nslots; j++)
3667 1.28 augustss ++sc->sc_bws[(best * nslots + j) % OHCI_NO_INTRS];
3668 1.1 augustss opipe->u.intr.nslots = nslots;
3669 1.1 augustss opipe->u.intr.pos = best;
3670 1.1 augustss
3671 1.1 augustss DPRINTFN(5, ("ohci_setintr: returns %p\n", opipe));
3672 1.1 augustss return (USBD_NORMAL_COMPLETION);
3673 1.60 augustss }
3674 1.60 augustss
3675 1.60 augustss /***********************/
3676 1.60 augustss
3677 1.60 augustss usbd_status
3678 1.91 augustss ohci_device_isoc_transfer(usbd_xfer_handle xfer)
3679 1.60 augustss {
3680 1.182.12.1 itohy ohci_softc_t *sc = (ohci_softc_t *)xfer->pipe->device->bus;
3681 1.60 augustss usbd_status err;
3682 1.60 augustss
3683 1.60 augustss DPRINTFN(5,("ohci_device_isoc_transfer: xfer=%p\n", xfer));
3684 1.60 augustss
3685 1.60 augustss /* Put it on our queue, */
3686 1.182.12.1 itohy err = usb_insert_transfer_dma(xfer, &sc->sc_dmatag,
3687 1.182.12.1 itohy &OXFER(xfer)->dmabuf);
3688 1.60 augustss
3689 1.60 augustss /* bail out on error, */
3690 1.60 augustss if (err && err != USBD_IN_PROGRESS)
3691 1.60 augustss return (err);
3692 1.60 augustss
3693 1.60 augustss /* XXX should check inuse here */
3694 1.60 augustss
3695 1.60 augustss /* insert into schedule, */
3696 1.60 augustss ohci_device_isoc_enter(xfer);
3697 1.60 augustss
3698 1.83 augustss /* and start if the pipe wasn't running */
3699 1.60 augustss if (!err)
3700 1.60 augustss ohci_device_isoc_start(SIMPLEQ_FIRST(&xfer->pipe->queue));
3701 1.60 augustss
3702 1.60 augustss return (err);
3703 1.60 augustss }
3704 1.60 augustss
3705 1.60 augustss void
3706 1.91 augustss ohci_device_isoc_enter(usbd_xfer_handle xfer)
3707 1.60 augustss {
3708 1.61 augustss struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
3709 1.61 augustss usbd_device_handle dev = opipe->pipe.device;
3710 1.61 augustss ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
3711 1.61 augustss ohci_soft_ed_t *sed = opipe->sed;
3712 1.61 augustss struct iso *iso = &opipe->u.iso;
3713 1.182.12.1 itohy struct usb_buffer_dma *ub = &OXFER(xfer)->dmabuf;
3714 1.182.12.1 itohy bus_dma_segment_t *segs = USB_BUFFER_SEGS(ub);
3715 1.182.12.1 itohy int nsegs = USB_BUFFER_NSEGS(ub);
3716 1.120 augustss ohci_soft_itd_t *sitd, *nsitd;
3717 1.182.12.1 itohy ohci_physaddr_t dataphys, bp0, physend, prevpage;
3718 1.182.12.1 itohy ohci_physaddr_t dmaadr;
3719 1.182.12.1 itohy int curlen, i, len, ncur, nframes, npages, seg, segoff;
3720 1.61 augustss int s;
3721 1.61 augustss
3722 1.83 augustss DPRINTFN(1,("ohci_device_isoc_enter: used=%d next=%d xfer=%p "
3723 1.83 augustss "nframes=%d\n",
3724 1.83 augustss iso->inuse, iso->next, xfer, xfer->nframes));
3725 1.83 augustss
3726 1.83 augustss if (sc->sc_dying)
3727 1.83 augustss return;
3728 1.83 augustss
3729 1.83 augustss if (iso->next == -1) {
3730 1.83 augustss /* Not in use yet, schedule it a few frames ahead. */
3731 1.168 augustss iso->next = O32TOH(sc->sc_hcca->hcca_frame_number) + 5;
3732 1.120 augustss DPRINTFN(2,("ohci_device_isoc_enter: start next=%d\n",
3733 1.83 augustss iso->next));
3734 1.83 augustss }
3735 1.83 augustss
3736 1.61 augustss sitd = opipe->tail.itd;
3737 1.61 augustss nframes = xfer->nframes;
3738 1.83 augustss xfer->hcpriv = sitd;
3739 1.182.12.1 itohy seg = 0;
3740 1.182.12.1 itohy segoff = 0;
3741 1.182.12.1 itohy i = 0;
3742 1.182.12.1 itohy while (i < nframes) {
3743 1.182.12.1 itohy /*
3744 1.182.12.1 itohy * Fill in as many ITD frames as possible.
3745 1.182.12.1 itohy */
3746 1.182.12.1 itohy USB_KASSERT2(seg < nsegs,
3747 1.182.12.1 itohy ("ohci_device_isoc_enter: overrun"));
3748 1.182.12.1 itohy bp0 = segs[seg].ds_addr + segoff;
3749 1.182.12.1 itohy sitd->itd.itd_bp0 = HTOO32(bp0);
3750 1.182.12.1 itohy prevpage = OHCI_PAGE(bp0);
3751 1.182.12.1 itohy npages = 1;
3752 1.182.12.1 itohy
3753 1.182.12.1 itohy ncur = 0;
3754 1.182.12.1 itohy while (ncur < OHCI_ITD_NOFFSET && i < nframes) {
3755 1.182.12.1 itohy /* Find the frame start and end physical addresses. */
3756 1.182.12.1 itohy len = xfer->frlengths[i];
3757 1.182.12.1 itohy dataphys = segs[seg].ds_addr + segoff;
3758 1.182.12.1 itohy curlen = segs[seg].ds_len - segoff;
3759 1.182.12.1 itohy if (len > curlen) {
3760 1.182.12.1 itohy USB_KASSERT2(seg + 1 < nsegs,
3761 1.182.12.1 itohy ("ohci_device_isoc_enter: overrun2"));
3762 1.182.12.1 itohy seg++;
3763 1.182.12.1 itohy segoff = len - curlen;
3764 1.182.12.1 itohy } else {
3765 1.182.12.1 itohy segoff += len;
3766 1.182.12.1 itohy }
3767 1.182.12.1 itohy USB_KASSERT2(segoff <= segs[seg].ds_len,
3768 1.182.12.1 itohy ("ohci_device_isoc_enter: overrun3"));
3769 1.182.12.1 itohy physend = segs[seg].ds_addr + segoff - 1;
3770 1.182.12.1 itohy
3771 1.182.12.1 itohy /* Check if there would be more than 2 pages . */
3772 1.182.12.1 itohy if (OHCI_PAGE(dataphys) != prevpage) {
3773 1.182.12.1 itohy prevpage = OHCI_PAGE(dataphys);
3774 1.182.12.1 itohy npages++;
3775 1.61 augustss }
3776 1.182.12.1 itohy if (OHCI_PAGE(physend) != prevpage) {
3777 1.182.12.1 itohy prevpage = OHCI_PAGE(physend);
3778 1.182.12.1 itohy npages++;
3779 1.182.12.1 itohy }
3780 1.182.12.1 itohy if (npages > 2 ||
3781 1.182.12.1 itohy ((sc->sc_flags & OHCI_FLAG_QUIRK_2ND_4KB) &&
3782 1.182.12.1 itohy npages == 2 &&
3783 1.182.12.1 itohy OHCI_PAGE_OFFSET(physend) == OHCI_PAGE_SIZE - 1)) {
3784 1.182.12.1 itohy /* We cannot fit this frame now. */
3785 1.182.12.1 itohy segoff -= len;
3786 1.182.12.1 itohy if (segoff < 0) {
3787 1.182.12.1 itohy seg--;
3788 1.182.12.1 itohy segoff += segs[seg].ds_len;
3789 1.182.12.1 itohy }
3790 1.182.12.1 itohy break;
3791 1.182.12.1 itohy }
3792 1.182.12.1 itohy
3793 1.182.12.1 itohy sitd->itd.itd_be = HTOO32(physend);
3794 1.182.12.1 itohy sitd->itd.itd_offset[ncur] =
3795 1.182.12.1 itohy HTOO16(OHCI_ITD_MK_OFFS(OHCI_PAGE(dataphys) ==
3796 1.182.12.1 itohy OHCI_PAGE(bp0) ? 0 : 1, dataphys));
3797 1.182.12.1 itohy i++;
3798 1.182.12.1 itohy ncur++;
3799 1.182.12.1 itohy }
3800 1.182.12.1 itohy if (segoff >= segs[seg].ds_len) {
3801 1.182.12.1 itohy USB_KASSERT2(segoff == segs[seg].ds_len,
3802 1.182.12.1 itohy ("ohci_device_isoc_enter: overlap"));
3803 1.182.12.1 itohy seg++;
3804 1.182.12.1 itohy segoff = 0;
3805 1.182.12.1 itohy }
3806 1.182.12.1 itohy
3807 1.182.12.1 itohy /* Allocate next ITD */
3808 1.182.12.1 itohy nsitd = ohci_alloc_sitd(sc);
3809 1.182.12.1 itohy if (nsitd == NULL) {
3810 1.182.12.1 itohy /* XXX what now? */
3811 1.182.12.1 itohy printf("%s: isoc TD alloc failed\n",
3812 1.182.12.1 itohy USBDEVNAME(sc->sc_bus.bdev));
3813 1.182.12.1 itohy return;
3814 1.182.12.1 itohy }
3815 1.83 augustss
3816 1.182.12.1 itohy /* Fill out remaining fields of current ITD */
3817 1.182.12.1 itohy sitd->nextitd = nsitd;
3818 1.182.12.1 itohy dmaadr = OHCI_SITD_DMAADDR(nsitd);
3819 1.182.12.1 itohy sitd->itd.itd_nextitd = HTOO32(dmaadr);
3820 1.182.12.1 itohy sitd->xfer = xfer;
3821 1.182.12.1 itohy if (i < nframes) {
3822 1.168 augustss sitd->itd.itd_flags = HTOO32(
3823 1.120 augustss OHCI_ITD_NOCC |
3824 1.61 augustss OHCI_ITD_SET_SF(iso->next) |
3825 1.83 augustss OHCI_ITD_SET_DI(6) | /* delay intr a little */
3826 1.83 augustss OHCI_ITD_SET_FC(ncur));
3827 1.182.12.1 itohy sitd->flags = OHCI_ITD_ACTIVE;
3828 1.182.12.1 itohy } else {
3829 1.182.12.1 itohy sitd->itd.itd_flags = HTOO32(
3830 1.182.12.1 itohy OHCI_ITD_NOCC |
3831 1.182.12.1 itohy OHCI_ITD_SET_SF(iso->next) |
3832 1.182.12.1 itohy OHCI_ITD_SET_DI(0) |
3833 1.182.12.1 itohy OHCI_ITD_SET_FC(ncur));
3834 1.182.12.1 itohy sitd->flags = OHCI_CALL_DONE | OHCI_ITD_ACTIVE;
3835 1.182.12.1 itohy }
3836 1.182.12.1 itohy iso->next += ncur;
3837 1.182.12.1 itohy
3838 1.182.12.1 itohy OHCI_SITD_SYNC(sc, sitd,
3839 1.182.12.1 itohy BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
3840 1.182.12.1 itohy sitd = nsitd;
3841 1.61 augustss }
3842 1.83 augustss
3843 1.83 augustss iso->inuse += nframes;
3844 1.83 augustss
3845 1.182.12.1 itohy /* XXX pretend we did it all */
3846 1.182.12.1 itohy xfer->actlen = 0;
3847 1.182.12.1 itohy for (i = 0; i < nframes; i++)
3848 1.182.12.1 itohy xfer->actlen += xfer->frlengths[i];
3849 1.83 augustss
3850 1.83 augustss xfer->status = USBD_IN_PROGRESS;
3851 1.83 augustss
3852 1.182.12.1 itohy #ifdef USB_DEBUG
3853 1.83 augustss if (ohcidebug > 5) {
3854 1.83 augustss DPRINTF(("ohci_device_isoc_enter: frame=%d\n",
3855 1.168 augustss O32TOH(sc->sc_hcca->hcca_frame_number)));
3856 1.168 augustss ohci_dump_itds(sc, xfer->hcpriv);
3857 1.168 augustss ohci_dump_ed(sc, sed);
3858 1.83 augustss }
3859 1.83 augustss #endif
3860 1.61 augustss
3861 1.83 augustss s = splusb();
3862 1.182.12.1 itohy opipe->tail.itd = sitd;
3863 1.168 augustss sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP);
3864 1.182.12.1 itohy dmaadr = OHCI_SITD_DMAADDR(sitd);
3865 1.182.12.1 itohy sed->ed.ed_tailp = HTOO32(dmaadr);
3866 1.182.12.1 itohy OHCI_SED_SYNC(sc, sed, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
3867 1.61 augustss splx(s);
3868 1.83 augustss
3869 1.182.12.1 itohy #ifdef USB_DEBUG
3870 1.83 augustss if (ohcidebug > 5) {
3871 1.83 augustss delay(150000);
3872 1.83 augustss DPRINTF(("ohci_device_isoc_enter: after frame=%d\n",
3873 1.168 augustss O32TOH(sc->sc_hcca->hcca_frame_number)));
3874 1.168 augustss ohci_dump_itds(sc, xfer->hcpriv);
3875 1.168 augustss ohci_dump_ed(sc, sed);
3876 1.83 augustss }
3877 1.83 augustss #endif
3878 1.60 augustss }
3879 1.60 augustss
3880 1.60 augustss usbd_status
3881 1.91 augustss ohci_device_isoc_start(usbd_xfer_handle xfer)
3882 1.60 augustss {
3883 1.83 augustss struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
3884 1.83 augustss ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
3885 1.182.12.1 itohy ohci_soft_ed_t *sed;
3886 1.182.12.1 itohy int s;
3887 1.83 augustss
3888 1.83 augustss DPRINTFN(5,("ohci_device_isoc_start: xfer=%p\n", xfer));
3889 1.83 augustss
3890 1.83 augustss if (sc->sc_dying)
3891 1.83 augustss return (USBD_IOERROR);
3892 1.83 augustss
3893 1.83 augustss #ifdef DIAGNOSTIC
3894 1.83 augustss if (xfer->status != USBD_IN_PROGRESS)
3895 1.121 tsutsui printf("ohci_device_isoc_start: not in progress %p\n", xfer);
3896 1.83 augustss #endif
3897 1.83 augustss
3898 1.83 augustss /* XXX anything to do? */
3899 1.83 augustss
3900 1.182.12.1 itohy s = splusb();
3901 1.182.12.1 itohy sed = opipe->sed; /* Turn off ED skip-bit to start processing */
3902 1.182.12.1 itohy sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); /* ED's ITD list.*/
3903 1.182.12.1 itohy splx(s);
3904 1.182.12.1 itohy
3905 1.83 augustss return (USBD_IN_PROGRESS);
3906 1.60 augustss }
3907 1.60 augustss
3908 1.60 augustss void
3909 1.91 augustss ohci_device_isoc_abort(usbd_xfer_handle xfer)
3910 1.60 augustss {
3911 1.83 augustss struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
3912 1.83 augustss ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
3913 1.83 augustss ohci_soft_ed_t *sed;
3914 1.182.12.1 itohy ohci_soft_itd_t *sitd, *sitdnext, *tmp_sitd;
3915 1.182.12.1 itohy ohci_physaddr_t dmaadr;
3916 1.182.12.1 itohy int s,undone,num_sitds;
3917 1.83 augustss
3918 1.83 augustss s = splusb();
3919 1.182.12.1 itohy opipe->aborting = 1;
3920 1.83 augustss
3921 1.83 augustss DPRINTFN(1,("ohci_device_isoc_abort: xfer=%p\n", xfer));
3922 1.83 augustss
3923 1.83 augustss /* Transfer is already done. */
3924 1.120 augustss if (xfer->status != USBD_NOT_STARTED &&
3925 1.83 augustss xfer->status != USBD_IN_PROGRESS) {
3926 1.83 augustss splx(s);
3927 1.83 augustss printf("ohci_device_isoc_abort: early return\n");
3928 1.83 augustss return;
3929 1.83 augustss }
3930 1.83 augustss
3931 1.83 augustss /* Give xfer the requested abort code. */
3932 1.83 augustss xfer->status = USBD_CANCELLED;
3933 1.83 augustss
3934 1.83 augustss sed = opipe->sed;
3935 1.182.12.1 itohy OHCI_SED_SYNC(sc, sed, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
3936 1.168 augustss sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); /* force hardware skip */
3937 1.83 augustss
3938 1.182.12.1 itohy num_sitds = 0;
3939 1.83 augustss sitd = xfer->hcpriv;
3940 1.83 augustss #ifdef DIAGNOSTIC
3941 1.83 augustss if (sitd == NULL) {
3942 1.102 augustss splx(s);
3943 1.83 augustss printf("ohci_device_isoc_abort: hcpriv==0\n");
3944 1.83 augustss return;
3945 1.83 augustss }
3946 1.83 augustss #endif
3947 1.182.12.1 itohy for (; sitd != NULL && sitd->xfer == xfer; sitd = sitd->nextitd) {
3948 1.182.12.1 itohy num_sitds++;
3949 1.83 augustss #ifdef DIAGNOSTIC
3950 1.83 augustss DPRINTFN(1,("abort sets done sitd=%p\n", sitd));
3951 1.83 augustss sitd->isdone = 1;
3952 1.83 augustss #endif
3953 1.83 augustss }
3954 1.83 augustss
3955 1.83 augustss splx(s);
3956 1.83 augustss
3957 1.182.12.1 itohy /*
3958 1.182.12.1 itohy * Each sitd has up to OHCI_ITD_NOFFSET transfers, each can
3959 1.182.12.1 itohy * take a usb 1ms cycle. Conservatively wait for it to drain.
3960 1.182.12.1 itohy * Even with DMA done, it can take awhile for the "batch"
3961 1.182.12.1 itohy * delivery of completion interrupts to occur thru the controller.
3962 1.182.12.1 itohy */
3963 1.182.12.1 itohy
3964 1.182.12.1 itohy do {
3965 1.182.12.1 itohy usb_delay_ms(&sc->sc_bus, 2*(num_sitds*OHCI_ITD_NOFFSET));
3966 1.182.12.1 itohy
3967 1.182.12.1 itohy undone = 0;
3968 1.182.12.1 itohy tmp_sitd = xfer->hcpriv;
3969 1.182.12.1 itohy for (; tmp_sitd != NULL && tmp_sitd->xfer == xfer;
3970 1.182.12.1 itohy tmp_sitd = tmp_sitd->nextitd) {
3971 1.182.12.1 itohy OHCI_SITD_SYNC(sc, tmp_sitd,
3972 1.182.12.1 itohy BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
3973 1.182.12.1 itohy if (OHCI_CC_NO_ERROR ==
3974 1.182.12.1 itohy OHCI_ITD_GET_CC(O32TOH(tmp_sitd->itd.itd_flags)) &&
3975 1.182.12.1 itohy tmp_sitd->flags & OHCI_ITD_ACTIVE &&
3976 1.182.12.1 itohy (tmp_sitd->flags & OHCI_ITD_INTFIN) == 0)
3977 1.182.12.1 itohy undone++;
3978 1.182.12.1 itohy }
3979 1.182.12.1 itohy } while( undone != 0 );
3980 1.182.12.1 itohy
3981 1.182.12.1 itohy /* Free the sitds */
3982 1.182.12.1 itohy for (sitd = xfer->hcpriv; sitd->xfer == xfer;
3983 1.182.12.1 itohy sitd = sitdnext) {
3984 1.182.12.1 itohy sitdnext = sitd->nextitd;
3985 1.182.12.1 itohy ohci_free_sitd(sc, sitd);
3986 1.182.12.1 itohy }
3987 1.83 augustss
3988 1.83 augustss s = splusb();
3989 1.83 augustss
3990 1.83 augustss /* Run callback. */
3991 1.182.12.1 itohy usb_transfer_complete_dma(xfer, &sc->sc_dmatag, &OXFER(xfer)->dmabuf);
3992 1.182.12.1 itohy
3993 1.182.12.1 itohy /* There is always a `next' sitd so link it up. */
3994 1.182.12.1 itohy dmaadr = OHCI_SITD_DMAADDR(sitd);
3995 1.182.12.1 itohy sed->ed.ed_headp = HTOO32(dmaadr);
3996 1.83 augustss
3997 1.168 augustss sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); /* remove hardware skip */
3998 1.182.12.1 itohy OHCI_SED_SYNC(sc, sed, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
3999 1.83 augustss
4000 1.83 augustss splx(s);
4001 1.60 augustss }
4002 1.60 augustss
4003 1.60 augustss void
4004 1.179 christos ohci_device_isoc_done(usbd_xfer_handle xfer)
4005 1.60 augustss {
4006 1.182.12.1 itohy /* This null routine corresponds to non-isoc "done()" routines
4007 1.182.12.1 itohy * that free the stds associated with an xfer after a completed
4008 1.182.12.1 itohy * xfer interrupt. However, in the case of isoc transfers, the
4009 1.182.12.1 itohy * sitds associated with the transfer have already been processed
4010 1.182.12.1 itohy * and reallocated for the next iteration by
4011 1.182.12.1 itohy * "ohci_device_isoc_transfer()".
4012 1.182.12.1 itohy *
4013 1.182.12.1 itohy * Routine "usb_transfer_complete()" is called at the end of every
4014 1.182.12.1 itohy * relevant usb interrupt. "usb_transfer_complete()" indirectly
4015 1.182.12.1 itohy * calls 1) "ohci_device_isoc_transfer()" (which keeps pumping the
4016 1.182.12.1 itohy * pipeline by setting up the next transfer iteration) and 2) then
4017 1.182.12.1 itohy * calls "ohci_device_isoc_done()". Isoc transfers have not been
4018 1.182.12.1 itohy * working for the ohci usb because this routine was trashing the
4019 1.182.12.1 itohy * xfer set up for the next iteration (thus, only the first
4020 1.182.12.1 itohy * UGEN_NISOREQS xfers outstanding on an open would work). Perhaps
4021 1.182.12.1 itohy * this could all be re-factored, but that's another pass...
4022 1.182.12.1 itohy */
4023 1.60 augustss }
4024 1.60 augustss
4025 1.60 augustss usbd_status
4026 1.91 augustss ohci_setup_isoc(usbd_pipe_handle pipe)
4027 1.60 augustss {
4028 1.60 augustss struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
4029 1.83 augustss ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
4030 1.60 augustss struct iso *iso = &opipe->u.iso;
4031 1.83 augustss int s;
4032 1.60 augustss
4033 1.60 augustss iso->next = -1;
4034 1.60 augustss iso->inuse = 0;
4035 1.60 augustss
4036 1.83 augustss s = splusb();
4037 1.168 augustss ohci_add_ed(sc, opipe->sed, sc->sc_isoc_head);
4038 1.83 augustss splx(s);
4039 1.83 augustss
4040 1.60 augustss return (USBD_NORMAL_COMPLETION);
4041 1.60 augustss }
4042 1.60 augustss
4043 1.60 augustss void
4044 1.91 augustss ohci_device_isoc_close(usbd_pipe_handle pipe)
4045 1.60 augustss {
4046 1.60 augustss struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
4047 1.60 augustss ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
4048 1.182.12.1 itohy ohci_soft_ed_t *sed;
4049 1.60 augustss
4050 1.60 augustss DPRINTF(("ohci_device_isoc_close: pipe=%p\n", pipe));
4051 1.182.12.1 itohy
4052 1.182.12.1 itohy sed = opipe->sed;
4053 1.182.12.1 itohy OHCI_SED_SYNC(sc, sed, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
4054 1.182.12.1 itohy sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); /* Stop device. */
4055 1.182.12.1 itohy OHCI_SED_SYNC(sc, sed, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
4056 1.182.12.1 itohy
4057 1.182.12.1 itohy ohci_close_pipe(pipe, sc->sc_isoc_head); /* Stop isoc list, free ED.*/
4058 1.182.12.1 itohy
4059 1.182.12.1 itohy /* up to NISOREQs xfers still outstanding. */
4060 1.182.12.1 itohy
4061 1.83 augustss #ifdef DIAGNOSTIC
4062 1.83 augustss opipe->tail.itd->isdone = 1;
4063 1.83 augustss #endif
4064 1.182.12.1 itohy ohci_free_sitd_norsv(sc, opipe->tail.itd); /* Next `avail free' sitd.*/
4065 1.1 augustss }
4066