summaryrefslogtreecommitdiff
path: root/drivers/tty/tty_baudrate.c
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2018-07-15 15:39:34 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-07-16 11:58:15 +0200
commit1cee38f0363a88db374e50b232ca17b9a4c12fa0 (patch)
tree28db78aff833dd8d36ee6f1725d1ffb8029e611c /drivers/tty/tty_baudrate.c
parentfada18c48d774b9e837928ecdce6a5d5fdd11ee7 (diff)
tty: fix termios input-speed encoding when using BOTHER
When the termios CIBAUD bits are left unset (i.e. B0), we use the same output and input speed and should leave CIBAUD unchanged. When the user requests a rate using BOTHER and c_ospeed which the driver cannot set exactly, the driver can report back the actual baud rate using tty_termios_encode_baud_rate(). If this rate is close enough to a standard rate however, we could end up setting CIBAUD to a Bfoo value despite the user having left it unset. This in turn could lead to an unexpected input rate being set on subsequent termios updates. Fix this by using a zero tolerance value also for the input rate when CIBAUD is clear so that the matching logic works as expected. Fixes: 78137e3b34e1 ("[PATCH] tty: improve encode_baud_rate logic") Signed-off-by: Johan Hovold <johan@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/tty_baudrate.c')
-rw-r--r--drivers/tty/tty_baudrate.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/drivers/tty/tty_baudrate.c b/drivers/tty/tty_baudrate.c
index a7a438f54e69..3e827a3d48d5 100644
--- a/drivers/tty/tty_baudrate.c
+++ b/drivers/tty/tty_baudrate.c
@@ -157,16 +157,20 @@ void tty_termios_encode_baud_rate(struct ktermios *termios,
termios->c_ospeed = obaud;
#ifdef BOTHER
+ if ((termios->c_cflag >> IBSHIFT) & CBAUD)
+ ibinput = 1; /* An input speed was specified */
+
/* If the user asked for a precise weird speed give a precise weird
answer. If they asked for a Bfoo speed they may have problems
digesting non-exact replies so fuzz a bit */
- if ((termios->c_cflag & CBAUD) == BOTHER)
+ if ((termios->c_cflag & CBAUD) == BOTHER) {
oclose = 0;
+ if (!ibinput)
+ iclose = 0;
+ }
if (((termios->c_cflag >> IBSHIFT) & CBAUD) == BOTHER)
iclose = 0;
- if ((termios->c_cflag >> IBSHIFT) & CBAUD)
- ibinput = 1; /* An input speed was specified */
#endif
termios->c_cflag &= ~CBAUD;
#ifdef IBSHIFT