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