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