aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Hurd <shurd@FreeBSD.org>2019-06-12 18:07:04 +0000
committerStephen Hurd <shurd@FreeBSD.org>2019-06-12 18:07:04 +0000
commit705aad98c64572aefe9bdb8f1fd854f976c1b03d (patch)
treea16bee1d7069dfb81f667ff7dcbee04f821f542c
parent0026d8ccb7296de6f66d3f2d2813b1a5f77b4035 (diff)
downloadsrc-705aad98c64572aefe9bdb8f1fd854f976c1b03d.tar.gz
src-705aad98c64572aefe9bdb8f1fd854f976c1b03d.zip
Some devices take undesired actions when RTS and DTR are
asserted. Some development boards for example will reset on DTR, and some radio interfaces will transmit on RTS. This patch allows "stty -f /dev/ttyu9.init -rtsdtr" to prevent RTS and DTR from being asserted on open(), allowing these devices to be used without problems. Reviewed by: imp Differential Revision: https://reviews.freebsd.org/D20031
Notes
Notes: svn path=/head/; revision=348999
-rw-r--r--bin/stty/modes.c2
-rw-r--r--bin/stty/print.c6
-rw-r--r--bin/stty/stty.12
-rw-r--r--share/man/man4/termios.48
-rw-r--r--sys/dev/uart/uart_tty.c9
-rw-r--r--sys/dev/usb/serial/umcs.c4
-rw-r--r--sys/dev/usb/serial/usb_serial.c3
-rw-r--r--sys/kern/tty.c5
-rw-r--r--sys/sys/_termios.h1
9 files changed, 33 insertions, 7 deletions
diff --git a/bin/stty/modes.c b/bin/stty/modes.c
index e34afb83ee38..0fe4e5168d2c 100644
--- a/bin/stty/modes.c
+++ b/bin/stty/modes.c
@@ -91,6 +91,8 @@ static const struct modes cmodes[] = {
{ "-rtsflow", 0, CRTS_IFLOW },
{ "mdmbuf", MDMBUF, 0 },
{ "-mdmbuf", 0, MDMBUF },
+ { "rtsdtr", 0, CNO_RTSDTR },
+ { "-rtsdtr", CNO_RTSDTR, 0 },
{ NULL, 0, 0 },
};
diff --git a/bin/stty/print.c b/bin/stty/print.c
index 03d5c3b8a770..a76cd46b765e 100644
--- a/bin/stty/print.c
+++ b/bin/stty/print.c
@@ -184,6 +184,12 @@ print(struct termios *tp, struct winsize *wp, int ldisc, enum FMT fmt)
put("-dsrflow", CDSR_OFLOW, 0);
put("-dtrflow", CDTR_IFLOW, 0);
put("-mdmbuf", MDMBUF, 0); /* XXX mdmbuf == dtrflow */
+ if (on(CNO_RTSDTR))
+ bput("-rtsdtr");
+ else {
+ if (fmt >= BSD)
+ bput("rtsdtr");
+ }
/* special control characters */
cc = tp->c_cc;
diff --git a/bin/stty/stty.1 b/bin/stty/stty.1
index a0f76fe2bfd1..1863c2286176 100644
--- a/bin/stty/stty.1
+++ b/bin/stty/stty.1
@@ -145,6 +145,8 @@ Assume a line without (with) modem
control.
.It Cm crtscts Pq Fl crtscts
Enable (disable) RTS/CTS flow control.
+.It Cm rtsdtr Pq Fl -rtsdtr
+Enable (disable) asserting RTS/DTR on open.
.El
.Ss Input Modes:
This corresponds to the c_iflag in the termios structure.
diff --git a/share/man/man4/termios.4 b/share/man/man4/termios.4
index 6f38cf3b9f91..e3fb9635d247 100644
--- a/share/man/man4/termios.4
+++ b/share/man/man4/termios.4
@@ -1185,6 +1185,8 @@ flow control of output */
/* RTS flow control of input */
.It Dv MDMBUF
/* flow control output via Carrier */
+.It Dv CNO_RTSDTR
+/* Do not assert RTS or DTR automatically */
.El
.Pp
The
@@ -1267,6 +1269,12 @@ If
is set then output flow control is controlled by the state
of Carrier Detect.
.Pp
+If
+.Dv CNO_RTSDTR
+is set then the RTS and DTR lines will not be asserted when the device
+is opened.
+As a result, this flag is only useful on initial-state devices.
+.Pp
If the object for which the control modes are set is not an asynchronous
serial connection, some of the modes may be ignored; for example, if an
attempt is made to set the baud rate on a network connection to a
diff --git a/sys/dev/uart/uart_tty.c b/sys/dev/uart/uart_tty.c
index 1bef6384678e..ad7052289f0b 100644
--- a/sys/dev/uart/uart_tty.c
+++ b/sys/dev/uart/uart_tty.c
@@ -285,13 +285,16 @@ uart_tty_param(struct tty *tp, struct termios *t)
parity = UART_PARITY_NONE;
if (UART_PARAM(sc, t->c_ospeed, databits, stopbits, parity) != 0)
return (EINVAL);
- UART_SETSIG(sc, SER_DDTR | SER_DTR);
+ if ((t->c_cflag & CNO_RTSDTR) == 0)
+ UART_SETSIG(sc, SER_DDTR | SER_DTR);
/* Set input flow control state. */
if (!sc->sc_hwiflow) {
if ((t->c_cflag & CRTS_IFLOW) && sc->sc_isquelch)
UART_SETSIG(sc, SER_DRTS);
- else
- UART_SETSIG(sc, SER_DRTS | SER_RTS);
+ else {
+ if ((t->c_cflag & CNO_RTSDTR) == 0)
+ UART_SETSIG(sc, SER_DRTS | SER_RTS);
+ }
} else
UART_IOCTL(sc, UART_IOCTL_IFLOW, (t->c_cflag & CRTS_IFLOW));
/* Set output flow control state. */
diff --git a/sys/dev/usb/serial/umcs.c b/sys/dev/usb/serial/umcs.c
index bcff8190344d..d314010b05b3 100644
--- a/sys/dev/usb/serial/umcs.c
+++ b/sys/dev/usb/serial/umcs.c
@@ -499,7 +499,9 @@ umcs7840_cfg_open(struct ucom_softc *ucom)
* Enable DTR/RTS on modem control, enable modem interrupts --
* documented
*/
- sc->sc_ports[pn].sc_mcr = MCS7840_UART_MCR_DTR | MCS7840_UART_MCR_RTS | MCS7840_UART_MCR_IE;
+ sc->sc_ports[pn].sc_mcr = MCS7840_UART_MCR_IE;
+ if (ucom->sc_tty == NULL || (ucom->sc_tty->t_termios.c_cflag & CNO_RTSDTR) == 0)
+ sc->sc_ports[pn].sc_mcr |= MCS7840_UART_MCR_DTR | MCS7840_UART_MCR_RTS;
if (umcs7840_set_UART_reg_sync(sc, pn, MCS7840_UART_REG_MCR, sc->sc_ports[pn].sc_mcr))
return;
diff --git a/sys/dev/usb/serial/usb_serial.c b/sys/dev/usb/serial/usb_serial.c
index 445c9f2127b8..698ad87c88fe 100644
--- a/sys/dev/usb/serial/usb_serial.c
+++ b/sys/dev/usb/serial/usb_serial.c
@@ -796,7 +796,8 @@ ucom_open(struct tty *tp)
&sc->sc_start_task[0].hdr,
&sc->sc_start_task[1].hdr);
- ucom_modem(tp, SER_DTR | SER_RTS, 0);
+ if (sc->sc_tty == NULL || (sc->sc_tty->t_termios.c_cflag & CNO_RTSDTR) == 0)
+ ucom_modem(tp, SER_DTR | SER_RTS, 0);
ucom_ring(sc, 0);
diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index 022c392d5c17..90f6245eac8a 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -93,7 +93,7 @@ static const char *dev_console_filename;
FLUSHO|NOKERNINFO|NOFLSH)
#define TTYSUP_CFLAG (CIGNORE|CSIZE|CSTOPB|CREAD|PARENB|PARODD|\
HUPCL|CLOCAL|CCTS_OFLOW|CRTS_IFLOW|CDTR_IFLOW|\
- CDSR_OFLOW|CCAR_OFLOW)
+ CDSR_OFLOW|CCAR_OFLOW|CNO_RTSDTR)
#define TTY_CALLOUT(tp,d) (dev2unit(d) & TTYUNIT_CALLOUT)
@@ -332,7 +332,8 @@ ttydev_open(struct cdev *dev, int oflags, int devtype __unused,
if (TTY_CALLOUT(tp, dev) || dev == dev_console)
tp->t_termios.c_cflag |= CLOCAL;
- ttydevsw_modem(tp, SER_DTR|SER_RTS, 0);
+ if ((tp->t_termios.c_cflag & CNO_RTSDTR) == 0)
+ ttydevsw_modem(tp, SER_DTR|SER_RTS, 0);
error = ttydevsw_open(tp);
if (error != 0)
diff --git a/sys/sys/_termios.h b/sys/sys/_termios.h
index 7a68dee99148..fab12cfa4064 100644
--- a/sys/sys/_termios.h
+++ b/sys/sys/_termios.h
@@ -143,6 +143,7 @@
#define CDTR_IFLOW 0x00040000 /* DTR flow control of input */
#define CDSR_OFLOW 0x00080000 /* DSR flow control of output */
#define CCAR_OFLOW 0x00100000 /* DCD flow control of output */
+#define CNO_RTSDTR 0x00200000 /* Do not assert RTS or DTR automatically */
#endif