Module Name: src Committed By: mrg Date: Mon Feb 20 02:12:25 UTC 2012
Modified Files: src/sys/dev/usb [jmcneill-usbmp]: ehci.c ohci.c uhci.c ukbd.c usb.c usbdi.c usbdivar.h Log Message: several changes to the MP usb apis, and other misc changes: - usb_transfer_complete()/usb_insert_transfer()/usb_start_next() all must have the thread lock held - (*soft_intr) now is called with the thread lock held unless we are in polling mode. add a usb_soft_intr() to deal with this - XXX usbd_set_polling() api exists to increase/decrease the polling count, but only ukbd uses. everyone else open codes it, but this should probably be changed - (*abort) is now called with the thread lock held - update several comments to not refer to splusb() anymore - add many more asserts - use more c99 struct initialisers To generate a diff of this commit: cvs rdiff -u -r1.181.6.5 -r1.181.6.6 src/sys/dev/usb/ehci.c cvs rdiff -u -r1.218.6.8 -r1.218.6.9 src/sys/dev/usb/ohci.c cvs rdiff -u -r1.240.6.6 -r1.240.6.7 src/sys/dev/usb/uhci.c cvs rdiff -u -r1.113.4.1 -r1.113.4.2 src/sys/dev/usb/ukbd.c cvs rdiff -u -r1.125.6.5 -r1.125.6.6 src/sys/dev/usb/usb.c cvs rdiff -u -r1.134.2.6 -r1.134.2.7 src/sys/dev/usb/usbdi.c cvs rdiff -u -r1.93.8.4 -r1.93.8.5 src/sys/dev/usb/usbdivar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/usb/ehci.c diff -u src/sys/dev/usb/ehci.c:1.181.6.5 src/sys/dev/usb/ehci.c:1.181.6.6 --- src/sys/dev/usb/ehci.c:1.181.6.5 Fri Dec 9 01:52:59 2011 +++ src/sys/dev/usb/ehci.c Mon Feb 20 02:12:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ehci.c,v 1.181.6.5 2011/12/09 01:52:59 mrg Exp $ */ +/* $NetBSD: ehci.c,v 1.181.6.6 2012/02/20 02:12:23 mrg Exp $ */ /* * Copyright (c) 2004-2011 The NetBSD Foundation, Inc. @@ -53,7 +53,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.181.6.5 2011/12/09 01:52:59 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.181.6.6 2012/02/20 02:12:23 mrg Exp $"); #include "ohci.h" #include "uhci.h" @@ -744,11 +744,11 @@ ehci_softintr(void *v) ehci_softc_t *sc = bus->hci_private; struct ehci_xfer *ex, *nextex; + KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); + DPRINTFN(10,("%s: ehci_softintr (%d)\n", device_xname(sc->sc_dev), sc->sc_bus.intr_context)); - mutex_enter(&sc->sc_lock); - sc->sc_bus.intr_context++; /* @@ -765,8 +765,8 @@ ehci_softintr(void *v) /* Schedule a callout to catch any dropped transactions. */ if ((sc->sc_flags & EHCIF_DROPPED_INTR_WORKAROUND) && !TAILQ_EMPTY(&sc->sc_intrhead)) - callout_reset(&(sc->sc_tmo_intrlist), - (hz), (ehci_intrlist_timeout), (sc)); + callout_reset(&sc->sc_tmo_intrlist, + hz, ehci_intrlist_timeout, sc); if (sc->sc_softwake) { sc->sc_softwake = 0; @@ -774,8 +774,6 @@ ehci_softintr(void *v) } sc->sc_bus.intr_context--; - - mutex_exit(&sc->sc_lock); } /* Check for an interrupt. */ @@ -1116,7 +1114,9 @@ ehci_waitintr(ehci_softc_t *sc, usbd_xfe /* Timeout */ DPRINTF(("ehci_waitintr: timeout\n")); xfer->status = USBD_TIMEOUT; + mutex_enter(&sc->sc_lock); usb_transfer_complete(xfer); + mutex_exit(&sc->sc_lock); /* XXX should free TD */ } @@ -1813,7 +1813,7 @@ ehci_open(usbd_pipe_handle pipe) } /* - * Add an ED to the schedule. Called at splusb(). + * Add an ED to the schedule. Called with USB thread lock held. */ Static void ehci_add_qh(ehci_softc_t *sc, ehci_soft_qh_t *sqh, ehci_soft_qh_t *head) @@ -1841,7 +1841,7 @@ ehci_add_qh(ehci_softc_t *sc, ehci_soft_ } /* - * Remove an ED from the schedule. Called at splusb(). + * Remove an ED from the schedule. Called with USB thread lock held. */ Static void ehci_rem_qh(ehci_softc_t *sc, ehci_soft_qh_t *sqh, ehci_soft_qh_t *head) @@ -2600,14 +2600,13 @@ ehci_root_intr_abort(usbd_xfer_handle xf { ehci_softc_t *sc = xfer->pipe->device->bus->hci_private; - mutex_enter(&sc->sc_lock); + KASSERT(mutex_owned(&sc->sc_lock)); if (xfer->pipe->intrxfer == xfer) { DPRINTF(("ehci_root_intr_abort: remove\n")); xfer->pipe->intrxfer = NULL; } xfer->status = USBD_CANCELLED; usb_transfer_complete(xfer); - mutex_exit(&sc->sc_lock); } /* Close the root pipe. */ @@ -3003,21 +3002,19 @@ ehci_abort_xfer(usbd_xfer_handle xfer, u DPRINTF(("ehci_abort_xfer: xfer=%p pipe=%p\n", xfer, epipe)); + KASSERT(mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) { /* If we're dying, just do the software part. */ - mutex_enter(&sc->sc_lock); xfer->status = status; /* make software ignore it */ callout_stop(&xfer->timeout_handle); usb_transfer_complete(xfer); - mutex_exit(&sc->sc_lock); return; } if (xfer->device->bus->intr_context) panic("ehci_abort_xfer: not in process context"); - mutex_enter(&sc->sc_lock); - /* * If an abort is already in progress then just wait for it to * complete and return. @@ -3034,7 +3031,6 @@ ehci_abort_xfer(usbd_xfer_handle xfer, u xfer->hcflags |= UXFER_ABORTWAIT; while (xfer->hcflags & UXFER_ABORTING) cv_wait(&xfer->hccv, &sc->sc_lock); - mutex_exit(&sc->sc_lock); return; } xfer->hcflags |= UXFER_ABORTING; @@ -3129,7 +3125,7 @@ ehci_abort_xfer(usbd_xfer_handle xfer, u cv_broadcast(&xfer->hccv); } - mutex_exit(&sc->sc_lock); + KASSERT(mutex_owned(&sc->sc_lock)); #undef exfer } @@ -3149,30 +3145,28 @@ ehci_abort_isoc_xfer(usbd_xfer_handle xf DPRINTF(("ehci_abort_isoc_xfer: xfer %p pipe %p\n", xfer, epipe)); + KASSERT(mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) { - mutex_enter(&sc->sc_lock); xfer->status = status; callout_stop(&xfer->timeout_handle); usb_transfer_complete(xfer); - mutex_exit(&sc->sc_lock); return; } - mutex_enter(&sc->sc_lock); - if (xfer->hcflags & UXFER_ABORTING) { DPRINTFN(2, ("ehci_abort_isoc_xfer: already aborting\n")); #ifdef DIAGNOSTIC if (status == USBD_TIMEOUT) - printf("ehci_abort_xfer: TIMEOUT while aborting\n"); + printf("ehci_abort_isoc_xfer: TIMEOUT while aborting\n"); #endif xfer->status = status; - DPRINTFN(2, ("ehci_abort_xfer: waiting for abort to finish\n")); + DPRINTFN(2, ("ehci_abort_isoc_xfer: waiting for abort to finish\n")); xfer->hcflags |= UXFER_ABORTWAIT; while (xfer->hcflags & UXFER_ABORTING) - cv_wait(&xfer->hccv, &sc->sc_intr_lock); + cv_wait(&xfer->hccv, &sc->sc_lock); goto done; } xfer->hcflags |= UXFER_ABORTING; @@ -3200,7 +3194,7 @@ ehci_abort_isoc_xfer(usbd_xfer_handle xf sc->sc_softwake = 1; usb_schedsoftintr(&sc->sc_bus); - cv_wait(&sc->sc_softwake_cv, &sc->sc_intr_lock); + cv_wait(&sc->sc_softwake_cv, &sc->sc_lock); #ifdef DIAGNOSTIC exfer->isdone = 1; @@ -3213,7 +3207,7 @@ ehci_abort_isoc_xfer(usbd_xfer_handle xf } done: - mutex_exit(&sc->sc_lock); + KASSERT(mutex_owned(&sc->sc_lock)); return; } @@ -3231,7 +3225,9 @@ ehci_timeout(void *addr) #endif if (sc->sc_dying) { + mutex_enter(&sc->sc_lock); ehci_abort_xfer(&exfer->xfer, USBD_TIMEOUT); + mutex_exit(&sc->sc_lock); return; } @@ -3245,10 +3241,13 @@ Static void ehci_timeout_task(void *addr) { usbd_xfer_handle xfer = addr; + ehci_softc_t *sc = xfer->pipe->device->bus->hci_private; DPRINTF(("ehci_timeout_task: xfer=%p\n", xfer)); + mutex_enter(&sc->sc_lock); ehci_abort_xfer(xfer, USBD_TIMEOUT); + mutex_exit(&sc->sc_lock); } /************************/ @@ -3533,9 +3532,7 @@ ehci_intrlist_timeout(void *arg) ehci_softc_t *sc = arg; DPRINTF(("ehci_intrlist_timeout\n")); - mutex_spin_enter(&sc->sc_intr_lock); usb_schedsoftintr(&sc->sc_bus); - mutex_spin_exit(&sc->sc_intr_lock); } /************************/ @@ -3714,7 +3711,9 @@ ehci_device_setintr(ehci_softc_t *sc, eh sqh->islot = islot; isp = &sc->sc_islots[islot]; + mutex_enter(&sc->sc_lock); ehci_add_qh(sc, sqh, isp->sqh); + mutex_exit(&sc->sc_lock); return (USBD_NORMAL_COMPLETION); } Index: src/sys/dev/usb/ohci.c diff -u src/sys/dev/usb/ohci.c:1.218.6.8 src/sys/dev/usb/ohci.c:1.218.6.9 --- src/sys/dev/usb/ohci.c:1.218.6.8 Fri Dec 9 01:53:00 2011 +++ src/sys/dev/usb/ohci.c Mon Feb 20 02:12:24 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ohci.c,v 1.218.6.8 2011/12/09 01:53:00 mrg Exp $ */ +/* $NetBSD: ohci.c,v 1.218.6.9 2012/02/20 02:12:24 mrg Exp $ */ /* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */ /* @@ -42,7 +42,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.218.6.8 2011/12/09 01:53:00 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.218.6.9 2012/02/20 02:12:24 mrg Exp $"); #include "opt_usb.h" @@ -1285,9 +1285,9 @@ ohci_softintr(void *v) int i, j, actlen, iframes, uedir; ohci_physaddr_t done; - DPRINTFN(10,("ohci_softintr: enter\n")); + KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); - mutex_enter(&sc->sc_lock); + DPRINTFN(10,("ohci_softintr: enter\n")); sc->sc_bus.intr_context++; @@ -1489,7 +1489,6 @@ ohci_softintr(void *v) } sc->sc_bus.intr_context--; - mutex_exit(&sc->sc_lock); DPRINTFN(10,("ohci_softintr: done:\n")); } @@ -1868,7 +1867,7 @@ ohci_device_request(usbd_xfer_handle xfe } /* - * Add an ED to the schedule. Called at splusb(). + * Add an ED to the schedule. Called with USB thread lock held. */ Static void ohci_add_ed(ohci_softc_t *sc, ohci_soft_ed_t *sed, ohci_soft_ed_t *head) @@ -1893,7 +1892,7 @@ ohci_add_ed(ohci_softc_t *sc, ohci_soft_ } /* - * Remove an ED from the schedule. Called at splusb(). + * Remove an ED from the schedule. Called with USB thread lock held. */ Static void ohci_rem_ed(ohci_softc_t *sc, ohci_soft_ed_t *sed, ohci_soft_ed_t *head) @@ -1928,7 +1927,7 @@ ohci_rem_ed(ohci_softc_t *sc, ohci_soft_ */ #define HASH(a) (((a) >> 4) % OHCI_HASH_SIZE) -/* Called at splusb() */ +/* Called with USB thread lock held. */ void ohci_hash_add_td(ohci_softc_t *sc, ohci_soft_td_t *std) { @@ -1939,7 +1938,7 @@ ohci_hash_add_td(ohci_softc_t *sc, ohci_ LIST_INSERT_HEAD(&sc->sc_hash_tds[h], std, hnext); } -/* Called at splusb() */ +/* Called with USB thread lock held. */ void ohci_hash_rem_td(ohci_softc_t *sc, ohci_soft_td_t *std) { @@ -1963,7 +1962,7 @@ ohci_hash_find_td(ohci_softc_t *sc, ohci return (NULL); } -/* Called at splusb() */ +/* Called with USB thread lock held. */ void ohci_hash_add_itd(ohci_softc_t *sc, ohci_soft_itd_t *sitd) { @@ -1977,7 +1976,7 @@ ohci_hash_add_itd(ohci_softc_t *sc, ohci LIST_INSERT_HEAD(&sc->sc_hash_itds[h], sitd, hnext); } -/* Called at splusb() */ +/* Called with USB thread lock held. */ void ohci_hash_rem_itd(ohci_softc_t *sc, ohci_soft_itd_t *sitd) { @@ -2013,7 +2012,9 @@ ohci_timeout(void *addr) DPRINTF(("ohci_timeout: oxfer=%p\n", oxfer)); if (sc->sc_dying) { + mutex_enter(&sc->sc_lock); ohci_abort_xfer(&oxfer->xfer, USBD_TIMEOUT); + mutex_exit(&sc->sc_lock); return; } @@ -2027,10 +2028,13 @@ void ohci_timeout_task(void *addr) { usbd_xfer_handle xfer = addr; + ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; DPRINTF(("ohci_timeout_task: xfer=%p\n", xfer)); + mutex_enter(&sc->sc_lock); ohci_abort_xfer(xfer, USBD_TIMEOUT); + mutex_exit(&sc->sc_lock); } #ifdef OHCI_DEBUG @@ -2309,21 +2313,19 @@ ohci_abort_xfer(usbd_xfer_handle xfer, u DPRINTF(("ohci_abort_xfer: xfer=%p pipe=%p sed=%p\n", xfer, opipe,sed)); + KASSERT(mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) { /* If we're dying, just do the software part. */ - mutex_enter(&sc->sc_lock); xfer->status = status; /* make software ignore it */ callout_halt(&xfer->timeout_handle, &sc->sc_lock); usb_transfer_complete(xfer); - mutex_exit(&sc->sc_lock); return; } if (xfer->device->bus->intr_context || !curproc) panic("ohci_abort_xfer: not in process context"); - mutex_enter(&sc->sc_lock); - /* * If an abort is already in progress then just wait for it to * complete and return. @@ -2432,7 +2434,7 @@ ohci_abort_xfer(usbd_xfer_handle xfer, u cv_broadcast(&xfer->hccv); done: - mutex_exit(&sc->sc_lock); + KASSERT(mutex_owned(&sc->sc_lock)); } /* @@ -2879,14 +2881,14 @@ ohci_root_intr_abort(usbd_xfer_handle xf { ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; + KASSERT(mutex_owned(&sc->sc_lock)); + if (xfer->pipe->intrxfer == xfer) { DPRINTF(("ohci_root_intr_abort: remove\n")); xfer->pipe->intrxfer = NULL; } xfer->status = USBD_CANCELLED; - mutex_enter(&sc->sc_lock); usb_transfer_complete(xfer); - mutex_exit(&sc->sc_lock); } /* Close the root pipe. */ @@ -2953,6 +2955,12 @@ ohci_device_ctrl_start(usbd_xfer_handle Static void ohci_device_ctrl_abort(usbd_xfer_handle xfer) { +#ifdef DIAGNOSTIC + ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; +#endif + + KASSERT(mutex_owned(&sc->sc_lock)); + DPRINTF(("ohci_device_ctrl_abort: xfer=%p\n", xfer)); ohci_abort_xfer(xfer, USBD_CANCELLED); } @@ -3115,6 +3123,12 @@ ohci_device_bulk_start(usbd_xfer_handle Static void ohci_device_bulk_abort(usbd_xfer_handle xfer) { +#ifdef DIAGNOSTIC + ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; +#endif + + KASSERT(mutex_owned(&sc->sc_lock)); + DPRINTF(("ohci_device_bulk_abort: xfer=%p\n", xfer)); ohci_abort_xfer(xfer, USBD_CANCELLED); } @@ -3246,6 +3260,12 @@ ohci_device_intr_start(usbd_xfer_handle Static void ohci_device_intr_abort(usbd_xfer_handle xfer) { +#ifdef DIAGNOSTIC + ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; +#endif + + KASSERT(mutex_owned(&sc->sc_lock)); + if (xfer->pipe->intrxfer == xfer) { DPRINTF(("ohci_device_intr_abort: remove\n")); xfer->pipe->intrxfer = NULL; @@ -3569,7 +3589,7 @@ ohci_device_isoc_abort(usbd_xfer_handle DPRINTFN(1,("ohci_device_isoc_abort: xfer=%p lock=%p\n", xfer, &sc->sc_lock)); - mutex_enter(&sc->sc_lock); + KASSERT(mutex_owned(&sc->sc_lock)); /* Transfer is already done. */ if (xfer->status != USBD_NOT_STARTED && @@ -3603,6 +3623,7 @@ ohci_device_isoc_abort(usbd_xfer_handle #endif } + /* XXXMRG is this ok? */ mutex_exit(&sc->sc_lock); usb_delay_ms(&sc->sc_bus, OHCI_ITD_NOFFSET); @@ -3618,7 +3639,7 @@ ohci_device_isoc_abort(usbd_xfer_handle BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); done: - mutex_exit(&sc->sc_lock); + KASSERT(mutex_owned(&sc->sc_lock)); } void Index: src/sys/dev/usb/uhci.c diff -u src/sys/dev/usb/uhci.c:1.240.6.6 src/sys/dev/usb/uhci.c:1.240.6.7 --- src/sys/dev/usb/uhci.c:1.240.6.6 Fri Dec 9 01:53:00 2011 +++ src/sys/dev/usb/uhci.c Mon Feb 20 02:12:24 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: uhci.c,v 1.240.6.6 2011/12/09 01:53:00 mrg Exp $ */ +/* $NetBSD: uhci.c,v 1.240.6.7 2012/02/20 02:12:24 mrg Exp $ */ /* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */ /* @@ -43,7 +43,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.240.6.6 2011/12/09 01:53:00 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.240.6.7 2012/02/20 02:12:24 mrg Exp $"); #include "opt_usb.h" @@ -1391,11 +1391,11 @@ uhci_softintr(void *v) uhci_softc_t *sc = bus->hci_private; uhci_intr_info_t *ii, *nextii; + KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); + DPRINTFN(10,("%s: uhci_softintr (%d)\n", device_xname(sc->sc_dev), sc->sc_bus.intr_context)); - mutex_enter(&sc->sc_lock); - sc->sc_bus.intr_context++; /* @@ -1420,8 +1420,6 @@ uhci_softintr(void *v) } sc->sc_bus.intr_context--; - - mutex_exit(&sc->sc_lock); } /* Check for an interrupt. */ @@ -1503,16 +1501,19 @@ uhci_check_intr(uhci_softc_t *sc, uhci_i uhci_idone(ii); } -/* Called at splusb() */ +/* Called with USB thread lock held. */ void uhci_idone(uhci_intr_info_t *ii) { usbd_xfer_handle xfer = ii->xfer; struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe; + uhci_softc_t *sc = upipe->pipe.device->bus->hci_private; uhci_soft_td_t *std; u_int32_t status = 0, nstatus; int actlen; + KASSERT(mutex_owned(&sc->sc_lock)); + DPRINTFN(12, ("uhci_idone: ii=%p\n", ii)); #ifdef DIAGNOSTIC { @@ -1632,6 +1633,7 @@ uhci_idone(uhci_intr_info_t *ii) end: usb_transfer_complete(xfer); + KASSERT(mutex_owned(&sc->sc_lock)); DPRINTFN(12, ("uhci_idone: ii=%p done\n", ii)); } @@ -1649,7 +1651,9 @@ uhci_timeout(void *addr) DPRINTF(("uhci_timeout: uxfer=%p\n", uxfer)); if (sc->sc_dying) { + mutex_enter(&sc->sc_lock); uhci_abort_xfer(&uxfer->xfer, USBD_TIMEOUT); + mutex_exit(&sc->sc_lock); return; } @@ -1663,10 +1667,13 @@ void uhci_timeout_task(void *addr) { usbd_xfer_handle xfer = addr; + uhci_softc_t *sc = xfer->pipe->device->bus->hci_private; DPRINTF(("uhci_timeout_task: xfer=%p\n", xfer)); + mutex_enter(&sc->sc_lock); uhci_abort_xfer(xfer, USBD_TIMEOUT); + mutex_exit(&sc->sc_lock); } /* @@ -2104,6 +2111,12 @@ uhci_device_bulk_start(usbd_xfer_handle void uhci_device_bulk_abort(usbd_xfer_handle xfer) { +#ifdef DIAGNOSTIC + uhci_softc_t *sc = xfer->pipe->device->bus->hci_private; +#endif + + KASSERT(mutex_owned(&sc->sc_lock)); + DPRINTF(("uhci_device_bulk_abort:\n")); uhci_abort_xfer(xfer, USBD_CANCELLED); } @@ -2129,21 +2142,19 @@ uhci_abort_xfer(usbd_xfer_handle xfer, u DPRINTFN(1,("uhci_abort_xfer: xfer=%p, status=%d\n", xfer, status)); + KASSERT(mutex_owned(&sc->sc_lock)); + if (sc->sc_dying) { /* If we're dying, just do the software part. */ - mutex_enter(&sc->sc_lock); xfer->status = status; /* make software ignore it */ callout_stop(&xfer->timeout_handle); usb_transfer_complete(xfer); - mutex_exit(&sc->sc_lock); return; } if (xfer->device->bus->intr_context || !curproc) panic("uhci_abort_xfer: not in process context"); - mutex_enter(&sc->sc_lock); - /* * If an abort is already in progress then just wait for it to * complete and return. @@ -2206,7 +2217,7 @@ uhci_abort_xfer(usbd_xfer_handle xfer, u if (wake) cv_broadcast(&xfer->hccv); done: - mutex_exit(&sc->sc_lock); + KASSERT(mutex_owned(&sc->sc_lock)); } /* Close a device bulk pipe. */ @@ -2379,6 +2390,12 @@ uhci_device_intr_start(usbd_xfer_handle void uhci_device_ctrl_abort(usbd_xfer_handle xfer) { +#ifdef DIAGNOSTIC + uhci_softc_t *sc = xfer->pipe->device->bus->hci_private; +#endif + + KASSERT(mutex_owned(&sc->sc_lock)); + DPRINTF(("uhci_device_ctrl_abort:\n")); uhci_abort_xfer(xfer, USBD_CANCELLED); } @@ -2393,6 +2410,12 @@ uhci_device_ctrl_close(usbd_pipe_handle void uhci_device_intr_abort(usbd_xfer_handle xfer) { +#ifdef DIAGNOSTIC + uhci_softc_t *sc = xfer->pipe->device->bus->hci_private; +#endif + + KASSERT(mutex_owned(&sc->sc_lock)); + DPRINTFN(1,("uhci_device_intr_abort: xfer=%p\n", xfer)); if (xfer->pipe->intrxfer == xfer) { DPRINTFN(1,("uhci_device_intr_abort: remove\n")); @@ -2734,12 +2757,11 @@ uhci_device_isoc_abort(usbd_xfer_handle uhci_soft_td_t *std; int i, n, nframes, maxlen, len; - mutex_enter(&sc->sc_lock); + KASSERT(mutex_owned(&sc->sc_lock)); /* Transfer is already done. */ if (xfer->status != USBD_NOT_STARTED && xfer->status != USBD_IN_PROGRESS) { - mutex_exit(&sc->sc_lock); return; } @@ -2781,7 +2803,7 @@ uhci_device_isoc_abort(usbd_xfer_handle /* Run callback and remove from interrupt list. */ usb_transfer_complete(xfer); - mutex_exit(&sc->sc_lock); + KASSERT(mutex_owned(&sc->sc_lock)); } void @@ -3858,6 +3880,8 @@ uhci_root_intr_abort(usbd_xfer_handle xf { uhci_softc_t *sc = xfer->pipe->device->bus->hci_private; + KASSERT(mutex_owned(&sc->sc_lock)); + callout_stop(&sc->sc_poll_handle); sc->sc_intr_xfer = NULL; Index: src/sys/dev/usb/ukbd.c diff -u src/sys/dev/usb/ukbd.c:1.113.4.1 src/sys/dev/usb/ukbd.c:1.113.4.2 --- src/sys/dev/usb/ukbd.c:1.113.4.1 Sat Feb 18 07:35:10 2012 +++ src/sys/dev/usb/ukbd.c Mon Feb 20 02:12:24 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ukbd.c,v 1.113.4.1 2012/02/18 07:35:10 mrg Exp $ */ +/* $NetBSD: ukbd.c,v 1.113.4.2 2012/02/20 02:12:24 mrg Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ukbd.c,v 1.113.4.1 2012/02/18 07:35:10 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ukbd.c,v 1.113.4.2 2012/02/20 02:12:24 mrg Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -321,9 +321,9 @@ Static void ukbd_cnpollc(void *, int); #if defined(__NetBSD__) const struct wskbd_consops ukbd_consops = { - ukbd_cngetc, - ukbd_cnpollc, - NULL, /* bell */ + .getc = ukbd_cngetc, + .pollc = ukbd_cnpollc, + .bell = NULL, }; #endif Index: src/sys/dev/usb/usb.c diff -u src/sys/dev/usb/usb.c:1.125.6.5 src/sys/dev/usb/usb.c:1.125.6.6 --- src/sys/dev/usb/usb.c:1.125.6.5 Fri Dec 9 01:53:00 2011 +++ src/sys/dev/usb/usb.c Mon Feb 20 02:12:24 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: usb.c,v 1.125.6.5 2011/12/09 01:53:00 mrg Exp $ */ +/* $NetBSD: usb.c,v 1.125.6.6 2012/02/20 02:12:24 mrg Exp $ */ /* * Copyright (c) 1998, 2002, 2008 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.125.6.5 2011/12/09 01:53:00 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.125.6.6 2012/02/20 02:12:24 mrg Exp $"); #include "opt_compat_netbsd.h" #include "opt_usb.h" @@ -143,6 +143,7 @@ Static void usb_free_event(struct usb_ev Static void usb_add_event(int, struct usb_event *); Static int usb_get_next_event(struct usb_event *); Static void usb_async_intr(void *); +Static void usb_soft_intr(void *); #ifdef COMPAT_30 Static void usb_copy_old_devinfo(struct usb_device_info_old *, const struct usb_device_info *); @@ -243,7 +244,7 @@ usb_doattach(device_t self) /* XXX we should have our own level */ sc->sc_bus->soft = softint_establish( SOFTINT_NET | (mpsafe ? SOFTINT_MPSAFE : 0), - sc->sc_bus->methods->soft_intr, sc->sc_bus); + usb_soft_intr, sc->sc_bus); if (sc->sc_bus->soft == NULL) { aprint_error("%s: can't register softintr\n", device_xname(self)); @@ -945,10 +946,24 @@ usb_async_intr(void *cookie) mutex_exit(proc_lock); } +Static void +usb_soft_intr(void *arg) +{ + usbd_bus_handle bus = arg; + + if (bus->lock) + mutex_enter(bus->lock); + (*bus->methods->soft_intr)(bus); + if (bus->lock) + mutex_exit(bus->lock); +} + void usb_schedsoftintr(usbd_bus_handle bus) { + DPRINTFN(10,("usb_schedsoftintr: polling=%d\n", bus->use_polling)); + if (bus->use_polling) { bus->methods->soft_intr(bus); } else { Index: src/sys/dev/usb/usbdi.c diff -u src/sys/dev/usb/usbdi.c:1.134.2.6 src/sys/dev/usb/usbdi.c:1.134.2.7 --- src/sys/dev/usb/usbdi.c:1.134.2.6 Sun Feb 19 21:37:12 2012 +++ src/sys/dev/usb/usbdi.c Mon Feb 20 02:12:24 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: usbdi.c,v 1.134.2.6 2012/02/19 21:37:12 mrg Exp $ */ +/* $NetBSD: usbdi.c,v 1.134.2.7 2012/02/20 02:12:24 mrg Exp $ */ /* $FreeBSD: src/sys/dev/usb/usbdi.c,v 1.28 1999/11/17 22:33:49 n_hibma Exp $ */ /* @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.134.2.6 2012/02/19 21:37:12 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.134.2.7 2012/02/20 02:12:24 mrg Exp $"); #include "opt_compat_netbsd.h" #include "opt_usb.h" @@ -759,7 +759,7 @@ usbd_ar_pipe(usbd_pipe_handle pipe) return (USBD_NORMAL_COMPLETION); } -/* Called at splusb() */ +/* Called with USB thread lock held. */ void usb_transfer_complete(usbd_xfer_handle xfer) { @@ -876,6 +876,7 @@ usb_transfer_complete(usbd_xfer_handle x } } +/* Called with USB thread lock held. */ usbd_status usb_insert_transfer(usbd_xfer_handle xfer) { @@ -905,7 +906,7 @@ usb_insert_transfer(usbd_xfer_handle xfe return (err); } -/* Called at splusb() */ +/* Called with USB thread lock held. */ void usbd_start_next(usbd_pipe_handle pipe) { @@ -925,8 +926,6 @@ usbd_start_next(usbd_pipe_handle pipe) } #endif - KASSERT(pipe->device->bus->lock == NULL || mutex_owned(pipe->device->bus->lock)); - /* Get next request in queue. */ xfer = SIMPLEQ_FIRST(&pipe->queue); DPRINTFN(5, ("usbd_start_next: pipe=%p, xfer=%p\n", pipe, xfer)); @@ -944,6 +943,8 @@ usbd_start_next(usbd_pipe_handle pipe) /* XXX do what? */ } } + + KASSERT(pipe->device->bus->lock == NULL || mutex_owned(pipe->device->bus->lock)); } usbd_status @@ -1108,6 +1109,9 @@ usbd_dopoll(usbd_interface_handle iface) iface->device->bus->methods->do_poll(iface->device->bus); } +/* + * XXX use this more??? use_polling it touched manually all over + */ void usbd_set_polling(usbd_device_handle dev, int on) { @@ -1117,7 +1121,12 @@ usbd_set_polling(usbd_device_handle dev, dev->bus->use_polling--; /* Kick the host controller when switching modes */ - dev->bus->methods->soft_intr(dev->bus); + if (dev->bus->lock) + mutex_enter(dev->bus->lock); + (*dev->bus->methods->soft_intr)(dev->bus); + if (dev->bus->lock) + mutex_exit(dev->bus->lock); + } Index: src/sys/dev/usb/usbdivar.h diff -u src/sys/dev/usb/usbdivar.h:1.93.8.4 src/sys/dev/usb/usbdivar.h:1.93.8.5 --- src/sys/dev/usb/usbdivar.h:1.93.8.4 Fri Dec 9 01:53:00 2011 +++ src/sys/dev/usb/usbdivar.h Mon Feb 20 02:12:24 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: usbdivar.h,v 1.93.8.4 2011/12/09 01:53:00 mrg Exp $ */ +/* $NetBSD: usbdivar.h,v 1.93.8.5 2012/02/20 02:12:24 mrg Exp $ */ /* $FreeBSD: src/sys/dev/usb/usbdivar.h,v 1.11 1999/11/17 22:33:51 n_hibma Exp $ */ /* @@ -48,7 +48,7 @@ * BUS METHOD INTR THREAD NOTES * ----------------------- ------- ------- ------------------------- * open_pipe - - might want to take thread lock? - * soft_intr - - intr lock is taken sometimes, thread lock taken often, but nothing demanded? + * soft_intr - x sometimes called with intr lock also held -- perhaps a problem? * do_poll - - might want to take thread lock? * allocm - - * freem - - @@ -60,13 +60,18 @@ * ----------------------- ------- ------- ------------------------- * transfer - - * start - - - * abort - - + * abort - x * close - x * cleartoggle - - * done - x * * The above semantics are likely to change. * + * USB functions known to expect the thread lock taken include: + * usb_transfer_complete() + * usb_insert_transfer() + * usb_start_next() + * */ /* From usb_mem.h */