diff options
Diffstat (limited to 'drivers/tty/tty_io.c')
| -rw-r--r-- | drivers/tty/tty_io.c | 56 | 
1 files changed, 28 insertions, 28 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index cfd12da8121..be18d60ddf4 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1249,16 +1249,16 @@ int tty_init_termios(struct tty_struct *tty)  	struct ktermios *tp;  	int idx = tty->index; -	tp = tty->driver->termios[idx]; -	if (tp == NULL) { -		tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); -		if (tp == NULL) -			return -ENOMEM; -		*tp = tty->driver->init_termios; -		tty->driver->termios[idx] = tp; +	if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) +		tty->termios = tty->driver->init_termios; +	else { +		/* Check for lazy saved data */ +		tp = tty->driver->termios[idx]; +		if (tp != NULL) +			tty->termios = *tp; +		else +			tty->termios = tty->driver->init_termios;  	} -	tty->termios = *tp; -  	/* Compatibility until drivers always set this */  	tty->termios.c_ispeed = tty_termios_input_baud_rate(&tty->termios);  	tty->termios.c_ospeed = tty_termios_baud_rate(&tty->termios); @@ -1437,24 +1437,24 @@ void tty_free_termios(struct tty_struct *tty)  {  	struct ktermios *tp;  	int idx = tty->index; -	/* Kill this flag and push into drivers for locking etc */ -	if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { -		/* FIXME: Locking on ->termios array */ -		tp = tty->driver->termios[idx]; -		tty->driver->termios[idx] = NULL; -		kfree(tp); + +	/* If the port is going to reset then it has no termios to save */ +	if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) +		return; + +	/* Stash the termios data */ +	tp = tty->driver->termios[idx]; +	if (tp == NULL) { +		tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); +		if (tp == NULL) { +			pr_warn("tty: no memory to save termios state.\n"); +			return; +		}  	} -	else -		*tty->driver->termios[idx] = tty->termios; +	*tp = tty->termios;  }  EXPORT_SYMBOL(tty_free_termios); -void tty_shutdown(struct tty_struct *tty) -{ -	tty_driver_remove_tty(tty->driver, tty); -	tty_free_termios(tty); -} -EXPORT_SYMBOL(tty_shutdown);  /**   *	release_one_tty		-	release tty structure memory @@ -1498,11 +1498,6 @@ static void queue_release_one_tty(struct kref *kref)  {  	struct tty_struct *tty = container_of(kref, struct tty_struct, kref); -	if (tty->ops->shutdown) -		tty->ops->shutdown(tty); -	else -		tty_shutdown(tty); -  	/* The hangup queue is now free so we can reuse it rather than  	   waste a chunk of memory for each port */  	INIT_WORK(&tty->hangup_work, release_one_tty); @@ -1542,6 +1537,11 @@ static void release_tty(struct tty_struct *tty, int idx)  	/* This should always be true but check for the moment */  	WARN_ON(tty->index != idx); +	if (tty->ops->shutdown) +		tty->ops->shutdown(tty); +	tty_free_termios(tty); +	tty_driver_remove_tty(tty->driver, tty); +  	if (tty->link)  		tty_kref_put(tty->link);  	tty_kref_put(tty);  |