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