From owner-freebsd-current@FreeBSD.ORG Fri Aug 10 15:05:23 2007 Return-Path: Delivered-To: current@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id F2F4C16A41A for ; Fri, 10 Aug 2007 15:05:22 +0000 (UTC) (envelope-from truckman@FreeBSD.org) Received: from gw.catspoiler.org (adsl-75-1-14-242.dsl.scrm01.sbcglobal.net [75.1.14.242]) by mx1.freebsd.org (Postfix) with ESMTP id B504E13C461 for ; Fri, 10 Aug 2007 15:05:22 +0000 (UTC) (envelope-from truckman@FreeBSD.org) Received: from FreeBSD.org (mousie.catspoiler.org [192.168.101.2]) by gw.catspoiler.org (8.13.3/8.13.3) with ESMTP id l7AF53jG043973; Fri, 10 Aug 2007 08:05:07 -0700 (PDT) (envelope-from truckman@FreeBSD.org) Message-Id: <200708101505.l7AF53jG043973@gw.catspoiler.org> Date: Fri, 10 Aug 2007 08:05:03 -0700 (PDT) From: Don Lewis To: bruce@cran.org.uk In-Reply-To: <46BC1418.9070008@cran.org.uk> MIME-Version: 1.0 Content-Type: TEXT/plain; charset=us-ascii Cc: tut@nhamon.com.ua, acpi@FreeBSD.org, Thomas.Sparrevohn@btinternet.com, current@FreeBSD.org Subject: Re: RE: Reboot on "shutdown -r" hangs after final "uptime ..." string X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 10 Aug 2007 15:05:23 -0000 On 10 Aug, Bruce Cran wrote: > Thomas Sparrevohn wrote: >> I have the same problem - just as a test try to load a kernel without >> any USB drivers at all And shutdown - on my machine it the ACPI part >> works - however the system hangs during the device Shutdown phase - >> this machine is a dell as well - would be nice if somebody using >> other than dell has the problem >> > I'm running 7.0-CURRENT and am seeing the same problem on my Dell > Inspiron 1501 amd64 laptop. This machine has OHCI and EHCI > controllers; removing the EHCI driver solves the problem and allows > the computer to reboot properly. I initially thought it was an ACPI > problem but now I'm not so sure - is there anything I can do to help > debug it? I've added printfs to kern_shutdown.c and as far as I can > see the last function to be called is shutdown_wait; since that > doesn't do anything I know more is going on, but I don't know where > to look. I'm seeing this problem on an Athlon 64 desktop machine with the NVIDIA GeForce 7050PV / nForce 630a chipset. The hang is occuring at this point in boot() in kern_shutdown.c: /* Now that we're going to really halt the system... */ EVENTHANDLER_INVOKE(shutdown_final, howto); The culprit is an infinite loop in ehci_pci_givecontroller(), which is called from ehci_shutdown(). The infinite loop is triggered by reading the incorrect value from one of the EHCI controller registers because the register is being read before a reset of the controller has completed. Try this patch: Index: sys/dev/usb/ehci.c =================================================================== RCS file: /home/ncvs/src/sys/dev/usb/ehci.c,v retrieving revision 1.55 diff -u -r1.55 ehci.c --- sys/dev/usb/ehci.c 20 Jun 2007 05:10:52 -0000 1.55 +++ sys/dev/usb/ehci.c 4 Aug 2007 21:05:46 -0000 @@ -311,6 +311,25 @@ ehci_device_isoc_done, }; +static usbd_status +ehci_hcreset(ehci_softc_t *sc) +{ + u_int32_t hcr; + u_int i; + + EOWRITE4(sc, EHCI_USBCMD, 0); /* Halt controller */ + usb_delay_ms(&sc->sc_bus, 1); + EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET); + for (i = 0; i < 100; i++) { + usb_delay_ms(&sc->sc_bus, 1); + hcr = EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_HCRESET; + if (!hcr) + return (USBD_NORMAL_COMPLETION); + } + printf("%s: reset timeout\n", device_get_nameunit(sc->sc_bus.bdev)); + return (USBD_IOERROR); +} + usbd_status ehci_init(ehci_softc_t *sc) { @@ -365,20 +384,9 @@ /* Reset the controller */ DPRINTF(("%s: resetting\n", device_get_nameunit(sc->sc_bus.bdev))); - EOWRITE4(sc, EHCI_USBCMD, 0); /* Halt controller */ - usb_delay_ms(&sc->sc_bus, 1); - EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET); - for (i = 0; i < 100; i++) { - usb_delay_ms(&sc->sc_bus, 1); - hcr = EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_HCRESET; - if (!hcr) - break; - } - if (hcr) { - printf("%s: reset timeout\n", - device_get_nameunit(sc->sc_bus.bdev)); - return (USBD_IOERROR); - } + err = ehci_hcreset(sc); + if (err != USBD_NORMAL_COMPLETION) + return (err); /* frame list size at default, read back what we got and use that */ switch (EHCI_CMD_FLS(EOREAD4(sc, EHCI_USBCMD))) { @@ -927,8 +935,7 @@ sc->sc_dying = 1; EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs); - EOWRITE4(sc, EHCI_USBCMD, 0); - EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET); + (void) ehci_hcreset(sc); callout_stop(&sc->sc_tmo_intrlist); callout_stop(&sc->sc_tmo_pcd); @@ -1090,8 +1097,7 @@ ehci_softc_t *sc = v; DPRINTF(("ehci_shutdown: stopping the HC\n")); - EOWRITE4(sc, EHCI_USBCMD, 0); /* Halt controller */ - EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET); + (void) ehci_hcreset(sc); } usbd_status