Finish support for wskbd @ kbd @ zs/sab for sparc64 consoles.

Based on work from John Heasley and Michael Lorenz.
This commit is contained in:
martin 2005-04-28 15:03:48 +00:00
parent 1e67869b4b
commit eb7e634f97
4 changed files with 98 additions and 44 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: kbd.c,v 1.43 2005/02/27 00:27:49 perry Exp $ */
/* $NetBSD: kbd.c,v 1.44 2005/04/28 15:03:48 martin Exp $ */
/*
* Copyright (c) 1992, 1993
@ -47,7 +47,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kbd.c,v 1.43 2005/02/27 00:27:49 perry Exp $");
__KERNEL_RCSID(0, "$NetBSD: kbd.c,v 1.44 2005/04/28 15:03:48 martin Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -99,6 +99,7 @@ void sunkbd_wskbd_cngetc(void *, u_int *, int *);
void sunkbd_wskbd_cnpollc(void *, int);
void sunkbd_wskbd_cnbell(void *, u_int, u_int, u_int);
static void sunkbd_bell_off(void *v);
void kbd_enable(struct device *); /* deferred keyboard initialization */
const struct wskbd_accessops sunkbd_wskbd_accessops = {
wssunkbd_enable,
@ -188,6 +189,8 @@ kbdopen(dev, flags, mode, p)
* events input, so we should probably just let the open to
* always succeed regardless (e.g. Xsun opening /dev/kbd).
*/
if (!k->k_wsenabled)
wssunkbd_enable(k, 1);
/* exclusive open required for /dev/kbd */
if (k->k_events.ev_io)
@ -364,6 +367,7 @@ kbdioctl(dev, cmd, data, flag, p)
break;
default:
printf("kbd: returning ENOTTY\n");
error = ENOTTY;
break;
}
@ -683,7 +687,6 @@ kbd_input_keysym(k, keysym)
{
struct kbd_state *ks = &k->k_state;
int data;
/* Check if a recipient has been configured */
if (k->k_cc == NULL || k->k_cc->cc_upstream == NULL)
return (0);
@ -956,20 +959,20 @@ wssunkbd_enable(v, on)
int on;
{
struct kbd_softc *k = v;
k->k_wsenabled = on;
if (on) {
/* open actual underlying device */
if (k->k_ops != NULL && k->k_ops->open != NULL)
(*k->k_ops->open)(k);
ev_init(&k->k_events);
k->k_evmode = 0; /* XXX: OK? */
} else {
/* close underlying device */
if (k->k_ops != NULL && k->k_ops->close != NULL)
(*k->k_ops->close)(k);
if (k->k_wsenabled != on) {
k->k_wsenabled = on;
if (on) {
/* open actual underlying device */
if (k->k_ops != NULL && k->k_ops->open != NULL)
(*k->k_ops->open)(k);
ev_init(&k->k_events);
k->k_evmode = 0; /* XXX: OK? */
} else {
/* close underlying device */
if (k->k_ops != NULL && k->k_ops->close != NULL)
(*k->k_ops->close)(k);
}
}
return 0;
}
@ -991,6 +994,7 @@ wssunkbd_set_leds(v, leds)
l |= LED_COMPOSE;
if (k->k_ops != NULL && k->k_ops->setleds != NULL)
(*k->k_ops->setleds)(k, l, 0);
k->k_leds=l;
}
int
@ -1001,9 +1005,31 @@ wssunkbd_ioctl(v, cmd, data, flag, p)
int flag;
struct proc *p;
{
struct kbd_softc *k = v;
switch (cmd) {
case WSKBDIO_GTYPE:
*(int *)data = WSKBD_TYPE_SUN5;
return (0);
case WSKBDIO_SETLEDS:
wssunkbd_set_leds(v, *(int *)data);
return (0);
case WSKBDIO_GETLEDS:
*(int *)data = k->k_leds;
return (0);
#ifdef WSDISPLAY_COMPAT_RAWKBD___
case WSKBDIO_SETMODE:
DPRINTF(("wssunkbd_ioctl: set raw = %d\n", *(int *)data));
sc->sc_rawkbd = *(int *)data == WSKBD_RAW;
usb_uncallout(sc->sc_rawrepeat_ch, ukbd_rawrepeat, sc);
return (0);
#endif
}
return EPASSTHROUGH;
}
extern int prom_cngetc(dev_t);
void
sunkbd_wskbd_cngetc(v, type, data)
void *v;
@ -1011,6 +1037,8 @@ sunkbd_wskbd_cngetc(v, type, data)
int *data;
{
/* struct kbd_sun_softc *k = v; */
*data = prom_cngetc(0);
*type = WSCONS_EVENT_ASCII;
}
void
@ -1039,26 +1067,44 @@ sunkbd_wskbd_cnbell(v, pitch, period, volume)
k->k_ops->docmd(k, KBD_CMD_BELL, 0);
}
void
kbd_enable(dev)
struct device *dev;
{
struct kbd_softc *k=(struct kbd_softc *)dev;
struct wskbddev_attach_args a;
if (k->k_isconsole)
wskbd_cnattach(&sunkbd_wskbd_consops, k,
&sunkbd_wskbd_keymapdata);
a.console = k->k_isconsole;
a.keymap = &sunkbd_wskbd_keymapdata;
a.accessops = &sunkbd_wskbd_accessops;
a.accesscookie = k;
/* XXX why? */
k->k_wsenabled = 0;
/* Attach the wskbd */
k->k_wskbd = config_found(&k->k_dev, &a, wskbddevprint);
callout_init(&k->k_wsbell);
wssunkbd_enable(k,1);
wssunkbd_set_leds(k, WSKBD_LED_SCROLL | WSKBD_LED_NUM | WSKBD_LED_CAPS);
delay(100000);
wssunkbd_set_leds(k, 0);
}
void
kbd_wskbd_attach(k, isconsole)
struct kbd_softc *k;
int isconsole;
{
struct wskbddev_attach_args a;
a.console = isconsole;
if (a.console)
wskbd_cnattach(&sunkbd_wskbd_consops, k, &sunkbd_wskbd_keymapdata);
a.keymap = &sunkbd_wskbd_keymapdata;
a.accessops = &sunkbd_wskbd_accessops;
a.accesscookie = k;
/* Attach the wskbd */
k->k_wskbd = config_found(&k->k_dev, &a, wskbddevprint);
k->k_wsenabled = 0;
callout_init(&k->k_wsbell);
k->k_isconsole=isconsole;
config_interrupts(&k->k_dev,kbd_enable);
}
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: kbd_zs.c,v 1.18 2005/02/27 00:27:49 perry Exp $ */
/* $NetBSD: kbd_zs.c,v 1.19 2005/04/28 15:03:48 martin Exp $ */
/*
* Copyright (c) 1992, 1993
@ -53,7 +53,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kbd_zs.c,v 1.18 2005/02/27 00:27:49 perry Exp $");
__KERNEL_RCSID(0, "$NetBSD: kbd_zs.c,v 1.19 2005/04/28 15:03:48 martin Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -77,6 +77,9 @@ __KERNEL_RCSID(0, "$NetBSD: kbd_zs.c,v 1.18 2005/02/27 00:27:49 perry Exp $");
#include <dev/sun/kbdvar.h>
#include <dev/sun/kbdsunvar.h>
#if NWSKBD > 0
void kbd_wskbd_attach(struct kbd_softc *k, int isconsole);
#endif
/****************************************************************
* Interface to the lower layer (zscc)
@ -188,6 +191,9 @@ kbd_zs_attach(parent, self, aux)
/* Magic sequence. */
k->k_magic1 = KBD_L1;
k->k_magic2 = KBD_A;
#if NWSKBD > 0
kbd_wskbd_attach(&k->k_kbd, k->k_kbd.k_isconsole);
#endif
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: kbdsun.c,v 1.6 2005/02/21 03:46:38 heas Exp $ */
/* $NetBSD: kbdsun.c,v 1.7 2005/04/28 15:03:48 martin Exp $ */
/* NetBSD: kbd.c,v 1.29 2001/11/13 06:54:32 lukem Exp */
/*
@ -47,7 +47,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kbdsun.c,v 1.6 2005/02/21 03:46:38 heas Exp $");
__KERNEL_RCSID(0, "$NetBSD: kbdsun.c,v 1.7 2005/04/28 15:03:48 martin Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -135,12 +135,11 @@ kbd_sun_open(kbd)
kbd_sun_drain_tx(k);
/* the wakeup for this is in kbd_sun_was_reset(). */
for (ntries = 200; ntries; ntries--) {
for (ntries = 30; ntries; ntries--) {
error = tsleep((caddr_t)&ks->kbd_id, PZERO | PCATCH, devopn,
hz);
hz/10);
if (ks->kbd_id)
break;
DELAY(10000);
}
if (error == EWOULDBLOCK || ks->kbd_id == 0) { /* no response */
@ -348,14 +347,16 @@ static int
kbd_sun_drain_tx(k)
struct kbd_sun_softc *k;
{
int error = 0;
int error = 0, bail = 0;
while (k->k_txflags & K_TXBUSY && !error) {
while ((k->k_txflags & K_TXBUSY) && (!error) && (bail<1000)) {
k->k_txflags |= K_TXWANT;
error = tsleep((caddr_t)&k->k_txflags,
PZERO | PCATCH, "kbdout", 0);
PZERO | PCATCH, "kbdout", 1);
bail++;
}
if (bail==1000)
error=EIO;
return (error);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: kbdvar.h,v 1.14 2005/02/20 20:32:45 heas Exp $ */
/* $NetBSD: kbdvar.h,v 1.15 2005/04/28 15:03:49 martin Exp $ */
/*
* Copyright (c) 1992, 1993
@ -73,6 +73,7 @@ struct kbd_softc {
int k_repeatsym; /* repeating symbol */
int k_repeating; /* callout is active (use callout_active?) */
struct callout k_repeat_ch;
int k_leds;
};