Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/usb stopgap fix for recursive locking on suspend/resume



details:   https://anonhg.NetBSD.org/src/rev/2905e961215b
branches:  trunk
changeset: 779874:2905e961215b
user:      drochner <drochner%NetBSD.org@localhost>
date:      Sun Jun 24 10:06:34 2012 +0000

description:
stopgap fix for recursive locking on suspend/resume
(This can be simplified imo because interrupts should be disabled
at this point.)

diffstat:

 sys/dev/usb/uhci.c |  25 ++++++++++++++-----------
 1 files changed, 14 insertions(+), 11 deletions(-)

diffs (99 lines):

diff -r 9ff6318ee72c -r 2905e961215b sys/dev/usb/uhci.c
--- a/sys/dev/usb/uhci.c        Sun Jun 24 09:38:54 2012 +0000
+++ b/sys/dev/usb/uhci.c        Sun Jun 24 10:06:34 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uhci.c,v 1.248 2012/06/10 06:15:53 mrg Exp $   */
+/*     $NetBSD: uhci.c,v 1.249 2012/06/24 10:06:34 drochner Exp $      */
 
 /*
  * Copyright (c) 1998, 2004, 2011, 2012 The NetBSD Foundation, Inc.
@@ -42,7 +42,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.248 2012/06/10 06:15:53 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.249 2012/06/24 10:06:34 drochner Exp $");
 
 #include "opt_usb.h"
 
@@ -130,7 +130,7 @@
 Static void            uhci_globalreset(uhci_softc_t *);
 Static usbd_status     uhci_portreset(uhci_softc_t*, int);
 Static void            uhci_reset(uhci_softc_t *);
-Static usbd_status     uhci_run(uhci_softc_t *, int run);
+Static usbd_status     uhci_run(uhci_softc_t *, int run, int locked);
 Static uhci_soft_td_t  *uhci_alloc_std(uhci_softc_t *);
 Static void            uhci_free_std(uhci_softc_t *, uhci_soft_td_t *);
 Static uhci_soft_qh_t  *uhci_alloc_sqh(uhci_softc_t *);
@@ -539,7 +539,7 @@
 
        DPRINTFN(1,("uhci_init: enabling\n"));
 
-       err =  uhci_run(sc, 1);         /* and here we go... */
+       err =  uhci_run(sc, 1, 0);              /* and here we go... */
        UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE |
                UHCI_INTR_IOCE | UHCI_INTR_SPIE);       /* enable interrupts */
        return err;
@@ -727,7 +727,7 @@
        uhci_globalreset(sc);
        uhci_reset(sc);
        if (cmd & UHCI_CMD_RS)
-               uhci_run(sc, 0);
+               uhci_run(sc, 0, 1);
 
        /* restore saved state */
        UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&sc->sc_dma, 0));
@@ -740,7 +740,7 @@
        UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE |
            UHCI_INTR_RIE | UHCI_INTR_IOCE | UHCI_INTR_SPIE);
        UHCICMD(sc, UHCI_CMD_MAXP);
-       uhci_run(sc, 1); /* and start traffic again */
+       uhci_run(sc, 1, 1); /* and start traffic again */
        usb_delay_ms_locked(&sc->sc_bus, USB_RESUME_RECOVERY, &sc->sc_intr_lock);
        sc->sc_bus.use_polling--;
        if (sc->sc_intr_xfer != NULL)
@@ -776,7 +776,7 @@
        sc->sc_suspend = PWR_SUSPEND;
        sc->sc_bus.use_polling++;
 
-       uhci_run(sc, 0); /* stop the controller */
+       uhci_run(sc, 0, 1); /* stop the controller */
        cmd &= ~UHCI_CMD_RS;
 
        /* save some state if BIOS doesn't */
@@ -1742,13 +1742,14 @@
 }
 
 usbd_status
-uhci_run(uhci_softc_t *sc, int run)
+uhci_run(uhci_softc_t *sc, int run, int locked)
 {
        int n, running;
        u_int16_t cmd;
 
        run = run != 0;
-       mutex_spin_enter(&sc->sc_intr_lock);
+       if (!locked)
+               mutex_spin_enter(&sc->sc_intr_lock);
        DPRINTF(("uhci_run: setting run=%d\n", run));
        cmd = UREAD2(sc, UHCI_CMD);
        if (run)
@@ -1760,14 +1761,16 @@
                running = !(UREAD2(sc, UHCI_STS) & UHCI_STS_HCH);
                /* return when we've entered the state we want */
                if (run == running) {
-                       mutex_spin_exit(&sc->sc_intr_lock);
+                       if (!locked)
+                               mutex_spin_exit(&sc->sc_intr_lock);
                        DPRINTF(("uhci_run: done cmd=0x%x sts=0x%x\n",
                                 UREAD2(sc, UHCI_CMD), UREAD2(sc, UHCI_STS)));
                        return (USBD_NORMAL_COMPLETION);
                }
                usb_delay_ms_locked(&sc->sc_bus, 1, &sc->sc_intr_lock);
        }
-       mutex_spin_exit(&sc->sc_intr_lock);
+       if (!locked)
+               mutex_spin_exit(&sc->sc_intr_lock);
        printf("%s: cannot %s\n", device_xname(sc->sc_dev),
               run ? "start" : "stop");
        return (USBD_IOERROR);



Home | Main Index | Thread Index | Old Index