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/a0fbd856a8ab
branches: netbsd-8
changeset: 434281:a0fbd856a8ab
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 9e03f34e8a85 -r a0fbd856a8ab 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 9e03f34e8a85 -r a0fbd856a8ab 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