If necessary, defer console output until TX interrupt handler runs.

This commit is contained in:
pk 1997-11-12 22:18:54 +00:00
parent 39879b883e
commit ff4f5f4528

View File

@ -1,4 +1,4 @@
/* $NetBSD: zs.c,v 1.53 1997/11/03 11:33:17 mycroft Exp $ */
/* $NetBSD: zs.c,v 1.54 1997/11/12 22:18:54 pk Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@ -106,6 +106,14 @@ int zs_major = 12;
# error "no suitable software interrupt bit"
#endif
/*
* The next three variables provide a shortcut to the channel state
* structure used by zscnputc().
*/
int zs_console_unit = -1;
int zs_console_channel = -1;
struct zs_chanstate *zs_conschanstate;
#define ZS_DELAY() (CPU_ISSUN4C ? (0) : delay(2))
/* The layout of this is hardware-dependent (padding, order). */
@ -271,6 +279,10 @@ zs_attach(parent, self, aux)
zsc_args.hwflags = zs_hwflags[zs_unit][channel];
cs = &zsc->zsc_cs_store[channel];
zsc->zsc_cs[channel] = cs;
if (zs_unit == zs_console_unit &&
channel == zs_console_channel) {
zs_conschanstate = cs;
}
cs->cs_channel = channel;
cs->cs_private = NULL;
@ -695,6 +707,26 @@ zs_putc(arg, c)
ZS_DELAY();
} while ((rr0 & ZSRR0_TX_READY) == 0);
/*
* If the transmitter was busy doing regular tty I/O (ZSWR1_TIE on),
* defer our output until the transmit interrupt runs. We still
* sync with TX_READY so we can get by with a single-char "queue".
*/
if (zs_conschanstate && (zs_conschanstate->cs_preg[1] & ZSWR1_TIE)) {
/*
* If a previous held character has not yet gone out, we can
* send it now; zsxint() will field the interrupt for our
* char, but doesn't care. We're running at sufficiently
* high spl for this to work.
*/
if (zs_conschanstate->cs_heldchar != 0)
zc->zc_data = zs_conschanstate->cs_heldchar;
zs_conschanstate->cs_heldchar = c;
ZS_DELAY();
splx(s);
return;
}
zc->zc_data = c;
ZS_DELAY();
splx(s);
@ -975,6 +1007,8 @@ setup_console:
cn = &consdev_tty;
cn->cn_dev = makedev(zs_major, zstty_unit);
cn->cn_pri = CN_REMOTE;
zs_console_unit = zs_unit;
zs_console_channel = channel;
break;
}