Clean-up kbd driver layers a bit more. Lift common code into the upper layer.

Add some wskbd TODO remarks (hi, martin).
This commit is contained in:
uwe 2002-10-21 15:36:35 +00:00
parent 35ec23469c
commit af2a75546d
7 changed files with 456 additions and 292 deletions

View File

@ -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 <sys/cdefs.h>
__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 <sys/param.h>
@ -38,7 +116,6 @@ __KERNEL_RCSID(0, "$NetBSD: kbd_pckbc.c,v 1.1 2002/10/03 16:27:04 uwe Exp $");
#include <sys/conf.h>
#include <sys/device.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/select.h>
#include <sys/syslog.h>
@ -46,8 +123,8 @@ __KERNEL_RCSID(0, "$NetBSD: kbd_pckbc.c,v 1.1 2002/10/03 16:27:04 uwe Exp $");
#include <machine/bus.h>
#include <machine/intr.h>
#include <machine/kbd.h>
#include <machine/kbio.h>
#include <dev/sun/kbd_reg.h>
#include <dev/sun/kbio.h>
#include <dev/pckbc/pckbdreg.h>
@ -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 */

View File

@ -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 <sys/cdefs.h>
__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 <sys/param.h>
#include <sys/systm.h>
@ -60,6 +60,7 @@ __KERNEL_RCSID(0, "$NetBSD: kbd.c,v 1.32 2002/10/03 16:13:25 uwe Exp $");
#include <sys/ioctl.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/malloc.h>
#include <sys/signal.h>
#include <sys/signalvar.h>
#include <sys/time.h>
@ -68,9 +69,9 @@ __KERNEL_RCSID(0, "$NetBSD: kbd.c,v 1.32 2002/10/03 16:13:25 uwe Exp $");
#include <sys/poll.h>
#include <sys/file.h>
#include <machine/vuid_event.h>
#include <machine/kbd.h>
#include <machine/kbio.h>
#include <dev/sun/kbd_reg.h>
#include <dev/sun/kbio.h>
#include <dev/sun/vuid_event.h>
#include <dev/sun/event_var.h>
#include <dev/sun/kbd_xlate.h>
#include <dev/sun/kbdvar.h>
@ -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);
}

View File

@ -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 <sys/cdefs.h>
__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 <sys/param.h>
#include <sys/systm.h>
@ -74,13 +74,14 @@ __KERNEL_RCSID(0, "$NetBSD: kbd_zs.c,v 1.14 2002/10/03 16:13:26 uwe Exp $");
#include <dev/ic/z8530reg.h>
#include <machine/z8530var.h>
#include <machine/vuid_event.h>
#include <machine/kbd.h>
#include <dev/sun/vuid_event.h>
#include <dev/sun/event_var.h>
#include <dev/sun/kbd_reg.h>
#include <dev/sun/kbd_xlate.h>
#include <dev/sun/kbdvar.h>
#include <dev/sun/kbdsunvar.h>
/****************************************************************
* 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;

View File

@ -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 <sys/cdefs.h>
__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 <sys/param.h>
#include <sys/systm.h>
@ -68,9 +68,9 @@ __KERNEL_RCSID(0, "$NetBSD: kbdsun.c,v 1.1 2002/10/03 16:13:26 uwe Exp $");
#include <sys/poll.h>
#include <sys/file.h>
#include <machine/vuid_event.h>
#include <machine/kbd.h>
#include <machine/kbio.h>
#include <dev/sun/kbd_reg.h>
#include <dev/sun/kbio.h>
#include <dev/sun/vuid_event.h>
#include <dev/sun/event_var.h>
#include <dev/sun/kbd_xlate.h>
@ -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);
}

View File

@ -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);

View File

@ -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 *);

View File

@ -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 <sys/cdefs.h>
__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 <sys/param.h>
#include <sys/systm.h>
@ -81,8 +81,6 @@ __KERNEL_RCSID(0, "$NetBSD: sunkbd.c,v 1.13 2002/10/03 16:13:26 uwe Exp $");
#include <dev/sun/kbdsunvar.h>
#include <dev/sun/kbd_ms_ttyvar.h>
#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