aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/serial/pl2303.c58
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
974static 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
974static void pl2303_read_bulk_callback(struct urb *urb) 1005static 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 */