]> git.lizzy.rs Git - plan9front.git/commitdiff
usb: fix wrong pollival calculation in setmaxpkt()
authorcinap_lenrek <cinap_lenrek@felloff.net>
Mon, 24 Jul 2017 21:47:55 +0000 (23:47 +0200)
committercinap_lenrek <cinap_lenrek@felloff.net>
Mon, 24 Jul 2017 21:47:55 +0000 (23:47 +0200)
sys/src/9/port/devusb.c
sys/src/9/port/usb.h
sys/src/cmd/nusb/lib/dev.c

index 35da994a0fcb310564e6e774fed3d463ad4d799d..0eb8db37a4a43e440413878f4aaf3b104d934a55 100644 (file)
@@ -1084,18 +1084,12 @@ usbread(Chan *c, void *a, long n, vlong offset)
        return n;
 }
 
-static long
-pow2(int n)
-{
-       return 1 << n;
-}
-
 static void
 setmaxpkt(Ep *ep, char* s)
 {
-       long spp;       /* samples per packet */
+       long spp, max;  /* samples per packet */
 
-       if(ep->dev->speed == Highspeed)
+       if(ep->dev->speed == Highspeed || ep->dev->speed == Superspeed)
                spp = (ep->hz * ep->pollival * ep->ntds + 7999) / 8000;
        else
                spp = (ep->hz * ep->pollival + 999) / 1000;
@@ -1104,9 +1098,24 @@ setmaxpkt(Ep *ep, char* s)
                " ntds %d %s speed -> spp %ld maxpkt %ld\n", s,
                ep->hz, ep->pollival, ep->ntds, spname[ep->dev->speed],
                spp, ep->maxpkt);
-       if(ep->maxpkt > 1024){
-               print("usb: %s: maxpkt %ld > 1024. truncating\n", s, ep->maxpkt);
-               ep->maxpkt = 1024;
+
+       switch(ep->dev->speed){
+       case Fullspeed:
+               max = 1024;
+               break;
+       case Highspeed:
+               max = 3*1024;
+               break;
+       case Superspeed:
+               max = 48*1024;
+               break;
+       default:
+               return;
+       }
+       if(ep->maxpkt*ep->ntds > max){
+               print("usb: %s: maxpkt %ld > %ld for %s, truncating\n",
+                       s, ep->maxpkt*ep->ntds, max, spname[ep->dev->speed]);
+               ep->maxpkt = max/ep->ntds;
        }
 }
 
@@ -1164,7 +1173,7 @@ epctl(Ep *ep, Chan *c, void *a, long n)
                        error("speed must be full|low|high");
                nep = newdev(ep->hp, 0, 0);
                nep->dev->speed = l;
-               if(nep->dev->speed  != Lowspeed)
+               if(nep->dev->speed != Lowspeed)
                        nep->maxpkt = 64;       /* assume full speed */
                nep->dev->hub = d->addr;
                nep->dev->port = atoi(cb->f[2]);
@@ -1214,14 +1223,14 @@ epctl(Ep *ep, Chan *c, void *a, long n)
                        error("not an intr or iso endpoint");
                l = strtoul(cb->f[1], nil, 0);
                deprint("usb epctl %s %d\n", cb->f[0], l);
-               if(ep->ttype == Tiso ||
-                  (ep->ttype == Tintr && ep->dev->speed == Highspeed)){
+               if(ep->dev->speed == Highspeed || ep->dev->speed == Superspeed){
                        if(l < 1 || l > 16)
                                error("pollival power not in [1:16]");
-                       l = pow2(l-1);
-               }else
+                       l = 1 << l-1;
+               } else {
                        if(l < 1 || l > 255)
                                error("pollival not in [1:255]");
+               }
                qlock(ep);
                ep->pollival = l;
                if(ep->ttype == Tiso)
index 2853513e1de8031301d99d6b6d9d61e44df6c09e..655ee4f4f5859fcaccf9907b4a0cf43305f20f1b 100644 (file)
@@ -162,11 +162,11 @@ struct Ep
        char*   info;           /* for humans to read */
        long    maxpkt;         /* maximum packet size */
        int     ttype;          /* tranfer type */
-       ulong   load;           /* in µs, for a fransfer of maxpkt bytes */
+       ulong   load;           /* in µs, for a transfer of maxpkt bytes */
        void*   aux;            /* for controller specific info */
        int     rhrepl;         /* fake root hub replies */
        int     toggle[2];      /* saved toggles (while ep is not in use) */
-       long    pollival;               /* poll interval ([µ]frames; intr/iso) */
+       long    pollival;       /* poll interval ([µ]frames; intr/iso) */
        long    hz;             /* poll frequency (iso) */
        long    samplesz;       /* sample size (iso) */
        int     ntds;           /* nb. of Tds per µframe */
index cd9d15a3856ec6d5cb78d2d89e89e595a6f96f5c..f7bcc04ae28111ef558033705db0d868a2a98a2e 100644 (file)
@@ -45,11 +45,6 @@ openep(Dev *d, int id)
                return nil;
        }
        ep = ud->ep[id];
-       mode = "rw";
-       if(ep->dir == Ein)
-               mode = "r";
-       if(ep->dir == Eout)
-               mode = "w";
        snprint(name, sizeof(name), "/dev/usb/ep%d.%d", d->id, id);
        if(access(name, AEXIST) == 0){
                dprint(2, "%s: %s already exists; trying to open\n", argv0, name);
@@ -60,6 +55,11 @@ openep(Dev *d, int id)
                }
                return epd;
        }
+       mode = "rw";
+       if(ep->dir == Ein)
+               mode = "r";
+       if(ep->dir == Eout)
+               mode = "w";
        if(devctl(d, "new %d %d %s", id, ep->type, mode) < 0){
                dprint(2, "%s: %s: new: %r\n", argv0, d->dir);
                return nil;
@@ -79,13 +79,6 @@ openep(Dev *d, int id)
        else
                dprint(2, "%s: %s: ntds %d\n", argv0, epd->dir, ep->ntds);
 
-       /*
-        * For iso endpoints and high speed interrupt endpoints the pollival is
-        * actually 2ⁿ and not n.
-        * The kernel usb driver must take that into account.
-        * It's simpler this way.
-        */
-
        if(ac != nil && (ep->type == Eintr || ep->type == Eiso) && ac->interval != 0)
                if(devctl(epd, "pollival %d", ac->interval) < 0)
                        fprint(2, "%s: %s: openep: pollival: %r\n", argv0, epd->dir);