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