aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/pl2303.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/pl2303.c')
-rw-r--r--drivers/usb/serial/pl2303.c60
1 files changed, 35 insertions, 25 deletions
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index ec6c132a25b5..3e86815b2705 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -94,6 +94,8 @@ static struct usb_device_id id_table [] = {
94 { USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) }, 94 { USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) },
95 { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) }, 95 { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) },
96 { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, 96 { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) },
97 { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },
98 { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
97 { } /* Terminating entry */ 99 { } /* Terminating entry */
98}; 100};
99 101
@@ -971,18 +973,46 @@ exit:
971 __func__, retval); 973 __func__, retval);
972} 974}
973 975
976static void pl2303_push_data(struct tty_struct *tty,
977 struct usb_serial_port *port, struct urb *urb,
978 u8 line_status)
979{
980 unsigned char *data = urb->transfer_buffer;
981 /* get tty_flag from status */
982 char tty_flag = TTY_NORMAL;
983 /* break takes precedence over parity, */
984 /* which takes precedence over framing errors */
985 if (line_status & UART_BREAK_ERROR)
986 tty_flag = TTY_BREAK;
987 else if (line_status & UART_PARITY_ERROR)
988 tty_flag = TTY_PARITY;
989 else if (line_status & UART_FRAME_ERROR)
990 tty_flag = TTY_FRAME;
991 dbg("%s - tty_flag = %d", __func__, tty_flag);
992
993 tty_buffer_request_room(tty, urb->actual_length + 1);
994 /* overrun is special, not associated with a char */
995 if (line_status & UART_OVERRUN_ERROR)
996 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
997 if (port->console && port->sysrq) {
998 int i;
999 for (i = 0; i < urb->actual_length; ++i)
1000 if (!usb_serial_handle_sysrq_char(tty, port, data[i]))
1001 tty_insert_flip_char(tty, data[i], tty_flag);
1002 } else
1003 tty_insert_flip_string(tty, data, urb->actual_length);
1004 tty_flip_buffer_push(tty);
1005}
1006
974static void pl2303_read_bulk_callback(struct urb *urb) 1007static void pl2303_read_bulk_callback(struct urb *urb)
975{ 1008{
976 struct usb_serial_port *port = urb->context; 1009 struct usb_serial_port *port = urb->context;
977 struct pl2303_private *priv = usb_get_serial_port_data(port); 1010 struct pl2303_private *priv = usb_get_serial_port_data(port);
978 struct tty_struct *tty; 1011 struct tty_struct *tty;
979 unsigned char *data = urb->transfer_buffer;
980 unsigned long flags; 1012 unsigned long flags;
981 int i;
982 int result; 1013 int result;
983 int status = urb->status; 1014 int status = urb->status;
984 u8 line_status; 1015 u8 line_status;
985 char tty_flag;
986 1016
987 dbg("%s - port %d", __func__, port->number); 1017 dbg("%s - port %d", __func__, port->number);
988 1018
@@ -1010,10 +1040,7 @@ static void pl2303_read_bulk_callback(struct urb *urb)
1010 } 1040 }
1011 1041
1012 usb_serial_debug_data(debug, &port->dev, __func__, 1042 usb_serial_debug_data(debug, &port->dev, __func__,
1013 urb->actual_length, data); 1043 urb->actual_length, urb->transfer_buffer);
1014
1015 /* get tty_flag from status */
1016 tty_flag = TTY_NORMAL;
1017 1044
1018 spin_lock_irqsave(&priv->lock, flags); 1045 spin_lock_irqsave(&priv->lock, flags);
1019 line_status = priv->line_status; 1046 line_status = priv->line_status;
@@ -1021,26 +1048,9 @@ static void pl2303_read_bulk_callback(struct urb *urb)
1021 spin_unlock_irqrestore(&priv->lock, flags); 1048 spin_unlock_irqrestore(&priv->lock, flags);
1022 wake_up_interruptible(&priv->delta_msr_wait); 1049 wake_up_interruptible(&priv->delta_msr_wait);
1023 1050
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); 1051 tty = tty_port_tty_get(&port->port);
1035 if (tty && urb->actual_length) { 1052 if (tty && urb->actual_length) {
1036 tty_buffer_request_room(tty, urb->actual_length + 1); 1053 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(port, data[i]))
1042 tty_insert_flip_char(tty, data[i], tty_flag);
1043 tty_flip_buffer_push(tty);
1044 } 1054 }
1045 tty_kref_put(tty); 1055 tty_kref_put(tty);
1046 /* Schedule the next read _if_ we are still open */ 1056 /* Schedule the next read _if_ we are still open */