- loaddevdesc() should request 18 bytes as per the spec. this avoids the problem of getting just a 17 byte descriptor. - loaddevstr() should request 256 bytes, as per standard. respect the length embedded in the string. - loaddevstr() should set a language id. this is important for some devices. Reference: /n/atom/patch/applied/usbshortdesc Date: Tue Mar 4 15:22:10 CET 2014 Signed-off-by: quanstro@quanstro.net --- /sys/src/cmd/usb/lib/dev.c Tue Mar 4 15:18:30 2014 +++ /sys/src/cmd/usb/lib/dev.c Tue Mar 4 15:18:30 2014 @@ -181,14 +181,16 @@ } static char* -mkstr(uchar *b, int n) +mkstr(uchar *b) { Rune r; char *us; char *s; char *e; + int n; - if(n <= 2 || (n & 1) != 0) + n = b[0]+2; + if((n & 1) != 0) return strdup("none"); n = (n - 2)/2; b += 2; @@ -204,7 +206,7 @@ char* loaddevstr(Dev *d, int sid) { - uchar buf[128]; + uchar buf[256]; int type, langid, nr; if(sid == 0) @@ -216,14 +218,16 @@ else langid = buf[3]<<8 | buf[2]; nr = usbcmd(d, type, Rgetdesc, Dstr<<8|sid, langid, buf, sizeof(buf)); + if(nr < 2) + return estrdup("none"); - return mkstr(buf, nr); + return mkstr(buf); } int loaddevdesc(Dev *d) { - uchar buf[Ddevlen+255]; + uchar buf[Ddevlen]; int nr; int type; Ep *ep0; @@ -231,27 +235,11 @@ type = Rd2h|Rstd|Rdev; nr = sizeof(buf); memset(buf, 0, Ddevlen); - if((nr=usbcmd(d, type, Rgetdesc, Ddev<<8|0, 0, buf, nr)) < 0) + if((nr = usbcmd(d, type, Rgetdesc, Ddev<<8|0, 0, buf, Ddevlen)) < 0) return -1; - if(nr == 17){ - print("langid %.4ux\n", buf[3]<<8|buf[2]); - if((nr = usbcmd(d, type, Rgetdesc, Ddev<<8|0, buf[3]<<8|buf[2], buf, 18)) < 0) - return -1; - print("nr = %d %.2ux\n", nr, buf[nr]); - } - - /* - * Several hubs are returning descriptors of 17 bytes, not 18. - * We accept them and leave number of configurations as zero. - * (a get configuration descriptor also fails for them!) - */ if(nr < Ddevlen){ - print("%s: %s: warning: device with short descriptor: %d bytes\n", - argv0, d->dir, nr); - if(nr < Ddevlen-1){ - werrstr("short device descriptor (%d bytes)", nr); - return -1; - } + werrstr("short device descriptor (%d bytes)", nr); + return -1; } d->usb = emallocz(sizeof(Usbdev), 1); ep0 = mkep(d->usb, 0);