diff options
author | Alan Cox <alan@linux.intel.com> | 2009-07-09 08:36:58 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-07-10 22:17:22 -0400 |
commit | d4fc4a7bfc2dee626f4fec1e209e58eaa4312de6 (patch) | |
tree | 9a5a3198f086a30703abbe591943dbed851dcba7 /drivers/usb/serial/pl2303.c | |
parent | 24a15a62dcb1968bf4ffdae55c88fa934d971180 (diff) |
tty: Fix the PL2303 private methods for sysrq
PL2303 has private data shovelling methods that also have no fast path. Fix
them to work the same way as the default handler.
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/usb/serial/pl2303.c')
-rw-r--r-- | drivers/usb/serial/pl2303.c | 58 |
1 files changed, 33 insertions, 25 deletions
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 8835802067f7..efaf59c4f5d0 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -971,18 +971,46 @@ exit: | |||
971 | __func__, retval); | 971 | __func__, retval); |
972 | } | 972 | } |
973 | 973 | ||
974 | static void pl2303_push_data(struct tty_struct *tty, | ||
975 | struct usb_serial_port *port, struct urb *urb, | ||
976 | u8 line_status) | ||
977 | { | ||
978 | unsigned char *data = urb->transfer_buffer; | ||
979 | /* get tty_flag from status */ | ||
980 | char tty_flag = TTY_NORMAL; | ||
981 | /* break takes precedence over parity, */ | ||
982 | /* which takes precedence over framing errors */ | ||
983 | if (line_status & UART_BREAK_ERROR) | ||
984 | tty_flag = TTY_BREAK; | ||
985 | else if (line_status & UART_PARITY_ERROR) | ||
986 | tty_flag = TTY_PARITY; | ||
987 | else if (line_status & UART_FRAME_ERROR) | ||
988 | tty_flag = TTY_FRAME; | ||
989 | dbg("%s - tty_flag = %d", __func__, tty_flag); | ||
990 | |||
991 | tty_buffer_request_room(tty, urb->actual_length + 1); | ||
992 | /* overrun is special, not associated with a char */ | ||
993 | if (line_status & UART_OVERRUN_ERROR) | ||
994 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
995 | if (port->console && port->sysrq) { | ||
996 | int i; | ||
997 | for (i = 0; i < urb->actual_length; ++i) | ||
998 | if (!usb_serial_handle_sysrq_char(tty, port, data[i])) | ||
999 | tty_insert_flip_char(tty, data[i], tty_flag); | ||
1000 | } else | ||
1001 | tty_insert_flip_string(tty, data, urb->actual_length); | ||
1002 | tty_flip_buffer_push(tty); | ||
1003 | } | ||
1004 | |||
974 | static void pl2303_read_bulk_callback(struct urb *urb) | 1005 | static void pl2303_read_bulk_callback(struct urb *urb) |
975 | { | 1006 | { |
976 | struct usb_serial_port *port = urb->context; | 1007 | struct usb_serial_port *port = urb->context; |
977 | struct pl2303_private *priv = usb_get_serial_port_data(port); | 1008 | struct pl2303_private *priv = usb_get_serial_port_data(port); |
978 | struct tty_struct *tty; | 1009 | struct tty_struct *tty; |
979 | unsigned char *data = urb->transfer_buffer; | ||
980 | unsigned long flags; | 1010 | unsigned long flags; |
981 | int i; | ||
982 | int result; | 1011 | int result; |
983 | int status = urb->status; | 1012 | int status = urb->status; |
984 | u8 line_status; | 1013 | u8 line_status; |
985 | char tty_flag; | ||
986 | 1014 | ||
987 | dbg("%s - port %d", __func__, port->number); | 1015 | dbg("%s - port %d", __func__, port->number); |
988 | 1016 | ||
@@ -1010,10 +1038,7 @@ static void pl2303_read_bulk_callback(struct urb *urb) | |||
1010 | } | 1038 | } |
1011 | 1039 | ||
1012 | usb_serial_debug_data(debug, &port->dev, __func__, | 1040 | usb_serial_debug_data(debug, &port->dev, __func__, |
1013 | urb->actual_length, data); | 1041 | urb->actual_length, urb->transfer_buffer); |
1014 | |||
1015 | /* get tty_flag from status */ | ||
1016 | tty_flag = TTY_NORMAL; | ||
1017 | 1042 | ||
1018 | spin_lock_irqsave(&priv->lock, flags); | 1043 | spin_lock_irqsave(&priv->lock, flags); |
1019 | line_status = priv->line_status; | 1044 | line_status = priv->line_status; |
@@ -1021,26 +1046,9 @@ static void pl2303_read_bulk_callback(struct urb *urb) | |||
1021 | spin_unlock_irqrestore(&priv->lock, flags); | 1046 | spin_unlock_irqrestore(&priv->lock, flags); |
1022 | wake_up_interruptible(&priv->delta_msr_wait); | 1047 | wake_up_interruptible(&priv->delta_msr_wait); |
1023 | 1048 | ||
1024 | /* break takes precedence over parity, */ | ||
1025 | /* which takes precedence over framing errors */ | ||
1026 | if (line_status & UART_BREAK_ERROR) | ||
1027 | tty_flag = TTY_BREAK; | ||
1028 | else if (line_status & UART_PARITY_ERROR) | ||
1029 | tty_flag = TTY_PARITY; | ||
1030 | else if (line_status & UART_FRAME_ERROR) | ||
1031 | tty_flag = TTY_FRAME; | ||
1032 | dbg("%s - tty_flag = %d", __func__, tty_flag); | ||
1033 | |||
1034 | tty = tty_port_tty_get(&port->port); | 1049 | tty = tty_port_tty_get(&port->port); |
1035 | if (tty && urb->actual_length) { | 1050 | if (tty && urb->actual_length) { |
1036 | tty_buffer_request_room(tty, urb->actual_length + 1); | 1051 | pl2303_push_data(tty, port, urb, line_status); |
1037 | /* overrun is special, not associated with a char */ | ||
1038 | if (line_status & UART_OVERRUN_ERROR) | ||
1039 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
1040 | for (i = 0; i < urb->actual_length; ++i) | ||
1041 | if (!usb_serial_handle_sysrq_char(tty, port, data[i])) | ||
1042 | tty_insert_flip_char(tty, data[i], tty_flag); | ||
1043 | tty_flip_buffer_push(tty); | ||
1044 | } | 1052 | } |
1045 | tty_kref_put(tty); | 1053 | tty_kref_put(tty); |
1046 | /* Schedule the next read _if_ we are still open */ | 1054 | /* Schedule the next read _if_ we are still open */ |