Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-8]: src/sys/dev/usb Pull up following revision(s) (requested by j...



details:   https://anonhg.NetBSD.org/src/rev/3c71d529b54b
branches:  netbsd-8
changeset: 851005:3c71d529b54b
user:      snj <snj%NetBSD.org@localhost>
date:      Mon Sep 04 06:43:14 2017 +0000

description:
Pull up following revision(s) (requested by jakllsch in ticket #263):
        sys/dev/usb/uhidev.c: revision 1.71
        sys/dev/usb/ukbd.c: revision 1.137-1.138
Fix memory leak in report parsing error paths.
--
Support more varieties of USB keyboard reports.
The previous code asssumed reports would closely match the Bootstrap
Keyboard Protocol.  This is no longer always the case, particularly
with higher-end keyboards.
--
Always try to set USB HID devices into Report Protocol.  (Unless the
device is known to be quirky.)
Some of the most-widely-compatible methods of implementing USB Keyboard
NKRO depend on this Request to function as designed.
Issuing this Request is recommended by the HID 1.11 spec (7.2.6):
... "the host should not make any assumptions about the device's state
and should set the desired protocol whenever initializing a device."

diffstat:

 sys/dev/usb/uhidev.c |    9 +-
 sys/dev/usb/ukbd.c   |  196 ++++++++++++++++++++++----------------------------
 2 files changed, 88 insertions(+), 117 deletions(-)

diffs (truncated from 361 to 300 lines):

diff -r 22d42a67734f -r 3c71d529b54b sys/dev/usb/uhidev.c
--- a/sys/dev/usb/uhidev.c      Mon Sep 04 06:40:37 2017 +0000
+++ b/sys/dev/usb/uhidev.c      Mon Sep 04 06:43:14 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uhidev.c,v 1.70 2017/06/01 02:45:12 chs Exp $  */
+/*     $NetBSD: uhidev.c,v 1.70.2.1 2017/09/04 06:43:14 snj Exp $      */
 
 /*
  * Copyright (c) 2001, 2012 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.70 2017/06/01 02:45:12 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.70.2.1 2017/09/04 06:43:14 snj Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -153,12 +153,9 @@
                aprint_error_dev(self, "couldn't establish power handler\n");
 
        (void)usbd_set_idle(iface, 0, 0);
-#if 0
 
-       if ((usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_NO_SET_PROTO) == 0 &&
-           id->bInterfaceSubClass != UISUBCLASS_BOOT)
+       if ((usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_NO_SET_PROTO) == 0)
                (void)usbd_set_protocol(iface, 1);
-#endif
 
        maxinpktsize = 0;
        sc->sc_iep_addr = sc->sc_oep_addr = -1;
diff -r 22d42a67734f -r 3c71d529b54b sys/dev/usb/ukbd.c
--- a/sys/dev/usb/ukbd.c        Mon Sep 04 06:40:37 2017 +0000
+++ b/sys/dev/usb/ukbd.c        Mon Sep 04 06:43:14 2017 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: ukbd.c,v 1.136 2017/01/20 02:25:24 maya Exp $        */
+/*      $NetBSD: ukbd.c,v 1.136.6.1 2017/09/04 06:43:14 snj Exp $        */
 
 /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ukbd.c,v 1.136 2017/01/20 02:25:24 maya Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ukbd.c,v 1.136.6.1 2017/09/04 06:43:14 snj Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -83,12 +83,11 @@
 #define DPRINTFN(n,x)
 #endif
 
-#define MAXKEYCODE 6
-#define MAXMOD 8               /* max 32 */
+#define MAXKEYCODE 32
+#define MAXKEYS 256
 
 struct ukbd_data {
-       uint32_t        modifiers;
-       uint8_t         keycode[MAXKEYCODE];
+       uint8_t         keys[MAXKEYS/NBBY];
 };
 
 #define PRESS    0x000
@@ -234,19 +233,14 @@
 
 #define KEY_ERROR 0x01
 
-#define MAXKEYS (MAXMOD+2*MAXKEYCODE)
-
 struct ukbd_softc {
        struct uhidev sc_hdev;
 
        struct ukbd_data sc_ndata;
        struct ukbd_data sc_odata;
-       struct hid_location sc_modloc[MAXMOD];
-       u_int sc_nmod;
-       struct {
-               uint32_t mask;
-               uint8_t key;
-       } sc_mods[MAXMOD];
+       struct hid_location sc_keyloc[MAXKEYS];
+       uint8_t sc_keyuse[MAXKEYS];
+       u_int sc_nkeyloc;
 
        struct hid_location sc_keycodeloc;
        u_int sc_nkeycode;
@@ -307,15 +301,17 @@
 void
 ukbdtracedump(void)
 {
-       int i;
+       size_t i, j;
        for (i = 0; i < UKBDTRACESIZE; i++) {
                struct ukbdtraceinfo *p =
                    &ukbdtracedata[(i+ukbdtraceindex)%UKBDTRACESIZE];
-               printf("%"PRIu64".%06"PRIu64": mod=0x%02x key0=0x%02x key1=0x%02x "
-                      "key2=0x%02x key3=0x%02x\n",
-                      p->tv.tv_sec, (uint64_t)p->tv.tv_usec,
-                      p->ud.modifiers, p->ud.keycode[0], p->ud.keycode[1],
-                      p->ud.keycode[2], p->ud.keycode[3]);
+               printf("%"PRIu64".%06"PRIu64":", p->tv.tv_sec,
+                   (uint64_t)p->tv.tv_usec);
+               for (j = 0; j < MAXKEYS; j++) {
+                       if (isset(p->ud.keys, j))
+                               printf(" %zu", j);
+               }
+               printf(".\n");
        }
 }
 #endif
@@ -438,7 +434,7 @@
 #endif
 
 #ifdef DIAGNOSTIC
-       aprint_normal(": %d modifier keys, %d key codes", sc->sc_nmod,
+       aprint_normal(": %d Variable keys, %d Array codes", sc->sc_nkeyloc,
               sc->sc_nkeycode);
        if (sc->sc_flags & FLAG_APPLE_FN)
                aprint_normal(", apple fn key");
@@ -595,21 +591,22 @@
     const struct ukbd_keycodetrans *tab)
 {
        const struct ukbd_keycodetrans *tp;
+       struct ukbd_data oud;
        int i;
-       uint8_t key;
+
+       oud = *ud;
 
-       for (i = 0; i < sc->sc_nkeycode; i++) {
-               key = ud->keycode[i];
-               if (key)
+       for (i = 4; i < MAXKEYS; i++) {
+               if (isset(oud.keys, i))
                        for (tp = tab; tp->from; tp++)
-                               if (tp->from == key) {
+                               if (tp->from == i) {
                                        if (tp->to & IS_PMF) {
                                                pmf_event_inject(
                                                    sc->sc_hdev.sc_dev,
                                                    tp->to & 0xff);
-                                               ud->keycode[i] = 0;
                                        } else
-                                               ud->keycode[i] = tp->to;
+                                               setbit(ud->keys, tp->to);
+                                       clrbit(ud->keys, i);
                                        break;
                                }
        }
@@ -652,12 +649,18 @@
        }
 #endif
 
-       ud->modifiers = 0;
-       for (i = 0; i < sc->sc_nmod; i++)
-               if (hid_get_data(ibuf, &sc->sc_modloc[i]))
-                       ud->modifiers |= sc->sc_mods[i].mask;
-       memcpy(ud->keycode, (char *)ibuf + sc->sc_keycodeloc.pos / 8,
-              sc->sc_nkeycode);
+       memset(ud->keys, 0, sizeof(ud->keys));
+
+       for (i = 0; i < sc->sc_nkeyloc; i++)
+               if (hid_get_data(ibuf, &sc->sc_keyloc[i]))
+                       setbit(ud->keys, sc->sc_keyuse[i]);
+
+       const uint8_t * const scancode = (char *)ibuf + sc->sc_keycodeloc.pos / 8;
+       const uint16_t Keyboard_NoEvent = 0x0000;
+       for (i = 0; i < sc->sc_nkeycode; i++) {
+               if (scancode[i] != Keyboard_NoEvent)
+                       setbit(ud->keys, scancode[i]);
+       }
 
        if (sc->sc_flags & FLAG_APPLE_FN) {
                if (hid_get_data(ibuf, &sc->sc_apple_fn)) {
@@ -714,10 +717,12 @@
 void
 ukbd_decode(struct ukbd_softc *sc, struct ukbd_data *ud)
 {
-       int mod, omod;
        uint16_t ibuf[MAXKEYS]; /* chars events */
        int s;
-       int nkeys, i, j;
+       int nkeys, i;
+#ifdef WSDISPLAY_COMPAT_RAWKBD
+       int j;
+#endif
        int key;
 #define ADDKEY(c) do { \
     KASSERT(nkeys < MAXKEYS); \
@@ -740,15 +745,17 @@
        if (ukbddebug > 5) {
                struct timeval tv;
                microtime(&tv);
-               DPRINTF((" at %"PRIu64".%06"PRIu64"  mod=0x%02x key0=0x%02x key1=0x%02x "
-                        "key2=0x%02x key3=0x%02x\n",
-                        tv.tv_sec, (uint64_t)tv.tv_usec,
-                        ud->modifiers, ud->keycode[0], ud->keycode[1],
-                        ud->keycode[2], ud->keycode[3]));
+               DPRINTF((" at %"PRIu64".%06"PRIu64":", tv.tv_sec,
+                   (uint64_t)tv.tv_usec));
+               for (size_t k = 0; k < MAXKEYS; k++) {
+                       if (isset(ud->keys, k))
+                               DPRINTF((" %zu", k));
+               }
+               DPRINTF((".\n"));
        }
 #endif
 
-       if (ud->keycode[0] == KEY_ERROR) {
+       if (isset(ud->keys, KEY_ERROR)) {
                DPRINTF(("ukbd_intr: KEY_ERROR\n"));
                return;         /* ignore  */
        }
@@ -757,61 +764,19 @@
                ukbd_translate_keycodes(sc, ud, trtab_apple_iso);
 
        nkeys = 0;
-       mod = ud->modifiers;
-       omod = sc->sc_odata.modifiers;
-       if (mod != omod)
-               for (i = 0; i < sc->sc_nmod; i++)
-                       if (( mod & sc->sc_mods[i].mask) !=
-                           (omod & sc->sc_mods[i].mask)) {
-                               key = sc->sc_mods[i].key |
-                                   ((mod & sc->sc_mods[i].mask) ?
-                                   PRESS : RELEASE);
+       for (i = 0; i < MAXKEYS; i++) {
+#ifdef GDIUM_KEYBOARD_HACK
+                       if (sc->sc_flags & FLAG_GDIUM_FN && i == 0x82) {
+                               if (isset(ud->keys, i))
+                                       sc->sc_flags |= FLAG_FN_PRESSED;
+                               else
+                                       sc->sc_flags &= ~FLAG_FN_PRESSED;
+                       }
+#endif
+                       if (isset(ud->keys, i) != isset(sc->sc_odata.keys, i)) {
+                               key = i | ((isset(ud->keys, i) ? PRESS : RELEASE));
                                ADDKEY(ukbd_translate_modifier(sc, key));
                        }
-       if (memcmp(ud->keycode, sc->sc_odata.keycode, sc->sc_nkeycode) != 0) {
-               /* Check for released keys. */
-               for (i = 0; i < sc->sc_nkeycode; i++) {
-                       key = sc->sc_odata.keycode[i];
-                       if (key == 0)
-                               continue;
-                       for (j = 0; j < sc->sc_nkeycode; j++)
-                               if (key == ud->keycode[j])
-                                       goto rfound;
-                       DPRINTFN(3,("ukbd_intr: relse key=0x%02x\n", key));
-#ifdef GDIUM_KEYBOARD_HACK
-                       if (sc->sc_flags & FLAG_GDIUM_FN) {
-                               if (key == 0x82) {
-                                       sc->sc_flags &= ~FLAG_FN_PRESSED;
-                                       goto rfound;
-                               }
-                       }
-#endif
-                       ADDKEY(key | RELEASE);
-               rfound:
-                       ;
-               }
-
-               /* Check for pressed keys. */
-               for (i = 0; i < sc->sc_nkeycode; i++) {
-                       key = ud->keycode[i];
-                       if (key == 0)
-                               continue;
-                       for (j = 0; j < sc->sc_nkeycode; j++)
-                               if (key == sc->sc_odata.keycode[j])
-                                       goto pfound;
-                       DPRINTFN(2,("ukbd_intr: press key=0x%02x\n", key));
-#ifdef GDIUM_KEYBOARD_HACK
-                       if (sc->sc_flags & FLAG_GDIUM_FN) {
-                               if (key == 0x82) {
-                                       sc->sc_flags |= FLAG_FN_PRESSED;
-                                       goto pfound;
-                               }
-                       }
-#endif
-                       ADDKEY(key | PRESS);
-               pfound:
-                       ;
-               }
        }
        sc->sc_odata = *ud;
 
@@ -1052,10 +1017,10 @@
        struct hid_item h;
        int size;
        void *desc;
-       int imod;
+       int ikey;
 
        uhidev_get_report_desc(sc->sc_hdev.sc_parent, &desc, &size);
-       imod = 0;
+       ikey = 0;
        sc->sc_nkeycode = 0;



Home | Main Index | Thread Index | Old Index