diff options
| author | leo <leo@NetBSD.org> | 1998-03-25 09:46:09 +0000 |
|---|---|---|
| committer | leo <leo@NetBSD.org> | 1998-03-25 09:46:09 +0000 |
| commit | e32073cbb13f56b0c0fc80b6042f3aa33ca73f67 (patch) | |
| tree | f59f66e83d4b15de948e9fed9bae2bbee7fd6cd4 /sys | |
| parent | b40a3c98f5ca34471b7b6c2e00d4d5e20fc0110d (diff) | |
Sync with latest tty changes.
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/arch/atari/dev/ite.c | 46 | ||||
| -rw-r--r-- | sys/arch/atari/dev/ser.c | 125 | ||||
| -rw-r--r-- | sys/arch/atari/dev/zs.c | 132 | ||||
| -rw-r--r-- | sys/arch/atari/dev/zsvar.h | 5 |
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) |
