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