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 _at__at_ -311,6 +311,25 _at__at_ 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) { _at__at_ -365,20 +384,9 _at__at_ /* 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))) { _at__at_ -927,8 +935,7 _at__at_ 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); _at__at_ -1090,8 +1097,7 _at__at_ 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_statusReceived on Fri Aug 10 2007 - 13:05:23 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:16 UTC