aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/serial/pl2303.c84
1 files changed, 25 insertions, 59 deletions
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 7aff62260fd4..77e968045f75 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -770,10 +770,8 @@ static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port)
770 pl2303_set_termios(tty, port, &tmp_termios); 770 pl2303_set_termios(tty, port, &tmp_termios);
771 771
772 dbg("%s - submitting read urb", __func__); 772 dbg("%s - submitting read urb", __func__);
773 result = usb_submit_urb(port->read_urb, GFP_KERNEL); 773 result = usb_serial_generic_submit_read_urb(port, GFP_KERNEL);
774 if (result) { 774 if (result) {
775 dev_err(&port->dev, "%s - failed submitting read urb,"
776 " error %d\n", __func__, result);
777 pl2303_close(port); 775 pl2303_close(port);
778 return -EPROTO; 776 return -EPROTO;
779 } 777 }
@@ -1037,13 +1035,31 @@ exit:
1037 __func__, retval); 1035 __func__, retval);
1038} 1036}
1039 1037
1040static void pl2303_push_data(struct tty_struct *tty, 1038static void pl2303_process_read_urb(struct urb *urb)
1041 struct usb_serial_port *port, struct urb *urb,
1042 u8 line_status)
1043{ 1039{
1040 struct usb_serial_port *port = urb->context;
1041 struct pl2303_private *priv = usb_get_serial_port_data(port);
1042 struct tty_struct *tty;
1044 unsigned char *data = urb->transfer_buffer; 1043 unsigned char *data = urb->transfer_buffer;
1045 /* get tty_flag from status */
1046 char tty_flag = TTY_NORMAL; 1044 char tty_flag = TTY_NORMAL;
1045 unsigned long flags;
1046 u8 line_status;
1047 int i;
1048
1049 /* update line status */
1050 spin_lock_irqsave(&priv->lock, flags);
1051 line_status = priv->line_status;
1052 priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
1053 spin_unlock_irqrestore(&priv->lock, flags);
1054 wake_up_interruptible(&priv->delta_msr_wait);
1055
1056 if (!urb->actual_length)
1057 return;
1058
1059 tty = tty_port_tty_get(&port->port);
1060 if (!tty)
1061 return;
1062
1047 /* break takes precedence over parity, */ 1063 /* break takes precedence over parity, */
1048 /* which takes precedence over framing errors */ 1064 /* which takes precedence over framing errors */
1049 if (line_status & UART_BREAK_ERROR) 1065 if (line_status & UART_BREAK_ERROR)
@@ -1061,63 +1077,13 @@ static void pl2303_push_data(struct tty_struct *tty,
1061 if (tty_flag == TTY_NORMAL && !(port->port.console && port->sysrq)) 1077 if (tty_flag == TTY_NORMAL && !(port->port.console && port->sysrq))
1062 tty_insert_flip_string(tty, data, urb->actual_length); 1078 tty_insert_flip_string(tty, data, urb->actual_length);
1063 else { 1079 else {
1064 int i;
1065 for (i = 0; i < urb->actual_length; ++i) 1080 for (i = 0; i < urb->actual_length; ++i)
1066 if (!usb_serial_handle_sysrq_char(tty, port, data[i])) 1081 if (!usb_serial_handle_sysrq_char(tty, port, data[i]))
1067 tty_insert_flip_char(tty, data[i], tty_flag); 1082 tty_insert_flip_char(tty, data[i], tty_flag);
1068 } 1083 }
1069 tty_flip_buffer_push(tty);
1070}
1071
1072static void pl2303_read_bulk_callback(struct urb *urb)
1073{
1074 struct usb_serial_port *port = urb->context;
1075 struct pl2303_private *priv = usb_get_serial_port_data(port);
1076 struct tty_struct *tty;
1077 unsigned long flags;
1078 int result;
1079 int status = urb->status;
1080 u8 line_status;
1081
1082 dbg("%s - port %d", __func__, port->number);
1083
1084 if (status) {
1085 dbg("%s - urb status = %d", __func__, status);
1086 if (status == -EPROTO) {
1087 /* PL2303 mysteriously fails with -EPROTO reschedule
1088 * the read */
1089 dbg("%s - caught -EPROTO, resubmitting the urb",
1090 __func__);
1091 result = usb_submit_urb(urb, GFP_ATOMIC);
1092 if (result)
1093 dev_err(&urb->dev->dev, "%s - failed"
1094 " resubmitting read urb, error %d\n",
1095 __func__, result);
1096 return;
1097 }
1098 dbg("%s - unable to handle the error, exiting.", __func__);
1099 return;
1100 }
1101 1084
1102 usb_serial_debug_data(debug, &port->dev, __func__, 1085 tty_flip_buffer_push(tty);
1103 urb->actual_length, urb->transfer_buffer);
1104
1105 spin_lock_irqsave(&priv->lock, flags);
1106 line_status = priv->line_status;
1107 priv->line_status &= ~UART_STATE_TRANSIENT_MASK;
1108 spin_unlock_irqrestore(&priv->lock, flags);
1109 wake_up_interruptible(&priv->delta_msr_wait);
1110
1111 tty = tty_port_tty_get(&port->port);
1112 if (tty && urb->actual_length) {
1113 pl2303_push_data(tty, port, urb, line_status);
1114 }
1115 tty_kref_put(tty); 1086 tty_kref_put(tty);
1116 /* Schedule the next read _if_ we are still open */
1117 result = usb_submit_urb(urb, GFP_ATOMIC);
1118 if (result && result != -EPERM)
1119 dev_err(&urb->dev->dev, "%s - failed resubmitting"
1120 " read urb, error %d\n", __func__, result);
1121} 1087}
1122 1088
1123static void pl2303_write_bulk_callback(struct urb *urb) 1089static void pl2303_write_bulk_callback(struct urb *urb)
@@ -1182,7 +1148,7 @@ static struct usb_serial_driver pl2303_device = {
1182 .set_termios = pl2303_set_termios, 1148 .set_termios = pl2303_set_termios,
1183 .tiocmget = pl2303_tiocmget, 1149 .tiocmget = pl2303_tiocmget,
1184 .tiocmset = pl2303_tiocmset, 1150 .tiocmset = pl2303_tiocmset,
1185 .read_bulk_callback = pl2303_read_bulk_callback, 1151 .process_read_urb = pl2303_process_read_urb,
1186 .read_int_callback = pl2303_read_int_callback, 1152 .read_int_callback = pl2303_read_int_callback,
1187 .write_bulk_callback = pl2303_write_bulk_callback, 1153 .write_bulk_callback = pl2303_write_bulk_callback,
1188 .write_room = pl2303_write_room, 1154 .write_room = pl2303_write_room,