mirror of
https://abf.rosa.ru/djam/kernel-5.15.git
synced 2025-02-24 02:52:55 +00:00
75 lines
2.3 KiB
Diff
75 lines
2.3 KiB
Diff
From a6bb1e17a39818b01b55d8e6238b4b5f06d55038 Mon Sep 17 00:00:00 2001
|
|
From: Johan Hovold <johan@kernel.org>
|
|
Date: Thu, 2 Feb 2017 17:38:35 +0100
|
|
Subject: USB: serial: ftdi_sio: fix line-status over-reporting
|
|
|
|
From: Johan Hovold <johan@kernel.org>
|
|
|
|
commit a6bb1e17a39818b01b55d8e6238b4b5f06d55038 upstream.
|
|
|
|
FTDI devices use a receive latency timer to periodically empty the
|
|
receive buffer and report modem and line status (also when the buffer is
|
|
empty).
|
|
|
|
When a break or error condition is detected the corresponding status
|
|
flags will be set on a packet with nonzero data payload and the flags
|
|
are not updated until the break is over or further characters are
|
|
received.
|
|
|
|
In order to avoid over-reporting break and error conditions, these flags
|
|
must therefore only be processed for packets with payload.
|
|
|
|
This specifically fixes the case where after an overrun, the error
|
|
condition is continuously reported and NULL-characters inserted until
|
|
further data is received.
|
|
|
|
Reported-by: Michael Walle <michael@walle.cc>
|
|
Fixes: 72fda3ca6fc1 ("USB: serial: ftd_sio: implement sysrq handling on
|
|
break")
|
|
Fixes: 166ceb690750 ("USB: ftdi_sio: clean up line-status handling")
|
|
Signed-off-by: Johan Hovold <johan@kernel.org>
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
|
|
---
|
|
drivers/usb/serial/ftdi_sio.c | 23 ++++++++++++++---------
|
|
1 file changed, 14 insertions(+), 9 deletions(-)
|
|
|
|
--- a/drivers/usb/serial/ftdi_sio.c
|
|
+++ b/drivers/usb/serial/ftdi_sio.c
|
|
@@ -2070,6 +2070,20 @@ static int ftdi_process_packet(struct us
|
|
priv->prev_status = status;
|
|
}
|
|
|
|
+ /* save if the transmitter is empty or not */
|
|
+ if (packet[1] & FTDI_RS_TEMT)
|
|
+ priv->transmit_empty = 1;
|
|
+ else
|
|
+ priv->transmit_empty = 0;
|
|
+
|
|
+ len -= 2;
|
|
+ if (!len)
|
|
+ return 0; /* status only */
|
|
+
|
|
+ /*
|
|
+ * Break and error status must only be processed for packets with
|
|
+ * data payload to avoid over-reporting.
|
|
+ */
|
|
flag = TTY_NORMAL;
|
|
if (packet[1] & FTDI_RS_ERR_MASK) {
|
|
/* Break takes precedence over parity, which takes precedence
|
|
@@ -2092,15 +2106,6 @@ static int ftdi_process_packet(struct us
|
|
}
|
|
}
|
|
|
|
- /* save if the transmitter is empty or not */
|
|
- if (packet[1] & FTDI_RS_TEMT)
|
|
- priv->transmit_empty = 1;
|
|
- else
|
|
- priv->transmit_empty = 0;
|
|
-
|
|
- len -= 2;
|
|
- if (!len)
|
|
- return 0; /* status only */
|
|
port->icount.rx += len;
|
|
ch = packet + 2;
|
|
|