summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohan Hovold <jhovold@gmail.com>2010-05-08 15:19:24 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2010-05-20 13:21:44 -0700
commit166ceb69075066cba196434482370f1e0318bc3e (patch)
treed401d8c4d3ee4df6d7ec42a94ae5f5bd5da3a12e
parentd45cc8df7f59eb4db28408076ce979cd5e18f2b7 (diff)
USB: ftdi_sio: clean up line-status handling
Reverse priority of errors reported to ldisc so that it matches that of other serial drivers (break takes precedence over parity, which takes precedence over framing errors). Also make sure overrun errors are handled as in other drivers, that is, an overrun error is always reported and is not associated with any received character (instead a NULL character with the TTY_OVERRUN flag set is inserted). Signed-off-by: Johan Hovold <jhovold@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/serial/ftdi_sio.c37
1 files changed, 16 insertions, 21 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 6f1c05b2bdb7..00b938a81f33 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -1767,6 +1767,8 @@ static int ftdi_prepare_write_buffer(struct usb_serial_port *port,
return count;
}
+#define FTDI_RS_ERR_MASK (FTDI_RS_BI | FTDI_RS_PE | FTDI_RS_FE | FTDI_RS_OE)
+
static int ftdi_process_packet(struct tty_struct *tty,
struct usb_serial_port *port, struct ftdi_private *priv,
char *packet, int len)
@@ -1793,28 +1795,21 @@ static int ftdi_process_packet(struct tty_struct *tty,
priv->prev_status = status;
}
- /*
- * Although the device uses a bitmask and hence can have multiple
- * errors on a packet - the order here sets the priority the error is
- * returned to the tty layer.
- */
flag = TTY_NORMAL;
- if (packet[1] & FTDI_RS_OE) {
- flag = TTY_OVERRUN;
- dbg("OVERRRUN error");
- }
- if (packet[1] & FTDI_RS_BI) {
- flag = TTY_BREAK;
- dbg("BREAK received");
- usb_serial_handle_break(port);
- }
- if (packet[1] & FTDI_RS_PE) {
- flag = TTY_PARITY;
- dbg("PARITY error");
- }
- if (packet[1] & FTDI_RS_FE) {
- flag = TTY_FRAME;
- dbg("FRAMING error");
+ if (packet[1] & FTDI_RS_ERR_MASK) {
+ /* Break takes precedence over parity, which takes precedence
+ * over framing errors */
+ if (packet[1] & FTDI_RS_BI) {
+ flag = TTY_BREAK;
+ usb_serial_handle_break(port);
+ } else if (packet[1] & FTDI_RS_PE) {
+ flag = TTY_PARITY;
+ } else if (packet[1] & FTDI_RS_FE) {
+ flag = TTY_FRAME;
+ }
+ /* Overrun is special, not associated with a char */
+ if (packet[1] & FTDI_RS_OE)
+ tty_insert_flip_char(tty, 0, TTY_OVERRUN);
}
len -= 2;