diff options
| -rw-r--r-- | drivers/char/tty_ioctl.c | 19 | ||||
| -rw-r--r-- | drivers/usb/serial/pl2303.c | 7 | ||||
| -rw-r--r-- | include/linux/tty.h | 1 |
3 files changed, 27 insertions, 0 deletions
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index e02d59245a17..d4b6d64e858b 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c | |||
| @@ -365,6 +365,25 @@ void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old) | |||
| 365 | EXPORT_SYMBOL(tty_termios_copy_hw); | 365 | EXPORT_SYMBOL(tty_termios_copy_hw); |
| 366 | 366 | ||
| 367 | /** | 367 | /** |
| 368 | * tty_termios_hw_change - check for setting change | ||
| 369 | * @a: termios | ||
| 370 | * @b: termios to compare | ||
| 371 | * | ||
| 372 | * Check if any of the bits that affect a dumb device have changed | ||
| 373 | * between the two termios structures, or a speed change is needed. | ||
| 374 | */ | ||
| 375 | |||
| 376 | int tty_termios_hw_change(struct ktermios *a, struct ktermios *b) | ||
| 377 | { | ||
| 378 | if (a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed) | ||
| 379 | return 1; | ||
| 380 | if ((a->c_cflag ^ b->c_cflag) & ~(HUPCL | CREAD | CLOCAL)) | ||
| 381 | return 1; | ||
| 382 | return 0; | ||
| 383 | } | ||
| 384 | EXPORT_SYMBOL(tty_termios_hw_change); | ||
| 385 | |||
| 386 | /** | ||
| 368 | * change_termios - update termios values | 387 | * change_termios - update termios values |
| 369 | * @tty: tty to update | 388 | * @tty: tty to update |
| 370 | * @new_termios: desired new value | 389 | * @new_termios: desired new value |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index cf8add91de05..0da1df9c79bf 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
| @@ -483,6 +483,13 @@ static void pl2303_set_termios(struct usb_serial_port *port, | |||
| 483 | } | 483 | } |
| 484 | spin_unlock_irqrestore(&priv->lock, flags); | 484 | spin_unlock_irqrestore(&priv->lock, flags); |
| 485 | 485 | ||
| 486 | /* The PL2303 is reported to lose bytes if you change | ||
| 487 | serial settings even to the same values as before. Thus | ||
| 488 | we actually need to filter in this specific case */ | ||
| 489 | |||
| 490 | if (!tty_termios_hw_change(port->tty->termios, old_termios)) | ||
| 491 | return; | ||
| 492 | |||
| 486 | cflag = port->tty->termios->c_cflag; | 493 | cflag = port->tty->termios->c_cflag; |
| 487 | 494 | ||
| 488 | buf = kzalloc(7, GFP_KERNEL); | 495 | buf = kzalloc(7, GFP_KERNEL); |
diff --git a/include/linux/tty.h b/include/linux/tty.h index c555f5442bd7..defd2ab72449 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
| @@ -319,6 +319,7 @@ extern speed_t tty_termios_input_baud_rate(struct ktermios *termios); | |||
| 319 | extern void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed_t obaud); | 319 | extern void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed_t obaud); |
| 320 | extern void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud); | 320 | extern void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud); |
| 321 | extern void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old); | 321 | extern void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old); |
| 322 | extern int tty_termios_hw_change(struct ktermios *a, struct ktermios *b); | ||
| 322 | 323 | ||
| 323 | extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *); | 324 | extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *); |
| 324 | extern void tty_ldisc_deref(struct tty_ldisc *); | 325 | extern void tty_ldisc_deref(struct tty_ldisc *); |
