From owner-svn-src-all@FreeBSD.ORG Thu Aug 13 07:21:24 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A7C2F106564A; Thu, 13 Aug 2009 07:21:24 +0000 (UTC) (envelope-from n_hibma@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 7D21E8FC51; Thu, 13 Aug 2009 07:21:24 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n7D7LOse090863; Thu, 13 Aug 2009 07:21:24 GMT (envelope-from n_hibma@svn.freebsd.org) Received: (from n_hibma@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n7D7LOWd090861; Thu, 13 Aug 2009 07:21:24 GMT (envelope-from n_hibma@svn.freebsd.org) Message-Id: <200908130721.n7D7LOWd090861@svn.freebsd.org> From: Nick Hibma Date: Thu, 13 Aug 2009 07:21:24 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r196167 - stable/7/sys/dev/usb X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Aug 2009 07:21:25 -0000 Author: n_hibma Date: Thu Aug 13 07:21:24 2009 New Revision: 196167 URL: http://svn.freebsd.org/changeset/base/196167 Log: Restart the controller if it has halted. Restarting it makes the USB tree functional again (without reconnecting the devices, mind you). On my laptop there is probably a short somewhere on the motherboard and once in a while the host controller halts. Modified: stable/7/sys/dev/usb/uhci.c Modified: stable/7/sys/dev/usb/uhci.c ============================================================================== --- stable/7/sys/dev/usb/uhci.c Thu Aug 13 07:19:43 2009 (r196166) +++ stable/7/sys/dev/usb/uhci.c Thu Aug 13 07:21:24 2009 (r196167) @@ -1205,20 +1205,55 @@ uhci_intr1(uhci_softc_t *sc) device_get_nameunit(sc->sc_bus.bdev)); } if (status & UHCI_STS_HCH) { - /* no acknowledge needed */ if (!sc->sc_dying) { + ack |= UHCI_STS_HCH; printf("%s: host controller halted\n", - device_get_nameunit(sc->sc_bus.bdev)); -#ifdef USB_DEBUG - uhci_dump_all(sc); -#endif + device_get_nameunit(sc->sc_bus.bdev)); } - sc->sc_dying = 1; } if (!ack) return (0); /* nothing to acknowledge */ - UWRITE2(sc, UHCI_STS, ack); /* acknowledge the ints */ + + UWRITE2(sc, UHCI_STS, ack & ~UHCI_STS_HCH); /* acknowledge the ints */ + + if (ack & UHCI_STS_HCH) { + /* Restart the controller, by Manuel Bouyer */ + sc->sc_saved_frnum = UREAD2(sc, UHCI_FRNUM); + sc->sc_saved_sof = UREAD1(sc, UHCI_SOF); + + sc->sc_bus.use_polling++; + uhci_run(sc, 0); /* stop the controller */ + UWRITE2(sc, UHCI_INTR, 0); /* disable intrs */ + + uhci_globalreset(sc); + uhci_reset(sc); + + /* restore saved state */ + UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&sc->sc_dma, 0)); + UWRITE2(sc, UHCI_FRNUM, sc->sc_saved_frnum); + UWRITE1(sc, UHCI_SOF, sc->sc_saved_sof); + + UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE | + UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* re-enable intrs */ + UHCICMD(sc, UHCI_CMD_MAXP); + + uhci_run(sc, 1); /* and start traffic again */ + sc->sc_bus.use_polling--; + + if (UREAD2(sc, UHCI_STS) & UHCI_STS_HCH) { + printf("%s: host controller couldn't be restarted\n", + device_get_nameunit(sc->sc_bus.bdev)); +#ifdef USB_DEBUG + uhci_dump_all(sc); +#endif + sc->sc_dying = 1; + return (0); + } + + printf("%s: host controller restarted\n", + device_get_nameunit(sc->sc_bus.bdev)); + } sc->sc_bus.no_intrs++; usb_schedsoftintr(&sc->sc_bus);