NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/42979 (Data toggle issues in usb(4), slhci(4), uhci(4) and ehci(4))



The slhci patch should use USB_MAX_ENDPOINTS instead of 16.
The patch below should replace the slhci part originally submitted.
I could rewrite it more in the style of the UHCI changes, if that
is preferred.

This patch is still untested (I don't have the hardware).

-- 
Kind regards,

Yorick Hardy


Index: sys/dev/ic/sl811hs.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/sl811hs.c,v
retrieving revision 1.25
diff -u -r1.25 sl811hs.c
--- sys/dev/ic/sl811hs.c        25 Nov 2009 14:28:50 -0000      1.25
+++ sys/dev/ic/sl811hs.c        16 Mar 2010 23:20:12 -0000
@@ -280,7 +280,7 @@
        struct gcq      ap;             /* All pipes */
        struct gcq      to;             /* Timeout list */
        struct gcq      xq;             /* Xfer queues */
-       unsigned int    pflags;         /* Pipe flags */
+       unsigned int    *pflags;        /* Pipe flags */
 #define PF_GONE                (0x01)          /* Pipe is on disabled device */
 #define PF_TOGGLE      (0x02)          /* Data toggle status */
 #define PF_LS          (0x04)          /* Pipe is low speed */
@@ -433,6 +433,7 @@
 void slhci_freem(struct usbd_bus *, usb_dma_t *);
 struct usbd_xfer * slhci_allocx(struct usbd_bus *);
 void slhci_freex(struct usbd_bus *, struct usbd_xfer *);
+void slhci_clear_all_toggle(struct usbd_bus *);
 
 usbd_status slhci_transfer(struct usbd_xfer *);
 usbd_status slhci_start(struct usbd_xfer *);
@@ -685,6 +686,7 @@
        slhci_freem,
        slhci_allocx,
        slhci_freex,
+       slhci_clear_all_toggle,
 };
 
 const struct usbd_pipe_methods slhci_pipe_methods = {
@@ -849,6 +851,15 @@
        free(xfer, M_USB);
 }
 
+void slhci_clear_all_toggle(struct usbd_bus *bus)
+{
+       struct slhci_softc *sc = bus->hci_private;
+       int i;
+
+       for (i = 0; i < 32; i++)
+               sc->pflags[i] &= ~PF_TOGGLE;
+}
+
 usbd_status
 slhci_transfer(struct usbd_xfer *xfer)
 {
@@ -923,7 +934,7 @@
        spipe->newlen[1] = min(xfer->length, max_packet);
 
        if (spipe->ptype == PT_BULK || spipe->ptype == PT_INTR) {
-               if (spipe->pflags & PF_TOGGLE)
+               if (*(spipe->pflags) & PF_TOGGLE)
                        spipe->control |= SL11_EPCTRL_DATATOGGLE;
                spipe->tregs[LEN] = spipe->newlen[1];
                if (spipe->tregs[LEN]) 
@@ -971,10 +982,10 @@
         * same place shares constants. Index 0 is "short length" for bulk and 
         * ctrl data and 1 is "full length" for ctrl data (bulk/intr are 
         * already set to full length). */
-       if (spipe->pflags & PF_LS) {
+       if (*(spipe->pflags) & PF_LS) {
                /* Setting PREAMBLE for directly connnected LS devices will
                 * lock up the chip. */
-               if (spipe->pflags & PF_PREAMBLE)
+               if (*(spipe->pflags) & PF_PREAMBLE)
                        spipe->control |= SL11_EPCTRL_PREAMBLE;
                if (max_packet <= 8) {
                        spipe->bustime = SLHCI_LS_CONST + 
@@ -1031,6 +1042,7 @@
        usb_endpoint_descriptor_t *ed;
        struct slhci_transfers *t;
        unsigned int max_packet, pmaxpkt;
+       int epaddr;
 
        dev = pipe->device;
        sc = dev->bus->hci_private;
@@ -1041,7 +1053,13 @@
        DLOG(D_TRACE, "slhci_open(addr=%d,ep=%d,rootaddr=%d)",
                dev->address, ed->bEndpointAddress, t->rootaddr, 0);
 
-       spipe->pflags = 0;
+       epaddr = UE_GET_ADDR(ed->bEndpointAddress);
+       if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT)
+               spipe->pflags = &(sc->pflags[epaddr]);
+       else
+               spipe->pflags = &(sc->pflags[epaddr + USB_MAX_ENDPOINTS]);
+
+       *(spipe->pflags) &= PF_TOGGLE; /* clear all flags except toggle */
        spipe->frame = 0;
        spipe->lastframe = 0;
        spipe->xfer = NULL;
@@ -1058,9 +1076,9 @@
        max_packet = UGETW(ed->wMaxPacketSize);
 
        if (dev->speed == USB_SPEED_LOW) {
-               spipe->pflags |= PF_LS;
+               *(spipe->pflags) |= PF_LS;
                if (dev->myhub->address != t->rootaddr) {
-                       spipe->pflags |= PF_PREAMBLE;
+                       *(spipe->pflags) |= PF_PREAMBLE;
                        if (!slhci_try_lsvh)
                                return slhci_lock_call(sc, &slhci_lsvh_warn, 
                                    spipe, NULL);
@@ -1291,7 +1309,7 @@
        DLOG(D_TRACE, "%s toggle spipe %p", pnames(spipe->ptype), 
            spipe,0,0);
 
-       spipe->pflags &= ~PF_TOGGLE;
+       *(spipe->pflags) &= ~PF_TOGGLE;
 
 #ifdef DIAGNOSTIC
        if (spipe->xfer != NULL) {
@@ -2085,7 +2103,7 @@
 status_setup:
                        /* CTRL_DATA swaps direction in PID then jumps here */
                        spipe->tregs[LEN] = 0;
-                       if (spipe->pflags & PF_LS)
+                       if (*(spipe->pflags) & PF_LS)
                                spipe->bustime = SLHCI_LS_CONST;
                        else
                                spipe->bustime = SLHCI_FS_CONST;
@@ -2140,9 +2158,9 @@
                         * current setting will apply to the next 
                         * transfer. */ 
                        if (spipe->control & SL11_EPCTRL_DATATOGGLE)
-                               spipe->pflags |= PF_TOGGLE;
+                               *(spipe->pflags) |= PF_TOGGLE;
                        else
-                               spipe->pflags &= ~PF_TOGGLE;
+                               *(spipe->pflags) &= ~PF_TOGGLE;
 
                        head = Q_CALLBACKS;
                }
@@ -2373,7 +2391,7 @@
        SLHCI_MAINLOCKASSERT(sc);
 
        if (__predict_false(t->flags & F_DISABLED) || 
-           __predict_false(spipe->pflags & PF_GONE)) {
+           __predict_false(*(spipe->pflags) & PF_GONE)) {
                DLOG(D_MSG, "slhci_enter_xfer: DISABLED or GONE", 0,0,0,0);
                spipe->xfer->status = USBD_CANCELLED; 
        }
@@ -2799,7 +2817,7 @@
        /* Cancel all pipes.  Note that not all of these may be on the 
         * callback queue yet; some could be in slhci_start, for example. */
        FOREACH_AP(q, t, spipe) {
-               spipe->pflags = PF_GONE;
+               *(spipe->pflags) = PF_GONE;
                spipe->pipe.repeat = 0;
                spipe->pipe.aborting = 1;
                if (spipe->xfer != NULL)
@@ -2928,7 +2946,7 @@
        t = &sc->sc_transfers;
        max_packet = UGETW(spipe->pipe.endpoint->edesc->wMaxPacketSize);
 
-       if (spipe->pflags & PF_LS)
+       if (*(spipe->pflags) & PF_LS)
                bustime = SLHCI_LS_CONST + SLHCI_LS_DATA_TIME(max_packet);
        else
                bustime = SLHCI_FS_CONST + SLHCI_FS_DATA_TIME(max_packet);
@@ -3612,7 +3630,7 @@
            "AP" : "", gcq_onlist(&spipe->to) ? "TO" : "", 
            gcq_onlist(&spipe->xq) ? "XQ" : "");
        DDOLOG("spipe: xfer %p buffer %p pflags %#x ptype %s",
-           spipe->xfer, spipe->buffer, spipe->pflags, pnames(spipe->ptype));
+           spipe->xfer, spipe->buffer, *(spipe->pflags), pnames(spipe->ptype));
 }
 
 void
Index: sys/dev/ic/sl811hsvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/sl811hsvar.h,v
retrieving revision 1.6
diff -u -r1.6 sl811hsvar.h
--- sys/dev/ic/sl811hsvar.h     12 May 2009 14:25:18 -0000      1.6
+++ sys/dev/ic/sl811hsvar.h     16 Mar 2010 23:20:13 -0000
@@ -83,6 +83,8 @@
 
        uint8_t                 sc_ier;         /* enabled interrupts */
        uint8_t                 sc_stride;      /* port stride */
+
+       unsigned int            pflags[2*USB_MAX_ENDPOINTS];    /* Pipe flags 
for each endpoint */
 };
 
 /* last preinit arguments are: max current (in mA, not mA/2), port stride */


Home | Main Index | Thread Index | Old Index