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 */