Some more fixes for some more mice. Reference: /n/sources/patch/applied/usb-mouse Date: Mon Mar 5 15:17:10 CET 2012 Signed-off-by: paurea@lsub.org --- /sys/src/cmd/usb/kb/hid.c Mon Mar 5 15:16:42 2012 +++ /sys/src/cmd/usb/kb/hid.c Mon Mar 5 15:16:40 2012 @@ -31,7 +31,7 @@ else high = 0; ch->b += nbits; - return high | low; + return MSK(nbits)&(high | low); } static void @@ -52,25 +52,42 @@ *vp = get8bits(ch, nbi); } -/* TODO check report id, when it does appear (not all devices) */ int parsereportdesc(HidRepTempl *temp, uchar *repdesc, int repsz) { - int i, j, l, n, isptr, hasxy, hasbut, nk; + int i, j, l, n, isptr, hasxy, hasbut, nk, ncoll; int ks[MaxVals]; HidInterface *ifs; ifs = temp->ifcs; isptr = 0; hasxy = hasbut = 0; + ncoll = 0; n = 0; nk = 0; memset(ifs, 0, sizeof *ifs * MaxIfc); - for(i = 0; i < repsz / 2; i += 2){ - if(n == MaxIfc || repdesc[i] == HidEnd) + for(i = 0; i < repsz; i += 2){ + if(n == MaxIfc) break; + if(repdesc[i] == HidEnd){ + ncoll--; + i--; + if(ncoll == 0) + break; + } switch(repdesc[i]){ + case HidReportId: + switch(repdesc[i+1]){ + case HidReportApp: + temp->id = repdesc[i+1]; + break; + default: + fprint(2, "report type %#ux bad\n",repdesc[i+1]); + return -1; + break; + } + break; case HidTypeUsg: switch(repdesc[i+1]){ case HidX: @@ -118,9 +135,16 @@ ifs[n].nbits = 1; nk = 0; break; + case HidCollection: + ncoll++; + break; } } temp->nifcs = n; + for(i = 0; i < n; i++) + temp->sz += temp->ifcs[i].nbits*temp->ifcs[i].count; + temp->sz = (temp->sz + 7) / 8; + if(isptr && hasxy && hasbut) return 0; fprint(2, "bad report: isptr %d, hasxy %d, hasbut %d\n", --- /sys/src/cmd/usb/kb/hid.h Mon Mar 5 15:16:47 2012 +++ /sys/src/cmd/usb/kb/hid.h Mon Mar 5 15:16:44 2012 @@ -95,17 +95,22 @@ }; struct HidRepTempl{ + int id; /* id which may not be present */ + int sz; /* in bytes */ int nifcs; HidInterface ifcs[MaxIfc]; }; enum { /* report types */ + + HidReportApp = 0x01, HidTypeUsgPg = 0x05, HidPgButts = 0x09, HidTypeRepSz = 0x75, HidTypeCnt = 0x95, + HidCollection = 0xa1, HidTypeUsg = 0x09, HidPtr = 0x01, @@ -116,7 +121,7 @@ HidInput = 0x81, HidReportId = 0x85, - HidEnd = 0x0c, + HidEnd = 0xc0, }; void dumpreport(HidRepTempl *templ); --- /sys/src/cmd/usb/kb/kb.c Mon Mar 5 15:16:52 2012 +++ /sys/src/cmd/usb/kb/kb.c Tue Mar 6 21:08:31 2012 @@ -275,6 +275,13 @@ static char buts[] = {0x0, 0x2, 0x1}; c = ch->e / 8; + + /* sometimes there is a report id, sometimes not */ + if(c == kd->templ.sz + 1) + if( ch->buf[0] == kd->templ.id) + ch->b += 8; + else + return -1; parsereport(&kd->templ, ch); if(kbdebug) @@ -354,7 +361,6 @@ ch.e = 8 * c; if(f->ptrvals(f, &ch, &x, &y, &b) < 0) continue; - if(f->accel){ x = scale(f, x); y = scale(f, y); @@ -619,6 +625,11 @@ kd->in = in; kd->dev = d; res = -1; + kd->ep = openep(d, ep->id); + if(kd->ep == nil){ + fprint(2, "kb: %s: openep %d: %r\n", d->dir, ep->id); + return; + } if(!kd->bootp) res= setfirstconfig(kd, ep->id, desc, sizeof desc); if(res > 0) @@ -632,11 +643,6 @@ } }else if(kbdebug) dumpreport(&kd->templ); - kd->ep = openep(d, ep->id); - if(kd->ep == nil){ - fprint(2, "kb: %s: openep %d: %r\n", d->dir, ep->id); - return; - } if(opendevdata(kd->ep, OREAD) < 0){ fprint(2, "kb: %s: opendevdata: %r\n", kd->ep->dir); closedev(kd->ep);