diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-08-04 13:43:35 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2015-08-04 13:43:35 +0200 |
commit | dcb5f4212b85ce9ecb710e0f8ed926ba7a1bcb35 (patch) | |
tree | 6ff66f3371878b7aef62ced4fdaa3c12cdb1a293 | |
parent | 1f0057c5fdde41f61bb4b2fa014faa512b27aac0 (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.c | 20 |
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; } |