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