kbdmux - make it work for us
authorAlex Hornung <ahornung@gmail.com>
Wed, 9 Sep 2009 13:54:18 +0000 (14:54 +0100)
committerAlex Hornung <ahornung@gmail.com>
Fri, 11 Sep 2009 06:58:10 +0000 (07:58 +0100)
* port kbdmux to DragonFly.

* change syscons to use kbdmux, if available.

* change kbd to use kbdmux, if available.

* cleanup kbd.

* use a simple buffer instead of clists for kbd.

* move kbd_ macros from syscons.h to kbdregs.h

* use kbd_ macros everywhere instead of unreadable stuff.

* sync ukbd with FreeBSD's latest ukbd before their switch to
  usb4bsd.

Partially-Obtained-from: FreeBSD

sys/conf/files
sys/dev/misc/atkbd/atkbd_isa.c
sys/dev/misc/kbd/atkbd.c
sys/dev/misc/kbd/kbd.c
sys/dev/misc/kbd/kbdreg.h
sys/dev/misc/kbdmux/kbdmux.c
sys/dev/misc/syscons/syscons.c
sys/dev/misc/syscons/syscons.h
sys/dev/usbmisc/ukbd/ukbd.c
sys/sys/kbio.h

index 7275900..2449b83 100644 (file)
@@ -1496,6 +1496,7 @@ bus/isa/isa_common.c              optional isa
 bus/isa/isahint.c              optional isa
 bus/isa/pnpeat.c               optional isa
 dev/misc/joy/joy.c             optional joy
+dev/misc/kbdmux/kbdmux.c       optional kbdmux
 dev/misc/orm/orm.c             optional isa
 bus/isa/pnp.c                  optional isa
 bus/isa/pnpparse.c             optional isa
index 7319ab1..02eaa64 100644 (file)
@@ -125,7 +125,7 @@ atkbdresume(device_t dev)
        kbd = kbd_get_keyboard(kbd_find_keyboard(ATKBD_DRIVER_NAME,
                                                 device_get_unit(dev)));
        if (kbd)
-               (*kbdsw[kbd->kb_index]->clear_state)(kbd);
+               kbd_clear_state(kbd);
        return 0;
 }
 
@@ -135,7 +135,7 @@ atkbd_isa_intr(void *arg)
        keyboard_t *kbd;
 
        kbd = (keyboard_t *)arg;
-       (*kbdsw[kbd->kb_index]->intr)(kbd, NULL);
+       kbd_intr(kbd, NULL);
 }
 
 DRIVER_MODULE(atkbd, atkbdc, atkbd_driver, atkbd_devclass, 0, 0);
index 59de1f7..cb1d0f6 100644 (file)
@@ -149,15 +149,15 @@ atkbd_timeout(void *arg)
         */
        crit_enter();
        kbd = (keyboard_t *)arg;
-       if ((*kbdsw[kbd->kb_index]->lock)(kbd, TRUE)) {
+       if (kbd_lock(kbd, TRUE)) {
                /*
                 * We have seen the lock flag is not set. Let's reset
                 * the flag early, otherwise the LED update routine fails
                 * which may want the lock during the interrupt routine.
                 */
-               (*kbdsw[kbd->kb_index]->lock)(kbd, FALSE);
-               if ((*kbdsw[kbd->kb_index]->check_char)(kbd))
-                       (*kbdsw[kbd->kb_index]->intr)(kbd, NULL);
+               kbd_lock(kbd, FALSE);
+               if (kbd_check_char(kbd))
+                       kbd_intr(kbd, NULL);
        }
        callout_reset(&kbd->kb_atkbd_timeout_ch, hz / 10, atkbd_timeout, arg);
        crit_exit();
index 2e69d3d..c4266d9 100644 (file)
@@ -32,6 +32,7 @@
  * Interrupt note: keyboards use clist functions and since usb keyboard
  * interrupts are not protected by spltty(), we must use a critical section
  * to protect against corruption.
+ * XXX: this keyboard driver doesn't use clist functions anymore!
  */
 
 #include "opt_kbd.h"
 
 #define KBD_INDEX(dev) minor(dev)
 
+#define KB_QSIZE       512
+#define KB_BUFSIZE     64
+
 struct genkbd_softc {
        int             gkb_flags;      /* flag/status bits */
 #define KB_ASLEEP      (1 << 0)
-       struct clist    gkb_q;          /* input queue */
        struct selinfo  gkb_rsel;
+       char            gkb_q[KB_QSIZE];                /* input queue */
+       unsigned int    gkb_q_start;
+       unsigned int    gkb_q_length;
 };
 
 typedef struct genkbd_softc *genkbd_softc_t;
@@ -194,8 +200,12 @@ kbd_register(keyboard_t *kbd)
 {
        const keyboard_driver_t **list;
        const keyboard_driver_t *p;
+       keyboard_t *mux;
+       keyboard_info_t ki;
        int index;
 
+       mux = kbd_get_keyboard(kbd_find_keyboard("kbdmux", -1));
+
        for (index = 0; index < keyboards; ++index) {
                if (keyboard[index] == NULL)
                        break;
@@ -218,6 +228,14 @@ kbd_register(keyboard_t *kbd)
                if (strcmp(p->name, kbd->kb_name) == 0) {
                        keyboard[index] = kbd;
                        kbdsw[index] = p->kbdsw;
+
+                       if (mux != NULL) {
+                               bzero(&ki, sizeof(ki));
+                               strcpy(ki.kb_name, kbd->kb_name);
+                               ki.kb_unit = kbd->kb_unit;
+                               kbd_ioctl(mux, KBADDKBD, (caddr_t) &ki);
+                       }
+
                        return index;
                }
        }
@@ -226,6 +244,14 @@ kbd_register(keyboard_t *kbd)
                if (strcmp(p->name, kbd->kb_name) == 0) {
                        keyboard[index] = kbd;
                        kbdsw[index] = p->kbdsw;
+
+                       if (mux != NULL) {
+                               bzero(&ki, sizeof(ki));
+                               strcpy(ki.kb_name, kbd->kb_name);
+                               ki.kb_unit = kbd->kb_unit;
+                               kbd_ioctl(mux, KBADDKBD, (caddr_t) &ki);
+                       }
+
                        return index;
                }
        }
@@ -291,10 +317,12 @@ kbd_get_switch(char *driver)
  * cdev driver, use these functions to claim and release a keyboard for
  * exclusive use.
  */
-
-/* find the keyboard specified by a driver name and a unit number */
+/*
+ * find the keyboard specified by a driver name and a unit number
+ * starting at given index
+ */
 int
-kbd_find_keyboard(char *driver, int unit)
+kbd_find_keyboard2(char *driver, int unit, int index, int legacy)
 {
        int i;
        int pref;
@@ -303,7 +331,10 @@ kbd_find_keyboard(char *driver, int unit)
        pref = 0;
        pref_index = -1;
 
-       for (i = 0; i < keyboards; ++i) {
+       if ((index < 0) || (index >= keyboards))
+               return (-1);
+
+       for (i = index; i < keyboards; ++i) {
                if (keyboard[i] == NULL)
                        continue;
                if (!KBD_IS_VALID(keyboard[i]))
@@ -312,14 +343,33 @@ kbd_find_keyboard(char *driver, int unit)
                        continue;
                if ((unit != -1) && (keyboard[i]->kb_unit != unit))
                        continue;
-               if (pref <= keyboard[i]->kb_pref) {
-                       pref = keyboard[i]->kb_pref;
-                       pref_index = i;
+               /*
+                * If we are in legacy mode, we do the old preference magic and
+                * don't return on the first found unit.
+                */
+               if (legacy) {
+                       if (pref <= keyboard[i]->kb_pref) {
+                               pref = keyboard[i]->kb_pref;
+                               pref_index = i;
+                       }
+               } else {
+                       return i;
                }
        }
+
+       if (!legacy)
+               KKASSERT(pref_index == -1);
+
        return (pref_index);
 }
 
+/* find the keyboard specified by a driver name and a unit number */
+int
+kbd_find_keyboard(char *driver, int unit)
+{
+       return (kbd_find_keyboard2(driver, unit, 0, 1));
+}
+
 /* allocate a keyboard */
 int
 kbd_allocate(char *driver, int unit, void *id, kbd_callback_func_t *func,
@@ -341,7 +391,7 @@ kbd_allocate(char *driver, int unit, void *id, kbd_callback_func_t *func,
                KBD_BUSY(keyboard[index]);
                keyboard[index]->kb_callback.kc_func = func;
                keyboard[index]->kb_callback.kc_arg = arg;
-               (*kbdsw[index]->clear_state)(keyboard[index]);
+               kbd_clear_state(keyboard[index]);
        }
        crit_exit();
        return index;
@@ -362,7 +412,7 @@ kbd_release(keyboard_t *kbd, void *id)
                KBD_UNBUSY(kbd);
                kbd->kb_callback.kc_func = NULL;
                kbd->kb_callback.kc_arg = NULL;
-               (*kbdsw[kbd->kb_index]->clear_state)(kbd);
+               kbd_clear_state(kbd);
                error = 0;
        }
        crit_exit();
@@ -517,8 +567,38 @@ kbd_detach(keyboard_t *kbd)
  * driver functions.
  */
 
-#define KB_QSIZE       512
-#define KB_BUFSIZE     64
+static void
+genkbd_putc(genkbd_softc_t sc, char c)
+{
+       unsigned int p;
+
+       if (sc->gkb_q_length == KB_QSIZE)
+               return;
+
+       p = (sc->gkb_q_start + sc->gkb_q_length) % KB_QSIZE;
+       sc->gkb_q[p] = c;
+       sc->gkb_q_length++;
+}
+
+static size_t
+genkbd_getc(genkbd_softc_t sc, char *buf, size_t len)
+{
+
+       /* Determine copy size. */
+       if (sc->gkb_q_length == 0)
+               return (0);
+       if (len >= sc->gkb_q_length)
+               len = sc->gkb_q_length;
+       if (len >= KB_QSIZE - sc->gkb_q_start)
+               len = KB_QSIZE - sc->gkb_q_start;
+
+       /* Copy out data and progress offset. */
+       memcpy(buf, sc->gkb_q + sc->gkb_q_start, len);
+       sc->gkb_q_start = (sc->gkb_q_start + len) % KB_QSIZE;
+       sc->gkb_q_length -= len;
+
+       return (len);
+}
 
 static kbd_callback_func_t genkbd_event;
 
@@ -551,12 +631,7 @@ genkbdopen(struct dev_open_args *ap)
         * the device may still be missing (!KBD_HAS_DEVICE(kbd)).
         */
 
-#if 0
-       bzero(&sc->gkb_q, sizeof(sc->gkb_q));
-#endif
-       clist_alloc_cblocks(&sc->gkb_q, KB_QSIZE, KB_QSIZE/2); /* XXX */
-       sc->gkb_rsel.si_flags = 0;
-       sc->gkb_rsel.si_pid = 0;
+       sc->gkb_q_length = 0;
        crit_exit();
 
        return 0;
@@ -580,9 +655,6 @@ genkbdclose(struct dev_close_args *ap)
                /* XXX: we shall be forgiving and don't report error... */
        } else {
                kbd_release(kbd, (void *)sc);
-#if 0
-               clist_free_cblocks(&sc->gkb_q);
-#endif
        }
        crit_exit();
        return 0;
@@ -607,8 +679,8 @@ genkbdread(struct dev_read_args *ap)
                crit_exit();
                return ENXIO;
        }
-       while (sc->gkb_q.c_cc == 0) {
-               if (ap->a_ioflag & IO_NDELAY) {
+       while (sc->gkb_q_length == 0) {
+               if (ap->a_ioflag & IO_NDELAY) { /* O_NONBLOCK? */
                        crit_exit();
                        return EWOULDBLOCK;
                }
@@ -631,8 +703,8 @@ genkbdread(struct dev_read_args *ap)
        error = 0;
        while (uio->uio_resid > 0) {
                len = (int)szmin(uio->uio_resid, sizeof(buffer));
-               len = q_to_b(&sc->gkb_q, buffer, len);
-               if (len == 0)
+               len = genkbd_getc(sc, buffer, len);
+               if (len <= 0)
                        break;
                error = uiomove(buffer, (size_t)len, uio);
                if (error)
@@ -664,7 +736,7 @@ genkbdioctl(struct dev_ioctl_args *ap)
        kbd = kbd_get_keyboard(KBD_INDEX(dev));
        if ((kbd == NULL) || !KBD_IS_VALID(kbd))
                return ENXIO;
-       error = (*kbdsw[kbd->kb_index]->ioctl)(kbd, ap->a_cmd, ap->a_data);
+       error = kbd_ioctl(kbd, ap->a_cmd, ap->a_data);
        if (error == ENOIOCTL)
                error = ENODEV;
        return error;
@@ -685,7 +757,7 @@ genkbdpoll(struct dev_poll_args *ap)
        if ((sc == NULL) || (kbd == NULL) || !KBD_IS_VALID(kbd)) {
                revents =  POLLHUP;     /* the keyboard has gone */
        } else if (ap->a_events & (POLLIN | POLLRDNORM)) {
-               if (sc->gkb_q.c_cc > 0)
+               if (sc->gkb_q_length > 0)
                        revents = ap->a_events & (POLLIN | POLLRDNORM);
                else
                        selrecord(curthread, &sc->gkb_rsel);
@@ -724,12 +796,12 @@ genkbd_event(keyboard_t *kbd, int event, void *arg)
        }
 
        /* obtain the current key input mode */
-       if ((*kbdsw[kbd->kb_index]->ioctl)(kbd, KDGKBMODE, (caddr_t)&mode))
+       if (kbd_ioctl(kbd, KDGKBMODE, (caddr_t)&mode))
                mode = K_XLATE;
 
        /* read all pending input */
-       while ((*kbdsw[kbd->kb_index]->check_char)(kbd)) {
-               c = (*kbdsw[kbd->kb_index]->read_char)(kbd, FALSE);
+       while (kbd_check_char(kbd)) {
+               c = kbd_read_char(kbd, FALSE);
                if (c == NOKEY)
                        continue;
                if (c == ERRKEY)        /* XXX: ring bell? */
@@ -740,7 +812,7 @@ genkbd_event(keyboard_t *kbd, int event, void *arg)
 
                /* store the byte as is for K_RAW and K_CODE modes */
                if (mode != K_XLATE) {
-                       clist_putc(KEYCHAR(c), &sc->gkb_q);
+                       genkbd_putc(sc, KEYCHAR(c));
                        continue;
                }
 
@@ -755,9 +827,9 @@ genkbd_event(keyboard_t *kbd, int event, void *arg)
                                /* ignore them... */
                                continue;
                        case BTAB:      /* a backtab: ESC [ Z */
-                               clist_putc(0x1b, &sc->gkb_q);
-                               clist_putc('[', &sc->gkb_q);
-                               clist_putc('Z', &sc->gkb_q);
+                               genkbd_putc(sc, 0x1b);
+                               genkbd_putc(sc, '[');
+                               genkbd_putc(sc, 'Z');
                                continue;
                        }
                }
@@ -765,25 +837,24 @@ genkbd_event(keyboard_t *kbd, int event, void *arg)
                /* normal chars, normal chars with the META, function keys */
                switch (KEYFLAGS(c)) {
                case 0:                 /* a normal char */
-                       clist_putc(KEYCHAR(c), &sc->gkb_q);
+                       genkbd_putc(sc, KEYCHAR(c));
                        break;
                case MKEY:              /* the META flag: prepend ESC */
-                       clist_putc(0x1b, &sc->gkb_q);
-                       clist_putc(KEYCHAR(c), &sc->gkb_q);
+                       genkbd_putc(sc, 0x1b);
+                       genkbd_putc(sc, KEYCHAR(c));
                        break;
                case FKEY | SPCLKEY:    /* a function key, return string */
-                       cp = (*kbdsw[kbd->kb_index]->get_fkeystr)(kbd,
-                                                       KEYCHAR(c), &len);
+                       cp = kbd_get_fkeystr(kbd, KEYCHAR(c), &len);
                        if (cp != NULL) {
                                while (len-- >  0)
-                                       clist_putc(*cp++, &sc->gkb_q);
+                                       genkbd_putc(sc, *cp++);
                        }
                        break;
                }
        }
 
        /* wake up sleeping/polling processes */
-       if (sc->gkb_q.c_cc > 0) {
+       if (sc->gkb_q_length > 0) {
                if (sc->gkb_flags & KB_ASLEEP) {
                        sc->gkb_flags &= ~KB_ASLEEP;
                        wakeup((caddr_t)sc);
@@ -973,7 +1044,7 @@ genkbd_diag(keyboard_t *kbd, int level)
                (s) |= l ## DOWN;                               \
                (s) ^= l ## ED;                                 \
                i = (s) & LOCK_MASK;                            \
-               (*kbdsw[(k)->kb_index]->ioctl)((k), KDSETLED, (caddr_t)&i); \
+               kbd_ioctl((k), KDSETLED, (caddr_t)&i); \
        }
 
 static u_int
index cc126c2..b97527c 100644 (file)
@@ -62,6 +62,7 @@ struct keyboard {
 #define KB_INITIALIZED (1 << 19)       /* device initialized */
 #define KB_REGISTERED  (1 << 20)       /* device registered to kbdio */
 #define KB_BUSY                (1 << 21)       /* device used by a client */
+#define KB_POLLED      (1 << 22)       /* device is polled */
        int             kb_active;      /* 0: inactive */
        void            *kb_token;      /* id of the current client */
        keyboard_callback_t kb_callback;/* callback function */
@@ -114,6 +115,9 @@ struct keyboard {
 #define KBD_IS_BUSY(k)         ((k)->kb_flags & KB_BUSY)
 #define KBD_BUSY(k)            ((k)->kb_flags |= KB_BUSY)
 #define KBD_UNBUSY(k)          ((k)->kb_flags &= ~KB_BUSY)
+#define KBD_IS_POLLED(k)       ((k)->kb_flags & KB_POLLED)
+#define KBD_POLL(k)            ((k)->kb_flags |= KB_POLLED)
+#define KBD_UNPOLL(k)          ((k)->kb_flags &= ~KB_POLLED)
 #define KBD_IS_ACTIVE(k)       ((k)->kb_active)
 #define KBD_ACTIVATE(k)                (++(k)->kb_active)
 #define KBD_DEACTIVATE(k)      (--(k)->kb_active)
@@ -164,6 +168,50 @@ typedef struct keyboard_switch {
        kbd_diag_t      *diag;
 } keyboard_switch_t;
 
+/*
+ * Keyboard disciplines: call actual handlers via kbdsw[].
+ */
+#define kbd_probe(kbd, unit, arg, flags)                               \
+       (*kbdsw[(kbd)->kb_index]->probe)((unit), (arg), (flags))
+#define kbd_init(kbd, unit, kbdpp, arg, flags)                         \
+       (*kbdsw[(kbd)->kb_index]->init)((unit), (kbdpp), (arg), (flags))
+#define kbd_term(kbd)                                                  \
+       (*kbdsw[(kbd)->kb_index]->term)((kbd))
+#define kbd_intr(kbd, arg)                                             \
+       (*kbdsw[(kbd)->kb_index]->intr)((kbd), (arg))
+#define kbd_test_if(kbd)                                               \
+       (*kbdsw[(kbd)->kb_index]->test_if)((kbd))
+#define kbd_enable(kbd)                                                \
+       (*kbdsw[(kbd)->kb_index]->enable)((kbd))
+#define kbd_disable(kbd)                                               \
+       (*kbdsw[(kbd)->kb_index]->disable)((kbd))
+#define kbd_read(kbd, wait)                                            \
+       (*kbdsw[(kbd)->kb_index]->read)((kbd), (wait))
+#define kbd_check(kbd)                                                 \
+       (*kbdsw[(kbd)->kb_index]->check)((kbd))
+#define kbd_read_char(kbd, wait)                                       \
+       (*kbdsw[(kbd)->kb_index]->read_char)((kbd), (wait))
+#define kbd_check_char(kbd)                                            \
+       (*kbdsw[(kbd)->kb_index]->check_char)((kbd))
+#define kbd_ioctl(kbd, cmd, arg)                                       \
+       (((kbd) == NULL) ?                                              \
+           ENODEV :                                                    \
+           (*kbdsw[(kbd)->kb_index]->ioctl)((kbd), (cmd), (arg)))
+#define kbd_lock(kbd, lockf)                                           \
+       (*kbdsw[(kbd)->kb_index]->lock)((kbd), (lockf))
+#define kbd_clear_state(kbd)                                           \
+       (*kbdsw[(kbd)->kb_index]->clear_state)((kbd))
+#define kbd_get_state(kbd, buf, len)                                   \
+       (*kbdsw[(kbd)->kb_index]->get_state)((kbd), (buf), (len))
+#define kbd_set_state(kbd, buf, len)                                   \
+       (*kbdsw[(kbd)->kb_index]->set_state)((kbd), (buf), (len))
+#define kbd_get_fkeystr(kbd, fkey, len)                                \
+       (*kbdsw[(kbd)->kb_index]->get_fkeystr)((kbd), (fkey), (len))
+#define kbd_poll(kbd, on)                                              \
+       (*kbdsw[(kbd)->kb_index]->poll)((kbd), (on))
+#define kbd_diag(kbd, level)                                           \
+       (*kbdsw[(kbd)->kb_index]->diag)((kbd), (leve))
+
 /* keyboard driver */
 typedef struct keyboard_driver {
     SLIST_ENTRY(keyboard_driver) link;
@@ -205,6 +253,7 @@ int                 kbd_release(keyboard_t *kbd, void *id);
 int                    kbd_change_callback(keyboard_t *kbd, void *id,
                                     kbd_callback_func_t *func, void *arg);
 int                    kbd_find_keyboard(char *driver, int unit);
+int                    kbd_find_keyboard2(char *driver, int unit, int index, int legacy);
 keyboard_t             *kbd_get_keyboard(int index);
 
 /* a back door for the console driver to tickle the keyboard driver XXX */
@@ -255,6 +304,7 @@ int                 kbd_detach(keyboard_t *kbd);
 #define LED_MASK       (LED_CAP | LED_NUM | LED_SCR)
 */
 
+#define KB_PRI_MUX     10
 #define KB_PRI_ATKBD   50
 #define KB_PRI_USB     60
 
index 26afbe4..1ec93e6 100644 (file)
@@ -31,9 +31,6 @@
  * $FreeBSD$
  */
 
-#include "opt_compat.h"
-#include "opt_kbd.h"
-
 #include <sys/param.h>
 #include <sys/bus.h>
 #include <sys/conf.h>
@@ -53,8 +50,8 @@
 #include <sys/systm.h>
 #include <sys/taskqueue.h>
 #include <sys/uio.h>
-#include <dev/kbd/kbdreg.h>
-#include <dev/kbd/kbdtables.h>
+#include <dev/misc/kbd/kbdreg.h>
+#include <dev/misc/kbd/kbdtables.h>
 
 #define KEYBOARD_NAME  "kbdmux"
 
@@ -75,9 +72,12 @@ MALLOC_DEFINE(M_KBDMUX, KEYBOARD_NAME, "Keyboard multiplexor");
  * Just like the rest of keyboard drivers and syscons(4) do.
  * Note that callout is initialized as not MP-safe to make sure
  * Giant is held.
+ * XXX: I don't think we are MP-Safing the callout, maybe we
+ *      should, using get_mplock() around it? NFI
  */
 
 #if 0 /* not yet */
+#error "This stuff still needs porting!"
 #define KBDMUX_LOCK_DECL_GLOBAL \
        struct mtx ks_lock
 #define KBDMUX_LOCK_INIT(s) \
@@ -95,7 +95,7 @@ MALLOC_DEFINE(M_KBDMUX, KEYBOARD_NAME, "Keyboard multiplexor");
 #define KBDMUX_CALLOUT_INIT(s) \
        callout_init_mtx(&(s)->ks_timo, &(s)->ks_lock, 0)
 #define KBDMUX_QUEUE_INTR(s) \
-       taskqueue_enqueue(taskqueue_swi_giant, &(s)->ks_task)
+       taskqueue_enqueue(taskqueue_swi, &(s)->ks_task)
 #else
 #define KBDMUX_LOCK_DECL_GLOBAL
 
@@ -110,11 +110,11 @@ MALLOC_DEFINE(M_KBDMUX, KEYBOARD_NAME, "Keyboard multiplexor");
 #define KBDMUX_LOCK_ASSERT(s, w)
 
 #define KBDMUX_SLEEP(s, f, d, t) \
-       tsleep(&(s)->f, PCATCH | (PZERO + 1), (d), (t))
+       tsleep(&(s)->f, PCATCH | (84 + 1), (d), (t))
 #define KBDMUX_CALLOUT_INIT(s) \
-       callout_init(&(s)->ks_timo, 0)
+       callout_init(&(s)->ks_timo)
 #define KBDMUX_QUEUE_INTR(s) \
-       taskqueue_enqueue(taskqueue_swi_giant, &(s)->ks_task)
+       taskqueue_enqueue(taskqueue_swi, &(s)->ks_task)
 #endif /* not yet */
 
 /*
@@ -205,7 +205,7 @@ kbdmux_kbd_intr(void *xkbd, int pending)
        keyboard_t      *kbd = (keyboard_t *) xkbd;
        kbdmux_state_t  *state = (kbdmux_state_t *) kbd->kb_data;
 
-       kbdd_intr(kbd, NULL);
+       kbd_intr(kbd, NULL);
 
        KBDMUX_LOCK(state);
 
@@ -266,8 +266,8 @@ kbdmux_kbd_event(keyboard_t *kbd, int event, void *arg)
                 * NOKEY.
                 */
 
-               while (kbdd_check_char(kbd)) {
-                       c = kbdd_read_char(kbd, 0);
+               while (kbd_check_char(kbd)) {
+                       c = kbd_read_char(kbd, 0);
                        if (c == NOKEY)
                                break;
                        if (c == ERRKEY)
@@ -301,7 +301,7 @@ kbdmux_kbd_event(keyboard_t *kbd, int event, void *arg)
 
                        k->kbd = NULL;
 
-                       free(k, M_KBDMUX);
+                       kfree(k, M_KBDMUX);
                }
 
                KBDMUX_UNLOCK(state);
@@ -398,11 +398,11 @@ kbdmux_init(int unit, keyboard_t **kbdp, void *arg, int flags)
        int              error, needfree, fkeymap_size, delay[2];
 
        if (*kbdp == NULL) {
-               *kbdp = kbd = malloc(sizeof(*kbd), M_KBDMUX, M_NOWAIT | M_ZERO);
-               state = malloc(sizeof(*state), M_KBDMUX, M_NOWAIT | M_ZERO);
-               keymap = malloc(sizeof(key_map), M_KBDMUX, M_NOWAIT);
-               accmap = malloc(sizeof(accent_map), M_KBDMUX, M_NOWAIT);
-               fkeymap = malloc(sizeof(fkey_tab), M_KBDMUX, M_NOWAIT);
+               *kbdp = kbd = kmalloc(sizeof(*kbd), M_KBDMUX, M_NOWAIT | M_ZERO);
+               state = kmalloc(sizeof(*state), M_KBDMUX, M_NOWAIT | M_ZERO);
+               keymap = kmalloc(sizeof(key_map), M_KBDMUX, M_NOWAIT);
+               accmap = kmalloc(sizeof(accent_map), M_KBDMUX, M_NOWAIT);
+               fkeymap = kmalloc(sizeof(fkey_tab), M_KBDMUX, M_NOWAIT);
                fkeymap_size = sizeof(fkey_tab)/sizeof(fkey_tab[0]);
                needfree = 1;
 
@@ -430,7 +430,8 @@ kbdmux_init(int unit, keyboard_t **kbdp, void *arg, int flags)
 
        if (!KBD_IS_PROBED(kbd)) {
                /* XXX assume 101/102 keys keyboard */
-               kbd_init_struct(kbd, KEYBOARD_NAME, KB_101, unit, flags, 0, 0);
+               kbd_init_struct(kbd, KEYBOARD_NAME, KB_101, unit, flags,
+                           KB_PRI_MUX, 0, 0);
                bcopy(&key_map, keymap, sizeof(key_map));
                bcopy(&accent_map, accmap, sizeof(accent_map));
                bcopy(fkey_tab, fkeymap,
@@ -476,15 +477,15 @@ kbdmux_init(int unit, keyboard_t **kbdp, void *arg, int flags)
 bad:
        if (needfree) {
                if (state != NULL)
-                       free(state, M_KBDMUX);
+                       kfree(state, M_KBDMUX);
                if (keymap != NULL)
-                       free(keymap, M_KBDMUX);
+                       kfree(keymap, M_KBDMUX);
                if (accmap != NULL)
-                       free(accmap, M_KBDMUX);
+                       kfree(accmap, M_KBDMUX);
                if (fkeymap != NULL)
-                       free(fkeymap, M_KBDMUX);
+                       kfree(fkeymap, M_KBDMUX);
                if (kbd != NULL) {
-                       free(kbd, M_KBDMUX);
+                       kfree(kbd, M_KBDMUX);
                        *kbdp = NULL;   /* insure ref doesn't leak to caller */
                }
        }
@@ -517,7 +518,7 @@ kbdmux_term(keyboard_t *kbd)
 
                k->kbd = NULL;
 
-               free(k, M_KBDMUX);
+               kfree(k, M_KBDMUX);
        }
 
        KBDMUX_UNLOCK(state);
@@ -526,12 +527,12 @@ kbdmux_term(keyboard_t *kbd)
 
        KBDMUX_LOCK_DESTROY(state);
        bzero(state, sizeof(*state));
-       free(state, M_KBDMUX);
+       kfree(state, M_KBDMUX);
 
-       free(kbd->kb_keymap, M_KBDMUX);
-       free(kbd->kb_accentmap, M_KBDMUX);
-       free(kbd->kb_fkeytab, M_KBDMUX);
-       free(kbd, M_KBDMUX);
+       kfree(kbd->kb_keymap, M_KBDMUX);
+       kfree(kbd->kb_accentmap, M_KBDMUX);
+       kfree(kbd->kb_fkeytab, M_KBDMUX);
+       kfree(kbd, M_KBDMUX);
 
        return (0);
 }
@@ -662,8 +663,8 @@ next_code:
                        kbdmux_kbd_t    *k;
 
                        SLIST_FOREACH(k, &state->ks_kbds, next) {
-                               while (kbdd_check_char(k->kbd)) {
-                                       scancode = kbdd_read_char(k->kbd, 0);
+                               while (kbd_check_char(k->kbd)) {
+                                       scancode = kbd_read_char(k->kbd, 0);
                                        if (scancode == NOKEY)
                                                break;
                                        if (scancode == ERRKEY)
@@ -944,9 +945,6 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
        kbdmux_kbd_t    *k;
        keyboard_info_t *ki;
        int              error = 0, mode;
-#ifdef COMPAT_FREEBSD6
-       int              ival;
-#endif
 
        if (state == NULL)
                return (ENXIO);
@@ -972,7 +970,7 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
                        return (0); /* keyboard already in the mux */
                }
 
-               k = malloc(sizeof(*k), M_KBDMUX, M_NOWAIT | M_ZERO);
+               k = kmalloc(sizeof(*k), M_KBDMUX, M_NOWAIT | M_ZERO);
                if (k == NULL) {
                        KBDMUX_UNLOCK(state);
 
@@ -987,21 +985,21 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
                                        kbdmux_kbd_event, (void *) state));
                if (k->kbd == NULL) {
                        KBDMUX_UNLOCK(state);
-                       free(k, M_KBDMUX);
+                       kfree(k, M_KBDMUX);
 
                        return (EINVAL); /* bad keyboard */
                }
 
-               kbdd_enable(k->kbd);
-               kbdd_clear_state(k->kbd);
+               kbd_enable(k->kbd);
+               kbd_clear_state(k->kbd);
 
                /* set K_RAW mode on slave keyboard */
                mode = K_RAW;
-               error = kbdd_ioctl(k->kbd, KDSKBMODE, (caddr_t)&mode);
+               error = kbd_ioctl(k->kbd, KDSKBMODE, (caddr_t)&mode);
                if (error == 0) {
                        /* set lock keys state on slave keyboard */
                        mode = state->ks_state & LOCK_MASK;
-                       error = kbdd_ioctl(k->kbd, KDSKBSTATE, (caddr_t)&mode);
+                       error = kbd_ioctl(k->kbd, KDSKBSTATE, (caddr_t)&mode);
                }
 
                if (error != 0) {
@@ -1010,7 +1008,7 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
                        kbd_release(k->kbd, &k->kbd);
                        k->kbd = NULL;
 
-                       free(k, M_KBDMUX);
+                       kfree(k, M_KBDMUX);
 
                        return (error); /* could not set mode */
                }
@@ -1041,7 +1039,7 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
 
                                k->kbd = NULL;
 
-                               free(k, M_KBDMUX);
+                               kfree(k, M_KBDMUX);
                        }
                } else
                        error = ENXIO; /* keyboard is not in the mux */
@@ -1055,12 +1053,6 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
                KBDMUX_UNLOCK(state);
                break;
 
-#ifdef COMPAT_FREEBSD6
-       case _IO('K', 7):
-               ival = IOCPARM_IVAL(arg);
-               arg = (caddr_t)&ival;
-               /* FALLTHROUGH */
-#endif
        case KDSKBMODE: /* set keyboard mode */
                KBDMUX_LOCK(state);
 
@@ -1095,12 +1087,6 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
                KBDMUX_UNLOCK(state);
                break;
 
-#ifdef COMPAT_FREEBSD6
-       case _IO('K', 66):
-               ival = IOCPARM_IVAL(arg);
-               arg = (caddr_t)&ival;
-               /* FALLTHROUGH */
-#endif
        case KDSETLED: /* set keyboard LED */
                KBDMUX_LOCK(state);
 
@@ -1115,7 +1101,7 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
 
                /* KDSETLED on all slave keyboards */
                SLIST_FOREACH(k, &state->ks_kbds, next)
-                       kbdd_ioctl(k->kbd, KDSETLED, arg);
+                       kbd_ioctl(k->kbd, KDSETLED, arg);
 
                KBDMUX_UNLOCK(state);
                break;
@@ -1126,12 +1112,6 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
                KBDMUX_UNLOCK(state);
                break;
 
-#ifdef COMPAT_FREEBSD6
-       case _IO('K', 20):
-               ival = IOCPARM_IVAL(arg);
-               arg = (caddr_t)&ival;
-               /* FALLTHROUGH */
-#endif
        case KDSKBSTATE: /* set lock key state */
                KBDMUX_LOCK(state);
 
@@ -1146,20 +1126,13 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
 
                /* KDSKBSTATE on all slave keyboards */
                SLIST_FOREACH(k, &state->ks_kbds, next)
-                       kbdd_ioctl(k->kbd, KDSKBSTATE, arg);
+                       kbd_ioctl(k->kbd, KDSKBSTATE, arg);
 
                KBDMUX_UNLOCK(state);
 
                return (kbdmux_ioctl(kbd, KDSETLED, arg));
                /* NOT REACHED */
 
-#ifdef COMPAT_FREEBSD6
-       case _IO('K', 67):
-               cmd = KDSETRAD;
-               ival = IOCPARM_IVAL(arg);
-               arg = (caddr_t)&ival;
-               /* FALLTHROUGH */
-#endif
        case KDSETREPEAT: /* set keyboard repeat rate (new interface) */
        case KDSETRAD: /* set keyboard repeat rate (old interface) */
                KBDMUX_LOCK(state);
@@ -1192,7 +1165,7 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
 
                /* perform command on all slave keyboards */
                SLIST_FOREACH(k, &state->ks_kbds, next)
-                       kbdd_ioctl(k->kbd, cmd, arg);
+                       kbd_ioctl(k->kbd, cmd, arg);
 
                KBDMUX_UNLOCK(state);
                break;
@@ -1205,7 +1178,7 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
 
                /* perform command on all slave keyboards */
                SLIST_FOREACH(k, &state->ks_kbds, next)
-                       kbdd_ioctl(k->kbd, cmd, arg);
+                       kbd_ioctl(k->kbd, cmd, arg);
 
                KBDMUX_UNLOCK(state);
                 /* FALLTHROUGH */
@@ -1301,7 +1274,7 @@ kbdmux_poll(keyboard_t *kbd, int on)
 
        /* set poll on slave keyboards */
        SLIST_FOREACH(k, &state->ks_kbds, next)
-               kbdd_poll(k->kbd, on);
+               kbd_poll(k->kbd, on);
 
        KBDMUX_UNLOCK(state);
 
index 3d056d2..95cbc53 100644 (file)
@@ -180,6 +180,7 @@ static int save_kbd_state(scr_stat *scp);
 static int update_kbd_state(scr_stat *scp, int state, int mask);
 static int update_kbd_leds(scr_stat *scp, int which);
 static timeout_t blink_screen;
+static int sc_allocate_keyboard(sc_softc_t *sc, int unit);
 
 #define        CDEV_MAJOR      12
 
@@ -1120,6 +1121,13 @@ scioctl(struct dev_ioctl_args *ap)
        *(int *)data = scp->status & LED_MASK;
        return 0;
 
+       case KBADDKBD:              /* add/remove keyboard to/from mux */
+       case KBRELKBD:
+               error = kbd_ioctl(sc->kbd, cmd, data);
+               if (error == ENOIOCTL)
+                       error = ENODEV;
+               return error;
+
     case CONS_SETKBD:          /* set the new keyboard */
        {
            keyboard_t *newkbd;
@@ -1609,8 +1617,7 @@ scrn_timer(void *arg)
     if ((sc->kbd == NULL) && (sc->config & SC_AUTODETECT_KBD)) {
        /* try to allocate a keyboard automatically */
        if (++kbd_interval >= 25) {
-           sc->keyboard = kbd_allocate("*", -1, (void *)&sc->keyboard,
-                                       sckbdevent, sc);
+           sc->keyboard = sc_allocate_keyboard(sc, -1);
            if (sc->keyboard >= 0) {
                sc->kbd = kbd_get_keyboard(sc->keyboard);
                kbd_ioctl(sc->kbd, KDSKBMODE,
@@ -2513,8 +2520,7 @@ scinit(int unit, int flags)
     sc->adapter = vid_allocate("*", unit, (void *)&sc->adapter);
     sc->adp = vid_get_adapter(sc->adapter);
     /* assert((sc->adapter >= 0) && (sc->adp != NULL)) */
-    sc->keyboard = kbd_allocate("*", unit, (void *)&sc->keyboard,
-                               sckbdevent, sc);
+    sc->keyboard = sc_allocate_keyboard(sc, unit);
     DPRINTF(1, ("sc%d: keyboard %d\n", unit, sc->keyboard));
     sc->kbd = kbd_get_keyboard(sc->keyboard);
     if (sc->kbd != NULL) {
@@ -3466,3 +3472,41 @@ blink_screen(void *arg)
        callout_reset(&scp->blink_screen_ch, hz / 10, blink_screen, scp);
     }
 }
+
+
+/*
+ * Allocate active keyboard. Try to allocate "kbdmux" keyboard first, and,
+ * if found, add all non-busy keyboards to "kbdmux". Otherwise look for
+ * any keyboard.
+ */
+
+static int
+sc_allocate_keyboard(sc_softc_t *sc, int unit)
+{
+       int              idx0, idx;
+       keyboard_t      *k0, *k;
+       keyboard_info_t  ki;
+
+       idx0 = kbd_allocate("kbdmux", -1, (void *)&sc->keyboard, sckbdevent, sc);
+       if (idx0 != -1) {
+               k0 = kbd_get_keyboard(idx0);
+
+               for (idx = kbd_find_keyboard2("*", -1, 0, 0);
+                    idx != -1;
+                    idx = kbd_find_keyboard2("*", -1, idx + 1, 0)) {
+                       k = kbd_get_keyboard(idx);
+
+                       if (idx == idx0 || KBD_IS_BUSY(k))
+                               continue;
+
+                       bzero(&ki, sizeof(ki));
+                       strcpy(ki.kb_name, k->kb_name);
+                       ki.kb_unit = k->kb_unit;
+
+                       kbd_ioctl(k0, KBADDKBD, (caddr_t) &ki);
+               }
+       } else
+               idx0 = kbd_allocate("*", unit, (void *)&sc->keyboard, sckbdevent, sc);
+
+       return (idx0);
+}
index 3f0b114..a1a6096 100644 (file)
@@ -495,26 +495,6 @@ typedef struct {
 
 #define ISSIGVALID(sig)        ((sig) > 0 && (sig) < NSIG)
 
-#define kbd_read_char(kbd, wait)                                       \
-               (*kbdsw[(kbd)->kb_index]->read_char)((kbd), (wait))
-#define kbd_check_char(kbd)                                            \
-               (*kbdsw[(kbd)->kb_index]->check_char)((kbd))
-#define kbd_enable(kbd)                                                        \
-               (*kbdsw[(kbd)->kb_index]->enable)((kbd))
-#define kbd_disable(kbd)                                               \
-               (*kbdsw[(kbd)->kb_index]->disable)((kbd))
-#define kbd_lock(kbd, lockf)                                           \
-               (*kbdsw[(kbd)->kb_index]->lock)((kbd), (lockf))
-#define kbd_ioctl(kbd, cmd, arg)                                       \
-           (((kbd) == NULL) ?                                          \
-               ENODEV : (*kbdsw[(kbd)->kb_index]->ioctl)((kbd), (cmd), (arg)))
-#define kbd_clear_state(kbd)                                           \
-               (*kbdsw[(kbd)->kb_index]->clear_state)((kbd))
-#define kbd_get_fkeystr(kbd, fkey, len)                                        \
-               (*kbdsw[(kbd)->kb_index]->get_fkeystr)((kbd), (fkey), (len))
-#define kbd_poll(kbd, on)                                              \
-               (*kbdsw[(kbd)->kb_index]->poll)((kbd), (on))
-
 /* syscons.c */
 int            sc_probe_unit(int unit, int flags);
 int            sc_attach_unit(int unit, int flags);
index a4537ce..e895d90 100644 (file)
@@ -119,7 +119,6 @@ typedef void usbd_disco_t(void *);
 static int             ukbd_resume(device_t self);
 static usbd_intr_t     ukbd_intr;
 static int             ukbd_driver_load(module_t mod, int what, void *arg);
-static int             ukbd_default_term(keyboard_t *kbd);
 
 static keyboard_t      default_kbd;
 
@@ -177,12 +176,12 @@ ukbd_attach(device_t self)
        void *arg[2];
        int unit = device_get_unit(self);
 
+       sc->sc_dev = self;
+
        sw = kbd_get_switch(DRIVER_NAME);
        if (sw == NULL)
                return ENXIO;
 
-       sc->sc_dev = self;
-
        arg[0] = (void *)uaa;
        arg[1] = (void *)ukbd_intr;
        kbd = NULL;
@@ -214,22 +213,16 @@ ukbd_detach(device_t self)
                DPRINTF(("%s: keyboard not attached!?\n", device_get_nameunit(self)));
                return ENXIO;
        }
-       (*kbdsw[kbd->kb_index]->disable)(kbd);
+       kbd_disable(kbd);
 
 #ifdef KBD_INSTALL_CDEV
-       if (kbd != &default_kbd) {
-               error = kbd_detach(kbd);
-               if (error)
-                       return error;
-       }
+       error = kbd_detach(kbd);
+       if (error)
+               return error;
 #endif
-       if (kbd == &default_kbd) {
-               ukbd_default_term(kbd);
-       } else {
-               error = (*kbdsw[kbd->kb_index]->term)(kbd);
-               if (error)
-                       return error;
-       }
+       error = kbd_term(kbd);
+       if (error)
+               return error;
 
        DPRINTF(("%s: disconnected\n", device_get_nameunit(self)));
 
@@ -244,7 +237,7 @@ ukbd_resume(device_t self)
        kbd = kbd_get_keyboard(kbd_find_keyboard(DRIVER_NAME,
                                                 device_get_unit(self)));
        if (kbd)
-               (*kbdsw[kbd->kb_index]->clear_state)(kbd);
+               kbd_clear_state(kbd);
        return (0);
 }
 
@@ -253,7 +246,7 @@ ukbd_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
 {
        keyboard_t *kbd = (keyboard_t *)addr;
 
-       (*kbdsw[kbd->kb_index]->intr)(kbd, (void *)status);
+       kbd_intr(kbd, (void *)status);
 }
 
 DRIVER_MODULE(ukbd, uhub, ukbd_driver, ukbd_devclass, ukbd_driver_load, 0);
@@ -317,11 +310,11 @@ static u_int8_t ukbd_trtab[256] = {
         104, 102,  94,  96, 103,  99, 101,  98, /* 48 - 4F */
          97, 100,  95,  69,  91,  55,  74,  78, /* 50 - 57 */
          89,  79,  80,  81,  75,  76,  77,  71, /* 58 - 5F */
-          72,  73,  82,  83,  86, 107,  NN,  NN, /* 60 - 67 */
+          72,  73,  82,  83,  86, 107, 122,  NN, /* 60 - 67 */
           NN,  NN,  NN,  NN,  NN,  NN,  NN,  NN, /* 68 - 6F */
-          NN,  NN,  NN,  NN,  NN,  NN,  NN,  NN, /* 70 - 77 */
-          NN,  NN,  NN,  NN,  NN,  NN,  NN,  NN, /* 78 - 7F */
-          NN,  NN,  NN,  NN,  NN,  NN,  NN, 115, /* 80 - 87 */
+          NN,  NN,  NN,  NN, 115, 108, 111, 113, /* 70 - 77 */
+          109, 110, 112, 118, 114, 116, 117, 119, /* 78 - 7F */
+          121, 120,  NN,  NN,  NN,  NN,  NN, 115, /* 80 - 87 */
          112, 125, 121, 123,  NN,  NN,  NN,  NN, /* 88 - 8F */
           NN,  NN,  NN,  NN,  NN,  NN,  NN,  NN, /* 90 - 97 */
           NN,  NN,  NN,  NN,  NN,  NN,  NN,  NN, /* 98 - 9F */
@@ -571,13 +564,9 @@ ukbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
        }
 
        if (!KBD_IS_PROBED(kbd)) {
-               if (KBD_IS_CONFIGURED(kbd)) {
-                       kbd_reinit_struct(kbd, flags, KB_PRI_USB);
-               } else {
-                       kbd_init_struct(kbd, DRIVER_NAME, KB_OTHER, 
-                                       unit, flags, KB_PRI_USB,
-                                       0, 0);
-               }
+               kbd_init_struct(kbd, DRIVER_NAME, KB_OTHER,
+                               unit, flags, KB_PRI_USB,
+                               0, 0);
                bzero(state, sizeof(*state));
                bcopy(&key_map, keymap, sizeof(key_map));
                bcopy(&accent_map, accmap, sizeof(accent_map));
@@ -598,12 +587,7 @@ ukbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
                 * translation mode to, well, translation mode so we don't
                 * get garbage.
                 */
-               if (!KBD_IS_CONFIGURED(kbd)) {
-                       state->ks_mode = K_XLATE;
-                       kbd->kb_savemode = state->ks_mode;
-               } else {
-                       state->ks_mode = kbd->kb_savemode;
-               }
+               state->ks_mode = K_XLATE;
                state->ks_iface = uaa->iface;
                state->ks_uaa = uaa;
                state->ks_ifstate = 0;
@@ -622,14 +606,14 @@ ukbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
                ukbd_ioctl(kbd, KDSETLED, (caddr_t)&(state->ks_state));
        }
        if (!KBD_IS_CONFIGURED(kbd)) {
-               if (kbd_register(kbd) < 0)
+               if (kbd_register(kbd) < 0) {
+                       kbd->kb_flags = 0;
+                       /* XXX: Missing free()'s */
                        return ENXIO;
-               KBD_CONFIG_DONE(kbd);
-       }
-       if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) {
+               }
                if (ukbd_enable_intr(kbd, TRUE, (usbd_intr_t *)data[1]) == 0)
                        ukbd_timeout((void *)kbd);
-               KBD_INIT_DONE(kbd);
+               KBD_CONFIG_DONE(kbd);
        }
        return 0;
 }
@@ -647,7 +631,7 @@ ukbd_enable_intr(keyboard_t *kbd, int on, usbd_intr_t *func)
 
                state->ks_ifstate |= INTRENABLED;
                err = usbd_open_pipe_intr(state->ks_iface, state->ks_ep_addr,
-                                       USBD_SHORT_XFER_OK | USBD_CALLBACK_LAST,
+                                       USBD_SHORT_XFER_OK,
                                        &state->ks_intrpipe, kbd,
                                        &state->ks_ndata,
                                        sizeof(state->ks_ndata), func,
@@ -702,36 +686,6 @@ ukbd_term(keyboard_t *kbd)
        return error;
 }
 
-/*
- * Finish using the default keyboard.  Shutdown the USB side of the keyboard
- * but do not unregister it.
- */
-static int
-ukbd_default_term(keyboard_t *kbd)
-{
-       ukbd_state_t *state;
-
-       crit_enter();
-
-       state = (ukbd_state_t *)kbd->kb_data;
-       DPRINTF(("ukbd_default_term: ks_ifstate=0x%x\n", state->ks_ifstate));
-
-       callout_stop(&state->ks_timeout);
-
-       if (state->ks_ifstate & INTRENABLED)
-               ukbd_enable_intr(kbd, FALSE, NULL);
-       if (state->ks_ifstate & INTRENABLED) {
-               crit_exit();
-               DPRINTF(("ukbd_term: INTRENABLED!\n"));
-               return ENXIO;
-       }
-       KBD_LOST_DEVICE(kbd);
-       KBD_LOST_PROBE(kbd);
-       KBD_LOST_INIT(kbd);
-       crit_exit();
-       return (0);
-}
-
 /* keyboard interrupt routine */
 
 static void
@@ -743,7 +697,7 @@ ukbd_timeout(void *arg)
        kbd = (keyboard_t *)arg;
        state = (ukbd_state_t *)kbd->kb_data;
        crit_enter();
-       (*kbdsw[kbd->kb_index]->intr)(kbd, (void *)USBD_NORMAL_COMPLETION);
+       kbd_intr(kbd, (void *)USBD_NORMAL_COMPLETION);
        callout_reset(&state->ks_timeout, hz / 40, ukbd_timeout, arg);
        crit_exit();
 }
@@ -832,6 +786,15 @@ ukbd_interrupt(keyboard_t *kbd, void *arg)
                        }
                }
                ADDKEY1(key | KEY_PRESS);
+               /*
+                * If any other key is presently down, force its repeat to be
+                * well in the future (100s).  This makes the last key to be
+                * pressed do the autorepeat.
+                */
+               for (j = 0; j < NKEYCODE; j++) {
+                       if (j != i)
+                               state->ks_ntime[j] = now + 100 * 1000;
+               }
        pfound:
                ;
        }
@@ -958,7 +921,7 @@ ukbd_read(keyboard_t *kbd, int wait)
 #endif /* UKBD_EMULATE_ATSCANCODE */
 
        usbcode = ukbd_getc(state, wait);
-       if (!KBD_IS_ACTIVE(kbd) || !KBD_HAS_DEVICE(kbd) || (usbcode == -1))
+       if (!KBD_IS_ACTIVE(kbd) || (usbcode == -1))
                return -1;
        ++kbd->kb_count;
 #ifdef UKBD_EMULATE_ATSCANCODE
@@ -994,7 +957,7 @@ ukbd_read(keyboard_t *kbd, int wait)
 static int
 ukbd_check(keyboard_t *kbd)
 {
-       if (!KBD_IS_ACTIVE(kbd) || !KBD_HAS_DEVICE(kbd))
+       if (!KBD_IS_ACTIVE(kbd))
                return FALSE;
 #ifdef UKBD_EMULATE_ATSCANCODE
        if (((ukbd_state_t *)kbd->kb_data)->ks_buffered_char[0])
@@ -1197,7 +1160,7 @@ ukbd_check_char(keyboard_t *kbd)
 {
        ukbd_state_t *state;
 
-       if (!KBD_IS_ACTIVE(kbd) || !KBD_HAS_DEVICE(kbd))
+       if (!KBD_IS_ACTIVE(kbd))
                return FALSE;
        state = (ukbd_state_t *)kbd->kb_data;
        if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0))
@@ -1255,7 +1218,8 @@ ukbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
                }
                i = *(int *)arg;
                /* replace CAPS LED with ALTGR LED for ALTGR keyboards */
-               if (kbd->kb_keymap->n_keys > ALTGR_OFFSET) {
+               if (state->ks_mode == K_XLATE &&
+                   kbd->kb_keymap->n_keys > ALTGR_OFFSET) {
                        if (i & ALKED)
                                i |= CLKED;
                        else
@@ -1384,9 +1348,9 @@ ukbd_poll(keyboard_t *kbd, int on)
 
        crit_enter();
        if (on) {
-               if (state->ks_polling == 0)
-                       usbd_set_polling(dev, on);
                ++state->ks_polling;
+               if (state->ks_polling == 1)
+                       usbd_set_polling(dev, on);
        } else {
                --state->ks_polling;
                if (state->ks_polling == 0)
index b5ee14f..e920bb0 100644 (file)
@@ -78,6 +78,8 @@ struct keyboard_info {
        int             kb_flags;       /* internal flags               */
 };
 typedef struct keyboard_info keyboard_info_t;
+#define KBADDKBD       _IOW('K', 68, keyboard_info_t)  /* add keyboard */
+#define KBRELKBD       _IOW('K', 69, keyboard_info_t)  /* release keyboard */
 #define KDGKBINFO      _IOR('K', 101, keyboard_info_t)
 
 /* set/get keyboard repeat rate (new interface) */
@@ -176,6 +178,7 @@ typedef struct keymap keymap_t;
 #define RALTA          0xa0            /* right alt key / alt lock     */
 #define HALT           0xa1            /* halt machine */
 #define PDWN           0xa2            /* halt machine and power down */
+#define PASTE          0xa3            /* paste from cut-paste buffer */
 
 #define F(x)           ((x)+F_FN-1)
 #define        S(x)            ((x)+F_SCR-1)