Skip site navigation (1)Skip section navigation (2)
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>