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);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to