Module Name: src Committed By: mrg Date: Tue Dec 6 02:10:02 UTC 2011
Modified Files: src/sys/dev/usb [jmcneill-usbmp]: ehci.c ohci.c usb.c Log Message: need to ensure kpreempt_disable() for softint_schedule(). fix the locking in ohci_timeout_task(), ohci_device_isoc_start(), ohci_device_isoc_abort() and ohci_device_isoc_close(). uaudio(4) can still play with these, but mixerctl -a against it will hang the writer. however, mixerctl continues to run in a tight loop and the system isn't soft-locked up at this point, an advance from how it is in -current. To generate a diff of this commit: cvs rdiff -u -r1.181.6.2 -r1.181.6.3 src/sys/dev/usb/ehci.c cvs rdiff -u -r1.218.6.2 -r1.218.6.3 src/sys/dev/usb/ohci.c cvs rdiff -u -r1.125.6.1 -r1.125.6.2 src/sys/dev/usb/usb.c 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.2 src/sys/dev/usb/ehci.c:1.181.6.3 --- src/sys/dev/usb/ehci.c:1.181.6.2 Sun Dec 4 19:22:56 2011 +++ src/sys/dev/usb/ehci.c Tue Dec 6 02:10:01 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: ehci.c,v 1.181.6.2 2011/12/04 19:22:56 jmcneill Exp $ */ +/* $NetBSD: ehci.c,v 1.181.6.3 2011/12/06 02:10:01 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.2 2011/12/04 19:22:56 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.181.6.3 2011/12/06 02:10:01 mrg Exp $"); #include "ohci.h" #include "uhci.h" @@ -652,7 +652,9 @@ ehci_intr1(ehci_softc_t *sc) sc->sc_bus.no_intrs++; if (eintrs & EHCI_STS_IAA) { DPRINTF(("ehci_intr1: door bell\n")); + kpreempt_disable(); softint_schedule(sc->sc_doorbell_si); + kpreempt_enable(); eintrs &= ~EHCI_STS_IAA; } if (eintrs & (EHCI_STS_INT | EHCI_STS_ERRINT)) { @@ -668,7 +670,9 @@ ehci_intr1(ehci_softc_t *sc) /* XXX what else */ } if (eintrs & EHCI_STS_PCD) { + kpreempt_disable(); softint_schedule(sc->sc_pcd_si); + kpreempt_enable(); eintrs &= ~EHCI_STS_PCD; } Index: src/sys/dev/usb/ohci.c diff -u src/sys/dev/usb/ohci.c:1.218.6.2 src/sys/dev/usb/ohci.c:1.218.6.3 --- src/sys/dev/usb/ohci.c:1.218.6.2 Sun Dec 4 21:02:27 2011 +++ src/sys/dev/usb/ohci.c Tue Dec 6 02:10:01 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: ohci.c,v 1.218.6.2 2011/12/04 21:02:27 jmcneill Exp $ */ +/* $NetBSD: ohci.c,v 1.218.6.3 2011/12/06 02:10:01 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.2 2011/12/04 21:02:27 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.218.6.3 2011/12/06 02:10:01 mrg Exp $"); #include "opt_usb.h" @@ -2020,14 +2020,10 @@ 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)); - KASSERT(mutex_owned(&sc->sc_lock)); - //mutex_enter(&sc->sc_lock); ohci_abort_xfer(xfer, USBD_TIMEOUT); - //mutex_exit(&sc->sc_lock); } #ifdef OHCI_DEBUG @@ -3540,6 +3536,8 @@ ohci_device_isoc_start(usbd_xfer_handle /* XXX anything to do? */ + mutex_exit(&sc->sc_lock); + return (USBD_IN_PROGRESS); } @@ -3551,9 +3549,9 @@ ohci_device_isoc_abort(usbd_xfer_handle ohci_soft_ed_t *sed; ohci_soft_itd_t *sitd; - DPRINTFN(1,("ohci_device_isoc_abort: xfer=%p\n", xfer)); + DPRINTFN(1,("ohci_device_isoc_abort: xfer=%p lock=%p\n", xfer, &sc->sc_lock)); - KASSERT(mutex_owned(&sc->sc_lock)); + mutex_enter(&sc->sc_lock); /* Transfer is already done. */ if (xfer->status != USBD_NOT_STARTED && @@ -3635,9 +3633,11 @@ ohci_device_isoc_close(usbd_pipe_handle ohci_softc_t *sc = pipe->device->bus->hci_private; 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 + mutex_exit(&sc->sc_lock); ohci_free_sitd(sc, opipe->tail.itd); } Index: src/sys/dev/usb/usb.c diff -u src/sys/dev/usb/usb.c:1.125.6.1 src/sys/dev/usb/usb.c:1.125.6.2 --- src/sys/dev/usb/usb.c:1.125.6.1 Sun Dec 4 13:23:17 2011 +++ src/sys/dev/usb/usb.c Tue Dec 6 02:10:01 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: usb.c,v 1.125.6.1 2011/12/04 13:23:17 jmcneill Exp $ */ +/* $NetBSD: usb.c,v 1.125.6.2 2011/12/06 02:10:01 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.1 2011/12/04 13:23:17 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.125.6.2 2011/12/06 02:10:01 mrg Exp $"); #include "opt_compat_netbsd.h" #include "opt_usb.h" @@ -890,7 +890,9 @@ usb_add_event(int type, struct usb_event wakeup(&usb_events); selnotify(&usb_selevent, 0, 0); if (usb_async_proc != NULL) { + kpreempt_disable(); softint_schedule(usb_async_sih); + kpreempt_enable(); } splx(s); } @@ -913,7 +915,9 @@ usb_schedsoftintr(usbd_bus_handle bus) if (bus->use_polling) { bus->methods->soft_intr(bus); } else { + kpreempt_disable(); softint_schedule(bus->soft); + kpreempt_enable(); } }