Module Name:    src
Committed By:   mrg
Date:           Fri Dec  9 01:53:00 UTC 2011

Modified Files:
        src/sys/dev/pci [jmcneill-usbmp]: ehci_pci.c ohci_pci.c uhci_pci.c
        src/sys/dev/usb [jmcneill-usbmp]: ehci.c ohci.c uaudio.c uhci.c umidi.c
            usb.c usb_subr.c usbdi.c usbdivar.h

Log Message:
- make pipe->close method take the thread lock

- convert usb_taskq to use mutex/cv

- convert needs_explore usage into a cv on the thread lock

- remove KERNEL_*LOCK from uaudio and umidi, since we're supposedly
  MPSAFE here now

- use IPL_SCHED instead of IPL_USB (aka biglocked) interrupts

- drop the audio thread lock when calling into usb when it may sleep,
  avoiding a deadlock between audiowrite and audioioctl.  this fixes
  mixerctl -a vs. playing hanging the system
  XXX probably need to check this in a bunch more places.


To generate a diff of this commit:
cvs rdiff -u -r1.53.6.1 -r1.53.6.2 src/sys/dev/pci/ehci_pci.c
cvs rdiff -u -r1.47 -r1.47.8.1 src/sys/dev/pci/ohci_pci.c
cvs rdiff -u -r1.53 -r1.53.8.1 src/sys/dev/pci/uhci_pci.c
cvs rdiff -u -r1.181.6.4 -r1.181.6.5 src/sys/dev/usb/ehci.c
cvs rdiff -u -r1.218.6.7 -r1.218.6.8 src/sys/dev/usb/ohci.c
cvs rdiff -u -r1.124 -r1.124.2.1 src/sys/dev/usb/uaudio.c
cvs rdiff -u -r1.240.6.5 -r1.240.6.6 src/sys/dev/usb/uhci.c
cvs rdiff -u -r1.53 -r1.53.2.1 src/sys/dev/usb/umidi.c
cvs rdiff -u -r1.125.6.4 -r1.125.6.5 src/sys/dev/usb/usb.c
cvs rdiff -u -r1.180.6.2 -r1.180.6.3 src/sys/dev/usb/usb_subr.c
cvs rdiff -u -r1.134.2.4 -r1.134.2.5 src/sys/dev/usb/usbdi.c
cvs rdiff -u -r1.93.8.3 -r1.93.8.4 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/pci/ehci_pci.c
diff -u src/sys/dev/pci/ehci_pci.c:1.53.6.1 src/sys/dev/pci/ehci_pci.c:1.53.6.2
--- src/sys/dev/pci/ehci_pci.c:1.53.6.1	Sun Dec  4 13:23:16 2011
+++ src/sys/dev/pci/ehci_pci.c	Fri Dec  9 01:52:59 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ehci_pci.c,v 1.53.6.1 2011/12/04 13:23:16 jmcneill Exp $	*/
+/*	$NetBSD: ehci_pci.c,v 1.53.6.2 2011/12/09 01:52:59 mrg Exp $	*/
 
 /*
  * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ehci_pci.c,v 1.53.6.1 2011/12/04 13:23:16 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci_pci.c,v 1.53.6.2 2011/12/09 01:52:59 mrg Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -182,7 +182,7 @@ ehci_pci_attach(device_t parent, device_
 	 * Allocate IRQ
 	 */
 	intrstr = pci_intr_string(pc, ih);
-	sc->sc_ih = pci_intr_establish(pc, ih, IPL_USB, ehci_intr, sc);
+	sc->sc_ih = pci_intr_establish(pc, ih, IPL_SCHED, ehci_intr, sc);
 	if (sc->sc_ih == NULL) {
 		aprint_error_dev(self, "couldn't establish interrupt");
 		if (intrstr != NULL)

Index: src/sys/dev/pci/ohci_pci.c
diff -u src/sys/dev/pci/ohci_pci.c:1.47 src/sys/dev/pci/ohci_pci.c:1.47.8.1
--- src/sys/dev/pci/ohci_pci.c:1.47	Mon Apr  4 22:48:15 2011
+++ src/sys/dev/pci/ohci_pci.c	Fri Dec  9 01:52:59 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ohci_pci.c,v 1.47 2011/04/04 22:48:15 dyoung Exp $	*/
+/*	$NetBSD: ohci_pci.c,v 1.47.8.1 2011/12/09 01:52:59 mrg Exp $	*/
 
 /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ohci_pci.c,v 1.47 2011/04/04 22:48:15 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ohci_pci.c,v 1.47.8.1 2011/12/09 01:52:59 mrg Exp $");
 
 #include "ehci.h"
 
@@ -131,7 +131,7 @@ ohci_pci_attach(device_t parent, device_
 	 * Allocate IRQ
 	 */
 	intrstr = pci_intr_string(pc, ih);
-	sc->sc_ih = pci_intr_establish(pc, ih, IPL_USB, ohci_intr, sc);
+	sc->sc_ih = pci_intr_establish(pc, ih, IPL_SCHED, ohci_intr, sc);
 	if (sc->sc_ih == NULL) {
 		aprint_error_dev(self, "couldn't establish interrupt");
 		if (intrstr != NULL)

Index: src/sys/dev/pci/uhci_pci.c
diff -u src/sys/dev/pci/uhci_pci.c:1.53 src/sys/dev/pci/uhci_pci.c:1.53.8.1
--- src/sys/dev/pci/uhci_pci.c:1.53	Mon Apr  4 22:48:15 2011
+++ src/sys/dev/pci/uhci_pci.c	Fri Dec  9 01:52:59 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhci_pci.c,v 1.53 2011/04/04 22:48:15 dyoung Exp $	*/
+/*	$NetBSD: uhci_pci.c,v 1.53.8.1 2011/12/09 01:52:59 mrg Exp $	*/
 
 /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uhci_pci.c,v 1.53 2011/04/04 22:48:15 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhci_pci.c,v 1.53.8.1 2011/12/09 01:52:59 mrg Exp $");
 
 #include "ehci.h"
 
@@ -134,7 +134,7 @@ uhci_pci_attach(device_t parent, device_
 		return;
 	}
 	intrstr = pci_intr_string(pc, ih);
-	sc->sc_ih = pci_intr_establish(pc, ih, IPL_USB, uhci_intr, sc);
+	sc->sc_ih = pci_intr_establish(pc, ih, IPL_SCHED, uhci_intr, sc);
 	if (sc->sc_ih == NULL) {
 		aprint_error_dev(self, "couldn't establish interrupt");
 		if (intrstr != NULL)

Index: src/sys/dev/usb/ehci.c
diff -u src/sys/dev/usb/ehci.c:1.181.6.4 src/sys/dev/usb/ehci.c:1.181.6.5
--- src/sys/dev/usb/ehci.c:1.181.6.4	Thu Dec  8 02:51:07 2011
+++ src/sys/dev/usb/ehci.c	Fri Dec  9 01:52:59 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ehci.c,v 1.181.6.4 2011/12/08 02:51:07 mrg Exp $ */
+/*	$NetBSD: ehci.c,v 1.181.6.5 2011/12/09 01:52:59 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.4 2011/12/08 02:51:07 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.181.6.5 2011/12/09 01:52:59 mrg Exp $");
 
 #include "ohci.h"
 #include "uhci.h"
@@ -352,7 +352,7 @@ ehci_init(ehci_softc_t *sc)
 #endif
 
 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB);
-	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_USB);
+	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED);
 	cv_init(&sc->sc_softwake_cv, "ehciab");
 	cv_init(&sc->sc_doorbell, "ehcidi");
 
@@ -2616,11 +2616,11 @@ ehci_root_intr_close(usbd_pipe_handle pi
 {
 	ehci_softc_t *sc = pipe->device->bus->hci_private;
 
+	KASSERT(mutex_owned(&sc->sc_lock));
+
 	DPRINTF(("ehci_root_intr_close\n"));
 
-	mutex_enter(&sc->sc_lock);
 	sc->sc_intrxfer = NULL;
-	mutex_exit(&sc->sc_lock);
 }
 
 Static void
@@ -3346,11 +3346,11 @@ ehci_device_ctrl_close(usbd_pipe_handle 
 	ehci_softc_t *sc = pipe->device->bus->hci_private;
 	/*struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;*/
 
+	KASSERT(mutex_owned(&sc->sc_lock));
+
 	DPRINTF(("ehci_device_ctrl_close: pipe=%p\n", pipe));
 
-	mutex_enter(&sc->sc_lock);
 	ehci_close_pipe(pipe, sc->sc_async_head);
-	mutex_exit(&sc->sc_lock);
 }
 
 Static usbd_status
@@ -3663,11 +3663,11 @@ ehci_device_bulk_close(usbd_pipe_handle 
 	ehci_softc_t *sc = pipe->device->bus->hci_private;
 	struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
 
+	KASSERT(mutex_owned(&sc->sc_lock));
+
 	DPRINTF(("ehci_device_bulk_close: pipe=%p\n", pipe));
-	mutex_enter(&sc->sc_lock);
 	pipe->endpoint->datatoggle = epipe->nexttoggle;
 	ehci_close_pipe(pipe, sc->sc_async_head);
-	mutex_exit(&sc->sc_lock);
 }
 
 Static void
@@ -3848,6 +3848,8 @@ ehci_device_intr_close(usbd_pipe_handle 
 	struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
 	struct ehci_soft_islot *isp;
 
+	KASSERT(mutex_owned(&sc->sc_lock));
+
 	isp = &sc->sc_islots[epipe->sqh->islot];
 	ehci_close_pipe(pipe, isp->sqh);
 }

Index: src/sys/dev/usb/ohci.c
diff -u src/sys/dev/usb/ohci.c:1.218.6.7 src/sys/dev/usb/ohci.c:1.218.6.8
--- src/sys/dev/usb/ohci.c:1.218.6.7	Thu Dec  8 22:38:47 2011
+++ src/sys/dev/usb/ohci.c	Fri Dec  9 01:53:00 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ohci.c,v 1.218.6.7 2011/12/08 22:38:47 mrg Exp $	*/
+/*	$NetBSD: ohci.c,v 1.218.6.8 2011/12/09 01:53:00 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.7 2011/12/08 22:38:47 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.218.6.8 2011/12/09 01:53:00 mrg Exp $");
 
 #include "opt_usb.h"
 
@@ -665,7 +665,7 @@ ohci_init(ohci_softc_t *sc)
 	callout_init(&sc->sc_tmo_rhsc, CALLOUT_MPSAFE);
 
 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB);
-	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_USB);
+	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED);
 	cv_init(&sc->sc_softwake_cv, "ohciab");
 
 	sc->sc_rhsc_si = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE,
@@ -2895,6 +2895,8 @@ ohci_root_intr_close(usbd_pipe_handle pi
 {
 	ohci_softc_t *sc = pipe->device->bus->hci_private;
 
+	KASSERT(mutex_owned(&sc->sc_lock));
+
 	DPRINTF(("ohci_root_intr_close\n"));
 
 	sc->sc_intrxfer = NULL;
@@ -2962,11 +2964,11 @@ ohci_device_ctrl_close(usbd_pipe_handle 
 	struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
 	ohci_softc_t *sc = pipe->device->bus->hci_private;
 
+	KASSERT(mutex_owned(&sc->sc_lock));
+
 	DPRINTF(("ohci_device_ctrl_close: pipe=%p\n", pipe));
-	mutex_enter(&sc->sc_lock);
 	ohci_close_pipe(pipe, sc->sc_ctrl_head);
 	ohci_free_std(sc, opipe->tail.td);
-	mutex_exit(&sc->sc_lock);
 }
 
 /************************/
@@ -3126,11 +3128,11 @@ ohci_device_bulk_close(usbd_pipe_handle 
 	struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
 	ohci_softc_t *sc = pipe->device->bus->hci_private;
 
+	KASSERT(mutex_owned(&sc->sc_lock));
+
 	DPRINTF(("ohci_device_bulk_close: pipe=%p\n", pipe));
-	mutex_enter(&sc->sc_lock);
 	ohci_close_pipe(pipe, sc->sc_bulk_head);
 	ohci_free_std(sc, opipe->tail.td);
-	mutex_exit(&sc->sc_lock);
 }
 
 /************************/
@@ -3262,9 +3264,10 @@ ohci_device_intr_close(usbd_pipe_handle 
 	int j;
 	ohci_soft_ed_t *p, *sed = opipe->sed;
 
+	KASSERT(mutex_owned(&sc->sc_lock));
+
 	DPRINTFN(1,("ohci_device_intr_close: pipe=%p nslots=%d pos=%d\n",
 		    pipe, nslots, pos));
-	mutex_enter(&sc->sc_lock);
 	usb_syncmem(&sed->dma, sed->offs,
 	    sizeof(sed->ed), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
 	sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP);
@@ -3286,7 +3289,6 @@ ohci_device_intr_close(usbd_pipe_handle 
 	usb_syncmem(&p->dma, p->offs + offsetof(ohci_ed_t, ed_nexted),
 	    sizeof(p->ed.ed_nexted),
 	    BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
-	mutex_exit(&sc->sc_lock);
 
 	for (j = 0; j < nslots; j++)
 		--sc->sc_bws[(pos * nslots + j) % OHCI_NO_INTRS];
@@ -3648,12 +3650,12 @@ ohci_device_isoc_close(usbd_pipe_handle 
 	struct ohci_pipe *opipe = (struct ohci_pipe *)pipe;
 	ohci_softc_t *sc = pipe->device->bus->hci_private;
 
+	KASSERT(mutex_owned(&sc->sc_lock));
+
 	DPRINTF(("ohci_device_isoc_close: pipe=%p\n", pipe));
-	mutex_enter(&sc->sc_lock);
 	ohci_close_pipe(pipe, sc->sc_isoc_head);
 #ifdef DIAGNOSTIC
 	opipe->tail.itd->isdone = 1;
 #endif
 	ohci_free_sitd(sc, opipe->tail.itd);
-	mutex_exit(&sc->sc_lock);
 }

Index: src/sys/dev/usb/uaudio.c
diff -u src/sys/dev/usb/uaudio.c:1.124 src/sys/dev/usb/uaudio.c:1.124.2.1
--- src/sys/dev/usb/uaudio.c:1.124	Sun Nov 27 07:36:54 2011
+++ src/sys/dev/usb/uaudio.c	Fri Dec  9 01:53:00 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: uaudio.c,v 1.124 2011/11/27 07:36:54 mrg Exp $	*/
+/*	$NetBSD: uaudio.c,v 1.124.2.1 2011/12/09 01:53:00 mrg Exp $	*/
 
 /*
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uaudio.c,v 1.124 2011/11/27 07:36:54 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uaudio.c,v 1.124.2.1 2011/12/09 01:53:00 mrg Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -421,7 +421,7 @@ uaudio_attach(device_t parent, device_t 
 	sc->sc_dev = self;
 	sc->sc_udev = uaa->device;
 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
-	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_USB);
+	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED);
 
 	strlcpy(sc->sc_adev.name, "USB audio", sizeof(sc->sc_adev.name));
 	strlcpy(sc->sc_adev.version, "", sizeof(sc->sc_adev.version));
@@ -2097,7 +2097,7 @@ uaudio_query_devinfo(void *addr, mixer_d
 	struct mixerctl *mc;
 	int n, nctls, i;
 
-	DPRINTFN(2, "index=%d\n", mi->index);
+	DPRINTFN(7, "index=%d\n", mi->index);
 	sc = addr;
 	if (sc->sc_dying)
 		return EIO;
@@ -2220,7 +2220,6 @@ uaudio_halt_out_dma(void *addr)
 
 	DPRINTF("%s", "enter\n");
 
-	KERNEL_LOCK(1, curlwp);
 	mutex_spin_exit(&sc->sc_intr_lock);
 	if (sc->sc_playchan.pipe != NULL) {
 		uaudio_chan_close(sc, &sc->sc_playchan);
@@ -2229,7 +2228,6 @@ uaudio_halt_out_dma(void *addr)
 		sc->sc_playchan.intr = NULL;
 	}
 	mutex_spin_enter(&sc->sc_intr_lock);
-	KERNEL_UNLOCK_ONE(curlwp);
 
 	return 0;
 }
@@ -2241,7 +2239,6 @@ uaudio_halt_in_dma(void *addr)
 
 	DPRINTF("%s", "enter\n");
 
-	KERNEL_LOCK(1, curlwp);
 	mutex_spin_exit(&sc->sc_intr_lock);
 	if (sc->sc_recchan.pipe != NULL) {
 		uaudio_chan_close(sc, &sc->sc_recchan);
@@ -2250,7 +2247,6 @@ uaudio_halt_in_dma(void *addr)
 		sc->sc_recchan.intr = NULL;
 	}
 	mutex_spin_enter(&sc->sc_intr_lock);
-	KERNEL_UNLOCK_ONE(curlwp);
 
 	return 0;
 }
@@ -2464,10 +2460,10 @@ uaudio_ctl_get(struct uaudio_softc *sc, 
 	int val;
 
 	DPRINTFN(5,"which=%d chan=%d\n", which, chan);
-	KERNEL_LOCK(1, curlwp);
+	mutex_exit(&sc->sc_lock);
 	val = uaudio_get(sc, which, UT_READ_CLASS_INTERFACE, mc->wValue[chan],
 			 mc->wIndex, MIX_SIZE(mc->type));
-	KERNEL_UNLOCK_ONE(curlwp);
+	mutex_enter(&sc->sc_lock);
 	return uaudio_value2bsd(mc, val);
 }
 
@@ -2477,10 +2473,10 @@ uaudio_ctl_set(struct uaudio_softc *sc, 
 {
 
 	val = uaudio_bsd2value(mc, val);
-	KERNEL_LOCK(1, curlwp);
+	mutex_exit(&sc->sc_lock);
 	uaudio_set(sc, which, UT_WRITE_CLASS_INTERFACE, mc->wValue[chan],
 		   mc->wIndex, MIX_SIZE(mc->type), val);
-	KERNEL_UNLOCK_ONE(curlwp);
+	mutex_enter(&sc->sc_lock);
 }
 
 Static int
@@ -2592,18 +2588,15 @@ uaudio_trigger_input(void *addr, void *s
 		    "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame,
 		    ch->fraction);
 
-	KERNEL_LOCK(1, curlwp);
 	mutex_spin_exit(&sc->sc_intr_lock);
 	err = uaudio_chan_alloc_buffers(sc, ch);
 	if (err) {
 		mutex_spin_enter(&sc->sc_intr_lock);
-		KERNEL_UNLOCK_ONE(curlwp);
 		return EIO;
 	}
 
 	err = uaudio_chan_open(sc, ch);
 	mutex_spin_enter(&sc->sc_intr_lock);
-	KERNEL_UNLOCK_ONE(curlwp);
 	if (err) {
 		uaudio_chan_free_buffers(sc, ch);
 		return EIO;
@@ -2612,14 +2605,12 @@ uaudio_trigger_input(void *addr, void *s
 	ch->intr = intr;
 	ch->arg = arg;
 
-	KERNEL_LOCK(1, curlwp);
 	mutex_spin_exit(&sc->sc_intr_lock);
 	s = splusb();
 	for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX -1 shouldn't be needed */
 		uaudio_chan_rtransfer(ch);
 	splx(s);
 	mutex_spin_enter(&sc->sc_intr_lock);
-	KERNEL_UNLOCK_ONE(curlwp);
 
 	return 0;
 }
@@ -2646,18 +2637,15 @@ uaudio_trigger_output(void *addr, void *
 		    "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame,
 		    ch->fraction);
 
-	KERNEL_LOCK(1, curlwp);
 	mutex_spin_exit(&sc->sc_intr_lock);
 	err = uaudio_chan_alloc_buffers(sc, ch);
 	if (err) {
 		mutex_spin_enter(&sc->sc_intr_lock);
-		KERNEL_UNLOCK_ONE(curlwp);
 		return EIO;
 	}
 
 	err = uaudio_chan_open(sc, ch);
 	mutex_spin_enter(&sc->sc_intr_lock);
-	KERNEL_UNLOCK_ONE(curlwp);
 	if (err) {
 		uaudio_chan_free_buffers(sc, ch);
 		return EIO;
@@ -2666,14 +2654,12 @@ uaudio_trigger_output(void *addr, void *
 	ch->intr = intr;
 	ch->arg = arg;
 
-	KERNEL_LOCK(1, curlwp);
 	mutex_spin_exit(&sc->sc_intr_lock);
 	s = splusb();
 	for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX */
 		uaudio_chan_ptransfer(ch);
 	splx(s);
 	mutex_spin_enter(&sc->sc_intr_lock);
-	KERNEL_UNLOCK_ONE(curlwp);
 
 	return 0;
 }
@@ -3129,9 +3115,7 @@ uaudio_set_speed(struct uaudio_softc *sc
 	data[1] = speed >> 8;
 	data[2] = speed >> 16;
 
-	KERNEL_LOCK(1, curlwp);
 	err = usbd_do_request(sc->sc_udev, &req, data);
-	KERNEL_UNLOCK_ONE(curlwp);
 
 	return err;
 }

Index: src/sys/dev/usb/uhci.c
diff -u src/sys/dev/usb/uhci.c:1.240.6.5 src/sys/dev/usb/uhci.c:1.240.6.6
--- src/sys/dev/usb/uhci.c:1.240.6.5	Thu Dec  8 02:51:08 2011
+++ src/sys/dev/usb/uhci.c	Fri Dec  9 01:53:00 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhci.c,v 1.240.6.5 2011/12/08 02:51:08 mrg Exp $	*/
+/*	$NetBSD: uhci.c,v 1.240.6.6 2011/12/09 01:53:00 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.5 2011/12/08 02:51:08 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.240.6.6 2011/12/09 01:53:00 mrg Exp $");
 
 #include "opt_usb.h"
 
@@ -529,7 +529,7 @@ uhci_init(uhci_softc_t *sc)
 	callout_init(&sc->sc_poll_handle, CALLOUT_MPSAFE);
 
 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB);
-	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_USB);
+	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED);
 	cv_init(&sc->sc_softwake_cv, "uhciab");
 
 	/* Set up the bus struct. */
@@ -2217,6 +2217,8 @@ uhci_device_bulk_close(usbd_pipe_handle 
 	usbd_device_handle dev = upipe->pipe.device;
 	uhci_softc_t *sc = dev->bus->hci_private;
 
+	KASSERT(mutex_owned(&sc->sc_lock));
+
 	uhci_free_sqh(sc, upipe->u.bulk.sqh);
 
 	pipe->endpoint->datatoggle = upipe->nexttoggle;
@@ -2407,12 +2409,12 @@ uhci_device_intr_close(usbd_pipe_handle 
 	uhci_softc_t *sc = pipe->device->bus->hci_private;
 	int i, npoll;
 
+	KASSERT(mutex_owned(&sc->sc_lock));
+
 	/* Unlink descriptors from controller data structures. */
 	npoll = upipe->u.intr.npoll;
-	mutex_enter(&sc->sc_lock);
 	for (i = 0; i < npoll; i++)
 		uhci_remove_intr(sc, upipe->u.intr.qhs[i]);
-	mutex_exit(&sc->sc_lock);
 
 	/*
 	 * We now have to wait for any activity on the physical
@@ -2792,6 +2794,8 @@ uhci_device_isoc_close(usbd_pipe_handle 
 	struct iso *iso;
 	int i;
 
+	KASSERT(mutex_owned(&sc->sc_lock));
+
 	/*
 	 * Make sure all TDs are marked as inactive.
 	 * Wait for completion.
@@ -2800,7 +2804,6 @@ uhci_device_isoc_close(usbd_pipe_handle 
 	 */
 	iso = &upipe->u.iso;
 
-	mutex_enter(&sc->sc_lock);
 	for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
 		std = iso->stds[i];
 		usb_syncmem(&std->dma,
@@ -2839,7 +2842,6 @@ uhci_device_isoc_close(usbd_pipe_handle 
 		    BUS_DMASYNC_PREWRITE);
 		uhci_free_std(sc, std);
 	}
-	mutex_exit(&sc->sc_lock);
 
 	kmem_free(iso->stds, UHCI_VFRAMELIST_COUNT * sizeof (uhci_soft_td_t *));
 }
@@ -3918,6 +3920,8 @@ uhci_root_intr_close(usbd_pipe_handle pi
 {
 	uhci_softc_t *sc = pipe->device->bus->hci_private;
 
+	KASSERT(mutex_owned(&sc->sc_lock));
+
 	callout_stop(&sc->sc_poll_handle);
 	sc->sc_intr_xfer = NULL;
 	DPRINTF(("uhci_root_intr_close\n"));

Index: src/sys/dev/usb/umidi.c
diff -u src/sys/dev/usb/umidi.c:1.53 src/sys/dev/usb/umidi.c:1.53.2.1
--- src/sys/dev/usb/umidi.c:1.53	Sat Nov 26 13:31:52 2011
+++ src/sys/dev/usb/umidi.c	Fri Dec  9 01:53:00 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: umidi.c,v 1.53 2011/11/26 13:31:52 mrg Exp $	*/
+/*	$NetBSD: umidi.c,v 1.53.2.1 2011/12/09 01:53:00 mrg Exp $	*/
 /*
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: umidi.c,v 1.53 2011/11/26 13:31:52 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: umidi.c,v 1.53.2.1 2011/12/09 01:53:00 mrg Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -209,7 +209,6 @@ umidi_attach(device_t parent, device_t s
 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_USB);
 	cv_init(&sc->sc_cv, "umidopcl");
 
-	KERNEL_LOCK(1, curlwp);
 	err = alloc_all_endpoints(sc);
 	if (err != USBD_NORMAL_COMPLETION) {
 		aprint_error_dev(self,
@@ -242,7 +241,6 @@ umidi_attach(device_t parent, device_t s
 		aprint_error_dev(self,
 		    "attach_all_mididevs failed. (err=%d)\n", err);
 	}
-	KERNEL_UNLOCK_ONE(curlwp);
 
 #ifdef UMIDI_DEBUG
 	dump_sc(sc);
@@ -299,7 +297,6 @@ umidi_detach(device_t self, int flags)
 	DPRINTFN(1,("umidi_detach\n"));
 
 	sc->sc_dying = 1;
-	KERNEL_LOCK(1, curlwp);
 	detach_all_mididevs(sc, flags);
 	free_all_mididevs(sc);
 	free_all_jacks(sc);
@@ -307,7 +304,6 @@ umidi_detach(device_t self, int flags)
 
 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
 			   sc->sc_dev);
-	KERNEL_UNLOCK_ONE(curlwp);
 
 	mutex_destroy(&sc->sc_lock);
 	cv_destroy(&sc->sc_cv);
@@ -1433,13 +1429,11 @@ start_output_transfer(struct umidi_endpo
 	length = (ep->next_slot - ep->buffer) * sizeof *ep->buffer;
 	DPRINTFN(200,("umidi out transfer: start %p end %p length %u\n",
 	    ep->buffer, ep->next_slot, length));
-	KERNEL_LOCK(1, curlwp);
 	usbd_setup_xfer(ep->xfer, ep->pipe,
 			(usbd_private_handle)ep,
 			ep->buffer, length,
 			USBD_NO_COPY, USBD_NO_TIMEOUT, out_intr);
 	rv = usbd_transfer(ep->xfer);
-	KERNEL_UNLOCK_ONE(curlwp);
 	
 	/*
 	 * Once the transfer is scheduled, no more adding to partial

Index: src/sys/dev/usb/usb.c
diff -u src/sys/dev/usb/usb.c:1.125.6.4 src/sys/dev/usb/usb.c:1.125.6.5
--- src/sys/dev/usb/usb.c:1.125.6.4	Thu Dec  8 02:51:08 2011
+++ src/sys/dev/usb/usb.c	Fri Dec  9 01:53:00 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: usb.c,v 1.125.6.4 2011/12/08 02:51:08 mrg Exp $	*/
+/*	$NetBSD: usb.c,v 1.125.6.5 2011/12/09 01:53:00 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.4 2011/12/08 02:51:08 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.125.6.5 2011/12/09 01:53:00 mrg Exp $");
 
 #include "opt_compat_netbsd.h"
 #include "opt_usb.h"
@@ -100,6 +100,8 @@ struct usb_softc {
 
 struct usb_taskq {
 	TAILQ_HEAD(, usb_task) tasks;
+	kmutex_t lock;
+	kcondvar_t cv;
 	struct lwp *task_thread_lwp;
 	const char *name;
 	int taskcreated;	/* task thread exists. */
@@ -232,6 +234,7 @@ usb_doattach(device_t self)
 	} else {
 		sc->sc_bus->intr_lock = sc->sc_bus->lock = NULL;
 	}
+	cv_init(&sc->sc_bus->needs_explore_cv, "usbevt");
 
 	ue = usb_alloc_event();
 	ue->u.ue_ctrlr.ue_bus = device_unit(self);
@@ -308,6 +311,8 @@ usb_create_event_thread(device_t self)
 			continue;
 
 		TAILQ_INIT(&taskq->tasks);
+		mutex_init(&taskq->lock, MUTEX_DEFAULT, IPL_NONE);
+		cv_init(&taskq->cv, "usbtsk");
 		taskq->taskcreated = 1;
 		taskq->name = taskq_names[i];
 		if (kthread_create(PRI_NONE, 0, NULL, usb_task_thread,
@@ -327,10 +332,9 @@ void
 usb_add_task(usbd_device_handle dev, struct usb_task *task, int queue)
 {
 	struct usb_taskq *taskq;
-	int s;
 
 	taskq = &usb_taskq[queue];
-	s = splusb();
+	mutex_enter(&taskq->lock);
 	if (task->queue == -1) {
 		DPRINTFN(2,("usb_add_task: task=%p\n", task));
 		TAILQ_INSERT_TAIL(&taskq->tasks, task, next);
@@ -338,23 +342,22 @@ usb_add_task(usbd_device_handle dev, str
 	} else {
 		DPRINTFN(3,("usb_add_task: task=%p on q\n", task));
 	}
-	wakeup(&taskq->tasks);
-	splx(s);
+	cv_signal(&taskq->cv);
+	mutex_exit(&taskq->lock);
 }
 
 void
 usb_rem_task(usbd_device_handle dev, struct usb_task *task)
 {
 	struct usb_taskq *taskq;
-	int s;
 
 	taskq = &usb_taskq[task->queue];
-	s = splusb();
+	mutex_enter(&taskq->lock);
 	if (task->queue != -1) {
 		TAILQ_REMOVE(&taskq->tasks, task, next);
 		task->queue = -1;
 	}
-	splx(s);
+	mutex_exit(&taskq->lock);
 }
 
 void
@@ -375,21 +378,36 @@ usb_event_thread(void *arg)
 	usb_delay_ms(sc->sc_bus, 500);
 
 	/* Make sure first discover does something. */
+	if (sc->sc_bus->lock)
+		mutex_enter(sc->sc_bus->lock);
 	sc->sc_bus->needs_explore = 1;
 	usb_discover(sc);
+	if (sc->sc_bus->lock)
+		mutex_exit(sc->sc_bus->lock);
 	config_pending_decr();
 
+	if (sc->sc_bus->lock)
+		mutex_enter(sc->sc_bus->lock);
 	while (!sc->sc_dying) {
 		if (usb_noexplore < 2)
 			usb_discover(sc);
-		(void)tsleep(&sc->sc_bus->needs_explore, PWAIT, "usbevt",
-		    usb_noexplore ? 0 : hz * 60);
+
+		if (sc->sc_bus->lock)
+			cv_timedwait(&sc->sc_bus->needs_explore_cv,
+			    sc->sc_bus->lock, usb_noexplore ? 0 : hz * 60);
+		else
+			(void)tsleep(&sc->sc_bus->needs_explore, PWAIT,
+			    "usbevt", usb_noexplore ? 0 : hz * 60);
 		DPRINTFN(2,("usb_event_thread: woke up\n"));
 	}
 	sc->sc_event_thread = NULL;
 
 	/* In case parent is waiting for us to exit. */
-	wakeup(sc);
+	if (sc->sc_bus->lock) {
+		cv_signal(&sc->sc_bus->needs_explore_cv);
+		mutex_exit(sc->sc_bus->lock);
+	} else
+		wakeup(sc);
 
 	DPRINTF(("usb_event_thread: exit\n"));
 	kthread_exit(0);
@@ -400,27 +418,27 @@ usb_task_thread(void *arg)
 {
 	struct usb_task *task;
 	struct usb_taskq *taskq;
-	int s;
 
 	taskq = arg;
 	DPRINTF(("usb_task_thread: start taskq %s\n", taskq->name));
 
-	s = splusb();
+	mutex_enter(&taskq->lock);
 	for (;;) {
 		task = TAILQ_FIRST(&taskq->tasks);
 		if (task == NULL) {
-			tsleep(&taskq->tasks, PWAIT, "usbtsk", 0);
+			cv_wait(&taskq->cv, &taskq->lock);
 			task = TAILQ_FIRST(&taskq->tasks);
 		}
 		DPRINTFN(2,("usb_task_thread: woke up task=%p\n", task));
 		if (task != NULL) {
 			TAILQ_REMOVE(&taskq->tasks, task, next);
 			task->queue = -1;
-			splx(s);
+			mutex_exit(&taskq->lock);
 			task->fun(task->arg);
-			s = splusb();
+			mutex_enter(&taskq->lock);
 		}
 	}
+	mutex_exit(&taskq->lock);
 }
 
 int
@@ -777,6 +795,8 @@ Static void
 usb_discover(struct usb_softc *sc)
 {
 
+	KASSERT(sc->sc_bus->lock == NULL || mutex_owned(sc->sc_bus->lock));
+
 	DPRINTFN(2,("usb_discover\n"));
 	if (usb_noexplore > 1)
 		return;
@@ -784,10 +804,16 @@ usb_discover(struct usb_softc *sc)
 	 * We need mutual exclusion while traversing the device tree,
 	 * but this is guaranteed since this function is only called
 	 * from the event thread for the controller.
+	 *
+	 * Also, we now have sc_bus->lock held for MPSAFE controllers.
 	 */
 	while (sc->sc_bus->needs_explore && !sc->sc_dying) {
 		sc->sc_bus->needs_explore = 0;
+		if (sc->sc_bus->lock)
+			mutex_exit(sc->sc_bus->lock);
 		sc->sc_bus->root_hub->hub->explore(sc->sc_bus->root_hub);
+		if (sc->sc_bus->lock)
+			mutex_enter(sc->sc_bus->lock);
 	}
 }
 
@@ -795,17 +821,29 @@ void
 usb_needs_explore(usbd_device_handle dev)
 {
 	DPRINTFN(2,("usb_needs_explore\n"));
+	if (dev->bus->lock)
+		mutex_enter(dev->bus->lock);
 	dev->bus->needs_explore = 1;
-	wakeup(&dev->bus->needs_explore);
+	if (dev->bus->lock) {
+		cv_signal(&dev->bus->needs_explore_cv);
+		mutex_exit(dev->bus->lock);
+	} else
+		wakeup(&dev->bus->needs_explore);
 }
 
 void
 usb_needs_reattach(usbd_device_handle dev)
 {
 	DPRINTFN(2,("usb_needs_reattach\n"));
+	if (dev->bus->lock)
+		mutex_enter(dev->bus->lock);
 	dev->powersrc->reattach = 1;
 	dev->bus->needs_explore = 1;
-	wakeup(&dev->bus->needs_explore);
+	if (dev->bus->lock) {
+		cv_signal(&dev->bus->needs_explore_cv);
+		mutex_exit(dev->bus->lock);
+	} else
+		wakeup(&dev->bus->needs_explore);
 }
 
 /* Called at splusb() */
@@ -967,8 +1005,16 @@ usb_detach(device_t self, int flags)
 	/* Kill off event thread. */
 	sc->sc_dying = 1;
 	while (sc->sc_event_thread != NULL) {
-		wakeup(&sc->sc_bus->needs_explore);
-		tsleep(sc, PWAIT, "usbdet", hz * 60);
+		if (sc->sc_bus->lock) {
+			mutex_enter(sc->sc_bus->lock);
+			cv_signal(&sc->sc_bus->needs_explore_cv);
+			cv_timedwait(&sc->sc_bus->needs_explore_cv,
+			    sc->sc_bus->lock, hz * 60);
+			mutex_exit(sc->sc_bus->lock);
+		} else {
+			wakeup(&sc->sc_bus->needs_explore);
+			tsleep(sc, PWAIT, "usbdet", hz * 60);
+		}
 	}
 	DPRINTF(("usb_detach: event thread dead\n"));
 

Index: src/sys/dev/usb/usb_subr.c
diff -u src/sys/dev/usb/usb_subr.c:1.180.6.2 src/sys/dev/usb/usb_subr.c:1.180.6.3
--- src/sys/dev/usb/usb_subr.c:1.180.6.2	Thu Dec  8 02:51:08 2011
+++ src/sys/dev/usb/usb_subr.c	Fri Dec  9 01:53:00 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: usb_subr.c,v 1.180.6.2 2011/12/08 02:51:08 mrg Exp $	*/
+/*	$NetBSD: usb_subr.c,v 1.180.6.3 2011/12/09 01:53:00 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.2 2011/12/08 02:51:08 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.180.6.3 2011/12/09 01:53:00 mrg Exp $");
 
 #include "opt_compat_netbsd.h"
 #include "opt_usbverbose.h"
@@ -759,8 +759,12 @@ usbd_setup_pipe(usbd_device_handle dev, 
 void
 usbd_kill_pipe(usbd_pipe_handle pipe)
 {
+	int s;
+
 	usbd_abort_pipe(pipe);
+	usbd_lock_pipe(pipe);
 	pipe->methods->close(pipe);
+	usbd_unlock_pipe(pipe);
 	pipe->endpoint->refcnt--;
 	free(pipe, M_USB);
 }
@@ -1280,6 +1284,7 @@ usbd_reload_device_desc(usbd_device_hand
 void
 usbd_remove_device(usbd_device_handle dev, struct usbd_port *up)
 {
+
 	DPRINTF(("usbd_remove_device: %p\n", dev));
 
 	if (dev->default_pipe != NULL)

Index: src/sys/dev/usb/usbdi.c
diff -u src/sys/dev/usb/usbdi.c:1.134.2.4 src/sys/dev/usb/usbdi.c:1.134.2.5
--- src/sys/dev/usb/usbdi.c:1.134.2.4	Thu Dec  8 22:38:47 2011
+++ src/sys/dev/usb/usbdi.c	Fri Dec  9 01:53:00 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: usbdi.c,v 1.134.2.4 2011/12/08 22:38:47 mrg Exp $	*/
+/*	$NetBSD: usbdi.c,v 1.134.2.5 2011/12/09 01:53:00 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.4 2011/12/08 22:38:47 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.134.2.5 2011/12/09 01:53:00 mrg Exp $");
 
 #include "opt_compat_netbsd.h"
 #include "opt_usb.h"
@@ -229,6 +229,7 @@ usbd_open_pipe_intr(usbd_interface_handl
 usbd_status
 usbd_close_pipe(usbd_pipe_handle pipe)
 {
+	int s;
 
 #ifdef DIAGNOSTIC
 	if (pipe == NULL) {
@@ -237,13 +238,19 @@ usbd_close_pipe(usbd_pipe_handle pipe)
 	}
 #endif
 
-	if (--pipe->refcnt != 0)
+	usbd_lock_pipe(pipe);
+	if (--pipe->refcnt != 0) {
+		usbd_unlock_pipe(pipe);
 		return (USBD_NORMAL_COMPLETION);
-	if (! SIMPLEQ_EMPTY(&pipe->queue))
+	}
+	if (! SIMPLEQ_EMPTY(&pipe->queue)) {
+		usbd_unlock_pipe(pipe);
 		return (USBD_PENDING_REQUESTS);
+	}
 	LIST_REMOVE(pipe, next);
 	pipe->endpoint->refcnt--;
 	pipe->methods->close(pipe);
+	usbd_unlock_pipe(pipe);
 	if (pipe->intrxfer != NULL)
 		usbd_free_xfer(pipe->intrxfer);
 	free(pipe, M_USB);

Index: src/sys/dev/usb/usbdivar.h
diff -u src/sys/dev/usb/usbdivar.h:1.93.8.3 src/sys/dev/usb/usbdivar.h:1.93.8.4
--- src/sys/dev/usb/usbdivar.h:1.93.8.3	Thu Dec  8 22:38:47 2011
+++ src/sys/dev/usb/usbdivar.h	Fri Dec  9 01:53:00 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: usbdivar.h,v 1.93.8.3 2011/12/08 22:38:47 mrg Exp $	*/
+/*	$NetBSD: usbdivar.h,v 1.93.8.4 2011/12/09 01:53:00 mrg Exp $	*/
 /*	$FreeBSD: src/sys/dev/usb/usbdivar.h,v 1.11 1999/11/17 22:33:51 n_hibma Exp $	*/
 
 /*
@@ -61,7 +61,7 @@
  *	transfer		-	-
  *	start			-	-
  *	abort			-	-
- *	close			-	-
+ *	close			-	x
  *	cleartoggle		-	-
  *	done			-	x
  *
@@ -146,6 +146,7 @@ struct usbd_bus {
 	kmutex_t		*lock;
 	struct usbd_device      *root_hub;
 	usbd_device_handle	devices[USB_MAX_DEVICES];
+	kcondvar_t              needs_explore_cv;
 	char			needs_explore;/* a hub a signalled a change */
 	char			use_polling;
 	device_t		usbctl;
@@ -301,18 +302,24 @@ void		usb_needs_explore(usbd_device_hand
 void		usb_needs_reattach(usbd_device_handle);
 void		usb_schedsoftintr(struct usbd_bus *);
 
-#define usbd_lock_pipe(p)	do { \
-	if ((p)->device->bus->lock) { \
+/*
+ * These macros help while not all host controllers are ported to the MP code.
+ */
+#define usbd_mutex_enter(m)	do { \
+	if (m) { \
 		s = -1; \
-		mutex_enter((p)->device->bus->lock); \
+		mutex_enter(m); \
 	} else \
 		s = splusb(); \
 } while (0)
 
-#define usbd_unlock_pipe(p)	do { \
-	if ((p)->device->bus->lock) { \
+#define usbd_mutex_exit(m)	do { \
+	if (m) { \
 		s = -1; \
-		mutex_exit((p)->device->bus->lock); \
+		mutex_exit(m); \
 	} else \
 		splx(s); \
 } while (0)
+
+#define usbd_lock_pipe(p)	usbd_mutex_enter((p)->device->bus->lock)
+#define usbd_unlock_pipe(p)	usbd_mutex_exit((p)->device->bus->lock)

Reply via email to