Subject: kern/29558: USB keyboards don't provide autorepeat on netbsd/i386
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Matthias Pfaller <leo@dachau.marco.de>
List: netbsd-bugs
Date: 02/28/2005 16:40:00
>Number: 29558
>Category: kern
>Synopsis: USB keyboards don't provide autorepeat on netbsd/i386
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Feb 28 16:40:00 +0000 2005
>Originator: Matthias Pfaller
>Release: NetBSD 2.99.14
>Organization:
Matthias Pfaller Software Entwicklung
marco Systemanalyse und Entwicklung GmbH Tel +49 8131 5161-41
Hans-B=F6ckler-Str. 2, D 85221 Dachau Fax +49 8131 5161-66
http://www.marco.de/ Email leo@dachau.marco.de
>Environment:
System: NetBSD joghurt 2.99.14 NetBSD 2.99.14 (SIN) #24: Mon Jan 17 10:21:1=
7 CET 2005 leo@joghurt:/usr/src/sys/arch/i386/compile/SIN i386
Architecture: i386
Machine: i386
>Description:
When using usb keyboards with XF86 (secondary keyboard, RAW mode is
not enabled), autorepeat is not working.
How does this work with architectures that use USB keyboards only?
Should this be fixed in the kernel (as I did it) or should this be
fixed in the xserver?
>How-To-Repeat:
Connect an usb keyboard and change XF86Config to use this keyboard
instead of the console keyboard.
>Fix:
RCS file: /cvsroot/src/sys/dev/usb/ukbd.c,v
retrieving revision 1.85
diff -u -u -r1.85 ukbd.c
--- ukbd.c 11 Mar 2003 16:44:00 -0000 1.85
+++ ukbd.c 28 Feb 2005 16:34:04 -0000
@@ -172,6 +172,8 @@
struct hid_location sc_capsloc;
struct hid_location sc_scroloc;
int sc_leds;
+ usb_callout_t sc_repeat_ch;
+ int sc_rep_char;
#if defined(__NetBSD__)
usb_callout_t sc_rawrepeat_ch;
=20
@@ -250,6 +252,7 @@
#ifdef WSDISPLAY_COMPAT_RAWKBD
Static void ukbd_rawrepeat(void *v);
#endif
+Static void ukbd_repeat(void *v);
=20
const struct wskbd_accessops ukbd_accessops =3D {
ukbd_enable,
@@ -631,14 +634,20 @@
return;
}
#endif
-
s =3D spltty();
+ key =3D 0; /* shutup gcc */
for (i =3D 0; i < nkeys; i++) {
key =3D ibuf[i];
wskbd_input(sc->sc_wskbddev,
key&RELEASE ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN,
key&CODEMASK);
}
+ usb_uncallout(sc->sc_repeat_ch, ukbd_repeat, sc);
+ if ((key & RELEASE) =3D=3D 0) {
+ sc->sc_rep_char =3D key;
+ usb_callout(sc->sc_repeat_ch,
+ hz * REP_DELAY1 / 1000, ukbd_repeat, sc);
+ }
splx(s);
}
=20
@@ -683,6 +692,22 @@
}
#endif
=20
+void
+ukbd_repeat(void *v)
+{
+ struct ukbd_softc *sc =3D v;
+ int s;
+
+ s =3D spltty();
+ wskbd_input(sc->sc_wskbddev, WSCONS_EVENT_KEY_UP,
+ sc->sc_rep_char & CODEMASK);
+ wskbd_input(sc->sc_wskbddev, WSCONS_EVENT_KEY_DOWN,
+ sc->sc_rep_char & CODEMASK);
+ splx(s);
+ usb_callout(sc->sc_repeat_ch, hz * REP_DELAYN / 1000,
+ ukbd_repeat, sc);
+}
+
int
ukbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, usb_proc_ptr p)
{