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