git: 1dec30a65a31 - stable/13 - hkbd(4): Use bitstring(3) KPI for key bitmaps processing.
Vladimir Kondratyev
wulf at FreeBSD.org
Thu Sep 23 01:03:58 UTC 2021
The branch stable/13 has been updated by wulf:
URL: https://cgit.FreeBSD.org/src/commit/?id=1dec30a65a3125ed02f1c83f9b1d22cfd11dbc86
commit 1dec30a65a3125ed02f1c83f9b1d22cfd11dbc86
Author: Vladimir Kondratyev <wulf at FreeBSD.org>
AuthorDate: 2021-09-09 21:39:46 +0000
Commit: Vladimir Kondratyev <wulf at FreeBSD.org>
CommitDate: 2021-09-23 00:57:57 +0000
hkbd(4): Use bitstring(3) KPI for key bitmaps processing.
No functional changes intended.
(cherry picked from commit 04918395f18dfb115dc0fe2865780dc607c5dc71)
---
sys/dev/hid/hkbd.c | 160 ++++++++++++++++++++---------------------------------
1 file changed, 61 insertions(+), 99 deletions(-)
diff --git a/sys/dev/hid/hkbd.c b/sys/dev/hid/hkbd.c
index 729602b12f3a..65e8b9446e9d 100644
--- a/sys/dev/hid/hkbd.c
+++ b/sys/dev/hid/hkbd.c
@@ -65,6 +65,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kdb.h>
#include <sys/epoch.h>
#include <sys/taskqueue.h>
+#include <sys/bitstring.h>
#include <machine/atomic.h>
@@ -116,7 +117,7 @@ SYSCTL_INT(_hw_hid_hkbd, OID_AUTO, no_leds, CTLFLAG_RWTUN,
#define HKBD_BUFFER_SIZE 64 /* bytes */
#define HKBD_KEY_PRESSED(map, key) ({ \
CTASSERT((key) >= 0 && (key) < HKBD_NKEYCODE); \
- ((map)[(key) / 64] & (1ULL << ((key) % 64))); \
+ bit_test(map, key); \
})
#define MOD_EJECT 0x01
@@ -125,10 +126,6 @@ SYSCTL_INT(_hw_hid_hkbd, OID_AUTO, no_leds, CTLFLAG_RWTUN,
#define MOD_MIN 0xe0
#define MOD_MAX 0xe7
-struct hkbd_data {
- uint64_t bitmap[howmany(HKBD_NKEYCODE, 64)];
-};
-
struct hkbd_softc {
device_t sc_dev;
@@ -136,7 +133,7 @@ struct hkbd_softc {
keymap_t sc_keymap;
accentmap_t sc_accmap;
fkeytab_t sc_fkeymap[HKBD_NFKEY];
- uint64_t sc_loc_key_valid[howmany(HKBD_NKEYCODE, 64)];
+ bitstr_t bit_decl(sc_loc_key_valid, HKBD_NKEYCODE);
struct hid_location sc_loc_apple_eject;
struct hid_location sc_loc_apple_fn;
struct hid_location sc_loc_key[HKBD_NKEYCODE];
@@ -146,8 +143,8 @@ struct hkbd_softc {
struct mtx sc_mtx;
struct task sc_task;
struct callout sc_callout;
- struct hkbd_data sc_ndata;
- struct hkbd_data sc_odata;
+ bitstr_t bit_decl(sc_ndata, HKBD_NKEYCODE);
+ bitstr_t bit_decl(sc_odata, HKBD_NKEYCODE);
struct thread *sc_poll_thread;
#ifdef EVDEV_SUPPORT
@@ -328,23 +325,19 @@ static const struct evdev_methods hkbd_evdev_methods = {
static bool
hkbd_any_key_pressed(struct hkbd_softc *sc)
{
- bool ret = false;
- unsigned i;
+ int result;
- for (i = 0; i != howmany(HKBD_NKEYCODE, 64); i++)
- ret |= (sc->sc_odata.bitmap[i] != 0);
- return (ret);
+ bit_ffs(sc->sc_odata, HKBD_NKEYCODE, &result);
+ return (result != -1);
}
static bool
hkbd_any_key_valid(struct hkbd_softc *sc)
{
- bool ret = false;
- unsigned i;
+ int result;
- for (i = 0; i != howmany(HKBD_NKEYCODE, 64); i++)
- ret |= (sc->sc_loc_key_valid[i] != 0);
- return (ret);
+ bit_ffs(sc->sc_loc_key_valid, HKBD_NKEYCODE, &result);
+ return (result != -1);
}
static bool
@@ -487,65 +480,47 @@ hkbd_interrupt(struct hkbd_softc *sc)
HKBD_LOCK_ASSERT(sc);
- /* Check for key changes, the order is:
- * 1. Modifier keys down
- * 2. Regular keys up/down
- * 3. Modifier keys up
+ /*
+ * Check for key changes, the order is:
+ * 1. Regular keys up
+ * 2. Modifier keys up
+ * 3. Modifier keys down
+ * 4. Regular keys down
*
* This allows devices which send events changing the state of
* both a modifier key and a regular key, to be correctly
* translated. */
- for (key = MOD_MIN; key <= MOD_MAX; key++) {
- const uint64_t mask = 1ULL << (key % 64);
+ bit_foreach(sc->sc_odata, HKBD_NKEYCODE, key) {
+ if (hkbd_is_modifier_key(key) || bit_test(sc->sc_ndata, key))
+ continue;
+ hkbd_put_key(sc, key | KEY_RELEASE);
- if (!(sc->sc_odata.bitmap[key / 64] & mask) &&
- (sc->sc_ndata.bitmap[key / 64] & mask)) {
- hkbd_put_key(sc, key | KEY_PRESS);
- }
+ /* clear repeating key, if any */
+ if (sc->sc_repeat_key == key)
+ sc->sc_repeat_key = 0;
}
- for (key = 0; key != HKBD_NKEYCODE; key++) {
- const uint64_t mask = 1ULL << (key % 64);
- const uint64_t delta =
- sc->sc_odata.bitmap[key / 64] ^
- sc->sc_ndata.bitmap[key / 64];
-
- if (hkbd_is_modifier_key(key))
+ bit_foreach_at(sc->sc_odata, MOD_MIN, MOD_MAX + 1, key)
+ if (!bit_test(sc->sc_ndata, key))
+ hkbd_put_key(sc, key | KEY_RELEASE);
+ bit_foreach_at(sc->sc_ndata, MOD_MIN, MOD_MAX + 1, key)
+ if (!bit_test(sc->sc_odata, key))
+ hkbd_put_key(sc, key | KEY_PRESS);
+ bit_foreach(sc->sc_ndata, HKBD_NKEYCODE, key) {
+ if (hkbd_is_modifier_key(key) || bit_test(sc->sc_odata, key))
continue;
+ hkbd_put_key(sc, key | KEY_PRESS);
- if (mask == 1 && delta == 0) {
- key += 63;
- continue; /* skip empty areas */
- } else if (delta & mask) {
- if (sc->sc_odata.bitmap[key / 64] & mask) {
- hkbd_put_key(sc, key | KEY_RELEASE);
-
- /* clear repeating key, if any */
- if (sc->sc_repeat_key == key)
- sc->sc_repeat_key = 0;
- } else {
- hkbd_put_key(sc, key | KEY_PRESS);
-
- sc->sc_co_basetime = sbinuptime();
- sc->sc_delay = sc->sc_kbd.kb_delay1;
- hkbd_start_timer(sc);
-
- /* set repeat time for last key */
- sc->sc_repeat_time = now + sc->sc_kbd.kb_delay1;
- sc->sc_repeat_key = key;
- }
- }
- }
- for (key = MOD_MIN; key <= MOD_MAX; key++) {
- const uint64_t mask = 1ULL << (key % 64);
+ sc->sc_co_basetime = sbinuptime();
+ sc->sc_delay = sc->sc_kbd.kb_delay1;
+ hkbd_start_timer(sc);
- if ((sc->sc_odata.bitmap[key / 64] & mask) &&
- !(sc->sc_ndata.bitmap[key / 64] & mask)) {
- hkbd_put_key(sc, key | KEY_RELEASE);
- }
+ /* set repeat time for last key */
+ sc->sc_repeat_time = now + sc->sc_kbd.kb_delay1;
+ sc->sc_repeat_key = key;
}
/* synchronize old data with new data */
- sc->sc_odata = sc->sc_ndata;
+ memcpy(sc->sc_odata, sc->sc_ndata, bitstr_size(HKBD_NKEYCODE));
/* check if last key is still pressed */
if (sc->sc_repeat_key != 0) {
@@ -679,7 +654,7 @@ hkbd_intr_callback(void *context, void *data, hid_size_t len)
}
/* clear temporary storage */
- memset(&sc->sc_ndata, 0, sizeof(sc->sc_ndata));
+ memset(&sc->sc_ndata, 0, bitstr_size(HKBD_NKEYCODE));
/* clear modifiers */
modifiers = 0;
@@ -696,16 +671,8 @@ hkbd_intr_callback(void *context, void *data, hid_size_t len)
modifiers |= MOD_FN;
}
- for (i = 0; i != HKBD_NKEYCODE; i++) {
- const uint64_t valid = sc->sc_loc_key_valid[i / 64];
- const uint64_t mask = 1ULL << (i % 64);
-
- if (mask == 1 && valid == 0) {
- i += 63;
- continue; /* skip empty areas */
- } else if (~valid & mask) {
- continue; /* location is not valid */
- } else if (id != sc->sc_id_loc_key[i]) {
+ bit_foreach(sc->sc_loc_key_valid, HKBD_NKEYCODE, i) {
+ if (id != sc->sc_id_loc_key[i]) {
continue; /* invalid HID ID */
} else if (i == 0) {
struct hid_location tmp_loc = sc->sc_loc_key[0];
@@ -719,7 +686,8 @@ hkbd_intr_callback(void *context, void *data, hid_size_t len)
tmp_loc.pos += tmp_loc.size;
if (key == KEY_ERROR) {
DPRINTF("KEY_ERROR\n");
- sc->sc_ndata = sc->sc_odata;
+ memcpy(sc->sc_ndata, sc->sc_odata,
+ bitstr_size(HKBD_NKEYCODE));
return; /* ignore */
}
if (modifiers & MOD_FN)
@@ -729,7 +697,7 @@ hkbd_intr_callback(void *context, void *data, hid_size_t len)
if (key == KEY_NONE || key >= HKBD_NKEYCODE)
continue;
/* set key in bitmap */
- sc->sc_ndata.bitmap[key / 64] |= 1ULL << (key % 64);
+ bit_set(sc->sc_ndata, key);
}
} else if (hid_get_data(buf, len, &sc->sc_loc_key[i])) {
uint32_t key = i;
@@ -741,18 +709,13 @@ hkbd_intr_callback(void *context, void *data, hid_size_t len)
if (key == KEY_NONE || key == KEY_ERROR || key >= HKBD_NKEYCODE)
continue;
/* set key in bitmap */
- sc->sc_ndata.bitmap[key / 64] |= 1ULL << (key % 64);
+ bit_set(sc->sc_ndata, key);
}
}
#ifdef HID_DEBUG
DPRINTF("modifiers = 0x%04x\n", modifiers);
- for (i = 0; i != HKBD_NKEYCODE; i++) {
- const uint64_t valid = sc->sc_ndata.bitmap[i / 64];
- const uint64_t mask = 1ULL << (i % 64);
-
- if (valid & mask)
- DPRINTF("Key 0x%02x pressed\n", i);
- }
+ bit_foreach(sc->sc_ndata, HKBD_NKEYCODE, i)
+ DPRINTF("Key 0x%02x pressed\n", i);
#endif
hkbd_interrupt(sc);
}
@@ -795,7 +758,7 @@ hkbd_parse_hid(struct hkbd_softc *sc, const uint8_t *ptr, uint32_t len,
sc->sc_flags &= ~HKBD_FLAG_HID_MASK;
/* reset detected keys */
- memset(sc->sc_loc_key_valid, 0, sizeof(sc->sc_loc_key_valid));
+ memset(sc->sc_loc_key_valid, 0, bitstr_size(HKBD_NKEYCODE));
/* check if there is an ID byte */
sc->sc_kbd_size = hid_report_size_max(ptr, len,
@@ -828,7 +791,7 @@ hkbd_parse_hid(struct hkbd_softc *sc, const uint8_t *ptr, uint32_t len,
if (flags & HIO_VARIABLE) {
DPRINTFN(1, "Ignoring keyboard event control\n");
} else {
- sc->sc_loc_key_valid[0] |= 1;
+ bit_set(sc->sc_loc_key_valid, 0);
DPRINTFN(1, "Found keyboard event array\n");
}
}
@@ -840,8 +803,7 @@ hkbd_parse_hid(struct hkbd_softc *sc, const uint8_t *ptr, uint32_t len,
hid_input, tlc_index, 0, &sc->sc_loc_key[key], &flags,
&sc->sc_id_loc_key[key], NULL)) {
if (flags & HIO_VARIABLE) {
- sc->sc_loc_key_valid[key / 64] |=
- 1ULL << (key % 64);
+ bit_set(sc->sc_loc_key_valid, key);
DPRINTFN(1, "Found key 0x%02x\n", key);
}
}
@@ -1057,7 +1019,7 @@ hkbd_detach(device_t dev)
hidbus_intr_stop(dev);
/* release all leftover keys, if any */
- memset(&sc->sc_ndata, 0, sizeof(sc->sc_ndata));
+ memset(&sc->sc_ndata, 0, bitstr_size(HKBD_NKEYCODE));
/* process releasing of all keys */
HKBD_LOCK(sc);
@@ -1305,11 +1267,11 @@ hkbd_read(keyboard_t *kbd, int wait)
++(kbd->kb_count);
#ifdef HKBD_EMULATE_ATSCANCODE
- keycode = hkbd_atkeycode(usbcode, sc->sc_ndata.bitmap);
+ keycode = hkbd_atkeycode(usbcode, sc->sc_ndata);
if (keycode == NN) {
return -1;
}
- return (hkbd_key2scan(sc, keycode, sc->sc_ndata.bitmap,
+ return (hkbd_key2scan(sc, keycode, sc->sc_ndata,
(usbcode & KEY_RELEASE)));
#else /* !HKBD_EMULATE_ATSCANCODE */
return (usbcode);
@@ -1375,13 +1337,13 @@ next_code:
#ifdef HKBD_EMULATE_ATSCANCODE
/* USB key index -> key code -> AT scan code */
- keycode = hkbd_atkeycode(usbcode, sc->sc_ndata.bitmap);
+ keycode = hkbd_atkeycode(usbcode, sc->sc_ndata);
if (keycode == NN) {
return (NOKEY);
}
/* return an AT scan code for the K_RAW mode */
if (sc->sc_mode == K_RAW) {
- return (hkbd_key2scan(sc, keycode, sc->sc_ndata.bitmap,
+ return (hkbd_key2scan(sc, keycode, sc->sc_ndata,
(usbcode & KEY_RELEASE)));
}
#else /* !HKBD_EMULATE_ATSCANCODE */
@@ -1720,8 +1682,8 @@ hkbd_clear_state(keyboard_t *kbd)
sc->sc_buffered_char[0] = 0;
sc->sc_buffered_char[1] = 0;
#endif
- memset(&sc->sc_ndata, 0, sizeof(sc->sc_ndata));
- memset(&sc->sc_odata, 0, sizeof(sc->sc_odata));
+ memset(&sc->sc_ndata, 0, bitstr_size(HKBD_NKEYCODE));
+ memset(&sc->sc_odata, 0, bitstr_size(HKBD_NKEYCODE));
sc->sc_repeat_time = 0;
sc->sc_repeat_key = 0;
}
@@ -1865,7 +1827,7 @@ hkbd_set_typematic(keyboard_t *kbd, int code)
#ifdef HKBD_EMULATE_ATSCANCODE
static uint32_t
-hkbd_atkeycode(int usbcode, const uint64_t *bitmap)
+hkbd_atkeycode(int usbcode, const bitstr_t *bitmap)
{
uint32_t keycode;
@@ -1892,7 +1854,7 @@ hkbd_atkeycode(int usbcode, const uint64_t *bitmap)
}
static int
-hkbd_key2scan(struct hkbd_softc *sc, int code, const uint64_t *bitmap, int up)
+hkbd_key2scan(struct hkbd_softc *sc, int code, const bitstr_t *bitmap, int up)
{
static const int scan[] = {
/* 89 */
More information about the dev-commits-src-all
mailing list