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