From af2a75546df315f515c8027b40901ad1ead5d8c1 Mon Sep 17 00:00:00 2001 From: uwe Date: Mon, 21 Oct 2002 15:36:35 +0000 Subject: [PATCH] Clean-up kbd driver layers a bit more. Lift common code into the upper layer. Add some wskbd TODO remarks (hi, martin). --- sys/arch/sparc/dev/kbd_pckbc.c | 171 +++++++++++++--------- sys/dev/sun/kbd.c | 257 ++++++++++++++++++++++++++++----- sys/dev/sun/kbd_zs.c | 24 +-- sys/dev/sun/kbdsun.c | 153 +++++--------------- sys/dev/sun/kbdsunvar.h | 62 ++++++-- sys/dev/sun/kbdvar.h | 51 ++++--- sys/dev/sun/sunkbd.c | 30 +--- 7 files changed, 456 insertions(+), 292 deletions(-) diff --git a/sys/arch/sparc/dev/kbd_pckbc.c b/sys/arch/sparc/dev/kbd_pckbc.c index b4c3d2cf0bda..afc6956ebf01 100644 --- a/sys/arch/sparc/dev/kbd_pckbc.c +++ b/sys/arch/sparc/dev/kbd_pckbc.c @@ -1,4 +1,4 @@ -/* $NetBSD: kbd_pckbc.c,v 1.1 2002/10/03 16:27:04 uwe Exp $ */ +/* $NetBSD: kbd_pckbc.c,v 1.2 2002/10/21 15:36:35 uwe Exp $ */ /* * Copyright (c) 2002 Valeriy E. Ushakov @@ -26,11 +26,89 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +/*- + * Copyright (c) 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles M. Hannum. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz and Don Ahn. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)pccons.c 5.11 (Berkeley) 5/21/91 + */ #include -__KERNEL_RCSID(0, "$NetBSD: kbd_pckbc.c,v 1.1 2002/10/03 16:27:04 uwe Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kbd_pckbc.c,v 1.2 2002/10/21 15:36:35 uwe Exp $"); /* - * Pretend we are a Type5 keyboard with US101A layout. + * Serve JavaStation-1 PS/2 keyboard as a Type5 keyboard with US101A + * layout. Since stock Xsun(1) knows this layout, JavaStation-1 gets + * X for free. When sparc port is switched to wscons and its X server + * knows how to talk wskbd, this driver will no longer be necessary, + * and we will be able to attach the keyboard with the MI pckbc(4) driver. */ #include @@ -38,7 +116,6 @@ __KERNEL_RCSID(0, "$NetBSD: kbd_pckbc.c,v 1.1 2002/10/03 16:27:04 uwe Exp $"); #include #include #include -#include #include #include @@ -46,8 +123,8 @@ __KERNEL_RCSID(0, "$NetBSD: kbd_pckbc.c,v 1.1 2002/10/03 16:27:04 uwe Exp $"); #include #include -#include -#include +#include +#include #include @@ -61,11 +138,11 @@ __KERNEL_RCSID(0, "$NetBSD: kbd_pckbc.c,v 1.1 2002/10/03 16:27:04 uwe Exp $"); struct kbd_pckbc_softc { - struct kbd_softc sc_kbd; + struct kbd_softc sc_kbd; /* pckbc attachment */ - pckbc_tag_t sc_kbctag; - pckbc_slot_t sc_kbcslot; + pckbc_tag_t sc_kbctag; + pckbc_slot_t sc_kbcslot; /* * Middle layer data. @@ -97,7 +174,7 @@ static int kbd_pckbc_close(struct kbd_softc *); static int kbd_pckbc_do_cmd(struct kbd_softc *, int, int); static int kbd_pckbc_set_leds(struct kbd_softc *, int, int); -struct kbd_ops kbd_ops_pckbc = { +static const struct kbd_ops kbd_ops_pckbc = { kbd_pckbc_open, kbd_pckbc_close, kbd_pckbc_do_cmd, @@ -105,7 +182,7 @@ struct kbd_ops kbd_ops_pckbc = { }; -static u_int8_t kbd_pckbc_xt_to_sun[]; +static const u_int8_t kbd_pckbc_xt_to_sun[]; static int kbd_pckbc_set_xtscancode(pckbc_tag_t, pckbc_slot_t); static void kbd_pckbc_input(void *, int); @@ -140,7 +217,6 @@ kbd_pckbc_attach(parent, self, aux) struct kbd_pckbc_softc *sc = (void *)self; struct pckbc_attach_args *pa = aux; struct kbd_softc *kbd = &sc->sc_kbd; - struct kbd_state *ks = &kbd->k_state; /* save our attachment to pckbc */ sc->sc_kbctag = pa->pa_tag; @@ -149,29 +225,22 @@ kbd_pckbc_attach(parent, self, aux) /* provide upper layer a link to our middle layer */ kbd->k_ops = &kbd_ops_pckbc; - /* pre-fill keyboard id/layout */ - ks->kbd_id = KB_SUN4; - ks->kbd_layout = 19; /* US101A */ + /* pre-fill keyboard type/layout */ + kbd->k_state.kbd_id = KB_SUN4; /* NB: type5 keyboards actually report type4 */ + kbd->k_state.kbd_layout = 19; /* US101A */ - if (1) { + if (1) { /* XXX: pckbc_machdep_cnattach should tell us */ /* * Hookup ourselves as the console input channel */ extern void kd_attach_input(struct cons_channel *); struct cons_channel *cc; - if ((cc = malloc(sizeof *cc, M_DEVBUF, M_NOWAIT)) == NULL) + if ((cc = kbd_cc_alloc(kbd)) == NULL) return; - cc->cc_dev = self; - cc->cc_iopen = kbd_cc_open; - cc->cc_iclose = kbd_cc_close; - cc->cc_upstream = NULL; /* will be provided by upper driver */ - kd_attach_input(cc); /* XXX ???? */ - - kbd->k_cc = cc; + kd_attach_input(cc); /* XXX ???? */ kbd->k_isconsole = 1; - printf(": console input"); } @@ -281,7 +350,7 @@ kbd_pckbc_open(kbd) ks = &kbd->k_state; - /* tolerate extra calls. */ + /* tolerate extra calls */ if (sc->sc_isopen) return (0); @@ -289,14 +358,14 @@ kbd_pckbc_open(kbd) /* reset the keyboard (and enable interrupts?) */ - /* initialize the table pointers for this type */ + /* + * Initialize the table pointers for this type/layout. + * NB: fixed type/layout were preset during attach. + */ kbd_xlate_init(ks); - /* layout US101A */ - if (error == 0) sc->sc_isopen = 1; - return (error); } @@ -313,7 +382,7 @@ kbd_pckbc_close(kbd) /* - * Middle layer feeds talks sun keyboard protocol to us. + * Upper layer talks sun keyboard protocol to us. */ /* ARGSUSED2 */ static int @@ -330,7 +399,7 @@ kbd_pckbc_do_cmd(kbd, suncmd, isioctl) case KBD_CMD_NOBELL: /* FALLTHROUGH */ case KBD_CMD_CLICK: /* FALLTHROUGH */ case KBD_CMD_NOCLICK: - /* do nothing */ + /* not supported, do nothing */ DPRINTF(("%s: ignoring KIOCCMD 0x%02x\n", kbd->k_dev.dv_xname, suncmd)); break; @@ -397,45 +466,13 @@ kbd_pckbc_input(vsc, data) { struct kbd_pckbc_softc *sc = vsc; struct kbd_softc *kbd = &sc->sc_kbd; - struct kbd_state *ks = &kbd->k_state; int sunkey; - int keysym; - /* convert to sun scan code (up/down is encoded in the high bit) */ + /* convert to sun make/break code */ if (!kbd_pckbc_decode(sc, data, &sunkey)) return; - if (kbd->k_evmode) { - /* - * Keyboard is generating events. Turn this keystroke - * into an event and put it in the queue. - */ - kbd_input_event(kbd, sunkey); - return; - } - - /* Console input */ - - /* Any input stops auto-repeat (i.e. key release). */ - - /* Translate this code to a keysym */ - keysym = kbd_code_to_keysym(ks, sunkey); - - /* Pass up to the next layer. */ - if (kbd_input_keysym(kbd, keysym)) { - log(LOG_WARNING, "%s: code=0x%x with mod=0x%x" - " produced unexpected keysym 0x%x\n", - kbd->k_dev.dv_xname, - sunkey, ks->kbd_modbits, keysym); - /* No point in auto-repeat here. */ - return; - } - - /* Does this symbol get auto-repeat? */ - if (KEYSYM_NOREPEAT(keysym)) - return; - - /* Setup for auto-repeat after initial delay. */ + kbd_input(kbd, sunkey); } @@ -510,7 +547,7 @@ kbd_pckbc_decode(sc, data, sundata) return (1); } -static u_int8_t kbd_pckbc_xt_to_sun[256] = { +static const u_int8_t kbd_pckbc_xt_to_sun[256] = { /* 0x00 */ 0, /* */ /* 0x01 */ 29, /* Esc */ /* 0x02 */ 30, /* 1 */ diff --git a/sys/dev/sun/kbd.c b/sys/dev/sun/kbd.c index 78a10058607b..617ab4b14c67 100644 --- a/sys/dev/sun/kbd.c +++ b/sys/dev/sun/kbd.c @@ -1,4 +1,4 @@ -/* $NetBSD: kbd.c,v 1.32 2002/10/03 16:13:25 uwe Exp $ */ +/* $NetBSD: kbd.c,v 1.33 2002/10/21 15:36:35 uwe Exp $ */ /* * Copyright (c) 1992, 1993 @@ -51,7 +51,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: kbd.c,v 1.32 2002/10/03 16:13:25 uwe Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kbd.c,v 1.33 2002/10/21 15:36:35 uwe Exp $"); #include #include @@ -60,6 +60,7 @@ __KERNEL_RCSID(0, "$NetBSD: kbd.c,v 1.32 2002/10/03 16:13:25 uwe Exp $"); #include #include #include +#include #include #include #include @@ -68,9 +69,9 @@ __KERNEL_RCSID(0, "$NetBSD: kbd.c,v 1.32 2002/10/03 16:13:25 uwe Exp $"); #include #include -#include -#include -#include +#include +#include +#include #include #include #include @@ -99,10 +100,22 @@ static int kbd_oldkeymap(struct kbd_state *ks, u_long cmd, struct okiockey *okio); #endif -/* console input helpers */ -static void kbd_input_string(struct kbd_softc *, char *); -static void kbd_input_funckey(struct kbd_softc *, int); -static void kbd_update_leds(struct kbd_softc *); + +/* callbacks for console driver */ +static int kbd_cc_open(struct cons_channel *); +static int kbd_cc_close(struct cons_channel *); + +/* console input */ +static void kbd_input_console(struct kbd_softc *, int); +static void kbd_repeat(void *); +static int kbd_input_keysym(struct kbd_softc *, int); +static void kbd_input_string(struct kbd_softc *, char *); +static void kbd_input_funckey(struct kbd_softc *, int); +static void kbd_update_leds(struct kbd_softc *); + +/* firm events input */ +static void kbd_input_event(struct kbd_softc *, int); + /**************************************************************** @@ -132,11 +145,24 @@ kbdopen(dev, flags, mode, p) if (k == NULL) return (ENXIO); + /* + * NB: wscons support: while we can track if wskbd has called + * enable(), we can't tell if that's for console input or for + * events input, so we should probably just let the open to + * always succeed regardless (e.g. Xsun opening /dev/kbd). + */ + /* exclusive open required for /dev/kbd */ if (k->k_events.ev_io) return (EBUSY); k->k_events.ev_io = p; + /* stop pending autorepeat of console input */ + if (k->k_repeating) { + k->k_repeating = 0; + callout_stop(&k->k_repeat_ch); + } + /* open actual underlying device */ if (k->k_ops != NULL && k->k_ops->open != NULL) if ((error = (*k->k_ops->open)(k)) != 0) { @@ -387,61 +413,213 @@ kbd_oldkeymap(ks, cmd, kio) #endif /* KIOCGETKEY */ + /**************************************************************** - * Callbacks we supply to console driver + * Keyboard input - called by middle layer at spltty(). ****************************************************************/ -/* - * Open/close routines called upon opening /dev/console - * if we serve console input. - */ -int +void +kbd_input(k, code) + struct kbd_softc *k; + int code; +{ + /* + * TODO: wscons support: check if attached wskbd has called + * enable() and pass input to wskbd_input() if it has. But + * check for k_evmode first(!) - see the comment in kbdopen(). + */ + + /* + * If /dev/kbd is not connected in event mode, + * translate and send upstream (to console). + */ + if (!k->k_evmode) { + kbd_input_console(k, code); + return; + } + + /* + * XXX: is this still true? + * IDLEs confuse the MIT X11R4 server badly, so we must drop them. + * This is bad as it means the server will not automatically resync + * on all-up IDLEs, but I did not drop them before, and the server + * goes crazy when it comes time to blank the screen.... + */ + if (code == KBD_IDLE) + return; + + /* + * Keyboard is generating firm events. Turn this keystroke + * into an event and put it in the queue. + */ + kbd_input_event(k, code); +} + + + +/**************************************************************** + * Open/close routines called upon opening /dev/console + * if we serve console input. + ****************************************************************/ + +struct cons_channel * +kbd_cc_alloc(k) + struct kbd_softc *k; +{ + struct cons_channel *cc; + + if ((cc = malloc(sizeof *cc, M_DEVBUF, M_NOWAIT)) == NULL) + return (NULL); + + /* our callbacks for the console driver */ + cc->cc_dev = k; + cc->cc_iopen = kbd_cc_open; + cc->cc_iclose = kbd_cc_close; + + /* will be provided by the console driver so that we can feed input */ + cc->cc_upstream = NULL; + + /* + * TODO: clean up cons_attach_input() vs kd_attach_input() in + * lower layers and move that code here. + */ + + k->k_cc = cc; + return (cc); +} + + +static int kbd_cc_open(cc) struct cons_channel *cc; { struct kbd_softc *k; + int ret; if (cc == NULL) - return (0); + return (0); k = (struct kbd_softc *)cc->cc_dev; - if (k != NULL && k->k_ops != NULL && k->k_ops->open != NULL) - return ((*k->k_ops->open)(k)); - else + if (k == NULL) return (0); + + if (k->k_ops != NULL && k->k_ops->open != NULL) + ret = (*k->k_ops->open)(k); + else + ret = 0; + + /* XXX: verify that callout is not active? */ + k->k_repeat_start = hz/2; + k->k_repeat_step = hz/20; + callout_init(&k->k_repeat_ch); + + return (ret); } -int +static int kbd_cc_close(cc) struct cons_channel *cc; { struct kbd_softc *k; + int ret; if (cc == NULL) - return (0); + return (0); k = (struct kbd_softc *)cc->cc_dev; - if (k != NULL && k->k_ops != NULL && k->k_ops->close != NULL) - return ((*k->k_ops->close)(k)); - else + if (k == NULL) return (0); + + if (k->k_ops != NULL && k->k_ops->close != NULL) + ret = (*k->k_ops->close)(k); + else + ret = 0; + + /* stop any pending auto-repeat */ + if (k->k_repeating) { + k->k_repeating = 0; + callout_stop(&k->k_repeat_ch); + } + + return (ret); } + /**************************************************************** * Console input - called by middle layer at spltty(). ****************************************************************/ +static void +kbd_input_console(k, code) + struct kbd_softc *k; + int code; +{ + struct kbd_state *ks= &k->k_state; + int keysym; + + /* any input stops auto-repeat (i.e. key release) */ + if (k->k_repeating) { + k->k_repeating = 0; + callout_stop(&k->k_repeat_ch); + } + + keysym = kbd_code_to_keysym(ks, code); + + /* pass to console */ + if (kbd_input_keysym(k, keysym)) { + log(LOG_WARNING, "%s: code=0x%x with mod=0x%x" + " produced unexpected keysym 0x%x\n", + k->k_dev.dv_xname, + code, ks->kbd_modbits, keysym); + return; /* no point in auto-repeat here */ + } + + if (KEYSYM_NOREPEAT(keysym)) + return; + + /* setup for auto-repeat after initial delay */ + k->k_repeating = 1; + k->k_repeatsym = keysym; + callout_reset(&k->k_repeat_ch, k->k_repeat_start, + kbd_repeat, k); +} + + /* - * Entry point for the middle layer to supply keysym as console input. - * Convert keysym to character(s) and pass them up to cons_channel's - * upstream hook. + * This is the autorepeat callout function scheduled by kbd_input() above. + * Called at splsoftclock(). + */ +static void +kbd_repeat(arg) + void *arg; +{ + struct kbd_softc *k = (struct kbd_softc *)arg; + int s; + + s = spltty(); + if (k->k_repeating && k->k_repeatsym >= 0) { + /* feed typematic keysym to the console */ + (void)kbd_input_keysym(k, k->k_repeatsym); + + /* reschedule next repeat */ + callout_reset(&k->k_repeat_ch, k->k_repeat_step, + kbd_repeat, k); + } + splx(s); +} + + + +/* + * Supply keysym as console input. Convert keysym to character(s) and + * pass them up to cons_channel's upstream hook. * * Return zero on success, else the keysym that we could not handle * (so that the caller may complain). */ -int +static int kbd_input_keysym(k, keysym) struct kbd_softc *k; int keysym; @@ -567,16 +745,15 @@ kbd_update_leds(k) ****************************************************************/ /* - * Entry point for the middle layer to supply raw keystrokes when - * keyboard is open (i.e. is in event mode). + * Supply raw keystrokes when keyboard is open in firm event mode. * * Turn the keystroke into an event and put it in the queue. * If the queue is full, the keystroke is lost (sorry!). */ -void -kbd_input_event(k, c) +static void +kbd_input_event(k, code) struct kbd_softc *k; - int c; + int code; { struct firm_event *fe; int put; @@ -596,14 +773,16 @@ kbd_input_event(k, c) k->k_dev.dv_xname); return; } - fe->id = KEY_CODE(c); - fe->value = KEY_UP(c) ? VKEY_UP : VKEY_DOWN; + + fe->id = KEY_CODE(code); + fe->value = KEY_UP(code) ? VKEY_UP : VKEY_DOWN; fe->time = time; k->k_events.ev_put = put; EV_WAKEUP(&k->k_events); } + /**************************************************************** * Translation stuff declared in kbd_xlate.h ****************************************************************/ @@ -695,6 +874,10 @@ void kbd_bell(on) int on; { - /* XXX: stub out for now */ - return; + struct kbd_softc *k = kbd_cd.cd_devs[0]; /* XXX: hardcoded minor */ + + if (k == NULL || k->k_ops == NULL || k->k_ops->docmd == NULL) + return; + + (void)(*k->k_ops->docmd)(k, on ? KBD_CMD_BELL : KBD_CMD_NOBELL, 0); } diff --git a/sys/dev/sun/kbd_zs.c b/sys/dev/sun/kbd_zs.c index ce91a8d0de72..069d3add334d 100644 --- a/sys/dev/sun/kbd_zs.c +++ b/sys/dev/sun/kbd_zs.c @@ -1,4 +1,4 @@ -/* $NetBSD: kbd_zs.c,v 1.14 2002/10/03 16:13:26 uwe Exp $ */ +/* $NetBSD: kbd_zs.c,v 1.15 2002/10/21 15:36:35 uwe Exp $ */ /* * Copyright (c) 1992, 1993 @@ -57,7 +57,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: kbd_zs.c,v 1.14 2002/10/03 16:13:26 uwe Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kbd_zs.c,v 1.15 2002/10/21 15:36:35 uwe Exp $"); #include #include @@ -74,13 +74,14 @@ __KERNEL_RCSID(0, "$NetBSD: kbd_zs.c,v 1.14 2002/10/03 16:13:26 uwe Exp $"); #include #include -#include -#include +#include #include +#include #include #include #include + /**************************************************************** * Interface to the lower layer (zscc) ****************************************************************/ @@ -159,24 +160,17 @@ kbd_zs_attach(parent, self, aux) /* * Hookup ourselves as the console input channel */ - struct cons_channel *cc; + struct cons_channel *cc = kbd_cc_alloc(&k->k_kbd); - if ((cc = malloc(sizeof *cc, M_DEVBUF, M_NOWAIT)) == NULL) + if (cc == NULL) return; - cc->cc_dev = self; - cc->cc_iopen = kbd_cc_open; - cc->cc_iclose = kbd_cc_close; - cc->cc_upstream = NULL; cons_attach_input(cc, args->consdev); - k->k_kbd.k_cc = cc; k->k_kbd.k_isconsole = 1; printf(" (console input)"); } printf("\n"); - callout_init(&k->k_repeat_ch); - /* Initialize the speed, etc. */ s = splzs(); if (k->k_kbd.k_isconsole == 0) { @@ -195,10 +189,6 @@ kbd_zs_attach(parent, self, aux) /* Do this before any calls to kbd_rint(). */ kbd_xlate_init(&k->k_kbd.k_state); - /* XXX - Do this in open? */ - k->k_repeat_start = hz/2; - k->k_repeat_step = hz/20; - /* Magic sequence. */ k->k_magic1 = KBD_L1; k->k_magic2 = KBD_A; diff --git a/sys/dev/sun/kbdsun.c b/sys/dev/sun/kbdsun.c index 400b0af6be0a..2e8189e554b0 100644 --- a/sys/dev/sun/kbdsun.c +++ b/sys/dev/sun/kbdsun.c @@ -1,4 +1,4 @@ -/* $NetBSD: kbdsun.c,v 1.1 2002/10/03 16:13:26 uwe Exp $ */ +/* $NetBSD: kbdsun.c,v 1.2 2002/10/21 15:36:35 uwe Exp $ */ /* NetBSD: kbd.c,v 1.29 2001/11/13 06:54:32 lukem Exp */ /* @@ -51,7 +51,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: kbdsun.c,v 1.1 2002/10/03 16:13:26 uwe Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kbdsun.c,v 1.2 2002/10/21 15:36:35 uwe Exp $"); #include #include @@ -68,9 +68,9 @@ __KERNEL_RCSID(0, "$NetBSD: kbdsun.c,v 1.1 2002/10/03 16:13:26 uwe Exp $"); #include #include -#include -#include -#include +#include +#include +#include #include #include @@ -86,7 +86,7 @@ static int kbd_sun_set_leds(struct kbd_softc *, int, int); static void kbd_sun_set_leds1(struct kbd_softc *, int); /* aux */ -struct kbd_ops kbd_ops_sun = { +const struct kbd_ops kbd_ops_sun = { kbd_sun_open, kbd_sun_close, kbd_sun_do_cmd, @@ -99,7 +99,6 @@ static int kbd_sun_drain_tx(struct kbd_sun_softc *); /* helper functions for kbd_sun_input */ static void kbd_sun_was_reset(struct kbd_sun_softc *); static void kbd_sun_new_layout(struct kbd_sun_softc *); -static void kbd_sun_repeat(void *); /*********************************************************************** @@ -128,12 +127,6 @@ kbd_sun_open(kbd) if (k->k_isopen) return (0); - /* stop pending autorepeat */ - if (k->k_repeating) { - k->k_repeating = 0; - callout_stop(&k->k_repeat_ch); - } - /* open internal device */ if (k->k_deviopen) (*k->k_deviopen)((struct device *)k, FREAD|FWRITE); @@ -158,32 +151,30 @@ kbd_sun_open(kbd) ks->kbd_id = KB_SUN2; } - /* initialize the table pointers for this type */ + /* earlier than type 4 does not know "layout" */ + if (ks->kbd_id >= KB_SUN4) { + /* ask for the layout */ + kbd_sun_output(k, KBD_CMD_GETLAYOUT); + kbd_sun_start_tx(k); + kbd_sun_drain_tx(k); + + /* the wakeup for this is in kbd_new_layout() */ + error = tsleep((caddr_t)&ks->kbd_layout, PZERO | PCATCH, devopn, hz); + if (error == EWOULDBLOCK) { /* no response */ + log(LOG_ERR, "%s: no response to get_layout\n", + kbd->k_dev.dv_xname); + error = 0; + ks->kbd_layout = 0; /* US layout */ + } + } + + /* initialize the table pointers for this type/layout */ kbd_xlate_init(ks); - /* earlier than type 4 does not know "layout" */ - if (ks->kbd_id < KB_SUN4) - goto done; - - /* ask for the layout */ - kbd_sun_output(k, KBD_CMD_GETLAYOUT); - kbd_sun_start_tx(k); - kbd_sun_drain_tx(k); - - /* the wakeup for this is in kbd_new_layout() */ - error = tsleep((caddr_t)&ks->kbd_layout, PZERO | PCATCH, devopn, hz); - if (error == EWOULDBLOCK) { /* no response */ - log(LOG_ERR, "%s: no response to get_layout\n", - kbd->k_dev.dv_xname); - error = 0; - ks->kbd_layout = 0; /* US layout */ - } - done: splx(s); if (error == 0) k->k_isopen = 1; - return (error); } @@ -395,17 +386,15 @@ kbd_sun_start_tx(k) /* * Called by underlying driver's softint() routine on input, - * which passes us the raw hardware scan codes. + * which passes us the raw hardware make/break codes. * Called at spltty() */ void -kbd_sun_input(k, c) +kbd_sun_input(k, code) struct kbd_sun_softc *k; - int c; + int code; { struct kbd_softc *kbd = (struct kbd_softc *)k; - struct kbd_state *ks = &kbd->k_state; - int keysym; /* XXX - Input errors already handled. */ @@ -413,12 +402,12 @@ kbd_sun_input(k, c) if (k->k_expect) { if (k->k_expect & KBD_EXPECT_IDCODE) { /* We read a KBD_RESET last time. */ - ks->kbd_id = c; + kbd->k_state.kbd_id = code; kbd_sun_was_reset(k); } if (k->k_expect & KBD_EXPECT_LAYOUT) { /* We read a KBD_LAYOUT last time. */ - ks->kbd_layout = c; + kbd->k_state.kbd_layout = code; kbd_sun_new_layout(k); } k->k_expect = 0; @@ -426,12 +415,12 @@ kbd_sun_input(k, c) } /* Is this one of the "special" input codes? */ - if (KBD_SPECIAL(c)) { - switch (c) { + if (KBD_SPECIAL(code)) { + switch (code) { case KBD_RESET: k->k_expect |= KBD_EXPECT_IDCODE; /* Fake an "all-up" to resync. translation. */ - c = KBD_IDLE; + code = KBD_IDLE; break; case KBD_LAYOUT: @@ -449,57 +438,7 @@ kbd_sun_input(k, c) } } - /* - * If /dev/kbd is not connected in event mode, - * translate and send upstream (to console). - */ - if (!kbd->k_evmode) { - - /* Any input stops auto-repeat (i.e. key release). */ - if (k->k_repeating) { - k->k_repeating = 0; - callout_stop(&k->k_repeat_ch); - } - - /* Translate this code to a keysym */ - keysym = kbd_code_to_keysym(ks, c); - - /* Pass up to the next layer. */ - if (kbd_input_keysym(kbd, keysym)) { - log(LOG_WARNING, "%s: code=0x%x with mod=0x%x" - " produced unexpected keysym 0x%x\n", - kbd->k_dev.dv_xname, - c, ks->kbd_modbits, keysym); - /* No point in auto-repeat here. */ - return; - } - - /* Does this symbol get auto-repeat? */ - if (KEYSYM_NOREPEAT(keysym)) - return; - - /* Setup for auto-repeat after initial delay. */ - k->k_repeating = 1; - k->k_repeatsym = keysym; - callout_reset(&k->k_repeat_ch, k->k_repeat_start, - kbd_sun_repeat, k); - return; - } - - /* - * IDLEs confuse the MIT X11R4 server badly, so we must drop them. - * This is bad as it means the server will not automatically resync - * on all-up IDLEs, but I did not drop them before, and the server - * goes crazy when it comes time to blank the screen.... - */ - if (c == KBD_IDLE) - return; - - /* - * Keyboard is generating events. Turn this keystroke into an - * event and put it in the queue. - */ - kbd_input_event(kbd, c); + kbd_input(kbd, code); } @@ -567,29 +506,3 @@ kbd_sun_new_layout(k) /* XXX: switch decoding tables? */ } - - -/* - * This is the autorepeat callout function. - * Autorepeat is scheduled by kbd_sun_input. - * Called at splsoftclock(). - */ -static void -kbd_sun_repeat(arg) - void *arg; -{ - struct kbd_sun_softc *k = (struct kbd_sun_softc *)arg; - int s; - - s = spltty(); - if (k->k_repeating && k->k_repeatsym >= 0) { - - /* feed typematic keysym to the upper layer */ - (void)kbd_input_keysym(&k->k_kbd, k->k_repeatsym); - - /* reschedule next repeat */ - callout_reset(&k->k_repeat_ch, k->k_repeat_step, - kbd_sun_repeat, k); - } - splx(s); -} diff --git a/sys/dev/sun/kbdsunvar.h b/sys/dev/sun/kbdsunvar.h index 29e83b150789..0ebfee67abfc 100644 --- a/sys/dev/sun/kbdsunvar.h +++ b/sys/dev/sun/kbdsunvar.h @@ -1,8 +1,55 @@ +/* $NetBSD: kbdsunvar.h,v 1.2 2002/10/21 15:36:35 uwe Exp $ */ + +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Lawrence Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)kbd.c 8.2 (Berkeley) 10/30/93 + */ + /* * Keyboard driver - middle layer for sun keyboard off a serial line. - * This code is used by kbd_zs and sunkbd drivers. + * This code is used by kbd_zs and sunkbd (line discipline) drivers. */ + /* * How many input characters we can buffer. * The port-specific var.h may override this. @@ -16,10 +63,12 @@ */ #define KBD_TX_RING_SIZE 16 #define KBD_TX_RING_MASK (KBD_TX_RING_SIZE - 1) + /* * Keyboard serial line speed defaults to 1200 bps. */ #define KBD_DEFAULT_BPS 1200 + #define KBD_RESET_TIMO 1000 /* mS. */ @@ -59,13 +108,6 @@ struct kbd_sun_softc { u_char k_magic1; /* L1 */ u_char k_magic2; /* A */ - /* Autorepeat for sun keyboards is handled in software */ - int k_repeat_start; /* initial delay */ - int k_repeat_step; /* inter-char delay */ - int k_repeatsym; /* repeating symbol */ - int k_repeating; /* callout is active (use callout_active?) */ - struct callout k_repeat_ch; - /* Expecting ID or layout byte from keyboard */ int k_expect; #define KBD_EXPECT_IDCODE 1 @@ -98,9 +140,9 @@ struct kbd_sun_softc { }; /* Middle layer methods exported to the upper layer. */ -extern struct kbd_ops kbd_ops_sun; +extern const struct kbd_ops kbd_ops_sun; -/* Methods for lower layer to call. */ +/* Methods for the lower layer to call. */ extern void kbd_sun_input(struct kbd_sun_softc *k, int); extern void kbd_sun_output(struct kbd_sun_softc *k, int c); extern void kbd_sun_start_tx(struct kbd_sun_softc *k); diff --git a/sys/dev/sun/kbdvar.h b/sys/dev/sun/kbdvar.h index 363a4d851494..14e9db61a947 100644 --- a/sys/dev/sun/kbdvar.h +++ b/sys/dev/sun/kbdvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: kbdvar.h,v 1.9 2002/10/03 16:13:26 uwe Exp $ */ +/* $NetBSD: kbdvar.h,v 1.10 2002/10/21 15:36:35 uwe Exp $ */ /* * Copyright (c) 1992, 1993 @@ -48,7 +48,7 @@ struct kbd_softc { struct device k_dev; /* required first: base device */ /* middle layer methods */ - struct kbd_ops *k_ops; + const struct kbd_ops *k_ops; /* state of the upper layer */ int k_evmode; /* set if we should produce events */ @@ -57,32 +57,33 @@ struct kbd_softc { /* ACSII translation state */ struct kbd_state k_state; - /* Console hooks */ + /* console hooks */ int k_isconsole; struct cons_channel *k_cc; + + /* autorepeat for console input */ + int k_repeat_start; /* initial delay */ + int k_repeat_step; /* inter-char delay */ + int k_repeatsym; /* repeating symbol */ + int k_repeating; /* callout is active (use callout_active?) */ + struct callout k_repeat_ch; }; -/* + +/* * Downcalls to the middle layer. - * NB: iocsled has user context to care about, - * setleds can be called from interrupt handler. */ struct kbd_ops { int (*open)(struct kbd_softc *); int (*close)(struct kbd_softc *); - int (*docmd)(struct kbd_softc *, int, int); /* KIOCCMD */ - int (*setleds)(struct kbd_softc *, int, int); /* KIOCSLED */ + int (*docmd)(struct kbd_softc *, int, int); + int (*setleds)(struct kbd_softc *, int, int); }; -/* Callbacks for middle layer to feed us keyboard input */ -extern int kbd_input_keysym(struct kbd_softc *, int); /* console */ -extern void kbd_input_event(struct kbd_softc *, int); /* events */ - - /* * kbd console input channel interface. - * XXX - does not belong in this header; but for now, kbd is the only user.. + * XXX - does not belong in this header; but for now, kbd is the only user... */ struct cons_channel { /* XXX: only used by PROM console, probably belongs to kd.c */ @@ -97,16 +98,28 @@ struct cons_channel { int (*cc_iclose)(struct cons_channel *); /* close underlying device */ /* - * Callback provided by the console driver. Underlying driver + * Callback provided by the console driver. Keyboard driver * calls it to pass input character up as console input. */ void (*cc_upstream)(int); }; -/* upper layer callbacks that lower layer passes to console driver */ -extern int kbd_cc_open(struct cons_channel *); -extern int kbd_cc_close(struct cons_channel *); -/* Special hook to attach the keyboard driver to the console */ +/* + * Allocate and link up console channel. + * Should be called by the lower layer during attachment. + */ +extern struct cons_channel *kbd_cc_alloc(struct kbd_softc *); + +/* + * Feed sun make/break code as keyboard input to the upper layer. + * Should be called by the middle layer. + */ +extern void kbd_input(struct kbd_softc *, int); + +/* + * Special hook to attach the keyboard driver to the console. + * XXX: this should be hidden in kbd_cc_alloc(). + */ struct consdev; extern void cons_attach_input(struct cons_channel *, struct consdev *); diff --git a/sys/dev/sun/sunkbd.c b/sys/dev/sun/sunkbd.c index ecc416bbd082..77d30ef13298 100644 --- a/sys/dev/sun/sunkbd.c +++ b/sys/dev/sun/sunkbd.c @@ -1,4 +1,4 @@ -/* $NetBSD: sunkbd.c,v 1.13 2002/10/03 16:13:26 uwe Exp $ */ +/* $NetBSD: sunkbd.c,v 1.14 2002/10/21 15:36:35 uwe Exp $ */ /* * Copyright (c) 1992, 1993 @@ -55,7 +55,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sunkbd.c,v 1.13 2002/10/03 16:13:26 uwe Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sunkbd.c,v 1.14 2002/10/21 15:36:35 uwe Exp $"); #include #include @@ -81,8 +81,6 @@ __KERNEL_RCSID(0, "$NetBSD: sunkbd.c,v 1.13 2002/10/03 16:13:26 uwe Exp $"); #include #include -#include "kbd.h" -#if NKBD > 0 /**************************************************************** * Interface to the lower layer (ttycc) @@ -145,21 +143,18 @@ sunkbd_attach(parent, self, aux) k->k_priv = tp; tp->t_sc = (void *)k; - /* provide upper layer with a link to the middle layer */ - k->k_kbd.k_ops = &kbd_ops_sun; - - /* provide middle layer with a link to the lower layer (i.e. us) */ + /* provide our middle layer with a link to the lower layer (i.e. us) */ k->k_deviopen = sunkbdiopen; k->k_deviclose = NULL; k->k_write_data = sunkbd_write_data; - if ((cc = malloc(sizeof *cc, M_DEVBUF, M_NOWAIT)) == NULL) + /* provide upper layer with a link to our middle layer */ + k->k_kbd.k_ops = &kbd_ops_sun; + + /* alloc console input channel */ + if ((cc = kbd_cc_alloc(&k->k_kbd)) == NULL) return; - cc->cc_dev = self; - cc->cc_iopen = kbd_cc_open; - cc->cc_iclose = kbd_cc_close; - cc->cc_upstream = NULL; if (args->kmta_consdev) { char magic[4]; @@ -185,19 +180,12 @@ sunkbd_attach(parent, self, aux) kd_attach_input(cc); } - k->k_kbd.k_cc = cc; printf("\n"); - callout_init(&k->k_repeat_ch); - /* Do this before any calls to kbd_rint(). */ kbd_xlate_init(&k->k_kbd.k_state); - /* XXX - Do this in open? */ - k->k_repeat_start = hz/2; - k->k_repeat_step = hz/20; - /* Magic sequence. */ k->k_magic1 = KBD_L1; k->k_magic2 = KBD_A; @@ -325,5 +313,3 @@ sunkbd_write_data(k, c) ttstart(tp); splx(s); } - -#endif