xref: /freebsd/sys/dev/kbdmux/kbdmux.c (revision aa24f48b361effe51163877d84f1b70d32b77e04)
1 /*
2  * kbdmux.c
3  */
4 
5 /*-
6  * Copyright (c) 2005 Maksim Yevmenkin <m_evmenkin@yahoo.com>
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  * $Id: kbdmux.c,v 1.4 2005/07/14 17:38:35 max Exp $
31  * $FreeBSD$
32  */
33 
34 #include "opt_compat.h"
35 #include "opt_evdev.h"
36 #include "opt_kbd.h"
37 #include "opt_kbdmux.h"
38 
39 #include <sys/param.h>
40 #include <sys/bus.h>
41 #include <sys/conf.h>
42 #include <sys/consio.h>
43 #include <sys/fcntl.h>
44 #include <sys/kbio.h>
45 #include <sys/kernel.h>
46 #include <sys/limits.h>
47 #include <sys/lock.h>
48 #include <sys/malloc.h>
49 #include <sys/module.h>
50 #include <sys/mutex.h>
51 #include <sys/poll.h>
52 #include <sys/proc.h>
53 #include <sys/queue.h>
54 #include <sys/selinfo.h>
55 #include <sys/systm.h>
56 #include <sys/taskqueue.h>
57 #include <sys/uio.h>
58 #include <dev/kbd/kbdreg.h>
59 
60 /* the initial key map, accent map and fkey strings */
61 #ifdef KBDMUX_DFLT_KEYMAP
62 #define KBD_DFLT_KEYMAP
63 #include "kbdmuxmap.h"
64 #endif
65 
66 #include <dev/kbd/kbdtables.h>
67 
68 #ifdef EVDEV_SUPPORT
69 #include <dev/evdev/evdev.h>
70 #include <dev/evdev/input.h>
71 #endif
72 
73 #define KEYBOARD_NAME	"kbdmux"
74 
75 MALLOC_DECLARE(M_KBDMUX);
76 MALLOC_DEFINE(M_KBDMUX, KEYBOARD_NAME, "Keyboard multiplexor");
77 
78 /*****************************************************************************
79  *****************************************************************************
80  **                             Keyboard state
81  *****************************************************************************
82  *****************************************************************************/
83 
84 #define	KBDMUX_Q_SIZE	512	/* input queue size */
85 
86 /*
87  * XXX
88  * For now rely on Giant mutex to protect our data structures.
89  * Just like the rest of keyboard drivers and syscons(4) do.
90  * Note that callout is initialized as not MP-safe to make sure
91  * Giant is held.
92  */
93 
94 #if 0 /* not yet */
95 #define KBDMUX_LOCK_DECL_GLOBAL \
96 	struct mtx ks_lock
97 #define KBDMUX_LOCK_INIT(s) \
98 	mtx_init(&(s)->ks_lock, "kbdmux", NULL, MTX_DEF|MTX_RECURSE)
99 #define KBDMUX_LOCK_DESTROY(s) \
100 	mtx_destroy(&(s)->ks_lock)
101 #define KBDMUX_LOCK(s) \
102 	mtx_lock(&(s)->ks_lock)
103 #define KBDMUX_UNLOCK(s) \
104 	mtx_unlock(&(s)->ks_lock)
105 #define KBDMUX_LOCK_ASSERT(s, w) \
106 	mtx_assert(&(s)->ks_lock, (w))
107 #define KBDMUX_SLEEP(s, f, d, t) \
108 	msleep(&(s)->f, &(s)->ks_lock, PCATCH | (PZERO + 1), (d), (t))
109 #define KBDMUX_CALLOUT_INIT(s) \
110 	callout_init_mtx(&(s)->ks_timo, &(s)->ks_lock, 0)
111 #define KBDMUX_QUEUE_INTR(s) \
112 	taskqueue_enqueue(taskqueue_swi_giant, &(s)->ks_task)
113 #else
114 #define KBDMUX_LOCK_DECL_GLOBAL
115 
116 #define KBDMUX_LOCK_INIT(s)
117 
118 #define KBDMUX_LOCK_DESTROY(s)
119 
120 #define KBDMUX_LOCK(s)
121 
122 #define KBDMUX_UNLOCK(s)
123 
124 #define KBDMUX_LOCK_ASSERT(s, w)
125 
126 #define KBDMUX_SLEEP(s, f, d, t) \
127 	tsleep(&(s)->f, PCATCH | (PZERO + 1), (d), (t))
128 #define KBDMUX_CALLOUT_INIT(s) \
129 	callout_init(&(s)->ks_timo, 0)
130 #define KBDMUX_QUEUE_INTR(s) \
131 	taskqueue_enqueue(taskqueue_swi_giant, &(s)->ks_task)
132 #endif /* not yet */
133 
134 /*
135  * kbdmux keyboard
136  */
137 struct kbdmux_kbd
138 {
139 	keyboard_t		*kbd;	/* keyboard */
140 	SLIST_ENTRY(kbdmux_kbd)	 next;	/* link to next */
141 };
142 
143 typedef struct kbdmux_kbd	kbdmux_kbd_t;
144 
145 /*
146  * kbdmux state
147  */
148 struct kbdmux_state
149 {
150 	char			 ks_inq[KBDMUX_Q_SIZE]; /* input chars queue */
151 	unsigned int		 ks_inq_start;
152 	unsigned int		 ks_inq_length;
153 	struct task		 ks_task;	/* interrupt task */
154 	struct callout		 ks_timo;	/* timeout handler */
155 #define TICKS			(hz)		/* rate */
156 
157 	int			 ks_flags;	/* flags */
158 #define COMPOSE			(1 << 0)	/* compose char flag */
159 #define TASK			(1 << 2)	/* interrupt task queued */
160 
161 	int			 ks_polling;	/* poll nesting count */
162 	int			 ks_mode;	/* K_XLATE, K_RAW, K_CODE */
163 	int			 ks_state;	/* state */
164 	int			 ks_accents;	/* accent key index (> 0) */
165 	u_int			 ks_composed_char; /* composed char code */
166 	u_char			 ks_prefix;	/* AT scan code prefix */
167 
168 #ifdef EVDEV_SUPPORT
169 	struct evdev_dev *	 ks_evdev;
170 	int			 ks_evdev_state;
171 #endif
172 
173 	SLIST_HEAD(, kbdmux_kbd) ks_kbds;	/* keyboards */
174 
175 	KBDMUX_LOCK_DECL_GLOBAL;
176 };
177 
178 typedef struct kbdmux_state	kbdmux_state_t;
179 
180 /*****************************************************************************
181  *****************************************************************************
182  **                             Helper functions
183  *****************************************************************************
184  *****************************************************************************/
185 
186 static task_fn_t		kbdmux_kbd_intr;
187 static timeout_t		kbdmux_kbd_intr_timo;
188 static kbd_callback_func_t	kbdmux_kbd_event;
189 
190 static void
191 kbdmux_kbd_putc(kbdmux_state_t *state, char c)
192 {
193 	unsigned int p;
194 
195 	if (state->ks_inq_length == KBDMUX_Q_SIZE)
196 		return;
197 
198 	p = (state->ks_inq_start + state->ks_inq_length) % KBDMUX_Q_SIZE;
199 	state->ks_inq[p] = c;
200 	state->ks_inq_length++;
201 }
202 
203 static int
204 kbdmux_kbd_getc(kbdmux_state_t *state)
205 {
206 	unsigned char c;
207 
208 	if (state->ks_inq_length == 0)
209 		return (-1);
210 
211 	c = state->ks_inq[state->ks_inq_start];
212 	state->ks_inq_start = (state->ks_inq_start + 1) % KBDMUX_Q_SIZE;
213 	state->ks_inq_length--;
214 
215 	return (c);
216 }
217 
218 /*
219  * Interrupt handler task
220  */
221 void
222 kbdmux_kbd_intr(void *xkbd, int pending)
223 {
224 	keyboard_t	*kbd = (keyboard_t *) xkbd;
225 	kbdmux_state_t	*state = (kbdmux_state_t *) kbd->kb_data;
226 
227 	kbdd_intr(kbd, NULL);
228 
229 	KBDMUX_LOCK(state);
230 
231 	state->ks_flags &= ~TASK;
232 	wakeup(&state->ks_task);
233 
234 	KBDMUX_UNLOCK(state);
235 }
236 
237 /*
238  * Schedule interrupt handler on timeout. Called with locked state.
239  */
240 void
241 kbdmux_kbd_intr_timo(void *xstate)
242 {
243 	kbdmux_state_t	*state = (kbdmux_state_t *) xstate;
244 
245 	KBDMUX_LOCK_ASSERT(state, MA_OWNED);
246 
247 	if (callout_pending(&state->ks_timo))
248 		return; /* callout was reset */
249 
250 	if (!callout_active(&state->ks_timo))
251 		return; /* callout was stopped */
252 
253 	callout_deactivate(&state->ks_timo);
254 
255 	/* queue interrupt task if needed */
256 	if (state->ks_inq_length > 0 && !(state->ks_flags & TASK) &&
257 	    KBDMUX_QUEUE_INTR(state) == 0)
258 		state->ks_flags |= TASK;
259 
260 	/* re-schedule timeout */
261 	callout_reset(&state->ks_timo, TICKS, kbdmux_kbd_intr_timo, state);
262 }
263 
264 /*
265  * Process event from one of our keyboards
266  */
267 static int
268 kbdmux_kbd_event(keyboard_t *kbd, int event, void *arg)
269 {
270 	kbdmux_state_t	*state = (kbdmux_state_t *) arg;
271 
272 	switch (event) {
273 	case KBDIO_KEYINPUT: {
274 		int	c;
275 
276 		KBDMUX_LOCK(state);
277 
278 		/*
279 		 * Read all chars from the keyboard
280 		 *
281 		 * Turns out that atkbd(4) check_char() method may return
282 		 * "true" while read_char() method returns NOKEY. If this
283 		 * happens we could stuck in the loop below. Avoid this
284 		 * by breaking out of the loop if read_char() method returns
285 		 * NOKEY.
286 		 */
287 
288 		while (kbdd_check_char(kbd)) {
289 			c = kbdd_read_char(kbd, 0);
290 			if (c == NOKEY)
291 				break;
292 			if (c == ERRKEY)
293 				continue; /* XXX ring bell */
294 			if (!KBD_IS_BUSY(kbd))
295 				continue; /* not open - discard the input */
296 
297 			kbdmux_kbd_putc(state, c);
298 		}
299 
300 		/* queue interrupt task if needed */
301 		if (state->ks_inq_length > 0 && !(state->ks_flags & TASK) &&
302 		    KBDMUX_QUEUE_INTR(state) == 0)
303 			state->ks_flags |= TASK;
304 
305 		KBDMUX_UNLOCK(state);
306 		} break;
307 
308 	case KBDIO_UNLOADING: {
309 		kbdmux_kbd_t	*k;
310 
311 		KBDMUX_LOCK(state);
312 
313 		SLIST_FOREACH(k, &state->ks_kbds, next)
314 			if (k->kbd == kbd)
315 				break;
316 
317 		if (k != NULL) {
318 			kbd_release(k->kbd, &k->kbd);
319 			SLIST_REMOVE(&state->ks_kbds, k, kbdmux_kbd, next);
320 
321 			k->kbd = NULL;
322 
323 			free(k, M_KBDMUX);
324 		}
325 
326 		KBDMUX_UNLOCK(state);
327 		} break;
328 
329 	default:
330 		return (EINVAL);
331 		/* NOT REACHED */
332 	}
333 
334 	return (0);
335 }
336 
337 /****************************************************************************
338  ****************************************************************************
339  **                              Keyboard driver
340  ****************************************************************************
341  ****************************************************************************/
342 
343 static int		kbdmux_configure(int flags);
344 static kbd_probe_t	kbdmux_probe;
345 static kbd_init_t	kbdmux_init;
346 static kbd_term_t	kbdmux_term;
347 static kbd_intr_t	kbdmux_intr;
348 static kbd_test_if_t	kbdmux_test_if;
349 static kbd_enable_t	kbdmux_enable;
350 static kbd_disable_t	kbdmux_disable;
351 static kbd_read_t	kbdmux_read;
352 static kbd_check_t	kbdmux_check;
353 static kbd_read_char_t	kbdmux_read_char;
354 static kbd_check_char_t	kbdmux_check_char;
355 static kbd_ioctl_t	kbdmux_ioctl;
356 static kbd_lock_t	kbdmux_lock;
357 static void		kbdmux_clear_state_locked(kbdmux_state_t *state);
358 static kbd_clear_state_t kbdmux_clear_state;
359 static kbd_get_state_t	kbdmux_get_state;
360 static kbd_set_state_t	kbdmux_set_state;
361 static kbd_poll_mode_t	kbdmux_poll;
362 
363 static keyboard_switch_t kbdmuxsw = {
364 	.probe =	kbdmux_probe,
365 	.init =		kbdmux_init,
366 	.term =		kbdmux_term,
367 	.intr =		kbdmux_intr,
368 	.test_if =	kbdmux_test_if,
369 	.enable =	kbdmux_enable,
370 	.disable =	kbdmux_disable,
371 	.read =		kbdmux_read,
372 	.check =	kbdmux_check,
373 	.read_char =	kbdmux_read_char,
374 	.check_char =	kbdmux_check_char,
375 	.ioctl =	kbdmux_ioctl,
376 	.lock =		kbdmux_lock,
377 	.clear_state =	kbdmux_clear_state,
378 	.get_state =	kbdmux_get_state,
379 	.set_state =	kbdmux_set_state,
380 	.get_fkeystr =	genkbd_get_fkeystr,
381 	.poll =		kbdmux_poll,
382 	.diag =		genkbd_diag,
383 };
384 
385 #ifdef EVDEV_SUPPORT
386 static const struct evdev_methods kbdmux_evdev_methods = {
387 	.ev_event = evdev_ev_kbd_event,
388 };
389 #endif
390 
391 /*
392  * Return the number of found keyboards
393  */
394 static int
395 kbdmux_configure(int flags)
396 {
397 	return (1);
398 }
399 
400 /*
401  * Detect a keyboard
402  */
403 static int
404 kbdmux_probe(int unit, void *arg, int flags)
405 {
406 	if (resource_disabled(KEYBOARD_NAME, unit))
407 		return (ENXIO);
408 
409 	return (0);
410 }
411 
412 /*
413  * Reset and initialize the keyboard (stolen from atkbd.c)
414  */
415 static int
416 kbdmux_init(int unit, keyboard_t **kbdp, void *arg, int flags)
417 {
418 	keyboard_t	*kbd = NULL;
419 	kbdmux_state_t	*state = NULL;
420 	keymap_t	*keymap = NULL;
421         accentmap_t	*accmap = NULL;
422         fkeytab_t	*fkeymap = NULL;
423 	int		 error, needfree, fkeymap_size, delay[2];
424 #ifdef EVDEV_SUPPORT
425 	struct evdev_dev *evdev;
426 	char		 phys_loc[NAMELEN];
427 #endif
428 
429 	if (*kbdp == NULL) {
430 		*kbdp = kbd = malloc(sizeof(*kbd), M_KBDMUX, M_NOWAIT | M_ZERO);
431 		state = malloc(sizeof(*state), M_KBDMUX, M_NOWAIT | M_ZERO);
432 		keymap = malloc(sizeof(key_map), M_KBDMUX, M_NOWAIT);
433 		accmap = malloc(sizeof(accent_map), M_KBDMUX, M_NOWAIT);
434 		fkeymap = malloc(sizeof(fkey_tab), M_KBDMUX, M_NOWAIT);
435 		fkeymap_size = sizeof(fkey_tab)/sizeof(fkey_tab[0]);
436 		needfree = 1;
437 
438 		if ((kbd == NULL) || (state == NULL) || (keymap == NULL) ||
439 		    (accmap == NULL) || (fkeymap == NULL)) {
440 			error = ENOMEM;
441 			goto bad;
442 		}
443 
444 		KBDMUX_LOCK_INIT(state);
445 		TASK_INIT(&state->ks_task, 0, kbdmux_kbd_intr, (void *) kbd);
446 		KBDMUX_CALLOUT_INIT(state);
447 		SLIST_INIT(&state->ks_kbds);
448 	} else if (KBD_IS_INITIALIZED(*kbdp) && KBD_IS_CONFIGURED(*kbdp)) {
449 		return (0);
450 	} else {
451 		kbd = *kbdp;
452 		state = (kbdmux_state_t *) kbd->kb_data;
453 		keymap = kbd->kb_keymap;
454 		accmap = kbd->kb_accentmap;
455 		fkeymap = kbd->kb_fkeytab;
456 		fkeymap_size = kbd->kb_fkeytab_size;
457 		needfree = 0;
458 	}
459 
460 	if (!KBD_IS_PROBED(kbd)) {
461 		/* XXX assume 101/102 keys keyboard */
462 		kbd_init_struct(kbd, KEYBOARD_NAME, KB_101, unit, flags, 0, 0);
463 		bcopy(&key_map, keymap, sizeof(key_map));
464 		bcopy(&accent_map, accmap, sizeof(accent_map));
465 		bcopy(fkey_tab, fkeymap,
466 			imin(fkeymap_size*sizeof(fkeymap[0]), sizeof(fkey_tab)));
467 		kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size);
468 		kbd->kb_data = (void *)state;
469 
470 		KBD_FOUND_DEVICE(kbd);
471 		KBD_PROBE_DONE(kbd);
472 
473 		KBDMUX_LOCK(state);
474 		kbdmux_clear_state_locked(state);
475 		state->ks_mode = K_XLATE;
476 		KBDMUX_UNLOCK(state);
477 	}
478 
479 	if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) {
480 		kbd->kb_config = flags & ~KB_CONF_PROBE_ONLY;
481 
482 		kbdmux_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state);
483 
484 		delay[0] = kbd->kb_delay1;
485 		delay[1] = kbd->kb_delay2;
486 		kbdmux_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
487 
488 #ifdef EVDEV_SUPPORT
489 		/* register as evdev provider */
490 		evdev = evdev_alloc();
491 		evdev_set_name(evdev, "System keyboard multiplexer");
492 		snprintf(phys_loc, NAMELEN, KEYBOARD_NAME"%d", unit);
493 		evdev_set_phys(evdev, phys_loc);
494 		evdev_set_id(evdev, BUS_VIRTUAL, 0, 0, 0);
495 		evdev_set_methods(evdev, kbd, &kbdmux_evdev_methods);
496 		evdev_support_event(evdev, EV_SYN);
497 		evdev_support_event(evdev, EV_KEY);
498 		evdev_support_event(evdev, EV_LED);
499 		evdev_support_event(evdev, EV_REP);
500 		evdev_support_all_known_keys(evdev);
501 		evdev_support_led(evdev, LED_NUML);
502 		evdev_support_led(evdev, LED_CAPSL);
503 		evdev_support_led(evdev, LED_SCROLLL);
504 
505 		if (evdev_register(evdev))
506 			evdev_free(evdev);
507 		else
508 			state->ks_evdev = evdev;
509 		state->ks_evdev_state = 0;
510 #endif
511 
512 		KBD_INIT_DONE(kbd);
513 	}
514 
515 	if (!KBD_IS_CONFIGURED(kbd)) {
516 		if (kbd_register(kbd) < 0) {
517 			error = ENXIO;
518 			goto bad;
519 		}
520 
521 		KBD_CONFIG_DONE(kbd);
522 
523 		KBDMUX_LOCK(state);
524 		callout_reset(&state->ks_timo, TICKS, kbdmux_kbd_intr_timo, state);
525 		KBDMUX_UNLOCK(state);
526 	}
527 
528 	return (0);
529 bad:
530 	if (needfree) {
531 		if (state != NULL)
532 			free(state, M_KBDMUX);
533 		if (keymap != NULL)
534 			free(keymap, M_KBDMUX);
535 		if (accmap != NULL)
536 			free(accmap, M_KBDMUX);
537 		if (fkeymap != NULL)
538 			free(fkeymap, M_KBDMUX);
539 		if (kbd != NULL) {
540 			free(kbd, M_KBDMUX);
541 			*kbdp = NULL;	/* insure ref doesn't leak to caller */
542 		}
543 	}
544 
545 	return (error);
546 }
547 
548 /*
549  * Finish using this keyboard
550  */
551 static int
552 kbdmux_term(keyboard_t *kbd)
553 {
554 	kbdmux_state_t	*state = (kbdmux_state_t *) kbd->kb_data;
555 	kbdmux_kbd_t	*k;
556 
557 	KBDMUX_LOCK(state);
558 
559 	/* kill callout */
560 	callout_stop(&state->ks_timo);
561 
562 	/* wait for interrupt task */
563 	while (state->ks_flags & TASK)
564 		KBDMUX_SLEEP(state, ks_task, "kbdmuxc", 0);
565 
566 	/* release all keyboards from the mux */
567 	while ((k = SLIST_FIRST(&state->ks_kbds)) != NULL) {
568 		kbd_release(k->kbd, &k->kbd);
569 		SLIST_REMOVE_HEAD(&state->ks_kbds, next);
570 
571 		k->kbd = NULL;
572 
573 		free(k, M_KBDMUX);
574 	}
575 
576 	KBDMUX_UNLOCK(state);
577 
578 	kbd_unregister(kbd);
579 
580 #ifdef EVDEV_SUPPORT
581 	evdev_free(state->ks_evdev);
582 #endif
583 
584 	KBDMUX_LOCK_DESTROY(state);
585 	bzero(state, sizeof(*state));
586 	free(state, M_KBDMUX);
587 
588 	free(kbd->kb_keymap, M_KBDMUX);
589 	free(kbd->kb_accentmap, M_KBDMUX);
590 	free(kbd->kb_fkeytab, M_KBDMUX);
591 	free(kbd, M_KBDMUX);
592 
593 	return (0);
594 }
595 
596 /*
597  * Keyboard interrupt routine
598  */
599 static int
600 kbdmux_intr(keyboard_t *kbd, void *arg)
601 {
602 	int	c;
603 
604 	if (KBD_IS_ACTIVE(kbd) && KBD_IS_BUSY(kbd)) {
605 		/* let the callback function to process the input */
606 		(*kbd->kb_callback.kc_func)(kbd, KBDIO_KEYINPUT,
607 					    kbd->kb_callback.kc_arg);
608 	} else {
609 		/* read and discard the input; no one is waiting for input */
610 		do {
611 			c = kbdmux_read_char(kbd, FALSE);
612 		} while (c != NOKEY);
613 	}
614 
615 	return (0);
616 }
617 
618 /*
619  * Test the interface to the device
620  */
621 static int
622 kbdmux_test_if(keyboard_t *kbd)
623 {
624 	return (0);
625 }
626 
627 /*
628  * Enable the access to the device; until this function is called,
629  * the client cannot read from the keyboard.
630  */
631 static int
632 kbdmux_enable(keyboard_t *kbd)
633 {
634 	KBD_ACTIVATE(kbd);
635 	return (0);
636 }
637 
638 /*
639  * Disallow the access to the device
640  */
641 static int
642 kbdmux_disable(keyboard_t *kbd)
643 {
644 	KBD_DEACTIVATE(kbd);
645 	return (0);
646 }
647 
648 /*
649  * Read one byte from the keyboard if it's allowed
650  */
651 static int
652 kbdmux_read(keyboard_t *kbd, int wait)
653 {
654 	kbdmux_state_t	*state = (kbdmux_state_t *) kbd->kb_data;
655 	int		 c;
656 
657 	KBDMUX_LOCK(state);
658 	c = kbdmux_kbd_getc(state);
659 	KBDMUX_UNLOCK(state);
660 
661 	if (c != -1)
662 		kbd->kb_count ++;
663 
664 	return (KBD_IS_ACTIVE(kbd)? c : -1);
665 }
666 
667 /*
668  * Check if data is waiting
669  */
670 static int
671 kbdmux_check(keyboard_t *kbd)
672 {
673 	kbdmux_state_t	*state = (kbdmux_state_t *) kbd->kb_data;
674 	int		 ready;
675 
676 	if (!KBD_IS_ACTIVE(kbd))
677 		return (FALSE);
678 
679 	KBDMUX_LOCK(state);
680 	ready = (state->ks_inq_length > 0) ? TRUE : FALSE;
681 	KBDMUX_UNLOCK(state);
682 
683 	return (ready);
684 }
685 
686 /*
687  * Read char from the keyboard (stolen from atkbd.c)
688  */
689 static u_int
690 kbdmux_read_char(keyboard_t *kbd, int wait)
691 {
692 	kbdmux_state_t	*state = (kbdmux_state_t *) kbd->kb_data;
693 	u_int		 action;
694 	int		 scancode, keycode;
695 
696 	KBDMUX_LOCK(state);
697 
698 next_code:
699 
700 	/* do we have a composed char to return? */
701 	if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0)) {
702 		action = state->ks_composed_char;
703 		state->ks_composed_char = 0;
704 		if (action > UCHAR_MAX) {
705 			KBDMUX_UNLOCK(state);
706 
707 			return (ERRKEY);
708 		}
709 
710 		KBDMUX_UNLOCK(state);
711 
712 		return (action);
713 	}
714 
715 	/* see if there is something in the keyboard queue */
716 	scancode = kbdmux_kbd_getc(state);
717 	if (scancode == -1) {
718 		if (state->ks_polling != 0) {
719 			kbdmux_kbd_t	*k;
720 
721 			SLIST_FOREACH(k, &state->ks_kbds, next) {
722 				while (kbdd_check_char(k->kbd)) {
723 					scancode = kbdd_read_char(k->kbd, 0);
724 					if (scancode == NOKEY)
725 						break;
726 					if (scancode == ERRKEY)
727 						continue;
728 					if (!KBD_IS_BUSY(k->kbd))
729 						continue;
730 
731 					kbdmux_kbd_putc(state, scancode);
732 				}
733 			}
734 
735 			if (state->ks_inq_length > 0)
736 				goto next_code;
737 		}
738 
739 		KBDMUX_UNLOCK(state);
740 		return (NOKEY);
741 	}
742 	/* XXX FIXME: check for -1 if wait == 1! */
743 
744 	kbd->kb_count ++;
745 
746 #ifdef EVDEV_SUPPORT
747 	/* push evdev event */
748 	if (evdev_rcpt_mask & EVDEV_RCPT_KBDMUX && state->ks_evdev != NULL) {
749 		uint16_t key = evdev_scancode2key(&state->ks_evdev_state,
750 		    scancode);
751 
752 		if (key != KEY_RESERVED) {
753 			evdev_push_event(state->ks_evdev, EV_KEY,
754 			    key, scancode & 0x80 ? 0 : 1);
755 			evdev_sync(state->ks_evdev);
756 		}
757 	}
758 #endif
759 
760 	/* return the byte as is for the K_RAW mode */
761 	if (state->ks_mode == K_RAW) {
762 		KBDMUX_UNLOCK(state);
763 		return (scancode);
764 	}
765 
766 	/* translate the scan code into a keycode */
767 	keycode = scancode & 0x7F;
768 	switch (state->ks_prefix) {
769 	case 0x00:	/* normal scancode */
770 		switch(scancode) {
771 		case 0xB8:	/* left alt (compose key) released */
772 			if (state->ks_flags & COMPOSE) {
773 				state->ks_flags &= ~COMPOSE;
774 				if (state->ks_composed_char > UCHAR_MAX)
775 					state->ks_composed_char = 0;
776 			}
777 			break;
778 		case 0x38:	/* left alt (compose key) pressed */
779 			if (!(state->ks_flags & COMPOSE)) {
780 				state->ks_flags |= COMPOSE;
781 				state->ks_composed_char = 0;
782 			}
783 			break;
784 		case 0xE0:
785 		case 0xE1:
786 			state->ks_prefix = scancode;
787 			goto next_code;
788 		}
789 		break;
790 	case 0xE0:      /* 0xE0 prefix */
791 		state->ks_prefix = 0;
792 		switch (keycode) {
793 		case 0x1C:	/* right enter key */
794 			keycode = 0x59;
795 			break;
796 		case 0x1D:	/* right ctrl key */
797 			keycode = 0x5A;
798 			break;
799 		case 0x35:	/* keypad divide key */
800 			keycode = 0x5B;
801 			break;
802 		case 0x37:	/* print scrn key */
803 			keycode = 0x5C;
804 			break;
805 		case 0x38:	/* right alt key (alt gr) */
806 			keycode = 0x5D;
807 			break;
808 		case 0x46:	/* ctrl-pause/break on AT 101 (see below) */
809 			keycode = 0x68;
810 			break;
811 		case 0x47:	/* grey home key */
812 			keycode = 0x5E;
813 			break;
814 		case 0x48:	/* grey up arrow key */
815 			keycode = 0x5F;
816 			break;
817 		case 0x49:	/* grey page up key */
818 			keycode = 0x60;
819 			break;
820 		case 0x4B:	/* grey left arrow key */
821 			keycode = 0x61;
822 			break;
823 		case 0x4D:	/* grey right arrow key */
824 			keycode = 0x62;
825 			break;
826 		case 0x4F:	/* grey end key */
827 			keycode = 0x63;
828 			break;
829 		case 0x50:	/* grey down arrow key */
830 			keycode = 0x64;
831 			break;
832 		case 0x51:	/* grey page down key */
833 			keycode = 0x65;
834 			break;
835 		case 0x52:	/* grey insert key */
836 			keycode = 0x66;
837 			break;
838 		case 0x53:	/* grey delete key */
839 			keycode = 0x67;
840 			break;
841 		/* the following 3 are only used on the MS "Natural" keyboard */
842 		case 0x5b:	/* left Window key */
843 			keycode = 0x69;
844 			break;
845 		case 0x5c:	/* right Window key */
846 			keycode = 0x6a;
847 			break;
848 		case 0x5d:	/* menu key */
849 			keycode = 0x6b;
850 			break;
851 		case 0x5e:	/* power key */
852 			keycode = 0x6d;
853 			break;
854 		case 0x5f:	/* sleep key */
855 			keycode = 0x6e;
856 			break;
857 		case 0x63:	/* wake key */
858 			keycode = 0x6f;
859 			break;
860 		case 0x64:	/* [JP106USB] backslash, underscore */
861 			keycode = 0x73;
862 			break;
863 		default:	/* ignore everything else */
864 			goto next_code;
865 		}
866 		break;
867 	case 0xE1:	/* 0xE1 prefix */
868 		/*
869 		 * The pause/break key on the 101 keyboard produces:
870 		 * E1-1D-45 E1-9D-C5
871 		 * Ctrl-pause/break produces:
872 		 * E0-46 E0-C6 (See above.)
873 		 */
874 		state->ks_prefix = 0;
875 		if (keycode == 0x1D)
876 			state->ks_prefix = 0x1D;
877 		goto next_code;
878 		/* NOT REACHED */
879 	case 0x1D:	/* pause / break */
880 		state->ks_prefix = 0;
881 		if (keycode != 0x45)
882 			goto next_code;
883 		keycode = 0x68;
884 		break;
885 	}
886 
887 	/* XXX assume 101/102 keys AT keyboard */
888 	switch (keycode) {
889 	case 0x5c:	/* print screen */
890 		if (state->ks_flags & ALTS)
891 			keycode = 0x54;	/* sysrq */
892 		break;
893 	case 0x68:	/* pause/break */
894 		if (state->ks_flags & CTLS)
895 			keycode = 0x6c;	/* break */
896 		break;
897 	}
898 
899 	/* return the key code in the K_CODE mode */
900 	if (state->ks_mode == K_CODE) {
901 		KBDMUX_UNLOCK(state);
902 		return (keycode | (scancode & 0x80));
903 	}
904 
905 	/* compose a character code */
906 	if (state->ks_flags & COMPOSE) {
907 		switch (keycode | (scancode & 0x80)) {
908 		/* key pressed, process it */
909 		case 0x47: case 0x48: case 0x49:	/* keypad 7,8,9 */
910 			state->ks_composed_char *= 10;
911 			state->ks_composed_char += keycode - 0x40;
912 			if (state->ks_composed_char > UCHAR_MAX) {
913 				KBDMUX_UNLOCK(state);
914 				return (ERRKEY);
915 			}
916 			goto next_code;
917 		case 0x4B: case 0x4C: case 0x4D:	/* keypad 4,5,6 */
918 			state->ks_composed_char *= 10;
919 			state->ks_composed_char += keycode - 0x47;
920 			if (state->ks_composed_char > UCHAR_MAX) {
921 				KBDMUX_UNLOCK(state);
922 				return (ERRKEY);
923 			}
924 			goto next_code;
925 		case 0x4F: case 0x50: case 0x51:	/* keypad 1,2,3 */
926 			state->ks_composed_char *= 10;
927 			state->ks_composed_char += keycode - 0x4E;
928 			if (state->ks_composed_char > UCHAR_MAX) {
929 				KBDMUX_UNLOCK(state);
930 				return (ERRKEY);
931 			}
932 			goto next_code;
933 		case 0x52:	/* keypad 0 */
934 			state->ks_composed_char *= 10;
935 			if (state->ks_composed_char > UCHAR_MAX) {
936 				KBDMUX_UNLOCK(state);
937 				return (ERRKEY);
938 			}
939 			goto next_code;
940 
941 		/* key released, no interest here */
942 		case 0xC7: case 0xC8: case 0xC9:	/* keypad 7,8,9 */
943 		case 0xCB: case 0xCC: case 0xCD:	/* keypad 4,5,6 */
944 		case 0xCF: case 0xD0: case 0xD1:	/* keypad 1,2,3 */
945 		case 0xD2:				/* keypad 0 */
946 			goto next_code;
947 
948 		case 0x38:				/* left alt key */
949 			break;
950 
951 		default:
952 			if (state->ks_composed_char > 0) {
953 				state->ks_flags &= ~COMPOSE;
954 				state->ks_composed_char = 0;
955 				KBDMUX_UNLOCK(state);
956 				return (ERRKEY);
957 			}
958 			break;
959 		}
960 	}
961 
962 	/* keycode to key action */
963 	action = genkbd_keyaction(kbd, keycode, scancode & 0x80,
964 			&state->ks_state, &state->ks_accents);
965 	if (action == NOKEY)
966 		goto next_code;
967 
968 	KBDMUX_UNLOCK(state);
969 
970 	return (action);
971 }
972 
973 /*
974  * Check if char is waiting
975  */
976 static int
977 kbdmux_check_char(keyboard_t *kbd)
978 {
979 	kbdmux_state_t	*state = (kbdmux_state_t *) kbd->kb_data;
980 	int		 ready;
981 
982 	if (!KBD_IS_ACTIVE(kbd))
983 		return (FALSE);
984 
985 	KBDMUX_LOCK(state);
986 
987 	if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char != 0))
988 		ready = TRUE;
989 	else
990 		ready = (state->ks_inq_length > 0) ? TRUE : FALSE;
991 
992 	KBDMUX_UNLOCK(state);
993 
994 	return (ready);
995 }
996 
997 /*
998  * Keyboard ioctl's
999  */
1000 static int
1001 kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
1002 {
1003 	static int	 delays[] = {
1004 		250, 500, 750, 1000
1005 	};
1006 
1007 	static int	 rates[]  =  {
1008 		34,  38,  42,  46,  50,   55,  59,  63,
1009 		68,  76,  84,  92,  100, 110, 118, 126,
1010 		136, 152, 168, 184, 200, 220, 236, 252,
1011 		272, 304, 336, 368, 400, 440, 472, 504
1012 	};
1013 
1014 	kbdmux_state_t	*state = (kbdmux_state_t *) kbd->kb_data;
1015 	kbdmux_kbd_t	*k;
1016 	keyboard_info_t	*ki;
1017 	int		 error = 0, mode;
1018 #ifdef COMPAT_FREEBSD6
1019 	int		 ival;
1020 #endif
1021 
1022 	if (state == NULL)
1023 		return (ENXIO);
1024 
1025 	switch (cmd) {
1026 	case KBADDKBD: /* add keyboard to the mux */
1027 		ki = (keyboard_info_t *) arg;
1028 
1029 		if (ki == NULL || ki->kb_unit < 0 || ki->kb_name[0] == '\0' ||
1030 		    strcmp(ki->kb_name, "*") == 0)
1031 			return (EINVAL); /* bad input */
1032 
1033 		KBDMUX_LOCK(state);
1034 
1035 		SLIST_FOREACH(k, &state->ks_kbds, next)
1036 			if (k->kbd->kb_unit == ki->kb_unit &&
1037 			    strcmp(k->kbd->kb_name, ki->kb_name) == 0)
1038 				break;
1039 
1040 		if (k != NULL) {
1041 			KBDMUX_UNLOCK(state);
1042 
1043 			return (0); /* keyboard already in the mux */
1044 		}
1045 
1046 		k = malloc(sizeof(*k), M_KBDMUX, M_NOWAIT | M_ZERO);
1047 		if (k == NULL) {
1048 			KBDMUX_UNLOCK(state);
1049 
1050 			return (ENOMEM); /* out of memory */
1051 		}
1052 
1053 		k->kbd = kbd_get_keyboard(
1054 				kbd_allocate(
1055 					ki->kb_name,
1056 					ki->kb_unit,
1057 					(void *) &k->kbd,
1058 					kbdmux_kbd_event, (void *) state));
1059 		if (k->kbd == NULL) {
1060 			KBDMUX_UNLOCK(state);
1061 			free(k, M_KBDMUX);
1062 
1063 			return (EINVAL); /* bad keyboard */
1064 		}
1065 
1066 		kbdd_enable(k->kbd);
1067 		kbdd_clear_state(k->kbd);
1068 
1069 		/* set K_RAW mode on slave keyboard */
1070 		mode = K_RAW;
1071 		error = kbdd_ioctl(k->kbd, KDSKBMODE, (caddr_t)&mode);
1072 		if (error == 0) {
1073 			/* set lock keys state on slave keyboard */
1074 			mode = state->ks_state & LOCK_MASK;
1075 			error = kbdd_ioctl(k->kbd, KDSKBSTATE, (caddr_t)&mode);
1076 		}
1077 
1078 		if (error != 0) {
1079 			KBDMUX_UNLOCK(state);
1080 
1081 			kbd_release(k->kbd, &k->kbd);
1082 			k->kbd = NULL;
1083 
1084 			free(k, M_KBDMUX);
1085 
1086 			return (error); /* could not set mode */
1087 		}
1088 
1089 		SLIST_INSERT_HEAD(&state->ks_kbds, k, next);
1090 
1091 		KBDMUX_UNLOCK(state);
1092 		break;
1093 
1094 	case KBRELKBD: /* release keyboard from the mux */
1095 		ki = (keyboard_info_t *) arg;
1096 
1097 		if (ki == NULL || ki->kb_unit < 0 || ki->kb_name[0] == '\0' ||
1098 		    strcmp(ki->kb_name, "*") == 0)
1099 			return (EINVAL); /* bad input */
1100 
1101 		KBDMUX_LOCK(state);
1102 
1103 		SLIST_FOREACH(k, &state->ks_kbds, next)
1104 			if (k->kbd->kb_unit == ki->kb_unit &&
1105 			    strcmp(k->kbd->kb_name, ki->kb_name) == 0)
1106 				break;
1107 
1108 		if (k != NULL) {
1109 			error = kbd_release(k->kbd, &k->kbd);
1110 			if (error == 0) {
1111 				SLIST_REMOVE(&state->ks_kbds, k, kbdmux_kbd, next);
1112 
1113 				k->kbd = NULL;
1114 
1115 				free(k, M_KBDMUX);
1116 			}
1117 		} else
1118 			error = ENXIO; /* keyboard is not in the mux */
1119 
1120 		KBDMUX_UNLOCK(state);
1121 		break;
1122 
1123 	case KDGKBMODE: /* get kyboard mode */
1124 		KBDMUX_LOCK(state);
1125 		*(int *)arg = state->ks_mode;
1126 		KBDMUX_UNLOCK(state);
1127 		break;
1128 
1129 #ifdef COMPAT_FREEBSD6
1130 	case _IO('K', 7):
1131 		ival = IOCPARM_IVAL(arg);
1132 		arg = (caddr_t)&ival;
1133 		/* FALLTHROUGH */
1134 #endif
1135 	case KDSKBMODE: /* set keyboard mode */
1136 		KBDMUX_LOCK(state);
1137 
1138 		switch (*(int *)arg) {
1139 		case K_XLATE:
1140 			if (state->ks_mode != K_XLATE) {
1141 				/* make lock key state and LED state match */
1142 				state->ks_state &= ~LOCK_MASK;
1143 				state->ks_state |= KBD_LED_VAL(kbd);
1144                         }
1145                         /* FALLTHROUGH */
1146 
1147 		case K_RAW:
1148 		case K_CODE:
1149 			if (state->ks_mode != *(int *)arg) {
1150 				kbdmux_clear_state_locked(state);
1151 				state->ks_mode = *(int *)arg;
1152 			}
1153 			break;
1154 
1155                 default:
1156 			error = EINVAL;
1157 			break;
1158 		}
1159 
1160 		KBDMUX_UNLOCK(state);
1161 		break;
1162 
1163 	case KDGETLED: /* get keyboard LED */
1164 		KBDMUX_LOCK(state);
1165 		*(int *)arg = KBD_LED_VAL(kbd);
1166 		KBDMUX_UNLOCK(state);
1167 		break;
1168 
1169 #ifdef COMPAT_FREEBSD6
1170 	case _IO('K', 66):
1171 		ival = IOCPARM_IVAL(arg);
1172 		arg = (caddr_t)&ival;
1173 		/* FALLTHROUGH */
1174 #endif
1175 	case KDSETLED: /* set keyboard LED */
1176 		KBDMUX_LOCK(state);
1177 
1178 		/* NOTE: lock key state in ks_state won't be changed */
1179 		if (*(int *)arg & ~LOCK_MASK) {
1180 			KBDMUX_UNLOCK(state);
1181 
1182 			return (EINVAL);
1183 		}
1184 
1185 		KBD_LED_VAL(kbd) = *(int *)arg;
1186 #ifdef EVDEV_SUPPORT
1187 		if (state->ks_evdev != NULL &&
1188 		    evdev_rcpt_mask & EVDEV_RCPT_KBDMUX)
1189 			evdev_push_leds(state->ks_evdev, *(int *)arg);
1190 #endif
1191 		/* KDSETLED on all slave keyboards */
1192 		SLIST_FOREACH(k, &state->ks_kbds, next)
1193 			(void)kbdd_ioctl(k->kbd, KDSETLED, arg);
1194 
1195 		KBDMUX_UNLOCK(state);
1196 		break;
1197 
1198 	case KDGKBSTATE: /* get lock key state */
1199 		KBDMUX_LOCK(state);
1200 		*(int *)arg = state->ks_state & LOCK_MASK;
1201 		KBDMUX_UNLOCK(state);
1202 		break;
1203 
1204 #ifdef COMPAT_FREEBSD6
1205 	case _IO('K', 20):
1206 		ival = IOCPARM_IVAL(arg);
1207 		arg = (caddr_t)&ival;
1208 		/* FALLTHROUGH */
1209 #endif
1210 	case KDSKBSTATE: /* set lock key state */
1211 		KBDMUX_LOCK(state);
1212 
1213 		if (*(int *)arg & ~LOCK_MASK) {
1214 			KBDMUX_UNLOCK(state);
1215 
1216 			return (EINVAL);
1217 		}
1218 
1219 		state->ks_state &= ~LOCK_MASK;
1220 		state->ks_state |= *(int *)arg;
1221 
1222 		/* KDSKBSTATE on all slave keyboards */
1223 		SLIST_FOREACH(k, &state->ks_kbds, next)
1224 			(void)kbdd_ioctl(k->kbd, KDSKBSTATE, arg);
1225 
1226 		KBDMUX_UNLOCK(state);
1227 
1228 		return (kbdmux_ioctl(kbd, KDSETLED, arg));
1229 		/* NOT REACHED */
1230 
1231 #ifdef COMPAT_FREEBSD6
1232 	case _IO('K', 67):
1233 		cmd = KDSETRAD;
1234 		ival = IOCPARM_IVAL(arg);
1235 		arg = (caddr_t)&ival;
1236 		/* FALLTHROUGH */
1237 #endif
1238 	case KDSETREPEAT: /* set keyboard repeat rate (new interface) */
1239 	case KDSETRAD: /* set keyboard repeat rate (old interface) */
1240 		KBDMUX_LOCK(state);
1241 
1242 		if (cmd == KDSETREPEAT) {
1243 			int	i;
1244 
1245 			/* lookup delay */
1246 			for (i = sizeof(delays)/sizeof(delays[0]) - 1; i > 0; i --)
1247 				if (((int *)arg)[0] >= delays[i])
1248 					break;
1249 			mode = i << 5;
1250 
1251 			/* lookup rate */
1252 			for (i = sizeof(rates)/sizeof(rates[0]) - 1; i > 0; i --)
1253 				if (((int *)arg)[1] >= rates[i])
1254 					break;
1255 			mode |= i;
1256 		} else
1257 			mode = *(int *)arg;
1258 
1259 		if (mode & ~0x7f) {
1260 			KBDMUX_UNLOCK(state);
1261 
1262 			return (EINVAL);
1263 		}
1264 
1265 		kbd->kb_delay1 = delays[(mode >> 5) & 3];
1266 		kbd->kb_delay2 = rates[mode & 0x1f];
1267 #ifdef EVDEV_SUPPORT
1268 		if (state->ks_evdev != NULL &&
1269 		    evdev_rcpt_mask & EVDEV_RCPT_KBDMUX)
1270 			evdev_push_repeats(state->ks_evdev, kbd);
1271 #endif
1272 		/* perform command on all slave keyboards */
1273 		SLIST_FOREACH(k, &state->ks_kbds, next)
1274 			(void)kbdd_ioctl(k->kbd, cmd, arg);
1275 
1276 		KBDMUX_UNLOCK(state);
1277 		break;
1278 
1279 	case PIO_KEYMAP:	/* set keyboard translation table */
1280 	case OPIO_KEYMAP:	/* set keyboard translation table (compat) */
1281 	case PIO_KEYMAPENT:	/* set keyboard translation table entry */
1282 	case PIO_DEADKEYMAP:	/* set accent key translation table */
1283 		KBDMUX_LOCK(state);
1284                 state->ks_accents = 0;
1285 
1286 		/* perform command on all slave keyboards */
1287 		SLIST_FOREACH(k, &state->ks_kbds, next)
1288 			(void)kbdd_ioctl(k->kbd, cmd, arg);
1289 
1290 		KBDMUX_UNLOCK(state);
1291                 /* FALLTHROUGH */
1292 
1293 	default:
1294 		error = genkbd_commonioctl(kbd, cmd, arg);
1295 		break;
1296 	}
1297 
1298 	return (error);
1299 }
1300 
1301 /*
1302  * Lock the access to the keyboard
1303  */
1304 static int
1305 kbdmux_lock(keyboard_t *kbd, int lock)
1306 {
1307 	return (1); /* XXX */
1308 }
1309 
1310 /*
1311  * Clear the internal state of the keyboard
1312  */
1313 static void
1314 kbdmux_clear_state_locked(kbdmux_state_t *state)
1315 {
1316 	KBDMUX_LOCK_ASSERT(state, MA_OWNED);
1317 
1318 	state->ks_flags &= ~COMPOSE;
1319 	state->ks_polling = 0;
1320 	state->ks_state &= LOCK_MASK;	/* preserve locking key state */
1321 	state->ks_accents = 0;
1322 	state->ks_composed_char = 0;
1323 /*	state->ks_prefix = 0;		XXX */
1324 	state->ks_inq_length = 0;
1325 }
1326 
1327 static void
1328 kbdmux_clear_state(keyboard_t *kbd)
1329 {
1330 	kbdmux_state_t	*state = (kbdmux_state_t *) kbd->kb_data;
1331 
1332 	KBDMUX_LOCK(state);
1333 	kbdmux_clear_state_locked(state);
1334 	KBDMUX_UNLOCK(state);
1335 }
1336 
1337 /*
1338  * Save the internal state
1339  */
1340 static int
1341 kbdmux_get_state(keyboard_t *kbd, void *buf, size_t len)
1342 {
1343 	if (len == 0)
1344 		return (sizeof(kbdmux_state_t));
1345 	if (len < sizeof(kbdmux_state_t))
1346 		return (-1);
1347 
1348 	bcopy(kbd->kb_data, buf, sizeof(kbdmux_state_t)); /* XXX locking? */
1349 
1350 	return (0);
1351 }
1352 
1353 /*
1354  * Set the internal state
1355  */
1356 static int
1357 kbdmux_set_state(keyboard_t *kbd, void *buf, size_t len)
1358 {
1359 	if (len < sizeof(kbdmux_state_t))
1360 		return (ENOMEM);
1361 
1362 	bcopy(buf, kbd->kb_data, sizeof(kbdmux_state_t)); /* XXX locking? */
1363 
1364 	return (0);
1365 }
1366 
1367 /*
1368  * Set polling
1369  */
1370 static int
1371 kbdmux_poll(keyboard_t *kbd, int on)
1372 {
1373 	kbdmux_state_t	*state = (kbdmux_state_t *) kbd->kb_data;
1374 	kbdmux_kbd_t	*k;
1375 
1376 	KBDMUX_LOCK(state);
1377 
1378 	if (on)
1379 		state->ks_polling++;
1380 	else
1381 		state->ks_polling--;
1382 
1383 	/* set poll on slave keyboards */
1384 	SLIST_FOREACH(k, &state->ks_kbds, next)
1385 		kbdd_poll(k->kbd, on);
1386 
1387 	KBDMUX_UNLOCK(state);
1388 
1389 	return (0);
1390 }
1391 
1392 /*****************************************************************************
1393  *****************************************************************************
1394  **                                    Module
1395  *****************************************************************************
1396  *****************************************************************************/
1397 
1398 KEYBOARD_DRIVER(kbdmux, kbdmuxsw, kbdmux_configure);
1399 
1400 static int
1401 kbdmux_modevent(module_t mod, int type, void *data)
1402 {
1403 	keyboard_switch_t	*sw;
1404 	keyboard_t		*kbd;
1405 	int			 error;
1406 
1407 	switch (type) {
1408 	case MOD_LOAD:
1409 		if ((error = kbd_add_driver(&kbdmux_kbd_driver)) != 0)
1410 			break;
1411 
1412 		if ((sw = kbd_get_switch(KEYBOARD_NAME)) == NULL) {
1413 			kbd_delete_driver(&kbdmux_kbd_driver);
1414 			error = ENXIO;
1415 			break;
1416 		}
1417 
1418 		kbd = NULL;
1419 
1420 		if ((error = (*sw->probe)(0, NULL, 0)) != 0 ||
1421 		    (error = (*sw->init)(0, &kbd, NULL, 0)) != 0) {
1422 			kbd_delete_driver(&kbdmux_kbd_driver);
1423 			break;
1424 		}
1425 
1426 #ifdef KBD_INSTALL_CDEV
1427 		if ((error = kbd_attach(kbd)) != 0) {
1428 			(*sw->term)(kbd);
1429 			kbd_delete_driver(&kbdmux_kbd_driver);
1430 			break;
1431 		}
1432 #endif
1433 
1434 		if ((error = (*sw->enable)(kbd)) != 0) {
1435 			(*sw->disable)(kbd);
1436 #ifdef KBD_INSTALL_CDEV
1437 			kbd_detach(kbd);
1438 #endif
1439 			(*sw->term)(kbd);
1440 			kbd_delete_driver(&kbdmux_kbd_driver);
1441 			break;
1442 		}
1443 		break;
1444 
1445 	case MOD_UNLOAD:
1446 		if ((sw = kbd_get_switch(KEYBOARD_NAME)) == NULL)
1447 			panic("kbd_get_switch(" KEYBOARD_NAME ") == NULL");
1448 
1449 		kbd = kbd_get_keyboard(kbd_find_keyboard(KEYBOARD_NAME, 0));
1450 		if (kbd != NULL) {
1451 			(*sw->disable)(kbd);
1452 #ifdef KBD_INSTALL_CDEV
1453 			kbd_detach(kbd);
1454 #endif
1455 			(*sw->term)(kbd);
1456 			kbd_delete_driver(&kbdmux_kbd_driver);
1457 		}
1458 		error = 0;
1459 		break;
1460 
1461 	default:
1462 		error = EOPNOTSUPP;
1463 		break;
1464 	}
1465 
1466 	return (error);
1467 }
1468 
1469 DEV_MODULE(kbdmux, kbdmux_modevent, NULL);
1470 #ifdef EVDEV_SUPPORT
1471 MODULE_DEPEND(kbdmux, evdev, 1, 1, 1);
1472 #endif
1473