summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2015-08-04 13:43:35 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2015-08-04 13:43:35 +0200
commitdcb5f4212b85ce9ecb710e0f8ed926ba7a1bcb35 (patch)
tree6ff66f3371878b7aef62ced4fdaa3c12cdb1a293
parent1f0057c5fdde41f61bb4b2fa014faa512b27aac0 (diff)
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.
-rw-r--r--sys/src/9/pc/devkbd.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/sys/src/9/pc/devkbd.c b/sys/src/9/pc/devkbd.c
index 9ce1a4895..bf43d85ba 100644
--- a/sys/src/9/pc/devkbd.c
+++ b/sys/src/9/pc/devkbd.c
@@ -277,6 +277,14 @@ i8042auxenable(void (*putc)(int, int))
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 @@ kbdclose(Chan *c)
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;
}