Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 23 Dec 2008 04:42:11 +0000 (UTC)
From:      Sam Leffler <sam@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r186415 - head/sys/dev/usb
Message-ID:  <200812230442.mBN4gBmV080928@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sam
Date: Tue Dec 23 04:42:10 2008
New Revision: 186415
URL: http://svn.freebsd.org/changeset/base/186415

Log:
  o add Transaction Translator support (still missing ISOC xfers)
  o add EHCI_SCFLG_BIGEMMIO flag to force big-endian byte-select to be
    set in USBMODE
  o split reset work into new public routine ehci_reset so bus shim drivers
    can force big-endian byte-select before ehci_init

Modified:
  head/sys/dev/usb/ehci.c
  head/sys/dev/usb/ehcivar.h

Modified: head/sys/dev/usb/ehci.c
==============================================================================
--- head/sys/dev/usb/ehci.c	Tue Dec 23 04:36:11 2008	(r186414)
+++ head/sys/dev/usb/ehci.c	Tue Dec 23 04:42:10 2008	(r186415)
@@ -310,33 +310,18 @@ static struct usbd_pipe_methods ehci_dev
 	ehci_device_isoc_done,
 };
 
-static usbd_status
-ehci_hcreset(ehci_softc_t *sc)
+usbd_status
+ehci_reset(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.
-                 */
-		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) {
+			if (sc->sc_flags & (EHCI_SCFLG_SETMODE | EHCI_SCFLG_BIGEMMIO)) {
 				/*
 				 * Force USBMODE as requested.  Controllers
 				 * may have multiple operating modes.
@@ -347,6 +332,11 @@ ehci_hcreset(ehci_softc_t *sc)
 					device_printf(sc->sc_bus.bdev,
 					    "set host controller mode\n");
 				}
+				if (sc->sc_flags & EHCI_SCFLG_BIGEMMIO) {
+					usbmode = (usbmode &~ EHCI_UM_ES) | EHCI_UM_ES_BE;
+					device_printf(sc->sc_bus.bdev,
+					    "set big-endian mode\n");
+				}
 				EOWRITE4(sc,  EHCI_USBMODE, usbmode);
 			}
 			return (USBD_NORMAL_COMPLETION);
@@ -356,6 +346,30 @@ ehci_hcreset(ehci_softc_t *sc)
 	return (USBD_IOERROR);
 }
 
+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.
+                 */
+		device_printf(sc->sc_bus.bdev, "stop timeout\n");
+
+	return ehci_reset(sc);
+}
+
 usbd_status
 ehci_init(ehci_softc_t *sc)
 {
@@ -2008,7 +2022,7 @@ ehci_root_ctrl_start(usbd_xfer_handle xf
 
 		i = UPS_HIGH_SPEED;
 
-		if (sc->sc_flags & EHCI_SCFLG_FORCESPEED) {
+		if (sc->sc_flags & (EHCI_SCFLG_FORCESPEED | EHCI_SCFLG_TT)) {
 			if ((v & 0xc000000) == 0x8000000)
 				i = UPS_HIGH_SPEED;
 			else if ((v & 0xc000000) == 0x4000000)
@@ -2056,7 +2070,8 @@ ehci_root_ctrl_start(usbd_xfer_handle xf
 		case UHF_PORT_RESET:
 			DPRINTFN(5,("ehci_root_ctrl_start: reset port %d\n",
 				    index));
-			if (EHCI_PS_IS_LOWSPEED(v)) {
+			if (EHCI_PS_IS_LOWSPEED(v) &&
+			    (sc->sc_flags & EHCI_SCFLG_TT) == 0) {
 				/* Low speed device, give up ownership. */
 				ehci_disown(sc, index, 1);
 				break;
@@ -2089,7 +2104,8 @@ ehci_root_ctrl_start(usbd_xfer_handle xf
 				       device_get_nameunit(sc->sc_bus.bdev));
 				return (USBD_TIMEOUT);
 			}
-			if (!(v & EHCI_PS_PE)) {
+			if (!(v & EHCI_PS_PE) &&
+			    (sc->sc_flags & EHCI_SCFLG_TT) == 0) {
 				/* Not a high speed device, give up ownership.*/
 				ehci_disown(sc, index, 0);
 				break;

Modified: head/sys/dev/usb/ehcivar.h
==============================================================================
--- head/sys/dev/usb/ehcivar.h	Tue Dec 23 04:36:11 2008	(r186414)
+++ head/sys/dev/usb/ehcivar.h	Tue Dec 23 04:42:10 2008	(r186415)
@@ -126,6 +126,8 @@ struct ehci_soft_islot {
 #define EHCI_SCFLG_FORCESPEED	0x0008	/* force speed (Marvell) */
 #define EHCI_SCFLG_NORESTERM	0x0010	/* don't terminate reset sequence (Marvell) */
 #define	EHCI_SCFLG_BIGEDESC	0x0020	/* big-endian byte order descriptors */
+#define	EHCI_SCFLG_BIGEMMIO	0x0040	/* big-endian byte order MMIO */
+#define	EHCI_SCFLG_TT		0x0080	/* transaction translator present */
 
 typedef struct ehci_softc {
 	struct usbd_bus sc_bus;		/* base device */
@@ -257,6 +259,7 @@ hc16toh(const struct ehci_softc *sc, con
 }
 #endif
 
+usbd_status	ehci_reset(ehci_softc_t *);
 usbd_status	ehci_init(ehci_softc_t *);
 int		ehci_intr(void *);
 int		ehci_detach(ehci_softc_t *, int);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200812230442.mBN4gBmV080928>