aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hurley <peter@hurleysoftware.com>2014-06-16 08:10:42 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-07-09 11:18:28 -0700
commit693639e6d5de17cdd5db53f8046a4c6fd275647a (patch)
tree49777c716d386e6f9de9f35c3157d5cc5c202f6e
parentd41660414cbb85cfef0df11c2580890648211355 (diff)
tty: Correct INPCK handling
commit 66528f90669691c85c73bea4f0c9f4a5857c4cab upstream. If INPCK is not set, input parity detection should be disabled. This means parity errors should not be received from the tty driver, and the data received should be treated normally. SUS v3, 11.2.2, General Terminal Interface - Input Modes, states: "If INPCK is set, input parity checking shall be enabled. If INPCK is not set, input parity checking shall be disabled, allowing output parity generation without input parity errors. Note that whether input parity checking is enabled or disabled is independent of whether parity detection is enabled or disabled (see Control Modes). If parity detection is enabled but input parity checking is disabled, the hardware to which the terminal is connected shall recognize the parity bit, but the terminal special file shall not check whether or not this bit is correctly set." Ignore parity errors reported by the tty driver when INPCK is not set, and handle the received data normally. Fixes: Bugzilla #71681, 'Improvement of n_tty_receive_parity_error from n_tty.c' Reported-by: Ivan <athlon_@mail.ru> Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/tty/n_tty.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index e36d1f5ca19..28ac3f3b7ec 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -1214,15 +1214,16 @@ static void n_tty_receive_parity_error(struct tty_struct *tty, unsigned char c)
{
struct n_tty_data *ldata = tty->disc_data;
- if (I_IGNPAR(tty))
- return;
- if (I_PARMRK(tty)) {
- put_tty_queue('\377', ldata);
- put_tty_queue('\0', ldata);
- put_tty_queue(c, ldata);
- } else if (I_INPCK(tty))
- put_tty_queue('\0', ldata);
- else
+ if (I_INPCK(tty)) {
+ if (I_IGNPAR(tty))
+ return;
+ if (I_PARMRK(tty)) {
+ put_tty_queue('\377', ldata);
+ put_tty_queue('\0', ldata);
+ put_tty_queue(c, ldata);
+ } else
+ put_tty_queue('\0', ldata);
+ } else
put_tty_queue(c, ldata);
if (waitqueue_active(&tty->read_wait))
wake_up_interruptible(&tty->read_wait);