PERFORCE change 154065 for review
Sam Leffler
sam at FreeBSD.org
Thu Dec 4 11:15:39 PST 2008
http://perforce.freebsd.org/chv.cgi?CH=154065
Change 154065 by sam at 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 */
More information about the p4-projects
mailing list