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
This commit is contained in:
shurd 2019-06-12 18:07:04 +00:00
parent 244c928774
commit 59fa6d1f5b
9 changed files with 33 additions and 7 deletions

View File

@ -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 },
};

View File

@ -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;

View File

@ -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.

View File

@ -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

View File

@ -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. */

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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