-allow the "show_screen" call to the display driver to complete

asynchronously, in the same style like the process attach/detach functions
-intercept the "cnpollc" call which originally went directly to the
 keyboard driver and keep track whether the console is in "polling" state
 (DDB!)
-pass a NULL callback to the screen switcher and the process attach/detach
 functions if the console is "polling", to tell them that asynchronous
 completion is forbidden
This commit is contained in:
drochner 1999-12-06 18:52:23 +00:00
parent c9457413cb
commit 8996199a85
3 changed files with 99 additions and 31 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: wsdisplay.c,v 1.32 1999/12/01 23:22:59 augustss Exp $ */
/* $NetBSD: wsdisplay.c,v 1.33 1999/12/06 18:52:23 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.32 1999/12/01 23:22:59 augustss Exp $";
"$NetBSD: wsdisplay.c,v 1.33 1999/12/06 18:52:23 drochner Exp $";
#include <sys/param.h>
#include <sys/conf.h>
@ -199,11 +199,14 @@ static struct wsdisplay_softc *wsdisplay_console_device;
static struct wsscreen_internal wsdisplay_console_conf;
static int wsdisplay_getc_dummy __P((dev_t));
static void wsdisplay_pollc_dummy __P((dev_t, int));
static void wsdisplay_pollc __P((dev_t, int));
static int wsdisplay_cons_pollmode;
static void (*wsdisplay_cons_kbd_pollc) __P((dev_t, int));
static struct consdev wsdisplay_cons = {
NULL, NULL, wsdisplay_getc_dummy, wsdisplay_cnputc,
wsdisplay_pollc_dummy, NODEV, CN_NORMAL
wsdisplay_pollc, NODEV, CN_NORMAL
};
#ifndef WSDISPLAY_DEFAULTSCREENS
@ -212,6 +215,7 @@ static struct consdev wsdisplay_cons = {
int wsdisplay_defaultscreens = WSDISPLAY_DEFAULTSCREENS;
int wsdisplay_switch1 __P((void *, int, int));
int wsdisplay_switch2 __P((void *, int, int));
int wsdisplay_switch3 __P((void *, int, int));
int wsdisplay_clearonclose;
@ -378,7 +382,8 @@ wsdisplay_addscreen(sc, idx, screentype, emul)
s = spltty();
if (!sc->sc_focus) {
(*sc->sc_accessops->show_screen)(sc->sc_accesscookie,
scr->scr_dconf->emulcookie);
scr->scr_dconf->emulcookie,
0, 0, 0);
sc->sc_focusidx = idx;
sc->sc_focus = scr;
}
@ -1405,6 +1410,65 @@ wsdisplay_switch3(arg, error, waitok)
return (error);
}
int
wsdisplay_switch2(arg, error, waitok)
void *arg;
int error, waitok;
{
struct wsdisplay_softc *sc = arg;
int no;
struct wsscreen *scr;
if (!(sc->sc_flags & SC_SWITCHPENDING)) {
printf("wsdisplay_switch2: not switching\n");
return (EINVAL);
}
no = sc->sc_screenwanted;
if (no < 0 || no >= WSDISPLAY_MAXSCREEN)
panic("wsdisplay_switch2: invalid screen %d", no);
scr = sc->sc_scr[no];
if (!scr) {
printf("wsdisplay_switch2: screen %d disappeared\n", no);
error = ENXIO;
}
if (error) {
/* try to recover, avoid recursion */
if (sc->sc_oldscreen == -1) {
printf("wsdisplay_switch2: giving up\n");
sc->sc_focus = 0;
sc->sc_flags &= ~SC_SWITCHPENDING;
return (error);
}
sc->sc_screenwanted = sc->sc_oldscreen;
sc->sc_oldscreen = -1;
return (wsdisplay_switch1(arg, 0, waitok));
}
sc->sc_focusidx = no;
sc->sc_focus = scr;
#ifdef WSDISPLAY_COMPAT_RAWKBD
(void) wsdisplay_update_rawkbd(sc, scr);
#endif
/* keyboard map??? */
#define wsswitch_cb3 ((void (*) __P((void *, int, int)))wsdisplay_switch3)
if (scr->scr_syncops) {
error = (*scr->scr_syncops->attach)(scr->scr_synccookie, waitok,
sc->sc_isconsole && wsdisplay_cons_pollmode ? 0 : wsswitch_cb3, sc);
if (error == EAGAIN) {
/* switch will be done asynchronously */
return (0);
}
}
return (wsdisplay_switch3(sc, error, waitok));
}
int
wsdisplay_switch1(arg, error, waitok)
void *arg;
@ -1433,27 +1497,17 @@ wsdisplay_switch1(arg, error, waitok)
return (error);
}
(*sc->sc_accessops->show_screen)(sc->sc_accesscookie,
scr->scr_dconf->emulcookie);
sc->sc_focusidx = no;
sc->sc_focus = scr;
#ifdef WSDISPLAY_COMPAT_RAWKBD
(void) wsdisplay_update_rawkbd(sc, scr);
#endif
/* keyboard map??? */
#define wsswitch_cb3 ((void (*) __P((void *, int, int)))wsdisplay_switch3)
if (scr->scr_syncops) {
error = (*scr->scr_syncops->attach)(scr->scr_synccookie, waitok,
wsswitch_cb3, sc);
if (error == EAGAIN) {
/* switch will be done asynchronously */
return (0);
}
#define wsswitch_cb2 ((void (*) __P((void *, int, int)))wsdisplay_switch2)
error = (*sc->sc_accessops->show_screen)(sc->sc_accesscookie,
scr->scr_dconf->emulcookie,
waitok,
sc->sc_isconsole && wsdisplay_cons_pollmode ? 0 : wsswitch_cb2, sc);
if (error == EAGAIN) {
/* switch will be done asynchronously */
return (0);
}
return (wsdisplay_switch3(sc, error, waitok));
return (wsdisplay_switch2(sc, error, waitok));
}
int
@ -1495,7 +1549,7 @@ wsdisplay_switch(dev, no, waitok)
#define wsswitch_cb1 ((void (*) __P((void *, int, int)))wsdisplay_switch1)
if (scr->scr_syncops) {
res = (*scr->scr_syncops->detach)(scr->scr_synccookie, waitok,
wsswitch_cb1, sc);
sc->sc_isconsole && wsdisplay_cons_pollmode ? 0 : wsswitch_cb1, sc);
if (res == EAGAIN) {
/* switch will be done asynchronously */
return (0);
@ -1697,10 +1751,15 @@ wsdisplay_getc_dummy(dev)
}
static void
wsdisplay_pollc_dummy(dev, on)
wsdisplay_pollc(dev, on)
dev_t dev;
int on;
{
wsdisplay_cons_pollmode = on;
if (wsdisplay_cons_kbd_pollc)
(*wsdisplay_cons_kbd_pollc)(dev, on);
}
void
@ -1709,14 +1768,14 @@ wsdisplay_set_cons_kbd(get, poll)
void (*poll) __P((dev_t, int));
{
wsdisplay_cons.cn_getc = get;
wsdisplay_cons.cn_pollc = poll;
wsdisplay_cons_kbd_pollc = poll;
}
void
wsdisplay_unset_cons_kbd()
{
wsdisplay_cons.cn_getc = wsdisplay_getc_dummy;
wsdisplay_cons.cn_pollc = wsdisplay_pollc_dummy;
wsdisplay_cons_kbd_pollc = 0;
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: wsdisplay_compat_usl.c,v 1.10 1999/10/19 00:03:18 mycroft Exp $ */
/* $NetBSD: wsdisplay_compat_usl.c,v 1.11 1999/12/06 18:52:23 drochner Exp $ */
/*
* Copyright (c) 1998
@ -172,6 +172,10 @@ usl_detachproc(cookie, waitok, callback, cbarg)
if (!usl_sync_check(sd))
return (0);
/* we really need a callback */
if (!callback)
return (EINVAL);
/*
* Normally, this is called from the controlling process.
* Is is supposed to reply with a VT_RELDISP ioctl(), so
@ -238,6 +242,10 @@ usl_attachproc(cookie, waitok, callback, cbarg)
if (!usl_sync_check(sd))
return (0);
/* we really need a callback */
if (!callback)
return (EINVAL);
sd->s_callback = callback;
sd->s_cbarg = cbarg;
sd->s_flags |= SF_ATTACHPENDING;

View File

@ -1,4 +1,4 @@
/* $NetBSD: wsdisplayvar.h,v 1.13 1999/10/19 00:03:18 mycroft Exp $ */
/* $NetBSD: wsdisplayvar.h,v 1.14 1999/12/06 18:52:23 drochner Exp $ */
/*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
@ -107,7 +107,8 @@ struct wsdisplay_accessops {
int (*alloc_screen) __P((void *, const struct wsscreen_descr *,
void **, int *, int *, long *));
void (*free_screen) __P((void *, void *));
void (*show_screen) __P((void *, void *));
int (*show_screen) __P((void *, void *, int,
void (*) (void *, int, int), void *));
int (*load_font) __P((void *, void *, struct wsdisplay_font *));
};