Patch "USB: serial: ftdi_sio: fix break and sysrq handling" has been added to the 4.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    USB: serial: ftdi_sio: fix break and sysrq handling

to the 4.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     usb-serial-ftdi_sio-fix-break-and-sysrq-handling.patch
and it can be found in the queue-4.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit fa9cb56cffc3e2c6d0a157b8d0109079ab0ba43d
Author: Johan Hovold <johan@xxxxxxxxxx>
Date:   Wed Jul 8 14:49:53 2020 +0200

    USB: serial: ftdi_sio: fix break and sysrq handling
    
    [ Upstream commit 733fff67941dad64b8a630450b8372b1873edc41 ]
    
    Only the last NUL in a packet should be flagged as a break character,
    for example, to avoid dropping unrelated characters when IGNBRK is set.
    
    Also make sysrq work by consuming the break character instead of having
    it immediately cancel the sysrq request, and by not processing it
    prematurely to avoid triggering a sysrq based on an unrelated character
    received in the same packet (which was received *before* the break).
    
    Note that the break flag can be left set also for a packet received
    immediately following a break and that and an ending NUL in such a
    packet will continue to be reported as a break as there's no good way to
    tell it apart from an actual break.
    
    Tested on FT232R and FT232H.
    
    Fixes: 72fda3ca6fc1 ("USB: serial: ftd_sio: implement sysrq handling on break")
    Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
    Reviewed-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
    Signed-off-by: Johan Hovold <johan@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 0afea511eb376..2dfec4c1ef4de 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -2054,6 +2054,7 @@ static int ftdi_process_packet(struct usb_serial_port *port,
 		struct ftdi_private *priv, unsigned char *buf, int len)
 {
 	unsigned char status;
+	bool brkint = false;
 	int i;
 	char flag;
 
@@ -2105,13 +2106,17 @@ static int ftdi_process_packet(struct usb_serial_port *port,
 	 */
 	flag = TTY_NORMAL;
 	if (buf[1] & FTDI_RS_ERR_MASK) {
-		/* Break takes precedence over parity, which takes precedence
-		 * over framing errors */
-		if (buf[1] & FTDI_RS_BI) {
-			flag = TTY_BREAK;
+		/*
+		 * Break takes precedence over parity, which takes precedence
+		 * over framing errors. Note that break is only associated
+		 * with the last character in the buffer and only when it's a
+		 * NUL.
+		 */
+		if (buf[1] & FTDI_RS_BI && buf[len - 1] == '\0') {
 			port->icount.brk++;
-			usb_serial_handle_break(port);
-		} else if (buf[1] & FTDI_RS_PE) {
+			brkint = true;
+		}
+		if (buf[1] & FTDI_RS_PE) {
 			flag = TTY_PARITY;
 			port->icount.parity++;
 		} else if (buf[1] & FTDI_RS_FE) {
@@ -2127,8 +2132,13 @@ static int ftdi_process_packet(struct usb_serial_port *port,
 
 	port->icount.rx += len - 2;
 
-	if (port->port.console && port->sysrq) {
+	if (brkint || (port->port.console && port->sysrq)) {
 		for (i = 2; i < len; i++) {
+			if (brkint && i == len - 1) {
+				if (usb_serial_handle_break(port))
+					return len - 3;
+				flag = TTY_BREAK;
+			}
 			if (usb_serial_handle_sysrq_char(port, buf[i]))
 				continue;
 			tty_insert_flip_char(&port->port, buf[i], flag);



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux