tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
restarting a UHCI controller after "host controller halted"
Hi,
background: I have a home-made USB device which gets attached as a USB modem:
ehci2: handing over low speed device on port 3 to uhci6
uhub9: port 3, device disappeared after reset
umodem0 at uhub8 port 1 configuration 1 interface 0
umodem0: LIP6/SoC USB Thermo, rev 2.00/0.71, addr 2, iclass 2/2
umodem0: data interface 1, has no CM over data, has no break
umodem0: status change notification available
ucom0 at umodem0
Once in a while, when openning /dev/ttyU0 (the application open/close
it several times per minutes), I get:
uhci6: host controller process error
uhci6: host controller halted
When this happens the device's firmware reports a PID error when connected
to a Intel EHCI, but no error when connected to a VIA EHCI. Also, the
UHCI docs refers to a PID error for a possible cause of "host controller
process error". Because of this I think the issue is on the host
side, and more specifically I suspect there's a race between CPU and
controller when updating the descriptor lists (I need to look at this
more closely).
When a "host controller halted" is reported, the controller is dead, and
a reboot is required to get it working again. It's annoying by itself,
even if it's currently triggered by a software error.
With the attached patch, the controller is reset and restarted, and
stay functionnal:
uhci6: host controller process error
uhci6: host controller halted
umodem0: at uhub8 port 1 (addr 2) disconnected
ucom0: detached
umodem0: detached
ehci2: handing over low speed device on port 3 to uhci6
uhub9: port 3, device disappeared after reset
umodem0 at uhub8 port 1 configuration 1 interface 0
umodem0: LIP6/SoC USB Thermo, rev 2.00/0.71, addr 2, iclass 2/2
umodem0: data interface 1, has no CM over data, has no break
umodem0: status change notification available
ucom0 at umodem0
would anyone object if I commit it ? It has been tested on both a Intel
EHCI and add-on VIA EHCI.
--
Manuel Bouyer <bouyer%antioche.eu.org@localhost>
NetBSD: 26 ans d'experience feront toujours la difference
--
Index: uhci.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/uhci.c,v
retrieving revision 1.219
diff -u -p -u -r1.219 uhci.c
--- uhci.c 2 Jun 2008 01:02:21 -0000 1.219
+++ uhci.c 2 Jun 2008 20:49:20 -0000
@@ -1259,20 +1259,38 @@ uhci_intr1(uhci_softc_t *sc)
device_xname(sc->sc_dev));
}
if (status & UHCI_STS_HCH) {
- /* no acknowledge needed */
if (!sc->sc_dying) {
printf("%s: host controller halted\n",
device_xname(sc->sc_dev));
#ifdef UHCI_DEBUG
uhci_dump_all(sc);
#endif
+ ack |= UHCI_STS_HCH;
}
- sc->sc_dying = 1;
}
if (!ack)
- return (0); /* nothing to acknowledge */
- UWRITE2(sc, UHCI_STS, ack); /* acknowledge the ints */
+ return (0); /* nothing to acknowledge */
+ UWRITE2(sc, UHCI_STS, ack & ~UHCI_STS_HCH); /* acknowledge the ints */
+ if (ack & UHCI_STS_HCH) {
+ sc->sc_bus.use_polling++;
+ uhci_run(sc, 0);
+ UWRITE2(sc, UHCI_INTR, 0);
+ uhci_globalreset(sc);
+ uhci_reset(sc);
+ UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE |
+ UHCI_INTR_IOCE | UHCI_INTR_SPIE);
+ UHCICMD(sc, UHCI_CMD_MAXP); /* Assume 64 byte packets at frame
end */
+ UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&sc->sc_dma, 0));
+ uhci_run(sc, 1);
+ sc->sc_bus.use_polling--;
+ if (UREAD2(sc, UHCI_STS) & UHCI_STS_HCH) {
+ printf("%s: host controller couldn't be restarted\n",
+ device_xname(sc->sc_dev));
+ sc->sc_dying = 1;
+ return (0);
+ }
+ }
sc->sc_bus.no_intrs++;
usb_schedsoftintr(&sc->sc_bus);
Home |
Main Index |
Thread Index |
Old Index