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 following reply was made to PR kern/42979; it has been noted by GNATS.

From: Yorick Hardy <yorickhardy%gmail.com@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc: martin%NetBSD.org@localhost, kern-bug-people%netbsd.org@localhost, 
netbsd-bugs%netbsd.org@localhost,
        gnats-admin%netbsd.org@localhost
Subject: Re: kern/42979 (Data toggle issues in usb(4), slhci(4), uhci(4) and 
ehci(4))
Date: Wed, 17 Mar 2010 01:37:30 +0200

 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