The branch main has been updated by wulf:

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

commit b93f6bfca34363f9c285e3e027fbfd4032b02b64
Author:     Vladimir Kondratyev <[email protected]>
AuthorDate: 2020-10-12 19:52:29 +0000
Commit:     Vladimir Kondratyev <[email protected]>
CommitDate: 2021-01-07 23:18:43 +0000

    hid: Port ukbd to HID and attach to build
    
    Reviewed by:    hselasky
    Differential revision:  https://reviews.freebsd.org/D27991
---
 share/man/man4/Makefile       |    1 +
 share/man/man4/hkbd.4         |   59 +-
 sys/conf/files                |    3 +-
 sys/conf/options              |    1 +
 sys/dev/hid/hkbd.c            | 1354 ++++++++++++++++++-----------------------
 sys/modules/hid/Makefile      |    1 +
 sys/modules/hid/hkbd/Makefile |   10 +
 7 files changed, 628 insertions(+), 801 deletions(-)

diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index c92c8f50545f..4fd816804062 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -183,6 +183,7 @@ MAN=        aac.4 \
        hidbus.4 \
        hidquirk.4 \
        hifn.4 \
+       hkbd.4 \
        hmt.4 \
        hpet.4 \
        ${_hpt27xx.4} \
diff --git a/share/man/man4/hkbd.4 b/share/man/man4/hkbd.4
index f443f51ce8e1..400bf1d989cd 100644
--- a/share/man/man4/hkbd.4
+++ b/share/man/man4/hkbd.4
@@ -24,37 +24,41 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd April 24, 2018
-.Dt UKBD 4
+.Dd September 12, 2020
+.Dt HKBD 4
 .Os
 .Sh NAME
-.Nm ukbd
-.Nd USB keyboard driver
+.Nm hkbd
+.Nd HID keyboard driver
 .Sh SYNOPSIS
 To compile this driver into the kernel,
 place the following line in your
 kernel configuration file:
 .Bd -ragged -offset indent
-.Cd "device ukbd"
+.Cd "device hkbd"
 .Cd "device hid"
-.Cd "device usb"
+.Cd "device hidbus"
+.Cd "device evdev"
+.Cd "options EVDEV_SUPPORT"
 .Ed
 .Pp
 Alternatively, to load the driver as a
 module at boot time, place the following line in
 .Xr loader.conf 5 :
 .Bd -literal -offset indent
-ukbd_load="YES"
+hkbd_load="YES"
 .Ed
 .Sh DESCRIPTION
 The
 .Nm
-driver provides support for keyboards that attach to the USB port.
-.Xr usb 4
+driver provides support for keyboards that attach to the HID transport
+backend.
+.Xr hid 4 ,
+.Xr hidbus 4 ,
 and one of
-.Xr uhci 4
+.Xr iichid 4
 or
-.Xr ohci 4
+.Xr usbhid 4
 must be configured in the kernel as well.
 .Sh CONFIGURATION
 By default, the keyboard subsystem does not create the appropriate devices yet.
@@ -63,12 +67,12 @@ config file:
 .Pp
 .Dl "options KBD_INSTALL_CDEV"
 .Pp
-If both an AT keyboard USB keyboards are used at the same time, the
+If both an AT keyboard HID keyboards are used at the same time, the
 AT keyboard will appear as
 .Pa kbd0
 in
 .Pa /dev .
-The USB keyboards will be
+The HID keyboards will be
 .Pa kbd1 , kbd2 ,
 etc.
 You can see some information about the keyboard with the following command:
@@ -87,19 +91,19 @@ You can swap console keyboards by using the command
 .Pp
 .Dl "kbdcontrol -k /dev/kbd1"
 .Pp
-From this point on, the first USB keyboard will be the keyboard
+From this point on, the first HID keyboard will be the keyboard
 to be used by the console.
 .Pp
-If you want to use a USB keyboard as your default and not use an AT keyboard at
+If you want to use a HID keyboard as your default and not use an AT keyboard at
 all, you will have to remove the
 .Cd "device atkbd"
 line from the kernel configuration file.
 Because of the device initialization order,
-the USB keyboard will be detected
+the HID keyboard will be detected
 .Em after
 the console driver
 initializes itself and you have to explicitly tell the console
-driver to use the existence of the USB keyboard.
+driver to use the existence of the HID keyboard.
 This can be done in
 one of the following two ways.
 .Pp
@@ -107,7 +111,7 @@ Run the following command as a part of system 
initialization:
 .Pp
 .Dl "kbdcontrol -k /dev/kbd0 < /dev/ttyv0 > /dev/null"
 .Pp
-(Note that as the USB keyboard is the only keyboard, it is accessed as
+(Note that as the HID keyboard is the only keyboard, it is accessed as
 .Pa /dev/kbd0 )
 or otherwise tell the console driver to periodically look for a
 keyboard by setting a flag in the kernel configuration file:
@@ -123,8 +127,8 @@ initialized at boot time.
 Make the keyboards available through a character device in
 .Pa /dev .
 .Pp
-.D1 Cd options UKBD_DFLT_KEYMAP
-.D1 Cd makeoptions UKBD_DFLT_KEYMAP=fr.iso
+.D1 Cd options HKBD_DFLT_KEYMAP
+.D1 Cd makeoptions HKBD_DFLT_KEYMAP=fr.iso
 .Pp
 The above lines will put the French ISO keymap in the ukbd driver.
 You can specify any keymap in
@@ -145,28 +149,31 @@ variables and
 .Xr loader 8
 tunables:
 .Bl -tag -width indent
-.It Va hw.usb.ukbd.debug
+.It Va hw.hid.hkbd.debug
 Debug output level, where 0 is debugging disabled and larger values increase
 debug message verbosity.
 Default is 0.
 .El
 .Sh FILES
-.Bl -tag -width ".Pa /dev/kbd*" -compact
+.Bl -tag -width ".Pa /dev/input/event*" -compact
 .It Pa /dev/kbd*
 blocking device nodes
+.It Pa /dev/input/event*
+input event device nodes.
 .El
 .Sh EXAMPLES
-.D1 Cd "device ukbd"
+.D1 Cd "device hkbd"
 .Pp
 Add the
 .Nm
 driver to the kernel.
 .Sh SEE ALSO
 .Xr kbdcontrol 1 ,
-.Xr ohci 4 ,
+.Xr hid 4 ,
+.Xr hidbus 4 ,
+.Xr iichid 4 ,
 .Xr syscons 4 ,
-.Xr uhci 4 ,
-.Xr usb 4 ,
+.Xr usbhid 4 ,
 .Xr vt 4 ,
 .Xr config 8
 .Sh AUTHORS
diff --git a/sys/conf/files b/sys/conf/files
index 13dd93d9d2cd..71d78778d500 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1820,6 +1820,7 @@ dev/hid/hid.c                     optional hid
 dev/hid/hid_if.m               optional hid
 dev/hid/hidbus.c               optional hidbus
 dev/hid/hidquirk.c             optional hid
+dev/hid/hkbd.c                 optional hkbd
 dev/hid/hmt.c                  optional hmt hconf
 dev/hifn/hifn7751.c            optional hifn
 dev/hptiop/hptiop.c            optional hptiop scbus
@@ -2327,7 +2328,7 @@ dev/ixgbe/ixgbe_dcb_82599.c       optional ix inet | ixv 
inet \
        compile-with "${NORMAL_C} -I$S/dev/ixgbe"
 dev/jedec_dimm/jedec_dimm.c    optional jedec_dimm smbus
 dev/jme/if_jme.c               optional jme pci
-dev/kbd/kbd.c                  optional atkbd | pckbd | sc | ukbd | vt
+dev/kbd/kbd.c                  optional atkbd | pckbd | sc | ukbd | vt | hkbd
 dev/kbdmux/kbdmux.c            optional kbdmux
 dev/ksyms/ksyms.c              optional ksyms
 dev/le/am7990.c                        optional le
diff --git a/sys/conf/options b/sys/conf/options
index 48b7f362a80a..789def58cb48 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -1019,3 +1019,4 @@ LINDEBUGFS
 HID_DEBUG      opt_hid.h
 IICHID_DEBUG   opt_hid.h
 IICHID_SAMPLING        opt_hid.h
+HKBD_DFLT_KEYMAP       opt_hkbd.h
diff --git a/sys/dev/hid/hkbd.c b/sys/dev/hid/hkbd.c
index 0edacbefcbfc..321a51734664 100644
--- a/sys/dev/hid/hkbd.c
+++ b/sys/dev/hid/hkbd.c
@@ -39,7 +39,7 @@ __FBSDID("$FreeBSD$");
  */
 
 #include "opt_kbd.h"
-#include "opt_ukbd.h"
+#include "opt_hkbd.h"
 #include "opt_evdev.h"
 
 #include <sys/stdint.h>
@@ -61,18 +61,14 @@ __FBSDID("$FreeBSD$");
 #include <sys/malloc.h>
 #include <sys/priv.h>
 #include <sys/proc.h>
+#include <sys/kdb.h>
+#include <sys/epoch.h>
 
+#define        HID_DEBUG_VAR hkbd_debug
 #include <dev/hid/hid.h>
-
-#include <dev/usb/usb.h>
-#include <dev/usb/usbdi.h>
-#include <dev/usb/usbdi_util.h>
-#include <dev/usb/usbhid.h>
-
-#define        USB_DEBUG_VAR ukbd_debug
-#include <dev/usb/usb_debug.h>
-
-#include <dev/usb/quirk/usb_quirk.h>
+#include <dev/hid/hidbus.h>
+#include <dev/hid/hidquirk.h>
+#include <dev/hid/hidrdesc.h>
 
 #ifdef EVDEV_SUPPORT
 #include <dev/evdev/input.h>
@@ -86,7 +82,7 @@ __FBSDID("$FreeBSD$");
 #include <dev/kbd/kbdreg.h>
 
 /* the initial key map, accent map and fkey strings */
-#if defined(UKBD_DFLT_KEYMAP) && !defined(KLD_MODULE)
+#if defined(HKBD_DFLT_KEYMAP) && !defined(KLD_MODULE)
 #define        KBD_DFLT_KEYMAP
 #include "ukbdmap.h"
 #endif
@@ -94,67 +90,60 @@ __FBSDID("$FreeBSD$");
 /* the following file must be included after "ukbdmap.h" */
 #include <dev/kbd/kbdtables.h>
 
-#ifdef USB_DEBUG
-static int ukbd_debug = 0;
-static int ukbd_no_leds = 0;
-static int ukbd_pollrate = 0;
-
-static SYSCTL_NODE(_hw_usb, OID_AUTO, ukbd, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
-    "USB keyboard");
-SYSCTL_INT(_hw_usb_ukbd, OID_AUTO, debug, CTLFLAG_RWTUN,
-    &ukbd_debug, 0, "Debug level");
-SYSCTL_INT(_hw_usb_ukbd, OID_AUTO, no_leds, CTLFLAG_RWTUN,
-    &ukbd_no_leds, 0, "Disables setting of keyboard leds");
-SYSCTL_INT(_hw_usb_ukbd, OID_AUTO, pollrate, CTLFLAG_RWTUN,
-    &ukbd_pollrate, 0, "Force this polling rate, 1-1000Hz");
+#ifdef HID_DEBUG
+static int hkbd_debug = 0;
+static int hkbd_no_leds = 0;
+
+static SYSCTL_NODE(_hw_hid, OID_AUTO, hkbd, CTLFLAG_RW, 0, "USB keyboard");
+SYSCTL_INT(_hw_hid_hkbd, OID_AUTO, debug, CTLFLAG_RWTUN,
+    &hkbd_debug, 0, "Debug level");
+SYSCTL_INT(_hw_hid_hkbd, OID_AUTO, no_leds, CTLFLAG_RWTUN,
+    &hkbd_no_leds, 0, "Disables setting of keyboard leds");
 #endif
 
-#define        UKBD_EMULATE_ATSCANCODE        1
-#define        UKBD_DRIVER_NAME          "ukbd"
-#define        UKBD_NKEYCODE                 256 /* units */
-#define        UKBD_IN_BUF_SIZE  (4 * UKBD_NKEYCODE) /* scancodes */
-#define        UKBD_IN_BUF_FULL  ((UKBD_IN_BUF_SIZE / 2) - 1)  /* scancodes */
-#define        UKBD_NFKEY        (sizeof(fkey_tab)/sizeof(fkey_tab[0]))        
/* units */
-#define        UKBD_BUFFER_SIZE              64        /* bytes */
-#define        UKBD_KEY_PRESSED(map, key) ({ \
-       CTASSERT((key) >= 0 && (key) < UKBD_NKEYCODE); \
+#define        INPUT_EPOCH     global_epoch_preempt
+
+#define        HKBD_EMULATE_ATSCANCODE        1
+#define        HKBD_DRIVER_NAME          "hkbd"
+#define        HKBD_NKEYCODE                 256 /* units */
+#define        HKBD_IN_BUF_SIZE  (4 * HKBD_NKEYCODE) /* scancodes */
+#define        HKBD_IN_BUF_FULL  ((HKBD_IN_BUF_SIZE / 2) - 1)  /* scancodes */
+#define        HKBD_NFKEY        (sizeof(fkey_tab)/sizeof(fkey_tab[0]))        
/* units */
+#define        HKBD_BUFFER_SIZE              64        /* bytes */
+#define        HKBD_KEY_PRESSED(map, key) ({ \
+       CTASSERT((key) >= 0 && (key) < HKBD_NKEYCODE); \
        ((map)[(key) / 64] & (1ULL << ((key) % 64))); \
 })
 
 #define        MOD_EJECT       0x01
 #define        MOD_FN          0x02
 
-struct ukbd_data {
-       uint64_t bitmap[howmany(UKBD_NKEYCODE, 64)];
-};
+#define MOD_MIN     0xe0
+#define MOD_MAX     0xe7
 
-enum {
-       UKBD_INTR_DT_0,
-       UKBD_INTR_DT_1,
-       UKBD_CTRL_LED,
-       UKBD_N_TRANSFER,
+struct hkbd_data {
+       uint64_t bitmap[howmany(HKBD_NKEYCODE, 64)];
 };
 
-struct ukbd_softc {
+struct hkbd_softc {
+       device_t sc_dev;
+
        keyboard_t sc_kbd;
        keymap_t sc_keymap;
        accentmap_t sc_accmap;
-       fkeytab_t sc_fkeymap[UKBD_NFKEY];
-       uint64_t sc_loc_key_valid[howmany(UKBD_NKEYCODE, 64)];
+       fkeytab_t sc_fkeymap[HKBD_NFKEY];
+       uint64_t sc_loc_key_valid[howmany(HKBD_NKEYCODE, 64)];
        struct hid_location sc_loc_apple_eject;
        struct hid_location sc_loc_apple_fn;
-       struct hid_location sc_loc_key[UKBD_NKEYCODE];
+       struct hid_location sc_loc_key[HKBD_NKEYCODE];
        struct hid_location sc_loc_numlock;
        struct hid_location sc_loc_capslock;
        struct hid_location sc_loc_scrolllock;
-       struct usb_callout sc_callout;
-       struct ukbd_data sc_ndata;
-       struct ukbd_data sc_odata;
+       struct callout sc_callout;
+       struct hkbd_data sc_ndata;
+       struct hkbd_data sc_odata;
 
        struct thread *sc_poll_thread;
-       struct usb_device *sc_udev;
-       struct usb_interface *sc_iface;
-       struct usb_xfer *sc_xfer[UKBD_N_TRANSFER];
 #ifdef EVDEV_SUPPORT
        struct evdev_dev *sc_evdev;
 #endif
@@ -162,26 +151,25 @@ struct ukbd_softc {
        sbintime_t sc_co_basetime;
        int     sc_delay;
        uint32_t sc_repeat_time;
-       uint32_t sc_input[UKBD_IN_BUF_SIZE];    /* input buffer */
+       uint32_t sc_input[HKBD_IN_BUF_SIZE];    /* input buffer */
        uint32_t sc_time_ms;
        uint32_t sc_composed_char;      /* composed char code, if non-zero */
-#ifdef UKBD_EMULATE_ATSCANCODE
+#ifdef HKBD_EMULATE_ATSCANCODE
        uint32_t sc_buffered_char[2];
 #endif
        uint32_t sc_flags;              /* flags */
-#define        UKBD_FLAG_COMPOSE       0x00000001
-#define        UKBD_FLAG_POLLING       0x00000002
-#define        UKBD_FLAG_SET_LEDS      0x00000004
-#define        UKBD_FLAG_ATTACHED      0x00000010
-#define        UKBD_FLAG_GONE          0x00000020
-
-#define        UKBD_FLAG_HID_MASK      0x003fffc0
-#define        UKBD_FLAG_APPLE_EJECT   0x00000040
-#define        UKBD_FLAG_APPLE_FN      0x00000080
-#define        UKBD_FLAG_APPLE_SWAP    0x00000100
-#define        UKBD_FLAG_NUMLOCK       0x00080000
-#define        UKBD_FLAG_CAPSLOCK      0x00100000
-#define        UKBD_FLAG_SCROLLLOCK    0x00200000
+#define        HKBD_FLAG_COMPOSE       0x00000001
+#define        HKBD_FLAG_POLLING       0x00000002
+#define        HKBD_FLAG_ATTACHED      0x00000010
+#define        HKBD_FLAG_GONE          0x00000020
+
+#define        HKBD_FLAG_HID_MASK      0x003fffc0
+#define        HKBD_FLAG_APPLE_EJECT   0x00000040
+#define        HKBD_FLAG_APPLE_FN      0x00000080
+#define        HKBD_FLAG_APPLE_SWAP    0x00000100
+#define        HKBD_FLAG_NUMLOCK       0x00080000
+#define        HKBD_FLAG_CAPSLOCK      0x00100000
+#define        HKBD_FLAG_SCROLLLOCK    0x00200000
 
        int     sc_mode;                /* input mode (K_XLATE,K_RAW,K_CODE) */
        int     sc_state;               /* shift/lock key state */
@@ -194,19 +182,16 @@ struct ukbd_softc {
        uint16_t sc_inputhead;
        uint16_t sc_inputtail;
 
-       uint8_t sc_leds;                /* store for async led requests */
        uint8_t sc_iface_index;
        uint8_t sc_iface_no;
        uint8_t sc_id_apple_eject;
        uint8_t sc_id_apple_fn;
-       uint8_t sc_id_loc_key[UKBD_NKEYCODE];
-       uint8_t sc_id_numlock;
-       uint8_t sc_id_capslock;
-       uint8_t sc_id_scrolllock;
+       uint8_t sc_id_loc_key[HKBD_NKEYCODE];
+       uint8_t sc_id_leds;
        uint8_t sc_kbd_id;
        uint8_t sc_repeat_key;
 
-       uint8_t sc_buffer[UKBD_BUFFER_SIZE];
+       uint8_t sc_buffer[HKBD_BUFFER_SIZE];
 };
 
 #define        KEY_NONE          0x00
@@ -226,9 +211,18 @@ struct ukbd_softc {
                         SCAN_PREFIX_CTL | SCAN_PREFIX_SHIFT)
 #define        SCAN_CHAR(c)    ((c) & 0x7f)
 
-#define        UKBD_LOCK()     USB_MTX_LOCK(&Giant)
-#define        UKBD_UNLOCK()   USB_MTX_UNLOCK(&Giant)
-#define        UKBD_LOCK_ASSERT()      USB_MTX_ASSERT(&Giant, MA_OWNED)
+#define        HKBD_LOCK()             do {                    \
+       if (!HID_IN_POLLING_MODE())                     \
+               mtx_lock(&Giant);                       \
+} while (0)
+#define        HKBD_UNLOCK()           do {                    \
+       if (!HID_IN_POLLING_MODE())                     \
+               mtx_unlock(&Giant);                     \
+} while (0)
+#define        HKBD_LOCK_ASSERT()      do {                    \
+       if (!HID_IN_POLLING_MODE())                     \
+               mtx_assert(&Giant, MA_OWNED);           \
+} while (0)
 
 #define        NN 0                            /* no translation */
 /*
@@ -247,7 +241,7 @@ struct ukbd_softc {
  * 0x90: Kana
  * 0x91: Eisu
  */
-static const uint8_t ukbd_trtab[256] = {
+static const uint8_t hkbd_trtab[256] = {
        0, 0, 0, 0, 30, 48, 46, 32,     /* 00 - 07 */
        18, 33, 34, 35, 23, 36, 37, 38, /* 08 - 0F */
        50, 49, 24, 25, 16, 19, 31, 20, /* 10 - 17 */
@@ -282,82 +276,68 @@ static const uint8_t ukbd_trtab[256] = {
        NN, NN, NN, NN, NN, NN, NN, NN, /* F8 - FF */
 };
 
-static const uint8_t ukbd_boot_desc[] = {
-       0x05, 0x01, 0x09, 0x06, 0xa1,
-       0x01, 0x05, 0x07, 0x19, 0xe0,
-       0x29, 0xe7, 0x15, 0x00, 0x25,
-       0x01, 0x75, 0x01, 0x95, 0x08,
-       0x81, 0x02, 0x95, 0x01, 0x75,
-       0x08, 0x81, 0x01, 0x95, 0x03,
-       0x75, 0x01, 0x05, 0x08, 0x19,
-       0x01, 0x29, 0x03, 0x91, 0x02,
-       0x95, 0x05, 0x75, 0x01, 0x91,
-       0x01, 0x95, 0x06, 0x75, 0x08,
-       0x15, 0x00, 0x26, 0xff, 0x00,
-       0x05, 0x07, 0x19, 0x00, 0x2a,
-       0xff, 0x00, 0x81, 0x00, 0xc0
-};
+static const uint8_t hkbd_boot_desc[] = { HID_KBD_BOOTPROTO_DESCR() };
 
 /* prototypes */
-static void    ukbd_timeout(void *);
-static void    ukbd_set_leds(struct ukbd_softc *, uint8_t);
-static int     ukbd_set_typematic(keyboard_t *, int);
-#ifdef UKBD_EMULATE_ATSCANCODE
-static uint32_t        ukbd_atkeycode(int, const uint64_t *);
-static int     ukbd_key2scan(struct ukbd_softc *, int, const uint64_t *, int);
+static void    hkbd_timeout(void *);
+static int     hkbd_set_leds(struct hkbd_softc *, uint8_t);
+static int     hkbd_set_typematic(keyboard_t *, int);
+#ifdef HKBD_EMULATE_ATSCANCODE
+static uint32_t        hkbd_atkeycode(int, const uint64_t *);
+static int     hkbd_key2scan(struct hkbd_softc *, int, const uint64_t *, int);
 #endif
-static uint32_t        ukbd_read_char(keyboard_t *, int);
-static void    ukbd_clear_state(keyboard_t *);
-static int     ukbd_ioctl(keyboard_t *, u_long, caddr_t);
-static int     ukbd_enable(keyboard_t *);
-static int     ukbd_disable(keyboard_t *);
-static void    ukbd_interrupt(struct ukbd_softc *);
-static void    ukbd_event_keyinput(struct ukbd_softc *);
-
-static device_probe_t ukbd_probe;
-static device_attach_t ukbd_attach;
-static device_detach_t ukbd_detach;
-static device_resume_t ukbd_resume;
+static uint32_t        hkbd_read_char(keyboard_t *, int);
+static void    hkbd_clear_state(keyboard_t *);
+static int     hkbd_ioctl(keyboard_t *, u_long, caddr_t);
+static int     hkbd_enable(keyboard_t *);
+static int     hkbd_disable(keyboard_t *);
+static void    hkbd_interrupt(struct hkbd_softc *);
+static void    hkbd_event_keyinput(struct hkbd_softc *);
+
+static device_probe_t hkbd_probe;
+static device_attach_t hkbd_attach;
+static device_detach_t hkbd_detach;
+static device_resume_t hkbd_resume;
 
 #ifdef EVDEV_SUPPORT
-static evdev_event_t ukbd_ev_event;
+static evdev_event_t hkbd_ev_event;
 
-static const struct evdev_methods ukbd_evdev_methods = {
-       .ev_event = ukbd_ev_event,
+static const struct evdev_methods hkbd_evdev_methods = {
+       .ev_event = hkbd_ev_event,
 };
 #endif
 
 static bool
-ukbd_any_key_pressed(struct ukbd_softc *sc)
+hkbd_any_key_pressed(struct hkbd_softc *sc)
 {
        bool ret = false;
        unsigned i;
 
-       for (i = 0; i != howmany(UKBD_NKEYCODE, 64); i++)
+       for (i = 0; i != howmany(HKBD_NKEYCODE, 64); i++)
                ret |= (sc->sc_odata.bitmap[i] != 0);
        return (ret);
 }
 
 static bool
-ukbd_any_key_valid(struct ukbd_softc *sc)
+hkbd_any_key_valid(struct hkbd_softc *sc)
 {
        bool ret = false;
        unsigned i;
 
-       for (i = 0; i != howmany(UKBD_NKEYCODE, 64); i++)
+       for (i = 0; i != howmany(HKBD_NKEYCODE, 64); i++)
                ret |= (sc->sc_loc_key_valid[i] != 0);
        return (ret);
 }
 
 static bool
-ukbd_is_modifier_key(uint32_t key)
+hkbd_is_modifier_key(uint32_t key)
 {
 
-       return (key >= 0xe0 && key <= 0xe7);
+       return (key >= MOD_MIN && key <= MOD_MAX);
 }
 
 static void
-ukbd_start_timer(struct ukbd_softc *sc)
+hkbd_start_timer(struct hkbd_softc *sc)
 {
        sbintime_t delay, now, prec;
 
@@ -377,15 +357,16 @@ ukbd_start_timer(struct ukbd_softc *sc)
 
        /* This is rarely called, so prefer precision to efficiency. */
        prec = qmin(delay >> 7, SBT_1MS * 10);
-       usb_callout_reset_sbt(&sc->sc_callout, sc->sc_co_basetime, prec,
-           ukbd_timeout, sc, C_ABSOLUTE);
+       if (!HID_IN_POLLING_MODE())
+               callout_reset_sbt(&sc->sc_callout, sc->sc_co_basetime, prec,
+                   hkbd_timeout, sc, C_ABSOLUTE);
 }
 
 static void
-ukbd_put_key(struct ukbd_softc *sc, uint32_t key)
+hkbd_put_key(struct hkbd_softc *sc, uint32_t key)
 {
 
-       UKBD_LOCK_ASSERT();
+       HKBD_LOCK_ASSERT();
 
        DPRINTF("0x%02x (%d) %s\n", key, key,
            (key & KEY_RELEASE) ? "released" : "pressed");
@@ -396,11 +377,11 @@ ukbd_put_key(struct ukbd_softc *sc, uint32_t key)
                    evdev_hid2key(KEY_INDEX(key)), !(key & KEY_RELEASE));
 #endif
 
-       if (sc->sc_inputs < UKBD_IN_BUF_SIZE) {
+       if (sc->sc_inputs < HKBD_IN_BUF_SIZE) {
                sc->sc_input[sc->sc_inputtail] = key;
                ++(sc->sc_inputs);
                ++(sc->sc_inputtail);
-               if (sc->sc_inputtail >= UKBD_IN_BUF_SIZE) {
+               if (sc->sc_inputtail >= HKBD_IN_BUF_SIZE) {
                        sc->sc_inputtail = 0;
                }
        } else {
@@ -409,15 +390,15 @@ ukbd_put_key(struct ukbd_softc *sc, uint32_t key)
 }
 
 static void
-ukbd_do_poll(struct ukbd_softc *sc, uint8_t wait)
+hkbd_do_poll(struct hkbd_softc *sc, uint8_t wait)
 {
 
-       UKBD_LOCK_ASSERT();
-       KASSERT((sc->sc_flags & UKBD_FLAG_POLLING) != 0,
-           ("ukbd_do_poll called when not polling\n"));
+       HKBD_LOCK_ASSERT();
+       KASSERT((sc->sc_flags & HKBD_FLAG_POLLING) != 0,
+           ("hkbd_do_poll called when not polling\n"));
        DPRINTFN(2, "polling\n");
 
-       if (USB_IN_POLLING_MODE_FUNC() == 0) {
+       if (!HID_IN_POLLING_MODE()) {
                /*
                 * In this context the kernel is polling for input,
                 * but the USB subsystem works in normal interrupt-driven
@@ -438,10 +419,10 @@ ukbd_do_poll(struct ukbd_softc *sc, uint8_t wait)
        }
 
        while (sc->sc_inputs == 0) {
-               usbd_transfer_poll(sc->sc_xfer, UKBD_N_TRANSFER);
+               hidbus_intr_poll(sc->sc_dev);
 
                /* Delay-optimised support for repetition of keys */
-               if (ukbd_any_key_pressed(sc)) {
+               if (hkbd_any_key_pressed(sc)) {
                        /* a key is pressed - need timekeeping */
                        DELAY(1000);
 
@@ -449,7 +430,7 @@ ukbd_do_poll(struct ukbd_softc *sc, uint8_t wait)
                        sc->sc_time_ms += 1;
                }
 
-               ukbd_interrupt(sc);
+               hkbd_interrupt(sc);
 
                if (!wait)
                        break;
@@ -457,24 +438,17 @@ ukbd_do_poll(struct ukbd_softc *sc, uint8_t wait)
 }
 
 static int32_t
-ukbd_get_key(struct ukbd_softc *sc, uint8_t wait)
+hkbd_get_key(struct hkbd_softc *sc, uint8_t wait)
 {
        int32_t c;
 
-       UKBD_LOCK_ASSERT();
-       KASSERT((USB_IN_POLLING_MODE_FUNC() == 0) ||
-           (sc->sc_flags & UKBD_FLAG_POLLING) != 0,
+       HKBD_LOCK_ASSERT();
+       KASSERT(!HID_IN_POLLING_MODE() ||
+           (sc->sc_flags & HKBD_FLAG_POLLING) != 0,
            ("not polling in kdb or panic\n"));
 
-       if (sc->sc_inputs == 0 &&
-           (sc->sc_flags & UKBD_FLAG_GONE) == 0) {
-               /* start transfer, if not already started */
-               usbd_transfer_start(sc->sc_xfer[UKBD_INTR_DT_0]);
-               usbd_transfer_start(sc->sc_xfer[UKBD_INTR_DT_1]);
-       }
-
-       if (sc->sc_flags & UKBD_FLAG_POLLING)
-               ukbd_do_poll(sc, wait);
+       if (sc->sc_flags & HKBD_FLAG_POLLING)
+               hkbd_do_poll(sc, wait);
 
        if (sc->sc_inputs == 0) {
                c = -1;
@@ -482,7 +456,7 @@ ukbd_get_key(struct ukbd_softc *sc, uint8_t wait)
                c = sc->sc_input[sc->sc_inputhead];
                --(sc->sc_inputs);
                ++(sc->sc_inputhead);
-               if (sc->sc_inputhead >= UKBD_IN_BUF_SIZE) {
+               if (sc->sc_inputhead >= HKBD_IN_BUF_SIZE) {
                        sc->sc_inputhead = 0;
                }
        }
@@ -490,53 +464,54 @@ ukbd_get_key(struct ukbd_softc *sc, uint8_t wait)
 }
 
 static void
-ukbd_interrupt(struct ukbd_softc *sc)
+hkbd_interrupt(struct hkbd_softc *sc)
 {
        const uint32_t now = sc->sc_time_ms;
        unsigned key;
 
-       UKBD_LOCK_ASSERT();
+       HKBD_LOCK_ASSERT();
 
-       /* Check for modifier key changes first */
-       for (key = 0xe0; key != 0xe8; key++) {
+       /* Check for key changes, the order is:
+        * 1. Modifier keys down
+        * 2. Regular keys up/down
+        * 3. Modifier keys up
+        *
+        * 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);
-               const uint64_t delta =
-                   sc->sc_odata.bitmap[key / 64] ^
-                   sc->sc_ndata.bitmap[key / 64];
 
-               if (delta & mask) {
-                       if (sc->sc_odata.bitmap[key / 64] & mask)
-                               ukbd_put_key(sc, key | KEY_RELEASE);
-                       else
-                               ukbd_put_key(sc, key | KEY_PRESS);
+               if (!(sc->sc_odata.bitmap[key / 64] & mask) &&
+                   (sc->sc_ndata.bitmap[key / 64] & mask)) {
+                       hkbd_put_key(sc, key | KEY_PRESS);
                }
        }
-
-       /* Check for key changes */
-       for (key = 0; key != UKBD_NKEYCODE; key++) {
+       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))
+                       continue;
+
                if (mask == 1 && delta == 0) {
                        key += 63;
                        continue;       /* skip empty areas */
-               } else if (ukbd_is_modifier_key(key)) {
-                       continue;
                } else if (delta & mask) {
                        if (sc->sc_odata.bitmap[key / 64] & mask) {
-                               ukbd_put_key(sc, key | KEY_RELEASE);
+                               hkbd_put_key(sc, key | KEY_RELEASE);
 
                                /* clear repeating key, if any */
                                if (sc->sc_repeat_key == key)
                                        sc->sc_repeat_key = 0;
                        } else {
-                               ukbd_put_key(sc, key | KEY_PRESS);
+                               hkbd_put_key(sc, key | KEY_PRESS);
 
                                sc->sc_co_basetime = sbinuptime();
                                sc->sc_delay = sc->sc_kbd.kb_delay1;
-                               ukbd_start_timer(sc);
+                               hkbd_start_timer(sc);
 
                                /* set repeat time for last key */
                                sc->sc_repeat_time = now + sc->sc_kbd.kb_delay1;
@@ -544,6 +519,14 @@ ukbd_interrupt(struct ukbd_softc *sc)
                        }
                }
        }
+       for (key = MOD_MIN; key <= MOD_MAX; key++) {
+               const uint64_t mask = 1ULL << (key % 64);
+
+               if ((sc->sc_odata.bitmap[key / 64] & mask) &&
+                   !(sc->sc_ndata.bitmap[key / 64] & mask)) {
+                       hkbd_put_key(sc, key | KEY_RELEASE);
+               }
+       }
 
        /* synchronize old data with new data */
        sc->sc_odata = sc->sc_ndata;
@@ -554,7 +537,7 @@ ukbd_interrupt(struct ukbd_softc *sc)
 
                /* check if time has elapsed */
                if (dtime <= 0) {
-                       ukbd_put_key(sc, sc->sc_repeat_key | KEY_PRESS);
+                       hkbd_put_key(sc, sc->sc_repeat_key | KEY_PRESS);
                        sc->sc_repeat_time = now + sc->sc_kbd.kb_delay2;
                }
        }
@@ -565,17 +548,17 @@ ukbd_interrupt(struct ukbd_softc *sc)
 #endif
 
        /* wakeup keyboard system */
-       ukbd_event_keyinput(sc);
+       hkbd_event_keyinput(sc);
 }
 
 static void
-ukbd_event_keyinput(struct ukbd_softc *sc)
+hkbd_event_keyinput(struct hkbd_softc *sc)
 {
        int c;
 
-       UKBD_LOCK_ASSERT();
+       HKBD_LOCK_ASSERT();
 
-       if ((sc->sc_flags & UKBD_FLAG_POLLING) != 0)
+       if ((sc->sc_flags & HKBD_FLAG_POLLING) != 0)
                return;
 
        if (sc->sc_inputs == 0)
@@ -589,33 +572,36 @@ ukbd_event_keyinput(struct ukbd_softc *sc)
        } else {
                /* read and discard the input, no one is waiting for it */
                do {
-                       c = ukbd_read_char(&sc->sc_kbd, 0);
+                       c = hkbd_read_char(&sc->sc_kbd, 0);
                } while (c != NOKEY);
        }
 }
 
 static void
-ukbd_timeout(void *arg)
+hkbd_timeout(void *arg)
 {
-       struct ukbd_softc *sc = arg;
+       struct hkbd_softc *sc = arg;
+       struct epoch_tracker et;
 
-       UKBD_LOCK_ASSERT();
+       HKBD_LOCK_ASSERT();
 
        sc->sc_time_ms += sc->sc_delay;
        sc->sc_delay = 0;
 
-       ukbd_interrupt(sc);
+       epoch_enter_preempt(INPUT_EPOCH, &et);
+       hkbd_interrupt(sc);
+       epoch_exit_preempt(INPUT_EPOCH, &et);
 
        /* Make sure any leftover key events gets read out */
-       ukbd_event_keyinput(sc);
+       hkbd_event_keyinput(sc);
 
-       if (ukbd_any_key_pressed(sc) || (sc->sc_inputs != 0)) {
-               ukbd_start_timer(sc);
+       if (hkbd_any_key_pressed(sc) || (sc->sc_inputs != 0)) {
+               hkbd_start_timer(sc);
        }
 }
 
 static uint32_t
-ukbd_apple_fn(uint32_t keycode)
+hkbd_apple_fn(uint32_t keycode)
 {
        switch (keycode) {
        case 0x28: return 0x49; /* RETURN -> INSERT */
@@ -629,7 +615,7 @@ ukbd_apple_fn(uint32_t keycode)
 }
 
 static uint32_t
-ukbd_apple_swap(uint32_t keycode)
+hkbd_apple_swap(uint32_t keycode)
 {
        switch (keycode) {
        case 0x35: return 0x64;
@@ -639,347 +625,141 @@ ukbd_apple_swap(uint32_t keycode)
 }
 
 static void
-ukbd_intr_callback(struct usb_xfer *xfer, usb_error_t error)
+hkbd_intr_callback(void *context, void *data, hid_size_t len)
 {
-       struct ukbd_softc *sc = usbd_xfer_softc(xfer);
-       struct usb_page_cache *pc;
+       struct hkbd_softc *sc = context;
+       uint8_t *buf = data;
        uint32_t i;
-       uint8_t id;
+       uint8_t id = 0;
        uint8_t modifiers;
        int offset;
-       int len;
 
-       UKBD_LOCK_ASSERT();
+       HKBD_LOCK_ASSERT();
 
-       usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
-       pc = usbd_xfer_get_frame(xfer, 0);
+       DPRINTF("actlen=%d bytes\n", len);
 
-       switch (USB_GET_STATE(xfer)) {
-       case USB_ST_TRANSFERRED:
-               DPRINTF("actlen=%d bytes\n", len);
+       if (len == 0) {
+               DPRINTF("zero length data\n");
+               return;
+       }
 
+       if (sc->sc_kbd_id != 0) {
+               /* check and remove HID ID byte */
+               id = buf[0];
+               buf++;
+               len--;
                if (len == 0) {
                        DPRINTF("zero length data\n");
-                       goto tr_setup;
+                       return;
                }
+       }
 
-               if (sc->sc_kbd_id != 0) {
-                       /* check and remove HID ID byte */
-                       usbd_copy_out(pc, 0, &id, 1);
-                       offset = 1;
-                       len--;
-                       if (len == 0) {
-                               DPRINTF("zero length data\n");
-                               goto tr_setup;
-                       }
-               } else {
-                       offset = 0;
-                       id = 0;
-               }
-
-               if (len > UKBD_BUFFER_SIZE)
-                       len = UKBD_BUFFER_SIZE;
-
-               /* get data */
-               usbd_copy_out(pc, offset, sc->sc_buffer, len);
-
-               /* clear temporary storage */
-               memset(&sc->sc_ndata, 0, sizeof(sc->sc_ndata));
+       /* clear temporary storage */
+       memset(&sc->sc_ndata, 0, sizeof(sc->sc_ndata));
 
-               /* clear modifiers */
-               modifiers = 0;
+       /* clear modifiers */
+       modifiers = 0;
 
-               /* scan through HID data */
-               if ((sc->sc_flags & UKBD_FLAG_APPLE_EJECT) &&
-                   (id == sc->sc_id_apple_eject)) {
-                       if (hid_get_data(sc->sc_buffer, len, 
&sc->sc_loc_apple_eject))
-                               modifiers |= MOD_EJECT;
-               }
-               if ((sc->sc_flags & UKBD_FLAG_APPLE_FN) &&
-                   (id == sc->sc_id_apple_fn)) {
-                       if (hid_get_data(sc->sc_buffer, len, 
&sc->sc_loc_apple_fn))
-                               modifiers |= MOD_FN;
-               }
+       /* scan through HID data */
+       if ((sc->sc_flags & HKBD_FLAG_APPLE_EJECT) &&
+           (id == sc->sc_id_apple_eject)) {
+               if (hid_get_data(buf, len, &sc->sc_loc_apple_eject))
+                       modifiers |= MOD_EJECT;
+       }
+       if ((sc->sc_flags & HKBD_FLAG_APPLE_FN) &&
+           (id == sc->sc_id_apple_fn)) {
+               if (hid_get_data(buf, len, &sc->sc_loc_apple_fn))
+                       modifiers |= MOD_FN;
+       }
 
-               for (i = 0; i != UKBD_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]) {
-                               continue;       /* invalid HID ID */
-                       } else if (i == 0) {
-                               struct hid_location tmp_loc = sc->sc_loc_key[0];
-                               /* range check array size */
-                               if (tmp_loc.count > UKBD_NKEYCODE)
-                                       tmp_loc.count = UKBD_NKEYCODE;
-                               while (tmp_loc.count--) {
-                                       uint32_t key =
-                                           hid_get_udata(sc->sc_buffer, len, 
&tmp_loc);
-                                       /* advance to next location */
*** 1579 LINES SKIPPED ***
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to