diff options
Diffstat (limited to 'drivers/usb/serial/keyspan.c')
-rw-r--r-- | drivers/usb/serial/keyspan.c | 96 |
1 files changed, 42 insertions, 54 deletions
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index b011478d2e5f..eb30d7b01f36 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c | |||
@@ -712,45 +712,45 @@ static void usa49wg_indat_callback(struct urb *urb) | |||
712 | i = 0; | 712 | i = 0; |
713 | len = 0; | 713 | len = 0; |
714 | 714 | ||
715 | if (urb->actual_length) { | 715 | while (i < urb->actual_length) { |
716 | while (i < urb->actual_length) { | ||
717 | 716 | ||
718 | /* Check port number from message*/ | 717 | /* Check port number from message */ |
719 | if (data[i] >= serial->num_ports) { | 718 | if (data[i] >= serial->num_ports) { |
720 | dev_dbg(&urb->dev->dev, "%s - Unexpected port number %d\n", | 719 | dev_dbg(&urb->dev->dev, "%s - Unexpected port number %d\n", |
721 | __func__, data[i]); | 720 | __func__, data[i]); |
722 | return; | 721 | return; |
723 | } | 722 | } |
724 | port = serial->port[data[i++]]; | 723 | port = serial->port[data[i++]]; |
725 | len = data[i++]; | 724 | len = data[i++]; |
726 | 725 | ||
727 | /* 0x80 bit is error flag */ | 726 | /* 0x80 bit is error flag */ |
728 | if ((data[i] & 0x80) == 0) { | 727 | if ((data[i] & 0x80) == 0) { |
729 | /* no error on any byte */ | 728 | /* no error on any byte */ |
730 | i++; | 729 | i++; |
731 | for (x = 1; x < len ; ++x) | 730 | for (x = 1; x < len && i < urb->actual_length; ++x) |
732 | tty_insert_flip_char(&port->port, | 731 | tty_insert_flip_char(&port->port, |
733 | data[i++], 0); | 732 | data[i++], 0); |
734 | } else { | 733 | } else { |
735 | /* | 734 | /* |
736 | * some bytes had errors, every byte has status | 735 | * some bytes had errors, every byte has status |
737 | */ | 736 | */ |
738 | for (x = 0; x + 1 < len; x += 2) { | 737 | for (x = 0; x + 1 < len && |
739 | int stat = data[i], flag = 0; | 738 | i + 1 < urb->actual_length; x += 2) { |
740 | if (stat & RXERROR_OVERRUN) | 739 | int stat = data[i], flag = 0; |
741 | flag |= TTY_OVERRUN; | 740 | |
742 | if (stat & RXERROR_FRAMING) | 741 | if (stat & RXERROR_OVERRUN) |
743 | flag |= TTY_FRAME; | 742 | flag |= TTY_OVERRUN; |
744 | if (stat & RXERROR_PARITY) | 743 | if (stat & RXERROR_FRAMING) |
745 | flag |= TTY_PARITY; | 744 | flag |= TTY_FRAME; |
746 | /* XXX should handle break (0x10) */ | 745 | if (stat & RXERROR_PARITY) |
747 | tty_insert_flip_char(&port->port, | 746 | flag |= TTY_PARITY; |
748 | data[i+1], flag); | 747 | /* XXX should handle break (0x10) */ |
749 | i += 2; | 748 | tty_insert_flip_char(&port->port, data[i+1], |
750 | } | 749 | flag); |
750 | i += 2; | ||
751 | } | 751 | } |
752 | tty_flip_buffer_push(&port->port); | ||
753 | } | 752 | } |
753 | tty_flip_buffer_push(&port->port); | ||
754 | } | 754 | } |
755 | 755 | ||
756 | /* Resubmit urb so we continue receiving */ | 756 | /* Resubmit urb so we continue receiving */ |
@@ -1092,7 +1092,6 @@ static void keyspan_dtr_rts(struct usb_serial_port *port, int on) | |||
1092 | static void keyspan_close(struct usb_serial_port *port) | 1092 | static void keyspan_close(struct usb_serial_port *port) |
1093 | { | 1093 | { |
1094 | int i; | 1094 | int i; |
1095 | struct usb_serial *serial = port->serial; | ||
1096 | struct keyspan_port_private *p_priv; | 1095 | struct keyspan_port_private *p_priv; |
1097 | 1096 | ||
1098 | p_priv = usb_get_serial_port_data(port); | 1097 | p_priv = usb_get_serial_port_data(port); |
@@ -1100,28 +1099,17 @@ static void keyspan_close(struct usb_serial_port *port) | |||
1100 | p_priv->rts_state = 0; | 1099 | p_priv->rts_state = 0; |
1101 | p_priv->dtr_state = 0; | 1100 | p_priv->dtr_state = 0; |
1102 | 1101 | ||
1103 | if (serial->dev) { | 1102 | keyspan_send_setup(port, 2); |
1104 | keyspan_send_setup(port, 2); | 1103 | /* pilot-xfer seems to work best with this delay */ |
1105 | /* pilot-xfer seems to work best with this delay */ | 1104 | mdelay(100); |
1106 | mdelay(100); | ||
1107 | /* keyspan_set_termios(port, NULL); */ | ||
1108 | } | ||
1109 | |||
1110 | /*while (p_priv->outcont_urb->status == -EINPROGRESS) { | ||
1111 | dev_dbg(&port->dev, "%s - urb in progress\n", __func__); | ||
1112 | }*/ | ||
1113 | 1105 | ||
1114 | p_priv->out_flip = 0; | 1106 | p_priv->out_flip = 0; |
1115 | p_priv->in_flip = 0; | 1107 | p_priv->in_flip = 0; |
1116 | 1108 | ||
1117 | if (serial->dev) { | 1109 | stop_urb(p_priv->inack_urb); |
1118 | /* Stop reading/writing urbs */ | 1110 | for (i = 0; i < 2; i++) { |
1119 | stop_urb(p_priv->inack_urb); | 1111 | stop_urb(p_priv->in_urbs[i]); |
1120 | /* stop_urb(p_priv->outcont_urb); */ | 1112 | stop_urb(p_priv->out_urbs[i]); |
1121 | for (i = 0; i < 2; i++) { | ||
1122 | stop_urb(p_priv->in_urbs[i]); | ||
1123 | stop_urb(p_priv->out_urbs[i]); | ||
1124 | } | ||
1125 | } | 1113 | } |
1126 | } | 1114 | } |
1127 | 1115 | ||