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.
This commit is contained in:
parent
f37d68003d
commit
aadc581040
1 changed files with 57 additions and 61 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue