shithub: riscv

Download patch

ref: aadc58104016170b61b62a31daa295895a640b60
parent: f37d68003dc452fb9bd157de7d5b2a329cddd42a
author: cinap_lenrek <[email protected]>
date: Sat Nov 24 11:37:39 EST 2012

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.

--- 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 @@
 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 @@
 		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 @@
 {
 	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 @@
 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 @@
 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 @@
 		}
 		dk = putkeys(f, buf, lbuf, f->ep->maxpkt, dk);
 		memmove(lbuf, buf, c);
-		nerrs = 0;
 	}
 }