- 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/sources/patch/maybe/usb-short-desc Date: Wed Mar 5 15:00:36 CET 2014 Signed-off-by: quanstro@quanstro.net --- /sys/src/cmd/usb/lib/dev.c Wed Mar 5 15:00:26 2014 +++ /sys/src/cmd/usb/lib/dev.c Wed Mar 5 15:00:24 2014 @@ -188,6 +188,8 @@ char *s; char *e; + if(n > b[0]) + n = b[0]; if(n <= 2 || (n & 1) != 0) return strdup("none"); n = (n - 2)/2; @@ -204,42 +206,37 @@ char* loaddevstr(Dev *d, int sid) { - uchar buf[128]; - int type; - int nr; + uchar buf[256]; + int type, langid, nr; if(sid == 0) return estrdup("none"); type = Rd2h|Rstd|Rdev; - nr=usbcmd(d, type, Rgetdesc, Dstr<<8|sid, 0, buf, sizeof(buf)); + nr = usbcmd(d, type, Rgetdesc, Dstr<<8|sid, 0, buf, sizeof(buf)); + if(nr < 4) + langid = 0x0409; /* english */ + else + langid = buf[3]<<8 | buf[2]; + nr = usbcmd(d, type, Rgetdesc, Dstr<<8|sid, langid, buf, sizeof(buf)); + return mkstr(buf, nr); } int loaddevdesc(Dev *d) { - uchar buf[Ddevlen+255]; + uchar buf[Ddevlen]; int nr; int type; Ep *ep0; 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; - /* - * 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\n", - argv0, d->dir); - 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); @@ -254,6 +251,8 @@ d->usb->serial = loaddevstr(d, d->usb->ssid); } } + else + print("usbd: desc error: %r"); return nr; }