shithub: riscv

Download patch

ref: dcb5f4212b85ce9ecb710e0f8ed926ba7a1bcb35
parent: 1f0057c5fdde41f61bb4b2fa014faa512b27aac0
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Tue Aug 4 09:43:35 EDT 2015

devkbd: poll pc keyboard before blocking on kbd.q

the keyboard stops sending interrupts when its fifo gets full,
which can happen on boot when keys get mashed while interrupts
are still disabled. to work arround this, call the keyboard
interrupt handler when kbd.q is starved before blocking.

--- a/sys/src/9/pc/devkbd.c
+++ b/sys/src/9/pc/devkbd.c
@@ -277,6 +277,14 @@
 	iunlock(&i8042lock);
 }
 
+static void
+kbdpoll(void)
+{
+	if(nokbd || qlen(kbd.q) > 0)
+		return;
+	i8042intr(0, 0);
+}
+
 static Chan *
 kbdattach(char *spec)
 {
@@ -324,20 +332,22 @@
 static Block*
 kbdbread(Chan *c, long n, ulong off)
 {
-	if(c->qid.path == Qscancode)
+	if(c->qid.path == Qscancode){
+		kbdpoll();
 		return qbread(kbd.q, n);
-	else
-		return devbread(c, n, off);
+	}
+	return devbread(c, n, off);
 }
 
 static long
 kbdread(Chan *c, void *a, long n, vlong)
 {
-	if(c->qid.path == Qscancode)
+	if(c->qid.path == Qscancode){
+		kbdpoll();
 		return qread(kbd.q, a, n);
+	}
 	if(c->qid.path == Qdir)
 		return devdirread(c, a, n, kbdtab, nelem(kbdtab), devgen);
-
 	error(Egreg);
 	return 0;
 }