aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2012-08-07 15:47:42 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-08-10 16:29:58 -0400
commit7f0bc6a68ed93f3b4ad77b94df5ef32446c583e3 (patch)
treec51b79c16850d6a23347072aec81bf6acd3c97af
parent2312e4f3b2f17cac2cf257c759ad48eb80fdf230 (diff)
TTY: pass flags to alloc_tty_driver
We need to allow drivers that use neither tty_port_install nor tty_port_register_device to link a tty_port to a tty somehow. To avoid a race with open, this has to be performed before tty_register_device. But currently tty_driver->ports is allocated even in tty_register_device because we do not know whether this is the PTY driver. The PTY driver is special here due to an excessive count of lines it declares to handle. We cannot handle tty_ports there this way. To circumvent this, we start passing tty_driver flags to alloc_tty_driver already and we create tty_alloc_driver for this purpose. There we can allocate tty_driver->ports and do all the magic between tty_alloc_driver and tty_register_device. Later we will introduce tty_port_link_device function for that purpose. All drivers should eventually switch to this new tty driver allocation interface. Signed-off-by: Jiri Slaby <jslaby@suse.cz> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/tty/tty_io.c34
-rw-r--r--include/linux/tty_driver.h23
2 files changed, 44 insertions, 13 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 690224483fa..098a7c72b64 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -3061,21 +3061,37 @@ void tty_unregister_device(struct tty_driver *driver, unsigned index)
3061} 3061}
3062EXPORT_SYMBOL(tty_unregister_device); 3062EXPORT_SYMBOL(tty_unregister_device);
3063 3063
3064struct tty_driver *__alloc_tty_driver(int lines, struct module *owner) 3064/**
3065 * __tty_alloc_driver -- allocate tty driver
3066 * @lines: count of lines this driver can handle at most
3067 * @owner: module which is repsonsible for this driver
3068 * @flags: some of TTY_DRIVER_* flags, will be set in driver->flags
3069 *
3070 * This should not be called directly, some of the provided macros should be
3071 * used instead. Use IS_ERR and friends on @retval.
3072 */
3073struct tty_driver *__tty_alloc_driver(unsigned int lines, struct module *owner,
3074 unsigned long flags)
3065{ 3075{
3066 struct tty_driver *driver; 3076 struct tty_driver *driver;
3067 3077
3078 if (!lines)
3079 return ERR_PTR(-EINVAL);
3080
3068 driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL); 3081 driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL);
3069 if (driver) { 3082 if (!driver)
3070 kref_init(&driver->kref); 3083 return ERR_PTR(-ENOMEM);
3071 driver->magic = TTY_DRIVER_MAGIC; 3084
3072 driver->num = lines; 3085 kref_init(&driver->kref);
3073 driver->owner = owner; 3086 driver->magic = TTY_DRIVER_MAGIC;
3074 /* later we'll move allocation of tables here */ 3087 driver->num = lines;
3075 } 3088 driver->owner = owner;
3089 driver->flags = flags;
3090 /* later we'll move allocation of tables here */
3091
3076 return driver; 3092 return driver;
3077} 3093}
3078EXPORT_SYMBOL(__alloc_tty_driver); 3094EXPORT_SYMBOL(__tty_alloc_driver);
3079 3095
3080static void destruct_tty_driver(struct kref *kref) 3096static void destruct_tty_driver(struct kref *kref)
3081{ 3097{
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h
index 80e72dc564a..3adc362f0bd 100644
--- a/include/linux/tty_driver.h
+++ b/include/linux/tty_driver.h
@@ -296,11 +296,11 @@ struct tty_driver {
296 int name_base; /* offset of printed name */ 296 int name_base; /* offset of printed name */
297 int major; /* major device number */ 297 int major; /* major device number */
298 int minor_start; /* start of minor device number */ 298 int minor_start; /* start of minor device number */
299 int num; /* number of devices allocated */ 299 unsigned int num; /* number of devices allocated */
300 short type; /* type of tty driver */ 300 short type; /* type of tty driver */
301 short subtype; /* subtype of tty driver */ 301 short subtype; /* subtype of tty driver */
302 struct ktermios init_termios; /* Initial termios */ 302 struct ktermios init_termios; /* Initial termios */
303 int flags; /* tty driver flags */ 303 unsigned long flags; /* tty driver flags */
304 struct proc_dir_entry *proc_entry; /* /proc fs entry */ 304 struct proc_dir_entry *proc_entry; /* /proc fs entry */
305 struct tty_driver *other; /* only used for the PTY driver */ 305 struct tty_driver *other; /* only used for the PTY driver */
306 306
@@ -322,7 +322,8 @@ struct tty_driver {
322 322
323extern struct list_head tty_drivers; 323extern struct list_head tty_drivers;
324 324
325extern struct tty_driver *__alloc_tty_driver(int lines, struct module *owner); 325extern struct tty_driver *__tty_alloc_driver(unsigned int lines,
326 struct module *owner, unsigned long flags);
326extern void put_tty_driver(struct tty_driver *driver); 327extern void put_tty_driver(struct tty_driver *driver);
327extern void tty_set_operations(struct tty_driver *driver, 328extern void tty_set_operations(struct tty_driver *driver,
328 const struct tty_operations *op); 329 const struct tty_operations *op);
@@ -330,7 +331,21 @@ extern struct tty_driver *tty_find_polling_driver(char *name, int *line);
330 331
331extern void tty_driver_kref_put(struct tty_driver *driver); 332extern void tty_driver_kref_put(struct tty_driver *driver);
332 333
333#define alloc_tty_driver(lines) __alloc_tty_driver(lines, THIS_MODULE) 334/* Use TTY_DRIVER_* flags below */
335#define tty_alloc_driver(lines, flags) \
336 __tty_alloc_driver(lines, THIS_MODULE, flags)
337
338/*
339 * DEPRECATED Do not use this in new code, use tty_alloc_driver instead.
340 * (And change the return value checks.)
341 */
342static inline struct tty_driver *alloc_tty_driver(unsigned int lines)
343{
344 struct tty_driver *ret = tty_alloc_driver(lines, 0);
345 if (IS_ERR(ret))
346 return NULL;
347 return ret;
348}
334 349
335static inline struct tty_driver *tty_driver_kref_get(struct tty_driver *d) 350static inline struct tty_driver *tty_driver_kref_get(struct tty_driver *d)
336{ 351{