diff options
Diffstat (limited to 'drivers/usb/serial/pl2303.c')
-rw-r--r-- | drivers/usb/serial/pl2303.c | 60 |
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 | ||
976 | static 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 | |||
974 | static void pl2303_read_bulk_callback(struct urb *urb) | 1007 | static 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 */ |