usb4bsd: Use NULL for pointers.
[dragonfly.git] / sys / bus / u4b / input / ukbd.c
CommitLineData
12bd3c8b
SW
1/*-
2 * Copyright (c) 1998 The NetBSD Foundation, Inc.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to The NetBSD Foundation
6 * by Lennart Augustsson (lennart@augustsson.net) at
7 * Carlstedt Research & Technology.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 *
30 */
31
32/*
33 * HID spec: http://www.usb.org/developers/devclass_docs/HID1_11.pdf
34 */
35
36#include "opt_compat.h"
37#include "opt_kbd.h"
38#include "opt_ukbd.h"
39
40#include <sys/stdint.h>
12bd3c8b
SW
41#include <sys/param.h>
42#include <sys/queue.h>
43#include <sys/types.h>
44#include <sys/systm.h>
45#include <sys/kernel.h>
46#include <sys/bus.h>
47#include <sys/module.h>
48#include <sys/lock.h>
12bd3c8b
SW
49#include <sys/condvar.h>
50#include <sys/sysctl.h>
12bd3c8b
SW
51#include <sys/unistd.h>
52#include <sys/callout.h>
53#include <sys/malloc.h>
54#include <sys/priv.h>
55#include <sys/proc.h>
56#include <sys/sched.h>
8d7664cb 57#include <sys/thread2.h>
12bd3c8b 58
8d7664cb
SW
59#include <bus/u4b/usb.h>
60#include <bus/u4b/usbdi.h>
61#include <bus/u4b/usbdi_util.h>
62#include <bus/u4b/usbhid.h>
12bd3c8b
SW
63
64#define USB_DEBUG_VAR ukbd_debug
8d7664cb 65#include <bus/u4b/usb_debug.h>
12bd3c8b 66
8d7664cb 67#include <bus/u4b/quirk/usb_quirk.h>
12bd3c8b
SW
68
69#include <sys/ioccom.h>
70#include <sys/filio.h>
71#include <sys/tty.h>
72#include <sys/kbio.h>
73
8d7664cb 74#include <dev/misc/kbd/kbdreg.h>
12bd3c8b
SW
75
76/* the initial key map, accent map and fkey strings */
77#if defined(UKBD_DFLT_KEYMAP) && !defined(KLD_MODULE)
78#define KBD_DFLT_KEYMAP
79#include "ukbdmap.h"
80#endif
81
82/* the following file must be included after "ukbdmap.h" */
8d7664cb 83#include <dev/misc/kbd/kbdtables.h>
12bd3c8b
SW
84
85#ifdef USB_DEBUG
86static int ukbd_debug = 0;
87static int ukbd_no_leds = 0;
88
89static SYSCTL_NODE(_hw_usb, OID_AUTO, ukbd, CTLFLAG_RW, 0, "USB ukbd");
90SYSCTL_INT(_hw_usb_ukbd, OID_AUTO, debug, CTLFLAG_RW,
91 &ukbd_debug, 0, "Debug level");
92SYSCTL_INT(_hw_usb_ukbd, OID_AUTO, no_leds, CTLFLAG_RW,
93 &ukbd_no_leds, 0, "Disables setting of keyboard leds");
94
95TUNABLE_INT("hw.usb.ukbd.debug", &ukbd_debug);
96TUNABLE_INT("hw.usb.ukbd.no_leds", &ukbd_no_leds);
97#endif
98
99#define UKBD_EMULATE_ATSCANCODE 1
100#define UKBD_DRIVER_NAME "ukbd"
101#define UKBD_NMOD 8 /* units */
102#define UKBD_NKEYCODE 6 /* units */
103#define UKBD_IN_BUF_SIZE (2*(UKBD_NMOD + (2*UKBD_NKEYCODE))) /* bytes */
104#define UKBD_IN_BUF_FULL (UKBD_IN_BUF_SIZE / 2) /* bytes */
105#define UKBD_NFKEY (sizeof(fkey_tab)/sizeof(fkey_tab[0])) /* units */
106#define UKBD_BUFFER_SIZE 64 /* bytes */
107
108struct ukbd_data {
109 uint16_t modifiers;
110#define MOD_CONTROL_L 0x01
111#define MOD_CONTROL_R 0x10
112#define MOD_SHIFT_L 0x02
113#define MOD_SHIFT_R 0x20
114#define MOD_ALT_L 0x04
115#define MOD_ALT_R 0x40
116#define MOD_WIN_L 0x08
117#define MOD_WIN_R 0x80
118/* internal */
119#define MOD_EJECT 0x0100
120#define MOD_FN 0x0200
121 uint8_t keycode[UKBD_NKEYCODE];
122};
123
124enum {
125 UKBD_INTR_DT,
126 UKBD_CTRL_LED,
127 UKBD_N_TRANSFER,
128};
129
130struct ukbd_softc {
8d7664cb
SW
131 device_t sc_dev;
132 struct lock sc_lock;
12bd3c8b
SW
133 keyboard_t sc_kbd;
134 keymap_t sc_keymap;
135 accentmap_t sc_accmap;
8d7664cb 136
12bd3c8b
SW
137 fkeytab_t sc_fkeymap[UKBD_NFKEY];
138 struct hid_location sc_loc_apple_eject;
139 struct hid_location sc_loc_apple_fn;
140 struct hid_location sc_loc_ctrl_l;
141 struct hid_location sc_loc_ctrl_r;
142 struct hid_location sc_loc_shift_l;
143 struct hid_location sc_loc_shift_r;
144 struct hid_location sc_loc_alt_l;
145 struct hid_location sc_loc_alt_r;
146 struct hid_location sc_loc_win_l;
147 struct hid_location sc_loc_win_r;
148 struct hid_location sc_loc_events;
149 struct hid_location sc_loc_numlock;
150 struct hid_location sc_loc_capslock;
151 struct hid_location sc_loc_scrolllock;
152 struct usb_callout sc_callout;
153 struct ukbd_data sc_ndata;
154 struct ukbd_data sc_odata;
155
156 struct thread *sc_poll_thread;
157 struct usb_device *sc_udev;
158 struct usb_interface *sc_iface;
159 struct usb_xfer *sc_xfer[UKBD_N_TRANSFER];
160
161 uint32_t sc_ntime[UKBD_NKEYCODE];
162 uint32_t sc_otime[UKBD_NKEYCODE];
163 uint32_t sc_input[UKBD_IN_BUF_SIZE]; /* input buffer */
164 uint32_t sc_time_ms;
165 uint32_t sc_composed_char; /* composed char code, if non-zero */
166#ifdef UKBD_EMULATE_ATSCANCODE
167 uint32_t sc_buffered_char[2];
168#endif
169 uint32_t sc_flags; /* flags */
170#define UKBD_FLAG_COMPOSE 0x00000001
171#define UKBD_FLAG_POLLING 0x00000002
172#define UKBD_FLAG_SET_LEDS 0x00000004
173#define UKBD_FLAG_ATTACHED 0x00000010
174#define UKBD_FLAG_GONE 0x00000020
175
176#define UKBD_FLAG_HID_MASK 0x003fffc0
177#define UKBD_FLAG_APPLE_EJECT 0x00000040
178#define UKBD_FLAG_APPLE_FN 0x00000080
179#define UKBD_FLAG_APPLE_SWAP 0x00000100
180#define UKBD_FLAG_TIMER_RUNNING 0x00000200
181#define UKBD_FLAG_CTRL_L 0x00000400
182#define UKBD_FLAG_CTRL_R 0x00000800
183#define UKBD_FLAG_SHIFT_L 0x00001000
184#define UKBD_FLAG_SHIFT_R 0x00002000
185#define UKBD_FLAG_ALT_L 0x00004000
186#define UKBD_FLAG_ALT_R 0x00008000
187#define UKBD_FLAG_WIN_L 0x00010000
188#define UKBD_FLAG_WIN_R 0x00020000
189#define UKBD_FLAG_EVENTS 0x00040000
190#define UKBD_FLAG_NUMLOCK 0x00080000
191#define UKBD_FLAG_CAPSLOCK 0x00100000
192#define UKBD_FLAG_SCROLLLOCK 0x00200000
193
194 int sc_mode; /* input mode (K_XLATE,K_RAW,K_CODE) */
195 int sc_state; /* shift/lock key state */
196 int sc_accents; /* accent key index (> 0) */
197 int sc_led_size;
198 int sc_kbd_size;
199
200 uint16_t sc_inputs;
201 uint16_t sc_inputhead;
202 uint16_t sc_inputtail;
203 uint16_t sc_modifiers;
204
205 uint8_t sc_leds; /* store for async led requests */
206 uint8_t sc_iface_index;
207 uint8_t sc_iface_no;
208 uint8_t sc_id_apple_eject;
209 uint8_t sc_id_apple_fn;
210 uint8_t sc_id_ctrl_l;
211 uint8_t sc_id_ctrl_r;
212 uint8_t sc_id_shift_l;
213 uint8_t sc_id_shift_r;
214 uint8_t sc_id_alt_l;
215 uint8_t sc_id_alt_r;
216 uint8_t sc_id_win_l;
217 uint8_t sc_id_win_r;
218 uint8_t sc_id_event;
219 uint8_t sc_id_numlock;
220 uint8_t sc_id_capslock;
221 uint8_t sc_id_scrolllock;
222 uint8_t sc_id_events;
223 uint8_t sc_kbd_id;
224
225 uint8_t sc_buffer[UKBD_BUFFER_SIZE];
226};
227
228#define KEY_ERROR 0x01
229
230#define KEY_PRESS 0
231#define KEY_RELEASE 0x400
232#define KEY_INDEX(c) ((c) & 0xFF)
233
234#define SCAN_PRESS 0
235#define SCAN_RELEASE 0x80
236#define SCAN_PREFIX_E0 0x100
237#define SCAN_PREFIX_E1 0x200
238#define SCAN_PREFIX_CTL 0x400
239#define SCAN_PREFIX_SHIFT 0x800
240#define SCAN_PREFIX (SCAN_PREFIX_E0 | SCAN_PREFIX_E1 | \
241 SCAN_PREFIX_CTL | SCAN_PREFIX_SHIFT)
242#define SCAN_CHAR(c) ((c) & 0x7f)
243
8d7664cb
SW
244#define UKBD_LOCK(sc) lockmgr(&(sc)->sc_lock, LK_EXCLUSIVE)
245#define UKBD_UNLOCK(sc) lockmgr(&(sc)->sc_lock, LK_RELEASE)
12bd3c8b
SW
246
247#ifdef INVARIANTS
248
249/*
250 * Assert that the lock is held in all contexts
251 * where the code can be executed.
252 */
8d7664cb 253#define UKBD_LOCK_ASSERT()
12bd3c8b
SW
254
255/*
256 * Assert that the lock is held in the contexts
257 * where it really has to be so.
258 */
8d7664cb 259#define UKBD_CTX_LOCK_ASSERT()
12bd3c8b
SW
260#else
261
262#define UKBD_LOCK_ASSERT() (void)0
263#define UKBD_CTX_LOCK_ASSERT() (void)0
264
265#endif
266
267struct ukbd_mods {
268 uint32_t mask, key;
269};
270
271static const struct ukbd_mods ukbd_mods[UKBD_NMOD] = {
272 {MOD_CONTROL_L, 0xe0},
273 {MOD_CONTROL_R, 0xe4},
274 {MOD_SHIFT_L, 0xe1},
275 {MOD_SHIFT_R, 0xe5},
276 {MOD_ALT_L, 0xe2},
277 {MOD_ALT_R, 0xe6},
278 {MOD_WIN_L, 0xe3},
279 {MOD_WIN_R, 0xe7},
280};
281
282#define NN 0 /* no translation */
283/*
284 * Translate USB keycodes to AT keyboard scancodes.
285 */
286/*
287 * FIXME: Mac USB keyboard generates:
288 * 0x53: keypad NumLock/Clear
289 * 0x66: Power
290 * 0x67: keypad =
291 * 0x68: F13
292 * 0x69: F14
293 * 0x6a: F15
294 */
295static const uint8_t ukbd_trtab[256] = {
296 0, 0, 0, 0, 30, 48, 46, 32, /* 00 - 07 */
297 18, 33, 34, 35, 23, 36, 37, 38, /* 08 - 0F */
298 50, 49, 24, 25, 16, 19, 31, 20, /* 10 - 17 */
299 22, 47, 17, 45, 21, 44, 2, 3, /* 18 - 1F */
300 4, 5, 6, 7, 8, 9, 10, 11, /* 20 - 27 */
301 28, 1, 14, 15, 57, 12, 13, 26, /* 28 - 2F */
302 27, 43, 43, 39, 40, 41, 51, 52, /* 30 - 37 */
303 53, 58, 59, 60, 61, 62, 63, 64, /* 38 - 3F */
304 65, 66, 67, 68, 87, 88, 92, 70, /* 40 - 47 */
305 104, 102, 94, 96, 103, 99, 101, 98, /* 48 - 4F */
306 97, 100, 95, 69, 91, 55, 74, 78,/* 50 - 57 */
307 89, 79, 80, 81, 75, 76, 77, 71, /* 58 - 5F */
308 72, 73, 82, 83, 86, 107, 122, NN, /* 60 - 67 */
309 NN, NN, NN, NN, NN, NN, NN, NN, /* 68 - 6F */
310 NN, NN, NN, NN, 115, 108, 111, 113, /* 70 - 77 */
311 109, 110, 112, 118, 114, 116, 117, 119, /* 78 - 7F */
312 121, 120, NN, NN, NN, NN, NN, 123, /* 80 - 87 */
313 124, 125, 126, 127, 128, NN, NN, NN, /* 88 - 8F */
314 NN, NN, NN, NN, NN, NN, NN, NN, /* 90 - 97 */
315 NN, NN, NN, NN, NN, NN, NN, NN, /* 98 - 9F */
316 NN, NN, NN, NN, NN, NN, NN, NN, /* A0 - A7 */
317 NN, NN, NN, NN, NN, NN, NN, NN, /* A8 - AF */
318 NN, NN, NN, NN, NN, NN, NN, NN, /* B0 - B7 */
319 NN, NN, NN, NN, NN, NN, NN, NN, /* B8 - BF */
320 NN, NN, NN, NN, NN, NN, NN, NN, /* C0 - C7 */
321 NN, NN, NN, NN, NN, NN, NN, NN, /* C8 - CF */
322 NN, NN, NN, NN, NN, NN, NN, NN, /* D0 - D7 */
323 NN, NN, NN, NN, NN, NN, NN, NN, /* D8 - DF */
324 29, 42, 56, 105, 90, 54, 93, 106, /* E0 - E7 */
325 NN, NN, NN, NN, NN, NN, NN, NN, /* E8 - EF */
326 NN, NN, NN, NN, NN, NN, NN, NN, /* F0 - F7 */
327 NN, NN, NN, NN, NN, NN, NN, NN, /* F8 - FF */
328};
329
330static const uint8_t ukbd_boot_desc[] = {
331 0x05, 0x01, 0x09, 0x06, 0xa1,
332 0x01, 0x05, 0x07, 0x19, 0xe0,
333 0x29, 0xe7, 0x15, 0x00, 0x25,
334 0x01, 0x75, 0x01, 0x95, 0x08,
335 0x81, 0x02, 0x95, 0x01, 0x75,
336 0x08, 0x81, 0x01, 0x95, 0x03,
337 0x75, 0x01, 0x05, 0x08, 0x19,
338 0x01, 0x29, 0x03, 0x91, 0x02,
339 0x95, 0x05, 0x75, 0x01, 0x91,
340 0x01, 0x95, 0x06, 0x75, 0x08,
341 0x15, 0x00, 0x26, 0xff, 0x00,
342 0x05, 0x07, 0x19, 0x00, 0x2a,
343 0xff, 0x00, 0x81, 0x00, 0xc0
344};
345
346/* prototypes */
347static void ukbd_timeout(void *);
348static void ukbd_set_leds(struct ukbd_softc *, uint8_t);
349static int ukbd_set_typematic(keyboard_t *, int);
350#ifdef UKBD_EMULATE_ATSCANCODE
351static int ukbd_key2scan(struct ukbd_softc *, int, int, int);
352#endif
353static uint32_t ukbd_read_char(keyboard_t *, int);
354static void ukbd_clear_state(keyboard_t *);
355static int ukbd_ioctl(keyboard_t *, u_long, caddr_t);
356static int ukbd_enable(keyboard_t *);
357static int ukbd_disable(keyboard_t *);
358static void ukbd_interrupt(struct ukbd_softc *);
359static void ukbd_event_keyinput(struct ukbd_softc *);
360
361static device_probe_t ukbd_probe;
362static device_attach_t ukbd_attach;
363static device_detach_t ukbd_detach;
364static device_resume_t ukbd_resume;
365
366static uint8_t
367ukbd_any_key_pressed(struct ukbd_softc *sc)
368{
369 uint8_t i;
370 uint8_t j;
371
372 for (j = i = 0; i < UKBD_NKEYCODE; i++)
373 j |= sc->sc_odata.keycode[i];
374
375 return (j ? 1 : 0);
376}
377
378static void
379ukbd_start_timer(struct ukbd_softc *sc)
380{
381 sc->sc_flags |= UKBD_FLAG_TIMER_RUNNING;
382 usb_callout_reset(&sc->sc_callout, hz / 40, &ukbd_timeout, sc);
383}
384
385static void
386ukbd_put_key(struct ukbd_softc *sc, uint32_t key)
387{
388
389 UKBD_CTX_LOCK_ASSERT();
390
391 DPRINTF("0x%02x (%d) %s\n", key, key,
392 (key & KEY_RELEASE) ? "released" : "pressed");
393
394 if (sc->sc_inputs < UKBD_IN_BUF_SIZE) {
395 sc->sc_input[sc->sc_inputtail] = key;
396 ++(sc->sc_inputs);
397 ++(sc->sc_inputtail);
398 if (sc->sc_inputtail >= UKBD_IN_BUF_SIZE) {
399 sc->sc_inputtail = 0;
400 }
401 } else {
402 DPRINTF("input buffer is full\n");
403 }
404}
405
406static void
407ukbd_do_poll(struct ukbd_softc *sc, uint8_t wait)
408{
409
410 UKBD_CTX_LOCK_ASSERT();
411 KASSERT((sc->sc_flags & UKBD_FLAG_POLLING) != 0,
412 ("ukbd_do_poll called when not polling\n"));
413 DPRINTFN(2, "polling\n");
8d7664cb 414#if 0 /* XXX */
12bd3c8b 415 if (!kdb_active && !SCHEDULER_STOPPED()) {
8d7664cb 416#endif
12bd3c8b
SW
417 /*
418 * In this context the kernel is polling for input,
419 * but the USB subsystem works in normal interrupt-driven
420 * mode, so we just wait on the USB threads to do the job.
421 * Note that we currently hold the Giant, but it's also used
422 * as the transfer mtx, so we must release it while waiting.
423 */
424 while (sc->sc_inputs == 0) {
425 /*
426 * Give USB threads a chance to run. Note that
427 * kern_yield performs DROP_GIANT + PICKUP_GIANT.
428 */
8d7664cb 429 lwkt_yield();
12bd3c8b
SW
430 if (!wait)
431 break;
432 }
433 return;
8d7664cb 434#if 0
12bd3c8b 435 }
8d7664cb 436#endif
12bd3c8b
SW
437
438 while (sc->sc_inputs == 0) {
439
440 usbd_transfer_poll(sc->sc_xfer, UKBD_N_TRANSFER);
441
442 /* Delay-optimised support for repetition of keys */
443 if (ukbd_any_key_pressed(sc)) {
444 /* a key is pressed - need timekeeping */
445 DELAY(1000);
446
447 /* 1 millisecond has passed */
448 sc->sc_time_ms += 1;
449 }
450
451 ukbd_interrupt(sc);
452
453 if (!wait)
454 break;
455 }
456}
457
458static int32_t
459ukbd_get_key(struct ukbd_softc *sc, uint8_t wait)
460{
461 int32_t c;
462
463 UKBD_CTX_LOCK_ASSERT();
8d7664cb 464#if 0
12bd3c8b
SW
465 KASSERT((!kdb_active && !SCHEDULER_STOPPED())
466 || (sc->sc_flags & UKBD_FLAG_POLLING) != 0,
467 ("not polling in kdb or panic\n"));
8d7664cb 468#endif
12bd3c8b
SW
469
470 if (sc->sc_inputs == 0) {
471 /* start transfer, if not already started */
472 usbd_transfer_start(sc->sc_xfer[UKBD_INTR_DT]);
473 }
474
475 if (sc->sc_flags & UKBD_FLAG_POLLING)
476 ukbd_do_poll(sc, wait);
477
478 if (sc->sc_inputs == 0) {
479 c = -1;
480 } else {
481 c = sc->sc_input[sc->sc_inputhead];
482 --(sc->sc_inputs);
483 ++(sc->sc_inputhead);
484 if (sc->sc_inputhead >= UKBD_IN_BUF_SIZE) {
485 sc->sc_inputhead = 0;
486 }
487 }
488 return (c);
489}
490
491static void
492ukbd_interrupt(struct ukbd_softc *sc)
493{
494 uint32_t n_mod;
495 uint32_t o_mod;
496 uint32_t now = sc->sc_time_ms;
497 uint32_t dtime;
498 uint8_t key;
499 uint8_t i;
500 uint8_t j;
501
502 UKBD_CTX_LOCK_ASSERT();
503
504 if (sc->sc_ndata.keycode[0] == KEY_ERROR)
505 return;
506
507 n_mod = sc->sc_ndata.modifiers;
508 o_mod = sc->sc_odata.modifiers;
509 if (n_mod != o_mod) {
510 for (i = 0; i < UKBD_NMOD; i++) {
511 if ((n_mod & ukbd_mods[i].mask) !=
512 (o_mod & ukbd_mods[i].mask)) {
513 ukbd_put_key(sc, ukbd_mods[i].key |
514 ((n_mod & ukbd_mods[i].mask) ?
515 KEY_PRESS : KEY_RELEASE));
516 }
517 }
518 }
519 /* Check for released keys. */
520 for (i = 0; i < UKBD_NKEYCODE; i++) {
521 key = sc->sc_odata.keycode[i];
522 if (key == 0) {
523 continue;
524 }
525 for (j = 0; j < UKBD_NKEYCODE; j++) {
526 if (sc->sc_ndata.keycode[j] == 0) {
527 continue;
528 }
529 if (key == sc->sc_ndata.keycode[j]) {
530 goto rfound;
531 }
532 }
533 ukbd_put_key(sc, key | KEY_RELEASE);
534rfound: ;
535 }
536
537 /* Check for pressed keys. */
538 for (i = 0; i < UKBD_NKEYCODE; i++) {
539 key = sc->sc_ndata.keycode[i];
540 if (key == 0) {
541 continue;
542 }
543 sc->sc_ntime[i] = now + sc->sc_kbd.kb_delay1;
544 for (j = 0; j < UKBD_NKEYCODE; j++) {
545 if (sc->sc_odata.keycode[j] == 0) {
546 continue;
547 }
548 if (key == sc->sc_odata.keycode[j]) {
549
550 /* key is still pressed */
551
552 sc->sc_ntime[i] = sc->sc_otime[j];
553 dtime = (sc->sc_otime[j] - now);
554
555 if (!(dtime & 0x80000000)) {
556 /* time has not elapsed */
557 goto pfound;
558 }
559 sc->sc_ntime[i] = now + sc->sc_kbd.kb_delay2;
560 break;
561 }
562 }
563 ukbd_put_key(sc, key | KEY_PRESS);
564
565 /*
566 * If any other key is presently down, force its repeat to be
567 * well in the future (100s). This makes the last key to be
568 * pressed do the autorepeat.
569 */
570 for (j = 0; j != UKBD_NKEYCODE; j++) {
571 if (j != i)
572 sc->sc_ntime[j] = now + (100 * 1000);
573 }
574pfound: ;
575 }
576
577 sc->sc_odata = sc->sc_ndata;
578
579 memcpy(sc->sc_otime, sc->sc_ntime, sizeof(sc->sc_otime));
580
581 ukbd_event_keyinput(sc);
582}
583
584static void
585ukbd_event_keyinput(struct ukbd_softc *sc)
586{
587 int c;
588
589 UKBD_CTX_LOCK_ASSERT();
590
591 if ((sc->sc_flags & UKBD_FLAG_POLLING) != 0)
592 return;
593
594 if (sc->sc_inputs == 0)
595 return;
596
597 if (KBD_IS_ACTIVE(&sc->sc_kbd) &&
598 KBD_IS_BUSY(&sc->sc_kbd)) {
599 /* let the callback function process the input */
600 (sc->sc_kbd.kb_callback.kc_func) (&sc->sc_kbd, KBDIO_KEYINPUT,
601 sc->sc_kbd.kb_callback.kc_arg);
602 } else {
603 /* read and discard the input, no one is waiting for it */
604 do {
605 c = ukbd_read_char(&sc->sc_kbd, 0);
606 } while (c != NOKEY);
607 }
608}
609
610static void
611ukbd_timeout(void *arg)
612{
613 struct ukbd_softc *sc = arg;
614
615 UKBD_LOCK_ASSERT();
616
617 sc->sc_time_ms += 25; /* milliseconds */
618
619 ukbd_interrupt(sc);
620
621 /* Make sure any leftover key events gets read out */
622 ukbd_event_keyinput(sc);
623
624 if (ukbd_any_key_pressed(sc) || (sc->sc_inputs != 0)) {
625 ukbd_start_timer(sc);
626 } else {
627 sc->sc_flags &= ~UKBD_FLAG_TIMER_RUNNING;
628 }
629}
630
631static uint8_t
632ukbd_apple_fn(uint8_t keycode) {
633 switch (keycode) {
634 case 0x28: return 0x49; /* RETURN -> INSERT */
635 case 0x2a: return 0x4c; /* BACKSPACE -> DEL */
636 case 0x50: return 0x4a; /* LEFT ARROW -> HOME */
637 case 0x4f: return 0x4d; /* RIGHT ARROW -> END */
638 case 0x52: return 0x4b; /* UP ARROW -> PGUP */
639 case 0x51: return 0x4e; /* DOWN ARROW -> PGDN */
640 default: return keycode;
641 }
642}
643
644static uint8_t
645ukbd_apple_swap(uint8_t keycode) {
646 switch (keycode) {
647 case 0x35: return 0x64;
648 case 0x64: return 0x35;
649 default: return keycode;
650 }
651}
652
653static void
654ukbd_intr_callback(struct usb_xfer *xfer, usb_error_t error)
655{
656 struct ukbd_softc *sc = usbd_xfer_softc(xfer);
657 struct usb_page_cache *pc;
658 uint8_t i;
659 uint8_t offset;
660 uint8_t id;
661 int len;
662
663 UKBD_LOCK_ASSERT();
664
665 usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
666 pc = usbd_xfer_get_frame(xfer, 0);
667
668 switch (USB_GET_STATE(xfer)) {
669 case USB_ST_TRANSFERRED:
670 DPRINTF("actlen=%d bytes\n", len);
671
672 if (len == 0) {
673 DPRINTF("zero length data\n");
674 goto tr_setup;
675 }
676
677 if (sc->sc_kbd_id != 0) {
678 /* check and remove HID ID byte */
679 usbd_copy_out(pc, 0, &id, 1);
680 offset = 1;
681 len--;
682 if (len == 0) {
683 DPRINTF("zero length data\n");
684 goto tr_setup;
685 }
686 } else {
687 offset = 0;
688 id = 0;
689 }
690
691 if (len > UKBD_BUFFER_SIZE)
692 len = UKBD_BUFFER_SIZE;
693
694 /* get data */
695 usbd_copy_out(pc, offset, sc->sc_buffer, len);
696
697 /* clear temporary storage */
698 memset(&sc->sc_ndata, 0, sizeof(sc->sc_ndata));
699
700 /* scan through HID data */
701 if ((sc->sc_flags & UKBD_FLAG_APPLE_EJECT) &&
702 (id == sc->sc_id_apple_eject)) {
703 if (hid_get_data(sc->sc_buffer, len, &sc->sc_loc_apple_eject))
704 sc->sc_modifiers |= MOD_EJECT;
705 else
706 sc->sc_modifiers &= ~MOD_EJECT;
707 }
708 if ((sc->sc_flags & UKBD_FLAG_APPLE_FN) &&
709 (id == sc->sc_id_apple_fn)) {
710 if (hid_get_data(sc->sc_buffer, len, &sc->sc_loc_apple_fn))
711 sc->sc_modifiers |= MOD_FN;
712 else
713 sc->sc_modifiers &= ~MOD_FN;
714 }
715 if ((sc->sc_flags & UKBD_FLAG_CTRL_L) &&
716 (id == sc->sc_id_ctrl_l)) {
717 if (hid_get_data(sc->sc_buffer, len, &sc->sc_loc_ctrl_l))
718 sc-> sc_modifiers |= MOD_CONTROL_L;
719 else
720 sc-> sc_modifiers &= ~MOD_CONTROL_L;
721 }
722 if ((sc->sc_flags & UKBD_FLAG_CTRL_R) &&
723 (id == sc->sc_id_ctrl_r)) {
724 if (hid_get_data(sc->sc_buffer, len, &sc->sc_loc_ctrl_r))
725 sc->sc_modifiers |= MOD_CONTROL_R;
726 else
727 sc->sc_modifiers &= ~MOD_CONTROL_R;
728 }
729 if ((sc->sc_flags & UKBD_FLAG_SHIFT_L) &&
730 (id == sc->sc_id_shift_l)) {
731 if (hid_get_data(sc->sc_buffer, len, &sc->sc_loc_shift_l))
732 sc->sc_modifiers |= MOD_SHIFT_L;
733 else
734 sc->sc_modifiers &= ~MOD_SHIFT_L;
735 }
736 if ((sc->sc_flags & UKBD_FLAG_SHIFT_R) &&
737 (id == sc->sc_id_shift_r)) {
738 if (hid_get_data(sc->sc_buffer, len, &sc->sc_loc_shift_r))
739 sc->sc_modifiers |= MOD_SHIFT_R;
740 else
741 sc->sc_modifiers &= ~MOD_SHIFT_R;
742 }
743 if ((sc->sc_flags & UKBD_FLAG_ALT_L) &&
744 (id == sc->sc_id_alt_l)) {
745 if (hid_get_data(sc->sc_buffer, len, &sc->sc_loc_alt_l))
746 sc->sc_modifiers |= MOD_ALT_L;
747 else
748 sc->sc_modifiers &= ~MOD_ALT_L;
749 }
750 if ((sc->sc_flags & UKBD_FLAG_ALT_R) &&
751 (id == sc->sc_id_alt_r)) {
752 if (hid_get_data(sc->sc_buffer, len, &sc->sc_loc_alt_r))
753 sc->sc_modifiers |= MOD_ALT_R;
754 else
755 sc->sc_modifiers &= ~MOD_ALT_R;
756 }
757 if ((sc->sc_flags & UKBD_FLAG_WIN_L) &&
758 (id == sc->sc_id_win_l)) {
759 if (hid_get_data(sc->sc_buffer, len, &sc->sc_loc_win_l))
760 sc->sc_modifiers |= MOD_WIN_L;
761 else
762 sc->sc_modifiers &= ~MOD_WIN_L;
763 }
764 if ((sc->sc_flags & UKBD_FLAG_WIN_R) &&
765 (id == sc->sc_id_win_r)) {
766 if (hid_get_data(sc->sc_buffer, len, &sc->sc_loc_win_r))
767 sc->sc_modifiers |= MOD_WIN_R;
768 else
769 sc->sc_modifiers &= ~MOD_WIN_R;
770 }
771
772 sc->sc_ndata.modifiers = sc->sc_modifiers;
773
774 if ((sc->sc_flags & UKBD_FLAG_EVENTS) &&
775 (id == sc->sc_id_events)) {
776 i = sc->sc_loc_events.count;
777 if (i > UKBD_NKEYCODE)
778 i = UKBD_NKEYCODE;
779 if (i > len)
780 i = len;
781 while (i--) {
782 sc->sc_ndata.keycode[i] =
783 hid_get_data(sc->sc_buffer + i, len - i,
784 &sc->sc_loc_events);
785 }
786 }
787
788#ifdef USB_DEBUG
789 DPRINTF("modifiers = 0x%04x\n", (int)sc->sc_modifiers);
790 for (i = 0; i < UKBD_NKEYCODE; i++) {
791 if (sc->sc_ndata.keycode[i]) {
792 DPRINTF("[%d] = 0x%02x\n",
793 (int)i, (int)sc->sc_ndata.keycode[i]);
794 }
795 }
796#endif
797 if (sc->sc_modifiers & MOD_FN) {
798 for (i = 0; i < UKBD_NKEYCODE; i++) {
799 sc->sc_ndata.keycode[i] =
800 ukbd_apple_fn(sc->sc_ndata.keycode[i]);
801 }
802 }
803
804 if (sc->sc_flags & UKBD_FLAG_APPLE_SWAP) {
805 for (i = 0; i < UKBD_NKEYCODE; i++) {
806 sc->sc_ndata.keycode[i] =
807 ukbd_apple_swap(sc->sc_ndata.keycode[i]);
808 }
809 }
810
811 ukbd_interrupt(sc);
812
813 if (!(sc->sc_flags & UKBD_FLAG_TIMER_RUNNING)) {
814 if (ukbd_any_key_pressed(sc)) {
815 ukbd_start_timer(sc);
816 }
817 }
818
819 case USB_ST_SETUP:
820tr_setup:
821 if (sc->sc_inputs < UKBD_IN_BUF_FULL) {
822 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
823 usbd_transfer_submit(xfer);
824 } else {
825 DPRINTF("input queue is full!\n");
826 }
827 break;
828
829 default: /* Error */
830 DPRINTF("error=%s\n", usbd_errstr(error));
831
832 if (error != USB_ERR_CANCELLED) {
833 /* try to clear stall first */
834 usbd_xfer_set_stall(xfer);
835 goto tr_setup;
836 }
837 break;
838 }
839}
840
841static void
842ukbd_set_leds_callback(struct usb_xfer *xfer, usb_error_t error)
843{
844 struct ukbd_softc *sc = usbd_xfer_softc(xfer);
845 struct usb_device_request req;
846 struct usb_page_cache *pc;
847 uint8_t id;
848 uint8_t any;
849 int len;
850
851 UKBD_LOCK_ASSERT();
852
853#ifdef USB_DEBUG
854 if (ukbd_no_leds)
855 return;
856#endif
857
858 switch (USB_GET_STATE(xfer)) {
859 case USB_ST_TRANSFERRED:
860 case USB_ST_SETUP:
861 if (!(sc->sc_flags & UKBD_FLAG_SET_LEDS))
862 break;
863 sc->sc_flags &= ~UKBD_FLAG_SET_LEDS;
864
865 req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
866 req.bRequest = UR_SET_REPORT;
867 USETW2(req.wValue, UHID_OUTPUT_REPORT, 0);
868 req.wIndex[0] = sc->sc_iface_no;
869 req.wIndex[1] = 0;
870 req.wLength[1] = 0;
871
872 memset(sc->sc_buffer, 0, UKBD_BUFFER_SIZE);
873
874 id = 0;
875 any = 0;
876
877 /* Assumption: All led bits must be in the same ID. */
878
879 if (sc->sc_flags & UKBD_FLAG_NUMLOCK) {
880 if (sc->sc_leds & NLKED) {
881 hid_put_data_unsigned(sc->sc_buffer + 1, UKBD_BUFFER_SIZE - 1,
882 &sc->sc_loc_numlock, 1);
883 }
884 id = sc->sc_id_numlock;
885 any = 1;
886 }
887
888 if (sc->sc_flags & UKBD_FLAG_SCROLLLOCK) {
889 if (sc->sc_leds & SLKED) {
890 hid_put_data_unsigned(sc->sc_buffer + 1, UKBD_BUFFER_SIZE - 1,
891 &sc->sc_loc_scrolllock, 1);
892 }
893 id = sc->sc_id_scrolllock;
894 any = 1;
895 }
896
897 if (sc->sc_flags & UKBD_FLAG_CAPSLOCK) {
898 if (sc->sc_leds & CLKED) {
899 hid_put_data_unsigned(sc->sc_buffer + 1, UKBD_BUFFER_SIZE - 1,
900 &sc->sc_loc_capslock, 1);
901 }
902 id = sc->sc_id_capslock;
903 any = 1;
904 }
905
906 /* if no leds, nothing to do */
907 if (!any)
908 break;
909
910 /* range check output report length */
911 len = sc->sc_led_size;
912 if (len > (UKBD_BUFFER_SIZE - 1))
913 len = (UKBD_BUFFER_SIZE - 1);
914
915 /* check if we need to prefix an ID byte */
916 sc->sc_buffer[0] = id;
917
918 pc = usbd_xfer_get_frame(xfer, 1);
919 if (id != 0) {
920 len++;
921 usbd_copy_in(pc, 0, sc->sc_buffer, len);
922 } else {
923 usbd_copy_in(pc, 0, sc->sc_buffer + 1, len);
924 }
925 req.wLength[0] = len;
926 usbd_xfer_set_frame_len(xfer, 1, len);
927
928 DPRINTF("len=%d, id=%d\n", len, id);
929
930 /* setup control request last */
931 pc = usbd_xfer_get_frame(xfer, 0);
932 usbd_copy_in(pc, 0, &req, sizeof(req));
933 usbd_xfer_set_frame_len(xfer, 0, sizeof(req));
934
935 /* start data transfer */
936 usbd_xfer_set_frames(xfer, 2);
937 usbd_transfer_submit(xfer);
938 break;
939
940 default: /* Error */
941 DPRINTFN(1, "error=%s\n", usbd_errstr(error));
942 break;
943 }
944}
945
946static const struct usb_config ukbd_config[UKBD_N_TRANSFER] = {
947
948 [UKBD_INTR_DT] = {
949 .type = UE_INTERRUPT,
950 .endpoint = UE_ADDR_ANY,
951 .direction = UE_DIR_IN,
952 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
953 .bufsize = 0, /* use wMaxPacketSize */
954 .callback = &ukbd_intr_callback,
955 },
956
957 [UKBD_CTRL_LED] = {
958 .type = UE_CONTROL,
959 .endpoint = 0x00, /* Control pipe */
960 .direction = UE_DIR_ANY,
961 .bufsize = sizeof(struct usb_device_request) + UKBD_BUFFER_SIZE,
962 .callback = &ukbd_set_leds_callback,
963 .timeout = 1000, /* 1 second */
964 },
965};
966
967/* A match on these entries will load ukbd */
968static const STRUCT_USB_HOST_ID __used ukbd_devs[] = {
969 {USB_IFACE_CLASS(UICLASS_HID),
970 USB_IFACE_SUBCLASS(UISUBCLASS_BOOT),
971 USB_IFACE_PROTOCOL(UIPROTO_BOOT_KEYBOARD),},
972};
973
974static int
975ukbd_probe(device_t dev)
976{
977 keyboard_switch_t *sw = kbd_get_switch(UKBD_DRIVER_NAME);
978 struct usb_attach_arg *uaa = device_get_ivars(dev);
979 void *d_ptr;
980 int error;
981 uint16_t d_len;
982
12bd3c8b
SW
983 DPRINTFN(11, "\n");
984
985 if (sw == NULL) {
986 return (ENXIO);
987 }
988 if (uaa->usb_mode != USB_MODE_HOST) {
989 return (ENXIO);
990 }
991
992 if (uaa->info.bInterfaceClass != UICLASS_HID)
993 return (ENXIO);
994
995 if ((uaa->info.bInterfaceSubClass == UISUBCLASS_BOOT) &&
996 (uaa->info.bInterfaceProtocol == UIPROTO_BOOT_KEYBOARD)) {
997 if (usb_test_quirk(uaa, UQ_KBD_IGNORE))
998 return (ENXIO);
999 else
1000 return (BUS_PROBE_DEFAULT);
1001 }
1002
1003 error = usbd_req_get_hid_desc(uaa->device, NULL,
1004 &d_ptr, &d_len, M_TEMP, uaa->info.bIfaceIndex);
1005
1006 if (error)
1007 return (ENXIO);
1008
1009 /*
1010 * NOTE: we currently don't support USB mouse and USB keyboard
1011 * on the same USB endpoint.
1012 */
1013 if (hid_is_collection(d_ptr, d_len,
1014 HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_MOUSE))) {
1015 /* most likely a mouse */
1016 error = ENXIO;
1017 } else if (hid_is_collection(d_ptr, d_len,
1018 HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_KEYBOARD))) {
1019 if (usb_test_quirk(uaa, UQ_KBD_IGNORE))
1020 error = ENXIO;
1021 else
1022 error = BUS_PROBE_DEFAULT;
1023 } else
1024 error = ENXIO;
1025
8d7664cb 1026 kfree(d_ptr, M_TEMP);
12bd3c8b
SW
1027 return (error);
1028}
1029
1030static void
1031ukbd_parse_hid(struct ukbd_softc *sc, const uint8_t *ptr, uint32_t len)
1032{
1033 uint32_t flags;
1034
1035 /* reset detected bits */
1036 sc->sc_flags &= ~UKBD_FLAG_HID_MASK;
1037
1038 /* check if there is an ID byte */
1039 sc->sc_kbd_size = hid_report_size(ptr, len,
1040 hid_input, &sc->sc_kbd_id);
1041
1042 /* investigate if this is an Apple Keyboard */
1043 if (hid_locate(ptr, len,
1044 HID_USAGE2(HUP_CONSUMER, HUG_APPLE_EJECT),
1045 hid_input, 0, &sc->sc_loc_apple_eject, &flags,
1046 &sc->sc_id_apple_eject)) {
1047 if (flags & HIO_VARIABLE)
1048 sc->sc_flags |= UKBD_FLAG_APPLE_EJECT |
1049 UKBD_FLAG_APPLE_SWAP;
1050 DPRINTFN(1, "Found Apple eject-key\n");
1051 }
1052 if (hid_locate(ptr, len,
1053 HID_USAGE2(0xFFFF, 0x0003),
1054 hid_input, 0, &sc->sc_loc_apple_fn, &flags,
1055 &sc->sc_id_apple_fn)) {
1056 if (flags & HIO_VARIABLE)
1057 sc->sc_flags |= UKBD_FLAG_APPLE_FN;
1058 DPRINTFN(1, "Found Apple FN-key\n");
1059 }
1060 /* figure out some keys */
1061 if (hid_locate(ptr, len,
1062 HID_USAGE2(HUP_KEYBOARD, 0xE0),
1063 hid_input, 0, &sc->sc_loc_ctrl_l, &flags,
1064 &sc->sc_id_ctrl_l)) {
1065 if (flags & HIO_VARIABLE)
1066 sc->sc_flags |= UKBD_FLAG_CTRL_L;
1067 DPRINTFN(1, "Found left control\n");
1068 }
1069 if (hid_locate(ptr, len,
1070 HID_USAGE2(HUP_KEYBOARD, 0xE4),
1071 hid_input, 0, &sc->sc_loc_ctrl_r, &flags,
1072 &sc->sc_id_ctrl_r)) {
1073 if (flags & HIO_VARIABLE)
1074 sc->sc_flags |= UKBD_FLAG_CTRL_R;
1075 DPRINTFN(1, "Found right control\n");
1076 }
1077 if (hid_locate(ptr, len,
1078 HID_USAGE2(HUP_KEYBOARD, 0xE1),
1079 hid_input, 0, &sc->sc_loc_shift_l, &flags,
1080 &sc->sc_id_shift_l)) {
1081 if (flags & HIO_VARIABLE)
1082 sc->sc_flags |= UKBD_FLAG_SHIFT_L;
1083 DPRINTFN(1, "Found left shift\n");
1084 }
1085 if (hid_locate(ptr, len,
1086 HID_USAGE2(HUP_KEYBOARD, 0xE5),
1087 hid_input, 0, &sc->sc_loc_shift_r, &flags,
1088 &sc->sc_id_shift_r)) {
1089 if (flags & HIO_VARIABLE)
1090 sc->sc_flags |= UKBD_FLAG_SHIFT_R;
1091 DPRINTFN(1, "Found right shift\n");
1092 }
1093 if (hid_locate(ptr, len,
1094 HID_USAGE2(HUP_KEYBOARD, 0xE2),
1095 hid_input, 0, &sc->sc_loc_alt_l, &flags,
1096 &sc->sc_id_alt_l)) {
1097 if (flags & HIO_VARIABLE)
1098 sc->sc_flags |= UKBD_FLAG_ALT_L;
1099 DPRINTFN(1, "Found left alt\n");
1100 }
1101 if (hid_locate(ptr, len,
1102 HID_USAGE2(HUP_KEYBOARD, 0xE6),
1103 hid_input, 0, &sc->sc_loc_alt_r, &flags,
1104 &sc->sc_id_alt_r)) {
1105 if (flags & HIO_VARIABLE)
1106 sc->sc_flags |= UKBD_FLAG_ALT_R;
1107 DPRINTFN(1, "Found right alt\n");
1108 }
1109 if (hid_locate(ptr, len,
1110 HID_USAGE2(HUP_KEYBOARD, 0xE3),
1111 hid_input, 0, &sc->sc_loc_win_l, &flags,
1112 &sc->sc_id_win_l)) {
1113 if (flags & HIO_VARIABLE)
1114 sc->sc_flags |= UKBD_FLAG_WIN_L;
1115 DPRINTFN(1, "Found left GUI\n");
1116 }
1117 if (hid_locate(ptr, len,
1118 HID_USAGE2(HUP_KEYBOARD, 0xE7),
1119 hid_input, 0, &sc->sc_loc_win_r, &flags,
1120 &sc->sc_id_win_r)) {
1121 if (flags & HIO_VARIABLE)
1122 sc->sc_flags |= UKBD_FLAG_WIN_R;
1123 DPRINTFN(1, "Found right GUI\n");
1124 }
1125 /* figure out event buffer */
1126 if (hid_locate(ptr, len,
1127 HID_USAGE2(HUP_KEYBOARD, 0x00),
1128 hid_input, 0, &sc->sc_loc_events, &flags,
1129 &sc->sc_id_events)) {
1130 sc->sc_flags |= UKBD_FLAG_EVENTS;
1131 DPRINTFN(1, "Found keyboard events\n");
1132 }
1133
1134 /* figure out leds on keyboard */
1135 sc->sc_led_size = hid_report_size(ptr, len,
1136 hid_output, NULL);
1137
1138 if (hid_locate(ptr, len,
1139 HID_USAGE2(HUP_LEDS, 0x01),
1140 hid_output, 0, &sc->sc_loc_numlock, &flags,
1141 &sc->sc_id_numlock)) {
1142 if (flags & HIO_VARIABLE)
1143 sc->sc_flags |= UKBD_FLAG_NUMLOCK;
1144 DPRINTFN(1, "Found keyboard numlock\n");
1145 }
1146 if (hid_locate(ptr, len,
1147 HID_USAGE2(HUP_LEDS, 0x02),
1148 hid_output, 0, &sc->sc_loc_capslock, &flags,
1149 &sc->sc_id_capslock)) {
1150 if (flags & HIO_VARIABLE)
1151 sc->sc_flags |= UKBD_FLAG_CAPSLOCK;
1152 DPRINTFN(1, "Found keyboard capslock\n");
1153 }
1154 if (hid_locate(ptr, len,
1155 HID_USAGE2(HUP_LEDS, 0x03),
1156 hid_output, 0, &sc->sc_loc_scrolllock, &flags,
1157 &sc->sc_id_scrolllock)) {
1158 if (flags & HIO_VARIABLE)
1159 sc->sc_flags |= UKBD_FLAG_SCROLLLOCK;
1160 DPRINTFN(1, "Found keyboard scrolllock\n");
1161 }
1162}
1163
1164static int
1165ukbd_attach(device_t dev)
1166{
1167 struct ukbd_softc *sc = device_get_softc(dev);
1168 struct usb_attach_arg *uaa = device_get_ivars(dev);
1169 int32_t unit = device_get_unit(dev);
1170 keyboard_t *kbd = &sc->sc_kbd;
1171 void *hid_ptr = NULL;
1172 usb_error_t err;
1173 uint16_t n;
1174 uint16_t hid_len;
1175
8d7664cb
SW
1176 lockinit(&sc->sc_lock, "ukbd", 0, 0);
1177 kbd_init_struct(kbd, UKBD_DRIVER_NAME, KB_OTHER,
1178 unit, 0, KB_PRI_USB, 0, 0);
12bd3c8b
SW
1179
1180 kbd->kb_data = (void *)sc;
1181
1182 device_set_usb_desc(dev);
1183
1184 sc->sc_udev = uaa->device;
1185 sc->sc_iface = uaa->iface;
1186 sc->sc_iface_index = uaa->info.bIfaceIndex;
1187 sc->sc_iface_no = uaa->info.bIfaceNum;
1188 sc->sc_mode = K_XLATE;
1189
8d7664cb 1190 usb_callout_init_mtx(&sc->sc_callout, &sc->sc_lock, 0);
12bd3c8b
SW
1191
1192 err = usbd_transfer_setup(uaa->device,
1193 &uaa->info.bIfaceIndex, sc->sc_xfer, ukbd_config,
8d7664cb 1194 UKBD_N_TRANSFER, sc, &sc->sc_lock);
12bd3c8b
SW
1195
1196 if (err) {
1197 DPRINTF("error=%s\n", usbd_errstr(err));
1198 goto detach;
1199 }
1200 /* setup default keyboard maps */
1201
1202 sc->sc_keymap = key_map;
1203 sc->sc_accmap = accent_map;
1204 for (n = 0; n < UKBD_NFKEY; n++) {
1205 sc->sc_fkeymap[n] = fkey_tab[n];
1206 }
1207
1208 kbd_set_maps(kbd, &sc->sc_keymap, &sc->sc_accmap,
1209 sc->sc_fkeymap, UKBD_NFKEY);
1210
1211 KBD_FOUND_DEVICE(kbd);
1212
1213 ukbd_clear_state(kbd);
1214
1215 /*
1216 * FIXME: set the initial value for lock keys in "sc_state"
1217 * according to the BIOS data?
1218 */
1219 KBD_PROBE_DONE(kbd);
1220
1221 /* get HID descriptor */
1222 err = usbd_req_get_hid_desc(uaa->device, NULL, &hid_ptr,
1223 &hid_len, M_TEMP, uaa->info.bIfaceIndex);
1224
1225 if (err == 0) {
1226 DPRINTF("Parsing HID descriptor of %d bytes\n",
1227 (int)hid_len);
1228
1229 ukbd_parse_hid(sc, hid_ptr, hid_len);
1230
8d7664cb 1231 kfree(hid_ptr, M_TEMP);
12bd3c8b
SW
1232 }
1233
1234 /* check if we should use the boot protocol */
1235 if (usb_test_quirk(uaa, UQ_KBD_BOOTPROTO) ||
1236 (err != 0) || (!(sc->sc_flags & UKBD_FLAG_EVENTS))) {
1237
1238 DPRINTF("Forcing boot protocol\n");
1239
1240 err = usbd_req_set_protocol(sc->sc_udev, NULL,
1241 sc->sc_iface_index, 0);
1242
1243 if (err != 0) {
1244 DPRINTF("Set protocol error=%s (ignored)\n",
1245 usbd_errstr(err));
1246 }
1247
1248 ukbd_parse_hid(sc, ukbd_boot_desc, sizeof(ukbd_boot_desc));
1249 }
1250
1251 /* ignore if SETIDLE fails, hence it is not crucial */
1252 usbd_req_set_idle(sc->sc_udev, NULL, sc->sc_iface_index, 0, 0);
1253
1254 ukbd_ioctl(kbd, KDSETLED, (caddr_t)&sc->sc_state);
1255
1256 KBD_INIT_DONE(kbd);
1257
1258 if (kbd_register(kbd) < 0) {
1259 goto detach;
1260 }
1261 KBD_CONFIG_DONE(kbd);
1262
1263 ukbd_enable(kbd);
1264
1265#ifdef KBD_INSTALL_CDEV
1266 if (kbd_attach(kbd)) {
1267 goto detach;
1268 }
1269#endif
1270 sc->sc_flags |= UKBD_FLAG_ATTACHED;
1271
1272 if (bootverbose) {
1273 genkbd_diag(kbd, bootverbose);
1274 }
1275
1276 /* start the keyboard */
8d7664cb 1277 UKBD_LOCK(sc);
12bd3c8b 1278 usbd_transfer_start(sc->sc_xfer[UKBD_INTR_DT]);
8d7664cb 1279 UKBD_UNLOCK(sc);
12bd3c8b
SW
1280
1281 return (0); /* success */
1282
1283detach:
1284 ukbd_detach(dev);
1285 return (ENXIO); /* error */
1286}
1287
1288static int
1289ukbd_detach(device_t dev)
1290{
1291 struct ukbd_softc *sc = device_get_softc(dev);
1292 int error;
1293
12bd3c8b
SW
1294 DPRINTF("\n");
1295
1296 sc->sc_flags |= UKBD_FLAG_GONE;
1297
1298 usb_callout_stop(&sc->sc_callout);
1299
1300 ukbd_disable(&sc->sc_kbd);
1301
1302#ifdef KBD_INSTALL_CDEV
1303 if (sc->sc_flags & UKBD_FLAG_ATTACHED) {
1304 error = kbd_detach(&sc->sc_kbd);
1305 if (error) {
1306 /* usb attach cannot return an error */
1307 device_printf(dev, "WARNING: kbd_detach() "
1308 "returned non-zero! (ignored)\n");
1309 }
1310 }
1311#endif
1312 if (KBD_IS_CONFIGURED(&sc->sc_kbd)) {
1313 error = kbd_unregister(&sc->sc_kbd);
1314 if (error) {
1315 /* usb attach cannot return an error */
1316 device_printf(dev, "WARNING: kbd_unregister() "
1317 "returned non-zero! (ignored)\n");
1318 }
1319 }
1320 sc->sc_kbd.kb_flags = 0;
1321
1322 usbd_transfer_unsetup(sc->sc_xfer, UKBD_N_TRANSFER);
1323
1324 usb_callout_drain(&sc->sc_callout);
1325
1326 DPRINTF("%s: disconnected\n",
1327 device_get_nameunit(dev));
1328
1329 return (0);
1330}
1331
1332static int
1333ukbd_resume(device_t dev)
1334{
1335 struct ukbd_softc *sc = device_get_softc(dev);
1336
12bd3c8b
SW
1337 ukbd_clear_state(&sc->sc_kbd);
1338
1339 return (0);
1340}
1341
1342/* early keyboard probe, not supported */
1343static int
1344ukbd_configure(int flags)
1345{
1346 return (0);
1347}
1348
1349/* detect a keyboard, not used */
1350static int
1351ukbd__probe(int unit, void *arg, int flags)
1352{
1353 return (ENXIO);
1354}
1355
1356/* reset and initialize the device, not used */
1357static int
1358ukbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
1359{
1360 return (ENXIO);
1361}
1362
1363/* test the interface to the device, not used */
1364static int
1365ukbd_test_if(keyboard_t *kbd)
1366{
1367 return (0);
1368}
1369
1370/* finish using this keyboard, not used */
1371static int
1372ukbd_term(keyboard_t *kbd)
1373{
1374 return (ENXIO);
1375}
1376
1377/* keyboard interrupt routine, not used */
1378static int
1379ukbd_intr(keyboard_t *kbd, void *arg)
1380{
1381 return (0);
1382}
1383
1384/* lock the access to the keyboard, not used */
1385static int
1386ukbd_lock(keyboard_t *kbd, int lock)
1387{
1388 return (1);
1389}
1390
1391/*
1392 * Enable the access to the device; until this function is called,
1393 * the client cannot read from the keyboard.
1394 */
1395static int
1396ukbd_enable(keyboard_t *kbd)
1397{
8d7664cb 1398 struct ukbd_softc *sc = kbd->kb_data;
12bd3c8b 1399
8d7664cb 1400 UKBD_LOCK(sc);
12bd3c8b 1401 KBD_ACTIVATE(kbd);
8d7664cb 1402 UKBD_UNLOCK(sc);
12bd3c8b
SW
1403
1404 return (0);
1405}
1406
1407/* disallow the access to the device */
1408static int
1409ukbd_disable(keyboard_t *kbd)
1410{
8d7664cb 1411 struct ukbd_softc *sc = kbd->kb_data;
12bd3c8b 1412
8d7664cb 1413 UKBD_LOCK(sc);
12bd3c8b 1414 KBD_DEACTIVATE(kbd);
8d7664cb 1415 UKBD_UNLOCK(sc);
12bd3c8b
SW
1416
1417 return (0);
1418}
1419
1420/* check if data is waiting */
1421/* Currently unused. */
1422static int
1423ukbd_check(keyboard_t *kbd)
1424{
1425 struct ukbd_softc *sc = kbd->kb_data;
1426
12bd3c8b
SW
1427 if (!KBD_IS_ACTIVE(kbd))
1428 return (0);
1429
1430 if (sc->sc_flags & UKBD_FLAG_POLLING)
1431 ukbd_do_poll(sc, 0);
1432
1433#ifdef UKBD_EMULATE_ATSCANCODE
1434 if (sc->sc_buffered_char[0]) {
1435 return (1);
1436 }
1437#endif
1438 if (sc->sc_inputs > 0) {
1439 return (1);
1440 }
1441 return (0);
1442}
1443
1444/* check if char is waiting */
1445static int
1446ukbd_check_char_locked(keyboard_t *kbd)
1447{
1448 struct ukbd_softc *sc = kbd->kb_data;
1449
12bd3c8b
SW
1450 if (!KBD_IS_ACTIVE(kbd))
1451 return (0);
1452
1453 if ((sc->sc_composed_char > 0) &&
1454 (!(sc->sc_flags & UKBD_FLAG_COMPOSE))) {
1455 return (1);
1456 }
1457 return (ukbd_check(kbd));
1458}
1459
1460static int
1461ukbd_check_char(keyboard_t *kbd)
1462{
1463 int result;
8d7664cb
SW
1464#if 0
1465 struct ukbd_softc *sc = kbd->kb_data;
12bd3c8b 1466
8d7664cb
SW
1467 UKBD_LOCK(sc);
1468#endif
12bd3c8b 1469 result = ukbd_check_char_locked(kbd);
8d7664cb
SW
1470#if 0
1471 UKBD_UNLOCK(sc);
1472#endif
12bd3c8b
SW
1473
1474 return (result);
1475}
1476
1477/* read one byte from the keyboard if it's allowed */
1478/* Currently unused. */
1479static int
1480ukbd_read(keyboard_t *kbd, int wait)
1481{
1482 struct ukbd_softc *sc = kbd->kb_data;
1483 int32_t usbcode;
1484#ifdef UKBD_EMULATE_ATSCANCODE
1485 uint32_t keycode;
1486 uint32_t scancode;
1487
1488#endif
1489
12bd3c8b
SW
1490 if (!KBD_IS_ACTIVE(kbd))
1491 return (-1);
1492
1493#ifdef UKBD_EMULATE_ATSCANCODE
1494 if (sc->sc_buffered_char[0]) {
1495 scancode = sc->sc_buffered_char[0];
1496 if (scancode & SCAN_PREFIX) {
1497 sc->sc_buffered_char[0] &= ~SCAN_PREFIX;
1498 return ((scancode & SCAN_PREFIX_E0) ? 0xe0 : 0xe1);
1499 }
1500 sc->sc_buffered_char[0] = sc->sc_buffered_char[1];
1501 sc->sc_buffered_char[1] = 0;
1502 return (scancode);
1503 }
1504#endif /* UKBD_EMULATE_ATSCANCODE */
1505
1506 /* XXX */
1507 usbcode = ukbd_get_key(sc, (wait == FALSE) ? 0 : 1);
1508 if (!KBD_IS_ACTIVE(kbd) || (usbcode == -1))
1509 return (-1);
1510
1511 ++(kbd->kb_count);
1512
1513#ifdef UKBD_EMULATE_ATSCANCODE
1514 keycode = ukbd_trtab[KEY_INDEX(usbcode)];
1515 if (keycode == NN) {
1516 return -1;
1517 }
1518 return (ukbd_key2scan(sc, keycode, sc->sc_ndata.modifiers,
1519 (usbcode & KEY_RELEASE)));
1520#else /* !UKBD_EMULATE_ATSCANCODE */
1521 return (usbcode);
1522#endif /* UKBD_EMULATE_ATSCANCODE */
1523}
1524
1525/* read char from the keyboard */
1526static uint32_t
1527ukbd_read_char_locked(keyboard_t *kbd, int wait)
1528{
1529 struct ukbd_softc *sc = kbd->kb_data;
1530 uint32_t action;
1531 uint32_t keycode;
1532 int32_t usbcode;
1533#ifdef UKBD_EMULATE_ATSCANCODE
1534 uint32_t scancode;
1535#endif
1536
12bd3c8b
SW
1537 if (!KBD_IS_ACTIVE(kbd))
1538 return (NOKEY);
1539
1540next_code:
1541
1542 /* do we have a composed char to return ? */
1543
1544 if ((sc->sc_composed_char > 0) &&
1545 (!(sc->sc_flags & UKBD_FLAG_COMPOSE))) {
1546
1547 action = sc->sc_composed_char;
1548 sc->sc_composed_char = 0;
1549
1550 if (action > 0xFF) {
1551 goto errkey;
1552 }
1553 goto done;
1554 }
1555#ifdef UKBD_EMULATE_ATSCANCODE
1556
1557 /* do we have a pending raw scan code? */
1558
1559 if (sc->sc_mode == K_RAW) {
1560 scancode = sc->sc_buffered_char[0];
1561 if (scancode) {
1562 if (scancode & SCAN_PREFIX) {
1563 sc->sc_buffered_char[0] = (scancode & ~SCAN_PREFIX);
1564 return ((scancode & SCAN_PREFIX_E0) ? 0xe0 : 0xe1);
1565 }
1566 sc->sc_buffered_char[0] = sc->sc_buffered_char[1];
1567 sc->sc_buffered_char[1] = 0;
1568 return (scancode);
1569 }
1570 }
1571#endif /* UKBD_EMULATE_ATSCANCODE */
1572
1573 /* see if there is something in the keyboard port */
1574 /* XXX */
1575 usbcode = ukbd_get_key(sc, (wait == FALSE) ? 0 : 1);
1576 if (usbcode == -1) {
1577 return (NOKEY);
1578 }
1579 ++kbd->kb_count;
1580
1581#ifdef UKBD_EMULATE_ATSCANCODE
1582 /* USB key index -> key code -> AT scan code */
1583 keycode = ukbd_trtab[KEY_INDEX(usbcode)];
1584 if (keycode == NN) {
1585 return (NOKEY);
1586 }
1587 /* return an AT scan code for the K_RAW mode */
1588 if (sc->sc_mode == K_RAW) {
1589 return (ukbd_key2scan(sc, keycode, sc->sc_ndata.modifiers,
1590 (usbcode & KEY_RELEASE)));
1591 }
1592#else /* !UKBD_EMULATE_ATSCANCODE */
1593
1594 /* return the byte as is for the K_RAW mode */
1595 if (sc->sc_mode == K_RAW) {
1596 return (usbcode);
1597 }
1598 /* USB key index -> key code */
1599 keycode = ukbd_trtab[KEY_INDEX(usbcode)];
1600 if (keycode == NN) {
1601 return (NOKEY);
1602 }
1603#endif /* UKBD_EMULATE_ATSCANCODE */
1604
1605 switch (keycode) {
1606 case 0x38: /* left alt (compose key) */
1607 if (usbcode & KEY_RELEASE) {
1608 if (sc->sc_flags & UKBD_FLAG_COMPOSE) {
1609 sc->sc_flags &= ~UKBD_FLAG_COMPOSE;
1610
1611 if (sc->sc_composed_char > 0xFF) {
1612 sc->sc_composed_char = 0;
1613 }
1614 }
1615 } else {
1616 if (!(sc->sc_flags & UKBD_FLAG_COMPOSE)) {
1617 sc->sc_flags |= UKBD_FLAG_COMPOSE;
1618 sc->sc_composed_char = 0;
1619 }
1620 }
1621 break;
1622 /* XXX: I don't like these... */
1623 case 0x5c: /* print screen */
1624 if (sc->sc_flags & ALTS) {
1625 keycode = 0x54; /* sysrq */
1626 }
1627 break;
1628 case 0x68: /* pause/break */
1629 if (sc->sc_flags & CTLS) {
1630 keycode = 0x6c; /* break */
1631 }
1632 break;
1633 }
1634
1635 /* return the key code in the K_CODE mode */
1636 if (usbcode & KEY_RELEASE) {
1637 keycode |= SCAN_RELEASE;
1638 }
1639 if (sc->sc_mode == K_CODE) {
1640 return (keycode);
1641 }
1642 /* compose a character code */
1643 if (sc->sc_flags & UKBD_FLAG_COMPOSE) {
1644 switch (keycode) {
1645 /* key pressed, process it */
1646 case 0x47:
1647 case 0x48:
1648 case 0x49: /* keypad 7,8,9 */
1649 sc->sc_composed_char *= 10;
1650 sc->sc_composed_char += keycode - 0x40;
1651 goto check_composed;
1652
1653 case 0x4B:
1654 case 0x4C:
1655 case 0x4D: /* keypad 4,5,6 */
1656 sc->sc_composed_char *= 10;
1657 sc->sc_composed_char += keycode - 0x47;
1658 goto check_composed;
1659
1660 case 0x4F:
1661 case 0x50:
1662 case 0x51: /* keypad 1,2,3 */
1663 sc->sc_composed_char *= 10;
1664 sc->sc_composed_char += keycode - 0x4E;
1665 goto check_composed;
1666
1667 case 0x52: /* keypad 0 */
1668 sc->sc_composed_char *= 10;
1669 goto check_composed;
1670
1671 /* key released, no interest here */
1672 case SCAN_RELEASE | 0x47:
1673 case SCAN_RELEASE | 0x48:
1674 case SCAN_RELEASE | 0x49: /* keypad 7,8,9 */
1675 case SCAN_RELEASE | 0x4B:
1676 case SCAN_RELEASE | 0x4C:
1677 case SCAN_RELEASE | 0x4D: /* keypad 4,5,6 */
1678 case SCAN_RELEASE | 0x4F:
1679 case SCAN_RELEASE | 0x50:
1680 case SCAN_RELEASE | 0x51: /* keypad 1,2,3 */
1681 case SCAN_RELEASE | 0x52: /* keypad 0 */
1682 goto next_code;
1683
1684 case 0x38: /* left alt key */
1685 break;
1686
1687 default:
1688 if (sc->sc_composed_char > 0) {
1689 sc->sc_flags &= ~UKBD_FLAG_COMPOSE;
1690 sc->sc_composed_char = 0;
1691 goto errkey;
1692 }
1693 break;
1694 }
1695 }
1696 /* keycode to key action */
1697 action = genkbd_keyaction(kbd, SCAN_CHAR(keycode),
1698 (keycode & SCAN_RELEASE),
1699 &sc->sc_state, &sc->sc_accents);
1700 if (action == NOKEY) {
1701 goto next_code;
1702 }
1703done:
1704 return (action);
1705
1706check_composed:
1707 if (sc->sc_composed_char <= 0xFF) {
1708 goto next_code;
1709 }
1710errkey:
1711 return (ERRKEY);
1712}
1713
1714/* Currently wait is always false. */
1715static uint32_t
1716ukbd_read_char(keyboard_t *kbd, int wait)
1717{
1718 uint32_t keycode;
8d7664cb
SW
1719#if 0
1720 struct ukbd_softc *sc = kbd->kb_data;
12bd3c8b 1721
8d7664cb
SW
1722 UKBD_LOCK(sc);
1723#endif
12bd3c8b 1724 keycode = ukbd_read_char_locked(kbd, wait);
8d7664cb
SW
1725#if 0
1726 UKBD_UNLOCK(sc);
1727#endif
12bd3c8b
SW
1728
1729 return (keycode);
1730}
1731
1732/* some useful control functions */
1733static int
1734ukbd_ioctl_locked(keyboard_t *kbd, u_long cmd, caddr_t arg)
1735{
1736 struct ukbd_softc *sc = kbd->kb_data;
1737 int i;
b7abfd18 1738#if 0 /* XXX */
12bd3c8b
SW
1739#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
1740 defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
1741 int ival;
1742
1743#endif
b7abfd18 1744#endif
12bd3c8b 1745
12bd3c8b
SW
1746 switch (cmd) {
1747 case KDGKBMODE: /* get keyboard mode */
1748 *(int *)arg = sc->sc_mode;
1749 break;
8d7664cb 1750#if 0 /* XXX */
12bd3c8b
SW
1751#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
1752 defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
1753 case _IO('K', 7):
1754 ival = IOCPARM_IVAL(arg);
1755 arg = (caddr_t)&ival;
1756 /* FALLTHROUGH */
1757#endif
8d7664cb 1758#endif
12bd3c8b
SW
1759 case KDSKBMODE: /* set keyboard mode */
1760 switch (*(int *)arg) {
1761 case K_XLATE:
1762 if (sc->sc_mode != K_XLATE) {
1763 /* make lock key state and LED state match */
1764 sc->sc_state &= ~LOCK_MASK;
1765 sc->sc_state |= KBD_LED_VAL(kbd);
1766 }
1767 /* FALLTHROUGH */
1768 case K_RAW:
1769 case K_CODE:
1770 if (sc->sc_mode != *(int *)arg) {
1771 if ((sc->sc_flags & UKBD_FLAG_POLLING) == 0)
1772 ukbd_clear_state(kbd);
1773 sc->sc_mode = *(int *)arg;
1774 }
1775 break;
1776 default:
1777 return (EINVAL);
1778 }
1779 break;
1780
1781 case KDGETLED: /* get keyboard LED */
1782 *(int *)arg = KBD_LED_VAL(kbd);
1783 break;
8d7664cb 1784#if 0 /* XXX */
12bd3c8b
SW
1785#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
1786 defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
1787 case _IO('K', 66):
1788 ival = IOCPARM_IVAL(arg);
1789 arg = (caddr_t)&ival;
1790 /* FALLTHROUGH */
1791#endif
8d7664cb 1792#endif
12bd3c8b
SW
1793 case KDSETLED: /* set keyboard LED */
1794 /* NOTE: lock key state in "sc_state" won't be changed */
1795 if (*(int *)arg & ~LOCK_MASK)
1796 return (EINVAL);
1797
1798 i = *(int *)arg;
1799
1800 /* replace CAPS LED with ALTGR LED for ALTGR keyboards */
1801 if (sc->sc_mode == K_XLATE &&
1802 kbd->kb_keymap->n_keys > ALTGR_OFFSET) {
1803 if (i & ALKED)
1804 i |= CLKED;
1805 else
1806 i &= ~CLKED;
1807 }
1808 if (KBD_HAS_DEVICE(kbd))
1809 ukbd_set_leds(sc, i);
1810
1811 KBD_LED_VAL(kbd) = *(int *)arg;
1812 break;
1813 case KDGKBSTATE: /* get lock key state */
1814 *(int *)arg = sc->sc_state & LOCK_MASK;
1815 break;
8d7664cb 1816#if 0 /* XXX */
12bd3c8b
SW
1817#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
1818 defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
1819 case _IO('K', 20):
1820 ival = IOCPARM_IVAL(arg);
1821 arg = (caddr_t)&ival;
1822 /* FALLTHROUGH */
1823#endif
8d7664cb 1824#endif
12bd3c8b
SW
1825 case KDSKBSTATE: /* set lock key state */
1826 if (*(int *)arg & ~LOCK_MASK) {
1827 return (EINVAL);
1828 }
1829 sc->sc_state &= ~LOCK_MASK;
1830 sc->sc_state |= *(int *)arg;
1831
1832 /* set LEDs and quit */
1833 return (ukbd_ioctl(kbd, KDSETLED, arg));
1834
1835 case KDSETREPEAT: /* set keyboard repeat rate (new
1836 * interface) */
1837 if (!KBD_HAS_DEVICE(kbd)) {
1838 return (0);
1839 }
1840 if (((int *)arg)[1] < 0) {
1841 return (EINVAL);
1842 }
1843 if (((int *)arg)[0] < 0) {
1844 return (EINVAL);
1845 }
1846 if (((int *)arg)[0] < 200) /* fastest possible value */
1847 kbd->kb_delay1 = 200;
1848 else
1849 kbd->kb_delay1 = ((int *)arg)[0];
1850 kbd->kb_delay2 = ((int *)arg)[1];
1851 return (0);
1852
8d7664cb 1853#if 0 /* XXX */
12bd3c8b
SW
1854#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
1855 defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
1856 case _IO('K', 67):
1857 ival = IOCPARM_IVAL(arg);
1858 arg = (caddr_t)&ival;
1859 /* FALLTHROUGH */
1860#endif
8d7664cb 1861#endif
12bd3c8b
SW
1862 case KDSETRAD: /* set keyboard repeat rate (old
1863 * interface) */
1864 return (ukbd_set_typematic(kbd, *(int *)arg));
1865
1866 case PIO_KEYMAP: /* set keyboard translation table */
12bd3c8b
SW
1867 case PIO_KEYMAPENT: /* set keyboard translation table
1868 * entry */
1869 case PIO_DEADKEYMAP: /* set accent key translation table */
1870 sc->sc_accents = 0;
1871 /* FALLTHROUGH */
1872 default:
1873 return (genkbd_commonioctl(kbd, cmd, arg));
1874 }
1875
1876 return (0);
1877}
1878
1879static int
1880ukbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
1881{
1882 int result;
8d7664cb 1883 struct ukbd_softc *sc = kbd->kb_data;
12bd3c8b
SW
1884
1885 /*
1886 * XXX KDGKBSTATE, KDSKBSTATE and KDSETLED can be called from any
1887 * context where printf(9) can be called, which among other things
1888 * includes interrupt filters and threads with any kinds of locks
1889 * already held. For this reason it would be dangerous to acquire
1890 * the Giant here unconditionally. On the other hand we have to
1891 * have it to handle the ioctl.
1892 * So we make our best effort to auto-detect whether we can grab
1893 * the Giant or not. Blame syscons(4) for this.
1894 */
1895 switch (cmd) {
1896 case KDGKBSTATE:
1897 case KDSKBSTATE:
1898 case KDSETLED:
8d7664cb 1899 return (EDEADLK); /* best I could come up with */
12bd3c8b
SW
1900 /* FALLTHROUGH */
1901 default:
8d7664cb 1902 UKBD_LOCK(sc);
12bd3c8b 1903 result = ukbd_ioctl_locked(kbd, cmd, arg);
8d7664cb 1904 UKBD_UNLOCK(sc);
12bd3c8b
SW
1905 return (result);
1906 }
1907}
1908
1909
1910/* clear the internal state of the keyboard */
1911static void
1912ukbd_clear_state(keyboard_t *kbd)
1913{
1914 struct ukbd_softc *sc = kbd->kb_data;
1915
12bd3c8b
SW
1916 sc->sc_flags &= ~(UKBD_FLAG_COMPOSE | UKBD_FLAG_POLLING);
1917 sc->sc_state &= LOCK_MASK; /* preserve locking key state */
1918 sc->sc_accents = 0;
1919 sc->sc_composed_char = 0;
1920#ifdef UKBD_EMULATE_ATSCANCODE
1921 sc->sc_buffered_char[0] = 0;
1922 sc->sc_buffered_char[1] = 0;
1923#endif
1924 memset(&sc->sc_ndata, 0, sizeof(sc->sc_ndata));
1925 memset(&sc->sc_odata, 0, sizeof(sc->sc_odata));
1926 memset(&sc->sc_ntime, 0, sizeof(sc->sc_ntime));
1927 memset(&sc->sc_otime, 0, sizeof(sc->sc_otime));
1928}
1929
1930/* save the internal state, not used */
1931static int
1932ukbd_get_state(keyboard_t *kbd, void *buf, size_t len)
1933{
1934 return (len == 0) ? 1 : -1;
1935}
1936
1937/* set the internal state, not used */
1938static int
1939ukbd_set_state(keyboard_t *kbd, void *buf, size_t len)
1940{
1941 return (EINVAL);
1942}
1943
1944static int
1945ukbd_poll(keyboard_t *kbd, int on)
1946{
1947 struct ukbd_softc *sc = kbd->kb_data;
1948
8d7664cb 1949 UKBD_LOCK(sc);
12bd3c8b
SW
1950 if (on) {
1951 sc->sc_flags |= UKBD_FLAG_POLLING;
1952 sc->sc_poll_thread = curthread;
1953 } else {
1954 sc->sc_flags &= ~UKBD_FLAG_POLLING;
1955 ukbd_start_timer(sc); /* start timer */
1956 }
8d7664cb 1957 UKBD_UNLOCK(sc);
12bd3c8b
SW
1958
1959 return (0);
1960}
1961
1962/* local functions */
1963
1964static void
1965ukbd_set_leds(struct ukbd_softc *sc, uint8_t leds)
1966{
1967
12bd3c8b
SW
1968 DPRINTF("leds=0x%02x\n", leds);
1969
1970 sc->sc_leds = leds;
1971 sc->sc_flags |= UKBD_FLAG_SET_LEDS;
1972
1973 /* start transfer, if not already started */
1974
1975 usbd_transfer_start(sc->sc_xfer[UKBD_CTRL_LED]);
1976}
1977
1978static int
1979ukbd_set_typematic(keyboard_t *kbd, int code)
1980{
1981 static const int delays[] = {250, 500, 750, 1000};
1982 static const int rates[] = {34, 38, 42, 46, 50, 55, 59, 63,
1983 68, 76, 84, 92, 100, 110, 118, 126,
1984 136, 152, 168, 184, 200, 220, 236, 252,
1985 272, 304, 336, 368, 400, 440, 472, 504};
1986
1987 if (code & ~0x7f) {
1988 return (EINVAL);
1989 }
1990 kbd->kb_delay1 = delays[(code >> 5) & 3];
1991 kbd->kb_delay2 = rates[code & 0x1f];
1992 return (0);
1993}
1994
1995#ifdef UKBD_EMULATE_ATSCANCODE
1996static int
1997ukbd_key2scan(struct ukbd_softc *sc, int code, int shift, int up)
1998{
1999 static const int scan[] = {
2000 /* 89 */
2001 0x11c, /* Enter */
2002 /* 90-99 */
2003 0x11d, /* Ctrl-R */
2004 0x135, /* Divide */
2005 0x137 | SCAN_PREFIX_SHIFT, /* PrintScreen */
2006 0x138, /* Alt-R */
2007 0x147, /* Home */
2008 0x148, /* Up */
2009 0x149, /* PageUp */
2010 0x14b, /* Left */
2011 0x14d, /* Right */
2012 0x14f, /* End */
2013 /* 100-109 */
2014 0x150, /* Down */
2015 0x151, /* PageDown */
2016 0x152, /* Insert */
2017 0x153, /* Delete */
2018 0x146, /* XXX Pause/Break */
2019 0x15b, /* Win_L(Super_L) */
2020 0x15c, /* Win_R(Super_R) */
2021 0x15d, /* Application(Menu) */
2022
2023 /* SUN TYPE 6 USB KEYBOARD */
2024 0x168, /* Sun Type 6 Help */
2025 0x15e, /* Sun Type 6 Stop */
2026 /* 110 - 119 */
2027 0x15f, /* Sun Type 6 Again */
2028 0x160, /* Sun Type 6 Props */
2029 0x161, /* Sun Type 6 Undo */
2030 0x162, /* Sun Type 6 Front */
2031 0x163, /* Sun Type 6 Copy */
2032 0x164, /* Sun Type 6 Open */
2033 0x165, /* Sun Type 6 Paste */
2034 0x166, /* Sun Type 6 Find */
2035 0x167, /* Sun Type 6 Cut */
2036 0x125, /* Sun Type 6 Mute */
2037 /* 120 - 128 */
2038 0x11f, /* Sun Type 6 VolumeDown */
2039 0x11e, /* Sun Type 6 VolumeUp */
2040 0x120, /* Sun Type 6 PowerDown */
2041
2042 /* Japanese 106/109 keyboard */
2043 0x73, /* Keyboard Intl' 1 (backslash / underscore) */
2044 0x70, /* Keyboard Intl' 2 (Katakana / Hiragana) */
2045 0x7d, /* Keyboard Intl' 3 (Yen sign) (Not using in jp106/109) */
2046 0x79, /* Keyboard Intl' 4 (Henkan) */
2047 0x7b, /* Keyboard Intl' 5 (Muhenkan) */
2048 0x5c, /* Keyboard Intl' 6 (Keypad ,) (For PC-9821 layout) */
2049 };
2050
2051 if ((code >= 89) && (code < (89 + (sizeof(scan) / sizeof(scan[0]))))) {
2052 code = scan[code - 89];
2053 }
2054 /* Pause/Break */
2055 if ((code == 104) && (!(shift & (MOD_CONTROL_L | MOD_CONTROL_R)))) {
2056 code = (0x45 | SCAN_PREFIX_E1 | SCAN_PREFIX_CTL);
2057 }
2058 if (shift & (MOD_SHIFT_L | MOD_SHIFT_R)) {
2059 code &= ~SCAN_PREFIX_SHIFT;
2060 }
2061 code |= (up ? SCAN_RELEASE : SCAN_PRESS);
2062
2063 if (code & SCAN_PREFIX) {
2064 if (code & SCAN_PREFIX_CTL) {
2065 /* Ctrl */
2066 sc->sc_buffered_char[0] = (0x1d | (code & SCAN_RELEASE));
2067 sc->sc_buffered_char[1] = (code & ~SCAN_PREFIX);
2068 } else if (code & SCAN_PREFIX_SHIFT) {
2069 /* Shift */
2070 sc->sc_buffered_char[0] = (0x2a | (code & SCAN_RELEASE));
2071 sc->sc_buffered_char[1] = (code & ~SCAN_PREFIX_SHIFT);
2072 } else {
2073 sc->sc_buffered_char[0] = (code & ~SCAN_PREFIX);
2074 sc->sc_buffered_char[1] = 0;
2075 }
2076 return ((code & SCAN_PREFIX_E0) ? 0xe0 : 0xe1);
2077 }
2078 return (code);
2079
2080}
2081
2082#endif /* UKBD_EMULATE_ATSCANCODE */
2083
2084static keyboard_switch_t ukbdsw = {
2085 .probe = &ukbd__probe,
2086 .init = &ukbd_init,
2087 .term = &ukbd_term,
2088 .intr = &ukbd_intr,
2089 .test_if = &ukbd_test_if,
2090 .enable = &ukbd_enable,
2091 .disable = &ukbd_disable,
2092 .read = &ukbd_read,
2093 .check = &ukbd_check,
2094 .read_char = &ukbd_read_char,
2095 .check_char = &ukbd_check_char,
2096 .ioctl = &ukbd_ioctl,
2097 .lock = &ukbd_lock,
2098 .clear_state = &ukbd_clear_state,
2099 .get_state = &ukbd_get_state,
2100 .set_state = &ukbd_set_state,
2101 .get_fkeystr = &genkbd_get_fkeystr,
2102 .poll = &ukbd_poll,
2103 .diag = &genkbd_diag,
2104};
2105
2106KEYBOARD_DRIVER(ukbd, ukbdsw, ukbd_configure);
2107
2108static int
2109ukbd_driver_load(module_t mod, int what, void *arg)
2110{
2111 switch (what) {
2112 case MOD_LOAD:
2113 kbd_add_driver(&ukbd_kbd_driver);
2114 break;
2115 case MOD_UNLOAD:
2116 kbd_delete_driver(&ukbd_kbd_driver);
2117 break;
2118 }
2119 return (0);
2120}
2121
2122static devclass_t ukbd_devclass;
2123
2124static device_method_t ukbd_methods[] = {
2125 DEVMETHOD(device_probe, ukbd_probe),
2126 DEVMETHOD(device_attach, ukbd_attach),
2127 DEVMETHOD(device_detach, ukbd_detach),
2128 DEVMETHOD(device_resume, ukbd_resume),
2129 {0, 0}
2130};
2131
2132static driver_t ukbd_driver = {
2133 .name = "ukbd",
2134 .methods = ukbd_methods,
2135 .size = sizeof(struct ukbd_softc),
2136};
2137
15f415f6 2138DRIVER_MODULE(ukbd, uhub, ukbd_driver, ukbd_devclass, ukbd_driver_load, NULL);
12bd3c8b
SW
2139MODULE_DEPEND(ukbd, usb, 1, 1, 1);
2140MODULE_VERSION(ukbd, 1);