aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/keyspan.c
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2014-11-18 05:25:19 -0500
committerJohan Hovold <johan@kernel.org>2014-11-19 10:22:21 -0500
commit5d1678a33c731b56e245e888fdae5e88efce0997 (patch)
tree297aad03ca184a50ac923dc5b1d76204a4ad8248 /drivers/usb/serial/keyspan.c
parent204ec6e07ea7aff863df0f7c53301f9cbbfbb9d3 (diff)
USB: keyspan: fix tty line-status reporting
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>
Diffstat (limited to 'drivers/usb/serial/keyspan.c')
-rw-r--r--drivers/usb/serial/keyspan.c76
1 files changed, 48 insertions, 28 deletions
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index 93cb7cebda62..7799d8bc4a63 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -321,14 +321,19 @@ static void usa26_indat_callback(struct urb *urb)
321 /* some bytes had errors, every byte has status */ 321 /* some bytes had errors, every byte has status */
322 dev_dbg(&port->dev, "%s - RX error!!!!\n", __func__); 322 dev_dbg(&port->dev, "%s - RX error!!!!\n", __func__);
323 for (i = 0; i + 1 < urb->actual_length; i += 2) { 323 for (i = 0; i + 1 < urb->actual_length; i += 2) {
324 int stat = data[i], flag = 0; 324 int stat = data[i];
325 if (stat & RXERROR_OVERRUN) 325 int flag = TTY_NORMAL;
326 flag |= TTY_OVERRUN; 326
327 if (stat & RXERROR_FRAMING) 327 if (stat & RXERROR_OVERRUN) {
328 flag |= TTY_FRAME; 328 tty_insert_flip_char(&port->port, 0,
329 if (stat & RXERROR_PARITY) 329 TTY_OVERRUN);
330 flag |= TTY_PARITY; 330 }
331 /* XXX should handle break (0x10) */ 331 /* XXX should handle break (0x10) */
332 if (stat & RXERROR_PARITY)
333 flag = TTY_PARITY;
334 else if (stat & RXERROR_FRAMING)
335 flag = TTY_FRAME;
336
332 tty_insert_flip_char(&port->port, data[i+1], 337 tty_insert_flip_char(&port->port, data[i+1],
333 flag); 338 flag);
334 } 339 }
@@ -649,14 +654,19 @@ static void usa49_indat_callback(struct urb *urb)
649 } else { 654 } else {
650 /* some bytes had errors, every byte has status */ 655 /* some bytes had errors, every byte has status */
651 for (i = 0; i + 1 < urb->actual_length; i += 2) { 656 for (i = 0; i + 1 < urb->actual_length; i += 2) {
652 int stat = data[i], flag = 0; 657 int stat = data[i];
653 if (stat & RXERROR_OVERRUN) 658 int flag = TTY_NORMAL;
654 flag |= TTY_OVERRUN; 659
655 if (stat & RXERROR_FRAMING) 660 if (stat & RXERROR_OVERRUN) {
656 flag |= TTY_FRAME; 661 tty_insert_flip_char(&port->port, 0,
657 if (stat & RXERROR_PARITY) 662 TTY_OVERRUN);
658 flag |= TTY_PARITY; 663 }
659 /* XXX should handle break (0x10) */ 664 /* XXX should handle break (0x10) */
665 if (stat & RXERROR_PARITY)
666 flag = TTY_PARITY;
667 else if (stat & RXERROR_FRAMING)
668 flag = TTY_FRAME;
669
660 tty_insert_flip_char(&port->port, data[i+1], 670 tty_insert_flip_char(&port->port, data[i+1],
661 flag); 671 flag);
662 } 672 }
@@ -713,15 +723,19 @@ static void usa49wg_indat_callback(struct urb *urb)
713 */ 723 */
714 for (x = 0; x + 1 < len && 724 for (x = 0; x + 1 < len &&
715 i + 1 < urb->actual_length; x += 2) { 725 i + 1 < urb->actual_length; x += 2) {
716 int stat = data[i], flag = 0; 726 int stat = data[i];
727 int flag = TTY_NORMAL;
717 728
718 if (stat & RXERROR_OVERRUN) 729 if (stat & RXERROR_OVERRUN) {
719 flag |= TTY_OVERRUN; 730 tty_insert_flip_char(&port->port, 0,
720 if (stat & RXERROR_FRAMING) 731 TTY_OVERRUN);
721 flag |= TTY_FRAME; 732 }
722 if (stat & RXERROR_PARITY)
723 flag |= TTY_PARITY;
724 /* XXX should handle break (0x10) */ 733 /* XXX should handle break (0x10) */
734 if (stat & RXERROR_PARITY)
735 flag = TTY_PARITY;
736 else if (stat & RXERROR_FRAMING)
737 flag = TTY_FRAME;
738
725 tty_insert_flip_char(&port->port, data[i+1], 739 tty_insert_flip_char(&port->port, data[i+1],
726 flag); 740 flag);
727 i += 2; 741 i += 2;
@@ -784,14 +798,20 @@ static void usa90_indat_callback(struct urb *urb)
784 /* some bytes had errors, every byte has status */ 798 /* some bytes had errors, every byte has status */
785 dev_dbg(&port->dev, "%s - RX error!!!!\n", __func__); 799 dev_dbg(&port->dev, "%s - RX error!!!!\n", __func__);
786 for (i = 0; i + 1 < urb->actual_length; i += 2) { 800 for (i = 0; i + 1 < urb->actual_length; i += 2) {
787 int stat = data[i], flag = 0; 801 int stat = data[i];
788 if (stat & RXERROR_OVERRUN) 802 int flag = TTY_NORMAL;
789 flag |= TTY_OVERRUN; 803
790 if (stat & RXERROR_FRAMING) 804 if (stat & RXERROR_OVERRUN) {
791 flag |= TTY_FRAME; 805 tty_insert_flip_char(
792 if (stat & RXERROR_PARITY) 806 &port->port, 0,
793 flag |= TTY_PARITY; 807 TTY_OVERRUN);
808 }
794 /* XXX should handle break (0x10) */ 809 /* XXX should handle break (0x10) */
810 if (stat & RXERROR_PARITY)
811 flag = TTY_PARITY;
812 else if (stat & RXERROR_FRAMING)
813 flag = TTY_FRAME;
814
795 tty_insert_flip_char(&port->port, 815 tty_insert_flip_char(&port->port,
796 data[i+1], flag); 816 data[i+1], flag);
797 } 817 }