svn commit: r305060 - head/sys/dev/kbdmux
Bruce Evans
bde at FreeBSD.org
Tue Aug 30 12:36:15 UTC 2016
Author: bde
Date: Tue Aug 30 12:36:14 2016
New Revision: 305060
URL: https://svnweb.freebsd.org/changeset/base/305060
Log:
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
Modified:
head/sys/dev/kbdmux/kbdmux.c
Modified: head/sys/dev/kbdmux/kbdmux.c
==============================================================================
--- head/sys/dev/kbdmux/kbdmux.c Tue Aug 30 10:57:19 2016 (r305059)
+++ head/sys/dev/kbdmux/kbdmux.c Tue Aug 30 12:36:14 2016 (r305060)
@@ -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 @@ next_code:
/* 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
{
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)
More information about the svn-src-head
mailing list