From aadc58104016170b61b62a31daa295895a640b60 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sat, 24 Nov 2012 16:37:39 +0100 Subject: [PATCH] nusb/kb: zero reads, error handling, priority, cleanup handle short reads as errors and retry. this can happen on ohci and some ps2 to usb converter. it might'v deen caused by a recent change on sources handling td overrun differently. fix error handling. have to check f->ep == nil after recovery and check packet size. also, use f->ep->dfd instead of ptrfd and kbdfd as it might be different after recovery. make a setleds() error non fatal. boost process priority for keyboard and mouse worker processes. cleanup: use single write() in putmod(), improve error reporting. --- sys/src/cmd/nusb/kb/kb.c | 118 +++++++++++++++++++-------------------- 1 file changed, 57 insertions(+), 61 deletions(-) diff --git a/sys/src/cmd/nusb/kb/kb.c b/sys/src/cmd/nusb/kb/kb.c index 57f6913cc..1a4634377 100644 --- a/sys/src/cmd/nusb/kb/kb.c +++ b/sys/src/cmd/nusb/kb/kb.c @@ -6,7 +6,8 @@ * * Mouse events are converted to the format of mouse(3)'s * mousein file. - * Keyboard keycodes are translated to scan codes and sent to kbin(3). + * Keyboard keycodes are translated to scan codes and sent to kbdfs(8) + * on kbin file. * */ @@ -225,35 +226,34 @@ static void ptrwork(void* a) { static char maptab[] = {0x0, 0x1, 0x4, 0x5, 0x2, 0x3, 0x6, 0x7}; - int x, y, b, c, ptrfd; - int mfd, nerrs; - char buf[64]; + int x, y, b, c, nerrs; + char err[ERRMAX], buf[64]; char mbuf[80]; KDev* f = a; - int hipri; - hipri = nerrs = 0; - ptrfd = f->ep->dfd; - mfd = f->in->fd; - - if(f->ep->maxpkt < 3 || f->ep->maxpkt > sizeof buf) - kbfatal(f, "weird mouse maxpkt"); + sethipri(); + nerrs = 0; for(;;){ - memset(buf, 0, sizeof buf); if(f->ep == nil) kbfatal(f, nil); - c = read(ptrfd, buf, f->ep->maxpkt); - assert(f->dev != nil); - assert(f->ep != nil); - if(c < 0){ - dprint(2, "kb: mouse: %s: read: %r\n", f->ep->dir); + if(f->ep->maxpkt < 3 || f->ep->maxpkt > sizeof buf) + kbfatal(f, "mouse: weird mouse maxpkt"); + memset(buf, 0, sizeof buf); + c = read(f->ep->dfd, buf, f->ep->maxpkt); + if(c <= 0){ + if(c < 0) + rerrstr(err, sizeof(err)); + else + strcpy(err, "zero read"); if(++nerrs < 3){ - recoverkb(f); + fprint(2, "%s: mouse: %s: read: %s\n", argv0, f->ep->dir, err); + if(strstr(err, "babble") != 0) + recoverkb(f); continue; } + kbfatal(f, err); } - if(c <= 0) - kbfatal(f, nil); + nerrs = 0; if(c < 3) continue; if(f->accel){ @@ -273,12 +273,8 @@ ptrwork(void* a) if(kbdebug > 1) fprint(2, "%s: m%11d %11d %11d\n", argv0, x, y, b); seprint(mbuf, mbuf+sizeof(mbuf), "m%11d %11d %11d", x, y,b); - if(write(mfd, mbuf, strlen(mbuf)) < 0) + if(write(f->in->fd, mbuf, strlen(mbuf)) < 0) kbfatal(f, "mousein i/o"); - if(hipri == 0){ - sethipri(); - hipri = 1; - } } } @@ -305,16 +301,6 @@ putscan(int kbinfd, uchar esc, uchar sc) { uchar s[2] = {SCesc1, 0}; - if(sc == 0x41){ - kbdebug += 2; - return; - } - if(sc == 0x42){ - kbdebug = 0; - return; - } - if(kbdebug) - fprint(2, "sc: %x %x\n", (esc? SCesc1: 0), sc); s[1] = sc; if(esc && sc != 0) write(kbinfd, s, 2); @@ -370,11 +356,21 @@ Abort: static void putmod(int fd, uchar mods, uchar omods, uchar mask, uchar esc, uchar sc) { - /* BUG: Should be a single write */ - if((mods&mask) && !(omods&mask)) - putscan(fd, esc, sc); - if(!(mods&mask) && (omods&mask)) - putscan(fd, esc, Keyup|sc); + uchar s[4], *p; + + p = s; + if((mods&mask) && !(omods&mask)){ + if(esc) + *p++ = SCesc1; + *p++ = sc; + } + if(!(mods&mask) && (omods&mask)){ + if(esc) + *p++ = SCesc1; + *p++ = Keyup|sc; + } + if(p > s) + write(fd, s, p - s); } /* @@ -443,41 +439,42 @@ kbdbusy(uchar* buf, int n) static void kbdwork(void *a) { - int c, i, kbdfd, nerrs; uchar dk, buf[64], lbuf[64]; + int c, i, nerrs; char err[128]; KDev *f = a; - kbdfd = f->ep->dfd; - - if(f->ep->maxpkt < 3 || f->ep->maxpkt > sizeof buf) - kbfatal(f, "weird maxpkt"); - - if(setleds(f, f->ep->id, 0) < 0) - kbfatal(f, "setleds failed"); - f->repeatc = chancreate(sizeof(ulong), 0); if(f->repeatc == nil) kbfatal(f, "chancreate failed"); - proccreate(repeatproc, f, Stack); + + sethipri(); + setleds(f, f->ep->id, 0); + memset(lbuf, 0, sizeof lbuf); dk = nerrs = 0; for(;;){ + if(f->ep == nil) + kbfatal(f, nil); + if(f->ep->maxpkt < 3 || f->ep->maxpkt > sizeof buf) + kbfatal(f, "kbd: weird maxpkt"); memset(buf, 0, sizeof buf); - c = read(kbdfd, buf, f->ep->maxpkt); - assert(f->dev != nil); - assert(f->ep != nil); - if(c < 0){ - rerrstr(err, sizeof(err)); - fprint(2, "%s: %s: read: %s\n", argv0, f->ep->dir, err); - if(strstr(err, "babble") != 0 && ++nerrs < 3){ - recoverkb(f); + c = read(f->ep->dfd, buf, f->ep->maxpkt); + if(c <= 0){ + if(c < 0) + rerrstr(err, sizeof(err)); + else + strcpy(err, "zero read"); + if(++nerrs < 3){ + fprint(2, "%s: kbd: %s: read: %s\n", argv0, f->ep->dir, err); + if(strstr(err, "babble") != 0) + recoverkb(f); continue; } + kbfatal(f, err); } - if(c <= 0) - kbfatal(f, nil); + nerrs = 0; if(c < 3) continue; if(kbdbusy(buf + 2, c - 2)) @@ -490,7 +487,6 @@ kbdwork(void *a) } dk = putkeys(f, buf, lbuf, f->ep->maxpkt, dk); memmove(lbuf, buf, c); - nerrs = 0; } }