diff options
Diffstat (limited to 'sys/arch/i386/isa/pccom.c')
-rw-r--r-- | sys/arch/i386/isa/pccom.c | 55 |
1 files changed, 40 insertions, 15 deletions
diff --git a/sys/arch/i386/isa/pccom.c b/sys/arch/i386/isa/pccom.c index c66dce26ab4..d235d46cbb9 100644 --- a/sys/arch/i386/isa/pccom.c +++ b/sys/arch/i386/isa/pccom.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pccom.c,v 1.2 1996/07/28 05:07:06 downsj Exp $ */ +/* $OpenBSD: pccom.c,v 1.3 1996/08/29 12:58:32 deraadt Exp $ */ /* $NetBSD: com.c,v 1.82.4.1 1996/06/02 09:08:00 mrg Exp $ */ /*- @@ -107,6 +107,8 @@ struct com_softc { u_char sc_msr, sc_mcr, sc_lcr, sc_ier; u_char sc_dtr; + u_char sc_cua; + #define RBUFSIZE 512 #define RBUFMASK 511 u_int sc_rxget; @@ -193,7 +195,8 @@ extern int kgdb_rate; extern int kgdb_debug_init; #endif -#define PCCOMUNIT(x) (minor(x)) +#define DEVUNIT(x) (minor(x) & 0x7f) +#define DEVCUA(x) (minor(x) & 0x80) /* Macros to clear/set/test flags. */ #define SET(t, f) (t) |= (f) @@ -748,7 +751,7 @@ comopen(dev, flag, mode, p) int flag, mode; struct proc *p; { - int unit = PCCOMUNIT(dev); + int unit = DEVUNIT(dev); struct com_softc *sc; bus_chipset_tag_t bc; bus_io_handle_t ioh; @@ -762,11 +765,13 @@ comopen(dev, flag, mode, p) if (!sc || ISSET(sc->sc_hwflags, COM_HW_ABSENT|COM_HW_ABSENT_PENDING)) return ENXIO; + s = spltty(); if (!sc->sc_tty) { tp = sc->sc_tty = ttymalloc(); tty_attach(tp); } else tp = sc->sc_tty; + splx(s); tp->t_oproc = comstart; tp->t_param = comparam; @@ -870,7 +875,7 @@ comopen(dev, flag, mode, p) bus_io_write_1(bc, ioh, com_ier, sc->sc_ier); sc->sc_msr = bus_io_read_1(bc, ioh, com_msr); - if (ISSET(sc->sc_swflags, COM_SW_SOFTCAR) || + if (ISSET(sc->sc_swflags, COM_SW_SOFTCAR) || DEVCUA(dev) || ISSET(sc->sc_msr, MSR_DCD) || ISSET(tp->t_cflag, MDMBUF)) SET(tp->t_state, TS_CARR_ON); else @@ -880,9 +885,25 @@ comopen(dev, flag, mode, p) else s = spltty(); + if (DEVCUA(dev)) { + if (ISSET(tp->t_state, TS_ISOPEN)) { + /* Ah, but someone already is dialed in... */ + splx(s); + return EBUSY; + } + sc->sc_cua = 1; /* We go into CUA mode */ + } + /* wait for carrier if necessary */ - if (!ISSET(flag, O_NONBLOCK)) - while (!ISSET(tp->t_cflag, CLOCAL) && + if (ISSET(flag, O_NONBLOCK)) { + if (!DEVCUA(dev) && sc->sc_cua) { + /* Opening TTY non-blocking... but the CUA is busy */ + splx(s); + return EBUSY; + } + } else { + while (!(DEVCUA(dev) && sc->sc_cua) && + !ISSET(tp->t_cflag, CLOCAL) && !ISSET(tp->t_state, TS_CARR_ON)) { SET(tp->t_state, TS_WOPEN); error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH, @@ -890,10 +911,13 @@ comopen(dev, flag, mode, p) if (error) { /* XXX should turn off chip if we're the only waiter */ + if (DEVCUA(dev)) + sc->sc_cua = 0; splx(s); return error; } } + } splx(s); return (*linesw[tp->t_line].l_open)(dev, tp); @@ -905,7 +929,7 @@ comclose(dev, flag, mode, p) int flag, mode; struct proc *p; { - int unit = PCCOMUNIT(dev); + int unit = DEVUNIT(dev); struct com_softc *sc = pccom_cd.cd_devs[unit]; struct tty *tp = sc->sc_tty; bus_chipset_tag_t bc = sc->sc_bc; @@ -934,6 +958,7 @@ comclose(dev, flag, mode, p) * FIFO off */ bus_io_write_1(bc, ioh, com_fifo, 0); + sc->sc_cua = 0; splx(s); ttyclose(tp); #ifdef PCCOM_DEBUG @@ -959,7 +984,7 @@ comread(dev, uio, flag) struct uio *uio; int flag; { - struct com_softc *sc = pccom_cd.cd_devs[PCCOMUNIT(dev)]; + struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(dev)]; struct tty *tp = sc->sc_tty; if (ISSET(sc->sc_hwflags, COM_HW_ABSENT|COM_HW_ABSENT_PENDING)) { @@ -978,7 +1003,7 @@ comwrite(dev, uio, flag) struct uio *uio; int flag; { - struct com_softc *sc = pccom_cd.cd_devs[PCCOMUNIT(dev)]; + struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(dev)]; struct tty *tp = sc->sc_tty; if (ISSET(sc->sc_hwflags, COM_HW_ABSENT|COM_HW_ABSENT_PENDING)) { @@ -995,7 +1020,7 @@ struct tty * comtty(dev) dev_t dev; { - struct com_softc *sc = pccom_cd.cd_devs[PCCOMUNIT(dev)]; + struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(dev)]; struct tty *tp = sc->sc_tty; return (tp); @@ -1022,7 +1047,7 @@ comioctl(dev, cmd, data, flag, p) int flag; struct proc *p; { - int unit = PCCOMUNIT(dev); + int unit = DEVUNIT(dev); struct com_softc *sc = pccom_cd.cd_devs[unit]; struct tty *tp = sc->sc_tty; bus_chipset_tag_t bc = sc->sc_bc; @@ -1142,7 +1167,7 @@ comparam(tp, t) struct tty *tp; struct termios *t; { - struct com_softc *sc = pccom_cd.cd_devs[PCCOMUNIT(tp->t_dev)]; + struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(tp->t_dev)]; bus_chipset_tag_t bc = sc->sc_bc; bus_io_handle_t ioh = sc->sc_ioh; int ospeed = comspeed(t->c_ospeed); @@ -1304,7 +1329,7 @@ comhwiflow(tp, block) struct tty *tp; int block; { - struct com_softc *sc = pccom_cd.cd_devs[PCCOMUNIT(tp->t_dev)]; + struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(tp->t_dev)]; bus_chipset_tag_t bc = sc->sc_bc; bus_io_handle_t ioh = sc->sc_ioh; int s; @@ -1345,7 +1370,7 @@ void comstart(tp) struct tty *tp; { - struct com_softc *sc = pccom_cd.cd_devs[PCCOMUNIT(tp->t_dev)]; + struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(tp->t_dev)]; bus_chipset_tag_t bc = sc->sc_bc; bus_io_handle_t ioh = sc->sc_ioh; int s, count; @@ -1414,7 +1439,7 @@ comstop(tp, flag) int flag; { int s; - struct com_softc *sc = pccom_cd.cd_devs[PCCOMUNIT(tp->t_dev)]; + struct com_softc *sc = pccom_cd.cd_devs[DEVUNIT(tp->t_dev)]; s = splhigh(); if (ISSET(tp->t_state, TS_BUSY)) { |