diff options
Diffstat (limited to 'drivers/usb')
-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 */ |