summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorleo <leo@NetBSD.org>1998-03-25 09:46:09 +0000
committerleo <leo@NetBSD.org>1998-03-25 09:46:09 +0000
commite32073cbb13f56b0c0fc80b6042f3aa33ca73f67 (patch)
treef59f66e83d4b15de948e9fed9bae2bbee7fd6cd4 /sys
parentb40a3c98f5ca34471b7b6c2e00d4d5e20fc0110d (diff)
Sync with latest tty changes.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/atari/dev/ite.c46
-rw-r--r--sys/arch/atari/dev/ser.c125
-rw-r--r--sys/arch/atari/dev/zs.c132
-rw-r--r--sys/arch/atari/dev/zsvar.h5
4 files changed, 185 insertions, 123 deletions
diff --git a/sys/arch/atari/dev/ite.c b/sys/arch/atari/dev/ite.c
index 16a90342b96..29cf09f7bdf 100644
--- a/sys/arch/atari/dev/ite.c
+++ b/sys/arch/atari/dev/ite.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ite.c,v 1.24 1998/01/12 18:04:06 thorpej Exp $ */
+/* $NetBSD: ite.c,v 1.25 1998/03/25 09:46:09 leo Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@@ -52,6 +52,7 @@
#include <sys/conf.h>
#include <sys/device.h>
#include <sys/malloc.h>
+#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <sys/tty.h>
#include <sys/termios.h>
@@ -411,29 +412,42 @@ iteopen(dev, mode, devtype, p)
return (error);
first = 1;
}
- tp->t_oproc = itestart;
- tp->t_param = ite_param;
- tp->t_dev = dev;
- if ((tp->t_state & TS_ISOPEN) == 0) {
- ttychars(tp);
+ if (!(tp->t_state & TS_ISOPEN) && tp->t_wopen == 0) {
+ tp->t_oproc = itestart;
+ tp->t_param = ite_param;
+ tp->t_dev = dev;
tp->t_iflag = TTYDEF_IFLAG;
tp->t_oflag = TTYDEF_OFLAG;
tp->t_cflag = TTYDEF_CFLAG;
tp->t_lflag = TTYDEF_LFLAG;
tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
- tp->t_state = TS_WOPEN | TS_CARR_ON;
+ tp->t_state = TS_CARR_ON;
+ ttychars(tp);
ttsetwater(tp);
}
+
+
+ error = ttyopen(tp, 0, (mode & O_NONBLOCK) ? 1 : 0);
+ if (error)
+ goto bad;
+
error = (*linesw[tp->t_line].l_open) (dev, tp);
- if (error == 0) {
- tp->t_winsize.ws_row = ip->rows;
- tp->t_winsize.ws_col = ip->cols;
- if (!kbd_init) {
- kbd_init = 1;
- kbdenable();
- }
- } else if (first)
+ if (error)
+ goto bad;
+
+ tp->t_winsize.ws_row = ip->rows;
+ tp->t_winsize.ws_col = ip->cols;
+ if (!kbd_init) {
+ kbd_init = 1;
+ kbdenable();
+ }
+ return (0);
+
+
+bad:
+ if (first)
ite_off(dev, 0);
+
return (error);
}
@@ -688,7 +702,7 @@ int flag;
ip->flags &= ~ITE_ACTIVE;
}
-static void
+void
ite_switch(unit)
int unit;
{
diff --git a/sys/arch/atari/dev/ser.c b/sys/arch/atari/dev/ser.c
index d4e3a5edbba..70c73d8a8a7 100644
--- a/sys/arch/atari/dev/ser.c
+++ b/sys/arch/atari/dev/ser.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ser.c,v 1.3 1998/01/12 18:04:15 thorpej Exp $ */
+/* $NetBSD: ser.c,v 1.4 1998/03/25 09:46:10 leo Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -62,7 +62,8 @@
/* #define SER_DEBUG */
-#define SERUNIT(x) (minor(x))
+#define SERUNIT(x) (minor(x) & 0x7ffff)
+#define SERDIALOUT(x) (minor(x) & 0x80000)
/* XXX */
#define CONSBAUD 9600
@@ -158,6 +159,7 @@ void sercnpollc __P((dev_t, int));
static void sermsrint __P((struct ser_softc *, struct tty*));
static void serrxint __P((struct ser_softc *, struct tty*));
+static void ser_shutdown __P((struct ser_softc *));
static int serspeed __P((long));
static void sersoft __P((void *));
static void sertxint __P((struct ser_softc *, struct tty*));
@@ -297,13 +299,10 @@ seropen(dev, flag, mode, p)
s = spltty();
- /* We need to set this early for the benefit of sersoft(). */
- SET(tp->t_state, TS_WOPEN);
-
/*
* Do the following if this is a first open.
*/
- if (!ISSET(tp->t_state, TS_ISOPEN)) {
+ if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
struct termios t;
/* Turn on interrupts. */
@@ -370,33 +369,28 @@ seropen(dev, flag, mode, p)
splx(s2);
}
- error = 0;
-
- /* If we're doing a blocking open... */
- if (!ISSET(flag, O_NONBLOCK))
- /* ...then wait for carrier. */
- while (!ISSET(tp->t_state, TS_CARR_ON) &&
- !ISSET(tp->t_cflag, CLOCAL | MDMBUF)) {
- error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH,
- ttopen, 0);
- if (error) {
- /*
- * If the open was interrupted and nobody
- * else has the device open, then hang up.
- */
- if (!ISSET(tp->t_state, TS_ISOPEN)) {
- ser_modem(sc, 0);
- CLR(tp->t_state, TS_WOPEN);
- ttwakeup(tp);
- }
- break;
- }
- SET(tp->t_state, TS_WOPEN);
- }
splx(s);
- if (error == 0)
- error = (*linesw[tp->t_line].l_open)(dev, tp);
+
+ error = ttyopen(tp, SERDIALOUT(dev), ISSET(flag, O_NONBLOCK));
+ if (error)
+ goto bad;
+
+ error = (*linesw[tp->t_line].l_open)(dev, tp);
+ if (error)
+ goto bad;
+
+ return (0);
+
+bad:
+ if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
+ /*
+ * We failed to open the device, and nobody else had it opened.
+ * Clean up the state as appropriate.
+ */
+ ser_shutdown(sc);
+ }
+
return (error);
}
@@ -409,7 +403,6 @@ serclose(dev, flag, mode, p)
int unit = SERUNIT(dev);
struct ser_softc *sc = ser_cd.cd_devs[unit];
struct tty *tp = sc->sc_tty;
- int s;
/* XXX This is for cons.c. */
if (!ISSET(tp->t_state, TS_ISOPEN))
@@ -418,30 +411,15 @@ serclose(dev, flag, mode, p)
(*linesw[tp->t_line].l_close)(tp, flag);
ttyclose(tp);
- /* If we were asserting flow control, then deassert it. */
- sc->sc_rx_blocked = 1;
- ser_hwiflow(sc, 1);
-
- /* Clear any break condition set with TIOCSBRK. */
- ser_break(sc, 0);
-
- /*
- * Hang up if necessary. Wait a bit, so the other side has time to
- * notice even if we immediately open the port again.
- */
- if (ISSET(tp->t_cflag, HUPCL)) {
- ser_modem(sc, 0);
- (void) tsleep(sc, TTIPRI, ttclos, hz);
+ if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
+ /*
+ * Although we got a last close, the device may still be in
+ * use; e.g. if this was the dialout node, and there are still
+ * processes waiting for carrier on the non-dialout node.
+ */
+ ser_shutdown(sc);
}
- s = splserial();
- /* Turn off interrupts. */
- CLR(sc->sc_imra, IA_RRDY|IA_RERR|IA_TRDY|IA_TERR);
- CLR(sc->sc_imrb, IB_SCTS|IB_SDCD);
- single_inst_bclr_b(MFP->mf_imrb, IB_SCTS|IB_SDCD);
- single_inst_bclr_b(MFP->mf_imra, IA_RRDY|IA_RERR|IA_TRDY|IA_TERR);
- splx(s);
-
return (0);
}
@@ -978,6 +956,40 @@ serdiag(arg)
floods, floods == 1 ? "" : "s");
}
+static
+void ser_shutdown(sc)
+ struct ser_softc *sc;
+{
+ int s;
+ struct tty *tp = sc->sc_tty;
+
+
+ s = splserial();
+
+ /* If we were asserting flow control, then deassert it. */
+ sc->sc_rx_blocked = 1;
+ ser_hwiflow(sc, 1);
+
+ /* Clear any break condition set with TIOCSBRK. */
+ ser_break(sc, 0);
+
+ /*
+ * Hang up if necessary. Wait a bit, so the other side has time to
+ * notice even if we immediately open the port again.
+ */
+ if (ISSET(tp->t_cflag, HUPCL)) {
+ ser_modem(sc, 0);
+ (void) tsleep(sc, TTIPRI, ttclos, hz);
+ }
+
+ /* Turn off interrupts. */
+ CLR(sc->sc_imra, IA_RRDY|IA_RERR|IA_TRDY|IA_TERR);
+ CLR(sc->sc_imrb, IB_SCTS|IB_SDCD);
+ single_inst_bclr_b(MFP->mf_imrb, IB_SCTS|IB_SDCD);
+ single_inst_bclr_b(MFP->mf_imra, IA_RRDY|IA_RERR|IA_TRDY|IA_TERR);
+ splx(s);
+}
+
static void
serrxint(sc, tp)
struct ser_softc *sc;
@@ -1097,7 +1109,10 @@ sersoft(arg)
ser_softintr_scheduled = 0;
tp = sc->sc_tty;
- if (tp == NULL || !ISSET(tp->t_state, TS_ISOPEN | TS_WOPEN))
+ if (tp == NULL)
+ return;
+
+ if (!ISSET(tp->t_state, TS_ISOPEN) && (tp->t_wopen == 0))
return;
if (sc->sc_rx_ready) {
diff --git a/sys/arch/atari/dev/zs.c b/sys/arch/atari/dev/zs.c
index cbdf0ecbab3..ca6fa056379 100644
--- a/sys/arch/atari/dev/zs.c
+++ b/sys/arch/atari/dev/zs.c
@@ -1,4 +1,4 @@
-/* $NetBSD: zs.c,v 1.28 1998/01/12 18:04:17 thorpej Exp $ */
+/* $NetBSD: zs.c,v 1.29 1998/03/25 09:46:10 leo Exp $ */
/*
* Copyright (c) 1995 L. Weppelman (Atari modifications)
@@ -224,6 +224,7 @@ static int zsparam __P((struct tty *, struct termios *));
static int zsbaudrate __P((int, int, int *, int *, int *, int *));
static int zs_modem __P((struct zs_chanstate *, int, int));
static void zs_loadchannelregs __P((volatile struct zschan *, u_char *));
+static void zs_shutdown __P((struct zs_chanstate *));
static int zsshortcuts; /* number of "shortcut" software interrupts */
@@ -360,9 +361,17 @@ struct proc *p;
tp->t_param = zsparam;
}
+ if ((tp->t_state & TS_ISOPEN) &&
+ (tp->t_state & TS_XCLUDE) &&
+ p->p_ucred->cr_uid != 0)
+ return (EBUSY);
+
s = spltty();
- if((tp->t_state & TS_ISOPEN) == 0) {
- ttychars(tp);
+
+ /*
+ * Do the following iff this is a first open.
+ */
+ if (!(tp->t_state & TS_ISOPEN) && tp->t_wopen == 0) {
if(tp->t_ispeed == 0) {
tp->t_iflag = TTYDEF_IFLAG;
tp->t_oflag = TTYDEF_OFLAG;
@@ -370,43 +379,45 @@ struct proc *p;
tp->t_lflag = TTYDEF_LFLAG;
tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
}
- (void)zsparam(tp, &tp->t_termios);
+ ttychars(tp);
ttsetwater(tp);
- }
- else if(tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) {
- splx(s);
- return (EBUSY);
- }
- error = 0;
- for(;;) {
- /* loop, turning on the device, until carrier present */
- zs_modem(cs, ZSWR5_RTS|ZSWR5_DTR, DMSET);
+ (void)zsparam(tp, &tp->t_termios);
+
+ /*
+ * Turn on DTR. We must always do this, even if carrier is not
+ * present, because otherwise we'd have to use TIOCSDTR
+ * immediately after setting CLOCAL, which applications do not
+ * expect. We always assert DTR while the device is open
+ * unless explicitly requested to deassert it.
+ */
+ zs_modem(cs, ZSWR5_RTS|ZSWR5_DTR, DMSET);
/* May never get a status intr. if DCD already on. -gwr */
if((cs->cs_rr0 = cs->cs_zc->zc_csr) & ZSRR0_DCD)
tp->t_state |= TS_CARR_ON;
if(cs->cs_softcar)
tp->t_state |= TS_CARR_ON;
- if(flags & O_NONBLOCK || tp->t_cflag & CLOCAL ||
- tp->t_state & TS_CARR_ON)
- break;
- tp->t_state |= TS_WOPEN;
- if((error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
- ttopen, 0)) != 0) {
- if(!(tp->t_state & TS_ISOPEN)) {
- zs_modem(cs, 0, DMSET);
- tp->t_state &= ~TS_WOPEN;
- ttwakeup(tp);
- }
- splx(s);
- return error;
- }
}
+
splx(s);
- if(error == 0)
- error = linesw[tp->t_line].l_open(dev, tp);
+
+ error = ttyopen(tp, ZS_DIALOUT(dev), (flags & O_NONBLOCK));
+ if (error)
+ goto bad;
+
+ error = linesw[tp->t_line].l_open(dev, tp);
if(error)
- zs_modem(cs, 0, DMSET);
+ goto bad;
+ return (0);
+
+bad:
+ if (!(tp->t_state & TS_ISOPEN) && tp->t_wopen == 0) {
+ /*
+ * We failed to open the device, and nobody else had it opened.
+ * Clean up the state as appropriate.
+ */
+ zs_shutdown(cs);
+ }
return(error);
}
@@ -424,33 +435,22 @@ struct proc *p;
register struct tty *tp;
struct zs_softc *zi;
int unit = ZS_UNIT(dev);
- int s;
zi = zs_cd.cd_devs[unit >> 1];
cs = &zi->zi_cs[unit & 1];
tp = cs->cs_ttyp;
+
linesw[tp->t_line].l_close(tp, flags);
- if(tp->t_cflag & HUPCL || tp->t_state & TS_WOPEN ||
- (tp->t_state & TS_ISOPEN) == 0) {
- zs_modem(cs, 0, DMSET);
- /* hold low for 1 second */
- (void)tsleep((caddr_t)cs, TTIPRI, ttclos, hz);
- }
- if(cs->cs_creg[5] & ZSWR5_BREAK) {
- s = splzs();
- cs->cs_preg[5] &= ~ZSWR5_BREAK;
- cs->cs_creg[5] &= ~ZSWR5_BREAK;
- ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
- splx(s);
- }
ttyclose(tp);
- /*
- * Drop all lines and cancel interrupts
- */
- s = splzs();
- zs_loadchannelregs(cs->cs_zc, zs_init_regs);
- splx(s);
+ if (!(tp->t_state & TS_ISOPEN) && tp->t_wopen == 0) {
+ /*
+ * Although we got a last close, the device may still be in
+ * use; e.g. if this was the dialout node, and there are still
+ * processes waiting for carrier on the non-dialout node.
+ */
+ zs_shutdown(cs);
+ }
return (0);
}
@@ -1002,6 +1002,38 @@ register struct tty *tp;
splx(s);
}
+static void
+zs_shutdown(cs)
+ struct zs_chanstate *cs;
+{
+ struct tty *tp = cs->cs_ttyp;
+ int s;
+
+ s = splzs();
+
+ /*
+ * Hang up if necessary. Wait a bit, so the other side has time to
+ * notice even if we immediately open the port again.
+ */
+ if(tp->t_cflag & HUPCL) {
+ zs_modem(cs, 0, DMSET);
+ (void)tsleep((caddr_t)cs, TTIPRI, ttclos, hz);
+ }
+
+ /* Clear any break condition set with TIOCSBRK. */
+ if(cs->cs_creg[5] & ZSWR5_BREAK) {
+ cs->cs_preg[5] &= ~ZSWR5_BREAK;
+ cs->cs_creg[5] &= ~ZSWR5_BREAK;
+ ZS_WRITE(cs->cs_zc, 5, cs->cs_creg[5]);
+ }
+
+ /*
+ * Drop all lines and cancel interrupts
+ */
+ zs_loadchannelregs(cs->cs_zc, zs_init_regs);
+ splx(s);
+}
+
/*
* Set ZS tty parameters from termios.
*
diff --git a/sys/arch/atari/dev/zsvar.h b/sys/arch/atari/dev/zsvar.h
index 35d5f374cb2..f43dbdec7a4 100644
--- a/sys/arch/atari/dev/zsvar.h
+++ b/sys/arch/atari/dev/zsvar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: zsvar.h,v 1.5 1996/01/24 19:26:40 gwr Exp $ */
+/* $NetBSD: zsvar.h,v 1.6 1998/03/25 09:46:10 leo Exp $ */
/*
* Copyright (c) 1995 Leo Weppelman (Atari modifications)
@@ -156,7 +156,8 @@ struct zs_chanstate {
#define ZS_WRITE(c, r, v) ((c)->zc_csr = (r), (c)->zc_csr = (v))
/*
- * Split minor into unit & flag nibble.
+ * Split minor into unit, dialin/dialout & flag nibble.
*/
#define ZS_UNIT(dev) ((minor(dev) >> 4) & 0xf)
#define ZS_FLAGS(dev) (minor(dev) & 0xf)
+#define ZS_DIALOUT(dev) (minor(dev) & 0x80000)