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