aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDon Lewis <truckman@FreeBSD.org>2007-08-12 18:45:24 +0000
committerDon Lewis <truckman@FreeBSD.org>2007-08-12 18:45:24 +0000
commit4d54b88811d95961d759a77daad84d5bb4990e53 (patch)
tree28615061eab47cfdd635b8a3c1f0aafa636ff4da
parent9136384dc29f227386e3fcb1524e2db62146d27a (diff)
Notes
-rw-r--r--sys/dev/usb/ehci.c56
1 files changed, 38 insertions, 18 deletions
diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c
index 2ce95e68375d..6b99d54b42e3 100644
--- a/sys/dev/usb/ehci.c
+++ b/sys/dev/usb/ehci.c
@@ -311,6 +311,39 @@ static struct usbd_pipe_methods ehci_device_isoc_methods = {
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 */
+ for (i = 0; i < 100; i++) {
+ usb_delay_ms(&sc->sc_bus, 1);
+ hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
+ if (hcr)
+ break;
+ }
+ if (!hcr)
+ /*
+ * Fall through and try reset anyway even though
+ * Table 2-9 in the EHCI spec says this will result
+ * in undefined behavior.
+ */
+ printf("%s: stop timeout\n",
+ device_get_nameunit(sc->sc_bus.bdev));
+
+ 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 +398,9 @@ ehci_init(ehci_softc_t *sc)
/* 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 +949,7 @@ ehci_detach(struct ehci_softc *sc, int flags)
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 +1111,7 @@ ehci_shutdown(void *v)
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