Redo the N previous changes, plus a couple of other things:
* Move the printf() delay to just after the printf(), where it actually makes sense. * Use zstty_stint() and zstty_softint() from zsparam(), to force an immediate update of the carrier and flow control status. Abuse this in the attach and open functions to defer all of that work. This insures that we don't lose any status updates. * Don't screw with register 1 when closing the console. * Fix bugs in TIOCM??? (stay semicolon, clearing DTR while transmitting). * Add comments in a couple of places.
This commit is contained in:
parent
fb0f57bc28
commit
b63b0fd80b
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: z8530tty.c,v 1.56 1999/01/31 21:41:00 wrstuden Exp $ */
|
||||
/* $NetBSD: z8530tty.c,v 1.57 1999/02/03 20:15:51 mycroft Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998
|
||||
* Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998, 1999
|
||||
* Charles M. Hannum. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -93,6 +93,9 @@
|
|||
* Gordon Ross <gwr@netbsd.org>,
|
||||
* Bill Studenmund <wrstuden@loki.stanford.edu>
|
||||
* Ian Dall <Ian.Dall@dsto.defence.gov.au>
|
||||
*
|
||||
* The driver was massively overhauled in November 1997 by Charles Hannum,
|
||||
* fixing *many* bugs, and substantially improving performance.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -208,6 +211,12 @@ static int zs_to_tiocm __P((struct zs_chanstate *));
|
|||
static int zshwiflow __P((struct tty *, int));
|
||||
static void zs_hwiflow __P((struct zstty_softc *));
|
||||
|
||||
/* Low-level routines. */
|
||||
static void zstty_rxint __P((struct zs_chanstate *));
|
||||
static void zstty_stint __P((struct zs_chanstate *, int));
|
||||
static void zstty_txint __P((struct zs_chanstate *));
|
||||
static void zstty_softint __P((struct zs_chanstate *));
|
||||
|
||||
#define ZSUNIT(x) (minor(x) & 0x7ffff)
|
||||
#define ZSDIALOUT(x) (minor(x) & 0x80000)
|
||||
|
||||
|
@ -263,25 +272,25 @@ zstty_attach(parent, self, aux)
|
|||
printf(" flags 0x%x", zst->zst_swflags);
|
||||
|
||||
if (ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) {
|
||||
printf(" (console)");
|
||||
printf(" (console)\n");
|
||||
DELAY(20000);
|
||||
cn_tab->cn_dev = dev;
|
||||
} else {
|
||||
} else
|
||||
#ifdef KGDB
|
||||
if (zs_check_kgdb(cs, dev)) {
|
||||
/*
|
||||
* Allow kgdb to "take over" this port. Returns true
|
||||
* if this serial port is in-use by kgdb.
|
||||
*/
|
||||
if (zs_check_kgdb(cs, dev)) {
|
||||
printf(" (kgdb)\n");
|
||||
/*
|
||||
* This is the kgdb port (exclusive use)
|
||||
* so skip the normal attach code.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
printf(" (kgdb)\n");
|
||||
/*
|
||||
* This is the kgdb port (exclusive use)
|
||||
* so skip the normal attach code.
|
||||
*/
|
||||
return;
|
||||
} else
|
||||
#endif
|
||||
}
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
|
||||
tp = ttymalloc();
|
||||
tp->t_dev = dev;
|
||||
|
@ -308,25 +317,25 @@ zstty_attach(parent, self, aux)
|
|||
/* Call zsparam similar to open. */
|
||||
struct termios t;
|
||||
|
||||
DELAY(20000);
|
||||
|
||||
s = splzs();
|
||||
|
||||
/* Fetch the current modem control status, needed later. */
|
||||
cs->cs_rr0 = zs_read_csr(cs);
|
||||
|
||||
splx(s);
|
||||
|
||||
/* Setup the "new" parameters in t. */
|
||||
t.c_ispeed = 0;
|
||||
t.c_ospeed = cs->cs_defspeed;
|
||||
t.c_cflag = cs->cs_defcflag;
|
||||
|
||||
s = splzs();
|
||||
|
||||
/*
|
||||
* Turn on receiver and status interrupts.
|
||||
* We defer the actual write of the register to zsparam(),
|
||||
* but we must make sure status interrupts are turned on by
|
||||
* the time zsparam() reads the initial rr0 state.
|
||||
*/
|
||||
SET(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_SIE);
|
||||
|
||||
splx(s);
|
||||
|
||||
/* Make sure zsparam will see changes. */
|
||||
tp->t_ospeed = 0;
|
||||
|
||||
/* Turn on interrupts when zsparam writes the chip. */
|
||||
cs->cs_creg[1] = cs->cs_preg[1] = ZSWR1_RIE | ZSWR1_SIE;
|
||||
|
||||
(void) zsparam(tp, &t);
|
||||
|
||||
s = splzs();
|
||||
|
@ -399,11 +408,11 @@ zs_shutdown(zst)
|
|||
}
|
||||
|
||||
/* Turn off interrupts if not the console. */
|
||||
if (ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE))
|
||||
cs->cs_creg[1] = cs->cs_preg[1] = ZSWR1_RIE | ZSWR1_SIE;
|
||||
else
|
||||
cs->cs_creg[1] = cs->cs_preg[1] = 0;
|
||||
zs_write_reg(cs, 1, cs->cs_creg[1]);
|
||||
if (!ISSET(zst->zst_hwflags, ZS_HWFLAG_CONSOLE)) {
|
||||
CLR(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_SIE);
|
||||
cs->cs_creg[1] = cs->cs_preg[1];
|
||||
zs_write_reg(cs, 1, cs->cs_creg[1]);
|
||||
}
|
||||
|
||||
splx(s);
|
||||
}
|
||||
|
@ -452,17 +461,6 @@ zsopen(dev, flags, mode, p)
|
|||
|
||||
tp->t_dev = dev;
|
||||
|
||||
s2 = splzs();
|
||||
|
||||
/* Turn on interrupts. */
|
||||
cs->cs_creg[1] = cs->cs_preg[1] = ZSWR1_RIE | ZSWR1_SIE;
|
||||
zs_write_reg(cs, 1, cs->cs_creg[1]);
|
||||
|
||||
/* Fetch the current modem control status, needed later. */
|
||||
cs->cs_rr0 = zs_read_csr(cs);
|
||||
|
||||
splx(s2);
|
||||
|
||||
/*
|
||||
* Initialize the termios status to the defaults. Add in the
|
||||
* sticky bits from TIOCSFLAGS.
|
||||
|
@ -478,9 +476,23 @@ zsopen(dev, flags, mode, p)
|
|||
SET(t.c_cflag, CDTRCTS);
|
||||
if (ISSET(zst->zst_swflags, TIOCFLAG_MDMBUF))
|
||||
SET(t.c_cflag, MDMBUF);
|
||||
|
||||
s2 = splzs();
|
||||
|
||||
/*
|
||||
* Turn on receiver and status interrupts.
|
||||
* We defer the actual write of the register to zsparam(),
|
||||
* but we must make sure status interrupts are turned on by
|
||||
* the time zsparam() reads the initial rr0 state.
|
||||
*/
|
||||
SET(cs->cs_preg[1], ZSWR1_RIE | ZSWR1_SIE);
|
||||
|
||||
splx(s2);
|
||||
|
||||
/* Make sure zsparam will see changes. */
|
||||
tp->t_ospeed = 0;
|
||||
(void) zsparam(tp, &t);
|
||||
|
||||
/*
|
||||
* Note: zsparam has done: cflag, ispeed, ospeed
|
||||
* so we just need to do: iflag, oflag, lflag, cc
|
||||
|
@ -835,7 +847,6 @@ zsparam(tp, t)
|
|||
|
||||
cs->cs_rr0_mask = cs->cs_rr0_cts | cs->cs_rr0_dcd;
|
||||
tmp15 = cs->cs_preg[15];
|
||||
#if 1
|
||||
if (ISSET(cs->cs_rr0_mask, ZSRR0_DCD))
|
||||
SET(tmp15, ZSWR15_DCD_IE);
|
||||
else
|
||||
|
@ -844,9 +855,6 @@ zsparam(tp, t)
|
|||
SET(tmp15, ZSWR15_CTS_IE);
|
||||
else
|
||||
CLR(tmp15, ZSWR15_CTS_IE);
|
||||
#else
|
||||
SET(tmp15, ZSWR15_DCD_IE | ZSWR15_CTS_IE);
|
||||
#endif
|
||||
cs->cs_preg[15] = tmp15;
|
||||
|
||||
/* Recompute character size bits. */
|
||||
|
@ -910,8 +918,12 @@ zsparam(tp, t)
|
|||
zs_loadchannelregs(cs);
|
||||
}
|
||||
|
||||
/*
|
||||
* If hardware flow control is disabled, turn off the buffer water
|
||||
* marks and unblock any soft flow control state. Otherwise, enable
|
||||
* the water marks.
|
||||
*/
|
||||
if (!ISSET(cflag, CHWFLOW)) {
|
||||
/* Disable the high water mark. */
|
||||
zst->zst_r_hiwat = 0;
|
||||
zst->zst_r_lowat = 0;
|
||||
if (ISSET(zst->zst_rx_flags, RX_TTY_OVERFLOWED)) {
|
||||
|
@ -929,20 +941,17 @@ zsparam(tp, t)
|
|||
}
|
||||
|
||||
/*
|
||||
* Fetch current state of rr0 - it might have changed if interrupts
|
||||
* were off.
|
||||
* Force a recheck of the hardware carrier and flow control status,
|
||||
* since we may have changed which bits we're looking at.
|
||||
*/
|
||||
cs->cs_rr0 = zs_read_csr(cs);
|
||||
zstty_stint(cs, 1);
|
||||
|
||||
splx(s);
|
||||
|
||||
/*
|
||||
* Update the tty layer's idea of the carrier bit, in case we changed
|
||||
* CLOCAL or MDMBUF. We don't hang up here; we only do that by
|
||||
* explicit request.
|
||||
* If hardware flow control is disabled, unblock any hard flow control
|
||||
* state.
|
||||
*/
|
||||
(void) (*linesw[tp->t_line].l_modem)(tp, ISSET(cs->cs_rr0, ZSRR0_DCD));
|
||||
|
||||
if (!ISSET(cflag, CHWFLOW)) {
|
||||
if (zst->zst_tx_stopped) {
|
||||
zst->zst_tx_stopped = 0;
|
||||
|
@ -950,6 +959,8 @@ zsparam(tp, t)
|
|||
}
|
||||
}
|
||||
|
||||
zstty_softint(cs);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -983,47 +994,46 @@ zs_modem(zst, onoff)
|
|||
}
|
||||
|
||||
static void
|
||||
tiocm_to_zs(zst, cs, how, val)
|
||||
tiocm_to_zs(zst, cs, how, ttybits)
|
||||
struct zstty_softc *zst;
|
||||
struct zs_chanstate *cs;
|
||||
int how, val;
|
||||
int how, ttybits;
|
||||
{
|
||||
int bits = 0, s;
|
||||
int s;
|
||||
u_char zsbits, tmp5;
|
||||
|
||||
if (val & TIOCM_DTR);
|
||||
bits |= ZSWR5_DTR;
|
||||
if (val & TIOCM_RTS)
|
||||
bits |= ZSWR5_RTS;
|
||||
zsbits = 0;
|
||||
if (ISSET(ttybits, TIOCM_DTR))
|
||||
SET(zsbits, ZSWR5_DTR);
|
||||
if (ISSET(ttybits, TIOCM_RTS))
|
||||
SET(zsbits, ZSWR5_RTS);
|
||||
|
||||
s = splzs();
|
||||
|
||||
tmp5 = cs->cs_preg[5];
|
||||
switch (how) {
|
||||
case TIOCMBIC:
|
||||
cs->cs_preg[5] &= ~bits;
|
||||
CLR(tmp5, zsbits);
|
||||
break;
|
||||
|
||||
case TIOCMBIS:
|
||||
cs->cs_preg[5] |= bits;
|
||||
SET(tmp5, zsbits);
|
||||
break;
|
||||
|
||||
case TIOCMSET:
|
||||
cs->cs_preg[5] &= ~(ZSWR5_RTS | ZSWR5_DTR);
|
||||
cs->cs_preg[5] |= bits;
|
||||
break;
|
||||
default:
|
||||
panic("zs: bad command");
|
||||
CLR(tmp5, ZSWR5_RTS | ZSWR5_DTR);
|
||||
SET(tmp5, zsbits);
|
||||
break;
|
||||
}
|
||||
cs->cs_preg[5] = tmp5;
|
||||
|
||||
if (!cs->cs_heldchange) {
|
||||
if (zst->zst_tx_busy) {
|
||||
zst->zst_heldtbc = zst->zst_tbc;
|
||||
zst->zst_tbc = 0;
|
||||
cs->cs_heldchange = 1;
|
||||
} else {
|
||||
cs->cs_creg[5] = cs->cs_preg[5];
|
||||
zs_write_reg(cs, 5, cs->cs_creg[5]);
|
||||
}
|
||||
} else
|
||||
zs_loadchannelregs(cs);
|
||||
}
|
||||
|
||||
splx(s);
|
||||
|
@ -1033,20 +1043,22 @@ static int
|
|||
zs_to_tiocm(cs)
|
||||
struct zs_chanstate *cs;
|
||||
{
|
||||
int bits = 0;
|
||||
u_char m = zs_read_csr(cs);
|
||||
u_char zsbits;
|
||||
int ttybits = 0;
|
||||
|
||||
if (cs->cs_preg[5] & ZSWR5_DTR)
|
||||
bits |= TIOCM_DTR;
|
||||
if (cs->cs_preg[5] & ZSWR5_RTS)
|
||||
bits |= TIOCM_RTS;
|
||||
zsbits = cs->cs_preg[5];
|
||||
if (ISSET(zsbits, ZSWR5_DTR))
|
||||
SET(ttybits, TIOCM_DTR);
|
||||
if (ISSET(zsbits, ZSWR5_RTS))
|
||||
SET(ttybits, TIOCM_RTS);
|
||||
|
||||
if (m & ZSRR0_DCD)
|
||||
bits |= TIOCM_CD;
|
||||
if (m & ZSRR0_CTS)
|
||||
bits |= TIOCM_CTS;
|
||||
zsbits = cs->cs_rr0;
|
||||
if (ISSET(zsbits, ZSRR0_DCD))
|
||||
SET(ttybits, TIOCM_CD);
|
||||
if (ISSET(zsbits, ZSRR0_CTS))
|
||||
SET(ttybits, TIOCM_CTS);
|
||||
|
||||
return bits;
|
||||
return (ttybits);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1116,12 +1128,7 @@ zs_hwiflow(zst)
|
|||
* Interface to the lower layer (zscc)
|
||||
****************************************************************/
|
||||
|
||||
static void zstty_rxint __P((struct zs_chanstate *));
|
||||
static void zstty_txint __P((struct zs_chanstate *));
|
||||
static void zstty_stint __P((struct zs_chanstate *));
|
||||
|
||||
#define integrate static inline
|
||||
static void zstty_softint __P((struct zs_chanstate *));
|
||||
integrate void zstty_rxsoft __P((struct zstty_softc *, struct tty *));
|
||||
integrate void zstty_txsoft __P((struct zstty_softc *, struct tty *));
|
||||
integrate void zstty_stsoft __P((struct zstty_softc *, struct tty *));
|
||||
|
@ -1252,8 +1259,9 @@ zstty_txint(cs)
|
|||
* status change interrupt. (splzs)
|
||||
*/
|
||||
static void
|
||||
zstty_stint(cs)
|
||||
zstty_stint(cs, force)
|
||||
struct zs_chanstate *cs;
|
||||
int force;
|
||||
{
|
||||
struct zstty_softc *zst = cs->cs_private;
|
||||
u_char rr0, delta;
|
||||
|
@ -1271,8 +1279,12 @@ zstty_stint(cs)
|
|||
return;
|
||||
}
|
||||
|
||||
delta = rr0 ^ cs->cs_rr0;
|
||||
if (!force)
|
||||
delta = rr0 ^ cs->cs_rr0;
|
||||
else
|
||||
delta = cs->cs_rr0_mask;
|
||||
cs->cs_rr0 = rr0;
|
||||
|
||||
if (ISSET(delta, cs->cs_rr0_mask)) {
|
||||
SET(cs->cs_rr0_delta, delta);
|
||||
|
||||
|
|
Loading…
Reference in New Issue