Thu Dec 8 02:51:08 2011 UTC ()
- convert usbd_bus_methods{} and usbd_pipe_methods{} to use
  c99 struct initialisers

- move the locks from the pipe to the bus, since we'll need
  access to them from bus-level ops

- remove dead-for-years SPLUSBCHECK and replaced it with
  asserts that the thread lock is held

- begin to document the locking scheme

- convert usbd_*lock_pipe() into real function-like macros


(mrg)
diff -r1.181.6.3 -r1.181.6.4 src/sys/dev/usb/ehci.c
diff -r1.218.6.5 -r1.218.6.6 src/sys/dev/usb/ohci.c
diff -r1.240.6.4 -r1.240.6.5 src/sys/dev/usb/uhci.c
diff -r1.125.6.3 -r1.125.6.4 src/sys/dev/usb/usb.c
diff -r1.180.6.1 -r1.180.6.2 src/sys/dev/usb/usb_subr.c
diff -r1.134.2.1 -r1.134.2.2 src/sys/dev/usb/usbdi.c
diff -r1.93.8.1 -r1.93.8.2 src/sys/dev/usb/usbdivar.h

cvs diff -r1.181.6.3 -r1.181.6.4 src/sys/dev/usb/ehci.c (expand / switch to context diff)
--- src/sys/dev/usb/ehci.c 2011/12/06 02:10:01 1.181.6.3
+++ src/sys/dev/usb/ehci.c 2011/12/08 02:51:07 1.181.6.4
@@ -1,4 +1,4 @@
-/*	$NetBSD: ehci.c,v 1.181.6.3 2011/12/06 02:10:01 mrg Exp $ */
+/*	$NetBSD: ehci.c,v 1.181.6.4 2011/12/08 02:51:07 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.3 2011/12/06 02:10:01 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.181.6.4 2011/12/08 02:51:07 mrg Exp $");
 
 #include "ohci.h"
 #include "uhci.h"
@@ -220,7 +220,8 @@
 Static usbd_status	ehci_device_setintr(ehci_softc_t *, ehci_soft_qh_t *,
 			    int ival);
 
-Static void		ehci_add_qh(ehci_soft_qh_t *, ehci_soft_qh_t *);
+Static void		ehci_add_qh(ehci_softc_t *, ehci_soft_qh_t *,
+				    ehci_soft_qh_t *);
 Static void		ehci_rem_qh(ehci_softc_t *, ehci_soft_qh_t *,
 				    ehci_soft_qh_t *);
 Static void		ehci_set_qh_qtd(ehci_soft_qh_t *, ehci_soft_qtd_t *);
@@ -261,68 +262,68 @@
 #define ehci_active_intr_list(ex) ((ex)->inext.tqe_prev != NULL)
 
 Static const struct usbd_bus_methods ehci_bus_methods = {
-	ehci_open,
-	ehci_softintr,
-	ehci_poll,
-	ehci_allocm,
-	ehci_freem,
-	ehci_allocx,
-	ehci_freex,
-	ehci_get_locks,
+	.open_pipe =	ehci_open,
+	.soft_intr =	ehci_softintr,
+	.do_poll =	ehci_poll,
+	.allocm =	ehci_allocm,
+	.freem =	ehci_freem,
+	.allocx =	ehci_allocx,
+	.freex =	ehci_freex,
+	.get_locks =	ehci_get_locks,
 };
 
 Static const struct usbd_pipe_methods ehci_root_ctrl_methods = {
-	ehci_root_ctrl_transfer,
-	ehci_root_ctrl_start,
-	ehci_root_ctrl_abort,
-	ehci_root_ctrl_close,
-	ehci_noop,
-	ehci_root_ctrl_done,
+	.transfer =	ehci_root_ctrl_transfer,
+	.start =	ehci_root_ctrl_start,
+	.abort =	ehci_root_ctrl_abort,
+	.close =	ehci_root_ctrl_close,
+	.cleartoggle =	ehci_noop,
+	.done =		ehci_root_ctrl_done,
 };
 
 Static const struct usbd_pipe_methods ehci_root_intr_methods = {
-	ehci_root_intr_transfer,
-	ehci_root_intr_start,
-	ehci_root_intr_abort,
-	ehci_root_intr_close,
-	ehci_noop,
-	ehci_root_intr_done,
+	.transfer =	ehci_root_intr_transfer,
+	.start =	ehci_root_intr_start,
+	.abort =	ehci_root_intr_abort,
+	.close =	ehci_root_intr_close,
+	.cleartoggle =	ehci_noop,
+	.done =		ehci_root_intr_done,
 };
 
 Static const struct usbd_pipe_methods ehci_device_ctrl_methods = {
-	ehci_device_ctrl_transfer,
-	ehci_device_ctrl_start,
-	ehci_device_ctrl_abort,
-	ehci_device_ctrl_close,
-	ehci_noop,
-	ehci_device_ctrl_done,
+	.transfer =	ehci_device_ctrl_transfer,
+	.start =	ehci_device_ctrl_start,
+	.abort =	ehci_device_ctrl_abort,
+	.close =	ehci_device_ctrl_close,
+	.cleartoggle =	ehci_noop,
+	.done =		ehci_device_ctrl_done,
 };
 
 Static const struct usbd_pipe_methods ehci_device_intr_methods = {
-	ehci_device_intr_transfer,
-	ehci_device_intr_start,
-	ehci_device_intr_abort,
-	ehci_device_intr_close,
-	ehci_device_clear_toggle,
-	ehci_device_intr_done,
+	.transfer =	ehci_device_intr_transfer,
+	.start =	ehci_device_intr_start,
+	.abort =	ehci_device_intr_abort,
+	.close =	ehci_device_intr_close,
+	.cleartoggle =	ehci_device_clear_toggle,
+	.done =		ehci_device_intr_done,
 };
 
 Static const struct usbd_pipe_methods ehci_device_bulk_methods = {
-	ehci_device_bulk_transfer,
-	ehci_device_bulk_start,
-	ehci_device_bulk_abort,
-	ehci_device_bulk_close,
-	ehci_device_clear_toggle,
-	ehci_device_bulk_done,
+	.transfer =	ehci_device_bulk_transfer,
+	.start =	ehci_device_bulk_start,
+	.abort =	ehci_device_bulk_abort,
+	.close =	ehci_device_bulk_close,
+	.cleartoggle =	ehci_device_clear_toggle,
+	.done =		ehci_device_bulk_done,
 };
 
 Static const struct usbd_pipe_methods ehci_device_isoc_methods = {
-	ehci_device_isoc_transfer,
-	ehci_device_isoc_start,
-	ehci_device_isoc_abort,
-	ehci_device_isoc_close,
-	ehci_noop,
-	ehci_device_isoc_done,
+	.transfer =	ehci_device_isoc_transfer,
+	.start =	ehci_device_isoc_start,
+	.abort =	ehci_device_isoc_abort,
+	.close =	ehci_device_isoc_close,
+	.cleartoggle =	ehci_noop,
+	.done =		ehci_device_isoc_done,
 };
 
 static const uint8_t revbits[EHCI_MAX_POLLRATE] = {
@@ -1753,13 +1754,13 @@
 			goto bad;
 		pipe->methods = &ehci_device_ctrl_methods;
 		mutex_enter(&sc->sc_lock);
-		ehci_add_qh(sqh, sc->sc_async_head);
+		ehci_add_qh(sc, sqh, sc->sc_async_head);
 		mutex_exit(&sc->sc_lock);
 		break;
 	case UE_BULK:
 		pipe->methods = &ehci_device_bulk_methods;
 		mutex_enter(&sc->sc_lock);
-		ehci_add_qh(sqh, sc->sc_async_head);
+		ehci_add_qh(sc, sqh, sc->sc_async_head);
 		mutex_exit(&sc->sc_lock);
 		break;
 	case UE_INTERRUPT:
@@ -1815,10 +1816,11 @@
  * Add an ED to the schedule.  Called at splusb().
  */
 Static void
-ehci_add_qh(ehci_soft_qh_t *sqh, ehci_soft_qh_t *head)
+ehci_add_qh(ehci_softc_t *sc, ehci_soft_qh_t *sqh, ehci_soft_qh_t *head)
 {
-	SPLUSBCHECK;
 
+	KASSERT(mutex_owned(&sc->sc_lock));
+
 	usb_syncmem(&head->dma, head->offs + offsetof(ehci_qh_t, qh_link),
 	    sizeof(head->qh.qh_link), BUS_DMASYNC_POSTWRITE);
 	sqh->next = head->next;
@@ -1846,7 +1848,8 @@
 {
 	ehci_soft_qh_t *p;
 
-	SPLUSBCHECK;
+	KASSERT(mutex_owned(&sc->sc_lock));
+
 	/* XXX */
 	for (p = head; p != NULL && p->next != sqh; p = p->next)
 		;
@@ -3711,7 +3714,7 @@
 
 	sqh->islot = islot;
 	isp = &sc->sc_islots[islot];
-	ehci_add_qh(sqh, isp->sqh);
+	ehci_add_qh(sc, sqh, isp->sqh);
 
 	return (USBD_NORMAL_COMPLETION);
 }

cvs diff -r1.218.6.5 -r1.218.6.6 src/sys/dev/usb/ohci.c (expand / switch to context diff)
--- src/sys/dev/usb/ohci.c 2011/12/07 05:41:53 1.218.6.5
+++ src/sys/dev/usb/ohci.c 2011/12/08 02:51:07 1.218.6.6
@@ -1,4 +1,4 @@
-/*	$NetBSD: ohci.c,v 1.218.6.5 2011/12/07 05:41:53 macallan Exp $	*/
+/*	$NetBSD: ohci.c,v 1.218.6.6 2011/12/08 02:51:07 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.5 2011/12/07 05:41:53 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.218.6.6 2011/12/08 02:51:07 mrg Exp $");
 
 #include "opt_usb.h"
 
@@ -120,7 +120,8 @@
 Static void		ohci_add_ed(ohci_softc_t *, ohci_soft_ed_t *,
 			    ohci_soft_ed_t *);
 
-Static void		ohci_rem_ed(ohci_soft_ed_t *, ohci_soft_ed_t *);
+Static void		ohci_rem_ed(ohci_softc_t *, ohci_soft_ed_t *,
+				    ohci_soft_ed_t *);
 Static void		ohci_hash_add_td(ohci_softc_t *, ohci_soft_td_t *);
 Static void		ohci_hash_rem_td(ohci_softc_t *, ohci_soft_td_t *);
 Static ohci_soft_td_t  *ohci_hash_find_td(ohci_softc_t *, ohci_physaddr_t);
@@ -271,68 +272,68 @@
 #define OHCI_INTR_ENDPT 1
 
 Static const struct usbd_bus_methods ohci_bus_methods = {
-	ohci_open,
-	ohci_softintr,
-	ohci_poll,
-	ohci_allocm,
-	ohci_freem,
-	ohci_allocx,
-	ohci_freex,
-	ohci_get_locks,
+	.open_pipe =	ohci_open,
+	.soft_intr =	ohci_softintr,
+	.do_poll =	ohci_poll,
+	.allocm =	ohci_allocm,
+	.freem =	ohci_freem,
+	.allocx =	ohci_allocx,
+	.freex =	ohci_freex,
+	.get_locks =	ohci_get_locks,
 };
 
 Static const struct usbd_pipe_methods ohci_root_ctrl_methods = {
-	ohci_root_ctrl_transfer,
-	ohci_root_ctrl_start,
-	ohci_root_ctrl_abort,
-	ohci_root_ctrl_close,
-	ohci_noop,
-	ohci_root_ctrl_done,
+	.transfer =	ohci_root_ctrl_transfer,
+	.start =	ohci_root_ctrl_start,
+	.abort =	ohci_root_ctrl_abort,
+	.close =	ohci_root_ctrl_close,
+	.cleartoggle =	ohci_noop,
+	.done =		ohci_root_ctrl_done,
 };
 
 Static const struct usbd_pipe_methods ohci_root_intr_methods = {
-	ohci_root_intr_transfer,
-	ohci_root_intr_start,
-	ohci_root_intr_abort,
-	ohci_root_intr_close,
-	ohci_noop,
-	ohci_root_intr_done,
+	.transfer =	ohci_root_intr_transfer,
+	.start =	ohci_root_intr_start,
+	.abort =	ohci_root_intr_abort,
+	.close =	ohci_root_intr_close,
+	.cleartoggle =	ohci_noop,
+	.done =		ohci_root_intr_done,
 };
 
 Static const struct usbd_pipe_methods ohci_device_ctrl_methods = {
-	ohci_device_ctrl_transfer,
-	ohci_device_ctrl_start,
-	ohci_device_ctrl_abort,
-	ohci_device_ctrl_close,
-	ohci_noop,
-	ohci_device_ctrl_done,
+	.transfer =	ohci_device_ctrl_transfer,
+	.start =	ohci_device_ctrl_start,
+	.abort =	ohci_device_ctrl_abort,
+	.close =	ohci_device_ctrl_close,
+	.cleartoggle =	ohci_noop,
+	.done =		ohci_device_ctrl_done,
 };
 
 Static const struct usbd_pipe_methods ohci_device_intr_methods = {
-	ohci_device_intr_transfer,
-	ohci_device_intr_start,
-	ohci_device_intr_abort,
-	ohci_device_intr_close,
-	ohci_device_clear_toggle,
-	ohci_device_intr_done,
+	.transfer =	ohci_device_intr_transfer,
+	.start =	ohci_device_intr_start,
+	.abort =	ohci_device_intr_abort,
+	.close =	ohci_device_intr_close,
+	.cleartoggle =	ohci_device_clear_toggle,
+	.done =		ohci_device_intr_done,
 };
 
 Static const struct usbd_pipe_methods ohci_device_bulk_methods = {
-	ohci_device_bulk_transfer,
-	ohci_device_bulk_start,
-	ohci_device_bulk_abort,
-	ohci_device_bulk_close,
-	ohci_device_clear_toggle,
-	ohci_device_bulk_done,
+	.transfer =	ohci_device_bulk_transfer,
+	.start =	ohci_device_bulk_start,
+	.abort =	ohci_device_bulk_abort,
+	.close =	ohci_device_bulk_close,
+	.cleartoggle =	ohci_device_clear_toggle,
+	.done =		ohci_device_bulk_done,
 };
 
 Static const struct usbd_pipe_methods ohci_device_isoc_methods = {
-	ohci_device_isoc_transfer,
-	ohci_device_isoc_start,
-	ohci_device_isoc_abort,
-	ohci_device_isoc_close,
-	ohci_noop,
-	ohci_device_isoc_done,
+	.transfer =	ohci_device_isoc_transfer,
+	.start =	ohci_device_isoc_start,
+	.abort =	ohci_device_isoc_abort,
+	.close =	ohci_device_isoc_close,
+	.cleartoggle =	ohci_noop,
+	.done =		ohci_device_isoc_done,
 };
 
 int
@@ -1869,12 +1870,13 @@
 /*
  * Add an ED to the schedule.  Called at splusb().
  */
-void
+Static void
 ohci_add_ed(ohci_softc_t *sc, ohci_soft_ed_t *sed, ohci_soft_ed_t *head)
 {
 	DPRINTFN(8,("ohci_add_ed: sed=%p head=%p\n", sed, head));
 
-	SPLUSBCHECK;
+	KASSERT(mutex_owned(&sc->sc_lock));
+
 	usb_syncmem(&head->dma, head->offs + offsetof(ohci_ed_t, ed_nexted),
 	    sizeof(head->ed.ed_nexted),
 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
@@ -1893,12 +1895,12 @@
 /*
  * Remove an ED from the schedule.  Called at splusb().
  */
-void
-ohci_rem_ed(ohci_soft_ed_t *sed, ohci_soft_ed_t *head)
+Static void
+ohci_rem_ed(ohci_softc_t *sc, ohci_soft_ed_t *sed, ohci_soft_ed_t *head)
 {
 	ohci_soft_ed_t *p;
 
-	SPLUSBCHECK;
+	KASSERT(mutex_owned(&sc->sc_lock));
 
 	/* XXX */
 	for (p = head; p != NULL && p->next != sed; p = p->next)
@@ -1932,7 +1934,7 @@
 {
 	int h = HASH(std->physaddr);
 
-	SPLUSBCHECK;
+	KASSERT(mutex_owned(&sc->sc_lock));
 
 	LIST_INSERT_HEAD(&sc->sc_hash_tds[h], std, hnext);
 }
@@ -1941,8 +1943,9 @@
 void
 ohci_hash_rem_td(ohci_softc_t *sc, ohci_soft_td_t *std)
 {
-	SPLUSBCHECK;
 
+	KASSERT(mutex_owned(&sc->sc_lock));
+
 	LIST_REMOVE(std, hnext);
 }
 
@@ -1966,7 +1969,7 @@
 {
 	int h = HASH(sitd->physaddr);
 
-	SPLUSBCHECK;
+	KASSERT(mutex_owned(&sc->sc_lock));
 
 	DPRINTFN(10,("ohci_hash_add_itd: sitd=%p physaddr=0x%08lx\n",
 		    sitd, (u_long)sitd->physaddr));
@@ -1978,7 +1981,7 @@
 void
 ohci_hash_rem_itd(ohci_softc_t *sc, ohci_soft_itd_t *sitd)
 {
-	SPLUSBCHECK;
+	KASSERT(mutex_owned(&sc->sc_lock));
 
 	DPRINTFN(10,("ohci_hash_rem_itd: sitd=%p physaddr=0x%08lx\n",
 		    sitd, (u_long)sitd->physaddr));
@@ -2271,7 +2274,7 @@
 			printf("ohci_close_pipe: pipe still not empty\n");
 	}
 #endif
-	ohci_rem_ed(sed, head);
+	ohci_rem_ed(sc, sed, head);
 	/* Make sure the host controller is not touching this ED */
 	usb_delay_ms(&sc->sc_bus, 1);
 	pipe->endpoint->datatoggle =

cvs diff -r1.240.6.4 -r1.240.6.5 src/sys/dev/usb/uhci.c (expand / switch to context diff)
--- src/sys/dev/usb/uhci.c 2011/12/06 05:40:02 1.240.6.4
+++ src/sys/dev/usb/uhci.c 2011/12/08 02:51:08 1.240.6.5
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhci.c,v 1.240.6.4 2011/12/06 05:40:02 mrg Exp $	*/
+/*	$NetBSD: uhci.c,v 1.240.6.5 2011/12/08 02:51:08 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.4 2011/12/06 05:40:02 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.240.6.5 2011/12/08 02:51:08 mrg Exp $");
 
 #include "opt_usb.h"
 
@@ -284,68 +284,68 @@
 #define UHCI_INTR_ENDPT 1
 
 const struct usbd_bus_methods uhci_bus_methods = {
-	uhci_open,
-	uhci_softintr,
-	uhci_poll,
-	uhci_allocm,
-	uhci_freem,
-	uhci_allocx,
-	uhci_freex,
-	uhci_get_locks,
+	.open_pipe =	uhci_open,
+	.soft_intr =	uhci_softintr,
+	.do_poll =	uhci_poll,
+	.allocm =	uhci_allocm,
+	.freem =	uhci_freem,
+	.allocx =	uhci_allocx,
+	.freex =	uhci_freex,
+	.get_locks =	uhci_get_locks,
 };
 
 const struct usbd_pipe_methods uhci_root_ctrl_methods = {
-	uhci_root_ctrl_transfer,
-	uhci_root_ctrl_start,
-	uhci_root_ctrl_abort,
-	uhci_root_ctrl_close,
-	uhci_noop,
-	uhci_root_ctrl_done,
+	.transfer =	uhci_root_ctrl_transfer,
+	.start =	uhci_root_ctrl_start,
+	.abort =	uhci_root_ctrl_abort,
+	.close =	uhci_root_ctrl_close,
+	.cleartoggle =	uhci_noop,
+	.done =		uhci_root_ctrl_done,
 };
 
 const struct usbd_pipe_methods uhci_root_intr_methods = {
-	uhci_root_intr_transfer,
-	uhci_root_intr_start,
-	uhci_root_intr_abort,
-	uhci_root_intr_close,
-	uhci_noop,
-	uhci_root_intr_done,
+	.transfer =	uhci_root_intr_transfer,
+	.start =	uhci_root_intr_start,
+	.abort =	uhci_root_intr_abort,
+	.close =	uhci_root_intr_close,
+	.cleartoggle =	uhci_noop,
+	.done =		uhci_root_intr_done,
 };
 
 const struct usbd_pipe_methods uhci_device_ctrl_methods = {
-	uhci_device_ctrl_transfer,
-	uhci_device_ctrl_start,
-	uhci_device_ctrl_abort,
-	uhci_device_ctrl_close,
-	uhci_noop,
-	uhci_device_ctrl_done,
+	.transfer =	uhci_device_ctrl_transfer,
+	.start =	uhci_device_ctrl_start,
+	.abort =	uhci_device_ctrl_abort,
+	.close =	uhci_device_ctrl_close,
+	.cleartoggle =	uhci_noop,
+	.done =		uhci_device_ctrl_done,
 };
 
 const struct usbd_pipe_methods uhci_device_intr_methods = {
-	uhci_device_intr_transfer,
-	uhci_device_intr_start,
-	uhci_device_intr_abort,
-	uhci_device_intr_close,
-	uhci_device_clear_toggle,
-	uhci_device_intr_done,
+	.transfer =	uhci_device_intr_transfer,
+	.start =	uhci_device_intr_start,
+	.abort =	uhci_device_intr_abort,
+	.close =	uhci_device_intr_close,
+	.cleartoggle =	uhci_device_clear_toggle,
+	.done =		uhci_device_intr_done,
 };
 
 const struct usbd_pipe_methods uhci_device_bulk_methods = {
-	uhci_device_bulk_transfer,
-	uhci_device_bulk_start,
-	uhci_device_bulk_abort,
-	uhci_device_bulk_close,
-	uhci_device_clear_toggle,
-	uhci_device_bulk_done,
+	.transfer =	uhci_device_bulk_transfer,
+	.start =	uhci_device_bulk_start,
+	.abort =	uhci_device_bulk_abort,
+	.close =	uhci_device_bulk_close,
+	.cleartoggle =	uhci_device_clear_toggle,
+	.done =		uhci_device_bulk_done,
 };
 
 const struct usbd_pipe_methods uhci_device_isoc_methods = {
-	uhci_device_isoc_transfer,
-	uhci_device_isoc_start,
-	uhci_device_isoc_abort,
-	uhci_device_isoc_close,
-	uhci_noop,
-	uhci_device_isoc_done,
+	.transfer =	uhci_device_isoc_transfer,
+	.start =	uhci_device_isoc_start,
+	.abort =	uhci_device_isoc_abort,
+	.close =	uhci_device_isoc_close,
+	.cleartoggle =	uhci_noop,
+	.done =		uhci_device_isoc_done,
 };
 
 #define uhci_add_intr_info(sc, ii) \
@@ -1097,7 +1097,7 @@
 {
 	uhci_soft_qh_t *eqh;
 
-	SPLUSBCHECK;
+	KASSERT(mutex_owned(&sc->sc_lock));
 
 	DPRINTFN(10, ("uhci_add_ctrl: sqh=%p\n", sqh));
 	eqh = sc->sc_hctl_end;
@@ -1124,7 +1124,7 @@
 {
 	uhci_soft_qh_t *pqh;
 
-	SPLUSBCHECK;
+	KASSERT(mutex_owned(&sc->sc_lock));
 
 	DPRINTFN(10, ("uhci_remove_hs_ctrl: sqh=%p\n", sqh));
 #ifdef UHCI_CTL_LOOP
@@ -1174,7 +1174,7 @@
 {
 	uhci_soft_qh_t *eqh;
 
-	SPLUSBCHECK;
+	KASSERT(mutex_owned(&sc->sc_lock));
 
 	DPRINTFN(10, ("uhci_add_ls_ctrl: sqh=%p\n", sqh));
 	eqh = sc->sc_lctl_end;
@@ -1197,7 +1197,7 @@
 {
 	uhci_soft_qh_t *pqh;
 
-	SPLUSBCHECK;
+	KASSERT(mutex_owned(&sc->sc_lock));
 
 	DPRINTFN(10, ("uhci_remove_ls_ctrl: sqh=%p\n", sqh));
 	/* See comment in uhci_remove_hs_ctrl() */
@@ -1231,7 +1231,7 @@
 {
 	uhci_soft_qh_t *eqh;
 
-	SPLUSBCHECK;
+	KASSERT(mutex_owned(&sc->sc_lock));
 
 	DPRINTFN(10, ("uhci_add_bulk: sqh=%p\n", sqh));
 	eqh = sc->sc_bulk_end;
@@ -1255,7 +1255,7 @@
 {
 	uhci_soft_qh_t *pqh;
 
-	SPLUSBCHECK;
+	KASSERT(mutex_owned(&sc->sc_lock));
 
 	DPRINTFN(10, ("uhci_remove_bulk: sqh=%p\n", sqh));
 	uhci_rem_loop(sc);

cvs diff -r1.125.6.3 -r1.125.6.4 src/sys/dev/usb/usb.c (expand / switch to context diff)
--- src/sys/dev/usb/usb.c 2011/12/07 22:52:17 1.125.6.3
+++ src/sys/dev/usb/usb.c 2011/12/08 02:51:08 1.125.6.4
@@ -1,4 +1,4 @@
-/*	$NetBSD: usb.c,v 1.125.6.3 2011/12/07 22:52:17 mrg Exp $	*/
+/*	$NetBSD: usb.c,v 1.125.6.4 2011/12/08 02:51:08 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.3 2011/12/07 22:52:17 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.125.6.4 2011/12/08 02:51:08 mrg Exp $");
 
 #include "opt_compat_netbsd.h"
 #include "opt_usb.h"
@@ -224,6 +224,13 @@
 		break;
 	default:
 		panic("usb_doattach");
+	}
+
+	if (mpsafe) {
+		sc->sc_bus->methods->get_locks(sc->sc_bus,
+		    &sc->sc_bus->intr_lock, &sc->sc_bus->lock);
+	} else {
+		sc->sc_bus->intr_lock = sc->sc_bus->lock = NULL;
 	}
 
 	ue = usb_alloc_event();

cvs diff -r1.180.6.1 -r1.180.6.2 src/sys/dev/usb/usb_subr.c (expand / switch to context diff)
--- src/sys/dev/usb/usb_subr.c 2011/12/04 13:23:17 1.180.6.1
+++ src/sys/dev/usb/usb_subr.c 2011/12/08 02:51:08 1.180.6.2
@@ -1,4 +1,4 @@
-/*	$NetBSD: usb_subr.c,v 1.180.6.1 2011/12/04 13:23:17 jmcneill Exp $	*/
+/*	$NetBSD: usb_subr.c,v 1.180.6.2 2011/12/08 02:51:08 mrg Exp $	*/
 /*	$FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $	*/
 
 /*
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.180.6.1 2011/12/04 13:23:17 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.180.6.2 2011/12/08 02:51:08 mrg Exp $");
 
 #include "opt_compat_netbsd.h"
 #include "opt_usbverbose.h"
@@ -750,11 +750,6 @@
 			 ep->edesc->bEndpointAddress, usbd_errstr(err)));
 		free(p, M_USB);
 		return (err);
-	}
-	if (dev->bus->methods->get_locks) {
-		dev->bus->methods->get_locks(dev->bus, &p->intr_lock, &p->lock);
-	} else {
-		p->intr_lock = p->lock = NULL;
 	}
 	*pipe = p;
 	return (USBD_NORMAL_COMPLETION);

cvs diff -r1.134.2.1 -r1.134.2.2 src/sys/dev/usb/usbdi.c (expand / switch to context diff)
--- src/sys/dev/usb/usbdi.c 2011/12/04 13:23:17 1.134.2.1
+++ src/sys/dev/usb/usbdi.c 2011/12/08 02:51:08 1.134.2.2
@@ -1,4 +1,4 @@
-/*	$NetBSD: usbdi.c,v 1.134.2.1 2011/12/04 13:23:17 jmcneill Exp $	*/
+/*	$NetBSD: usbdi.c,v 1.134.2.2 2011/12/08 02:51:08 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.1 2011/12/04 13:23:17 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.134.2.2 2011/12/08 02:51:08 mrg Exp $");
 
 #include "opt_compat_netbsd.h"
 #include "opt_usb.h"
@@ -310,17 +310,17 @@
 	/* Sync transfer, wait for completion. */
 	if (err != USBD_IN_PROGRESS)
 		return (err);
-	usbd_lock(pipe->lock);
+	usbd_lock_pipe(pipe);
 	if (!xfer->done) {
 		if (pipe->device->bus->use_polling)
 			panic("usbd_transfer: not done");
-		if (pipe->lock) {
-			cv_wait(&xfer->cv, pipe->lock);
+		if (pipe->device->bus->lock) {
+			cv_wait(&xfer->cv, pipe->device->bus->lock);
 		} else {
 			tsleep(xfer, PRIBIO, "usbsyn", 0);
 		}
 	}
-	usbd_unlock(pipe->lock);
+	usbd_unlock_pipe(pipe);
 	return (xfer->status);
 }
 
@@ -537,9 +537,9 @@
 		return (USBD_NORMAL_COMPLETION);
 	}
 #endif
-	usbd_lock(pipe->lock);
+	usbd_lock_pipe(pipe);
 	err = usbd_ar_pipe(pipe);
-	usbd_unlock(pipe->lock);
+	usbd_unlock_pipe(pipe);
 	if (pipe->intrxfer != intrxfer)
 		usbd_free_xfer(intrxfer);
 	return (err);
@@ -727,8 +727,7 @@
 {
 	usbd_xfer_handle xfer;
 
-	SPLUSBCHECK;
-	KASSERT(pipe->lock == NULL || mutex_owned(pipe->lock));
+	KASSERT(pipe->device->bus->lock == NULL || mutex_owned(pipe->device->bus->lock));
 
 	DPRINTFN(2,("usbd_ar_pipe: pipe=%p\n", pipe));
 #ifdef USB_DEBUG
@@ -741,11 +740,11 @@
 		DPRINTFN(2,("usbd_ar_pipe: pipe=%p xfer=%p (methods=%p)\n",
 			    pipe, xfer, pipe->methods));
 		/* Make the HC abort it (and invoke the callback). */
-		if (pipe->lock)
-			mutex_exit(pipe->lock);
+		if (pipe->device->bus->lock)
+			mutex_exit(pipe->device->bus->lock);
 		pipe->methods->abort(xfer);
-		if (pipe->lock)
-			mutex_enter(pipe->lock);
+		if (pipe->device->bus->lock)
+			mutex_enter(pipe->device->bus->lock);
 		/* XXX only for non-0 usbd_clear_endpoint_stall(pipe); */
 	}
 	pipe->aborting = 0;
@@ -763,12 +762,11 @@
 	    xfer->status == USBD_TIMEOUT;
 	int repeat, polling;
 
-	SPLUSBCHECK;
 
 	DPRINTFN(5, ("usb_transfer_complete: pipe=%p xfer=%p status=%d "
 		     "actlen=%d\n", pipe, xfer, xfer->status, xfer->actlen));
 
-	KASSERT(pipe->lock == NULL || mutex_owned(pipe->lock));
+	KASSERT(pipe->device->bus->lock == NULL || mutex_owned(pipe->device->bus->lock));
 
 #ifdef DIAGNOSTIC
 	if (xfer->busy_free != XFER_ONQU) {
@@ -837,22 +835,26 @@
 
 	if (repeat) {
 		if (xfer->callback) {
-			if (pipe->lock) mutex_exit(pipe->lock);
+			if (pipe->device->bus->lock)
+				mutex_exit(pipe->device->bus->lock);
 			xfer->callback(xfer, xfer->priv, xfer->status);
-			if (pipe->lock) mutex_enter(pipe->lock);
+			if (pipe->device->bus->lock)
+				mutex_enter(pipe->device->bus->lock);
 		}
 		pipe->methods->done(xfer);
 	} else {
 		pipe->methods->done(xfer);
 		if (xfer->callback) {
-			if (pipe->lock) mutex_exit(pipe->lock);
+			if (pipe->device->bus->lock)
+				mutex_exit(pipe->device->bus->lock);
 			xfer->callback(xfer, xfer->priv, xfer->status);
-			if (pipe->lock) mutex_enter(pipe->lock);
+			if (pipe->device->bus->lock)
+				mutex_enter(pipe->device->bus->lock);
 		}
 	}
 
 	if (sync && !polling) {
-		if (pipe->lock) {
+		if (pipe->device->bus->lock) {
 			cv_broadcast(&xfer->cv);
 		} else {
 			wakeup(xfer);
@@ -878,7 +880,7 @@
 	DPRINTFN(5,("usb_insert_transfer: pipe=%p running=%d timeout=%d\n",
 		    pipe, pipe->running, xfer->timeout));
 
-	KASSERT(pipe->lock == NULL || mutex_owned(pipe->lock));
+	KASSERT(pipe->device->bus->lock == NULL || mutex_owned(pipe->device->bus->lock));
 
 #ifdef DIAGNOSTIC
 	if (xfer->busy_free != XFER_BUSY) {
@@ -907,7 +909,7 @@
 	usbd_xfer_handle xfer;
 	usbd_status err;
 
-	SPLUSBCHECK;
+	KASSERT(pipe->device->bus->lock == NULL || mutex_owned(pipe->device->bus->lock));
 
 #ifdef DIAGNOSTIC
 	if (pipe == NULL) {
@@ -920,7 +922,7 @@
 	}
 #endif
 
-	KASSERT(pipe->lock == NULL || mutex_owned(pipe->lock));
+	KASSERT(pipe->device->bus->lock == NULL || mutex_owned(pipe->device->bus->lock));
 
 	/* Get next request in queue. */
 	xfer = SIMPLEQ_FIRST(&pipe->queue);
@@ -928,11 +930,11 @@
 	if (xfer == NULL) {
 		pipe->running = 0;
 	} else {
-		if (pipe->lock)
-			mutex_exit(pipe->lock);
+		if (pipe->device->bus->lock)
+			mutex_exit(pipe->device->bus->lock);
 		err = pipe->methods->start(xfer);
-		if (pipe->lock)
-			mutex_enter(pipe->lock);
+		if (pipe->device->bus->lock)
+			mutex_enter(pipe->device->bus->lock);
 		if (err != USBD_IN_PROGRESS) {
 			printf("usbd_start_next: error=%d\n", err);
 			pipe->running = 0;

cvs diff -r1.93.8.1 -r1.93.8.2 src/sys/dev/usb/usbdivar.h (expand / switch to context diff)
--- src/sys/dev/usb/usbdivar.h 2011/12/04 13:23:17 1.93.8.1
+++ src/sys/dev/usb/usbdivar.h 2011/12/08 02:51:08 1.93.8.2
@@ -1,4 +1,4 @@
-/*	$NetBSD: usbdivar.h,v 1.93.8.1 2011/12/04 13:23:17 jmcneill Exp $	*/
+/*	$NetBSD: usbdivar.h,v 1.93.8.2 2011/12/08 02:51:08 mrg Exp $	*/
 /*	$FreeBSD: src/sys/dev/usb/usbdivar.h,v 1.11 1999/11/17 22:33:51 n_hibma Exp $	*/
 
 /*
@@ -34,6 +34,41 @@
 #include <sys/callout.h>
 #include <sys/mutex.h>
 
+/*
+ * Discussion about locking in the USB code:
+ *
+ * There are two locks presented by the host controller: the interrupt lock
+ * and the thread lock.  The interrupt lock, either a spin or adaptive mutex,
+ * manages hardware state and anything else touched in an interrupt context.
+ * The thread lock has everything else.  
+ *
+ * List of hardware interface methods, and which locks are held when each
+ * is called by this module:
+ *
+ *	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?
+ *	do_poll			-	-	might want to take thread lock?
+ *	allocm			-	-
+ *	freem			-	-
+ *	allocx			-	-
+ *	freex			-	-
+ *	get_locks 		-	-	Called at attach time
+ *
+ *	PIPE METHOD		INTR	THREAD  NOTES
+ *	----------------------- ------- -------	-------------------------
+ *	transfer		-	-
+ *	start			-	-
+ *	abort			-	-
+ *	close			-	-
+ *	cleartoggle		-	-
+ *	done			-	x
+ *
+ * The above semantics are likely to change.
+ * 
+ */
+
 /* From usb_mem.h */
 struct usb_dma_block;
 typedef struct {
@@ -107,7 +142,9 @@
 	const struct usbd_bus_methods *methods;
 	u_int32_t		pipe_size; /* size of a pipe struct */
 	/* Filled by usb driver */
-	struct usbd_device     *root_hub;
+	kmutex_t		*intr_lock;
+	kmutex_t		*lock;
+	struct usbd_device	*root_hub;
 	usbd_device_handle	devices[USB_MAX_DEVICES];
 	char			needs_explore;/* a hub a signalled a change */
 	char			use_polling;
@@ -178,9 +215,6 @@
 	char			repeat;
 	int			interval;
 
-	kmutex_t		*intr_lock;
-	kmutex_t		*lock;
-
 	/* Filled by HC driver. */
 	const struct usbd_pipe_methods *methods;
 };
@@ -267,19 +301,18 @@
 void		usb_needs_reattach(usbd_device_handle);
 void		usb_schedsoftintr(struct usbd_bus *);
 
-#define usbd_lock(m)	if (m) { s = -1; mutex_enter(m); } else s = splusb()
-#define usbd_unlock(m)	if (m) { s = -1; mutex_exit(m); } else splx(s)
+#define usbd_lock_pipe(p)	do { \
+	if ((p)->device->bus->lock) { \
+		s = -1; \
+		mutex_enter((p)->device->bus->lock); \
+	} else \
+		s = splusb(); \
+} while (0)
 
-/*
+#define usbd_unlock_pipe(p)	do { \
- * XXX This check is extremely bogus. Bad Bad Bad.
+	if ((p)->device->bus->lock) { \
- */
+		s = -1; \
-#if defined(DIAGNOSTIC) && 0
+		mutex_exit((p)->device->bus->lock); \
-#define SPLUSBCHECK \
+	} else \
-	do { int _s = splusb(), _su = splusb(); \
+		splx(s); \
-             if (!cold && _s != _su) printf("SPLUSBCHECK failed 0x%x!=0x%x, %s:%d\n", \
+} while (0)
-				   _s, _su, __FILE__, __LINE__); \
-	     splx(_s); \
-        } while (0)
-#else
-#define SPLUSBCHECK
-#endif