Get rid of the timeout-driven wscons_glue stuff which caused a lot of

headaches.
Now console keyboard and display are connected at autoconfiguration time,
when the last of them is found. Other keyboards / displays remain
unconnected until a new ioctl (WSDISPLAYIO_SETKEYBOARD) is called.
This commit is contained in:
drochner 1999-05-15 14:22:46 +00:00
parent 3b602e5afa
commit b7a56e27df
6 changed files with 134 additions and 253 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: files.wscons,v 1.14 1999/05/14 16:01:11 drochner Exp $
# $NetBSD: files.wscons,v 1.15 1999/05/15 14:22:46 drochner Exp $
#
# "Workstation Console" glue; attaches frame buffer to emulator & keyboard,
@ -31,7 +31,6 @@ attach wskbd at wskbddev
device wsmouse
attach wsmouse at wsmousedev
file dev/wscons/wscons_glue.c wsdisplay & wskbd
file dev/wscons/wsdisplay.c wsdisplay needs-flag
file dev/wscons/wsdisplay_compat_usl.c wsdisplay & wsdisplay_compat_usl
file dev/wscons/wsemulconf.c wsdisplay

View File

@ -1,4 +1,4 @@
/* $NetBSD: wscons_callbacks.h,v 1.8 1999/01/18 20:03:59 drochner Exp $ */
/* $NetBSD: wscons_callbacks.h,v 1.9 1999/05/15 14:22:46 drochner Exp $ */
/*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
@ -30,17 +30,10 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Call to the glue, to get the whole process started.
*/
void wscons_glue_set_callback __P((void));
/*
* Calls to the display interface from the glue code.
*/
int wsdisplay_is_console __P((struct device *));
struct device *wsdisplay_kbd __P((struct device *));
void wsdisplay_set_kbd __P((struct device *, struct device *));
struct device *wsdisplay_set_console_kbd __P((struct device *));
/*
* Calls to the display interface from the keyboard interface.
@ -60,13 +53,12 @@ void wsdisplay_set_cons_kbd __P((int (*get)(dev_t),
/*
* Calls to the keyboard interface from the glue code.
*/
int wskbd_is_console __P((struct device *));
struct device *wskbd_display __P((struct device *));
void wskbd_set_display __P((struct device *, struct device *));
int wskbd_set_display __P((int, struct device *, struct device **));
struct device *wskbd_set_console_display __P((struct device *));
int wskbd_pickfree __P((void));
/*
* Calls to the keyboard interface from the display interface.
*/
int wskbd_displayioctl __P((struct device *dev, u_long cmd,
caddr_t data, int flag, struct proc *p));
int wskbd_enable __P((struct device *, int));

View File

@ -1,152 +0,0 @@
/* $NetBSD: wscons_glue.c,v 1.5 1999/01/18 20:03:59 drochner Exp $ */
/*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
*
* 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 Christopher G. Demetriou
* for the NetBSD Project.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/
static const char _copyright[] __attribute__ ((unused)) =
"Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.";
static const char _rcsid[] __attribute__ ((unused)) =
"$NetBSD: wscons_glue.c,v 1.5 1999/01/18 20:03:59 drochner Exp $";
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <dev/wscons/wsksymvar.h>
#include <dev/wscons/wscons_callbacks.h>
#include "wskbd.h"
#include "wsdisplay.h"
#if NWSKBD > 0 && NWSDISPLAY > 0
extern struct cfdriver wsdisplay_cd, wskbd_cd;
#endif
int wscons_setup_glue_callback_set;
static void wscons_setup_glue __P((void *v));
void
wscons_glue_set_callback()
{
if (!wscons_setup_glue_callback_set) {
/* doesn't really hurt to run it twice, though... */
timeout(wscons_setup_glue, NULL, 0);
wscons_setup_glue_callback_set = 1;
}
}
static void
wscons_setup_glue(v)
void *v;
{
#if NWSKBD > 0 && NWSDISPLAY > 0
int i, kbddev, displaydev;
struct device *kbddevice, *displaydevice;
wscons_setup_glue_callback_set = 0;
/*
* Two passes:
*
* First:
* Find the console keyboard and display devices,
* glue them together if they're not already attached.
*/
kbddev = displaydev = -1;
for (i = 0; i < wskbd_cd.cd_ndevs; i++)
if (wskbd_cd.cd_devs[i] != NULL &&
wskbd_is_console(wskbd_cd.cd_devs[i])) {
kbddev = i;
break;
}
for (i = 0; i < wsdisplay_cd.cd_ndevs; i++)
if (wsdisplay_cd.cd_devs[i] != NULL &&
wsdisplay_is_console(wsdisplay_cd.cd_devs[i])) {
displaydev = i;
break;
}
if (kbddev != -1 && (wskbd_cd.cd_devs[kbddev] != NULL) &&
wskbd_display(wskbd_cd.cd_devs[kbddev]) == NULL &&
displaydev != -1 && (wsdisplay_cd.cd_devs[displaydev] != NULL) &&
wsdisplay_kbd(wsdisplay_cd.cd_devs[displaydev]) == NULL) {
kbddevice = wskbd_cd.cd_devs[kbddev];
displaydevice = wsdisplay_cd.cd_devs[displaydev];
wskbd_set_display(kbddevice, displaydevice);
wsdisplay_set_kbd(displaydevice, kbddevice);
printf("wscons: %s glued to %s (console)\n",
kbddevice->dv_xname, displaydevice->dv_xname);
}
/*
* Second:
*
* Attach remaining unattached keyboard and display
* devices, in order by unit number.
*/
i = 0;
for (kbddev = 0; kbddev < wskbd_cd.cd_ndevs; kbddev++) {
if (wskbd_cd.cd_devs[kbddev] == NULL ||
wskbd_display(wskbd_cd.cd_devs[kbddev]) != NULL)
continue;
displaydev = -1;
for (; i < wsdisplay_cd.cd_ndevs; i++) {
if (wsdisplay_cd.cd_devs[i] == NULL ||
wsdisplay_kbd(wsdisplay_cd.cd_devs[i]) != NULL)
continue;
displaydev = i;
break;
}
if (displaydev == -1)
continue;
kbddevice = wskbd_cd.cd_devs[kbddev];
displaydevice = wsdisplay_cd.cd_devs[displaydev];
KASSERT(kbddevice != NULL);
KASSERT(wskbd_display(kbddevice) == NULL);
KASSERT(displaydevice != NULL);
KASSERT(wsdisplay_kbd(displaydevice) == NULL);
wskbd_set_display(kbddevice, displaydevice);
wsdisplay_set_kbd(displaydevice, kbddevice);
printf("wscons: %s glued to %s\n", kbddevice->dv_xname,
displaydevice->dv_xname);
}
/* Now wasn't that simple? */
#endif /* NWSKBD > 0 && NWSDISPLAY > 0 */
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: wsconsio.h,v 1.17 1999/05/03 15:43:25 ad Exp $ */
/* $NetBSD: wsconsio.h,v 1.18 1999/05/15 14:22:46 drochner Exp $ */
/*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
@ -261,7 +261,7 @@ struct wsdisplay_cursor {
/*
* XXX WARNING
* XXX The following 3 definitions are very preliminary and are likely
* XXX The following definitions are very preliminary and are likely
* XXX to be changed without care about backwards compatibility!
*/
struct wsdisplay_font {
@ -295,6 +295,14 @@ struct wsdisplay_usefontdata {
};
#define WSDISPLAYIO_USEFONT _IOW('W', 80, struct wsdisplay_usefontdata)
struct wsdisplay_kbddata {
int op;
#define WSDISPLAY_KBD_ADD 0
#define WSDISPLAY_KBD_DEL 1
int idx;
};
#define WSDISPLAYIO_SETKEYBOARD _IOWR('W', 81, struct wsdisplay_kbddata)
/* XXX NOT YET DEFINED */
/* Mapping information retrieval. */

View File

@ -1,4 +1,4 @@
/* $NetBSD: wsdisplay.c,v 1.23 1999/05/14 16:01:11 drochner Exp $ */
/* $NetBSD: wsdisplay.c,v 1.24 1999/05/15 14:22:46 drochner Exp $ */
/*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
@ -33,7 +33,7 @@
static const char _copyright[] __attribute__ ((unused)) =
"Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.";
static const char _rcsid[] __attribute__ ((unused)) =
"$NetBSD: wsdisplay.c,v 1.23 1999/05/14 16:01:11 drochner Exp $";
"$NetBSD: wsdisplay.c,v 1.24 1999/05/15 14:22:46 drochner Exp $";
#include <sys/param.h>
#include <sys/conf.h>
@ -564,6 +564,9 @@ wsdisplay_common_attach(sc, console, scrdata, accessops, accesscookie)
{
int i = 0;
sc->sc_kbddv = NULL;
sc->sc_isconsole = console;
if (console) {
KASSERT(wsdisplay_console_initted);
KASSERT(wsdisplay_console_device == NULL);
@ -575,26 +578,23 @@ wsdisplay_common_attach(sc, console, scrdata, accessops, accesscookie)
wsdisplay_console_conf.scrdata->name,
wsdisplay_console_conf.wsemul->name);
if ((sc->sc_kbddv = wskbd_set_console_display(&sc->sc_dv)))
printf(", using %s", sc->sc_kbddv->dv_xname);
sc->sc_focusidx = 0;
sc->sc_focus = sc->sc_scr[0];
i++;
}
printf("\n");
sc->sc_accessops = accessops;
sc->sc_accesscookie = accesscookie;
sc->sc_scrdata = scrdata;
sc->sc_isconsole = console;
sc->sc_kbddv = NULL;
wscons_glue_set_callback();
/*
* Set up a number of virtual screens if possible. The
* Set up a number of virtual screens if wanted. The
* WSDISPLAYIO_ADDSCREEN ioctl is more flexible, so this code
* should go away as soon as we have a userspace utility.
* is for special cases like installation kernels.
*/
#ifdef WSDISPLAY_DEFAULTSCREENS
for (; i < WSDISPLAY_DEFAULTSCREENS; i++)
@ -968,6 +968,7 @@ wsdisplay_cfg_ioctl(sc, cmd, data, flag, p)
int error;
char *type, typebuf[16], *emul, emulbuf[16];
void *buf;
struct device *kbddv;
switch (cmd) {
case WSDISPLAYIO_ADDSCREEN:
@ -1019,6 +1020,37 @@ wsdisplay_cfg_ioctl(sc, cmd, data, flag, p)
free(buf, M_DEVBUF);
#undef d
return (error);
case WSDISPLAYIO_SETKEYBOARD:
#define d ((struct wsdisplay_kbddata *)data)
switch (d->op) {
case WSDISPLAY_KBD_ADD:
if (sc->sc_kbddv)
return (EBUSY);
if (d->idx == -1) {
d->idx = wskbd_pickfree();
if (d->idx == -1)
return (ENXIO);
}
error = wskbd_set_display(d->idx, &sc->sc_dv, &kbddv);
if (error)
return (error);
sc->sc_kbddv = kbddv;
return (0);
case WSDISPLAY_KBD_DEL:
if (sc->sc_kbddv == NULL)
return (ENXIO);
if (d->idx == -1)
d->idx = sc->sc_kbddv->dv_unit;
error = wskbd_set_display(d->idx, 0, 0);
if (error)
return (error);
sc->sc_kbddv = NULL;
return (0);
default:
return (EINVAL);
}
#undef d
return (0);
}
return (EINVAL);
}
@ -1563,42 +1595,14 @@ wsdisplay_kbdholdscreen(dev, hold)
/*
* Calls from the glue code.
*/
int
wsdisplay_is_console(dv)
struct device *dv;
{
struct wsdisplay_softc *sc = (struct wsdisplay_softc *)dv;
KASSERT(sc != NULL);
return (sc->sc_isconsole);
}
struct device *
wsdisplay_kbd(dv)
struct device *dv;
wsdisplay_set_console_kbd(kbddv)
struct device *kbddv;
{
struct wsdisplay_softc *sc = (struct wsdisplay_softc *)dv;
KASSERT(sc != NULL);
return (sc->sc_kbddv);
}
void
wsdisplay_set_kbd(dv, kbddv)
struct device *dv, *kbddv;
{
struct wsdisplay_softc *sc = (struct wsdisplay_softc *)dv;
KASSERT(sc != NULL);
if (sc->sc_kbddv) {
/* disable old keyboard */
wskbd_enable(sc->sc_kbddv, 0);
}
if (kbddv) {
/* enable new keyboard */
wskbd_enable(kbddv, 1);
}
sc->sc_kbddv = kbddv;
if (!wsdisplay_console_device)
return (0);
wsdisplay_console_device->sc_kbddv = kbddv;
return (&wsdisplay_console_device->sc_dv);
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: wskbd.c,v 1.21 1999/05/14 16:01:12 drochner Exp $ */
/* $NetBSD: wskbd.c,v 1.22 1999/05/15 14:22:46 drochner Exp $ */
/*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
@ -36,7 +36,7 @@
static const char _copyright[] __attribute__ ((unused)) =
"Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.";
static const char _rcsid[] __attribute__ ((unused)) =
"$NetBSD: wskbd.c,v 1.21 1999/05/14 16:01:12 drochner Exp $";
"$NetBSD: wskbd.c,v 1.22 1999/05/15 14:22:46 drochner Exp $";
/*
* Copyright (c) 1992, 1993
@ -187,6 +187,7 @@ static inline void update_leds __P((struct wskbd_internal *));
static inline void update_modifier __P((struct wskbd_internal *, u_int, int, int));
static int internal_command __P((struct wskbd_softc *, u_int *, keysym_t));
static keysym_t wskbd_translate __P((struct wskbd_internal *, u_int, int));
static int wskbd_enable __P((struct wskbd_softc *, int));
#if NWSDISPLAY > 0
static void wskbd_holdscreen __P((struct wskbd_softc *, int));
#endif
@ -289,8 +290,22 @@ wskbd_attach(parent, self, aux)
struct wskbd_softc *sc = (struct wskbd_softc *)self;
struct wskbddev_attach_args *ap = aux;
if (ap->console)
#if NWSDISPLAY > 0
sc->sc_displaydv = NULL;
#endif
sc->sc_isconsole = ap->console;
if (ap->console) {
KASSERT(wskbd_console_initted);
KASSERT(wskbd_console_device == NULL);
wskbd_console_device = sc;
printf(": console keyboard");
if ((sc->sc_displaydv = wsdisplay_set_console_kbd(self)))
printf(", using %s", sc->sc_displaydv->dv_xname);
}
printf("\n");
if (ap->console) {
@ -317,16 +332,6 @@ wskbd_attach(parent, self, aux)
sc->sc_layout = sc->id->t_keymap->layout;
if (ap->console) {
KASSERT(wskbd_console_initted);
KASSERT(wskbd_console_device == NULL);
wskbd_console_device = sc;
}
sc->sc_isconsole = ap->console;
#if NWSDISPLAY > 0
sc->sc_displaydv = NULL;
#endif
/* set default bell and key repeat data */
sc->sc_bell_data = wskbd_default_bell_data;
sc->sc_keyrepeat_data = wskbd_default_keyrepeat_data;
@ -485,12 +490,11 @@ wskbd_holdscreen(sc, hold)
}
#endif
int
wskbd_enable(dev, on)
struct device *dev;
static int
wskbd_enable(sc, on)
struct wskbd_softc *sc;
int on;
{
struct wskbd_softc *sc = (struct wskbd_softc *)dev;
int res;
/* XXX reference count? */
@ -528,7 +532,7 @@ wskbdopen(dev, flags, mode, p)
sc->sc_translating = 0;
sc->sc_ready = 1; /* start accepting events */
wskbd_enable((struct device *)sc, 1);
wskbd_enable(sc, 1);
return (0);
}
@ -546,7 +550,7 @@ wskbdclose(dev, flags, mode, p)
wsevent_fini(&sc->sc_events);
sc->sc_events.io = NULL;
wskbd_enable((struct device *)sc, 0);
wskbd_enable(sc, 0);
return (0);
}
@ -786,36 +790,62 @@ wskbdpoll(dev, events, p)
return (wsevent_poll(&sc->sc_events, events, p));
}
int
wskbd_is_console(dv)
struct device *dv;
{
struct wskbd_softc *sc = (struct wskbd_softc *)dv;
KASSERT(sc != NULL);
return (sc->sc_isconsole);
}
#if NWSDISPLAY > 0
struct device *
wskbd_display(dv)
struct device *dv;
int
wskbd_pickfree()
{
struct wskbd_softc *sc = (struct wskbd_softc *)dv;
int i;
struct wskbd_softc *sc;
KASSERT(sc != NULL);
return (sc->sc_displaydv);
for (i = 0; i < wskbd_cd.cd_ndevs; i++) {
if ((sc = wskbd_cd.cd_devs[i]) == NULL)
continue;
if (sc->sc_displaydv == NULL)
return (i);
}
return (-1);
}
void
wskbd_set_display(dv, displaydv)
struct device *dv, *displaydv;
int
wskbd_set_display(idx, displaydv, kbddv)
int idx;
struct device *displaydv, **kbddv;
{
struct wskbd_softc *sc = (struct wskbd_softc *)dv;
struct wskbd_softc *sc;
if (idx >= wskbd_cd.cd_ndevs || /* make sure it was attached */
(sc = wskbd_cd.cd_devs[idx]) == NULL)
return (ENXIO);
if (sc->sc_isconsole)
return (EBUSY);
if (displaydv) {
if (sc->sc_displaydv)
return (EBUSY);
printf("%s: connecting to %s\n",
sc->sc_dv.dv_xname, displaydv->dv_xname);
} else {
if (sc->sc_displaydv == NULL)
return (ENXIO);
printf("%s: disconnecting\n", sc->sc_dv.dv_xname);
}
KASSERT(sc != NULL);
sc->sc_displaydv = displaydv;
wskbd_enable(sc, displaydv != NULL);
if (kbddv)
*kbddv = &sc->sc_dv;
return (0);
}
struct device *
wskbd_set_console_display(displaydv)
struct device *displaydv;
{
if (!wskbd_console_device)
return (0);
wskbd_console_device->sc_displaydv = displaydv;
return (&wskbd_console_device->sc_dv);
}
#endif /* NWSDISPLAY > 0 */