lkml.org 
[lkml]   [2012]   [Aug]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 19/41] TTY: move allocations to tty_alloc_driver
    Date
    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 <jslaby@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..8181cb5 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_EXCESSIVE_LINES)) {
    + 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



    \
     
     \ /
      Last update: 2012-08-07 23:02    [W:0.030 / U:0.568 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site