Sun Dec 4 21:02:27 2011 UTC ()
adapt ohci, from mrg with some changes by me


(jmcneill)
diff -r1.218.6.1 -r1.218.6.2 src/sys/dev/usb/ohci.c
diff -r1.51 -r1.51.8.1 src/sys/dev/usb/ohcivar.h

cvs diff -r1.218.6.1 -r1.218.6.2 src/sys/dev/usb/ohci.c (expand / switch to unified diff)

--- src/sys/dev/usb/ohci.c 2011/12/04 13:23:16 1.218.6.1
+++ src/sys/dev/usb/ohci.c 2011/12/04 21:02:27 1.218.6.2
@@ -1,23 +1,24 @@ @@ -1,23 +1,24 @@
1/* $NetBSD: ohci.c,v 1.218.6.1 2011/12/04 13:23:16 jmcneill Exp $ */ 1/* $NetBSD: ohci.c,v 1.218.6.2 2011/12/04 21:02:27 jmcneill Exp $ */
2/* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */ 2/* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 1998, 2004, 2005 The NetBSD Foundation, Inc. 5 * Copyright (c) 1998, 2004, 2005, 2011 The NetBSD Foundation, Inc.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * This code is derived from software contributed to The NetBSD Foundation 8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Lennart Augustsson (lennart@augustsson.net) at 9 * by Lennart Augustsson (lennart@augustsson.net) at
10 * Carlstedt Research & Technology. 10 * Carlstedt Research & Technology, Jared D. McNeill (jmcneill@invisible.ca)
 11 * and Matthew R. Green.
11 * This code is derived from software contributed to The NetBSD Foundation 12 * This code is derived from software contributed to The NetBSD Foundation
12 * by Charles M. Hannum. 13 * by Charles M. Hannum.
13 * 14 *
14 * Redistribution and use in source and binary forms, with or without 15 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions 16 * modification, are permitted provided that the following conditions
16 * are met: 17 * are met:
17 * 1. Redistributions of source code must retain the above copyright 18 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer. 19 * notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright 20 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the 21 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution. 22 * documentation and/or other materials provided with the distribution.
22 * 23 *
23 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 24 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
@@ -31,33 +32,33 @@ @@ -31,33 +32,33 @@
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
34 */ 35 */
35 36
36/* 37/*
37 * USB Open Host Controller driver. 38 * USB Open Host Controller driver.
38 * 39 *
39 * OHCI spec: http://www.compaq.com/productinfo/development/openhci.html 40 * OHCI spec: http://www.compaq.com/productinfo/development/openhci.html
40 * USB spec: http://www.usb.org/developers/docs/ 41 * USB spec: http://www.usb.org/developers/docs/
41 */ 42 */
42 43
43#include <sys/cdefs.h> 44#include <sys/cdefs.h>
44__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.218.6.1 2011/12/04 13:23:16 jmcneill Exp $"); 45__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.218.6.2 2011/12/04 21:02:27 jmcneill Exp $");
45 46
46#include "opt_usb.h" 47#include "opt_usb.h"
47 48
48#include <sys/param.h> 49#include <sys/param.h>
49#include <sys/systm.h> 50#include <sys/systm.h>
50#include <sys/malloc.h> 51#include <sys/kmem.h>
51#include <sys/kernel.h> 52#include <sys/kernel.h>
52#include <sys/device.h> 53#include <sys/device.h>
53#include <sys/select.h> 54#include <sys/select.h>
54#include <sys/proc.h> 55#include <sys/proc.h>
55#include <sys/queue.h> 56#include <sys/queue.h>
56 57
57#include <sys/bus.h> 58#include <sys/bus.h>
58#include <machine/endian.h> 59#include <machine/endian.h>
59 60
60#include <dev/usb/usb.h> 61#include <dev/usb/usb.h>
61#include <dev/usb/usbdi.h> 62#include <dev/usb/usbdi.h>
62#include <dev/usb/usbdivar.h> 63#include <dev/usb/usbdivar.h>
63#include <dev/usb/usb_mem.h> 64#include <dev/usb/usb_mem.h>
@@ -103,47 +104,50 @@ Static void ohci_free_sitd(ohci_softc_t @@ -103,47 +104,50 @@ Static void ohci_free_sitd(ohci_softc_t
103#if 0 104#if 0
104Static void ohci_free_std_chain(ohci_softc_t *, ohci_soft_td_t *, 105Static void ohci_free_std_chain(ohci_softc_t *, ohci_soft_td_t *,
105 ohci_soft_td_t *); 106 ohci_soft_td_t *);
106#endif 107#endif
107Static usbd_status ohci_alloc_std_chain(struct ohci_pipe *, 108Static usbd_status ohci_alloc_std_chain(struct ohci_pipe *,
108 ohci_softc_t *, int, int, usbd_xfer_handle, 109 ohci_softc_t *, int, int, usbd_xfer_handle,
109 ohci_soft_td_t *, ohci_soft_td_t **); 110 ohci_soft_td_t *, ohci_soft_td_t **);
110 111
111Static usbd_status ohci_open(usbd_pipe_handle); 112Static usbd_status ohci_open(usbd_pipe_handle);
112Static void ohci_poll(struct usbd_bus *); 113Static void ohci_poll(struct usbd_bus *);
113Static void ohci_softintr(void *); 114Static void ohci_softintr(void *);
114Static void ohci_waitintr(ohci_softc_t *, usbd_xfer_handle); 115Static void ohci_waitintr(ohci_softc_t *, usbd_xfer_handle);
115Static void ohci_rhsc(ohci_softc_t *, usbd_xfer_handle); 116Static void ohci_rhsc(ohci_softc_t *, usbd_xfer_handle);
 117Static void ohci_rhsc_softint(void *arg);
116 118
117Static usbd_status ohci_device_request(usbd_xfer_handle xfer); 119Static usbd_status ohci_device_request(usbd_xfer_handle xfer);
118Static void ohci_add_ed(ohci_softc_t *, ohci_soft_ed_t *, 120Static void ohci_add_ed(ohci_softc_t *, ohci_soft_ed_t *,
119 ohci_soft_ed_t *); 121 ohci_soft_ed_t *);
120 122
121Static void ohci_rem_ed(ohci_soft_ed_t *, ohci_soft_ed_t *); 123Static void ohci_rem_ed(ohci_soft_ed_t *, ohci_soft_ed_t *);
122Static void ohci_hash_add_td(ohci_softc_t *, ohci_soft_td_t *); 124Static void ohci_hash_add_td(ohci_softc_t *, ohci_soft_td_t *);
123Static void ohci_hash_rem_td(ohci_softc_t *, ohci_soft_td_t *); 125Static void ohci_hash_rem_td(ohci_softc_t *, ohci_soft_td_t *);
124Static ohci_soft_td_t *ohci_hash_find_td(ohci_softc_t *, ohci_physaddr_t); 126Static ohci_soft_td_t *ohci_hash_find_td(ohci_softc_t *, ohci_physaddr_t);
125Static void ohci_hash_add_itd(ohci_softc_t *, ohci_soft_itd_t *); 127Static void ohci_hash_add_itd(ohci_softc_t *, ohci_soft_itd_t *);
126Static void ohci_hash_rem_itd(ohci_softc_t *, ohci_soft_itd_t *); 128Static void ohci_hash_rem_itd(ohci_softc_t *, ohci_soft_itd_t *);
127Static ohci_soft_itd_t *ohci_hash_find_itd(ohci_softc_t *, ohci_physaddr_t); 129Static ohci_soft_itd_t *ohci_hash_find_itd(ohci_softc_t *, ohci_physaddr_t);
128 130
129Static usbd_status ohci_setup_isoc(usbd_pipe_handle pipe); 131Static usbd_status ohci_setup_isoc(usbd_pipe_handle pipe);
130Static void ohci_device_isoc_enter(usbd_xfer_handle); 132Static void ohci_device_isoc_enter(usbd_xfer_handle);
131 133
132Static usbd_status ohci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t); 134Static usbd_status ohci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t);
133Static void ohci_freem(struct usbd_bus *, usb_dma_t *); 135Static void ohci_freem(struct usbd_bus *, usb_dma_t *);
134 136
135Static usbd_xfer_handle ohci_allocx(struct usbd_bus *); 137Static usbd_xfer_handle ohci_allocx(struct usbd_bus *);
136Static void ohci_freex(struct usbd_bus *, usbd_xfer_handle); 138Static void ohci_freex(struct usbd_bus *, usbd_xfer_handle);
 139Static void ohci_get_locks(struct usbd_bus *, kmutex_t **,
 140 kmutex_t **);
137 141
138Static usbd_status ohci_root_ctrl_transfer(usbd_xfer_handle); 142Static usbd_status ohci_root_ctrl_transfer(usbd_xfer_handle);
139Static usbd_status ohci_root_ctrl_start(usbd_xfer_handle); 143Static usbd_status ohci_root_ctrl_start(usbd_xfer_handle);
140Static void ohci_root_ctrl_abort(usbd_xfer_handle); 144Static void ohci_root_ctrl_abort(usbd_xfer_handle);
141Static void ohci_root_ctrl_close(usbd_pipe_handle); 145Static void ohci_root_ctrl_close(usbd_pipe_handle);
142Static void ohci_root_ctrl_done(usbd_xfer_handle); 146Static void ohci_root_ctrl_done(usbd_xfer_handle);
143 147
144Static usbd_status ohci_root_intr_transfer(usbd_xfer_handle); 148Static usbd_status ohci_root_intr_transfer(usbd_xfer_handle);
145Static usbd_status ohci_root_intr_start(usbd_xfer_handle); 149Static usbd_status ohci_root_intr_start(usbd_xfer_handle);
146Static void ohci_root_intr_abort(usbd_xfer_handle); 150Static void ohci_root_intr_abort(usbd_xfer_handle);
147Static void ohci_root_intr_close(usbd_pipe_handle); 151Static void ohci_root_intr_close(usbd_pipe_handle);
148Static void ohci_root_intr_done(usbd_xfer_handle); 152Static void ohci_root_intr_done(usbd_xfer_handle);
149 153
@@ -264,27 +268,27 @@ struct ohci_pipe { @@ -264,27 +268,27 @@ struct ohci_pipe {
264 } u; 268 } u;
265}; 269};
266 270
267#define OHCI_INTR_ENDPT 1 271#define OHCI_INTR_ENDPT 1
268 272
269Static const struct usbd_bus_methods ohci_bus_methods = { 273Static const struct usbd_bus_methods ohci_bus_methods = {
270 ohci_open, 274 ohci_open,
271 ohci_softintr, 275 ohci_softintr,
272 ohci_poll, 276 ohci_poll,
273 ohci_allocm, 277 ohci_allocm,
274 ohci_freem, 278 ohci_freem,
275 ohci_allocx, 279 ohci_allocx,
276 ohci_freex, 280 ohci_freex,
277 NULL, /* ohci_get_locks */ 281 ohci_get_locks,
278}; 282};
279 283
280Static const struct usbd_pipe_methods ohci_root_ctrl_methods = { 284Static const struct usbd_pipe_methods ohci_root_ctrl_methods = {
281 ohci_root_ctrl_transfer, 285 ohci_root_ctrl_transfer,
282 ohci_root_ctrl_start, 286 ohci_root_ctrl_start,
283 ohci_root_ctrl_abort, 287 ohci_root_ctrl_abort,
284 ohci_root_ctrl_close, 288 ohci_root_ctrl_close,
285 ohci_noop, 289 ohci_noop,
286 ohci_root_ctrl_done, 290 ohci_root_ctrl_done,
287}; 291};
288 292
289Static const struct usbd_pipe_methods ohci_root_intr_methods = { 293Static const struct usbd_pipe_methods ohci_root_intr_methods = {
290 ohci_root_intr_transfer, 294 ohci_root_intr_transfer,
@@ -361,31 +365,38 @@ ohci_detach(struct ohci_softc *sc, int f @@ -361,31 +365,38 @@ ohci_detach(struct ohci_softc *sc, int f
361 usbd_xfer_handle xfer; 365 usbd_xfer_handle xfer;
362 366
363 if (sc->sc_child != NULL) 367 if (sc->sc_child != NULL)
364 rv = config_detach(sc->sc_child, flags); 368 rv = config_detach(sc->sc_child, flags);
365 369
366 if (rv != 0) 370 if (rv != 0)
367 return (rv); 371 return (rv);
368 372
369 callout_stop(&sc->sc_tmo_rhsc); 373 callout_stop(&sc->sc_tmo_rhsc);
370 374
371 usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */ 375 usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */
372 callout_destroy(&sc->sc_tmo_rhsc); 376 callout_destroy(&sc->sc_tmo_rhsc);
373 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
374 if (sc->sc_hcca != NULL) 385 if (sc->sc_hcca != NULL)
375 usb_freemem(&sc->sc_bus, &sc->sc_hccadma); 386 usb_freemem(&sc->sc_bus, &sc->sc_hccadma);
376 while((xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers)) != NULL) { 387 while((xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers)) != NULL) {
377 SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next); 388 SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
378 free(xfer, M_USB); 389 kmem_free(xfer, sizeof(struct ohci_xfer));
379 } 390 }
380 391
381 return (rv); 392 return (rv);
382} 393}
383 394
384ohci_soft_ed_t * 395ohci_soft_ed_t *
385ohci_alloc_sed(ohci_softc_t *sc) 396ohci_alloc_sed(ohci_softc_t *sc)
386{ 397{
387 ohci_soft_ed_t *sed; 398 ohci_soft_ed_t *sed;
388 usbd_status err; 399 usbd_status err;
389 int i, offs; 400 int i, offs;
390 usb_dma_t dma; 401 usb_dma_t dma;
391 402
@@ -416,85 +427,79 @@ void @@ -416,85 +427,79 @@ void
416ohci_free_sed(ohci_softc_t *sc, ohci_soft_ed_t *sed) 427ohci_free_sed(ohci_softc_t *sc, ohci_soft_ed_t *sed)
417{ 428{
418 sed->next = sc->sc_freeeds; 429 sed->next = sc->sc_freeeds;
419 sc->sc_freeeds = sed; 430 sc->sc_freeeds = sed;
420} 431}
421 432
422ohci_soft_td_t * 433ohci_soft_td_t *
423ohci_alloc_std(ohci_softc_t *sc) 434ohci_alloc_std(ohci_softc_t *sc)
424{ 435{
425 ohci_soft_td_t *std; 436 ohci_soft_td_t *std;
426 usbd_status err; 437 usbd_status err;
427 int i, offs; 438 int i, offs;
428 usb_dma_t dma; 439 usb_dma_t dma;
429 int s; 
430 440
431 if (sc->sc_freetds == NULL) { 441 if (sc->sc_freetds == NULL) {
432 DPRINTFN(2, ("ohci_alloc_std: allocating chunk\n")); 442 DPRINTFN(2, ("ohci_alloc_std: allocating chunk\n"));
433 err = usb_allocmem(&sc->sc_bus, OHCI_STD_SIZE * OHCI_STD_CHUNK, 443 err = usb_allocmem(&sc->sc_bus, OHCI_STD_SIZE * OHCI_STD_CHUNK,
434 OHCI_TD_ALIGN, &dma); 444 OHCI_TD_ALIGN, &dma);
435 if (err) 445 if (err)
436 return (NULL); 446 return (NULL);
437 s = splusb(); 
438 for(i = 0; i < OHCI_STD_CHUNK; i++) { 447 for(i = 0; i < OHCI_STD_CHUNK; i++) {
439 offs = i * OHCI_STD_SIZE; 448 offs = i * OHCI_STD_SIZE;
440 std = KERNADDR(&dma, offs); 449 std = KERNADDR(&dma, offs);
441 std->physaddr = DMAADDR(&dma, offs); 450 std->physaddr = DMAADDR(&dma, offs);
442 std->dma = dma; 451 std->dma = dma;
443 std->offs = offs; 452 std->offs = offs;
444 std->nexttd = sc->sc_freetds; 453 std->nexttd = sc->sc_freetds;
445 sc->sc_freetds = std; 454 sc->sc_freetds = std;
446 } 455 }
447 splx(s); 
448 } 456 }
449 457
450 s = splusb(); 
451 std = sc->sc_freetds; 458 std = sc->sc_freetds;
452 sc->sc_freetds = std->nexttd; 459 sc->sc_freetds = std->nexttd;
453 memset(&std->td, 0, sizeof(ohci_td_t)); 460 memset(&std->td, 0, sizeof(ohci_td_t));
454 std->nexttd = NULL; 461 std->nexttd = NULL;
455 std->xfer = NULL; 462 std->xfer = NULL;
456 ohci_hash_add_td(sc, std); 463 ohci_hash_add_td(sc, std);
457 splx(s); 
458 464
459 return (std); 465 return (std);
460} 466}
461 467
462void 468void
463ohci_free_std(ohci_softc_t *sc, ohci_soft_td_t *std) 469ohci_free_std(ohci_softc_t *sc, ohci_soft_td_t *std)
464{ 470{
465 int s; 
466 471
467 s = splusb(); 
468 ohci_hash_rem_td(sc, std); 472 ohci_hash_rem_td(sc, std);
469 std->nexttd = sc->sc_freetds; 473 std->nexttd = sc->sc_freetds;
470 sc->sc_freetds = std; 474 sc->sc_freetds = std;
471 splx(s); 
472} 475}
473 476
474usbd_status 477usbd_status
475ohci_alloc_std_chain(struct ohci_pipe *opipe, ohci_softc_t *sc, 478ohci_alloc_std_chain(struct ohci_pipe *opipe, ohci_softc_t *sc,
476 int alen, int rd, usbd_xfer_handle xfer, 479 int alen, int rd, usbd_xfer_handle xfer,
477 ohci_soft_td_t *sp, ohci_soft_td_t **ep) 480 ohci_soft_td_t *sp, ohci_soft_td_t **ep)
478{ 481{
479 ohci_soft_td_t *next, *cur; 482 ohci_soft_td_t *next, *cur;
480 ohci_physaddr_t dataphys, dataphysend; 483 ohci_physaddr_t dataphys, dataphysend;
481 u_int32_t tdflags; 484 u_int32_t tdflags;
482 int len, curlen; 485 int len, curlen;
483 usb_dma_t *dma = &xfer->dmabuf; 486 usb_dma_t *dma = &xfer->dmabuf;
484 u_int16_t flags = xfer->flags; 487 u_int16_t flags = xfer->flags;
485 488
486 DPRINTFN(alen < 4096,("ohci_alloc_std_chain: start len=%d\n", alen)); 489 DPRINTFN(alen < 4096,("ohci_alloc_std_chain: start len=%d\n", alen));
487 490
 491 KASSERT(mutex_owned(&sc->sc_lock));
 492
488 len = alen; 493 len = alen;
489 cur = sp; 494 cur = sp;
490 dataphys = DMAADDR(dma, 0); 495 dataphys = DMAADDR(dma, 0);
491 dataphysend = OHCI_PAGE(dataphys + len - 1); 496 dataphysend = OHCI_PAGE(dataphys + len - 1);
492 usb_syncmem(dma, 0, len, 497 usb_syncmem(dma, 0, len,
493 rd ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); 498 rd ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
494 tdflags = HTOO32( 499 tdflags = HTOO32(
495 (rd ? OHCI_TD_IN : OHCI_TD_OUT) | 500 (rd ? OHCI_TD_IN : OHCI_TD_OUT) |
496 (flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0) | 501 (flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0) |
497 OHCI_TD_NOCC | OHCI_TD_TOGGLE_CARRY | OHCI_TD_NOINTR); 502 OHCI_TD_NOCC | OHCI_TD_TOGGLE_CARRY | OHCI_TD_NOINTR);
498 503
499 for (;;) { 504 for (;;) {
500 next = ohci_alloc_std(sc); 505 next = ohci_alloc_std(sc);
@@ -580,100 +585,100 @@ ohci_free_std_chain(ohci_softc_t *sc, oh @@ -580,100 +585,100 @@ ohci_free_std_chain(ohci_softc_t *sc, oh
580 585
581 for (; std != stdend; std = p) { 586 for (; std != stdend; std = p) {
582 p = std->nexttd; 587 p = std->nexttd;
583 ohci_free_std(sc, std); 588 ohci_free_std(sc, std);
584 } 589 }
585} 590}
586#endif 591#endif
587 592
588ohci_soft_itd_t * 593ohci_soft_itd_t *
589ohci_alloc_sitd(ohci_softc_t *sc) 594ohci_alloc_sitd(ohci_softc_t *sc)
590{ 595{
591 ohci_soft_itd_t *sitd; 596 ohci_soft_itd_t *sitd;
592 usbd_status err; 597 usbd_status err;
593 int i, s, offs; 598 int i, offs;
594 usb_dma_t dma; 599 usb_dma_t dma;
595 600
596 if (sc->sc_freeitds == NULL) { 601 if (sc->sc_freeitds == NULL) {
597 DPRINTFN(2, ("ohci_alloc_sitd: allocating chunk\n")); 602 DPRINTFN(2, ("ohci_alloc_sitd: allocating chunk\n"));
598 err = usb_allocmem(&sc->sc_bus, OHCI_SITD_SIZE * OHCI_SITD_CHUNK, 603 err = usb_allocmem(&sc->sc_bus, OHCI_SITD_SIZE * OHCI_SITD_CHUNK,
599 OHCI_ITD_ALIGN, &dma); 604 OHCI_ITD_ALIGN, &dma);
600 if (err) 605 if (err)
601 return (NULL); 606 return (NULL);
602 s = splusb(); 
603 for(i = 0; i < OHCI_SITD_CHUNK; i++) { 607 for(i = 0; i < OHCI_SITD_CHUNK; i++) {
604 offs = i * OHCI_SITD_SIZE; 608 offs = i * OHCI_SITD_SIZE;
605 sitd = KERNADDR(&dma, offs); 609 sitd = KERNADDR(&dma, offs);
606 sitd->physaddr = DMAADDR(&dma, offs); 610 sitd->physaddr = DMAADDR(&dma, offs);
607 sitd->dma = dma; 611 sitd->dma = dma;
608 sitd->offs = offs; 612 sitd->offs = offs;
609 sitd->nextitd = sc->sc_freeitds; 613 sitd->nextitd = sc->sc_freeitds;
610 sc->sc_freeitds = sitd; 614 sc->sc_freeitds = sitd;
611 } 615 }
612 splx(s); 
613 } 616 }
614 617
615 s = splusb(); 
616 sitd = sc->sc_freeitds; 618 sitd = sc->sc_freeitds;
617 sc->sc_freeitds = sitd->nextitd; 619 sc->sc_freeitds = sitd->nextitd;
618 memset(&sitd->itd, 0, sizeof(ohci_itd_t)); 620 memset(&sitd->itd, 0, sizeof(ohci_itd_t));
619 sitd->nextitd = NULL; 621 sitd->nextitd = NULL;
620 sitd->xfer = NULL; 622 sitd->xfer = NULL;
621 ohci_hash_add_itd(sc, sitd); 623 ohci_hash_add_itd(sc, sitd);
622 splx(s); 
623 624
624#ifdef DIAGNOSTIC 625#ifdef DIAGNOSTIC
625 sitd->isdone = 0; 626 sitd->isdone = 0;
626#endif 627#endif
627 628
628 return (sitd); 629 return (sitd);
629} 630}
630 631
631void 632void
632ohci_free_sitd(ohci_softc_t *sc, ohci_soft_itd_t *sitd) 633ohci_free_sitd(ohci_softc_t *sc, ohci_soft_itd_t *sitd)
633{ 634{
634 int s; 
635 635
636 DPRINTFN(10,("ohci_free_sitd: sitd=%p\n", sitd)); 636 DPRINTFN(10,("ohci_free_sitd: sitd=%p\n", sitd));
637 637
638#ifdef DIAGNOSTIC 638#ifdef DIAGNOSTIC
639 if (!sitd->isdone) { 639 if (!sitd->isdone) {
640 panic("ohci_free_sitd: sitd=%p not done", sitd); 640 panic("ohci_free_sitd: sitd=%p not done", sitd);
641 return; 641 return;
642 } 642 }
643 /* Warn double free */ 643 /* Warn double free */
644 sitd->isdone = 0; 644 sitd->isdone = 0;
645#endif 645#endif
646 646
647 s = splusb(); 
648 ohci_hash_rem_itd(sc, sitd); 647 ohci_hash_rem_itd(sc, sitd);
649 sitd->nextitd = sc->sc_freeitds; 648 sitd->nextitd = sc->sc_freeitds;
650 sc->sc_freeitds = sitd; 649 sc->sc_freeitds = sitd;
651 splx(s); 
652} 650}
653 651
654usbd_status 652usbd_status
655ohci_init(ohci_softc_t *sc) 653ohci_init(ohci_softc_t *sc)
656{ 654{
657 ohci_soft_ed_t *sed, *psed; 655 ohci_soft_ed_t *sed, *psed;
658 usbd_status err; 656 usbd_status err;
659 int i; 657 int i;
660 u_int32_t s, ctl, rwc, ival, hcr, fm, per, rev, desca, descb; 658 u_int32_t s, ctl, rwc, ival, hcr, fm, per, rev, desca, descb;
661 659
662 DPRINTF(("ohci_init: start\n")); 660 DPRINTF(("ohci_init: start\n"));
663 aprint_normal_dev(sc->sc_dev, ""); 661 aprint_normal_dev(sc->sc_dev, "");
664 662
665 sc->sc_hcca = NULL; 663 sc->sc_hcca = NULL;
666 callout_init(&sc->sc_tmo_rhsc, 0); 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);
667 672
668 for (i = 0; i < OHCI_HASH_SIZE; i++) 673 for (i = 0; i < OHCI_HASH_SIZE; i++)
669 LIST_INIT(&sc->sc_hash_tds[i]); 674 LIST_INIT(&sc->sc_hash_tds[i]);
670 for (i = 0; i < OHCI_HASH_SIZE; i++) 675 for (i = 0; i < OHCI_HASH_SIZE; i++)
671 LIST_INIT(&sc->sc_hash_itds[i]); 676 LIST_INIT(&sc->sc_hash_itds[i]);
672 677
673 SIMPLEQ_INIT(&sc->sc_free_xfers); 678 SIMPLEQ_INIT(&sc->sc_free_xfers);
674 679
675 rev = OREAD4(sc, OHCI_REVISION); 680 rev = OREAD4(sc, OHCI_REVISION);
676 aprint_normal("OHCI version %d.%d%s\n", 681 aprint_normal("OHCI version %d.%d%s\n",
677 OHCI_REV_HI(rev), OHCI_REV_LO(rev), 682 OHCI_REV_HI(rev), OHCI_REV_LO(rev),
678 OHCI_REV_LEGACY(rev) ? ", legacy support" : ""); 683 OHCI_REV_LEGACY(rev) ? ", legacy support" : "");
679 684
@@ -949,124 +954,139 @@ ohci_allocx(struct usbd_bus *bus) @@ -949,124 +954,139 @@ ohci_allocx(struct usbd_bus *bus)
949 struct ohci_softc *sc = bus->hci_private; 954 struct ohci_softc *sc = bus->hci_private;
950 usbd_xfer_handle xfer; 955 usbd_xfer_handle xfer;
951 956
952 xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers); 957 xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
953 if (xfer != NULL) { 958 if (xfer != NULL) {
954 SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next); 959 SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
955#ifdef DIAGNOSTIC 960#ifdef DIAGNOSTIC
956 if (xfer->busy_free != XFER_FREE) { 961 if (xfer->busy_free != XFER_FREE) {
957 printf("ohci_allocx: xfer=%p not free, 0x%08x\n", xfer, 962 printf("ohci_allocx: xfer=%p not free, 0x%08x\n", xfer,
958 xfer->busy_free); 963 xfer->busy_free);
959 } 964 }
960#endif 965#endif
961 } else { 966 } else {
962 xfer = malloc(sizeof(struct ohci_xfer), M_USB, M_NOWAIT); 967 xfer = kmem_alloc(sizeof(struct ohci_xfer), KM_SLEEP);
963 } 968 }
964 if (xfer != NULL) { 969 if (xfer != NULL) {
965 memset(xfer, 0, sizeof (struct ohci_xfer)); 970 memset(xfer, 0, sizeof (struct ohci_xfer));
966#ifdef DIAGNOSTIC 971#ifdef DIAGNOSTIC
967 xfer->busy_free = XFER_BUSY; 972 xfer->busy_free = XFER_BUSY;
968#endif 973#endif
969 } 974 }
970 return (xfer); 975 return (xfer);
971} 976}
972 977
973void 978void
974ohci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer) 979ohci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer)
975{ 980{
976 struct ohci_softc *sc = bus->hci_private; 981 struct ohci_softc *sc = bus->hci_private;
977 982
978#ifdef DIAGNOSTIC 983#ifdef DIAGNOSTIC
979 if (xfer->busy_free != XFER_BUSY) { 984 if (xfer->busy_free != XFER_BUSY) {
980 printf("ohci_freex: xfer=%p not busy, 0x%08x\n", xfer, 985 printf("ohci_freex: xfer=%p not busy, 0x%08x\n", xfer,
981 xfer->busy_free); 986 xfer->busy_free);
982 } 987 }
983 xfer->busy_free = XFER_FREE; 988 xfer->busy_free = XFER_FREE;
984#endif 989#endif
985 SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next); 990 SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
986} 991}
987 992
 993Static void
 994ohci_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
988/* 1002/*
989 * Shut down the controller when the system is going down. 1003 * Shut down the controller when the system is going down.
990 */ 1004 */
991bool 1005bool
992ohci_shutdown(device_t self, int flags) 1006ohci_shutdown(device_t self, int flags)
993{ 1007{
994 ohci_softc_t *sc = device_private(self); 1008 ohci_softc_t *sc = device_private(self);
995 1009
996 DPRINTF(("ohci_shutdown: stopping the HC\n")); 1010 DPRINTF(("ohci_shutdown: stopping the HC\n"));
997 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET); 1011 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
998 return true; 1012 return true;
999} 1013}
1000 1014
1001bool 1015bool
1002ohci_resume(device_t dv, const pmf_qual_t *qual) 1016ohci_resume(device_t dv, const pmf_qual_t *qual)
1003{ 1017{
1004 ohci_softc_t *sc = device_private(dv); 1018 ohci_softc_t *sc = device_private(dv);
1005 uint32_t ctl; 1019 uint32_t ctl;
1006 int s; 
1007 1020
1008 s = splhardusb(); 1021 mutex_spin_enter(&sc->sc_intr_lock);
1009 sc->sc_bus.use_polling++; 1022 sc->sc_bus.use_polling++;
 1023 mutex_spin_exit(&sc->sc_intr_lock);
 1024
1010 /* Some broken BIOSes do not recover these values */ 1025 /* Some broken BIOSes do not recover these values */
1011 OWRITE4(sc, OHCI_HCCA, DMAADDR(&sc->sc_hccadma, 0)); 1026 OWRITE4(sc, OHCI_HCCA, DMAADDR(&sc->sc_hccadma, 0));
1012 OWRITE4(sc, OHCI_CONTROL_HEAD_ED, 1027 OWRITE4(sc, OHCI_CONTROL_HEAD_ED,
1013 sc->sc_ctrl_head->physaddr); 1028 sc->sc_ctrl_head->physaddr);
1014 OWRITE4(sc, OHCI_BULK_HEAD_ED, 1029 OWRITE4(sc, OHCI_BULK_HEAD_ED,
1015 sc->sc_bulk_head->physaddr); 1030 sc->sc_bulk_head->physaddr);
1016 if (sc->sc_intre) 1031 if (sc->sc_intre)
1017 OWRITE4(sc, OHCI_INTERRUPT_ENABLE, sc->sc_intre & 1032 OWRITE4(sc, OHCI_INTERRUPT_ENABLE, sc->sc_intre &
1018 (OHCI_ALL_INTRS | OHCI_MIE)); 1033 (OHCI_ALL_INTRS | OHCI_MIE));
1019 if (sc->sc_control) 1034 if (sc->sc_control)
1020 ctl = sc->sc_control; 1035 ctl = sc->sc_control;
1021 else 1036 else
1022 ctl = OREAD4(sc, OHCI_CONTROL); 1037 ctl = OREAD4(sc, OHCI_CONTROL);
1023 ctl |= OHCI_HCFS_RESUME; 1038 ctl |= OHCI_HCFS_RESUME;
1024 OWRITE4(sc, OHCI_CONTROL, ctl); 1039 OWRITE4(sc, OHCI_CONTROL, ctl);
1025 usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY); 1040 usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY);
1026 ctl = (ctl & ~OHCI_HCFS_MASK) | OHCI_HCFS_OPERATIONAL; 1041 ctl = (ctl & ~OHCI_HCFS_MASK) | OHCI_HCFS_OPERATIONAL;
1027 OWRITE4(sc, OHCI_CONTROL, ctl); 1042 OWRITE4(sc, OHCI_CONTROL, ctl);
1028 usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY); 1043 usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY);
1029 sc->sc_control = sc->sc_intre = 0; 1044 sc->sc_control = sc->sc_intre = 0;
 1045
 1046 mutex_spin_enter(&sc->sc_intr_lock);
1030 sc->sc_bus.use_polling--; 1047 sc->sc_bus.use_polling--;
1031 splx(s); 1048 mutex_spin_exit(&sc->sc_intr_lock);
1032 1049
1033 return true; 1050 return true;
1034} 1051}
1035 1052
1036bool 1053bool
1037ohci_suspend(device_t dv, const pmf_qual_t *qual) 1054ohci_suspend(device_t dv, const pmf_qual_t *qual)
1038{ 1055{
1039 ohci_softc_t *sc = device_private(dv); 1056 ohci_softc_t *sc = device_private(dv);
1040 uint32_t ctl; 1057 uint32_t ctl;
1041 int s; 
1042 1058
1043 s = splhardusb(); 1059 mutex_spin_enter(&sc->sc_intr_lock);
1044 sc->sc_bus.use_polling++; 1060 sc->sc_bus.use_polling++;
 1061 mutex_spin_exit(&sc->sc_intr_lock);
 1062
1045 ctl = OREAD4(sc, OHCI_CONTROL) & ~OHCI_HCFS_MASK; 1063 ctl = OREAD4(sc, OHCI_CONTROL) & ~OHCI_HCFS_MASK;
1046 if (sc->sc_control == 0) { 1064 if (sc->sc_control == 0) {
1047 /* 1065 /*
1048 * Preserve register values, in case that BIOS 1066 * Preserve register values, in case that BIOS
1049 * does not recover them. 1067 * does not recover them.
1050 */ 1068 */
1051 sc->sc_control = ctl; 1069 sc->sc_control = ctl;
1052 sc->sc_intre = OREAD4(sc, 1070 sc->sc_intre = OREAD4(sc,
1053 OHCI_INTERRUPT_ENABLE); 1071 OHCI_INTERRUPT_ENABLE);
1054 } 1072 }
1055 ctl |= OHCI_HCFS_SUSPEND; 1073 ctl |= OHCI_HCFS_SUSPEND;
1056 OWRITE4(sc, OHCI_CONTROL, ctl); 1074 OWRITE4(sc, OHCI_CONTROL, ctl);
1057 usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT); 1075 usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
 1076
 1077 mutex_spin_enter(&sc->sc_intr_lock);
1058 sc->sc_bus.use_polling--; 1078 sc->sc_bus.use_polling--;
1059 splx(s); 1079 mutex_spin_exit(&sc->sc_intr_lock);
1060 1080
1061 return true; 1081 return true;
1062} 1082}
1063 1083
1064#ifdef OHCI_DEBUG 1084#ifdef OHCI_DEBUG
1065void 1085void
1066ohci_dumpregs(ohci_softc_t *sc) 1086ohci_dumpregs(ohci_softc_t *sc)
1067{ 1087{
1068 DPRINTF(("ohci_dumpregs: rev=0x%08x control=0x%08x command=0x%08x\n", 1088 DPRINTF(("ohci_dumpregs: rev=0x%08x control=0x%08x command=0x%08x\n",
1069 OREAD4(sc, OHCI_REVISION), 1089 OREAD4(sc, OHCI_REVISION),
1070 OREAD4(sc, OHCI_CONTROL), 1090 OREAD4(sc, OHCI_CONTROL),
1071 OREAD4(sc, OHCI_COMMAND_STATUS))); 1091 OREAD4(sc, OHCI_COMMAND_STATUS)));
1072 DPRINTF((" intrstat=0x%08x intre=0x%08x intrd=0x%08x\n", 1092 DPRINTF((" intrstat=0x%08x intre=0x%08x intrd=0x%08x\n",
@@ -1098,60 +1118,72 @@ ohci_dumpregs(ohci_softc_t *sc) @@ -1098,60 +1118,72 @@ ohci_dumpregs(ohci_softc_t *sc)
1098 OREAD4(sc, OHCI_RH_PORT_STATUS(2)))); 1118 OREAD4(sc, OHCI_RH_PORT_STATUS(2))));
1099 DPRINTF((" HCCA: frame_number=0x%04x done_head=0x%08x\n", 1119 DPRINTF((" HCCA: frame_number=0x%04x done_head=0x%08x\n",
1100 O32TOH(sc->sc_hcca->hcca_frame_number), 1120 O32TOH(sc->sc_hcca->hcca_frame_number),
1101 O32TOH(sc->sc_hcca->hcca_done_head))); 1121 O32TOH(sc->sc_hcca->hcca_done_head)));
1102} 1122}
1103#endif 1123#endif
1104 1124
1105Static int ohci_intr1(ohci_softc_t *); 1125Static int ohci_intr1(ohci_softc_t *);
1106 1126
1107int 1127int
1108ohci_intr(void *p) 1128ohci_intr(void *p)
1109{ 1129{
1110 ohci_softc_t *sc = p; 1130 ohci_softc_t *sc = p;
 1131 int ret = 0;
1111 1132
1112 if (sc == NULL || sc->sc_dying || !device_has_power(sc->sc_dev)) 1133 if (sc == NULL)
1113 return (0); 1134 return (0);
1114 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
1115 /* If we get an interrupt while polling, then just ignore it. */ 1141 /* If we get an interrupt while polling, then just ignore it. */
1116 if (sc->sc_bus.use_polling) { 1142 if (sc->sc_bus.use_polling) {
1117#ifdef DIAGNOSTIC 1143#ifdef DIAGNOSTIC
1118 DPRINTFN(16, ("ohci_intr: ignored interrupt while polling\n")); 1144 DPRINTFN(16, ("ohci_intr: ignored interrupt while polling\n"));
1119#endif 1145#endif
1120 /* for level triggered intrs, should do something to ack */ 1146 /* for level triggered intrs, should do something to ack */
1121 OWRITE4(sc, OHCI_INTERRUPT_STATUS, 1147 OWRITE4(sc, OHCI_INTERRUPT_STATUS,
1122 OREAD4(sc, OHCI_INTERRUPT_STATUS)); 1148 OREAD4(sc, OHCI_INTERRUPT_STATUS));
1123 1149
1124 return (0); 1150 return (0);
1125 } 1151 }
1126 1152
1127 return (ohci_intr1(sc)); 1153 ret = ohci_intr1(sc);
 1154
 1155done:
 1156 mutex_spin_exit(&sc->sc_intr_lock);
 1157 return ret;
1128} 1158}
1129 1159
1130Static int 1160Static int
1131ohci_intr1(ohci_softc_t *sc) 1161ohci_intr1(ohci_softc_t *sc)
1132{ 1162{
1133 u_int32_t intrs, eintrs; 1163 u_int32_t intrs, eintrs;
1134 1164
1135 DPRINTFN(14,("ohci_intr1: enter\n")); 1165 DPRINTFN(14,("ohci_intr1: enter\n"));
1136 1166
1137 /* In case the interrupt occurs before initialization has completed. */ 1167 /* In case the interrupt occurs before initialization has completed. */
1138 if (sc == NULL || sc->sc_hcca == NULL) { 1168 if (sc == NULL || sc->sc_hcca == NULL) {
1139#ifdef DIAGNOSTIC 1169#ifdef DIAGNOSTIC
1140 printf("ohci_intr: sc->sc_hcca == NULL\n"); 1170 printf("ohci_intr: sc->sc_hcca == NULL\n");
1141#endif 1171#endif
1142 return (0); 1172 return (0);
1143 } 1173 }
1144 1174
 1175 KASSERT(mutex_owned(&sc->sc_intr_lock));
 1176
1145 intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS); 1177 intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS);
1146 if (!intrs) 1178 if (!intrs)
1147 return (0); 1179 return (0);
1148 1180
1149 OWRITE4(sc, OHCI_INTERRUPT_STATUS, intrs & ~(OHCI_MIE|OHCI_WDH)); /* Acknowledge */ 1181 OWRITE4(sc, OHCI_INTERRUPT_STATUS, intrs & ~(OHCI_MIE|OHCI_WDH)); /* Acknowledge */
1150 eintrs = intrs & sc->sc_eintrs; 1182 eintrs = intrs & sc->sc_eintrs;
1151 DPRINTFN(7, ("ohci_intr: sc=%p intrs=%#x(%#x) eintrs=%#x(%#x)\n", 1183 DPRINTFN(7, ("ohci_intr: sc=%p intrs=%#x(%#x) eintrs=%#x(%#x)\n",
1152 sc, (u_int)intrs, OREAD4(sc, OHCI_INTERRUPT_STATUS), 1184 sc, (u_int)intrs, OREAD4(sc, OHCI_INTERRUPT_STATUS),
1153 (u_int)eintrs, sc->sc_eintrs)); 1185 (u_int)eintrs, sc->sc_eintrs));
1154 1186
1155 if (!eintrs) { 1187 if (!eintrs) {
1156 return (0); 1188 return (0);
1157 } 1189 }
@@ -1180,54 +1212,52 @@ ohci_intr1(ohci_softc_t *sc) @@ -1180,54 +1212,52 @@ ohci_intr1(ohci_softc_t *sc)
1180 /* XXX process resume detect */ 1212 /* XXX process resume detect */
1181 } 1213 }
1182 if (eintrs & OHCI_UE) { 1214 if (eintrs & OHCI_UE) {
1183 printf("%s: unrecoverable error, controller halted\n", 1215 printf("%s: unrecoverable error, controller halted\n",
1184 device_xname(sc->sc_dev)); 1216 device_xname(sc->sc_dev));
1185 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET); 1217 OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
1186 /* XXX what else */ 1218 /* XXX what else */
1187 } 1219 }
1188 if (eintrs & OHCI_RHSC) { 1220 if (eintrs & OHCI_RHSC) {
1189 /* 1221 /*
1190 * We block the interrupt below, and reenable it later from 1222 * We block the interrupt below, and reenable it later from
1191 * a timeout. 1223 * a timeout.
1192 */ 1224 */
1193 ohci_rhsc(sc, sc->sc_intrxfer); 1225 softint_schedule(sc->sc_rhsc_si);
1194 /* Do not allow RHSC interrupts > 1 per second */ 
1195 callout_reset(&sc->sc_tmo_rhsc, hz, ohci_rhsc_enable, sc); 
1196 } 1226 }
1197 1227
1198 sc->sc_bus.intr_context--; 1228 sc->sc_bus.intr_context--;
1199 1229
1200 if (eintrs != 0) { 1230 if (eintrs != 0) {
1201 /* Block unprocessed interrupts. */ 1231 /* Block unprocessed interrupts. */
1202 OWRITE4(sc, OHCI_INTERRUPT_DISABLE, eintrs); 1232 OWRITE4(sc, OHCI_INTERRUPT_DISABLE, eintrs);
1203 sc->sc_eintrs &= ~eintrs; 1233 sc->sc_eintrs &= ~eintrs;
1204 DPRINTFN(1, ("%s: blocking intrs 0x%x\n", 1234 DPRINTFN(1, ("%s: blocking intrs 0x%x\n",
1205 device_xname(sc->sc_dev), eintrs)); 1235 device_xname(sc->sc_dev), eintrs));
1206 } 1236 }
1207 1237
1208 return (1); 1238 return (1);
1209} 1239}
1210 1240
1211void 1241void
1212ohci_rhsc_enable(void *v_sc) 1242ohci_rhsc_enable(void *v_sc)
1213{ 1243{
1214 ohci_softc_t *sc = v_sc; 1244 ohci_softc_t *sc = v_sc;
1215 int s; 
1216 1245
1217 s = splhardusb(); 1246 DPRINTFN(1, ("%s: %s\n", __func__, device_xname(sc->sc_dev)));
 1247 mutex_spin_enter(&sc->sc_intr_lock);
1218 sc->sc_eintrs |= OHCI_RHSC; 1248 sc->sc_eintrs |= OHCI_RHSC;
1219 OWRITE4(sc, OHCI_INTERRUPT_ENABLE, OHCI_RHSC); 1249 OWRITE4(sc, OHCI_INTERRUPT_ENABLE, OHCI_RHSC);
1220 splx(s); 1250 mutex_spin_exit(&sc->sc_intr_lock);
1221} 1251}
1222 1252
1223#ifdef OHCI_DEBUG 1253#ifdef OHCI_DEBUG
1224const char *ohci_cc_strs[] = { 1254const char *ohci_cc_strs[] = {
1225 "NO_ERROR", 1255 "NO_ERROR",
1226 "CRC", 1256 "CRC",
1227 "BIT_STUFFING", 1257 "BIT_STUFFING",
1228 "DATA_TOGGLE_MISMATCH", 1258 "DATA_TOGGLE_MISMATCH",
1229 "STALL", 1259 "STALL",
1230 "DEVICE_NOT_RESPONDING", 1260 "DEVICE_NOT_RESPONDING",
1231 "PID_CHECK_FAILURE", 1261 "PID_CHECK_FAILURE",
1232 "UNEXPECTED_PID", 1262 "UNEXPECTED_PID",
1233 "DATA_OVERRUN", 1263 "DATA_OVERRUN",
@@ -1240,47 +1270,47 @@ const char *ohci_cc_strs[] = { @@ -1240,47 +1270,47 @@ const char *ohci_cc_strs[] = {
1240 "NOT_ACCESSED", 1270 "NOT_ACCESSED",
1241}; 1271};
1242#endif 1272#endif
1243 1273
1244void 1274void
1245ohci_softintr(void *v) 1275ohci_softintr(void *v)
1246{ 1276{
1247 struct usbd_bus *bus = v; 1277 struct usbd_bus *bus = v;
1248 ohci_softc_t *sc = bus->hci_private; 1278 ohci_softc_t *sc = bus->hci_private;
1249 ohci_soft_itd_t *sitd, *sidone, *sitdnext; 1279 ohci_soft_itd_t *sitd, *sidone, *sitdnext;
1250 ohci_soft_td_t *std, *sdone, *stdnext; 1280 ohci_soft_td_t *std, *sdone, *stdnext;
1251 usbd_xfer_handle xfer; 1281 usbd_xfer_handle xfer;
1252 struct ohci_pipe *opipe; 1282 struct ohci_pipe *opipe;
1253 int len, cc, s; 1283 int len, cc;
1254 int i, j, actlen, iframes, uedir; 1284 int i, j, actlen, iframes, uedir;
1255 ohci_physaddr_t done; 1285 ohci_physaddr_t done;
1256 1286
1257 DPRINTFN(10,("ohci_softintr: enter\n")); 1287 DPRINTFN(10,("ohci_softintr: enter\n"));
1258 1288
 1289 mutex_enter(&sc->sc_lock);
 1290
1259 sc->sc_bus.intr_context++; 1291 sc->sc_bus.intr_context++;
1260 1292
1261 s = splhardusb(); 
1262 usb_syncmem(&sc->sc_hccadma, offsetof(struct ohci_hcca, hcca_done_head), 1293 usb_syncmem(&sc->sc_hccadma, offsetof(struct ohci_hcca, hcca_done_head),
1263 sizeof(sc->sc_hcca->hcca_done_head), 1294 sizeof(sc->sc_hcca->hcca_done_head),
1264 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1295 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1265 done = O32TOH(sc->sc_hcca->hcca_done_head) & ~OHCI_DONE_INTRS; 1296 done = O32TOH(sc->sc_hcca->hcca_done_head) & ~OHCI_DONE_INTRS;
1266 sc->sc_hcca->hcca_done_head = 0; 1297 sc->sc_hcca->hcca_done_head = 0;
1267 usb_syncmem(&sc->sc_hccadma, offsetof(struct ohci_hcca, hcca_done_head), 1298 usb_syncmem(&sc->sc_hccadma, offsetof(struct ohci_hcca, hcca_done_head),
1268 sizeof(sc->sc_hcca->hcca_done_head), 1299 sizeof(sc->sc_hcca->hcca_done_head),
1269 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1300 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1270 OWRITE4(sc, OHCI_INTERRUPT_STATUS, OHCI_WDH); 1301 OWRITE4(sc, OHCI_INTERRUPT_STATUS, OHCI_WDH);
1271 sc->sc_eintrs |= OHCI_WDH; 1302 sc->sc_eintrs |= OHCI_WDH;
1272 OWRITE4(sc, OHCI_INTERRUPT_ENABLE, OHCI_WDH); 1303 OWRITE4(sc, OHCI_INTERRUPT_ENABLE, OHCI_WDH);
1273 splx(s); 
1274 1304
1275 /* Reverse the done list. */ 1305 /* Reverse the done list. */
1276 for (sdone = NULL, sidone = NULL; done != 0; ) { 1306 for (sdone = NULL, sidone = NULL; done != 0; ) {
1277 std = ohci_hash_find_td(sc, done); 1307 std = ohci_hash_find_td(sc, done);
1278 if (std != NULL) { 1308 if (std != NULL) {
1279 usb_syncmem(&std->dma, std->offs, sizeof(std->td), 1309 usb_syncmem(&std->dma, std->offs, sizeof(std->td),
1280 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1310 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1281 std->dnext = sdone; 1311 std->dnext = sdone;
1282 done = O32TOH(std->td.td_nexttd); 1312 done = O32TOH(std->td.td_nexttd);
1283 sdone = std; 1313 sdone = std;
1284 DPRINTFN(10,("add TD %p\n", std)); 1314 DPRINTFN(10,("add TD %p\n", std));
1285 continue; 1315 continue;
1286 } 1316 }
@@ -1334,29 +1364,27 @@ ohci_softintr(void *v) @@ -1334,29 +1364,27 @@ ohci_softintr(void *v)
1334 len = std->len; 1364 len = std->len;
1335 if (std->td.td_cbp != 0) 1365 if (std->td.td_cbp != 0)
1336 len -= O32TOH(std->td.td_be) - 1366 len -= O32TOH(std->td.td_be) -
1337 O32TOH(std->td.td_cbp) + 1; 1367 O32TOH(std->td.td_cbp) + 1;
1338 DPRINTFN(10, ("ohci_process_done: len=%d, flags=0x%x\n", len, 1368 DPRINTFN(10, ("ohci_process_done: len=%d, flags=0x%x\n", len,
1339 std->flags)); 1369 std->flags));
1340 if (std->flags & OHCI_ADD_LEN) 1370 if (std->flags & OHCI_ADD_LEN)
1341 xfer->actlen += len; 1371 xfer->actlen += len;
1342 1372
1343 cc = OHCI_TD_GET_CC(O32TOH(std->td.td_flags)); 1373 cc = OHCI_TD_GET_CC(O32TOH(std->td.td_flags));
1344 if (cc == OHCI_CC_NO_ERROR) { 1374 if (cc == OHCI_CC_NO_ERROR) {
1345 if (std->flags & OHCI_CALL_DONE) { 1375 if (std->flags & OHCI_CALL_DONE) {
1346 xfer->status = USBD_NORMAL_COMPLETION; 1376 xfer->status = USBD_NORMAL_COMPLETION;
1347 s = splusb(); 
1348 usb_transfer_complete(xfer); 1377 usb_transfer_complete(xfer);
1349 splx(s); 
1350 } 1378 }
1351 ohci_free_std(sc, std); 1379 ohci_free_std(sc, std);
1352 } else { 1380 } else {
1353 /* 1381 /*
1354 * Endpoint is halted. First unlink all the TDs 1382 * Endpoint is halted. First unlink all the TDs
1355 * belonging to the failed transfer, and then restart 1383 * belonging to the failed transfer, and then restart
1356 * the endpoint. 1384 * the endpoint.
1357 */ 1385 */
1358 ohci_soft_td_t *p, *n; 1386 ohci_soft_td_t *p, *n;
1359 opipe = (struct ohci_pipe *)xfer->pipe; 1387 opipe = (struct ohci_pipe *)xfer->pipe;
1360 1388
1361 DPRINTFN(15,("ohci_process_done: error cc=%d (%s)\n", 1389 DPRINTFN(15,("ohci_process_done: error cc=%d (%s)\n",
1362 OHCI_TD_GET_CC(O32TOH(std->td.td_flags)), 1390 OHCI_TD_GET_CC(O32TOH(std->td.td_flags)),
@@ -1366,29 +1394,27 @@ ohci_softintr(void *v) @@ -1366,29 +1394,27 @@ ohci_softintr(void *v)
1366 for (p = std; p->xfer == xfer; p = n) { 1394 for (p = std; p->xfer == xfer; p = n) {
1367 n = p->nexttd; 1395 n = p->nexttd;
1368 ohci_free_std(sc, p); 1396 ohci_free_std(sc, p);
1369 } 1397 }
1370 1398
1371 /* clear halt */ 1399 /* clear halt */
1372 opipe->sed->ed.ed_headp = HTOO32(p->physaddr); 1400 opipe->sed->ed.ed_headp = HTOO32(p->physaddr);
1373 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF); 1401 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
1374 1402
1375 if (cc == OHCI_CC_STALL) 1403 if (cc == OHCI_CC_STALL)
1376 xfer->status = USBD_STALLED; 1404 xfer->status = USBD_STALLED;
1377 else 1405 else
1378 xfer->status = USBD_IOERROR; 1406 xfer->status = USBD_IOERROR;
1379 s = splusb(); 
1380 usb_transfer_complete(xfer); 1407 usb_transfer_complete(xfer);
1381 splx(s); 
1382 } 1408 }
1383 } 1409 }
1384 1410
1385#ifdef OHCI_DEBUG 1411#ifdef OHCI_DEBUG
1386 if (ohcidebug > 10) { 1412 if (ohcidebug > 10) {
1387 DPRINTF(("ohci_softintr: ITD done:\n")); 1413 DPRINTF(("ohci_softintr: ITD done:\n"));
1388 ohci_dump_itds(sc, sidone); 1414 ohci_dump_itds(sc, sidone);
1389 } 1415 }
1390#endif 1416#endif
1391 1417
1392 for (sitd = sidone; sitd != NULL; sitd = sitdnext) { 1418 for (sitd = sidone; sitd != NULL; sitd = sitdnext) {
1393 xfer = sitd->xfer; 1419 xfer = sitd->xfer;
1394 sitdnext = sitd->dnext; 1420 sitdnext = sitd->dnext;
@@ -1442,78 +1468,80 @@ ohci_softintr(void *v) @@ -1442,78 +1468,80 @@ ohci_softintr(void *v)
1442 actlen += len; 1468 actlen += len;
1443 } 1469 }
1444 } 1470 }
1445 if (sitd->flags & OHCI_CALL_DONE) 1471 if (sitd->flags & OHCI_CALL_DONE)
1446 break; 1472 break;
1447 ohci_free_sitd(sc, sitd); 1473 ohci_free_sitd(sc, sitd);
1448 } 1474 }
1449 ohci_free_sitd(sc, sitd); 1475 ohci_free_sitd(sc, sitd);
1450 if (uedir == UE_DIR_IN && 1476 if (uedir == UE_DIR_IN &&
1451 xfer->status == USBD_NORMAL_COMPLETION) 1477 xfer->status == USBD_NORMAL_COMPLETION)
1452 xfer->actlen = actlen; 1478 xfer->actlen = actlen;
1453 xfer->hcpriv = NULL; 1479 xfer->hcpriv = NULL;
1454 1480
1455 s = splusb(); 
1456 usb_transfer_complete(xfer); 1481 usb_transfer_complete(xfer);
1457 splx(s); 
1458 } 1482 }
1459 } 1483 }
1460 1484
1461#ifdef USB_USE_SOFTINTR 
1462 if (sc->sc_softwake) { 1485 if (sc->sc_softwake) {
1463 sc->sc_softwake = 0; 1486 sc->sc_softwake = 0;
1464 wakeup(&sc->sc_softwake); 1487 cv_broadcast(&sc->sc_softwake_cv);
1465 } 1488 }
1466#endif /* USB_USE_SOFTINTR */ 
1467 1489
1468 sc->sc_bus.intr_context--; 1490 sc->sc_bus.intr_context--;
 1491 mutex_exit(&sc->sc_lock);
 1492
1469 DPRINTFN(10,("ohci_softintr: done:\n")); 1493 DPRINTFN(10,("ohci_softintr: done:\n"));
1470} 1494}
1471 1495
1472void 1496void
1473ohci_device_ctrl_done(usbd_xfer_handle xfer) 1497ohci_device_ctrl_done(usbd_xfer_handle xfer)
1474{ 1498{
1475 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; 1499 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
 1500 ohci_softc_t *sc = xfer->pipe->device->bus->hci_private;
1476 int len = UGETW(xfer->request.wLength); 1501 int len = UGETW(xfer->request.wLength);
1477 int isread = (xfer->request.bmRequestType & UT_READ); 1502 int isread = (xfer->request.bmRequestType & UT_READ);
1478 1503
1479 DPRINTFN(10,("ohci_device_ctrl_done: xfer=%p\n", xfer)); 1504 DPRINTFN(10,("ohci_device_ctrl_done: xfer=%p\n", xfer));
1480 1505
 1506 KASSERT(mutex_owned(&sc->sc_lock));
 1507
1481#ifdef DIAGNOSTIC 1508#ifdef DIAGNOSTIC
1482 if (!(xfer->rqflags & URQ_REQUEST)) { 1509 if (!(xfer->rqflags & URQ_REQUEST)) {
1483 panic("ohci_device_ctrl_done: not a request"); 1510 panic("ohci_device_ctrl_done: not a request");
1484 } 1511 }
1485#endif 1512#endif
1486 if (len) 1513 if (len)
1487 usb_syncmem(&xfer->dmabuf, 0, len, 1514 usb_syncmem(&xfer->dmabuf, 0, len,
1488 isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 1515 isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
1489 usb_syncmem(&opipe->u.ctl.reqdma, 0, 1516 usb_syncmem(&opipe->u.ctl.reqdma, 0,
1490 sizeof(usb_device_request_t), BUS_DMASYNC_POSTWRITE); 1517 sizeof(usb_device_request_t), BUS_DMASYNC_POSTWRITE);
1491} 1518}
1492 1519
1493void 1520void
1494ohci_device_intr_done(usbd_xfer_handle xfer) 1521ohci_device_intr_done(usbd_xfer_handle xfer)
1495{ 1522{
1496 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; 1523 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
1497 ohci_softc_t *sc = opipe->pipe.device->bus->hci_private; 1524 ohci_softc_t *sc = opipe->pipe.device->bus->hci_private;
1498 ohci_soft_ed_t *sed = opipe->sed; 1525 ohci_soft_ed_t *sed = opipe->sed;
1499 ohci_soft_td_t *data, *tail; 1526 ohci_soft_td_t *data, *tail;
1500 int isread = 1527 int isread =
1501 (UE_GET_DIR(xfer->pipe->endpoint->edesc->bEndpointAddress) == UE_DIR_IN); 1528 (UE_GET_DIR(xfer->pipe->endpoint->edesc->bEndpointAddress) == UE_DIR_IN);
1502 1529
1503 
1504 DPRINTFN(10,("ohci_device_intr_done: xfer=%p, actlen=%d\n", 1530 DPRINTFN(10,("ohci_device_intr_done: xfer=%p, actlen=%d\n",
1505 xfer, xfer->actlen)); 1531 xfer, xfer->actlen));
1506 1532
 1533 KASSERT(mutex_owned(&sc->sc_lock));
 1534
1507 usb_syncmem(&xfer->dmabuf, 0, xfer->length, 1535 usb_syncmem(&xfer->dmabuf, 0, xfer->length,
1508 isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 1536 isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
1509 if (xfer->pipe->repeat) { 1537 if (xfer->pipe->repeat) {
1510 data = opipe->tail.td; 1538 data = opipe->tail.td;
1511 tail = ohci_alloc_std(sc); /* XXX should reuse TD */ 1539 tail = ohci_alloc_std(sc); /* XXX should reuse TD */
1512 if (tail == NULL) { 1540 if (tail == NULL) {
1513 xfer->status = USBD_NOMEM; 1541 xfer->status = USBD_NOMEM;
1514 return; 1542 return;
1515 } 1543 }
1516 tail->xfer = NULL; 1544 tail->xfer = NULL;
1517 1545
1518 data->td.td_flags = HTOO32( 1546 data->td.td_flags = HTOO32(
1519 OHCI_TD_IN | OHCI_TD_NOCC | 1547 OHCI_TD_IN | OHCI_TD_NOCC |
@@ -1535,43 +1563,63 @@ ohci_device_intr_done(usbd_xfer_handle x @@ -1535,43 +1563,63 @@ ohci_device_intr_done(usbd_xfer_handle x
1535 1563
1536 sed->ed.ed_tailp = HTOO32(tail->physaddr); 1564 sed->ed.ed_tailp = HTOO32(tail->physaddr);
1537 usb_syncmem(&sed->dma, 1565 usb_syncmem(&sed->dma,
1538 sed->offs + offsetof(ohci_ed_t, ed_tailp), 1566 sed->offs + offsetof(ohci_ed_t, ed_tailp),
1539 sizeof(sed->ed.ed_tailp), 1567 sizeof(sed->ed.ed_tailp),
1540 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1568 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1541 opipe->tail.td = tail; 1569 opipe->tail.td = tail;
1542 } 1570 }
1543} 1571}
1544 1572
1545void 1573void
1546ohci_device_bulk_done(usbd_xfer_handle xfer) 1574ohci_device_bulk_done(usbd_xfer_handle xfer)
1547{ 1575{
 1576 ohci_softc_t *sc = xfer->pipe->device->bus->hci_private;
1548 int isread = 1577 int isread =
1549 (UE_GET_DIR(xfer->pipe->endpoint->edesc->bEndpointAddress) == UE_DIR_IN); 1578 (UE_GET_DIR(xfer->pipe->endpoint->edesc->bEndpointAddress) == UE_DIR_IN);
1550 1579
 1580 KASSERT(mutex_owned(&sc->sc_lock));
 1581
1551 DPRINTFN(10,("ohci_device_bulk_done: xfer=%p, actlen=%d\n", 1582 DPRINTFN(10,("ohci_device_bulk_done: xfer=%p, actlen=%d\n",
1552 xfer, xfer->actlen)); 1583 xfer, xfer->actlen));
1553 usb_syncmem(&xfer->dmabuf, 0, xfer->length, 1584 usb_syncmem(&xfer->dmabuf, 0, xfer->length,
1554 isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 1585 isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
1555} 1586}
1556 1587
 1588Static void
 1589ohci_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
1557void 1603void
1558ohci_rhsc(ohci_softc_t *sc, usbd_xfer_handle xfer) 1604ohci_rhsc(ohci_softc_t *sc, usbd_xfer_handle xfer)
1559{ 1605{
1560 usbd_pipe_handle pipe; 1606 usbd_pipe_handle pipe;
1561 u_char *p; 1607 u_char *p;
1562 int i, m; 1608 int i, m;
1563 int hstatus; 1609 int hstatus;
1564 1610
 1611 KASSERT(mutex_owned(&sc->sc_lock));
 1612
1565 hstatus = OREAD4(sc, OHCI_RH_STATUS); 1613 hstatus = OREAD4(sc, OHCI_RH_STATUS);
1566 DPRINTF(("ohci_rhsc: sc=%p xfer=%p hstatus=0x%08x\n", 1614 DPRINTF(("ohci_rhsc: sc=%p xfer=%p hstatus=0x%08x\n",
1567 sc, xfer, hstatus)); 1615 sc, xfer, hstatus));
1568 1616
1569 if (xfer == NULL) { 1617 if (xfer == NULL) {
1570 /* Just ignore the change. */ 1618 /* Just ignore the change. */
1571 return; 1619 return;
1572 } 1620 }
1573 1621
1574 pipe = xfer->pipe; 1622 pipe = xfer->pipe;
1575 1623
1576 p = KERNADDR(&xfer->dmabuf, 0); 1624 p = KERNADDR(&xfer->dmabuf, 0);
1577 m = min(sc->sc_noport, xfer->length * 8 - 1); 1625 m = min(sc->sc_noport, xfer->length * 8 - 1);
@@ -1599,84 +1647,95 @@ ohci_root_ctrl_done(usbd_xfer_handle xfe @@ -1599,84 +1647,95 @@ ohci_root_ctrl_done(usbd_xfer_handle xfe
1599} 1647}
1600 1648
1601/* 1649/*
1602 * Wait here until controller claims to have an interrupt. 1650 * Wait here until controller claims to have an interrupt.
1603 * Then call ohci_intr and return. Use timeout to avoid waiting 1651 * Then call ohci_intr and return. Use timeout to avoid waiting
1604 * too long. 1652 * too long.
1605 */ 1653 */
1606void 1654void
1607ohci_waitintr(ohci_softc_t *sc, usbd_xfer_handle xfer) 1655ohci_waitintr(ohci_softc_t *sc, usbd_xfer_handle xfer)
1608{ 1656{
1609 int timo; 1657 int timo;
1610 u_int32_t intrs; 1658 u_int32_t intrs;
1611 1659
 1660 mutex_enter(&sc->sc_lock);
 1661
1612 xfer->status = USBD_IN_PROGRESS; 1662 xfer->status = USBD_IN_PROGRESS;
1613 for (timo = xfer->timeout; timo >= 0; timo--) { 1663 for (timo = xfer->timeout; timo >= 0; timo--) {
1614 usb_delay_ms(&sc->sc_bus, 1); 1664 usb_delay_ms(&sc->sc_bus, 1);
1615 if (sc->sc_dying) 1665 if (sc->sc_dying)
1616 break; 1666 break;
1617 intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs; 1667 intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs;
1618 DPRINTFN(15,("ohci_waitintr: 0x%04x\n", intrs)); 1668 DPRINTFN(15,("ohci_waitintr: 0x%04x\n", intrs));
1619#ifdef OHCI_DEBUG 1669#ifdef OHCI_DEBUG
1620 if (ohcidebug > 15) 1670 if (ohcidebug > 15)
1621 ohci_dumpregs(sc); 1671 ohci_dumpregs(sc);
1622#endif 1672#endif
1623 if (intrs) { 1673 if (intrs) {
 1674 mutex_spin_enter(&sc->sc_intr_lock);
1624 ohci_intr1(sc); 1675 ohci_intr1(sc);
 1676 mutex_spin_exit(&sc->sc_intr_lock);
1625 if (xfer->status != USBD_IN_PROGRESS) 1677 if (xfer->status != USBD_IN_PROGRESS)
1626 return; 1678 return;
1627 } 1679 }
1628 } 1680 }
1629 1681
1630 /* Timeout */ 1682 /* Timeout */
1631 DPRINTF(("ohci_waitintr: timeout\n")); 1683 DPRINTF(("ohci_waitintr: timeout\n"));
1632 xfer->status = USBD_TIMEOUT; 1684 xfer->status = USBD_TIMEOUT;
1633 usb_transfer_complete(xfer); 1685 usb_transfer_complete(xfer);
 1686
1634 /* XXX should free TD */ 1687 /* XXX should free TD */
 1688
 1689 mutex_exit(&sc->sc_lock);
1635} 1690}
1636 1691
1637void 1692void
1638ohci_poll(struct usbd_bus *bus) 1693ohci_poll(struct usbd_bus *bus)
1639{ 1694{
1640 ohci_softc_t *sc = bus->hci_private; 1695 ohci_softc_t *sc = bus->hci_private;
1641#ifdef OHCI_DEBUG 1696#ifdef OHCI_DEBUG
1642 static int last; 1697 static int last;
1643 int new; 1698 int new;
1644 new = OREAD4(sc, OHCI_INTERRUPT_STATUS); 1699 new = OREAD4(sc, OHCI_INTERRUPT_STATUS);
1645 if (new != last) { 1700 if (new != last) {
1646 DPRINTFN(10,("ohci_poll: intrs=0x%04x\n", new)); 1701 DPRINTFN(10,("ohci_poll: intrs=0x%04x\n", new));
1647 last = new; 1702 last = new;
1648 } 1703 }
1649#endif 1704#endif
1650 1705
1651 sc->sc_eintrs |= OHCI_WDH; 1706 sc->sc_eintrs |= OHCI_WDH;
1652 if (OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs) 1707 if (OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs) {
 1708 mutex_spin_enter(&sc->sc_intr_lock);
1653 ohci_intr1(sc); 1709 ohci_intr1(sc);
 1710 mutex_spin_exit(&sc->sc_intr_lock);
 1711 }
1654} 1712}
1655 1713
1656usbd_status 1714usbd_status
1657ohci_device_request(usbd_xfer_handle xfer) 1715ohci_device_request(usbd_xfer_handle xfer)
1658{ 1716{
1659 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; 1717 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
1660 usb_device_request_t *req = &xfer->request; 1718 usb_device_request_t *req = &xfer->request;
1661 usbd_device_handle dev = opipe->pipe.device; 1719 usbd_device_handle dev = opipe->pipe.device;
1662 ohci_softc_t *sc = dev->bus->hci_private; 1720 ohci_softc_t *sc = dev->bus->hci_private;
1663 int addr = dev->address; 1721 int addr = dev->address;
1664 ohci_soft_td_t *setup, *stat, *next, *tail; 1722 ohci_soft_td_t *setup, *stat, *next, *tail;
1665 ohci_soft_ed_t *sed; 1723 ohci_soft_ed_t *sed;
1666 int isread; 1724 int isread;
1667 int len; 1725 int len;
1668 usbd_status err; 1726 usbd_status err;
1669 int s; 1727
 1728 KASSERT(mutex_owned(&sc->sc_lock));
1670 1729
1671 isread = req->bmRequestType & UT_READ; 1730 isread = req->bmRequestType & UT_READ;
1672 len = UGETW(req->wLength); 1731 len = UGETW(req->wLength);
1673 1732
1674 DPRINTFN(3,("ohci_device_control type=0x%02x, request=0x%02x, " 1733 DPRINTFN(3,("ohci_device_control type=0x%02x, request=0x%02x, "
1675 "wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n", 1734 "wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n",
1676 req->bmRequestType, req->bRequest, UGETW(req->wValue), 1735 req->bmRequestType, req->bRequest, UGETW(req->wValue),
1677 UGETW(req->wIndex), len, addr, 1736 UGETW(req->wIndex), len, addr,
1678 opipe->pipe.endpoint->edesc->bEndpointAddress)); 1737 opipe->pipe.endpoint->edesc->bEndpointAddress));
1679 1738
1680 setup = opipe->tail.td; 1739 setup = opipe->tail.td;
1681 stat = ohci_alloc_std(sc); 1740 stat = ohci_alloc_std(sc);
1682 if (stat == NULL) { 1741 if (stat == NULL) {
@@ -1757,39 +1816,37 @@ ohci_device_request(usbd_xfer_handle xfe @@ -1757,39 +1816,37 @@ ohci_device_request(usbd_xfer_handle xfe
1757 stat->xfer = xfer; 1816 stat->xfer = xfer;
1758 usb_syncmem(&stat->dma, stat->offs, sizeof(stat->td), 1817 usb_syncmem(&stat->dma, stat->offs, sizeof(stat->td),
1759 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1818 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1760 1819
1761#ifdef OHCI_DEBUG 1820#ifdef OHCI_DEBUG
1762 if (ohcidebug > 5) { 1821 if (ohcidebug > 5) {
1763 DPRINTF(("ohci_device_request:\n")); 1822 DPRINTF(("ohci_device_request:\n"));
1764 ohci_dump_ed(sc, sed); 1823 ohci_dump_ed(sc, sed);
1765 ohci_dump_tds(sc, setup); 1824 ohci_dump_tds(sc, setup);
1766 } 1825 }
1767#endif 1826#endif
1768 1827
1769 /* Insert ED in schedule */ 1828 /* Insert ED in schedule */
1770 s = splusb(); 
1771 sed->ed.ed_tailp = HTOO32(tail->physaddr); 1829 sed->ed.ed_tailp = HTOO32(tail->physaddr);
1772 usb_syncmem(&sed->dma, 1830 usb_syncmem(&sed->dma,
1773 sed->offs + offsetof(ohci_ed_t, ed_tailp), 1831 sed->offs + offsetof(ohci_ed_t, ed_tailp),
1774 sizeof(sed->ed.ed_tailp), 1832 sizeof(sed->ed.ed_tailp),
1775 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1833 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1776 opipe->tail.td = tail; 1834 opipe->tail.td = tail;
1777 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF); 1835 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
1778 if (xfer->timeout && !sc->sc_bus.use_polling) { 1836 if (xfer->timeout && !sc->sc_bus.use_polling) {
1779 callout_reset(&xfer->timeout_handle, mstohz(xfer->timeout), 1837 callout_reset(&xfer->timeout_handle, mstohz(xfer->timeout),
1780 ohci_timeout, xfer); 1838 ohci_timeout, xfer);
1781 } 1839 }
1782 splx(s); 
1783 1840
1784#ifdef OHCI_DEBUG 1841#ifdef OHCI_DEBUG
1785 if (ohcidebug > 20) { 1842 if (ohcidebug > 20) {
1786 delay(10000); 1843 delay(10000);
1787 DPRINTF(("ohci_device_request: status=%x\n", 1844 DPRINTF(("ohci_device_request: status=%x\n",
1788 OREAD4(sc, OHCI_COMMAND_STATUS))); 1845 OREAD4(sc, OHCI_COMMAND_STATUS)));
1789 ohci_dumpregs(sc); 1846 ohci_dumpregs(sc);
1790 printf("ctrl head:\n"); 1847 printf("ctrl head:\n");
1791 ohci_dump_ed(sc, sc->sc_ctrl_head); 1848 ohci_dump_ed(sc, sc->sc_ctrl_head);
1792 printf("sed:\n"); 1849 printf("sed:\n");
1793 ohci_dump_ed(sc, sed); 1850 ohci_dump_ed(sc, sed);
1794 ohci_dump_tds(sc, setup); 1851 ohci_dump_tds(sc, setup);
1795 } 1852 }
@@ -1953,33 +2010,34 @@ ohci_timeout(void *addr) @@ -1953,33 +2010,34 @@ ohci_timeout(void *addr)
1953 return; 2010 return;
1954 } 2011 }
1955 2012
1956 /* Execute the abort in a process context. */ 2013 /* Execute the abort in a process context. */
1957 usb_init_task(&oxfer->abort_task, ohci_timeout_task, addr); 2014 usb_init_task(&oxfer->abort_task, ohci_timeout_task, addr);
1958 usb_add_task(oxfer->xfer.pipe->device, &oxfer->abort_task, 2015 usb_add_task(oxfer->xfer.pipe->device, &oxfer->abort_task,
1959 USB_TASKQ_HC); 2016 USB_TASKQ_HC);
1960} 2017}
1961 2018
1962void 2019void
1963ohci_timeout_task(void *addr) 2020ohci_timeout_task(void *addr)
1964{ 2021{
1965 usbd_xfer_handle xfer = addr; 2022 usbd_xfer_handle xfer = addr;
1966 int s; 2023 ohci_softc_t *sc = xfer->pipe->device->bus->hci_private;
1967 2024
1968 DPRINTF(("ohci_timeout_task: xfer=%p\n", xfer)); 2025 DPRINTF(("ohci_timeout_task: xfer=%p\n", xfer));
1969 2026
1970 s = splusb(); 2027 KASSERT(mutex_owned(&sc->sc_lock));
 2028 //mutex_enter(&sc->sc_lock);
1971 ohci_abort_xfer(xfer, USBD_TIMEOUT); 2029 ohci_abort_xfer(xfer, USBD_TIMEOUT);
1972 splx(s); 2030 //mutex_exit(&sc->sc_lock);
1973} 2031}
1974 2032
1975#ifdef OHCI_DEBUG 2033#ifdef OHCI_DEBUG
1976void 2034void
1977ohci_dump_tds(ohci_softc_t *sc, ohci_soft_td_t *std) 2035ohci_dump_tds(ohci_softc_t *sc, ohci_soft_td_t *std)
1978{ 2036{
1979 for (; std; std = std->nexttd) 2037 for (; std; std = std->nexttd)
1980 ohci_dump_td(sc, std); 2038 ohci_dump_td(sc, std);
1981} 2039}
1982 2040
1983void 2041void
1984ohci_dump_td(ohci_softc_t *sc, ohci_soft_td_t *std) 2042ohci_dump_td(ohci_softc_t *sc, ohci_soft_td_t *std)
1985{ 2043{
@@ -2060,49 +2118,51 @@ usbd_status @@ -2060,49 +2118,51 @@ usbd_status
2060ohci_open(usbd_pipe_handle pipe) 2118ohci_open(usbd_pipe_handle pipe)
2061{ 2119{
2062 usbd_device_handle dev = pipe->device; 2120 usbd_device_handle dev = pipe->device;
2063 ohci_softc_t *sc = dev->bus->hci_private; 2121 ohci_softc_t *sc = dev->bus->hci_private;
2064 usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc; 2122 usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
2065 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; 2123 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
2066 u_int8_t addr = dev->address; 2124 u_int8_t addr = dev->address;
2067 u_int8_t xfertype = ed->bmAttributes & UE_XFERTYPE; 2125 u_int8_t xfertype = ed->bmAttributes & UE_XFERTYPE;
2068 ohci_soft_ed_t *sed; 2126 ohci_soft_ed_t *sed;
2069 ohci_soft_td_t *std; 2127 ohci_soft_td_t *std;
2070 ohci_soft_itd_t *sitd; 2128 ohci_soft_itd_t *sitd;
2071 ohci_physaddr_t tdphys; 2129 ohci_physaddr_t tdphys;
2072 u_int32_t fmt; 2130 u_int32_t fmt;
2073 usbd_status err; 2131 usbd_status err = USBD_NOMEM;
2074 int s; 
2075 int ival; 2132 int ival;
2076 2133
2077 DPRINTFN(1, ("ohci_open: pipe=%p, addr=%d, endpt=%d (%d)\n", 2134 DPRINTFN(1, ("ohci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
2078 pipe, addr, ed->bEndpointAddress, sc->sc_addr)); 2135 pipe, addr, ed->bEndpointAddress, sc->sc_addr));
2079 2136
2080 if (sc->sc_dying) 2137 if (sc->sc_dying) {
2081 return (USBD_IOERROR); 2138 err = USBD_IOERROR;
 2139 goto bad0;
 2140 }
2082 2141
2083 std = NULL; 2142 std = NULL;
2084 sed = NULL; 2143 sed = NULL;
2085 2144
2086 if (addr == sc->sc_addr) { 2145 if (addr == sc->sc_addr) {
2087 switch (ed->bEndpointAddress) { 2146 switch (ed->bEndpointAddress) {
2088 case USB_CONTROL_ENDPOINT: 2147 case USB_CONTROL_ENDPOINT:
2089 pipe->methods = &ohci_root_ctrl_methods; 2148 pipe->methods = &ohci_root_ctrl_methods;
2090 break; 2149 break;
2091 case UE_DIR_IN | OHCI_INTR_ENDPT: 2150 case UE_DIR_IN | OHCI_INTR_ENDPT:
2092 pipe->methods = &ohci_root_intr_methods; 2151 pipe->methods = &ohci_root_intr_methods;
2093 break; 2152 break;
2094 default: 2153 default:
2095 return (USBD_INVAL); 2154 err = USBD_INVAL;
 2155 goto bad0;
2096 } 2156 }
2097 } else { 2157 } else {
2098 sed = ohci_alloc_sed(sc); 2158 sed = ohci_alloc_sed(sc);
2099 if (sed == NULL) 2159 if (sed == NULL)
2100 goto bad0; 2160 goto bad0;
2101 opipe->sed = sed; 2161 opipe->sed = sed;
2102 if (xfertype == UE_ISOCHRONOUS) { 2162 if (xfertype == UE_ISOCHRONOUS) {
2103 sitd = ohci_alloc_sitd(sc); 2163 sitd = ohci_alloc_sitd(sc);
2104 if (sitd == NULL) 2164 if (sitd == NULL)
2105 goto bad1; 2165 goto bad1;
2106 opipe->tail.itd = sitd; 2166 opipe->tail.itd = sitd;
2107 tdphys = sitd->physaddr; 2167 tdphys = sitd->physaddr;
2108 fmt = OHCI_ED_FORMAT_ISO; 2168 fmt = OHCI_ED_FORMAT_ISO;
@@ -2128,73 +2188,75 @@ ohci_open(usbd_pipe_handle pipe) @@ -2128,73 +2188,75 @@ ohci_open(usbd_pipe_handle pipe)
2128 (pipe->endpoint->datatoggle ? OHCI_TOGGLECARRY : 0)); 2188 (pipe->endpoint->datatoggle ? OHCI_TOGGLECARRY : 0));
2129 sed->ed.ed_tailp = HTOO32(tdphys); 2189 sed->ed.ed_tailp = HTOO32(tdphys);
2130 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 2190 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed),
2131 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2191 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2132 2192
2133 switch (xfertype) { 2193 switch (xfertype) {
2134 case UE_CONTROL: 2194 case UE_CONTROL:
2135 pipe->methods = &ohci_device_ctrl_methods; 2195 pipe->methods = &ohci_device_ctrl_methods;
2136 err = usb_allocmem(&sc->sc_bus, 2196 err = usb_allocmem(&sc->sc_bus,
2137 sizeof(usb_device_request_t), 2197 sizeof(usb_device_request_t),
2138 0, &opipe->u.ctl.reqdma); 2198 0, &opipe->u.ctl.reqdma);
2139 if (err) 2199 if (err)
2140 goto bad; 2200 goto bad;
2141 s = splusb(); 2201 mutex_enter(&sc->sc_lock);
2142 ohci_add_ed(sc, sed, sc->sc_ctrl_head); 2202 ohci_add_ed(sc, sed, sc->sc_ctrl_head);
2143 splx(s); 2203 mutex_exit(&sc->sc_lock);
2144 break; 2204 break;
2145 case UE_INTERRUPT: 2205 case UE_INTERRUPT:
2146 pipe->methods = &ohci_device_intr_methods; 2206 pipe->methods = &ohci_device_intr_methods;
2147 ival = pipe->interval; 2207 ival = pipe->interval;
2148 if (ival == USBD_DEFAULT_INTERVAL) 2208 if (ival == USBD_DEFAULT_INTERVAL)
2149 ival = ed->bInterval; 2209 ival = ed->bInterval;
2150 return (ohci_device_setintr(sc, opipe, ival)); 2210 return (ohci_device_setintr(sc, opipe, ival));
2151 case UE_ISOCHRONOUS: 2211 case UE_ISOCHRONOUS:
2152 pipe->methods = &ohci_device_isoc_methods; 2212 pipe->methods = &ohci_device_isoc_methods;
2153 return (ohci_setup_isoc(pipe)); 2213 return (ohci_setup_isoc(pipe));
2154 case UE_BULK: 2214 case UE_BULK:
2155 pipe->methods = &ohci_device_bulk_methods; 2215 pipe->methods = &ohci_device_bulk_methods;
2156 s = splusb(); 2216 mutex_enter(&sc->sc_lock);
2157 ohci_add_ed(sc, sed, sc->sc_bulk_head); 2217 ohci_add_ed(sc, sed, sc->sc_bulk_head);
2158 splx(s); 2218 mutex_exit(&sc->sc_lock);
2159 break; 2219 break;
2160 } 2220 }
2161 } 2221 }
2162 return (USBD_NORMAL_COMPLETION); 2222
 2223 return USBD_NORMAL_COMPLETION;
2163 2224
2164 bad: 2225 bad:
2165 if (std != NULL) 2226 if (std != NULL)
2166 ohci_free_std(sc, std); 2227 ohci_free_std(sc, std);
2167 bad1: 2228 bad1:
2168 if (sed != NULL) 2229 if (sed != NULL)
2169 ohci_free_sed(sc, sed); 2230 ohci_free_sed(sc, sed);
2170 bad0: 2231 bad0:
2171 return (USBD_NOMEM); 2232 mutex_exit(&sc->sc_lock);
 2233 return err;
2172 2234
2173} 2235}
2174 2236
2175/* 2237/*
2176 * Close a reqular pipe. 2238 * Close a reqular pipe.
2177 * Assumes that there are no pending transactions. 2239 * Assumes that there are no pending transactions.
2178 */ 2240 */
2179void 2241void
2180ohci_close_pipe(usbd_pipe_handle pipe, ohci_soft_ed_t *head) 2242ohci_close_pipe(usbd_pipe_handle pipe, ohci_soft_ed_t *head)
2181{ 2243{
2182 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; 2244 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
2183 ohci_softc_t *sc = pipe->device->bus->hci_private; 2245 ohci_softc_t *sc = pipe->device->bus->hci_private;
2184 ohci_soft_ed_t *sed = opipe->sed; 2246 ohci_soft_ed_t *sed = opipe->sed;
2185 int s; 
2186 2247
2187 s = splusb(); 2248 KASSERT(mutex_owned(&sc->sc_lock));
 2249
2188#ifdef DIAGNOSTIC 2250#ifdef DIAGNOSTIC
2189 sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); 2251 sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP);
2190 if ((O32TOH(sed->ed.ed_tailp) & OHCI_HEADMASK) != 2252 if ((O32TOH(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
2191 (O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK)) { 2253 (O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK)) {
2192 ohci_soft_td_t *std; 2254 ohci_soft_td_t *std;
2193 std = ohci_hash_find_td(sc, O32TOH(sed->ed.ed_headp)); 2255 std = ohci_hash_find_td(sc, O32TOH(sed->ed.ed_headp));
2194 printf("ohci_close_pipe: pipe not empty sed=%p hd=0x%x " 2256 printf("ohci_close_pipe: pipe not empty sed=%p hd=0x%x "
2195 "tl=0x%x pipe=%p, std=%p\n", sed, 2257 "tl=0x%x pipe=%p, std=%p\n", sed,
2196 (int)O32TOH(sed->ed.ed_headp), 2258 (int)O32TOH(sed->ed.ed_headp),
2197 (int)O32TOH(sed->ed.ed_tailp), 2259 (int)O32TOH(sed->ed.ed_tailp),
2198 pipe, std); 2260 pipe, std);
2199#ifdef USB_DEBUG 2261#ifdef USB_DEBUG
2200 usbd_dump_pipe(&opipe->pipe); 2262 usbd_dump_pipe(&opipe->pipe);
@@ -2205,133 +2267,125 @@ ohci_close_pipe(usbd_pipe_handle pipe, o @@ -2205,133 +2267,125 @@ ohci_close_pipe(usbd_pipe_handle pipe, o
2205 ohci_dump_td(sc, std); 2267 ohci_dump_td(sc, std);
2206#endif 2268#endif
2207 usb_delay_ms(&sc->sc_bus, 2); 2269 usb_delay_ms(&sc->sc_bus, 2);
2208 if ((O32TOH(sed->ed.ed_tailp) & OHCI_HEADMASK) != 2270 if ((O32TOH(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
2209 (O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK)) 2271 (O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK))
2210 printf("ohci_close_pipe: pipe still not empty\n"); 2272 printf("ohci_close_pipe: pipe still not empty\n");
2211 } 2273 }
2212#endif 2274#endif
2213 ohci_rem_ed(sed, head); 2275 ohci_rem_ed(sed, head);
2214 /* Make sure the host controller is not touching this ED */ 2276 /* Make sure the host controller is not touching this ED */
2215 usb_delay_ms(&sc->sc_bus, 1); 2277 usb_delay_ms(&sc->sc_bus, 1);
2216 pipe->endpoint->datatoggle = 2278 pipe->endpoint->datatoggle =
2217 (O32TOH(sed->ed.ed_headp) & OHCI_TOGGLECARRY) ? 1 : 0; 2279 (O32TOH(sed->ed.ed_headp) & OHCI_TOGGLECARRY) ? 1 : 0;
2218 splx(s); 
2219 ohci_free_sed(sc, opipe->sed); 2280 ohci_free_sed(sc, opipe->sed);
2220} 2281}
2221 2282
2222/* 2283/*
2223 * Abort a device request. 2284 * Abort a device request.
2224 * If this routine is called at splusb() it guarantees that the request 2285 * If this routine is called at splusb() it guarantees that the request
2225 * will be removed from the hardware scheduling and that the callback 2286 * will be removed from the hardware scheduling and that the callback
2226 * for it will be called with USBD_CANCELLED status. 2287 * for it will be called with USBD_CANCELLED status.
2227 * It's impossible to guarantee that the requested transfer will not 2288 * It's impossible to guarantee that the requested transfer will not
2228 * have happened since the hardware runs concurrently. 2289 * have happened since the hardware runs concurrently.
2229 * If the transaction has already happened we rely on the ordinary 2290 * If the transaction has already happened we rely on the ordinary
2230 * interrupt processing to process it. 2291 * interrupt processing to process it.
2231 */ 2292 */
2232void 2293void
2233ohci_abort_xfer(usbd_xfer_handle xfer, usbd_status status) 2294ohci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
2234{ 2295{
2235 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; 2296 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
2236 ohci_softc_t *sc = opipe->pipe.device->bus->hci_private; 2297 ohci_softc_t *sc = opipe->pipe.device->bus->hci_private;
2237 ohci_soft_ed_t *sed = opipe->sed; 2298 ohci_soft_ed_t *sed = opipe->sed;
2238 ohci_soft_td_t *p, *n; 2299 ohci_soft_td_t *p, *n;
2239 ohci_physaddr_t headp; 2300 ohci_physaddr_t headp;
2240 int s, hit; 2301 int hit;
2241 int wake; 2302 int wake;
2242 2303
2243 DPRINTF(("ohci_abort_xfer: xfer=%p pipe=%p sed=%p\n", xfer, opipe,sed)); 2304 DPRINTF(("ohci_abort_xfer: xfer=%p pipe=%p sed=%p\n", xfer, opipe,sed));
2244 2305
2245 if (sc->sc_dying) { 2306 if (sc->sc_dying) {
2246 /* If we're dying, just do the software part. */ 2307 /* If we're dying, just do the software part. */
2247 s = splusb(); 2308 mutex_enter(&sc->sc_lock);
2248 xfer->status = status; /* make software ignore it */ 2309 xfer->status = status; /* make software ignore it */
2249 callout_stop(&xfer->timeout_handle); 2310 callout_halt(&xfer->timeout_handle, &sc->sc_lock);
2250 usb_transfer_complete(xfer); 2311 usb_transfer_complete(xfer);
2251 splx(s); 2312 mutex_exit(&sc->sc_lock);
2252 return; 2313 return;
2253 } 2314 }
2254 2315
2255 if (xfer->device->bus->intr_context || !curproc) 2316 if (xfer->device->bus->intr_context || !curproc)
2256 panic("ohci_abort_xfer: not in process context"); 2317 panic("ohci_abort_xfer: not in process context");
2257 2318
 2319 mutex_enter(&sc->sc_lock);
 2320
2258 /* 2321 /*
2259 * If an abort is already in progress then just wait for it to 2322 * If an abort is already in progress then just wait for it to
2260 * complete and return. 2323 * complete and return.
2261 */ 2324 */
2262 if (xfer->hcflags & UXFER_ABORTING) { 2325 if (xfer->hcflags & UXFER_ABORTING) {
2263 DPRINTFN(2, ("ohci_abort_xfer: already aborting\n")); 2326 DPRINTFN(2, ("ohci_abort_xfer: already aborting\n"));
2264#ifdef DIAGNOSTIC 2327#ifdef DIAGNOSTIC
2265 if (status == USBD_TIMEOUT) 2328 if (status == USBD_TIMEOUT)
2266 printf("0hci_abort_xfer: TIMEOUT while aborting\n"); 2329 printf("0hci_abort_xfer: TIMEOUT while aborting\n");
2267#endif 2330#endif
2268 /* Override the status which might be USBD_TIMEOUT. */ 2331 /* Override the status which might be USBD_TIMEOUT. */
2269 xfer->status = status; 2332 xfer->status = status;
2270 DPRINTFN(2, ("ohci_abort_xfer: waiting for abort to finish\n")); 2333 DPRINTFN(2, ("ohci_abort_xfer: waiting for abort to finish\n"));
2271 xfer->hcflags |= UXFER_ABORTWAIT; 2334 xfer->hcflags |= UXFER_ABORTWAIT;
2272 while (xfer->hcflags & UXFER_ABORTING) 2335 while (xfer->hcflags & UXFER_ABORTING)
2273 tsleep(&xfer->hcflags, PZERO, "ohciaw", 0); 2336 cv_wait(&xfer->hccv, &sc->sc_lock);
 2337 goto done;
2274 return; 2338 return;
2275 } 2339 }
2276 xfer->hcflags |= UXFER_ABORTING; 2340 xfer->hcflags |= UXFER_ABORTING;
2277 2341
2278 /* 2342 /*
2279 * Step 1: Make interrupt routine and hardware ignore xfer. 2343 * Step 1: Make interrupt routine and hardware ignore xfer.
2280 */ 2344 */
2281 s = splusb(); 
2282 xfer->status = status; /* make software ignore it */ 2345 xfer->status = status; /* make software ignore it */
2283 callout_stop(&xfer->timeout_handle); 2346 callout_stop(&xfer->timeout_handle);
2284 splx(s); 
2285 DPRINTFN(1,("ohci_abort_xfer: stop ed=%p\n", sed)); 2347 DPRINTFN(1,("ohci_abort_xfer: stop ed=%p\n", sed));
2286 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), 2348 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags),
2287 sizeof(sed->ed.ed_flags), 2349 sizeof(sed->ed.ed_flags),
2288 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 2350 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
2289 sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); /* force hardware skip */ 2351 sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); /* force hardware skip */
2290 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), 2352 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags),
2291 sizeof(sed->ed.ed_flags), 2353 sizeof(sed->ed.ed_flags),
2292 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2354 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2293 2355
2294 /* 2356 /*
2295 * Step 2: Wait until we know hardware has finished any possible 2357 * Step 2: Wait until we know hardware has finished any possible
2296 * use of the xfer. Also make sure the soft interrupt routine 2358 * use of the xfer. Also make sure the soft interrupt routine
2297 * has run. 2359 * has run.
2298 */ 2360 */
2299 usb_delay_ms(opipe->pipe.device->bus, 20); /* Hardware finishes in 1ms */ 2361 usb_delay_ms(opipe->pipe.device->bus, 20); /* Hardware finishes in 1ms */
2300 s = splusb(); 
2301#ifdef USB_USE_SOFTINTR 
2302 sc->sc_softwake = 1; 2362 sc->sc_softwake = 1;
2303#endif /* USB_USE_SOFTINTR */ 
2304 usb_schedsoftintr(&sc->sc_bus); 2363 usb_schedsoftintr(&sc->sc_bus);
2305#ifdef USB_USE_SOFTINTR 2364 cv_wait(&sc->sc_softwake_cv, &sc->sc_lock);
2306 tsleep(&sc->sc_softwake, PZERO, "ohciab", 0); 
2307#endif /* USB_USE_SOFTINTR */ 
2308 splx(s); 
2309 2365
2310 /* 2366 /*
2311 * Step 3: Remove any vestiges of the xfer from the hardware. 2367 * Step 3: Remove any vestiges of the xfer from the hardware.
2312 * The complication here is that the hardware may have executed 2368 * The complication here is that the hardware may have executed
2313 * beyond the xfer we're trying to abort. So as we're scanning 2369 * beyond the xfer we're trying to abort. So as we're scanning
2314 * the TDs of this xfer we check if the hardware points to 2370 * the TDs of this xfer we check if the hardware points to
2315 * any of them. 2371 * any of them.
2316 */ 2372 */
2317 s = splusb(); /* XXX why? */ 
2318 p = xfer->hcpriv; 2373 p = xfer->hcpriv;
2319#ifdef DIAGNOSTIC 2374#ifdef DIAGNOSTIC
2320 if (p == NULL) { 2375 if (p == NULL) {
2321 xfer->hcflags &= ~UXFER_ABORTING; /* XXX */ 2376 xfer->hcflags &= ~UXFER_ABORTING; /* XXX */
2322 splx(s); 
2323 printf("ohci_abort_xfer: hcpriv is NULL\n"); 2377 printf("ohci_abort_xfer: hcpriv is NULL\n");
2324 return; 2378 goto done;
2325 } 2379 }
2326#endif 2380#endif
2327#ifdef OHCI_DEBUG 2381#ifdef OHCI_DEBUG
2328 if (ohcidebug > 1) { 2382 if (ohcidebug > 1) {
2329 DPRINTF(("ohci_abort_xfer: sed=\n")); 2383 DPRINTF(("ohci_abort_xfer: sed=\n"));
2330 ohci_dump_ed(sc, sed); 2384 ohci_dump_ed(sc, sed);
2331 ohci_dump_tds(sc, p); 2385 ohci_dump_tds(sc, p);
2332 } 2386 }
2333#endif 2387#endif
2334 headp = O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK; 2388 headp = O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK;
2335 hit = 0; 2389 hit = 0;
2336 for (; p->xfer == xfer; p = n) { 2390 for (; p->xfer == xfer; p = n) {
2337 hit |= headp == p->physaddr; 2391 hit |= headp == p->physaddr;
@@ -2359,29 +2413,30 @@ ohci_abort_xfer(usbd_xfer_handle xfer, u @@ -2359,29 +2413,30 @@ ohci_abort_xfer(usbd_xfer_handle xfer, u
2359 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 2413 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
2360 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); /* remove hardware skip */ 2414 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); /* remove hardware skip */
2361 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), 2415 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags),
2362 sizeof(sed->ed.ed_flags), 2416 sizeof(sed->ed.ed_flags),
2363 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2417 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2364 2418
2365 /* 2419 /*
2366 * Step 5: Execute callback. 2420 * Step 5: Execute callback.
2367 */ 2421 */
2368 wake = xfer->hcflags & UXFER_ABORTWAIT; 2422 wake = xfer->hcflags & UXFER_ABORTWAIT;
2369 xfer->hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT); 2423 xfer->hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT);
2370 usb_transfer_complete(xfer); 2424 usb_transfer_complete(xfer);
2371 if (wake) 2425 if (wake)
2372 wakeup(&xfer->hcflags); 2426 cv_broadcast(&xfer->hccv);
2373 2427
2374 splx(s); 2428done:
 2429 mutex_exit(&sc->sc_lock);
2375} 2430}
2376 2431
2377/* 2432/*
2378 * Data structures and routines to emulate the root hub. 2433 * Data structures and routines to emulate the root hub.
2379 */ 2434 */
2380Static usb_device_descriptor_t ohci_devd = { 2435Static usb_device_descriptor_t ohci_devd = {
2381 USB_DEVICE_DESCRIPTOR_SIZE, 2436 USB_DEVICE_DESCRIPTOR_SIZE,
2382 UDESC_DEVICE, /* type */ 2437 UDESC_DEVICE, /* type */
2383 {0x00, 0x01}, /* USB version */ 2438 {0x00, 0x01}, /* USB version */
2384 UDCLASS_HUB, /* class */ 2439 UDCLASS_HUB, /* class */
2385 UDSUBCLASS_HUB, /* subclass */ 2440 UDSUBCLASS_HUB, /* subclass */
2386 UDPROTO_FSHUB, /* protocol */ 2441 UDPROTO_FSHUB, /* protocol */
2387 64, /* max packet */ 2442 64, /* max packet */
@@ -2425,45 +2480,48 @@ Static const usb_endpoint_descriptor_t o @@ -2425,45 +2480,48 @@ Static const usb_endpoint_descriptor_t o
2425}; 2480};
2426 2481
2427Static const usb_hub_descriptor_t ohci_hubd = { 2482Static const usb_hub_descriptor_t ohci_hubd = {
2428 .bDescLength = USB_HUB_DESCRIPTOR_SIZE, 2483 .bDescLength = USB_HUB_DESCRIPTOR_SIZE,
2429 .bDescriptorType = UDESC_HUB, 2484 .bDescriptorType = UDESC_HUB,
2430}; 2485};
2431 2486
2432/* 2487/*
2433 * Simulate a hardware hub by handling all the necessary requests. 2488 * Simulate a hardware hub by handling all the necessary requests.
2434 */ 2489 */
2435Static usbd_status 2490Static usbd_status
2436ohci_root_ctrl_transfer(usbd_xfer_handle xfer) 2491ohci_root_ctrl_transfer(usbd_xfer_handle xfer)
2437{ 2492{
 2493 ohci_softc_t *sc = xfer->pipe->device->bus->hci_private;
2438 usbd_status err; 2494 usbd_status err;
2439 2495
2440 /* Insert last in queue. */ 2496 /* Insert last in queue. */
 2497 mutex_enter(&sc->sc_lock);
2441 err = usb_insert_transfer(xfer); 2498 err = usb_insert_transfer(xfer);
 2499 mutex_exit(&sc->sc_lock);
2442 if (err) 2500 if (err)
2443 return (err); 2501 return (err);
2444 2502
2445 /* Pipe isn't running, start first */ 2503 /* Pipe isn't running, start first */
2446 return (ohci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); 2504 return (ohci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
2447} 2505}
2448 2506
2449Static usbd_status 2507Static usbd_status
2450ohci_root_ctrl_start(usbd_xfer_handle xfer) 2508ohci_root_ctrl_start(usbd_xfer_handle xfer)
2451{ 2509{
2452 ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; 2510 ohci_softc_t *sc = xfer->pipe->device->bus->hci_private;
2453 usb_device_request_t *req; 2511 usb_device_request_t *req;
2454 void *buf = NULL; 2512 void *buf = NULL;
2455 int port, i; 2513 int port, i;
2456 int s, len, value, index, l, totlen = 0; 2514 int len, value, index, l, totlen = 0;
2457 usb_port_status_t ps; 2515 usb_port_status_t ps;
2458 usb_hub_descriptor_t hubd; 2516 usb_hub_descriptor_t hubd;
2459 usbd_status err; 2517 usbd_status err;
2460 u_int32_t v; 2518 u_int32_t v;
2461 2519
2462 if (sc->sc_dying) 2520 if (sc->sc_dying)
2463 return (USBD_IOERROR); 2521 return (USBD_IOERROR);
2464 2522
2465#ifdef DIAGNOSTIC 2523#ifdef DIAGNOSTIC
2466 if (!(xfer->rqflags & URQ_REQUEST)) 2524 if (!(xfer->rqflags & URQ_REQUEST))
2467 /* XXX panic */ 2525 /* XXX panic */
2468 return (USBD_INVAL); 2526 return (USBD_INVAL);
2469#endif 2527#endif
@@ -2744,217 +2802,235 @@ ohci_root_ctrl_start(usbd_xfer_handle xf @@ -2744,217 +2802,235 @@ ohci_root_ctrl_start(usbd_xfer_handle xf
2744 default: 2802 default:
2745 err = USBD_IOERROR; 2803 err = USBD_IOERROR;
2746 goto ret; 2804 goto ret;
2747 } 2805 }
2748 break; 2806 break;
2749 default: 2807 default:
2750 err = USBD_IOERROR; 2808 err = USBD_IOERROR;
2751 goto ret; 2809 goto ret;
2752 } 2810 }
2753 xfer->actlen = totlen; 2811 xfer->actlen = totlen;
2754 err = USBD_NORMAL_COMPLETION; 2812 err = USBD_NORMAL_COMPLETION;
2755 ret: 2813 ret:
2756 xfer->status = err; 2814 xfer->status = err;
2757 s = splusb(); 2815 mutex_enter(&sc->sc_lock);
2758 usb_transfer_complete(xfer); 2816 usb_transfer_complete(xfer);
2759 splx(s); 2817 mutex_exit(&sc->sc_lock);
2760 return (USBD_IN_PROGRESS); 2818 return (USBD_IN_PROGRESS);
2761} 2819}
2762 2820
2763/* Abort a root control request. */ 2821/* Abort a root control request. */
2764Static void 2822Static void
2765ohci_root_ctrl_abort(usbd_xfer_handle xfer) 2823ohci_root_ctrl_abort(usbd_xfer_handle xfer)
2766{ 2824{
2767 /* Nothing to do, all transfers are synchronous. */ 2825 /* Nothing to do, all transfers are synchronous. */
2768} 2826}
2769 2827
2770/* Close the root pipe. */ 2828/* Close the root pipe. */
2771Static void 2829Static void
2772ohci_root_ctrl_close(usbd_pipe_handle pipe) 2830ohci_root_ctrl_close(usbd_pipe_handle pipe)
2773{ 2831{
2774 DPRINTF(("ohci_root_ctrl_close\n")); 2832 DPRINTF(("ohci_root_ctrl_close\n"));
2775 /* Nothing to do. */ 2833 /* Nothing to do. */
2776} 2834}
2777 2835
2778Static usbd_status 2836Static usbd_status
2779ohci_root_intr_transfer(usbd_xfer_handle xfer) 2837ohci_root_intr_transfer(usbd_xfer_handle xfer)
2780{ 2838{
 2839 ohci_softc_t *sc = xfer->pipe->device->bus->hci_private;
2781 usbd_status err; 2840 usbd_status err;
2782 2841
2783 /* Insert last in queue. */ 2842 /* Insert last in queue. */
 2843 mutex_enter(&sc->sc_lock);
2784 err = usb_insert_transfer(xfer); 2844 err = usb_insert_transfer(xfer);
 2845 mutex_exit(&sc->sc_lock);
2785 if (err) 2846 if (err)
2786 return (err); 2847 return (err);
2787 2848
2788 /* Pipe isn't running, start first */ 2849 /* Pipe isn't running, start first */
2789 return (ohci_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); 2850 return (ohci_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
2790} 2851}
2791 2852
2792Static usbd_status 2853Static usbd_status
2793ohci_root_intr_start(usbd_xfer_handle xfer) 2854ohci_root_intr_start(usbd_xfer_handle xfer)
2794{ 2855{
2795 usbd_pipe_handle pipe = xfer->pipe; 2856 usbd_pipe_handle pipe = xfer->pipe;
2796 ohci_softc_t *sc = pipe->device->bus->hci_private; 2857 ohci_softc_t *sc = pipe->device->bus->hci_private;
2797 2858
2798 if (sc->sc_dying) 2859 if (sc->sc_dying)
2799 return (USBD_IOERROR); 2860 return (USBD_IOERROR);
2800 2861
 2862 mutex_enter(&sc->sc_lock);
 2863 KASSERT(sc->sc_intrxfer == NULL);
2801 sc->sc_intrxfer = xfer; 2864 sc->sc_intrxfer = xfer;
 2865 mutex_exit(&sc->sc_lock);
2802 2866
2803 return (USBD_IN_PROGRESS); 2867 return (USBD_IN_PROGRESS);
2804} 2868}
2805 2869
2806/* Abort a root interrupt request. */ 2870/* Abort a root interrupt request. */
2807Static void 2871Static void
2808ohci_root_intr_abort(usbd_xfer_handle xfer) 2872ohci_root_intr_abort(usbd_xfer_handle xfer)
2809{ 2873{
2810 int s; 2874 ohci_softc_t *sc = xfer->pipe->device->bus->hci_private;
2811 2875
2812 if (xfer->pipe->intrxfer == xfer) { 2876 if (xfer->pipe->intrxfer == xfer) {
2813 DPRINTF(("ohci_root_intr_abort: remove\n")); 2877 DPRINTF(("ohci_root_intr_abort: remove\n"));
2814 xfer->pipe->intrxfer = NULL; 2878 xfer->pipe->intrxfer = NULL;
2815 } 2879 }
2816 xfer->status = USBD_CANCELLED; 2880 xfer->status = USBD_CANCELLED;
2817 s = splusb(); 2881 mutex_enter(&sc->sc_lock);
2818 usb_transfer_complete(xfer); 2882 usb_transfer_complete(xfer);
2819 splx(s); 2883 mutex_exit(&sc->sc_lock);
2820} 2884}
2821 2885
2822/* Close the root pipe. */ 2886/* Close the root pipe. */
2823Static void 2887Static void
2824ohci_root_intr_close(usbd_pipe_handle pipe) 2888ohci_root_intr_close(usbd_pipe_handle pipe)
2825{ 2889{
2826 ohci_softc_t *sc = pipe->device->bus->hci_private; 2890 ohci_softc_t *sc = pipe->device->bus->hci_private;
2827 2891
2828 DPRINTF(("ohci_root_intr_close\n")); 2892 DPRINTF(("ohci_root_intr_close\n"));
2829 2893
2830 sc->sc_intrxfer = NULL; 2894 sc->sc_intrxfer = NULL;
2831} 2895}
2832 2896
2833/************************/ 2897/************************/
2834 2898
2835Static usbd_status 2899Static usbd_status
2836ohci_device_ctrl_transfer(usbd_xfer_handle xfer) 2900ohci_device_ctrl_transfer(usbd_xfer_handle xfer)
2837{ 2901{
 2902 ohci_softc_t *sc = xfer->pipe->device->bus->hci_private;
2838 usbd_status err; 2903 usbd_status err;
2839 2904
2840 /* Insert last in queue. */ 2905 /* Insert last in queue. */
 2906 mutex_enter(&sc->sc_lock);
2841 err = usb_insert_transfer(xfer); 2907 err = usb_insert_transfer(xfer);
 2908 mutex_exit(&sc->sc_lock);
2842 if (err) 2909 if (err)
2843 return (err); 2910 return (err);
2844 2911
2845 /* Pipe isn't running, start first */ 2912 /* Pipe isn't running, start first */
2846 return (ohci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); 2913 return (ohci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
2847} 2914}
2848 2915
2849Static usbd_status 2916Static usbd_status
2850ohci_device_ctrl_start(usbd_xfer_handle xfer) 2917ohci_device_ctrl_start(usbd_xfer_handle xfer)
2851{ 2918{
2852 ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; 2919 ohci_softc_t *sc = xfer->pipe->device->bus->hci_private;
2853 usbd_status err; 2920 usbd_status err;
2854 2921
2855 if (sc->sc_dying) 2922 if (sc->sc_dying)
2856 return (USBD_IOERROR); 2923 return (USBD_IOERROR);
2857 2924
2858#ifdef DIAGNOSTIC 2925#ifdef DIAGNOSTIC
2859 if (!(xfer->rqflags & URQ_REQUEST)) { 2926 if (!(xfer->rqflags & URQ_REQUEST)) {
2860 /* XXX panic */ 2927 /* XXX panic */
2861 printf("ohci_device_ctrl_transfer: not a request\n"); 2928 printf("ohci_device_ctrl_transfer: not a request\n");
2862 return (USBD_INVAL); 2929 return (USBD_INVAL);
2863 } 2930 }
2864#endif 2931#endif
2865 2932
 2933 mutex_enter(&sc->sc_lock);
2866 err = ohci_device_request(xfer); 2934 err = ohci_device_request(xfer);
 2935 mutex_exit(&sc->sc_lock);
2867 if (err) 2936 if (err)
2868 return (err); 2937 return (err);
2869 2938
2870 if (sc->sc_bus.use_polling) 2939 if (sc->sc_bus.use_polling)
2871 ohci_waitintr(sc, xfer); 2940 ohci_waitintr(sc, xfer);
2872 return (USBD_IN_PROGRESS); 2941 return (USBD_IN_PROGRESS);
2873} 2942}
2874 2943
2875/* Abort a device control request. */ 2944/* Abort a device control request. */
2876Static void 2945Static void
2877ohci_device_ctrl_abort(usbd_xfer_handle xfer) 2946ohci_device_ctrl_abort(usbd_xfer_handle xfer)
2878{ 2947{
2879 DPRINTF(("ohci_device_ctrl_abort: xfer=%p\n", xfer)); 2948 DPRINTF(("ohci_device_ctrl_abort: xfer=%p\n", xfer));
2880 ohci_abort_xfer(xfer, USBD_CANCELLED); 2949 ohci_abort_xfer(xfer, USBD_CANCELLED);
2881} 2950}
2882 2951
2883/* Close a device control pipe. */ 2952/* Close a device control pipe. */
2884Static void 2953Static void
2885ohci_device_ctrl_close(usbd_pipe_handle pipe) 2954ohci_device_ctrl_close(usbd_pipe_handle pipe)
2886{ 2955{
2887 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; 2956 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
2888 ohci_softc_t *sc = pipe->device->bus->hci_private; 2957 ohci_softc_t *sc = pipe->device->bus->hci_private;
2889 2958
2890 DPRINTF(("ohci_device_ctrl_close: pipe=%p\n", pipe)); 2959 DPRINTF(("ohci_device_ctrl_close: pipe=%p\n", pipe));
 2960 mutex_enter(&sc->sc_lock);
2891 ohci_close_pipe(pipe, sc->sc_ctrl_head); 2961 ohci_close_pipe(pipe, sc->sc_ctrl_head);
 2962 mutex_exit(&sc->sc_lock);
2892 ohci_free_std(sc, opipe->tail.td); 2963 ohci_free_std(sc, opipe->tail.td);
2893} 2964}
2894 2965
2895/************************/ 2966/************************/
2896 2967
2897Static void 2968Static void
2898ohci_device_clear_toggle(usbd_pipe_handle pipe) 2969ohci_device_clear_toggle(usbd_pipe_handle pipe)
2899{ 2970{
2900 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; 2971 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
2901 ohci_softc_t *sc = pipe->device->bus->hci_private; 2972 ohci_softc_t *sc = pipe->device->bus->hci_private;
2902 2973
2903 opipe->sed->ed.ed_headp &= HTOO32(~OHCI_TOGGLECARRY); 2974 opipe->sed->ed.ed_headp &= HTOO32(~OHCI_TOGGLECARRY);
2904} 2975}
2905 2976
2906Static void 2977Static void
2907ohci_noop(usbd_pipe_handle pipe) 2978ohci_noop(usbd_pipe_handle pipe)
2908{ 2979{
2909} 2980}
2910 2981
2911Static usbd_status 2982Static usbd_status
2912ohci_device_bulk_transfer(usbd_xfer_handle xfer) 2983ohci_device_bulk_transfer(usbd_xfer_handle xfer)
2913{ 2984{
 2985 ohci_softc_t *sc = xfer->pipe->device->bus->hci_private;
2914 usbd_status err; 2986 usbd_status err;
2915 2987
2916 /* Insert last in queue. */ 2988 /* Insert last in queue. */
 2989 mutex_enter(&sc->sc_lock);
2917 err = usb_insert_transfer(xfer); 2990 err = usb_insert_transfer(xfer);
 2991 mutex_exit(&sc->sc_lock);
2918 if (err) 2992 if (err)
2919 return (err); 2993 return (err);
2920 2994
2921 /* Pipe isn't running, start first */ 2995 /* Pipe isn't running, start first */
2922 return (ohci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); 2996 return (ohci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
2923} 2997}
2924 2998
2925Static usbd_status 2999Static usbd_status
2926ohci_device_bulk_start(usbd_xfer_handle xfer) 3000ohci_device_bulk_start(usbd_xfer_handle xfer)
2927{ 3001{
2928 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; 3002 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
2929 usbd_device_handle dev = opipe->pipe.device; 3003 usbd_device_handle dev = opipe->pipe.device;
2930 ohci_softc_t *sc = dev->bus->hci_private; 3004 ohci_softc_t *sc = dev->bus->hci_private;
2931 int addr = dev->address; 3005 int addr = dev->address;
2932 ohci_soft_td_t *data, *tail, *tdp; 3006 ohci_soft_td_t *data, *tail, *tdp;
2933 ohci_soft_ed_t *sed; 3007 ohci_soft_ed_t *sed;
2934 int s, len, isread, endpt; 3008 int len, isread, endpt;
2935 usbd_status err; 3009 usbd_status err;
2936 3010
2937 if (sc->sc_dying) 3011 if (sc->sc_dying)
2938 return (USBD_IOERROR); 3012 return (USBD_IOERROR);
2939 3013
2940#ifdef DIAGNOSTIC 3014#ifdef DIAGNOSTIC
2941 if (xfer->rqflags & URQ_REQUEST) { 3015 if (xfer->rqflags & URQ_REQUEST) {
2942 /* XXX panic */ 3016 /* XXX panic */
2943 printf("ohci_device_bulk_start: a request\n"); 3017 printf("ohci_device_bulk_start: a request\n");
2944 return (USBD_INVAL); 3018 return (USBD_INVAL);
2945 } 3019 }
2946#endif 3020#endif
2947 3021
 3022 mutex_enter(&sc->sc_lock);
 3023
2948 len = xfer->length; 3024 len = xfer->length;
2949 endpt = xfer->pipe->endpoint->edesc->bEndpointAddress; 3025 endpt = xfer->pipe->endpoint->edesc->bEndpointAddress;
2950 isread = UE_GET_DIR(endpt) == UE_DIR_IN; 3026 isread = UE_GET_DIR(endpt) == UE_DIR_IN;
2951 sed = opipe->sed; 3027 sed = opipe->sed;
2952 3028
2953 DPRINTFN(4,("ohci_device_bulk_start: xfer=%p len=%d isread=%d " 3029 DPRINTFN(4,("ohci_device_bulk_start: xfer=%p len=%d isread=%d "
2954 "flags=%d endpt=%d\n", xfer, len, isread, xfer->flags, 3030 "flags=%d endpt=%d\n", xfer, len, isread, xfer->flags,
2955 endpt)); 3031 endpt));
2956 3032
2957 opipe->u.bulk.isread = isread; 3033 opipe->u.bulk.isread = isread;
2958 opipe->u.bulk.length = len; 3034 opipe->u.bulk.length = len;
2959 3035
2960 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 3036 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed),
@@ -2966,124 +3042,129 @@ ohci_device_bulk_start(usbd_xfer_handle  @@ -2966,124 +3042,129 @@ ohci_device_bulk_start(usbd_xfer_handle
2966 3042
2967 /* Allocate a chain of new TDs (including a new tail). */ 3043 /* Allocate a chain of new TDs (including a new tail). */
2968 data = opipe->tail.td; 3044 data = opipe->tail.td;
2969 err = ohci_alloc_std_chain(opipe, sc, len, isread, xfer, 3045 err = ohci_alloc_std_chain(opipe, sc, len, isread, xfer,
2970 data, &tail); 3046 data, &tail);
2971 /* We want interrupt at the end of the transfer. */ 3047 /* We want interrupt at the end of the transfer. */
2972 tail->td.td_flags &= HTOO32(~OHCI_TD_INTR_MASK); 3048 tail->td.td_flags &= HTOO32(~OHCI_TD_INTR_MASK);
2973 tail->td.td_flags |= HTOO32(OHCI_TD_SET_DI(1)); 3049 tail->td.td_flags |= HTOO32(OHCI_TD_SET_DI(1));
2974 tail->flags |= OHCI_CALL_DONE; 3050 tail->flags |= OHCI_CALL_DONE;
2975 tail = tail->nexttd; /* point at sentinel */ 3051 tail = tail->nexttd; /* point at sentinel */
2976 usb_syncmem(&tail->dma, tail->offs + offsetof(ohci_td_t, td_flags), 3052 usb_syncmem(&tail->dma, tail->offs + offsetof(ohci_td_t, td_flags),
2977 sizeof(tail->td.td_flags), 3053 sizeof(tail->td.td_flags),
2978 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3054 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2979 if (err) 3055 if (err) {
 3056 mutex_exit(&sc->sc_lock);
2980 return (err); 3057 return (err);
 3058 }
2981 3059
2982 tail->xfer = NULL; 3060 tail->xfer = NULL;
2983 xfer->hcpriv = data; 3061 xfer->hcpriv = data;
2984 3062
2985 DPRINTFN(4,("ohci_device_bulk_start: ed_flags=0x%08x td_flags=0x%08x " 3063 DPRINTFN(4,("ohci_device_bulk_start: ed_flags=0x%08x td_flags=0x%08x "
2986 "td_cbp=0x%08x td_be=0x%08x\n", 3064 "td_cbp=0x%08x td_be=0x%08x\n",
2987 (int)O32TOH(sed->ed.ed_flags), 3065 (int)O32TOH(sed->ed.ed_flags),
2988 (int)O32TOH(data->td.td_flags), 3066 (int)O32TOH(data->td.td_flags),
2989 (int)O32TOH(data->td.td_cbp), 3067 (int)O32TOH(data->td.td_cbp),
2990 (int)O32TOH(data->td.td_be))); 3068 (int)O32TOH(data->td.td_be)));
2991 3069
2992#ifdef OHCI_DEBUG 3070#ifdef OHCI_DEBUG
2993 if (ohcidebug > 5) { 3071 if (ohcidebug > 5) {
2994 ohci_dump_ed(sc, sed); 3072 ohci_dump_ed(sc, sed);
2995 ohci_dump_tds(sc, data); 3073 ohci_dump_tds(sc, data);
2996 } 3074 }
2997#endif 3075#endif
2998 3076
2999 /* Insert ED in schedule */ 3077 /* Insert ED in schedule */
3000 s = splusb(); 
3001 for (tdp = data; tdp != tail; tdp = tdp->nexttd) { 3078 for (tdp = data; tdp != tail; tdp = tdp->nexttd) {
3002 tdp->xfer = xfer; 3079 tdp->xfer = xfer;
3003 } 3080 }
3004 sed->ed.ed_tailp = HTOO32(tail->physaddr); 3081 sed->ed.ed_tailp = HTOO32(tail->physaddr);
3005 opipe->tail.td = tail; 3082 opipe->tail.td = tail;
3006 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); 3083 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP);
3007 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 3084 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed),
3008 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3085 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3009 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF); 3086 OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF);
3010 if (xfer->timeout && !sc->sc_bus.use_polling) { 3087 if (xfer->timeout && !sc->sc_bus.use_polling) {
3011 callout_reset(&xfer->timeout_handle, mstohz(xfer->timeout), 3088 callout_reset(&xfer->timeout_handle, mstohz(xfer->timeout),
3012 ohci_timeout, xfer); 3089 ohci_timeout, xfer);
3013 } 3090 }
 3091 mutex_exit(&sc->sc_lock);
3014 3092
3015#if 0 3093#if 0
3016/* This goes wrong if we are too slow. */ 3094/* This goes wrong if we are too slow. */
3017 if (ohcidebug > 10) { 3095 if (ohcidebug > 10) {
3018 delay(10000); 3096 delay(10000);
3019 DPRINTF(("ohci_device_intr_transfer: status=%x\n", 3097 DPRINTF(("ohci_device_intr_transfer: status=%x\n",
3020 OREAD4(sc, OHCI_COMMAND_STATUS))); 3098 OREAD4(sc, OHCI_COMMAND_STATUS)));
3021 ohci_dump_ed(sc, sed); 3099 ohci_dump_ed(sc, sed);
3022 ohci_dump_tds(sc, data); 3100 ohci_dump_tds(sc, data);
3023 } 3101 }
3024#endif 3102#endif
3025 3103
3026 splx(s); 
3027 
3028 return (USBD_IN_PROGRESS); 3104 return (USBD_IN_PROGRESS);
3029} 3105}
3030 3106
3031Static void 3107Static void
3032ohci_device_bulk_abort(usbd_xfer_handle xfer) 3108ohci_device_bulk_abort(usbd_xfer_handle xfer)
3033{ 3109{
3034 DPRINTF(("ohci_device_bulk_abort: xfer=%p\n", xfer)); 3110 DPRINTF(("ohci_device_bulk_abort: xfer=%p\n", xfer));
3035 ohci_abort_xfer(xfer, USBD_CANCELLED); 3111 ohci_abort_xfer(xfer, USBD_CANCELLED);
3036} 3112}
3037 3113
3038/* 3114/*
3039 * Close a device bulk pipe. 3115 * Close a device bulk pipe.
3040 */ 3116 */
3041Static void 3117Static void
3042ohci_device_bulk_close(usbd_pipe_handle pipe) 3118ohci_device_bulk_close(usbd_pipe_handle pipe)
3043{ 3119{
3044 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; 3120 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
3045 ohci_softc_t *sc = pipe->device->bus->hci_private; 3121 ohci_softc_t *sc = pipe->device->bus->hci_private;
3046 3122
3047 DPRINTF(("ohci_device_bulk_close: pipe=%p\n", pipe)); 3123 DPRINTF(("ohci_device_bulk_close: pipe=%p\n", pipe));
 3124 mutex_enter(&sc->sc_lock);
3048 ohci_close_pipe(pipe, sc->sc_bulk_head); 3125 ohci_close_pipe(pipe, sc->sc_bulk_head);
 3126 mutex_exit(&sc->sc_lock);
3049 ohci_free_std(sc, opipe->tail.td); 3127 ohci_free_std(sc, opipe->tail.td);
3050} 3128}
3051 3129
3052/************************/ 3130/************************/
3053 3131
3054Static usbd_status 3132Static usbd_status
3055ohci_device_intr_transfer(usbd_xfer_handle xfer) 3133ohci_device_intr_transfer(usbd_xfer_handle xfer)
3056{ 3134{
 3135 ohci_softc_t *sc = xfer->pipe->device->bus->hci_private;
3057 usbd_status err; 3136 usbd_status err;
3058 3137
3059 /* Insert last in queue. */ 3138 /* Insert last in queue. */
 3139 mutex_enter(&sc->sc_lock);
3060 err = usb_insert_transfer(xfer); 3140 err = usb_insert_transfer(xfer);
 3141 mutex_exit(&sc->sc_lock);
3061 if (err) 3142 if (err)
3062 return (err); 3143 return (err);
3063 3144
3064 /* Pipe isn't running, start first */ 3145 /* Pipe isn't running, start first */
3065 return (ohci_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); 3146 return (ohci_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
3066} 3147}
3067 3148
3068Static usbd_status 3149Static usbd_status
3069ohci_device_intr_start(usbd_xfer_handle xfer) 3150ohci_device_intr_start(usbd_xfer_handle xfer)
3070{ 3151{
3071 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; 3152 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
3072 usbd_device_handle dev = opipe->pipe.device; 3153 usbd_device_handle dev = opipe->pipe.device;
3073 ohci_softc_t *sc = dev->bus->hci_private; 3154 ohci_softc_t *sc = dev->bus->hci_private;
3074 ohci_soft_ed_t *sed = opipe->sed; 3155 ohci_soft_ed_t *sed = opipe->sed;
3075 ohci_soft_td_t *data, *tail; 3156 ohci_soft_td_t *data, *tail;
3076 int s, len, isread, endpt; 3157 int len, isread, endpt;
3077 3158
3078 if (sc->sc_dying) 3159 if (sc->sc_dying)
3079 return (USBD_IOERROR); 3160 return (USBD_IOERROR);
3080 3161
3081 DPRINTFN(3, ("ohci_device_intr_transfer: xfer=%p len=%d " 3162 DPRINTFN(3, ("ohci_device_intr_transfer: xfer=%p len=%d "
3082 "flags=%d priv=%p\n", 3163 "flags=%d priv=%p\n",
3083 xfer, xfer->length, xfer->flags, xfer->priv)); 3164 xfer, xfer->length, xfer->flags, xfer->priv));
3084 3165
3085#ifdef DIAGNOSTIC 3166#ifdef DIAGNOSTIC
3086 if (xfer->rqflags & URQ_REQUEST) 3167 if (xfer->rqflags & URQ_REQUEST)
3087 panic("ohci_device_intr_transfer: a request"); 3168 panic("ohci_device_intr_transfer: a request");
3088#endif 3169#endif
3089 3170
@@ -3113,114 +3194,113 @@ ohci_device_intr_start(usbd_xfer_handle  @@ -3113,114 +3194,113 @@ ohci_device_intr_start(usbd_xfer_handle
3113 usb_syncmem(&data->dma, data->offs, sizeof(data->td), 3194 usb_syncmem(&data->dma, data->offs, sizeof(data->td),
3114 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3195 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3115 xfer->hcpriv = data; 3196 xfer->hcpriv = data;
3116 3197
3117#ifdef OHCI_DEBUG 3198#ifdef OHCI_DEBUG
3118 if (ohcidebug > 5) { 3199 if (ohcidebug > 5) {
3119 DPRINTF(("ohci_device_intr_transfer:\n")); 3200 DPRINTF(("ohci_device_intr_transfer:\n"));
3120 ohci_dump_ed(sc, sed); 3201 ohci_dump_ed(sc, sed);
3121 ohci_dump_tds(sc, data); 3202 ohci_dump_tds(sc, data);
3122 } 3203 }
3123#endif 3204#endif
3124 3205
3125 /* Insert ED in schedule */ 3206 /* Insert ED in schedule */
3126 s = splusb(); 3207 mutex_enter(&sc->sc_lock);
3127 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 3208 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed),
3128 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 3209 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
3129 sed->ed.ed_tailp = HTOO32(tail->physaddr); 3210 sed->ed.ed_tailp = HTOO32(tail->physaddr);
3130 opipe->tail.td = tail; 3211 opipe->tail.td = tail;
3131 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); 3212 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP);
3132 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 3213 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed),
3133 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3214 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3134 3215
3135#if 0 3216#if 0
3136/* 3217/*
3137 * This goes horribly wrong, printing thousands of descriptors, 3218 * This goes horribly wrong, printing thousands of descriptors,
3138 * because false references are followed due to the fact that the 3219 * because false references are followed due to the fact that the
3139 * TD is gone. 3220 * TD is gone.
3140 */ 3221 */
3141 if (ohcidebug > 5) { 3222 if (ohcidebug > 5) {
3142 usb_delay_ms(&sc->sc_bus, 5); 3223 usb_delay_ms(&sc->sc_bus, 5);
3143 DPRINTF(("ohci_device_intr_transfer: status=%x\n", 3224 DPRINTF(("ohci_device_intr_transfer: status=%x\n",
3144 OREAD4(sc, OHCI_COMMAND_STATUS))); 3225 OREAD4(sc, OHCI_COMMAND_STATUS)));
3145 ohci_dump_ed(sc, sed); 3226 ohci_dump_ed(sc, sed);
3146 ohci_dump_tds(sc, data); 3227 ohci_dump_tds(sc, data);
3147 } 3228 }
3148#endif 3229#endif
3149 splx(s); 3230 mutex_exit(&sc->sc_lock);
3150 3231
3151 return (USBD_IN_PROGRESS); 3232 return (USBD_IN_PROGRESS);
3152} 3233}
3153 3234
3154/* Abort a device control request. */ 3235/* Abort a device control request. */
3155Static void 3236Static void
3156ohci_device_intr_abort(usbd_xfer_handle xfer) 3237ohci_device_intr_abort(usbd_xfer_handle xfer)
3157{ 3238{
3158 if (xfer->pipe->intrxfer == xfer) { 3239 if (xfer->pipe->intrxfer == xfer) {
3159 DPRINTF(("ohci_device_intr_abort: remove\n")); 3240 DPRINTF(("ohci_device_intr_abort: remove\n"));
3160 xfer->pipe->intrxfer = NULL; 3241 xfer->pipe->intrxfer = NULL;
3161 } 3242 }
3162 ohci_abort_xfer(xfer, USBD_CANCELLED); 3243 ohci_abort_xfer(xfer, USBD_CANCELLED);
3163} 3244}
3164 3245
3165/* Close a device interrupt pipe. */ 3246/* Close a device interrupt pipe. */
3166Static void 3247Static void
3167ohci_device_intr_close(usbd_pipe_handle pipe) 3248ohci_device_intr_close(usbd_pipe_handle pipe)
3168{ 3249{
3169 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; 3250 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
3170 ohci_softc_t *sc = pipe->device->bus->hci_private; 3251 ohci_softc_t *sc = pipe->device->bus->hci_private;
3171 int nslots = opipe->u.intr.nslots; 3252 int nslots = opipe->u.intr.nslots;
3172 int pos = opipe->u.intr.pos; 3253 int pos = opipe->u.intr.pos;
3173 int j; 3254 int j;
3174 ohci_soft_ed_t *p, *sed = opipe->sed; 3255 ohci_soft_ed_t *p, *sed = opipe->sed;
3175 int s; 
3176 3256
3177 DPRINTFN(1,("ohci_device_intr_close: pipe=%p nslots=%d pos=%d\n", 3257 DPRINTFN(1,("ohci_device_intr_close: pipe=%p nslots=%d pos=%d\n",
3178 pipe, nslots, pos)); 3258 pipe, nslots, pos));
3179 s = splusb(); 3259 mutex_enter(&sc->sc_lock);
3180 usb_syncmem(&sed->dma, sed->offs, 3260 usb_syncmem(&sed->dma, sed->offs,
3181 sizeof(sed->ed), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 3261 sizeof(sed->ed), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
3182 sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); 3262 sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP);
3183 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), 3263 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags),
3184 sizeof(sed->ed.ed_flags), 3264 sizeof(sed->ed.ed_flags),
3185 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3265 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3186 if ((O32TOH(sed->ed.ed_tailp) & OHCI_HEADMASK) != 3266 if ((O32TOH(sed->ed.ed_tailp) & OHCI_HEADMASK) !=
3187 (O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK)) 3267 (O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK))
3188 usb_delay_ms(&sc->sc_bus, 2); 3268 usb_delay_ms(&sc->sc_bus, 2);
3189 3269
3190 for (p = sc->sc_eds[pos]; p && p->next != sed; p = p->next) 3270 for (p = sc->sc_eds[pos]; p && p->next != sed; p = p->next)
3191 continue; 3271 continue;
3192#ifdef DIAGNOSTIC 3272#ifdef DIAGNOSTIC
3193 if (p == NULL) 3273 if (p == NULL)
3194 panic("ohci_device_intr_close: ED not found"); 3274 panic("ohci_device_intr_close: ED not found");
3195#endif 3275#endif
3196 p->next = sed->next; 3276 p->next = sed->next;
3197 p->ed.ed_nexted = sed->ed.ed_nexted; 3277 p->ed.ed_nexted = sed->ed.ed_nexted;
3198 usb_syncmem(&p->dma, p->offs + offsetof(ohci_ed_t, ed_nexted), 3278 usb_syncmem(&p->dma, p->offs + offsetof(ohci_ed_t, ed_nexted),
3199 sizeof(p->ed.ed_nexted), 3279 sizeof(p->ed.ed_nexted),
3200 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3280 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3201 splx(s); 3281 mutex_exit(&sc->sc_lock);
3202 3282
3203 for (j = 0; j < nslots; j++) 3283 for (j = 0; j < nslots; j++)
3204 --sc->sc_bws[(pos * nslots + j) % OHCI_NO_INTRS]; 3284 --sc->sc_bws[(pos * nslots + j) % OHCI_NO_INTRS];
3205 3285
3206 ohci_free_std(sc, opipe->tail.td); 3286 ohci_free_std(sc, opipe->tail.td);
3207 ohci_free_sed(sc, opipe->sed); 3287 ohci_free_sed(sc, opipe->sed);
3208} 3288}
3209 3289
3210Static usbd_status 3290Static usbd_status
3211ohci_device_setintr(ohci_softc_t *sc, struct ohci_pipe *opipe, int ival) 3291ohci_device_setintr(ohci_softc_t *sc, struct ohci_pipe *opipe, int ival)
3212{ 3292{
3213 int i, j, s, best; 3293 int i, j, best;
3214 u_int npoll, slow, shigh, nslots; 3294 u_int npoll, slow, shigh, nslots;
3215 u_int bestbw, bw; 3295 u_int bestbw, bw;
3216 ohci_soft_ed_t *hsed, *sed = opipe->sed; 3296 ohci_soft_ed_t *hsed, *sed = opipe->sed;
3217 3297
3218 DPRINTFN(2, ("ohci_setintr: pipe=%p\n", opipe)); 3298 DPRINTFN(2, ("ohci_setintr: pipe=%p\n", opipe));
3219 if (ival == 0) { 3299 if (ival == 0) {
3220 printf("ohci_setintr: 0 interval\n"); 3300 printf("ohci_setintr: 0 interval\n");
3221 return (USBD_INVAL); 3301 return (USBD_INVAL);
3222 } 3302 }
3223 3303
3224 npoll = OHCI_NO_INTRS; 3304 npoll = OHCI_NO_INTRS;
3225 while (npoll > ival) 3305 while (npoll > ival)
3226 npoll /= 2; 3306 npoll /= 2;
@@ -3242,63 +3322,66 @@ ohci_device_setintr(ohci_softc_t *sc, st @@ -3242,63 +3322,66 @@ ohci_device_setintr(ohci_softc_t *sc, st
3242 nslots = OHCI_NO_INTRS / npoll; 3322 nslots = OHCI_NO_INTRS / npoll;
3243 for (best = i = slow, bestbw = ~0; i < shigh; i++) { 3323 for (best = i = slow, bestbw = ~0; i < shigh; i++) {
3244 bw = 0; 3324 bw = 0;
3245 for (j = 0; j < nslots; j++) 3325 for (j = 0; j < nslots; j++)
3246 bw += sc->sc_bws[(i * nslots + j) % OHCI_NO_INTRS]; 3326 bw += sc->sc_bws[(i * nslots + j) % OHCI_NO_INTRS];
3247 if (bw < bestbw) { 3327 if (bw < bestbw) {
3248 best = i; 3328 best = i;
3249 bestbw = bw; 3329 bestbw = bw;
3250 } 3330 }
3251 } 3331 }
3252 DPRINTFN(2, ("ohci_setintr: best=%d(%d..%d) bestbw=%d\n", 3332 DPRINTFN(2, ("ohci_setintr: best=%d(%d..%d) bestbw=%d\n",
3253 best, slow, shigh, bestbw)); 3333 best, slow, shigh, bestbw));
3254 3334
3255 s = splusb(); 3335 mutex_enter(&sc->sc_lock);
3256 hsed = sc->sc_eds[best]; 3336 hsed = sc->sc_eds[best];
3257 sed->next = hsed->next; 3337 sed->next = hsed->next;
3258 usb_syncmem(&hsed->dma, hsed->offs + offsetof(ohci_ed_t, ed_flags), 3338 usb_syncmem(&hsed->dma, hsed->offs + offsetof(ohci_ed_t, ed_flags),
3259 sizeof(hsed->ed.ed_flags), 3339 sizeof(hsed->ed.ed_flags),
3260 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 3340 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
3261 sed->ed.ed_nexted = hsed->ed.ed_nexted; 3341 sed->ed.ed_nexted = hsed->ed.ed_nexted;
3262 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), 3342 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags),
3263 sizeof(sed->ed.ed_flags), 3343 sizeof(sed->ed.ed_flags),
3264 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3344 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3265 hsed->next = sed; 3345 hsed->next = sed;
3266 hsed->ed.ed_nexted = HTOO32(sed->physaddr); 3346 hsed->ed.ed_nexted = HTOO32(sed->physaddr);
3267 usb_syncmem(&hsed->dma, hsed->offs + offsetof(ohci_ed_t, ed_flags), 3347 usb_syncmem(&hsed->dma, hsed->offs + offsetof(ohci_ed_t, ed_flags),
3268 sizeof(hsed->ed.ed_flags), 3348 sizeof(hsed->ed.ed_flags),
3269 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3349 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3270 splx(s); 3350 mutex_exit(&sc->sc_lock);
3271 3351
3272 for (j = 0; j < nslots; j++) 3352 for (j = 0; j < nslots; j++)
3273 ++sc->sc_bws[(best * nslots + j) % OHCI_NO_INTRS]; 3353 ++sc->sc_bws[(best * nslots + j) % OHCI_NO_INTRS];
3274 opipe->u.intr.nslots = nslots; 3354 opipe->u.intr.nslots = nslots;
3275 opipe->u.intr.pos = best; 3355 opipe->u.intr.pos = best;
3276 3356
3277 DPRINTFN(5, ("ohci_setintr: returns %p\n", opipe)); 3357 DPRINTFN(5, ("ohci_setintr: returns %p\n", opipe));
3278 return (USBD_NORMAL_COMPLETION); 3358 return (USBD_NORMAL_COMPLETION);
3279} 3359}
3280 3360
3281/***********************/ 3361/***********************/
3282 3362
3283usbd_status 3363usbd_status
3284ohci_device_isoc_transfer(usbd_xfer_handle xfer) 3364ohci_device_isoc_transfer(usbd_xfer_handle xfer)
3285{ 3365{
 3366 ohci_softc_t *sc = xfer->pipe->device->bus->hci_private;
3286 usbd_status err; 3367 usbd_status err;
3287 3368
3288 DPRINTFN(5,("ohci_device_isoc_transfer: xfer=%p\n", xfer)); 3369 DPRINTFN(5,("ohci_device_isoc_transfer: xfer=%p\n", xfer));
3289 3370
3290 /* Put it on our queue, */ 3371 /* Put it on our queue, */
 3372 mutex_enter(&sc->sc_lock);
3291 err = usb_insert_transfer(xfer); 3373 err = usb_insert_transfer(xfer);
 3374 mutex_exit(&sc->sc_lock);
3292 3375
3293 /* bail out on error, */ 3376 /* bail out on error, */
3294 if (err && err != USBD_IN_PROGRESS) 3377 if (err && err != USBD_IN_PROGRESS)
3295 return (err); 3378 return (err);
3296 3379
3297 /* XXX should check inuse here */ 3380 /* XXX should check inuse here */
3298 3381
3299 /* insert into schedule, */ 3382 /* insert into schedule, */
3300 ohci_device_isoc_enter(xfer); 3383 ohci_device_isoc_enter(xfer);
3301 3384
3302 /* and start if the pipe wasn't running */ 3385 /* and start if the pipe wasn't running */
3303 if (!err) 3386 if (!err)
3304 ohci_device_isoc_start(SIMPLEQ_FIRST(&xfer->pipe->queue)); 3387 ohci_device_isoc_start(SIMPLEQ_FIRST(&xfer->pipe->queue));
@@ -3307,27 +3390,26 @@ ohci_device_isoc_transfer(usbd_xfer_hand @@ -3307,27 +3390,26 @@ ohci_device_isoc_transfer(usbd_xfer_hand
3307} 3390}
3308 3391
3309void 3392void
3310ohci_device_isoc_enter(usbd_xfer_handle xfer) 3393ohci_device_isoc_enter(usbd_xfer_handle xfer)
3311{ 3394{
3312 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; 3395 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
3313 usbd_device_handle dev = opipe->pipe.device; 3396 usbd_device_handle dev = opipe->pipe.device;
3314 ohci_softc_t *sc = dev->bus->hci_private; 3397 ohci_softc_t *sc = dev->bus->hci_private;
3315 ohci_soft_ed_t *sed = opipe->sed; 3398 ohci_soft_ed_t *sed = opipe->sed;
3316 struct iso *iso = &opipe->u.iso; 3399 struct iso *iso = &opipe->u.iso;
3317 ohci_soft_itd_t *sitd, *nsitd; 3400 ohci_soft_itd_t *sitd, *nsitd;
3318 ohci_physaddr_t buf, offs, noffs, bp0; 3401 ohci_physaddr_t buf, offs, noffs, bp0;
3319 int i, ncur, nframes; 3402 int i, ncur, nframes;
3320 int s; 
3321 3403
3322 DPRINTFN(1,("ohci_device_isoc_enter: used=%d next=%d xfer=%p " 3404 DPRINTFN(1,("ohci_device_isoc_enter: used=%d next=%d xfer=%p "
3323 "nframes=%d\n", 3405 "nframes=%d\n",
3324 iso->inuse, iso->next, xfer, xfer->nframes)); 3406 iso->inuse, iso->next, xfer, xfer->nframes));
3325 3407
3326 if (sc->sc_dying) 3408 if (sc->sc_dying)
3327 return; 3409 return;
3328 3410
3329 if (iso->next == -1) { 3411 if (iso->next == -1) {
3330 /* Not in use yet, schedule it a few frames ahead. */ 3412 /* Not in use yet, schedule it a few frames ahead. */
3331 iso->next = O32TOH(sc->sc_hcca->hcca_frame_number) + 5; 3413 iso->next = O32TOH(sc->sc_hcca->hcca_frame_number) + 5;
3332 DPRINTFN(2,("ohci_device_isoc_enter: start next=%d\n", 3414 DPRINTFN(2,("ohci_device_isoc_enter: start next=%d\n",
3333 iso->next)); 3415 iso->next));
@@ -3404,153 +3486,154 @@ ohci_device_isoc_enter(usbd_xfer_handle  @@ -3404,153 +3486,154 @@ ohci_device_isoc_enter(usbd_xfer_handle
3404 xfer->actlen = offs; /* XXX pretend we did it all */ 3486 xfer->actlen = offs; /* XXX pretend we did it all */
3405 3487
3406 xfer->status = USBD_IN_PROGRESS; 3488 xfer->status = USBD_IN_PROGRESS;
3407 3489
3408#ifdef OHCI_DEBUG 3490#ifdef OHCI_DEBUG
3409 if (ohcidebug > 5) { 3491 if (ohcidebug > 5) {
3410 DPRINTF(("ohci_device_isoc_enter: frame=%d\n", 3492 DPRINTF(("ohci_device_isoc_enter: frame=%d\n",
3411 O32TOH(sc->sc_hcca->hcca_frame_number))); 3493 O32TOH(sc->sc_hcca->hcca_frame_number)));
3412 ohci_dump_itds(sc, xfer->hcpriv); 3494 ohci_dump_itds(sc, xfer->hcpriv);
3413 ohci_dump_ed(sc, sed); 3495 ohci_dump_ed(sc, sed);
3414 } 3496 }
3415#endif 3497#endif
3416 3498
3417 s = splusb(); 3499 mutex_enter(&sc->sc_lock);
3418 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 3500 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed),
3419 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 3501 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
3420 sed->ed.ed_tailp = HTOO32(nsitd->physaddr); 3502 sed->ed.ed_tailp = HTOO32(nsitd->physaddr);
3421 opipe->tail.itd = nsitd; 3503 opipe->tail.itd = nsitd;
3422 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); 3504 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP);
3423 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), 3505 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags),
3424 sizeof(sed->ed.ed_flags), 3506 sizeof(sed->ed.ed_flags),
3425 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3507 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3426 splx(s); 3508 mutex_exit(&sc->sc_lock);
3427 3509
3428#ifdef OHCI_DEBUG 3510#ifdef OHCI_DEBUG
3429 if (ohcidebug > 5) { 3511 if (ohcidebug > 5) {
3430 delay(150000); 3512 delay(150000);
3431 DPRINTF(("ohci_device_isoc_enter: after frame=%d\n", 3513 DPRINTF(("ohci_device_isoc_enter: after frame=%d\n",
3432 O32TOH(sc->sc_hcca->hcca_frame_number))); 3514 O32TOH(sc->sc_hcca->hcca_frame_number)));
3433 ohci_dump_itds(sc, xfer->hcpriv); 3515 ohci_dump_itds(sc, xfer->hcpriv);
3434 ohci_dump_ed(sc, sed); 3516 ohci_dump_ed(sc, sed);
3435 } 3517 }
3436#endif 3518#endif
3437} 3519}
3438 3520
3439usbd_status 3521usbd_status
3440ohci_device_isoc_start(usbd_xfer_handle xfer) 3522ohci_device_isoc_start(usbd_xfer_handle xfer)
3441{ 3523{
3442 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; 3524 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
3443 ohci_softc_t *sc = opipe->pipe.device->bus->hci_private; 3525 ohci_softc_t *sc = opipe->pipe.device->bus->hci_private;
3444 3526
3445 DPRINTFN(5,("ohci_device_isoc_start: xfer=%p\n", xfer)); 3527 DPRINTFN(5,("ohci_device_isoc_start: xfer=%p\n", xfer));
3446 3528
3447 if (sc->sc_dying) 3529 mutex_enter(&sc->sc_lock);
 3530
 3531 if (sc->sc_dying) {
 3532 mutex_exit(&sc->sc_lock);
3448 return (USBD_IOERROR); 3533 return (USBD_IOERROR);
 3534 }
3449 3535
3450#ifdef DIAGNOSTIC 3536#ifdef DIAGNOSTIC
3451 if (xfer->status != USBD_IN_PROGRESS) 3537 if (xfer->status != USBD_IN_PROGRESS)
3452 printf("ohci_device_isoc_start: not in progress %p\n", xfer); 3538 printf("ohci_device_isoc_start: not in progress %p\n", xfer);
3453#endif 3539#endif
3454 3540
3455 /* XXX anything to do? */ 3541 /* XXX anything to do? */
3456 3542
3457 return (USBD_IN_PROGRESS); 3543 return (USBD_IN_PROGRESS);
3458} 3544}
3459 3545
3460void 3546void
3461ohci_device_isoc_abort(usbd_xfer_handle xfer) 3547ohci_device_isoc_abort(usbd_xfer_handle xfer)
3462{ 3548{
3463 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; 3549 struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
3464 ohci_softc_t *sc = opipe->pipe.device->bus->hci_private; 3550 ohci_softc_t *sc = opipe->pipe.device->bus->hci_private;
3465 ohci_soft_ed_t *sed; 3551 ohci_soft_ed_t *sed;
3466 ohci_soft_itd_t *sitd; 3552 ohci_soft_itd_t *sitd;
3467 int s; 
3468 
3469 s = splusb(); 
3470 3553
3471 DPRINTFN(1,("ohci_device_isoc_abort: xfer=%p\n", xfer)); 3554 DPRINTFN(1,("ohci_device_isoc_abort: xfer=%p\n", xfer));
3472 3555
 3556 KASSERT(mutex_owned(&sc->sc_lock));
 3557
3473 /* Transfer is already done. */ 3558 /* Transfer is already done. */
3474 if (xfer->status != USBD_NOT_STARTED && 3559 if (xfer->status != USBD_NOT_STARTED &&
3475 xfer->status != USBD_IN_PROGRESS) { 3560 xfer->status != USBD_IN_PROGRESS) {
3476 splx(s); 
3477 printf("ohci_device_isoc_abort: early return\n"); 3561 printf("ohci_device_isoc_abort: early return\n");
3478 return; 3562 goto done;
3479 } 3563 }
3480 3564
3481 /* Give xfer the requested abort code. */ 3565 /* Give xfer the requested abort code. */
3482 xfer->status = USBD_CANCELLED; 3566 xfer->status = USBD_CANCELLED;
3483 3567
3484 sed = opipe->sed; 3568 sed = opipe->sed;
3485 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 3569 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed),
3486 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 3570 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
3487 sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); /* force hardware skip */ 3571 sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); /* force hardware skip */
3488 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), 3572 usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags),
3489 sizeof(sed->ed.ed_flags), 3573 sizeof(sed->ed.ed_flags),
3490 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3574 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3491 3575
3492 sitd = xfer->hcpriv; 3576 sitd = xfer->hcpriv;
3493#ifdef DIAGNOSTIC 3577#ifdef DIAGNOSTIC
3494 if (sitd == NULL) { 3578 if (sitd == NULL) {
3495 splx(s); 
3496 printf("ohci_device_isoc_abort: hcpriv==0\n"); 3579 printf("ohci_device_isoc_abort: hcpriv==0\n");
3497 return; 3580 goto done;
3498 } 3581 }
3499#endif 3582#endif
3500 for (; sitd->xfer == xfer; sitd = sitd->nextitd) { 3583 for (; sitd->xfer == xfer; sitd = sitd->nextitd) {
3501#ifdef DIAGNOSTIC 3584#ifdef DIAGNOSTIC
3502 DPRINTFN(1,("abort sets done sitd=%p\n", sitd)); 3585 DPRINTFN(1,("abort sets done sitd=%p\n", sitd));
3503 sitd->isdone = 1; 3586 sitd->isdone = 1;
3504#endif 3587#endif
3505 } 3588 }
3506 3589
3507 splx(s); 3590 mutex_exit(&sc->sc_lock);
3508 3591
3509 usb_delay_ms(&sc->sc_bus, OHCI_ITD_NOFFSET); 3592 usb_delay_ms(&sc->sc_bus, OHCI_ITD_NOFFSET);
3510 3593
3511 s = splusb(); 3594 mutex_enter(&sc->sc_lock);
3512 3595
3513 /* Run callback. */ 3596 /* Run callback. */
3514 usb_transfer_complete(xfer); 3597 usb_transfer_complete(xfer);
3515 3598
3516 sed->ed.ed_headp = HTOO32(sitd->physaddr); /* unlink TDs */ 3599 sed->ed.ed_headp = HTOO32(sitd->physaddr); /* unlink TDs */
3517 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); /* remove hardware skip */ 3600 sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); /* remove hardware skip */
3518 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), 3601 usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed),
3519 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3602 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3520 3603
3521 splx(s); 3604 done:
 3605 mutex_exit(&sc->sc_lock);
3522} 3606}
3523 3607
3524void 3608void
3525ohci_device_isoc_done(usbd_xfer_handle xfer) 3609ohci_device_isoc_done(usbd_xfer_handle xfer)
3526{ 3610{
3527 DPRINTFN(1,("ohci_device_isoc_done: xfer=%p\n", xfer)); 3611 DPRINTFN(1,("ohci_device_isoc_done: xfer=%p\n", xfer));
3528} 3612}
3529 3613
3530usbd_status 3614usbd_status
3531ohci_setup_isoc(usbd_pipe_handle pipe) 3615ohci_setup_isoc(usbd_pipe_handle pipe)
3532{ 3616{
3533 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; 3617 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
3534 ohci_softc_t *sc = pipe->device->bus->hci_private; 3618 ohci_softc_t *sc = pipe->device->bus->hci_private;
3535 struct iso *iso = &opipe->u.iso; 3619 struct iso *iso = &opipe->u.iso;
3536 int s; 
3537 3620
3538 iso->next = -1; 3621 iso->next = -1;
3539 iso->inuse = 0; 3622 iso->inuse = 0;
3540 3623
3541 s = splusb(); 3624 mutex_enter(&sc->sc_lock);
3542 ohci_add_ed(sc, opipe->sed, sc->sc_isoc_head); 3625 ohci_add_ed(sc, opipe->sed, sc->sc_isoc_head);
3543 splx(s); 3626 mutex_exit(&sc->sc_lock);
3544 3627
3545 return (USBD_NORMAL_COMPLETION); 3628 return (USBD_NORMAL_COMPLETION);
3546} 3629}
3547 3630
3548void 3631void
3549ohci_device_isoc_close(usbd_pipe_handle pipe) 3632ohci_device_isoc_close(usbd_pipe_handle pipe)
3550{ 3633{
3551 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; 3634 struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
3552 ohci_softc_t *sc = pipe->device->bus->hci_private; 3635 ohci_softc_t *sc = pipe->device->bus->hci_private;
3553 3636
3554 DPRINTF(("ohci_device_isoc_close: pipe=%p\n", pipe)); 3637 DPRINTF(("ohci_device_isoc_close: pipe=%p\n", pipe));
3555 ohci_close_pipe(pipe, sc->sc_isoc_head); 3638 ohci_close_pipe(pipe, sc->sc_isoc_head);
3556#ifdef DIAGNOSTIC 3639#ifdef DIAGNOSTIC

cvs diff -r1.51 -r1.51.8.1 src/sys/dev/usb/ohcivar.h (expand / switch to unified diff)

--- src/sys/dev/usb/ohcivar.h 2011/05/28 15:47:17 1.51
+++ src/sys/dev/usb/ohcivar.h 2011/12/04 21:02:27 1.51.8.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ohcivar.h,v 1.51 2011/05/28 15:47:17 tsutsui Exp $ */ 1/* $NetBSD: ohcivar.h,v 1.51.8.1 2011/12/04 21:02:27 jmcneill Exp $ */
2/* $FreeBSD: src/sys/dev/usb/ohcivar.h,v 1.13 1999/11/17 22:33:41 n_hibma Exp $ */ 2/* $FreeBSD: src/sys/dev/usb/ohcivar.h,v 1.13 1999/11/17 22:33:41 n_hibma Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 * Copyright (c) 1998 The NetBSD Foundation, Inc.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * This code is derived from software contributed to The NetBSD Foundation 8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Lennart Augustsson (lennart@augustsson.net) at 9 * by Lennart Augustsson (lennart@augustsson.net) at
10 * Carlstedt Research & Technology. 10 * Carlstedt Research & Technology.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
14 * are met: 14 * are met:
@@ -77,51 +77,54 @@ typedef struct ohci_soft_itd { @@ -77,51 +77,54 @@ typedef struct ohci_soft_itd {
77 77
78 78
79#define OHCI_NO_EDS (2*OHCI_NO_INTRS-1) 79#define OHCI_NO_EDS (2*OHCI_NO_INTRS-1)
80 80
81#define OHCI_HASH_SIZE 128 81#define OHCI_HASH_SIZE 128
82 82
83typedef struct ohci_softc { 83typedef struct ohci_softc {
84 device_t sc_dev; 84 device_t sc_dev;
85 struct usbd_bus sc_bus; 85 struct usbd_bus sc_bus;
86 bus_space_tag_t iot; 86 bus_space_tag_t iot;
87 bus_space_handle_t ioh; 87 bus_space_handle_t ioh;
88 bus_size_t sc_size; 88 bus_size_t sc_size;
89 89
 90 kmutex_t sc_lock;
 91 kmutex_t sc_intr_lock;
 92 void *sc_rhsc_si;
 93
90 usb_dma_t sc_hccadma; 94 usb_dma_t sc_hccadma;
91 struct ohci_hcca *sc_hcca; 95 struct ohci_hcca *sc_hcca;
92 ohci_soft_ed_t *sc_eds[OHCI_NO_EDS]; 96 ohci_soft_ed_t *sc_eds[OHCI_NO_EDS];
93 u_int sc_bws[OHCI_NO_INTRS]; 97 u_int sc_bws[OHCI_NO_INTRS];
94 98
95 u_int32_t sc_eintrs; 99 u_int32_t sc_eintrs;
96 ohci_soft_ed_t *sc_isoc_head; 100 ohci_soft_ed_t *sc_isoc_head;
97 ohci_soft_ed_t *sc_ctrl_head; 101 ohci_soft_ed_t *sc_ctrl_head;
98 ohci_soft_ed_t *sc_bulk_head; 102 ohci_soft_ed_t *sc_bulk_head;
99 103
100 LIST_HEAD(, ohci_soft_td) sc_hash_tds[OHCI_HASH_SIZE]; 104 LIST_HEAD(, ohci_soft_td) sc_hash_tds[OHCI_HASH_SIZE];
101 LIST_HEAD(, ohci_soft_itd) sc_hash_itds[OHCI_HASH_SIZE]; 105 LIST_HEAD(, ohci_soft_itd) sc_hash_itds[OHCI_HASH_SIZE];
102 106
103 int sc_noport; 107 int sc_noport;
104 u_int8_t sc_addr; /* device address */ 108 u_int8_t sc_addr; /* device address */
105 u_int8_t sc_conf; /* device configuration */ 109 u_int8_t sc_conf; /* device configuration */
106 110
107 int sc_endian; 111 int sc_endian;
108#define OHCI_LITTLE_ENDIAN 0 /* typical (uninitialized default) */ 112#define OHCI_LITTLE_ENDIAN 0 /* typical (uninitialized default) */
109#define OHCI_BIG_ENDIAN 1 /* big endian OHCI? never seen it */ 113#define OHCI_BIG_ENDIAN 1 /* big endian OHCI? never seen it */
110#define OHCI_HOST_ENDIAN 2 /* if OHCI always matches CPU */ 114#define OHCI_HOST_ENDIAN 2 /* if OHCI always matches CPU */
111 115
112#ifdef USB_USE_SOFTINTR 
113 char sc_softwake; 116 char sc_softwake;
114#endif /* USB_USE_SOFTINTR */ 117 kcondvar_t sc_softwake_cv;
115 118
116 ohci_soft_ed_t *sc_freeeds; 119 ohci_soft_ed_t *sc_freeeds;
117 ohci_soft_td_t *sc_freetds; 120 ohci_soft_td_t *sc_freetds;
118 ohci_soft_itd_t *sc_freeitds; 121 ohci_soft_itd_t *sc_freeitds;
119 122
120 SIMPLEQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */ 123 SIMPLEQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */
121 124
122 usbd_xfer_handle sc_intrxfer; 125 usbd_xfer_handle sc_intrxfer;
123 126
124 char sc_vendor[32]; 127 char sc_vendor[32];
125 int sc_id_vendor; 128 int sc_id_vendor;
126 129
127 u_int32_t sc_control; /* Preserved during suspend/standby */ 130 u_int32_t sc_control; /* Preserved during suspend/standby */