diff options
-rw-r--r-- | drivers/tty/tty_io.c | 18 | ||||
-rw-r--r-- | include/linux/tty_driver.h | 1 |
2 files changed, 18 insertions, 1 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index d6e045b7079a..ac96f74573d0 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1407,6 +1407,9 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) if (retval < 0) goto err_deinit_tty; + if (!tty->port) + tty->port = driver->ports[idx]; + /* * Structures all installed ... call the ldisc open routines. * If we fail here just call release_tty to clean up. No need @@ -3094,6 +3097,7 @@ static void destruct_tty_driver(struct kref *kref) kfree(p); cdev_del(&driver->cdev); } + kfree(driver->ports); kfree(driver); } @@ -3132,6 +3136,18 @@ int tty_register_driver(struct tty_driver *driver) if (!p) return -ENOMEM; } + /* + * There is too many lines in PTY and we won't need the array there + * since it has an ->install hook where it assigns ports properly. + */ + if (driver->type != TTY_DRIVER_TYPE_PTY) { + driver->ports = kcalloc(driver->num, sizeof(struct tty_port *), + GFP_KERNEL); + if (!driver->ports) { + error = -ENOMEM; + goto err_free_p; + } + } if (!driver->major) { error = alloc_chrdev_region(&dev, driver->minor_start, @@ -3190,7 +3206,7 @@ err_unreg_char: unregister_chrdev_region(dev, driver->num); driver->ttys = NULL; driver->termios = NULL; -err_free_p: +err_free_p: /* destruct_tty_driver will free driver->ports */ kfree(p); return error; } diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index 6e6dbb7447b6..04419c141b00 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -313,6 +313,7 @@ struct tty_driver { * Pointer to the tty data structures */ struct tty_struct **ttys; + struct tty_port **ports; struct ktermios **termios; void *driver_state; |