The branch main has been updated by wulf:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=04918395f18dfb115dc0fe2865780dc607c5dc71

commit 04918395f18dfb115dc0fe2865780dc607c5dc71
Author:     Vladimir Kondratyev <w...@freebsd.org>
AuthorDate: 2021-09-09 21:39:46 +0000
Commit:     Vladimir Kondratyev <w...@freebsd.org>
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 <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 */
_______________________________________________
dev-commits-src-main@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main
To unsubscribe, send any mail to "dev-commits-src-main-unsubscr...@freebsd.org"

Reply via email to