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