From: Alan Cox <alan@xxxxxxxxxxxxxxx> 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 <alan@xxxxxxxxxxxxxxx> --- 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) -- To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html