6 * Copyright (c) 1998 The NetBSD Foundation, Inc.
9 * This code is derived from software contributed to The NetBSD Foundation
10 * by Lennart Augustsson (lennart@augustsson.net) at
11 * Carlstedt Research & Technology.
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
22 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
37 * HID spec: http://www.usb.org/developers/devclass_docs/HID1_11.pdf
40 #include "opt_compat.h"
44 #include <sys/stdint.h>
45 #include <sys/stddef.h>
46 #include <sys/param.h>
47 #include <sys/queue.h>
48 #include <sys/types.h>
49 #include <sys/systm.h>
50 #include <sys/kernel.h>
52 #include <sys/module.h>
54 #include <sys/mutex.h>
55 #include <sys/condvar.h>
56 #include <sys/sysctl.h>
58 #include <sys/unistd.h>
59 #include <sys/callout.h>
60 #include <sys/malloc.h>
63 #include <sys/sched.h>
66 #include <dev/usb/usb.h>
67 #include <dev/usb/usbdi.h>
68 #include <dev/usb/usbdi_util.h>
69 #include <dev/usb/usbhid.h>
71 #define USB_DEBUG_VAR ukbd_debug
72 #include <dev/usb/usb_debug.h>
74 #include <dev/usb/quirk/usb_quirk.h>
76 #include <sys/ioccom.h>
77 #include <sys/filio.h>
81 #include <dev/kbd/kbdreg.h>
83 /* the initial key map, accent map and fkey strings */
84 #if defined(UKBD_DFLT_KEYMAP) && !defined(KLD_MODULE)
85 #define KBD_DFLT_KEYMAP
89 /* the following file must be included after "ukbdmap.h" */
90 #include <dev/kbd/kbdtables.h>
93 static int ukbd_debug = 0;
94 static int ukbd_no_leds = 0;
96 SYSCTL_NODE(_hw_usb, OID_AUTO, ukbd, CTLFLAG_RW, 0, "USB ukbd");
97 SYSCTL_INT(_hw_usb_ukbd, OID_AUTO, debug, CTLFLAG_RW,
98 &ukbd_debug, 0, "Debug level");
99 SYSCTL_INT(_hw_usb_ukbd, OID_AUTO, no_leds, CTLFLAG_RW,
100 &ukbd_no_leds, 0, "Disables setting of keyboard leds");
102 TUNABLE_INT("hw.usb.ukbd.debug", &ukbd_debug);
103 TUNABLE_INT("hw.usb.ukbd.no_leds", &ukbd_no_leds);
106 #define UKBD_EMULATE_ATSCANCODE 1
107 #define UKBD_DRIVER_NAME "ukbd"
108 #define UKBD_NMOD 8 /* units */
109 #define UKBD_NKEYCODE 6 /* units */
110 #define UKBD_IN_BUF_SIZE (2*(UKBD_NMOD + (2*UKBD_NKEYCODE))) /* bytes */
111 #define UKBD_IN_BUF_FULL (UKBD_IN_BUF_SIZE / 2) /* bytes */
112 #define UKBD_NFKEY (sizeof(fkey_tab)/sizeof(fkey_tab[0])) /* units */
113 #define UKBD_BUFFER_SIZE 64 /* bytes */
117 #define MOD_CONTROL_L 0x01
118 #define MOD_CONTROL_R 0x10
119 #define MOD_SHIFT_L 0x02
120 #define MOD_SHIFT_R 0x20
121 #define MOD_ALT_L 0x04
122 #define MOD_ALT_R 0x40
123 #define MOD_WIN_L 0x08
124 #define MOD_WIN_R 0x80
126 #define MOD_EJECT 0x0100
127 #define MOD_FN 0x0200
128 uint8_t keycode[UKBD_NKEYCODE];
140 accentmap_t sc_accmap;
141 fkeytab_t sc_fkeymap[UKBD_NFKEY];
142 struct hid_location sc_loc_apple_eject;
143 struct hid_location sc_loc_apple_fn;
144 struct hid_location sc_loc_ctrl_l;
145 struct hid_location sc_loc_ctrl_r;
146 struct hid_location sc_loc_shift_l;
147 struct hid_location sc_loc_shift_r;
148 struct hid_location sc_loc_alt_l;
149 struct hid_location sc_loc_alt_r;
150 struct hid_location sc_loc_win_l;
151 struct hid_location sc_loc_win_r;
152 struct hid_location sc_loc_events;
153 struct hid_location sc_loc_numlock;
154 struct hid_location sc_loc_capslock;
155 struct hid_location sc_loc_scrolllock;
156 struct usb_callout sc_callout;
157 struct ukbd_data sc_ndata;
158 struct ukbd_data sc_odata;
160 struct thread *sc_poll_thread;
161 struct usb_device *sc_udev;
162 struct usb_interface *sc_iface;
163 struct usb_xfer *sc_xfer[UKBD_N_TRANSFER];
165 uint32_t sc_ntime[UKBD_NKEYCODE];
166 uint32_t sc_otime[UKBD_NKEYCODE];
167 uint32_t sc_input[UKBD_IN_BUF_SIZE]; /* input buffer */
169 uint32_t sc_composed_char; /* composed char code, if non-zero */
170 #ifdef UKBD_EMULATE_ATSCANCODE
171 uint32_t sc_buffered_char[2];
173 uint32_t sc_flags; /* flags */
174 #define UKBD_FLAG_COMPOSE 0x00000001
175 #define UKBD_FLAG_POLLING 0x00000002
176 #define UKBD_FLAG_SET_LEDS 0x00000004
177 #define UKBD_FLAG_ATTACHED 0x00000010
178 #define UKBD_FLAG_GONE 0x00000020
180 #define UKBD_FLAG_HID_MASK 0x003fffc0
181 #define UKBD_FLAG_APPLE_EJECT 0x00000040
182 #define UKBD_FLAG_APPLE_FN 0x00000080
183 #define UKBD_FLAG_APPLE_SWAP 0x00000100
184 #define UKBD_FLAG_TIMER_RUNNING 0x00000200
185 #define UKBD_FLAG_CTRL_L 0x00000400
186 #define UKBD_FLAG_CTRL_R 0x00000800
187 #define UKBD_FLAG_SHIFT_L 0x00001000
188 #define UKBD_FLAG_SHIFT_R 0x00002000
189 #define UKBD_FLAG_ALT_L 0x00004000
190 #define UKBD_FLAG_ALT_R 0x00008000
191 #define UKBD_FLAG_WIN_L 0x00010000
192 #define UKBD_FLAG_WIN_R 0x00020000
193 #define UKBD_FLAG_EVENTS 0x00040000
194 #define UKBD_FLAG_NUMLOCK 0x00080000
195 #define UKBD_FLAG_CAPSLOCK 0x00100000
196 #define UKBD_FLAG_SCROLLLOCK 0x00200000
198 int sc_mode; /* input mode (K_XLATE,K_RAW,K_CODE) */
199 int sc_state; /* shift/lock key state */
200 int sc_accents; /* accent key index (> 0) */
201 int sc_poll_tick_last;
206 uint16_t sc_inputhead;
207 uint16_t sc_inputtail;
208 uint16_t sc_modifiers;
210 uint8_t sc_leds; /* store for async led requests */
211 uint8_t sc_iface_index;
213 uint8_t sc_id_apple_eject;
214 uint8_t sc_id_apple_fn;
215 uint8_t sc_id_ctrl_l;
216 uint8_t sc_id_ctrl_r;
217 uint8_t sc_id_shift_l;
218 uint8_t sc_id_shift_r;
224 uint8_t sc_id_numlock;
225 uint8_t sc_id_capslock;
226 uint8_t sc_id_scrolllock;
227 uint8_t sc_id_events;
230 uint8_t sc_poll_detected;
231 uint8_t sc_buffer[UKBD_BUFFER_SIZE];
234 #define KEY_ERROR 0x01
237 #define KEY_RELEASE 0x400
238 #define KEY_INDEX(c) ((c) & 0xFF)
241 #define SCAN_RELEASE 0x80
242 #define SCAN_PREFIX_E0 0x100
243 #define SCAN_PREFIX_E1 0x200
244 #define SCAN_PREFIX_CTL 0x400
245 #define SCAN_PREFIX_SHIFT 0x800
246 #define SCAN_PREFIX (SCAN_PREFIX_E0 | SCAN_PREFIX_E1 | \
247 SCAN_PREFIX_CTL | SCAN_PREFIX_SHIFT)
248 #define SCAN_CHAR(c) ((c) & 0x7f)
254 static const struct ukbd_mods ukbd_mods[UKBD_NMOD] = {
255 {MOD_CONTROL_L, 0xe0},
256 {MOD_CONTROL_R, 0xe4},
265 #define NN 0 /* no translation */
267 * Translate USB keycodes to AT keyboard scancodes.
270 * FIXME: Mac USB keyboard generates:
271 * 0x53: keypad NumLock/Clear
278 static const uint8_t ukbd_trtab[256] = {
279 0, 0, 0, 0, 30, 48, 46, 32, /* 00 - 07 */
280 18, 33, 34, 35, 23, 36, 37, 38, /* 08 - 0F */
281 50, 49, 24, 25, 16, 19, 31, 20, /* 10 - 17 */
282 22, 47, 17, 45, 21, 44, 2, 3, /* 18 - 1F */
283 4, 5, 6, 7, 8, 9, 10, 11, /* 20 - 27 */
284 28, 1, 14, 15, 57, 12, 13, 26, /* 28 - 2F */
285 27, 43, 43, 39, 40, 41, 51, 52, /* 30 - 37 */
286 53, 58, 59, 60, 61, 62, 63, 64, /* 38 - 3F */
287 65, 66, 67, 68, 87, 88, 92, 70, /* 40 - 47 */
288 104, 102, 94, 96, 103, 99, 101, 98, /* 48 - 4F */
289 97, 100, 95, 69, 91, 55, 74, 78,/* 50 - 57 */
290 89, 79, 80, 81, 75, 76, 77, 71, /* 58 - 5F */
291 72, 73, 82, 83, 86, 107, 122, NN, /* 60 - 67 */
292 NN, NN, NN, NN, NN, NN, NN, NN, /* 68 - 6F */
293 NN, NN, NN, NN, 115, 108, 111, 113, /* 70 - 77 */
294 109, 110, 112, 118, 114, 116, 117, 119, /* 78 - 7F */
295 121, 120, NN, NN, NN, NN, NN, 123, /* 80 - 87 */
296 124, 125, 126, 127, 128, NN, NN, NN, /* 88 - 8F */
297 NN, NN, NN, NN, NN, NN, NN, NN, /* 90 - 97 */
298 NN, NN, NN, NN, NN, NN, NN, NN, /* 98 - 9F */
299 NN, NN, NN, NN, NN, NN, NN, NN, /* A0 - A7 */
300 NN, NN, NN, NN, NN, NN, NN, NN, /* A8 - AF */
301 NN, NN, NN, NN, NN, NN, NN, NN, /* B0 - B7 */
302 NN, NN, NN, NN, NN, NN, NN, NN, /* B8 - BF */
303 NN, NN, NN, NN, NN, NN, NN, NN, /* C0 - C7 */
304 NN, NN, NN, NN, NN, NN, NN, NN, /* C8 - CF */
305 NN, NN, NN, NN, NN, NN, NN, NN, /* D0 - D7 */
306 NN, NN, NN, NN, NN, NN, NN, NN, /* D8 - DF */
307 29, 42, 56, 105, 90, 54, 93, 106, /* E0 - E7 */
308 NN, NN, NN, NN, NN, NN, NN, NN, /* E8 - EF */
309 NN, NN, NN, NN, NN, NN, NN, NN, /* F0 - F7 */
310 NN, NN, NN, NN, NN, NN, NN, NN, /* F8 - FF */
313 static const uint8_t ukbd_boot_desc[] = {
314 0x05, 0x01, 0x09, 0x06, 0xa1,
315 0x01, 0x05, 0x07, 0x19, 0xe0,
316 0x29, 0xe7, 0x15, 0x00, 0x25,
317 0x01, 0x75, 0x01, 0x95, 0x08,
318 0x81, 0x02, 0x95, 0x01, 0x75,
319 0x08, 0x81, 0x01, 0x95, 0x03,
320 0x75, 0x01, 0x05, 0x08, 0x19,
321 0x01, 0x29, 0x03, 0x91, 0x02,
322 0x95, 0x05, 0x75, 0x01, 0x91,
323 0x01, 0x95, 0x06, 0x75, 0x08,
324 0x15, 0x00, 0x26, 0xff, 0x00,
325 0x05, 0x07, 0x19, 0x00, 0x2a,
326 0xff, 0x00, 0x81, 0x00, 0xc0
330 static void ukbd_timeout(void *);
331 static void ukbd_set_leds(struct ukbd_softc *, uint8_t);
332 static int ukbd_set_typematic(keyboard_t *, int);
333 #ifdef UKBD_EMULATE_ATSCANCODE
334 static int ukbd_key2scan(struct ukbd_softc *, int, int, int);
336 static uint32_t ukbd_read_char(keyboard_t *, int);
337 static void ukbd_clear_state(keyboard_t *);
338 static int ukbd_ioctl(keyboard_t *, u_long, caddr_t);
339 static int ukbd_enable(keyboard_t *);
340 static int ukbd_disable(keyboard_t *);
341 static void ukbd_interrupt(struct ukbd_softc *);
342 static int ukbd_is_polling(struct ukbd_softc *);
343 static int ukbd_polls_other_thread(struct ukbd_softc *);
344 static void ukbd_event_keyinput(struct ukbd_softc *);
346 static device_probe_t ukbd_probe;
347 static device_attach_t ukbd_attach;
348 static device_detach_t ukbd_detach;
349 static device_resume_t ukbd_resume;
352 ukbd_any_key_pressed(struct ukbd_softc *sc)
357 for (j = i = 0; i < UKBD_NKEYCODE; i++)
358 j |= sc->sc_odata.keycode[i];
364 ukbd_start_timer(struct ukbd_softc *sc)
366 sc->sc_flags |= UKBD_FLAG_TIMER_RUNNING;
367 usb_callout_reset(&sc->sc_callout, hz / 40, &ukbd_timeout, sc);
371 ukbd_put_key(struct ukbd_softc *sc, uint32_t key)
373 mtx_assert(&Giant, MA_OWNED);
375 DPRINTF("0x%02x (%d) %s\n", key, key,
376 (key & KEY_RELEASE) ? "released" : "pressed");
378 if (sc->sc_inputs < UKBD_IN_BUF_SIZE) {
379 sc->sc_input[sc->sc_inputtail] = key;
381 ++(sc->sc_inputtail);
382 if (sc->sc_inputtail >= UKBD_IN_BUF_SIZE) {
383 sc->sc_inputtail = 0;
386 DPRINTF("input buffer is full\n");
393 struct thread *td = curthread;
400 /* get current priority */
401 old_prio = td->td_base_pri;
403 /* set new priority */
404 sched_prio(td, td->td_user_pri);
406 /* cause a task switch */
407 mi_switch(SW_INVOL | SWT_RELINQUISH, NULL);
409 /* restore priority */
410 sched_prio(td, old_prio);
418 ukbd_do_poll(struct ukbd_softc *sc, uint8_t wait)
420 DPRINTFN(2, "polling\n");
422 /* update stats about last polling event */
423 sc->sc_poll_tick_last = ticks;
424 sc->sc_poll_detected = 1;
426 if (kdb_active == 0) {
427 while (sc->sc_inputs == 0) {
429 /* give USB threads a chance to run */
432 /* check if we should wait */
436 return; /* Only poll if KDB is active */
439 while (sc->sc_inputs == 0) {
441 usbd_transfer_poll(sc->sc_xfer, UKBD_N_TRANSFER);
443 /* Delay-optimised support for repetition of keys */
445 if (ukbd_any_key_pressed(sc)) {
446 /* a key is pressed - need timekeeping */
449 /* 1 millisecond has passed */
461 ukbd_get_key(struct ukbd_softc *sc, uint8_t wait)
465 mtx_assert(&Giant, MA_OWNED);
467 if (sc->sc_inputs == 0) {
468 /* start transfer, if not already started */
469 usbd_transfer_start(sc->sc_xfer[UKBD_INTR_DT]);
472 if (ukbd_polls_other_thread(sc))
475 if (sc->sc_flags & UKBD_FLAG_POLLING)
476 ukbd_do_poll(sc, wait);
478 if (sc->sc_inputs == 0) {
481 c = sc->sc_input[sc->sc_inputhead];
483 ++(sc->sc_inputhead);
484 if (sc->sc_inputhead >= UKBD_IN_BUF_SIZE) {
485 sc->sc_inputhead = 0;
492 ukbd_interrupt(struct ukbd_softc *sc)
496 uint32_t now = sc->sc_time_ms;
502 if (sc->sc_ndata.keycode[0] == KEY_ERROR)
505 n_mod = sc->sc_ndata.modifiers;
506 o_mod = sc->sc_odata.modifiers;
507 if (n_mod != o_mod) {
508 for (i = 0; i < UKBD_NMOD; i++) {
509 if ((n_mod & ukbd_mods[i].mask) !=
510 (o_mod & ukbd_mods[i].mask)) {
511 ukbd_put_key(sc, ukbd_mods[i].key |
512 ((n_mod & ukbd_mods[i].mask) ?
513 KEY_PRESS : KEY_RELEASE));
517 /* Check for released keys. */
518 for (i = 0; i < UKBD_NKEYCODE; i++) {
519 key = sc->sc_odata.keycode[i];
523 for (j = 0; j < UKBD_NKEYCODE; j++) {
524 if (sc->sc_ndata.keycode[j] == 0) {
527 if (key == sc->sc_ndata.keycode[j]) {
531 ukbd_put_key(sc, key | KEY_RELEASE);
535 /* Check for pressed keys. */
536 for (i = 0; i < UKBD_NKEYCODE; i++) {
537 key = sc->sc_ndata.keycode[i];
541 sc->sc_ntime[i] = now + sc->sc_kbd.kb_delay1;
542 for (j = 0; j < UKBD_NKEYCODE; j++) {
543 if (sc->sc_odata.keycode[j] == 0) {
546 if (key == sc->sc_odata.keycode[j]) {
548 /* key is still pressed */
550 sc->sc_ntime[i] = sc->sc_otime[j];
551 dtime = (sc->sc_otime[j] - now);
553 if (!(dtime & 0x80000000)) {
554 /* time has not elapsed */
557 sc->sc_ntime[i] = now + sc->sc_kbd.kb_delay2;
561 ukbd_put_key(sc, key | KEY_PRESS);
564 * If any other key is presently down, force its repeat to be
565 * well in the future (100s). This makes the last key to be
566 * pressed do the autorepeat.
568 for (j = 0; j != UKBD_NKEYCODE; j++) {
570 sc->sc_ntime[j] = now + (100 * 1000);
575 sc->sc_odata = sc->sc_ndata;
577 memcpy(sc->sc_otime, sc->sc_ntime, sizeof(sc->sc_otime));
579 ukbd_event_keyinput(sc);
583 ukbd_event_keyinput(struct ukbd_softc *sc)
587 if (ukbd_is_polling(sc))
590 if (sc->sc_inputs == 0)
593 if (KBD_IS_ACTIVE(&sc->sc_kbd) &&
594 KBD_IS_BUSY(&sc->sc_kbd)) {
595 /* let the callback function process the input */
596 (sc->sc_kbd.kb_callback.kc_func) (&sc->sc_kbd, KBDIO_KEYINPUT,
597 sc->sc_kbd.kb_callback.kc_arg);
599 /* read and discard the input, no one is waiting for it */
601 c = ukbd_read_char(&sc->sc_kbd, 0);
602 } while (c != NOKEY);
607 ukbd_timeout(void *arg)
609 struct ukbd_softc *sc = arg;
611 mtx_assert(&Giant, MA_OWNED);
613 sc->sc_time_ms += 25; /* milliseconds */
617 /* Make sure any leftover key events gets read out */
618 ukbd_event_keyinput(sc);
620 if (ukbd_any_key_pressed(sc) || (sc->sc_inputs != 0)) {
621 ukbd_start_timer(sc);
623 sc->sc_flags &= ~UKBD_FLAG_TIMER_RUNNING;
628 ukbd_apple_fn(uint8_t keycode) {
630 case 0x28: return 0x49; /* RETURN -> INSERT */
631 case 0x2a: return 0x4c; /* BACKSPACE -> DEL */
632 case 0x50: return 0x4a; /* LEFT ARROW -> HOME */
633 case 0x4f: return 0x4d; /* RIGHT ARROW -> END */
634 case 0x52: return 0x4b; /* UP ARROW -> PGUP */
635 case 0x51: return 0x4e; /* DOWN ARROW -> PGDN */
636 default: return keycode;
641 ukbd_apple_swap(uint8_t keycode) {
643 case 0x35: return 0x64;
644 case 0x64: return 0x35;
645 default: return keycode;
650 ukbd_intr_callback(struct usb_xfer *xfer, usb_error_t error)
652 struct ukbd_softc *sc = usbd_xfer_softc(xfer);
653 struct usb_page_cache *pc;
659 usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
660 pc = usbd_xfer_get_frame(xfer, 0);
662 switch (USB_GET_STATE(xfer)) {
663 case USB_ST_TRANSFERRED:
664 DPRINTF("actlen=%d bytes\n", len);
667 DPRINTF("zero length data\n");
671 if (sc->sc_kbd_id != 0) {
672 /* check and remove HID ID byte */
673 usbd_copy_out(pc, 0, &id, 1);
677 DPRINTF("zero length data\n");
685 if (len > UKBD_BUFFER_SIZE)
686 len = UKBD_BUFFER_SIZE;
689 usbd_copy_out(pc, offset, sc->sc_buffer, len);
691 /* clear temporary storage */
692 memset(&sc->sc_ndata, 0, sizeof(sc->sc_ndata));
694 /* scan through HID data */
695 if ((sc->sc_flags & UKBD_FLAG_APPLE_EJECT) &&
696 (id == sc->sc_id_apple_eject)) {
697 if (hid_get_data(sc->sc_buffer, len, &sc->sc_loc_apple_eject))
698 sc->sc_modifiers |= MOD_EJECT;
700 sc->sc_modifiers &= ~MOD_EJECT;
702 if ((sc->sc_flags & UKBD_FLAG_APPLE_FN) &&
703 (id == sc->sc_id_apple_fn)) {
704 if (hid_get_data(sc->sc_buffer, len, &sc->sc_loc_apple_fn))
705 sc->sc_modifiers |= MOD_FN;
707 sc->sc_modifiers &= ~MOD_FN;
709 if ((sc->sc_flags & UKBD_FLAG_CTRL_L) &&
710 (id == sc->sc_id_ctrl_l)) {
711 if (hid_get_data(sc->sc_buffer, len, &sc->sc_loc_ctrl_l))
712 sc-> sc_modifiers |= MOD_CONTROL_L;
714 sc-> sc_modifiers &= ~MOD_CONTROL_L;
716 if ((sc->sc_flags & UKBD_FLAG_CTRL_R) &&
717 (id == sc->sc_id_ctrl_r)) {
718 if (hid_get_data(sc->sc_buffer, len, &sc->sc_loc_ctrl_r))
719 sc->sc_modifiers |= MOD_CONTROL_R;
721 sc->sc_modifiers &= ~MOD_CONTROL_R;
723 if ((sc->sc_flags & UKBD_FLAG_SHIFT_L) &&
724 (id == sc->sc_id_shift_l)) {
725 if (hid_get_data(sc->sc_buffer, len, &sc->sc_loc_shift_l))
726 sc->sc_modifiers |= MOD_SHIFT_L;
728 sc->sc_modifiers &= ~MOD_SHIFT_L;
730 if ((sc->sc_flags & UKBD_FLAG_SHIFT_R) &&
731 (id == sc->sc_id_shift_r)) {
732 if (hid_get_data(sc->sc_buffer, len, &sc->sc_loc_shift_r))
733 sc->sc_modifiers |= MOD_SHIFT_R;
735 sc->sc_modifiers &= ~MOD_SHIFT_R;
737 if ((sc->sc_flags & UKBD_FLAG_ALT_L) &&
738 (id == sc->sc_id_alt_l)) {
739 if (hid_get_data(sc->sc_buffer, len, &sc->sc_loc_alt_l))
740 sc->sc_modifiers |= MOD_ALT_L;
742 sc->sc_modifiers &= ~MOD_ALT_L;
744 if ((sc->sc_flags & UKBD_FLAG_ALT_R) &&
745 (id == sc->sc_id_alt_r)) {
746 if (hid_get_data(sc->sc_buffer, len, &sc->sc_loc_alt_r))
747 sc->sc_modifiers |= MOD_ALT_R;
749 sc->sc_modifiers &= ~MOD_ALT_R;
751 if ((sc->sc_flags & UKBD_FLAG_WIN_L) &&
752 (id == sc->sc_id_win_l)) {
753 if (hid_get_data(sc->sc_buffer, len, &sc->sc_loc_win_l))
754 sc->sc_modifiers |= MOD_WIN_L;
756 sc->sc_modifiers &= ~MOD_WIN_L;
758 if ((sc->sc_flags & UKBD_FLAG_WIN_R) &&
759 (id == sc->sc_id_win_r)) {
760 if (hid_get_data(sc->sc_buffer, len, &sc->sc_loc_win_r))
761 sc->sc_modifiers |= MOD_WIN_R;
763 sc->sc_modifiers &= ~MOD_WIN_R;
766 sc->sc_ndata.modifiers = sc->sc_modifiers;
768 if ((sc->sc_flags & UKBD_FLAG_EVENTS) &&
769 (id == sc->sc_id_events)) {
770 i = sc->sc_loc_events.count;
771 if (i > UKBD_NKEYCODE)
776 sc->sc_ndata.keycode[i] =
777 hid_get_data(sc->sc_buffer + i, len - i,
783 DPRINTF("modifiers = 0x%04x\n", (int)sc->sc_modifiers);
784 for (i = 0; i < UKBD_NKEYCODE; i++) {
785 if (sc->sc_ndata.keycode[i]) {
786 DPRINTF("[%d] = 0x%02x\n",
787 (int)i, (int)sc->sc_ndata.keycode[i]);
791 if (sc->sc_modifiers & MOD_FN) {
792 for (i = 0; i < UKBD_NKEYCODE; i++) {
793 sc->sc_ndata.keycode[i] =
794 ukbd_apple_fn(sc->sc_ndata.keycode[i]);
798 if (sc->sc_flags & UKBD_FLAG_APPLE_SWAP) {
799 for (i = 0; i < UKBD_NKEYCODE; i++) {
800 sc->sc_ndata.keycode[i] =
801 ukbd_apple_swap(sc->sc_ndata.keycode[i]);
807 if (!(sc->sc_flags & UKBD_FLAG_TIMER_RUNNING)) {
808 if (ukbd_any_key_pressed(sc)) {
809 ukbd_start_timer(sc);
815 if (sc->sc_inputs < UKBD_IN_BUF_FULL) {
816 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
817 usbd_transfer_submit(xfer);
819 DPRINTF("input queue is full!\n");
824 DPRINTF("error=%s\n", usbd_errstr(error));
826 if (error != USB_ERR_CANCELLED) {
827 /* try to clear stall first */
828 usbd_xfer_set_stall(xfer);
836 ukbd_set_leds_callback(struct usb_xfer *xfer, usb_error_t error)
838 struct ukbd_softc *sc = usbd_xfer_softc(xfer);
839 struct usb_device_request req;
840 struct usb_page_cache *pc;
850 switch (USB_GET_STATE(xfer)) {
851 case USB_ST_TRANSFERRED:
853 if (!(sc->sc_flags & UKBD_FLAG_SET_LEDS))
855 sc->sc_flags &= ~UKBD_FLAG_SET_LEDS;
857 req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
858 req.bRequest = UR_SET_REPORT;
859 USETW2(req.wValue, UHID_OUTPUT_REPORT, 0);
860 req.wIndex[0] = sc->sc_iface_no;
864 memset(sc->sc_buffer, 0, UKBD_BUFFER_SIZE);
869 /* Assumption: All led bits must be in the same ID. */
871 if (sc->sc_flags & UKBD_FLAG_NUMLOCK) {
872 if (sc->sc_leds & NLKED) {
873 hid_put_data_unsigned(sc->sc_buffer + 1, UKBD_BUFFER_SIZE - 1,
874 &sc->sc_loc_numlock, 1);
876 id = sc->sc_id_numlock;
880 if (sc->sc_flags & UKBD_FLAG_SCROLLLOCK) {
881 if (sc->sc_leds & SLKED) {
882 hid_put_data_unsigned(sc->sc_buffer + 1, UKBD_BUFFER_SIZE - 1,
883 &sc->sc_loc_scrolllock, 1);
885 id = sc->sc_id_scrolllock;
889 if (sc->sc_flags & UKBD_FLAG_CAPSLOCK) {
890 if (sc->sc_leds & CLKED) {
891 hid_put_data_unsigned(sc->sc_buffer + 1, UKBD_BUFFER_SIZE - 1,
892 &sc->sc_loc_capslock, 1);
894 id = sc->sc_id_capslock;
898 /* if no leds, nothing to do */
902 /* range check output report length */
903 len = sc->sc_led_size;
904 if (len > (UKBD_BUFFER_SIZE - 1))
905 len = (UKBD_BUFFER_SIZE - 1);
907 /* check if we need to prefix an ID byte */
908 sc->sc_buffer[0] = id;
910 pc = usbd_xfer_get_frame(xfer, 1);
913 usbd_copy_in(pc, 0, sc->sc_buffer, len);
915 usbd_copy_in(pc, 0, sc->sc_buffer + 1, len);
917 req.wLength[0] = len;
918 usbd_xfer_set_frame_len(xfer, 1, len);
920 DPRINTF("len=%d, id=%d\n", len, id);
922 /* setup control request last */
923 pc = usbd_xfer_get_frame(xfer, 0);
924 usbd_copy_in(pc, 0, &req, sizeof(req));
925 usbd_xfer_set_frame_len(xfer, 0, sizeof(req));
927 /* start data transfer */
928 usbd_xfer_set_frames(xfer, 2);
929 usbd_transfer_submit(xfer);
933 DPRINTFN(1, "error=%s\n", usbd_errstr(error));
938 static const struct usb_config ukbd_config[UKBD_N_TRANSFER] = {
941 .type = UE_INTERRUPT,
942 .endpoint = UE_ADDR_ANY,
943 .direction = UE_DIR_IN,
944 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
945 .bufsize = 0, /* use wMaxPacketSize */
946 .callback = &ukbd_intr_callback,
951 .endpoint = 0x00, /* Control pipe */
952 .direction = UE_DIR_ANY,
953 .bufsize = sizeof(struct usb_device_request) + UKBD_BUFFER_SIZE,
954 .callback = &ukbd_set_leds_callback,
955 .timeout = 1000, /* 1 second */
959 /* A match on these entries will load ukbd */
960 static const STRUCT_USB_HOST_ID __used ukbd_devs[] = {
961 {USB_IFACE_CLASS(UICLASS_HID),
962 USB_IFACE_SUBCLASS(UISUBCLASS_BOOT),
963 USB_IFACE_PROTOCOL(UIPROTO_BOOT_KEYBOARD),},
967 ukbd_probe(device_t dev)
969 keyboard_switch_t *sw = kbd_get_switch(UKBD_DRIVER_NAME);
970 struct usb_attach_arg *uaa = device_get_ivars(dev);
980 if (uaa->usb_mode != USB_MODE_HOST) {
984 if (uaa->info.bInterfaceClass != UICLASS_HID)
987 if ((uaa->info.bInterfaceSubClass == UISUBCLASS_BOOT) &&
988 (uaa->info.bInterfaceProtocol == UIPROTO_BOOT_KEYBOARD)) {
989 if (usb_test_quirk(uaa, UQ_KBD_IGNORE))
992 return (BUS_PROBE_DEFAULT);
995 error = usbd_req_get_hid_desc(uaa->device, NULL,
996 &d_ptr, &d_len, M_TEMP, uaa->info.bIfaceIndex);
1002 * NOTE: we currently don't support USB mouse and USB keyboard
1003 * on the same USB endpoint.
1005 if (hid_is_collection(d_ptr, d_len,
1006 HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE))) {
1007 /* most likely a mouse */
1009 } else if (hid_is_collection(d_ptr, d_len,
1010 HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_KEYBOARD))) {
1011 if (usb_test_quirk(uaa, UQ_KBD_IGNORE))
1014 error = BUS_PROBE_DEFAULT;
1018 free(d_ptr, M_TEMP);
1023 ukbd_parse_hid(struct ukbd_softc *sc, const uint8_t *ptr, uint32_t len)
1027 /* reset detected bits */
1028 sc->sc_flags &= ~UKBD_FLAG_HID_MASK;
1030 /* check if there is an ID byte */
1031 sc->sc_kbd_size = hid_report_size(ptr, len,
1032 hid_input, &sc->sc_kbd_id);
1034 /* investigate if this is an Apple Keyboard */
1035 if (hid_locate(ptr, len,
1036 HID_USAGE2(HUP_CONSUMER, HUG_APPLE_EJECT),
1037 hid_input, 0, &sc->sc_loc_apple_eject, &flags,
1038 &sc->sc_id_apple_eject)) {
1039 if (flags & HIO_VARIABLE)
1040 sc->sc_flags |= UKBD_FLAG_APPLE_EJECT |
1041 UKBD_FLAG_APPLE_SWAP;
1042 DPRINTFN(1, "Found Apple eject-key\n");
1044 if (hid_locate(ptr, len,
1045 HID_USAGE2(0xFFFF, 0x0003),
1046 hid_input, 0, &sc->sc_loc_apple_fn, &flags,
1047 &sc->sc_id_apple_fn)) {
1048 if (flags & HIO_VARIABLE)
1049 sc->sc_flags |= UKBD_FLAG_APPLE_FN;
1050 DPRINTFN(1, "Found Apple FN-key\n");
1052 /* figure out some keys */
1053 if (hid_locate(ptr, len,
1054 HID_USAGE2(HUP_KEYBOARD, 0xE0),
1055 hid_input, 0, &sc->sc_loc_ctrl_l, &flags,
1056 &sc->sc_id_ctrl_l)) {
1057 if (flags & HIO_VARIABLE)
1058 sc->sc_flags |= UKBD_FLAG_CTRL_L;
1059 DPRINTFN(1, "Found left control\n");
1061 if (hid_locate(ptr, len,
1062 HID_USAGE2(HUP_KEYBOARD, 0xE4),
1063 hid_input, 0, &sc->sc_loc_ctrl_r, &flags,
1064 &sc->sc_id_ctrl_r)) {
1065 if (flags & HIO_VARIABLE)
1066 sc->sc_flags |= UKBD_FLAG_CTRL_R;
1067 DPRINTFN(1, "Found right control\n");
1069 if (hid_locate(ptr, len,
1070 HID_USAGE2(HUP_KEYBOARD, 0xE1),
1071 hid_input, 0, &sc->sc_loc_shift_l, &flags,
1072 &sc->sc_id_shift_l)) {
1073 if (flags & HIO_VARIABLE)
1074 sc->sc_flags |= UKBD_FLAG_SHIFT_L;
1075 DPRINTFN(1, "Found left shift\n");
1077 if (hid_locate(ptr, len,
1078 HID_USAGE2(HUP_KEYBOARD, 0xE5),
1079 hid_input, 0, &sc->sc_loc_shift_r, &flags,
1080 &sc->sc_id_shift_r)) {
1081 if (flags & HIO_VARIABLE)
1082 sc->sc_flags |= UKBD_FLAG_SHIFT_R;
1083 DPRINTFN(1, "Found right shift\n");
1085 if (hid_locate(ptr, len,
1086 HID_USAGE2(HUP_KEYBOARD, 0xE2),
1087 hid_input, 0, &sc->sc_loc_alt_l, &flags,
1088 &sc->sc_id_alt_l)) {
1089 if (flags & HIO_VARIABLE)
1090 sc->sc_flags |= UKBD_FLAG_ALT_L;
1091 DPRINTFN(1, "Found left alt\n");
1093 if (hid_locate(ptr, len,
1094 HID_USAGE2(HUP_KEYBOARD, 0xE6),
1095 hid_input, 0, &sc->sc_loc_alt_r, &flags,
1096 &sc->sc_id_alt_r)) {
1097 if (flags & HIO_VARIABLE)
1098 sc->sc_flags |= UKBD_FLAG_ALT_R;
1099 DPRINTFN(1, "Found right alt\n");
1101 if (hid_locate(ptr, len,
1102 HID_USAGE2(HUP_KEYBOARD, 0xE3),
1103 hid_input, 0, &sc->sc_loc_win_l, &flags,
1104 &sc->sc_id_win_l)) {
1105 if (flags & HIO_VARIABLE)
1106 sc->sc_flags |= UKBD_FLAG_WIN_L;
1107 DPRINTFN(1, "Found left GUI\n");
1109 if (hid_locate(ptr, len,
1110 HID_USAGE2(HUP_KEYBOARD, 0xE7),
1111 hid_input, 0, &sc->sc_loc_win_r, &flags,
1112 &sc->sc_id_win_r)) {
1113 if (flags & HIO_VARIABLE)
1114 sc->sc_flags |= UKBD_FLAG_WIN_R;
1115 DPRINTFN(1, "Found right GUI\n");
1117 /* figure out event buffer */
1118 if (hid_locate(ptr, len,
1119 HID_USAGE2(HUP_KEYBOARD, 0x00),
1120 hid_input, 0, &sc->sc_loc_events, &flags,
1121 &sc->sc_id_events)) {
1122 sc->sc_flags |= UKBD_FLAG_EVENTS;
1123 DPRINTFN(1, "Found keyboard events\n");
1126 /* figure out leds on keyboard */
1127 sc->sc_led_size = hid_report_size(ptr, len,
1130 if (hid_locate(ptr, len,
1131 HID_USAGE2(HUP_LEDS, 0x01),
1132 hid_output, 0, &sc->sc_loc_numlock, &flags,
1133 &sc->sc_id_numlock)) {
1134 if (flags & HIO_VARIABLE)
1135 sc->sc_flags |= UKBD_FLAG_NUMLOCK;
1136 DPRINTFN(1, "Found keyboard numlock\n");
1138 if (hid_locate(ptr, len,
1139 HID_USAGE2(HUP_LEDS, 0x02),
1140 hid_output, 0, &sc->sc_loc_capslock, &flags,
1141 &sc->sc_id_capslock)) {
1142 if (flags & HIO_VARIABLE)
1143 sc->sc_flags |= UKBD_FLAG_CAPSLOCK;
1144 DPRINTFN(1, "Found keyboard capslock\n");
1146 if (hid_locate(ptr, len,
1147 HID_USAGE2(HUP_LEDS, 0x03),
1148 hid_output, 0, &sc->sc_loc_scrolllock, &flags,
1149 &sc->sc_id_scrolllock)) {
1150 if (flags & HIO_VARIABLE)
1151 sc->sc_flags |= UKBD_FLAG_SCROLLLOCK;
1152 DPRINTFN(1, "Found keyboard scrolllock\n");
1157 ukbd_attach(device_t dev)
1159 struct ukbd_softc *sc = device_get_softc(dev);
1160 struct usb_attach_arg *uaa = device_get_ivars(dev);
1161 int32_t unit = device_get_unit(dev);
1162 keyboard_t *kbd = &sc->sc_kbd;
1163 void *hid_ptr = NULL;
1168 kbd_init_struct(kbd, UKBD_DRIVER_NAME, KB_OTHER, unit, 0, 0, 0);
1170 kbd->kb_data = (void *)sc;
1172 device_set_usb_desc(dev);
1174 sc->sc_udev = uaa->device;
1175 sc->sc_iface = uaa->iface;
1176 sc->sc_iface_index = uaa->info.bIfaceIndex;
1177 sc->sc_iface_no = uaa->info.bIfaceNum;
1178 sc->sc_mode = K_XLATE;
1180 usb_callout_init_mtx(&sc->sc_callout, &Giant, 0);
1182 err = usbd_transfer_setup(uaa->device,
1183 &uaa->info.bIfaceIndex, sc->sc_xfer, ukbd_config,
1184 UKBD_N_TRANSFER, sc, &Giant);
1187 DPRINTF("error=%s\n", usbd_errstr(err));
1190 /* setup default keyboard maps */
1192 sc->sc_keymap = key_map;
1193 sc->sc_accmap = accent_map;
1194 for (n = 0; n < UKBD_NFKEY; n++) {
1195 sc->sc_fkeymap[n] = fkey_tab[n];
1198 kbd_set_maps(kbd, &sc->sc_keymap, &sc->sc_accmap,
1199 sc->sc_fkeymap, UKBD_NFKEY);
1201 KBD_FOUND_DEVICE(kbd);
1203 ukbd_clear_state(kbd);
1206 * FIXME: set the initial value for lock keys in "sc_state"
1207 * according to the BIOS data?
1209 KBD_PROBE_DONE(kbd);
1211 /* get HID descriptor */
1212 err = usbd_req_get_hid_desc(uaa->device, NULL, &hid_ptr,
1213 &hid_len, M_TEMP, uaa->info.bIfaceIndex);
1216 DPRINTF("Parsing HID descriptor of %d bytes\n",
1219 ukbd_parse_hid(sc, hid_ptr, hid_len);
1221 free(hid_ptr, M_TEMP);
1224 /* check if we should use the boot protocol */
1225 if (usb_test_quirk(uaa, UQ_KBD_BOOTPROTO) ||
1226 (err != 0) || (!(sc->sc_flags & UKBD_FLAG_EVENTS))) {
1228 DPRINTF("Forcing boot protocol\n");
1230 err = usbd_req_set_protocol(sc->sc_udev, NULL,
1231 sc->sc_iface_index, 0);
1234 DPRINTF("Set protocol error=%s (ignored)\n",
1238 ukbd_parse_hid(sc, ukbd_boot_desc, sizeof(ukbd_boot_desc));
1241 /* ignore if SETIDLE fails, hence it is not crucial */
1242 usbd_req_set_idle(sc->sc_udev, NULL, sc->sc_iface_index, 0, 0);
1246 ukbd_ioctl(kbd, KDSETLED, (caddr_t)&sc->sc_state);
1252 if (kbd_register(kbd) < 0) {
1255 KBD_CONFIG_DONE(kbd);
1259 #ifdef KBD_INSTALL_CDEV
1260 if (kbd_attach(kbd)) {
1264 sc->sc_flags |= UKBD_FLAG_ATTACHED;
1267 genkbd_diag(kbd, bootverbose);
1269 /* lock keyboard mutex */
1273 /* start the keyboard */
1275 usbd_transfer_start(sc->sc_xfer[UKBD_INTR_DT]);
1278 return (0); /* success */
1282 return (ENXIO); /* error */
1286 ukbd_detach(device_t dev)
1288 struct ukbd_softc *sc = device_get_softc(dev);
1295 sc->sc_flags |= UKBD_FLAG_GONE;
1297 usb_callout_stop(&sc->sc_callout);
1299 ukbd_disable(&sc->sc_kbd);
1301 #ifdef KBD_INSTALL_CDEV
1302 if (sc->sc_flags & UKBD_FLAG_ATTACHED) {
1303 error = kbd_detach(&sc->sc_kbd);
1305 /* usb attach cannot return an error */
1306 device_printf(dev, "WARNING: kbd_detach() "
1307 "returned non-zero! (ignored)\n");
1311 if (KBD_IS_CONFIGURED(&sc->sc_kbd)) {
1312 error = kbd_unregister(&sc->sc_kbd);
1314 /* usb attach cannot return an error */
1315 device_printf(dev, "WARNING: kbd_unregister() "
1316 "returned non-zero! (ignored)\n");
1319 sc->sc_kbd.kb_flags = 0;
1323 usbd_transfer_unsetup(sc->sc_xfer, UKBD_N_TRANSFER);
1325 usb_callout_drain(&sc->sc_callout);
1327 DPRINTF("%s: disconnected\n",
1328 device_get_nameunit(dev));
1334 ukbd_resume(device_t dev)
1336 struct ukbd_softc *sc = device_get_softc(dev);
1340 ukbd_clear_state(&sc->sc_kbd);
1347 /* early keyboard probe, not supported */
1349 ukbd_configure(int flags)
1354 /* detect a keyboard, not used */
1356 ukbd__probe(int unit, void *arg, int flags)
1361 /* reset and initialize the device, not used */
1363 ukbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
1368 /* test the interface to the device, not used */
1370 ukbd_test_if(keyboard_t *kbd)
1375 /* finish using this keyboard, not used */
1377 ukbd_term(keyboard_t *kbd)
1382 /* keyboard interrupt routine, not used */
1384 ukbd_intr(keyboard_t *kbd, void *arg)
1389 /* lock the access to the keyboard, not used */
1391 ukbd_lock(keyboard_t *kbd, int lock)
1397 * Enable the access to the device; until this function is called,
1398 * the client cannot read from the keyboard.
1401 ukbd_enable(keyboard_t *kbd)
1403 if (!mtx_owned(&Giant)) {
1407 retval = ukbd_enable(kbd);
1415 /* disallow the access to the device */
1417 ukbd_disable(keyboard_t *kbd)
1419 if (!mtx_owned(&Giant)) {
1423 retval = ukbd_disable(kbd);
1427 KBD_DEACTIVATE(kbd);
1431 /* check if data is waiting */
1433 ukbd_check(keyboard_t *kbd)
1435 struct ukbd_softc *sc = kbd->kb_data;
1437 if (!KBD_IS_ACTIVE(kbd))
1440 if (sc->sc_flags & UKBD_FLAG_POLLING) {
1441 if (!mtx_owned(&Giant)) {
1445 retval = ukbd_check(kbd);
1450 /* XXX the keyboard layer requires Giant */
1451 if (!mtx_owned(&Giant))
1455 /* check if key belongs to this thread */
1456 if (ukbd_polls_other_thread(sc))
1459 if (sc->sc_flags & UKBD_FLAG_POLLING)
1460 ukbd_do_poll(sc, 0);
1462 #ifdef UKBD_EMULATE_ATSCANCODE
1463 if (sc->sc_buffered_char[0]) {
1467 if (sc->sc_inputs > 0) {
1473 /* check if char is waiting */
1475 ukbd_check_char(keyboard_t *kbd)
1477 struct ukbd_softc *sc = kbd->kb_data;
1479 if (!KBD_IS_ACTIVE(kbd))
1482 if (sc->sc_flags & UKBD_FLAG_POLLING) {
1483 if (!mtx_owned(&Giant)) {
1487 retval = ukbd_check_char(kbd);
1492 /* XXX the keyboard layer requires Giant */
1493 if (!mtx_owned(&Giant))
1497 /* check if key belongs to this thread */
1498 if (ukbd_polls_other_thread(sc))
1501 if ((sc->sc_composed_char > 0) &&
1502 (!(sc->sc_flags & UKBD_FLAG_COMPOSE))) {
1505 return (ukbd_check(kbd));
1509 /* read one byte from the keyboard if it's allowed */
1511 ukbd_read(keyboard_t *kbd, int wait)
1513 struct ukbd_softc *sc = kbd->kb_data;
1516 #ifdef UKBD_EMULATE_ATSCANCODE
1521 if (!KBD_IS_ACTIVE(kbd))
1524 if (sc->sc_flags & UKBD_FLAG_POLLING) {
1525 if (!mtx_owned(&Giant)) {
1529 retval = ukbd_read(kbd, wait);
1534 /* XXX the keyboard layer requires Giant */
1535 if (!mtx_owned(&Giant))
1539 /* check if key belongs to this thread */
1540 if (ukbd_polls_other_thread(sc))
1543 #ifdef UKBD_EMULATE_ATSCANCODE
1544 if (sc->sc_buffered_char[0]) {
1545 scancode = sc->sc_buffered_char[0];
1546 if (scancode & SCAN_PREFIX) {
1547 sc->sc_buffered_char[0] &= ~SCAN_PREFIX;
1548 return ((scancode & SCAN_PREFIX_E0) ? 0xe0 : 0xe1);
1550 sc->sc_buffered_char[0] = sc->sc_buffered_char[1];
1551 sc->sc_buffered_char[1] = 0;
1554 #endif /* UKBD_EMULATE_ATSCANCODE */
1557 usbcode = ukbd_get_key(sc, (wait == FALSE) ? 0 : 1);
1558 if (!KBD_IS_ACTIVE(kbd) || (usbcode == -1))
1563 #ifdef UKBD_EMULATE_ATSCANCODE
1564 keycode = ukbd_trtab[KEY_INDEX(usbcode)];
1565 if (keycode == NN) {
1568 return (ukbd_key2scan(sc, keycode, sc->sc_ndata.modifiers,
1569 (usbcode & KEY_RELEASE)));
1570 #else /* !UKBD_EMULATE_ATSCANCODE */
1572 #endif /* UKBD_EMULATE_ATSCANCODE */
1575 /* read char from the keyboard */
1577 ukbd_read_char(keyboard_t *kbd, int wait)
1579 struct ukbd_softc *sc = kbd->kb_data;
1584 #ifdef UKBD_EMULATE_ATSCANCODE
1589 if (!KBD_IS_ACTIVE(kbd))
1592 if (sc->sc_flags & UKBD_FLAG_POLLING) {
1593 if (!mtx_owned(&Giant)) {
1597 retval = ukbd_read_char(kbd, wait);
1602 /* XXX the keyboard layer requires Giant */
1603 if (!mtx_owned(&Giant))
1607 /* check if key belongs to this thread */
1608 if (ukbd_polls_other_thread(sc))
1613 /* do we have a composed char to return ? */
1615 if ((sc->sc_composed_char > 0) &&
1616 (!(sc->sc_flags & UKBD_FLAG_COMPOSE))) {
1618 action = sc->sc_composed_char;
1619 sc->sc_composed_char = 0;
1621 if (action > 0xFF) {
1626 #ifdef UKBD_EMULATE_ATSCANCODE
1628 /* do we have a pending raw scan code? */
1630 if (sc->sc_mode == K_RAW) {
1631 scancode = sc->sc_buffered_char[0];
1633 if (scancode & SCAN_PREFIX) {
1634 sc->sc_buffered_char[0] = (scancode & ~SCAN_PREFIX);
1635 return ((scancode & SCAN_PREFIX_E0) ? 0xe0 : 0xe1);
1637 sc->sc_buffered_char[0] = sc->sc_buffered_char[1];
1638 sc->sc_buffered_char[1] = 0;
1642 #endif /* UKBD_EMULATE_ATSCANCODE */
1644 /* see if there is something in the keyboard port */
1646 usbcode = ukbd_get_key(sc, (wait == FALSE) ? 0 : 1);
1647 if (usbcode == -1) {
1652 #ifdef UKBD_EMULATE_ATSCANCODE
1653 /* USB key index -> key code -> AT scan code */
1654 keycode = ukbd_trtab[KEY_INDEX(usbcode)];
1655 if (keycode == NN) {
1658 /* return an AT scan code for the K_RAW mode */
1659 if (sc->sc_mode == K_RAW) {
1660 return (ukbd_key2scan(sc, keycode, sc->sc_ndata.modifiers,
1661 (usbcode & KEY_RELEASE)));
1663 #else /* !UKBD_EMULATE_ATSCANCODE */
1665 /* return the byte as is for the K_RAW mode */
1666 if (sc->sc_mode == K_RAW) {
1669 /* USB key index -> key code */
1670 keycode = ukbd_trtab[KEY_INDEX(usbcode)];
1671 if (keycode == NN) {
1674 #endif /* UKBD_EMULATE_ATSCANCODE */
1677 case 0x38: /* left alt (compose key) */
1678 if (usbcode & KEY_RELEASE) {
1679 if (sc->sc_flags & UKBD_FLAG_COMPOSE) {
1680 sc->sc_flags &= ~UKBD_FLAG_COMPOSE;
1682 if (sc->sc_composed_char > 0xFF) {
1683 sc->sc_composed_char = 0;
1687 if (!(sc->sc_flags & UKBD_FLAG_COMPOSE)) {
1688 sc->sc_flags |= UKBD_FLAG_COMPOSE;
1689 sc->sc_composed_char = 0;
1693 /* XXX: I don't like these... */
1694 case 0x5c: /* print screen */
1695 if (sc->sc_flags & ALTS) {
1696 keycode = 0x54; /* sysrq */
1699 case 0x68: /* pause/break */
1700 if (sc->sc_flags & CTLS) {
1701 keycode = 0x6c; /* break */
1706 /* return the key code in the K_CODE mode */
1707 if (usbcode & KEY_RELEASE) {
1708 keycode |= SCAN_RELEASE;
1710 if (sc->sc_mode == K_CODE) {
1713 /* compose a character code */
1714 if (sc->sc_flags & UKBD_FLAG_COMPOSE) {
1716 /* key pressed, process it */
1719 case 0x49: /* keypad 7,8,9 */
1720 sc->sc_composed_char *= 10;
1721 sc->sc_composed_char += keycode - 0x40;
1722 goto check_composed;
1726 case 0x4D: /* keypad 4,5,6 */
1727 sc->sc_composed_char *= 10;
1728 sc->sc_composed_char += keycode - 0x47;
1729 goto check_composed;
1733 case 0x51: /* keypad 1,2,3 */
1734 sc->sc_composed_char *= 10;
1735 sc->sc_composed_char += keycode - 0x4E;
1736 goto check_composed;
1738 case 0x52: /* keypad 0 */
1739 sc->sc_composed_char *= 10;
1740 goto check_composed;
1742 /* key released, no interest here */
1743 case SCAN_RELEASE | 0x47:
1744 case SCAN_RELEASE | 0x48:
1745 case SCAN_RELEASE | 0x49: /* keypad 7,8,9 */
1746 case SCAN_RELEASE | 0x4B:
1747 case SCAN_RELEASE | 0x4C:
1748 case SCAN_RELEASE | 0x4D: /* keypad 4,5,6 */
1749 case SCAN_RELEASE | 0x4F:
1750 case SCAN_RELEASE | 0x50:
1751 case SCAN_RELEASE | 0x51: /* keypad 1,2,3 */
1752 case SCAN_RELEASE | 0x52: /* keypad 0 */
1755 case 0x38: /* left alt key */
1759 if (sc->sc_composed_char > 0) {
1760 sc->sc_flags &= ~UKBD_FLAG_COMPOSE;
1761 sc->sc_composed_char = 0;
1767 /* keycode to key action */
1768 action = genkbd_keyaction(kbd, SCAN_CHAR(keycode),
1769 (keycode & SCAN_RELEASE),
1770 &sc->sc_state, &sc->sc_accents);
1771 if (action == NOKEY) {
1778 if (sc->sc_composed_char <= 0xFF) {
1785 /* some useful control functions */
1787 ukbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
1789 struct ukbd_softc *sc = kbd->kb_data;
1792 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
1793 defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
1797 if (!mtx_owned(&Giant)) {
1799 * XXX big problem: If scroll lock is pressed and "printf()"
1800 * is called, the CPU will get here, to un-scroll lock the
1801 * keyboard. But if "printf()" acquires the "Giant" lock,
1802 * there will be a locking order reversal problem, so the
1803 * keyboard system must get out of "Giant" first, before the
1804 * CPU can proceed here ...
1809 /* workaround for Geli */
1811 i = ukbd_ioctl(kbd, cmd, arg);
1820 case KDGKBMODE: /* get keyboard mode */
1821 *(int *)arg = sc->sc_mode;
1823 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
1824 defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
1826 ival = IOCPARM_IVAL(arg);
1827 arg = (caddr_t)&ival;
1830 case KDSKBMODE: /* set keyboard mode */
1831 switch (*(int *)arg) {
1833 if (sc->sc_mode != K_XLATE) {
1834 /* make lock key state and LED state match */
1835 sc->sc_state &= ~LOCK_MASK;
1836 sc->sc_state |= KBD_LED_VAL(kbd);
1841 if (sc->sc_mode != *(int *)arg) {
1842 if (ukbd_is_polling(sc) == 0)
1843 ukbd_clear_state(kbd);
1844 sc->sc_mode = *(int *)arg;
1852 case KDGETLED: /* get keyboard LED */
1853 *(int *)arg = KBD_LED_VAL(kbd);
1855 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
1856 defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
1858 ival = IOCPARM_IVAL(arg);
1859 arg = (caddr_t)&ival;
1862 case KDSETLED: /* set keyboard LED */
1863 /* NOTE: lock key state in "sc_state" won't be changed */
1864 if (*(int *)arg & ~LOCK_MASK)
1869 /* replace CAPS LED with ALTGR LED for ALTGR keyboards */
1870 if (sc->sc_mode == K_XLATE &&
1871 kbd->kb_keymap->n_keys > ALTGR_OFFSET) {
1877 if (KBD_HAS_DEVICE(kbd))
1878 ukbd_set_leds(sc, i);
1880 KBD_LED_VAL(kbd) = *(int *)arg;
1882 case KDGKBSTATE: /* get lock key state */
1883 *(int *)arg = sc->sc_state & LOCK_MASK;
1885 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
1886 defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
1888 ival = IOCPARM_IVAL(arg);
1889 arg = (caddr_t)&ival;
1892 case KDSKBSTATE: /* set lock key state */
1893 if (*(int *)arg & ~LOCK_MASK) {
1896 sc->sc_state &= ~LOCK_MASK;
1897 sc->sc_state |= *(int *)arg;
1899 /* set LEDs and quit */
1900 return (ukbd_ioctl(kbd, KDSETLED, arg));
1902 case KDSETREPEAT: /* set keyboard repeat rate (new
1904 if (!KBD_HAS_DEVICE(kbd)) {
1907 if (((int *)arg)[1] < 0) {
1910 if (((int *)arg)[0] < 0) {
1913 if (((int *)arg)[0] < 200) /* fastest possible value */
1914 kbd->kb_delay1 = 200;
1916 kbd->kb_delay1 = ((int *)arg)[0];
1917 kbd->kb_delay2 = ((int *)arg)[1];
1920 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
1921 defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
1923 ival = IOCPARM_IVAL(arg);
1924 arg = (caddr_t)&ival;
1927 case KDSETRAD: /* set keyboard repeat rate (old
1929 return (ukbd_set_typematic(kbd, *(int *)arg));
1931 case PIO_KEYMAP: /* set keyboard translation table */
1932 case PIO_KEYMAPENT: /* set keyboard translation table
1934 case PIO_DEADKEYMAP: /* set accent key translation table */
1938 return (genkbd_commonioctl(kbd, cmd, arg));
1944 /* clear the internal state of the keyboard */
1946 ukbd_clear_state(keyboard_t *kbd)
1948 struct ukbd_softc *sc = kbd->kb_data;
1950 if (!mtx_owned(&Giant)) {
1953 ukbd_clear_state(kbd);
1958 sc->sc_flags &= ~(UKBD_FLAG_COMPOSE | UKBD_FLAG_POLLING);
1959 sc->sc_state &= LOCK_MASK; /* preserve locking key state */
1961 sc->sc_composed_char = 0;
1962 #ifdef UKBD_EMULATE_ATSCANCODE
1963 sc->sc_buffered_char[0] = 0;
1964 sc->sc_buffered_char[1] = 0;
1966 memset(&sc->sc_ndata, 0, sizeof(sc->sc_ndata));
1967 memset(&sc->sc_odata, 0, sizeof(sc->sc_odata));
1968 memset(&sc->sc_ntime, 0, sizeof(sc->sc_ntime));
1969 memset(&sc->sc_otime, 0, sizeof(sc->sc_otime));
1972 /* save the internal state, not used */
1974 ukbd_get_state(keyboard_t *kbd, void *buf, size_t len)
1976 return (len == 0) ? 1 : -1;
1979 /* set the internal state, not used */
1981 ukbd_set_state(keyboard_t *kbd, void *buf, size_t len)
1987 ukbd_is_polling(struct ukbd_softc *sc)
1991 if (sc->sc_flags & UKBD_FLAG_POLLING)
1992 return (1); /* polling */
1994 delta = ticks - sc->sc_poll_tick_last;
1995 if ((delta < 0) || (delta >= hz)) {
1996 sc->sc_poll_detected = 0;
1997 return (0); /* not polling */
2000 return (sc->sc_poll_detected);
2004 ukbd_polls_other_thread(struct ukbd_softc *sc)
2006 return (ukbd_is_polling(sc) &&
2007 (sc->sc_poll_thread != curthread));
2011 ukbd_poll(keyboard_t *kbd, int on)
2013 struct ukbd_softc *sc = kbd->kb_data;
2015 if (!mtx_owned(&Giant)) {
2019 retval = ukbd_poll(kbd, on);
2025 sc->sc_flags |= UKBD_FLAG_POLLING;
2026 sc->sc_poll_thread = curthread;
2028 sc->sc_flags &= ~UKBD_FLAG_POLLING;
2029 ukbd_start_timer(sc); /* start timer */
2034 /* local functions */
2037 ukbd_set_leds(struct ukbd_softc *sc, uint8_t leds)
2039 DPRINTF("leds=0x%02x\n", leds);
2042 sc->sc_flags |= UKBD_FLAG_SET_LEDS;
2044 /* start transfer, if not already started */
2046 usbd_transfer_start(sc->sc_xfer[UKBD_CTRL_LED]);
2050 ukbd_set_typematic(keyboard_t *kbd, int code)
2052 static const int delays[] = {250, 500, 750, 1000};
2053 static const int rates[] = {34, 38, 42, 46, 50, 55, 59, 63,
2054 68, 76, 84, 92, 100, 110, 118, 126,
2055 136, 152, 168, 184, 200, 220, 236, 252,
2056 272, 304, 336, 368, 400, 440, 472, 504};
2061 kbd->kb_delay1 = delays[(code >> 5) & 3];
2062 kbd->kb_delay2 = rates[code & 0x1f];
2066 #ifdef UKBD_EMULATE_ATSCANCODE
2068 ukbd_key2scan(struct ukbd_softc *sc, int code, int shift, int up)
2070 static const int scan[] = {
2076 0x137 | SCAN_PREFIX_SHIFT, /* PrintScreen */
2086 0x151, /* PageDown */
2089 0x146, /* XXX Pause/Break */
2090 0x15b, /* Win_L(Super_L) */
2091 0x15c, /* Win_R(Super_R) */
2092 0x15d, /* Application(Menu) */
2094 /* SUN TYPE 6 USB KEYBOARD */
2095 0x168, /* Sun Type 6 Help */
2096 0x15e, /* Sun Type 6 Stop */
2098 0x15f, /* Sun Type 6 Again */
2099 0x160, /* Sun Type 6 Props */
2100 0x161, /* Sun Type 6 Undo */
2101 0x162, /* Sun Type 6 Front */
2102 0x163, /* Sun Type 6 Copy */
2103 0x164, /* Sun Type 6 Open */
2104 0x165, /* Sun Type 6 Paste */
2105 0x166, /* Sun Type 6 Find */
2106 0x167, /* Sun Type 6 Cut */
2107 0x125, /* Sun Type 6 Mute */
2109 0x11f, /* Sun Type 6 VolumeDown */
2110 0x11e, /* Sun Type 6 VolumeUp */
2111 0x120, /* Sun Type 6 PowerDown */
2113 /* Japanese 106/109 keyboard */
2114 0x73, /* Keyboard Intl' 1 (backslash / underscore) */
2115 0x70, /* Keyboard Intl' 2 (Katakana / Hiragana) */
2116 0x7d, /* Keyboard Intl' 3 (Yen sign) (Not using in jp106/109) */
2117 0x79, /* Keyboard Intl' 4 (Henkan) */
2118 0x7b, /* Keyboard Intl' 5 (Muhenkan) */
2119 0x5c, /* Keyboard Intl' 6 (Keypad ,) (For PC-9821 layout) */
2122 if ((code >= 89) && (code < (int)(89 + (sizeof(scan) / sizeof(scan[0]))))) {
2123 code = scan[code - 89];
2126 if ((code == 104) && (!(shift & (MOD_CONTROL_L | MOD_CONTROL_R)))) {
2127 code = (0x45 | SCAN_PREFIX_E1 | SCAN_PREFIX_CTL);
2129 if (shift & (MOD_SHIFT_L | MOD_SHIFT_R)) {
2130 code &= ~SCAN_PREFIX_SHIFT;
2132 code |= (up ? SCAN_RELEASE : SCAN_PRESS);
2134 if (code & SCAN_PREFIX) {
2135 if (code & SCAN_PREFIX_CTL) {
2137 sc->sc_buffered_char[0] = (0x1d | (code & SCAN_RELEASE));
2138 sc->sc_buffered_char[1] = (code & ~SCAN_PREFIX);
2139 } else if (code & SCAN_PREFIX_SHIFT) {
2141 sc->sc_buffered_char[0] = (0x2a | (code & SCAN_RELEASE));
2142 sc->sc_buffered_char[1] = (code & ~SCAN_PREFIX_SHIFT);
2144 sc->sc_buffered_char[0] = (code & ~SCAN_PREFIX);
2145 sc->sc_buffered_char[1] = 0;
2147 return ((code & SCAN_PREFIX_E0) ? 0xe0 : 0xe1);
2153 #endif /* UKBD_EMULATE_ATSCANCODE */
2155 static keyboard_switch_t ukbdsw = {
2156 .probe = &ukbd__probe,
2160 .test_if = &ukbd_test_if,
2161 .enable = &ukbd_enable,
2162 .disable = &ukbd_disable,
2164 .check = &ukbd_check,
2165 .read_char = &ukbd_read_char,
2166 .check_char = &ukbd_check_char,
2167 .ioctl = &ukbd_ioctl,
2169 .clear_state = &ukbd_clear_state,
2170 .get_state = &ukbd_get_state,
2171 .set_state = &ukbd_set_state,
2172 .get_fkeystr = &genkbd_get_fkeystr,
2174 .diag = &genkbd_diag,
2177 KEYBOARD_DRIVER(ukbd, ukbdsw, ukbd_configure);
2180 ukbd_driver_load(module_t mod, int what, void *arg)
2184 kbd_add_driver(&ukbd_kbd_driver);
2187 kbd_delete_driver(&ukbd_kbd_driver);
2193 static devclass_t ukbd_devclass;
2195 static device_method_t ukbd_methods[] = {
2196 DEVMETHOD(device_probe, ukbd_probe),
2197 DEVMETHOD(device_attach, ukbd_attach),
2198 DEVMETHOD(device_detach, ukbd_detach),
2199 DEVMETHOD(device_resume, ukbd_resume),
2203 static driver_t ukbd_driver = {
2205 .methods = ukbd_methods,
2206 .size = sizeof(struct ukbd_softc),
2209 DRIVER_MODULE(ukbd, uhub, ukbd_driver, ukbd_devclass, ukbd_driver_load, 0);
2210 MODULE_DEPEND(ukbd, usb, 1, 1, 1);
2211 MODULE_VERSION(ukbd, 1);