Commit 93857edd authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman

tty: reset termios state on device registration

Free any saved termios data when registering a tty device so that the
termios state is reset when reusing a minor number.

This is useful for hot-pluggable buses such as USB where it does not
make much sense to reuse saved termios data from an unrelated device
when a new device is later plugged in.

This specifically avoids a situation where the new device does not have
the carrier-detect signal wired, but the saved termios state has CLOCAL
cleared, effectively preventing the port from being opened in blocking
mode as noted by Jan Kundrát <jan.kundrat@cesnet.cz>.

Note that clearing the saved data at deregistration would not work as
the device could still be open.

Also note that the termios data is not reset for drivers with
TTY_DRIVER_DYNAMIC_ALLOC set (e.g. legacy pty) as their character device
is registered at driver registration and could theoretically already
have been opened (and pty termios state is never saved anyway).
Reported-by: default avatarJan Kundrát <jan.kundrat@cesnet.cz>
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 16b00ae8
...@@ -3293,6 +3293,7 @@ struct device *tty_register_device_attr(struct tty_driver *driver, ...@@ -3293,6 +3293,7 @@ struct device *tty_register_device_attr(struct tty_driver *driver,
{ {
char name[64]; char name[64];
dev_t devt = MKDEV(driver->major, driver->minor_start) + index; dev_t devt = MKDEV(driver->major, driver->minor_start) + index;
struct ktermios *tp;
struct device *dev; struct device *dev;
int retval; int retval;
...@@ -3326,6 +3327,16 @@ struct device *tty_register_device_attr(struct tty_driver *driver, ...@@ -3326,6 +3327,16 @@ struct device *tty_register_device_attr(struct tty_driver *driver,
goto err_put; goto err_put;
if (!(driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)) { if (!(driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)) {
/*
* Free any saved termios data so that the termios state is
* reset when reusing a minor number.
*/
tp = driver->termios[index];
if (tp) {
driver->termios[index] = NULL;
kfree(tp);
}
retval = tty_cdev_add(driver, devt, index, 1); retval = tty_cdev_add(driver, devt, index, 1);
if (retval) if (retval)
goto err_del; goto err_del;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment