aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/keyspan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/keyspan.c')
-rw-r--r--drivers/usb/serial/keyspan.c96
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)
1092static void keyspan_close(struct usb_serial_port *port) 1092static 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