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

Reply via email to