summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJim Rees <rees@cvs.openbsd.org>1999-02-08 23:43:55 +0000
committerJim Rees <rees@cvs.openbsd.org>1999-02-08 23:43:55 +0000
commitb45206b9b5c7445dab9dba61b43ec0177c17c2e7 (patch)
treed1249eeb948020753832d129e92a5c9396d38a37 /sys
parentf42bc004f564dd15d1f642bd97c0d4e9f325665f (diff)
Fix cua device to not block on open.
Turn off chip (and dtr) on interrupted open.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/i386/isa/pccom.c137
1 files changed, 69 insertions, 68 deletions
diff --git a/sys/arch/i386/isa/pccom.c b/sys/arch/i386/isa/pccom.c
index 9b4f3fee2ab..490e4f186a3 100644
--- a/sys/arch/i386/isa/pccom.c
+++ b/sys/arch/i386/isa/pccom.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pccom.c,v 1.28 1999/01/21 08:55:08 niklas Exp $ */
+/* $OpenBSD: pccom.c,v 1.29 1999/02/08 23:43:54 rees Exp $ */
/* $NetBSD: com.c,v 1.82.4.1 1996/06/02 09:08:00 mrg Exp $ */
/*
@@ -121,6 +121,7 @@ int comprobe __P((struct device *, void *, void *));
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 *));
#if NPCCOM_ISA
struct cfattach pccom_isa_ca = {
@@ -1097,39 +1098,32 @@ comopen(dev, flag, mode, p)
return EBUSY;
}
sc->sc_cua = 1; /* We go into CUA mode */
- }
-
- /* wait for carrier if necessary */
- 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 (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,
- ttopen, 0);
- if (!DEVCUA(dev) && sc->sc_cua && error == EINTR)
- continue;
- if (error) {
- /* XXX should turn off chip if we're the
- only waiter */
- if (DEVCUA(dev))
- sc->sc_cua = 0;
- CLR(tp->t_state, TS_WOPEN);
+ /* tty (not cua) device; wait for carrier if necessary */
+ if (ISSET(flag, O_NONBLOCK)) {
+ if (sc->sc_cua) {
+ /* Opening TTY non-blocking... but the CUA is busy */
splx(s);
- return error;
+ return EBUSY;
+ }
+ } else {
+ while (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,
+ ttopen, 0);
+ if (error) {
+ CLR(tp->t_state, TS_WOPEN);
+ if (!sc->sc_cua && !ISSET(tp->t_state, TS_ISOPEN))
+ compwroff(sc);
+ splx(s);
+ return error;
+ }
}
- if (!DEVCUA(dev) && sc->sc_cua)
- continue;
}
}
splx(s);
-
return (*linesw[tp->t_line].l_open)(dev, tp);
}
@@ -1142,8 +1136,6 @@ comclose(dev, flag, mode, p)
int unit = DEVUNIT(dev);
struct com_softc *sc = pccom_cd.cd_devs[unit];
struct tty *tp = sc->sc_tty;
- bus_space_tag_t iot = sc->sc_iot;
- bus_space_handle_t ioh = sc->sc_ioh;
int s;
/* XXX This is for cons.c. */
@@ -1152,43 +1144,8 @@ 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)) {
- /* can't do any of this stuff .... */
- CLR(sc->sc_lcr, LCR_SBREAK);
- bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr);
- bus_space_write_1(iot, ioh, com_ier, 0);
- 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);
- }
-
- /*
- * Turn FIFO off; enter sleep mode if possible.
- */
- bus_space_write_1(iot, ioh, com_fifo, 0);
- delay(100);
- (void) bus_space_read_1(iot, ioh, com_data);
- delay(100);
- bus_space_write_1(iot, ioh, com_fifo,
- FIFO_RCV_RST | FIFO_XMT_RST);
-
- switch (sc->sc_uarttype) {
- case COM_UART_ST16650:
- case COM_UART_ST16650V2:
- case COM_UART_XR16850:
- bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
- bus_space_write_1(iot, ioh, com_efr, EFR_ECB);
- bus_space_write_1(iot, ioh, com_ier, IER_SLEEP);
- bus_space_write_1(iot, ioh, com_lcr, 0);
- break;
-#ifdef notyet
- case COM_UART_TI16750:
- bus_space_write_1(iot, ioh, com_ier, IER_SLEEP);
- break;
-#endif
- }
- }
+ if (!ISSET(sc->sc_hwflags, COM_HW_ABSENT|COM_HW_ABSENT_PENDING))
+ compwroff(sc);
CLR(tp->t_state, TS_BUSY | TS_FLUSH);
sc->sc_cua = 0;
splx(s);
@@ -1209,7 +1166,51 @@ comclose(dev, flag, mode, p)
#endif
return 0;
}
-
+
+void
+compwroff(sc)
+ struct com_softc *sc;
+{
+ bus_space_tag_t iot = sc->sc_iot;
+ bus_space_handle_t ioh = sc->sc_ioh;
+ struct tty *tp = sc->sc_tty;
+
+ CLR(sc->sc_lcr, LCR_SBREAK);
+ bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr);
+ bus_space_write_1(iot, ioh, com_ier, 0);
+ 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);
+ }
+
+ /*
+ * Turn FIFO off; enter sleep mode if possible.
+ */
+ bus_space_write_1(iot, ioh, com_fifo, 0);
+ delay(100);
+ (void) bus_space_read_1(iot, ioh, com_data);
+ delay(100);
+ bus_space_write_1(iot, ioh, com_fifo,
+ FIFO_RCV_RST | FIFO_XMT_RST);
+
+ switch (sc->sc_uarttype) {
+ case COM_UART_ST16650:
+ case COM_UART_ST16650V2:
+ case COM_UART_XR16850:
+ bus_space_write_1(iot, ioh, com_lcr, LCR_EFR);
+ bus_space_write_1(iot, ioh, com_efr, EFR_ECB);
+ bus_space_write_1(iot, ioh, com_ier, IER_SLEEP);
+ bus_space_write_1(iot, ioh, com_lcr, 0);
+ break;
+#ifdef notyet
+ case COM_UART_TI16750:
+ bus_space_write_1(iot, ioh, com_ier, IER_SLEEP);
+ break;
+#endif
+ }
+}
+
int
comread(dev, uio, flag)
dev_t dev;