Reboot on "shutdown -r" hangs after final "uptime ..."
string
Don Lewis
truckman at FreeBSD.org
Fri Aug 10 08:32:31 PDT 2007
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
More information about the freebsd-acpi
mailing list