|
@@ -142,6 +142,8 @@ struct pl2303_private {
|
|
|
spinlock_t lock;
|
|
|
u8 line_control;
|
|
|
u8 line_status;
|
|
|
+
|
|
|
+ u8 line_settings[7];
|
|
|
};
|
|
|
|
|
|
static int pl2303_vendor_read(__u16 value, __u16 index,
|
|
@@ -339,11 +341,6 @@ static void pl2303_set_termios(struct tty_struct *tty,
|
|
|
int i;
|
|
|
u8 control;
|
|
|
|
|
|
- /*
|
|
|
- * The PL2303 is reported to lose bytes if you change serial settings
|
|
|
- * even to the same values as before. Thus we actually need to filter
|
|
|
- * in this specific case.
|
|
|
- */
|
|
|
if (old_termios && !tty_termios_hw_change(&tty->termios, old_termios))
|
|
|
return;
|
|
|
|
|
@@ -428,10 +425,29 @@ static void pl2303_set_termios(struct tty_struct *tty,
|
|
|
dev_dbg(&port->dev, "parity = none\n");
|
|
|
}
|
|
|
|
|
|
- i = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
|
|
|
- SET_LINE_REQUEST, SET_LINE_REQUEST_TYPE,
|
|
|
- 0, 0, buf, 7, 100);
|
|
|
- dev_dbg(&port->dev, "0x21:0x20:0:0 %d\n", i);
|
|
|
+ /*
|
|
|
+ * Some PL2303 are known to lose bytes if you change serial settings
|
|
|
+ * even to the same values as before. Thus we actually need to filter
|
|
|
+ * in this specific case.
|
|
|
+ *
|
|
|
+ * Note that the tty_termios_hw_change check above is not sufficient
|
|
|
+ * as a previously requested baud rate may differ from the one
|
|
|
+ * actually used (and stored in old_termios).
|
|
|
+ *
|
|
|
+ * NOTE: No additional locking needed for line_settings as it is
|
|
|
+ * only used in set_termios, which is serialised against itself.
|
|
|
+ */
|
|
|
+ if (!old_termios || memcmp(buf, priv->line_settings, 7)) {
|
|
|
+ i = usb_control_msg(serial->dev,
|
|
|
+ usb_sndctrlpipe(serial->dev, 0),
|
|
|
+ SET_LINE_REQUEST, SET_LINE_REQUEST_TYPE,
|
|
|
+ 0, 0, buf, 7, 100);
|
|
|
+
|
|
|
+ dev_dbg(&port->dev, "0x21:0x20:0:0 %d\n", i);
|
|
|
+
|
|
|
+ if (i == 7)
|
|
|
+ memcpy(priv->line_settings, buf, 7);
|
|
|
+ }
|
|
|
|
|
|
/* change control lines if we are switching to or from B0 */
|
|
|
spin_lock_irqsave(&priv->lock, flags);
|