summaryrefslogtreecommitdiffstats
path: root/drivers/tty/tty_io.c
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2017-03-30 15:39:36 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-03-31 11:37:13 +0200
commit93857edd9829e144acb6c7e72d593f6e01aead66 (patch)
treec318e2838f66ea43bd41cb9b7344f7b0e43357b7 /drivers/tty/tty_io.c
parent16b00ae82dce0e36384744553c6e9e97070813e8 (diff)
downloadlinux-93857edd9829e144acb6c7e72d593f6e01aead66.tar.gz
linux-93857edd9829e144acb6c7e72d593f6e01aead66.tar.bz2
linux-93857edd9829e144acb6c7e72d593f6e01aead66.zip
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: Jan Kundrát <jan.kundrat@cesnet.cz> Signed-off-by: Johan Hovold <johan@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/tty_io.c')
-rw-r--r--drivers/tty/tty_io.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 5f834dcb0b15..d697053f5e42 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -3293,6 +3293,7 @@ struct device *tty_register_device_attr(struct tty_driver *driver,
{
char name[64];
dev_t devt = MKDEV(driver->major, driver->minor_start) + index;
+ struct ktermios *tp;
struct device *dev;
int retval;
@@ -3326,6 +3327,16 @@ struct device *tty_register_device_attr(struct tty_driver *driver,
goto err_put;
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);
if (retval)
goto err_del;