Date: Thu, 4 Dec 2008 19:15:38 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 154065 for review Message-ID: <200812041915.mB4JFc1t016631@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=154065 Change 154065 by sam@sam_ebb on 2008/12/04 19:14:40 o cleanup EHCI_SCFLG_SETMODE; we also need it for the ixp435 integral controller; it really means to force Host Controller mode after doing a reset o add EHCI_SCFLG_BIGENDIAN to enable support for big-endian byte alignment on controllers that support it; we need to manually handle big/little endian issues before reset and then after select big-endian handling in the controller Note big-endian changes are likely incomplete, still don't have working usb on the Cambria board. Affected files ... .. //depot/projects/vap/sys/dev/usb/ehci.c#15 edit .. //depot/projects/vap/sys/dev/usb/ehcivar.h#9 edit Differences ... ==== //depot/projects/vap/sys/dev/usb/ehci.c#15 (text+ko) ==== @@ -344,17 +344,33 @@ * 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)); + device_printf(sc->sc_bus.bdev, "stop timeout\n"); 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) { - if (sc->sc_flags & EHCI_SCFLG_SETMODE) - EOWRITE4(sc, 0x68, 0x3); - + if (sc->sc_flags & (EHCI_SCFLG_SETMODE | EHCI_SCFLG_BIGENDIAN)) { + /* + * Force USBMODE as requested. Controllers + * may have multiple operating modes and on + * some platforms we need to force big-endian + * byte alignement of data structures. + */ + uint32_t usbmode = EOREAD4(sc, EHCI_USBMODE); + if (sc->sc_flags & EHCI_SCFLG_SETMODE) { + usbmode = (usbmode &~ EHCI_UM_CM) | EHCI_UM_CM_HOST; + device_printf(sc->sc_bus.bdev, + "set host controller mode\n"); + } + if (sc->sc_flags & EHCI_SCFLG_BIGENDIAN) { + usbmode |= EHCI_UM_ES_BE; + device_printf(sc->sc_bus.bdev, + "set big-endian byte alignment\n"); + } + EOWRITE4(sc, EHCI_USBMODE, usbmode); + } return (USBD_NORMAL_COMPLETION); } } @@ -377,10 +393,14 @@ theehci = sc; #endif - sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH); + /* NB: must handle byte-order manually before ehci_hcreset */ + + sc->sc_offs = EREAD1(sc, sc->sc_flags & EHCI_SCFLG_BIGENDIAN ? + 3-EHCI_CAPLENGTH : EHCI_CAPLENGTH); - version = EREAD2(sc, EHCI_HCIVERSION); - printf("%s: EHCI version %x.%x\n", device_get_nameunit(sc->sc_bus.bdev), + version = EREAD2(sc, sc->sc_flags & EHCI_SCFLG_BIGENDIAN ? + 2-EHCI_HCIVERSION : EHCI_HCIVERSION); + device_printf(sc->sc_bus.bdev, "EHCI version %x.%x\n", version >> 8, version & 0xff); sparams = EREAD4(sc, EHCI_HCSPARAMS); ==== //depot/projects/vap/sys/dev/usb/ehcivar.h#9 (text+ko) ==== @@ -125,6 +125,7 @@ #define EHCI_SCFLG_SETMODE 0x0004 /* set bridge mode again after init (Marvell) */ #define EHCI_SCFLG_FORCESPEED 0x0008 /* force speed (Marvell) */ #define EHCI_SCFLG_NORESTERM 0x0010 /* don't terminate reset sequence (Marvell) */ +#define EHCI_SCFLG_BIGENDIAN 0x0020 /* set big-endian select on reset */ typedef struct ehci_softc { struct usbd_bus sc_bus; /* base device */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200812041915.mB4JFc1t016631>