From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alan Cox Subject: [PATCH 10/12] tty: tidy up the RESET_TERMIOS case Date: Wed, 27 Jun 2012 12:22:58 +0100 Message-ID: <20120627112256.5678.10358.stgit@localhost.localdomain> References: <20120627112102.5678.4141.stgit@localhost.localdomain> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Return-path: Received: from lxorguk.ukuu.org.uk ([81.2.110.251]:46101 "EHLO lxorguk.ukuu.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757383Ab2F0LG5 (ORCPT ); Wed, 27 Jun 2012 07:06:57 -0400 In-Reply-To: <20120627112102.5678.4141.stgit@localhost.localdomain> Sender: linux-serial-owner@vger.kernel.org List-Id: linux-serial@vger.kernel.org To: greg@kroah.com, linux-serial@vger.kernel.org From: Alan Cox If we are going to reset the termios then we don't need the driver side buffers at all as we now have the tty allocation. Signed-off-by: Alan Cox --- drivers/tty/tty_io.c | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index f5c8d4f..14db2a8 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1249,16 +1249,20 @@ 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; - } - tty->termios = *tp; - + if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) + tty->termios = tty->driver->init_termios; + else { + tp = tty->driver->termios[idx]; + if (tp == NULL) { + tp = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL); + if (tp == NULL) + return -ENOMEM; + tp[0] = tty->driver->init_termios; + tty->driver->termios[idx] = tp; + } + tty->termios = tp[0]; + tty->termios_locked = tp[1]; + } /* 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); @@ -1432,16 +1436,9 @@ err_release_tty: 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); - } - else + if (!(tty->driver->flags & TTY_DRIVER_RESET_TERMIOS)) *tty->driver->termios[idx] = tty->termios; } EXPORT_SYMBOL(tty_free_termios); @@ -3069,16 +3066,19 @@ static void destruct_tty_driver(struct kref *kref) * drivers are removed from the kernel. */ for (i = 0; i < driver->num; i++) { - tp = driver->termios[i]; - if (tp) { - driver->termios[i] = NULL; - kfree(tp); + if (!(driver->flags & TTY_DRIVER_RESET_TERMIOS)) { + tp = driver->termios[i]; + if (tp) { + driver->termios[i] = NULL; + kfree(tp); + } } if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) tty_unregister_device(driver, i); } p = driver->ttys; proc_tty_unregister_driver(driver); + /* FIXME: who frees driver->termios itself */ driver->ttys = NULL; driver->termios = NULL; kfree(p); @@ -3117,6 +3117,7 @@ int tty_register_driver(struct tty_driver *driver) void **p = NULL; struct device *d; + /* FIXME: at this point we are overallocating for the RESET_TERMIOS case */ if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) { p = kzalloc(driver->num * 2 * sizeof(void *), GFP_KERNEL); if (!p)