aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/tty_io.c
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2012-08-08 16:26:42 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-08-13 19:45:38 -0400
commit16a02081baa15becdb7d6460659e7832e6524d93 (patch)
tree8bd34de93db9a2c225241b1dedf7394baaa6819e /drivers/tty/tty_io.c
parent21aca2fa00259f781d228496631b61dbb4274e90 (diff)
TTY: move allocations to tty_alloc_driver
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> Acked-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/tty_io.c')
-rw-r--r--drivers/tty/tty_io.c73
1 files changed, 33 insertions, 40 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 098a7c72b640..a67609b9f21b 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -3074,6 +3074,7 @@ struct tty_driver *__tty_alloc_driver(unsigned int lines, struct module *owner,
3074 unsigned long flags) 3074 unsigned long flags)
3075{ 3075{
3076 struct tty_driver *driver; 3076 struct tty_driver *driver;
3077 int err;
3077 3078
3078 if (!lines) 3079 if (!lines)
3079 return ERR_PTR(-EINVAL); 3080 return ERR_PTR(-EINVAL);
@@ -3087,9 +3088,34 @@ struct tty_driver *__tty_alloc_driver(unsigned int lines, struct module *owner,
3087 driver->num = lines; 3088 driver->num = lines;
3088 driver->owner = owner; 3089 driver->owner = owner;
3089 driver->flags = flags; 3090 driver->flags = flags;
3090 /* later we'll move allocation of tables here */ 3091
3092 if (!(flags & TTY_DRIVER_DEVPTS_MEM)) {
3093 driver->ttys = kcalloc(lines, sizeof(*driver->ttys),
3094 GFP_KERNEL);
3095 driver->termios = kcalloc(lines, sizeof(*driver->termios),
3096 GFP_KERNEL);
3097 if (!driver->ttys || !driver->termios) {
3098 err = -ENOMEM;
3099 goto err_free_all;
3100 }
3101 }
3102
3103 if (!(flags & TTY_DRIVER_DYNAMIC_ALLOC)) {
3104 driver->ports = kcalloc(lines, sizeof(*driver->ports),
3105 GFP_KERNEL);
3106 if (!driver->ports) {
3107 err = -ENOMEM;
3108 goto err_free_all;
3109 }
3110 }
3091 3111
3092 return driver; 3112 return driver;
3113err_free_all:
3114 kfree(driver->ports);
3115 kfree(driver->ttys);
3116 kfree(driver->termios);
3117 kfree(driver);
3118 return ERR_PTR(err);
3093} 3119}
3094EXPORT_SYMBOL(__tty_alloc_driver); 3120EXPORT_SYMBOL(__tty_alloc_driver);
3095 3121
@@ -3098,7 +3124,6 @@ static void destruct_tty_driver(struct kref *kref)
3098 struct tty_driver *driver = container_of(kref, struct tty_driver, kref); 3124 struct tty_driver *driver = container_of(kref, struct tty_driver, kref);
3099 int i; 3125 int i;
3100 struct ktermios *tp; 3126 struct ktermios *tp;
3101 void *p;
3102 3127
3103 if (driver->flags & TTY_DRIVER_INSTALLED) { 3128 if (driver->flags & TTY_DRIVER_INSTALLED) {
3104 /* 3129 /*
@@ -3115,14 +3140,12 @@ static void destruct_tty_driver(struct kref *kref)
3115 if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) 3140 if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV))
3116 tty_unregister_device(driver, i); 3141 tty_unregister_device(driver, i);
3117 } 3142 }
3118 p = driver->ttys;
3119 proc_tty_unregister_driver(driver); 3143 proc_tty_unregister_driver(driver);
3120 driver->ttys = NULL;
3121 driver->termios = NULL;
3122 kfree(p);
3123 cdev_del(&driver->cdev); 3144 cdev_del(&driver->cdev);
3124 } 3145 }
3125 kfree(driver->ports); 3146 kfree(driver->ports);
3147 kfree(driver->termios);
3148 kfree(driver->ttys);
3126 kfree(driver); 3149 kfree(driver);
3127} 3150}
3128 3151
@@ -3153,27 +3176,8 @@ int tty_register_driver(struct tty_driver *driver)
3153 int error; 3176 int error;
3154 int i; 3177 int i;
3155 dev_t dev; 3178 dev_t dev;
3156 void **p = NULL;
3157 struct device *d; 3179 struct device *d;
3158 3180
3159 if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) {
3160 p = kzalloc(driver->num * 2 * sizeof(void *), GFP_KERNEL);
3161 if (!p)
3162 return -ENOMEM;
3163 }
3164 /*
3165 * There is too many lines in PTY and we won't need the array there
3166 * since it has an ->install hook where it assigns ports properly.
3167 */
3168 if (driver->type != TTY_DRIVER_TYPE_PTY) {
3169 driver->ports = kcalloc(driver->num, sizeof(struct tty_port *),
3170 GFP_KERNEL);
3171 if (!driver->ports) {
3172 error = -ENOMEM;
3173 goto err_free_p;
3174 }
3175 }
3176
3177 if (!driver->major) { 3181 if (!driver->major) {
3178 error = alloc_chrdev_region(&dev, driver->minor_start, 3182 error = alloc_chrdev_region(&dev, driver->minor_start,
3179 driver->num, driver->name); 3183 driver->num, driver->name);
@@ -3186,15 +3190,7 @@ int tty_register_driver(struct tty_driver *driver)
3186 error = register_chrdev_region(dev, driver->num, driver->name); 3190 error = register_chrdev_region(dev, driver->num, driver->name);
3187 } 3191 }
3188 if (error < 0) 3192 if (error < 0)
3189 goto err_free_p; 3193 goto err;
3190
3191 if (p) {
3192 driver->ttys = (struct tty_struct **)p;
3193 driver->termios = (struct ktermios **)(p + driver->num);
3194 } else {
3195 driver->ttys = NULL;
3196 driver->termios = NULL;
3197 }
3198 3194
3199 cdev_init(&driver->cdev, &tty_fops); 3195 cdev_init(&driver->cdev, &tty_fops);
3200 driver->cdev.owner = driver->owner; 3196 driver->cdev.owner = driver->owner;
@@ -3211,7 +3207,7 @@ int tty_register_driver(struct tty_driver *driver)
3211 d = tty_register_device(driver, i, NULL); 3207 d = tty_register_device(driver, i, NULL);
3212 if (IS_ERR(d)) { 3208 if (IS_ERR(d)) {
3213 error = PTR_ERR(d); 3209 error = PTR_ERR(d);
3214 goto err; 3210 goto err_unreg_devs;
3215 } 3211 }
3216 } 3212 }
3217 } 3213 }
@@ -3219,7 +3215,7 @@ int tty_register_driver(struct tty_driver *driver)
3219 driver->flags |= TTY_DRIVER_INSTALLED; 3215 driver->flags |= TTY_DRIVER_INSTALLED;
3220 return 0; 3216 return 0;
3221 3217
3222err: 3218err_unreg_devs:
3223 for (i--; i >= 0; i--) 3219 for (i--; i >= 0; i--)
3224 tty_unregister_device(driver, i); 3220 tty_unregister_device(driver, i);
3225 3221
@@ -3229,10 +3225,7 @@ err:
3229 3225
3230err_unreg_char: 3226err_unreg_char:
3231 unregister_chrdev_region(dev, driver->num); 3227 unregister_chrdev_region(dev, driver->num);
3232 driver->ttys = NULL; 3228err:
3233 driver->termios = NULL;
3234err_free_p: /* destruct_tty_driver will free driver->ports */
3235 kfree(p);
3236 return error; 3229 return error;
3237} 3230}
3238EXPORT_SYMBOL(tty_register_driver); 3231EXPORT_SYMBOL(tty_register_driver);