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