summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/pc98/pc98/syscons.c134
1 files changed, 64 insertions, 70 deletions
diff --git a/sys/pc98/pc98/syscons.c b/sys/pc98/pc98/syscons.c
index 1a929e7..1c9c657 100644
--- a/sys/pc98/pc98/syscons.c
+++ b/sys/pc98/pc98/syscons.c
@@ -172,6 +172,8 @@ static int do_switch_scr(sc_softc_t *sc, int s);
static int vt_proc_alive(scr_stat *scp);
static int signal_vt_rel(scr_stat *scp);
static int signal_vt_acq(scr_stat *scp);
+static int finish_vt_rel(scr_stat *scp, int release, int *s);
+static int finish_vt_acq(scr_stat *scp);
static void exchange_scr(sc_softc_t *sc);
static void update_cursor_image(scr_stat *scp);
static int save_kbd_state(scr_stat *scp);
@@ -508,18 +510,10 @@ scclose(dev_t dev, int flag, int mode, struct proc *p)
s = spltty();
if ((scp == scp->sc->cur_scp) && (scp->sc->unit == sc_console_unit))
cons_unavail = FALSE;
- if (scp->status & SWITCH_WAIT_REL) {
- /* assert(scp == scp->sc->cur_scp) */
+ if (finish_vt_rel(scp, TRUE, &s) == 0) /* force release */
DPRINTF(5, ("reset WAIT_REL, "));
- scp->status &= ~SWITCH_WAIT_REL;
- do_switch_scr(scp->sc, s);
- }
- if (scp->status & SWITCH_WAIT_ACQ) {
- /* assert(scp == scp->sc->cur_scp) */
+ if (finish_vt_acq(scp) == 0) /* force acknowledge */
DPRINTF(5, ("reset WAIT_ACQ, "));
- scp->status &= ~SWITCH_WAIT_ACQ;
- scp->sc->switch_in_progress = 0;
- }
#if not_yet_done
if (scp == &main_console) {
scp->pid = 0;
@@ -877,18 +871,10 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
if ((scp == sc->cur_scp) && (sc->unit == sc_console_unit))
cons_unavail = FALSE;
/* were we in the middle of the vty switching process? */
- if (scp->status & SWITCH_WAIT_REL) {
- /* assert(scp == scp->sc->cur_scp) */
+ if (finish_vt_rel(scp, TRUE, &s) == 0)
DPRINTF(5, ("reset WAIT_REL, "));
- scp->status &= ~SWITCH_WAIT_REL;
- s = do_switch_scr(sc, s);
- }
- if (scp->status & SWITCH_WAIT_ACQ) {
- /* assert(scp == scp->sc->cur_scp) */
+ if (finish_vt_acq(scp) == 0)
DPRINTF(5, ("reset WAIT_ACQ, "));
- scp->status &= ~SWITCH_WAIT_ACQ;
- sc->switch_in_progress = 0;
- }
} else {
if (!ISSIGVALID(mode->relsig) || !ISSIGVALID(mode->acqsig)
|| !ISSIGVALID(mode->frsig)) {
@@ -930,32 +916,17 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
error = EINVAL;
switch(*(int *)data) {
case VT_FALSE: /* user refuses to release screen, abort */
- if ((scp == sc->old_scp) && (scp->status & SWITCH_WAIT_REL)) {
- sc->old_scp->status &= ~SWITCH_WAIT_REL;
- sc->switch_in_progress = 0;
+ if ((error = finish_vt_rel(scp, FALSE, &s)) == 0)
DPRINTF(5, ("sc%d: VT_FALSE\n", sc->unit));
- error = 0;
- }
break;
-
case VT_TRUE: /* user has released screen, go on */
- if ((scp == sc->old_scp) && (scp->status & SWITCH_WAIT_REL)) {
- scp->status &= ~SWITCH_WAIT_REL;
- s = do_switch_scr(sc, s);
+ if ((error = finish_vt_rel(scp, TRUE, &s)) == 0)
DPRINTF(5, ("sc%d: VT_TRUE\n", sc->unit));
- error = 0;
- }
break;
-
case VT_ACKACQ: /* acquire acknowledged, switch completed */
- if ((scp == sc->new_scp) && (scp->status & SWITCH_WAIT_ACQ)) {
- scp->status &= ~SWITCH_WAIT_ACQ;
- sc->switch_in_progress = 0;
+ if ((error = finish_vt_acq(scp)) == 0)
DPRINTF(5, ("sc%d: VT_ACKACQ\n", sc->unit));
- error = 0;
- }
break;
-
default:
break;
}
@@ -973,22 +944,22 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return EINVAL;
case VT_ACTIVATE: /* switch to screen *data */
+ i = (*(int *)data == 0) ? scp->index : (*(int *)data - 1);
s = spltty();
sc_clean_up(sc->cur_scp);
splx(s);
- return sc_switch_scr(sc, *(int *)data - 1);
+ return sc_switch_scr(sc, i);
case VT_WAITACTIVE: /* wait for switch to occur */
- if ((*(int *)data >= sc->first_vty + sc->vtys)
- || (*(int *)data < sc->first_vty))
+ i = (*(int *)data == 0) ? scp->index : (*(int *)data - 1);
+ if ((i < sc->first_vty) || (i >= sc->first_vty + sc->vtys))
return EINVAL;
s = spltty();
error = sc_clean_up(sc->cur_scp);
splx(s);
if (error)
return error;
- if (*(int *)data != 0)
- scp = SC_STAT(SC_DEV(sc, *(int *)data - 1));
+ scp = SC_STAT(SC_DEV(sc, i));
if (scp == scp->sc->cur_scp)
return 0;
while ((error=tsleep((caddr_t)&scp->smode, PZERO|PCATCH,
@@ -2098,6 +2069,7 @@ sc_touch_scrn_saver(void)
int
sc_switch_scr(sc_softc_t *sc, u_int next_scr)
{
+ scr_stat *cur_scp;
struct tty *tp;
struct proc *p;
int s;
@@ -2114,13 +2086,14 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr)
}
s = spltty();
+ cur_scp = sc->cur_scp;
/* we are in the middle of the vty switching process... */
if (sc->switch_in_progress
- && (sc->cur_scp->smode.mode == VT_PROCESS)
- && sc->cur_scp->proc) {
- p = pfind(sc->cur_scp->pid);
- if (sc->cur_scp->proc != p) {
+ && (cur_scp->smode.mode == VT_PROCESS)
+ && cur_scp->proc) {
+ p = pfind(cur_scp->pid);
+ if (cur_scp->proc != p) {
if (p)
PROC_UNLOCK(p);
/*
@@ -2129,23 +2102,21 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr)
* are not reset here yet; they will be cleared later.
*/
DPRINTF(5, ("cur_scp controlling process %d died, ",
- sc->cur_scp->pid));
- if (sc->cur_scp->status & SWITCH_WAIT_REL) {
+ cur_scp->pid));
+ if (cur_scp->status & SWITCH_WAIT_REL) {
/*
* Force the previous switch to finish, but return now
* with error.
*/
DPRINTF(5, ("reset WAIT_REL, "));
- sc->cur_scp->status &= ~SWITCH_WAIT_REL;
- s = do_switch_scr(sc, s);
+ finish_vt_rel(cur_scp, TRUE, &s);
splx(s);
DPRINTF(5, ("finishing previous switch\n"));
return EINVAL;
- } else if (sc->cur_scp->status & SWITCH_WAIT_ACQ) {
+ } else if (cur_scp->status & SWITCH_WAIT_ACQ) {
/* let's assume screen switch has been completed. */
DPRINTF(5, ("reset WAIT_ACQ, "));
- sc->cur_scp->status &= ~SWITCH_WAIT_ACQ;
- sc->switch_in_progress = 0;
+ finish_vt_acq(cur_scp);
} else {
/*
* We are in between screen release and acquisition, and
@@ -2163,13 +2134,13 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr)
* The following code is a gross kludge to cope with this
* problem for which there is no clean solution. XXX
*/
- if (sc->cur_scp->status & SWITCH_WAIT_REL) {
+ if (cur_scp->status & SWITCH_WAIT_REL) {
switch (sc->switch_in_progress++) {
case 1:
break;
case 2:
DPRINTF(5, ("sending relsig again, "));
- signal_vt_rel(sc->cur_scp);
+ signal_vt_rel(cur_scp);
break;
case 3:
break;
@@ -2180,19 +2151,18 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr)
* VT_FALSE.
*/
DPRINTF(5, ("force reset WAIT_REL, "));
- sc->cur_scp->status &= ~SWITCH_WAIT_REL;
- sc->switch_in_progress = 0;
+ finish_vt_rel(cur_scp, FALSE, &s);
splx(s);
DPRINTF(5, ("act as if VT_FALSE was seen\n"));
return EINVAL;
}
- } else if (sc->cur_scp->status & SWITCH_WAIT_ACQ) {
+ } else if (cur_scp->status & SWITCH_WAIT_ACQ) {
switch (sc->switch_in_progress++) {
case 1:
break;
case 2:
DPRINTF(5, ("sending acqsig again, "));
- signal_vt_acq(sc->cur_scp);
+ signal_vt_acq(cur_scp);
break;
case 3:
break;
@@ -2200,8 +2170,7 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr)
default:
/* clear the flag and finish the previous switch */
DPRINTF(5, ("force reset WAIT_ACQ, "));
- sc->cur_scp->status &= ~SWITCH_WAIT_ACQ;
- sc->switch_in_progress = 0;
+ finish_vt_acq(cur_scp);
break;
}
}
@@ -2215,7 +2184,7 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr)
if ((next_scr < sc->first_vty) || (next_scr >= sc->first_vty + sc->vtys)
|| sc->switch_in_progress) {
splx(s);
- sc_bell(sc->cur_scp, bios_value.bell_pitch, BELL_DURATION);
+ sc_bell(cur_scp, bios_value.bell_pitch, BELL_DURATION);
DPRINTF(5, ("error 1\n"));
return EINVAL;
}
@@ -2225,13 +2194,13 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr)
* if the switch mode is VT_AUTO, unless the next vty is the same
* as the current or the current vty has been closed (but showing).
*/
- tp = VIRTUAL_TTY(sc, sc->cur_scp->index);
- if ((sc->cur_scp->index != next_scr)
+ tp = VIRTUAL_TTY(sc, cur_scp->index);
+ if ((cur_scp->index != next_scr)
&& ISTTYOPEN(tp)
- && (sc->cur_scp->smode.mode == VT_AUTO)
- && ISGRAPHSC(sc->cur_scp)) {
+ && (cur_scp->smode.mode == VT_AUTO)
+ && ISGRAPHSC(cur_scp)) {
splx(s);
- sc_bell(sc->cur_scp, bios_value.bell_pitch, BELL_DURATION);
+ sc_bell(cur_scp, bios_value.bell_pitch, BELL_DURATION);
DPRINTF(5, ("error, graphics mode\n"));
return EINVAL;
}
@@ -2246,7 +2215,7 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr)
tp = VIRTUAL_TTY(sc, next_scr);
if (!ISTTYOPEN(tp)) {
splx(s);
- sc_bell(sc->cur_scp, bios_value.bell_pitch, BELL_DURATION);
+ sc_bell(cur_scp, bios_value.bell_pitch, BELL_DURATION);
DPRINTF(5, ("error 2, requested vty isn't open!\n"));
return EINVAL;
}
@@ -2260,7 +2229,7 @@ sc_switch_scr(sc_softc_t *sc, u_int next_scr)
/* this is the start of vty switching process... */
++sc->switch_in_progress;
sc->delayed_next_scr = 0;
- sc->old_scp = sc->cur_scp;
+ sc->old_scp = cur_scp;
sc->new_scp = SC_STAT(SC_DEV(sc, next_scr));
if (sc->new_scp == sc->old_scp) {
sc->switch_in_progress = 0;
@@ -2369,6 +2338,31 @@ signal_vt_acq(scr_stat *scp)
return TRUE;
}
+static int
+finish_vt_rel(scr_stat *scp, int release, int *s)
+{
+ if (scp == scp->sc->old_scp && scp->status & SWITCH_WAIT_REL) {
+ scp->status &= ~SWITCH_WAIT_REL;
+ if (release)
+ *s = do_switch_scr(scp->sc, *s);
+ else
+ scp->sc->switch_in_progress = 0;
+ return 0;
+ }
+ return EINVAL;
+}
+
+static int
+finish_vt_acq(scr_stat *scp)
+{
+ if (scp == scp->sc->new_scp && scp->status & SWITCH_WAIT_ACQ) {
+ scp->status &= ~SWITCH_WAIT_ACQ;
+ scp->sc->switch_in_progress = 0;
+ return 0;
+ }
+ return EINVAL;
+}
+
static void
exchange_scr(sc_softc_t *sc)
{
OpenPOWER on IntegriCloud