From cc43fd1ab5afa9f4ed20168193fd1f16a363be88 Mon Sep 17 00:00:00 2001 From: Bruce Evans Date: Tue, 30 Aug 2016 12:36:14 +0000 Subject: [PATCH] Fix keyboard polling "on/off" to support recursion. vt depends on this, and sc will soon depend on it again. The on/off request is passed without modification to lower layers, so the bug was smaller in this layer than in in lower layers (the sequence on;on;off left polling off when it should be on, but the sequence on;on;off;on;off... doesn't allow the interrupt handler to eat the input after an "off" that should't turn off polled mode, provided lower layers don't have the bug, since this layer is virtual. The bug was small in lower layers too. Normally everything is Giant locked for keyboards, and this locks out the interrupt handler in on;on;off;on;off... sequences. However, PR 211884 says that fixing this bug in ukbd in r303765 apparently causes the eating-by-interrupt behaviour that the fix is to prevent. Discussed with: emax --- sys/dev/kbdmux/kbdmux.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sys/dev/kbdmux/kbdmux.c b/sys/dev/kbdmux/kbdmux.c index 0dce120ad6a8..4720a0e6fc88 100644 --- a/sys/dev/kbdmux/kbdmux.c +++ b/sys/dev/kbdmux/kbdmux.c @@ -150,9 +150,9 @@ struct kbdmux_state int ks_flags; /* flags */ #define COMPOSE (1 << 0) /* compose char flag */ -#define POLLING (1 << 1) /* polling */ #define TASK (1 << 2) /* interrupt task queued */ + int ks_polling; /* poll nesting count */ int ks_mode; /* K_XLATE, K_RAW, K_CODE */ int ks_state; /* state */ int ks_accents; /* accent key index (> 0) */ @@ -666,7 +666,7 @@ kbdmux_read_char(keyboard_t *kbd, int wait) /* see if there is something in the keyboard queue */ scancode = kbdmux_kbd_getc(state); if (scancode == -1) { - if (state->ks_flags & POLLING) { + if (state->ks_polling != 0) { kbdmux_kbd_t *k; SLIST_FOREACH(k, &state->ks_kbds, next) { @@ -1244,7 +1244,8 @@ kbdmux_clear_state_locked(kbdmux_state_t *state) { KBDMUX_LOCK_ASSERT(state, MA_OWNED); - state->ks_flags &= ~(COMPOSE|POLLING); + state->ks_flags &= ~COMPOSE; + state->ks_polling = 0; state->ks_state &= LOCK_MASK; /* preserve locking key state */ state->ks_accents = 0; state->ks_composed_char = 0; @@ -1304,9 +1305,9 @@ kbdmux_poll(keyboard_t *kbd, int on) KBDMUX_LOCK(state); if (on) - state->ks_flags |= POLLING; + state->ks_polling++; else - state->ks_flags &= ~POLLING; + state->ks_polling--; /* set poll on slave keyboards */ SLIST_FOREACH(k, &state->ks_kbds, next)