From owner-dev-commits-src-all@freebsd.org Thu Sep 9 21:41:44 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 85CCD677BB5; Thu, 9 Sep 2021 21:41:44 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4H5CBc3BV2z3GPP; Thu, 9 Sep 2021 21:41:44 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 49D8C20D34; Thu, 9 Sep 2021 21:41:44 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 189LfiQj016264; Thu, 9 Sep 2021 21:41:44 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 189LfidC016263; Thu, 9 Sep 2021 21:41:44 GMT (envelope-from git) Date: Thu, 9 Sep 2021 21:41:44 GMT Message-Id: <202109092141.189LfidC016263@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Vladimir Kondratyev Subject: git: 04918395f18d - main - hkbd(4): Use bitstring(3) KPI for key bitmaps processing. MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: wulf X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 04918395f18dfb115dc0fe2865780dc607c5dc71 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 09 Sep 2021 21:41:44 -0000 The branch main has been updated by wulf: URL: https://cgit.FreeBSD.org/src/commit/?id=04918395f18dfb115dc0fe2865780dc607c5dc71 commit 04918395f18dfb115dc0fe2865780dc607c5dc71 Author: Vladimir Kondratyev AuthorDate: 2021-09-09 21:39:46 +0000 Commit: Vladimir Kondratyev CommitDate: 2021-09-09 21:39:46 +0000 hkbd(4): Use bitstring(3) KPI for key bitmaps processing. No functional changes intended. MFC after: 2 weeks --- 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 #include #include +#include #include @@ -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 */