diff options
-rw-r--r-- | drivers/usb/serial/pl2303.c | 84 |
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 | ||
1040 | static void pl2303_push_data(struct tty_struct *tty, | 1038 | static 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 | |||
1072 | static 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 | ||
1123 | static void pl2303_write_bulk_callback(struct urb *urb) | 1089 | static 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, |