summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorJim Rees <rees@cvs.openbsd.org>1999-05-21 16:06:14 +0000
committerJim Rees <rees@cvs.openbsd.org>1999-05-21 16:06:14 +0000
commit4841e21b50bcb344da08f866b6c65d152d68938f (patch)
tree6c59805b7aaad17c8082df79a50bc1e9857c7a5f /sys/arch
parent5d93cb16917fc61776c42af26330311149b8bbae (diff)
Don't turn off uart when closing cua device if tty is waiting.
Instead just drop dtr briefly.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/i386/isa/pccom.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/sys/arch/i386/isa/pccom.c b/sys/arch/i386/isa/pccom.c
index 490e4f186a3..8710482c71f 100644
--- a/sys/arch/i386/isa/pccom.c
+++ b/sys/arch/i386/isa/pccom.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pccom.c,v 1.29 1999/02/08 23:43:54 rees Exp $ */
+/* $OpenBSD: pccom.c,v 1.30 1999/05/21 16:06:13 rees Exp $ */
/* $NetBSD: com.c,v 1.82.4.1 1996/06/02 09:08:00 mrg Exp $ */
/*
@@ -122,6 +122,7 @@ void comattach __P((struct device *, struct device *, void *));
void com_absent_notify __P((struct com_softc *sc));
void comstart_pending __P((void *));
void compwroff __P((struct com_softc *));
+void com_raisedtr __P((void *));
#if NPCCOM_ISA
struct cfattach pccom_isa_ca = {
@@ -1111,9 +1112,13 @@ comopen(dev, flag, mode, p)
(!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,
- ttopen, 0);
- if (error) {
+ error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH, ttopen, 0);
+ /*
+ * If TS_WOPEN has been reset, that means the cua device
+ * has been closed. We don't want to fail in that case,
+ * so just go around again.
+ */
+ if (error && ISSET(tp->t_state, TS_WOPEN)) {
CLR(tp->t_state, TS_WOPEN);
if (!sc->sc_cua && !ISSET(tp->t_state, TS_ISOPEN))
compwroff(sc);
@@ -1135,6 +1140,8 @@ comclose(dev, flag, mode, p)
{
int unit = DEVUNIT(dev);
struct com_softc *sc = pccom_cd.cd_devs[unit];
+ bus_space_tag_t iot = sc->sc_iot;
+ bus_space_handle_t ioh = sc->sc_ioh;
struct tty *tp = sc->sc_tty;
int s;
@@ -1144,8 +1151,17 @@ comclose(dev, flag, mode, p)
(*linesw[tp->t_line].l_close)(tp, flag);
s = spltty();
- if (!ISSET(sc->sc_hwflags, COM_HW_ABSENT|COM_HW_ABSENT_PENDING))
- compwroff(sc);
+ if (!ISSET(sc->sc_hwflags, COM_HW_ABSENT|COM_HW_ABSENT_PENDING)) {
+ if (ISSET(tp->t_state, TS_WOPEN)) {
+ /* tty device is waiting for carrier; drop dtr then re-raise */
+ CLR(sc->sc_mcr, MCR_DTR | MCR_RTS);
+ bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
+ timeout(com_raisedtr, sc, hz * 2);
+ } else {
+ /* no one else waiting; turn off the uart */
+ compwroff(sc);
+ }
+ }
CLR(tp->t_state, TS_BUSY | TS_FLUSH);
sc->sc_cua = 0;
splx(s);
@@ -1181,7 +1197,8 @@ compwroff(sc)
if (ISSET(tp->t_cflag, HUPCL) &&
!ISSET(sc->sc_swflags, COM_SW_SOFTCAR)) {
/* XXX perhaps only clear DTR */
- bus_space_write_1(iot, ioh, com_mcr, 0);
+ sc->sc_mcr = 0;
+ bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr);
}
/*
@@ -1211,6 +1228,16 @@ compwroff(sc)
}
}
+void
+com_raisedtr(arg)
+ void *arg;
+{
+ struct com_softc *sc = arg;
+
+ SET(sc->sc_mcr, MCR_DTR | MCR_RTS);
+ bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr);
+}
+
int
comread(dev, uio, flag)
dev_t dev;