So now, that we have flags and know everything needed, keep a promise and move all the tables and ports allocation from tty_register_driver to tty_alloc_driver.
Not only that it makes sense, but we need this for tty_port_link_device which needs tty_driver->ports but is to be called before tty_register_driver. Signed-off-by: Jiri Slaby <jsl...@suse.cz> --- drivers/tty/tty_io.c | 73 +++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 40 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index e024521..3098fa1 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -3059,6 +3059,7 @@ struct tty_driver *__tty_alloc_driver(unsigned int lines, struct module *owner, unsigned long flags) { struct tty_driver *driver; + int err; if (!lines) return ERR_PTR(-EINVAL); @@ -3072,9 +3073,34 @@ struct tty_driver *__tty_alloc_driver(unsigned int lines, struct module *owner, driver->num = lines; driver->owner = owner; driver->flags = flags; - /* later we'll move allocation of tables here */ + + if (!(flags & TTY_DRIVER_DEVPTS_MEM)) { + driver->ttys = kcalloc(lines, sizeof(*driver->ttys), + GFP_KERNEL); + driver->termios = kcalloc(lines, sizeof(*driver->termios), + GFP_KERNEL); + if (!driver->ttys || !driver->termios) { + err = -ENOMEM; + goto err_free_all; + } + } + + if (!(flags & TTY_DRIVER_DYNAMIC_ALLOC)) { + driver->ports = kcalloc(lines, sizeof(*driver->ports), + GFP_KERNEL); + if (!driver->ports) { + err = -ENOMEM; + goto err_free_all; + } + } return driver; +err_free_all: + kfree(driver->ports); + kfree(driver->ttys); + kfree(driver->termios); + kfree(driver); + return ERR_PTR(err); } EXPORT_SYMBOL(__tty_alloc_driver); @@ -3083,7 +3109,6 @@ static void destruct_tty_driver(struct kref *kref) struct tty_driver *driver = container_of(kref, struct tty_driver, kref); int i; struct ktermios *tp; - void *p; if (driver->flags & TTY_DRIVER_INSTALLED) { /* @@ -3100,14 +3125,12 @@ static void destruct_tty_driver(struct kref *kref) if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) tty_unregister_device(driver, i); } - p = driver->ttys; proc_tty_unregister_driver(driver); - driver->ttys = NULL; - driver->termios = NULL; - kfree(p); cdev_del(&driver->cdev); } kfree(driver->ports); + kfree(driver->termios); + kfree(driver->ttys); kfree(driver); } @@ -3138,27 +3161,8 @@ int tty_register_driver(struct tty_driver *driver) int error; int i; dev_t dev; - void **p = NULL; struct device *d; - if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) { - p = kzalloc(driver->num * 2 * sizeof(void *), GFP_KERNEL); - 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, driver->num, driver->name); @@ -3171,15 +3175,7 @@ int tty_register_driver(struct tty_driver *driver) error = register_chrdev_region(dev, driver->num, driver->name); } if (error < 0) - goto err_free_p; - - if (p) { - driver->ttys = (struct tty_struct **)p; - driver->termios = (struct ktermios **)(p + driver->num); - } else { - driver->ttys = NULL; - driver->termios = NULL; - } + goto err; cdev_init(&driver->cdev, &tty_fops); driver->cdev.owner = driver->owner; @@ -3196,7 +3192,7 @@ int tty_register_driver(struct tty_driver *driver) d = tty_register_device(driver, i, NULL); if (IS_ERR(d)) { error = PTR_ERR(d); - goto err; + goto err_unreg_devs; } } } @@ -3204,7 +3200,7 @@ int tty_register_driver(struct tty_driver *driver) driver->flags |= TTY_DRIVER_INSTALLED; return 0; -err: +err_unreg_devs: for (i--; i >= 0; i--) tty_unregister_device(driver, i); @@ -3214,10 +3210,7 @@ err: err_unreg_char: unregister_chrdev_region(dev, driver->num); - driver->ttys = NULL; - driver->termios = NULL; -err_free_p: /* destruct_tty_driver will free driver->ports */ - kfree(p); +err: return error; } EXPORT_SYMBOL(tty_register_driver); -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/