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