]> git.karo-electronics.de Git - linux-beck.git/commitdiff
USB: keyspan: fix tty line-status reporting
authorJohan Hovold <johan@kernel.org>
Tue, 18 Nov 2014 10:25:19 +0000 (11:25 +0100)
committerJohan Hovold <johan@kernel.org>
Wed, 19 Nov 2014 15:22:21 +0000 (16:22 +0100)
Fix handling of TTY error flags, which are not bitmasks and must
specifically not be ORed together as this prevents the line discipline
from recognising them.

Also insert null characters when reporting overrun errors as these are
not associated with the received character.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
drivers/usb/serial/keyspan.c

index 93cb7cebda62760bcaae46f3710e7477ff59a507..7799d8bc4a63c284cc6c6f2b61cd4c340e734239 100644 (file)
@@ -321,14 +321,19 @@ static void       usa26_indat_callback(struct urb *urb)
                        /* some bytes had errors, every byte has status */
                        dev_dbg(&port->dev, "%s - RX error!!!!\n", __func__);
                        for (i = 0; i + 1 < urb->actual_length; i += 2) {
-                               int stat = data[i], flag = 0;
-                               if (stat & RXERROR_OVERRUN)
-                                       flag |= TTY_OVERRUN;
-                               if (stat & RXERROR_FRAMING)
-                                       flag |= TTY_FRAME;
-                               if (stat & RXERROR_PARITY)
-                                       flag |= TTY_PARITY;
+                               int stat = data[i];
+                               int flag = TTY_NORMAL;
+
+                               if (stat & RXERROR_OVERRUN) {
+                                       tty_insert_flip_char(&port->port, 0,
+                                                               TTY_OVERRUN);
+                               }
                                /* XXX should handle break (0x10) */
+                               if (stat & RXERROR_PARITY)
+                                       flag = TTY_PARITY;
+                               else if (stat & RXERROR_FRAMING)
+                                       flag = TTY_FRAME;
+
                                tty_insert_flip_char(&port->port, data[i+1],
                                                flag);
                        }
@@ -649,14 +654,19 @@ static void       usa49_indat_callback(struct urb *urb)
                } else {
                        /* some bytes had errors, every byte has status */
                        for (i = 0; i + 1 < urb->actual_length; i += 2) {
-                               int stat = data[i], flag = 0;
-                               if (stat & RXERROR_OVERRUN)
-                                       flag |= TTY_OVERRUN;
-                               if (stat & RXERROR_FRAMING)
-                                       flag |= TTY_FRAME;
-                               if (stat & RXERROR_PARITY)
-                                       flag |= TTY_PARITY;
+                               int stat = data[i];
+                               int flag = TTY_NORMAL;
+
+                               if (stat & RXERROR_OVERRUN) {
+                                       tty_insert_flip_char(&port->port, 0,
+                                                               TTY_OVERRUN);
+                               }
                                /* XXX should handle break (0x10) */
+                               if (stat & RXERROR_PARITY)
+                                       flag = TTY_PARITY;
+                               else if (stat & RXERROR_FRAMING)
+                                       flag = TTY_FRAME;
+
                                tty_insert_flip_char(&port->port, data[i+1],
                                                flag);
                        }
@@ -713,15 +723,19 @@ static void usa49wg_indat_callback(struct urb *urb)
                         */
                        for (x = 0; x + 1 < len &&
                                    i + 1 < urb->actual_length; x += 2) {
-                               int stat = data[i], flag = 0;
+                               int stat = data[i];
+                               int flag = TTY_NORMAL;
 
-                               if (stat & RXERROR_OVERRUN)
-                                       flag |= TTY_OVERRUN;
-                               if (stat & RXERROR_FRAMING)
-                                       flag |= TTY_FRAME;
-                               if (stat & RXERROR_PARITY)
-                                       flag |= TTY_PARITY;
+                               if (stat & RXERROR_OVERRUN) {
+                                       tty_insert_flip_char(&port->port, 0,
+                                                               TTY_OVERRUN);
+                               }
                                /* XXX should handle break (0x10) */
+                               if (stat & RXERROR_PARITY)
+                                       flag = TTY_PARITY;
+                               else if (stat & RXERROR_FRAMING)
+                                       flag = TTY_FRAME;
+
                                tty_insert_flip_char(&port->port, data[i+1],
                                                     flag);
                                i += 2;
@@ -784,14 +798,20 @@ static void usa90_indat_callback(struct urb *urb)
                        /* some bytes had errors, every byte has status */
                                dev_dbg(&port->dev, "%s - RX error!!!!\n", __func__);
                                for (i = 0; i + 1 < urb->actual_length; i += 2) {
-                                       int stat = data[i], flag = 0;
-                                       if (stat & RXERROR_OVERRUN)
-                                               flag |= TTY_OVERRUN;
-                                       if (stat & RXERROR_FRAMING)
-                                               flag |= TTY_FRAME;
-                                       if (stat & RXERROR_PARITY)
-                                               flag |= TTY_PARITY;
+                                       int stat = data[i];
+                                       int flag = TTY_NORMAL;
+
+                                       if (stat & RXERROR_OVERRUN) {
+                                               tty_insert_flip_char(
+                                                               &port->port, 0,
+                                                               TTY_OVERRUN);
+                                       }
                                        /* XXX should handle break (0x10) */
+                                       if (stat & RXERROR_PARITY)
+                                               flag = TTY_PARITY;
+                                       else if (stat & RXERROR_FRAMING)
+                                               flag = TTY_FRAME;
+
                                        tty_insert_flip_char(&port->port,
                                                        data[i+1], flag);
                                }