aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_io.c
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2008-10-13 05:42:09 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-13 12:51:42 -0400
commit7d7b93c1452f381350dbaf276a63357fa6559e6d (patch)
tree02ce0c37e7fea66d1e8af20111d92171bfc0ff1d /drivers/char/tty_io.c
parent99f1fe189daf8e99a847e420567e49dd7ee2aae7 (diff)
tty: kref the tty driver object
Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r--drivers/char/tty_io.c110
1 files changed, 61 insertions, 49 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index ac41af8763d1..47aa437effe2 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -276,7 +276,7 @@ static struct tty_driver *get_tty_driver(dev_t device, int *index)
276 if (device < base || device >= base + p->num) 276 if (device < base || device >= base + p->num)
277 continue; 277 continue;
278 *index = device - base; 278 *index = device - base;
279 return p; 279 return tty_driver_kref_get(p);
280 } 280 }
281 return NULL; 281 return NULL;
282} 282}
@@ -320,7 +320,7 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line)
320 320
321 if (tty_line >= 0 && tty_line <= p->num && p->ops && 321 if (tty_line >= 0 && tty_line <= p->num && p->ops &&
322 p->ops->poll_init && !p->ops->poll_init(p, tty_line, str)) { 322 p->ops->poll_init && !p->ops->poll_init(p, tty_line, str)) {
323 res = p; 323 res = tty_driver_kref_get(p);
324 *line = tty_line; 324 *line = tty_line;
325 break; 325 break;
326 } 326 }
@@ -1410,7 +1410,7 @@ int tty_init_dev(struct tty_driver *driver, int idx,
1410 *o_ltp_loc = o_ltp; 1410 *o_ltp_loc = o_ltp;
1411 o_tty->termios = *o_tp_loc; 1411 o_tty->termios = *o_tp_loc;
1412 o_tty->termios_locked = *o_ltp_loc; 1412 o_tty->termios_locked = *o_ltp_loc;
1413 driver->other->refcount++; 1413 tty_driver_kref_get(driver->other);
1414 if (driver->subtype == PTY_TYPE_MASTER) 1414 if (driver->subtype == PTY_TYPE_MASTER)
1415 o_tty->count++; 1415 o_tty->count++;
1416 1416
@@ -1438,7 +1438,7 @@ int tty_init_dev(struct tty_driver *driver, int idx,
1438 /* Compatibility until drivers always set this */ 1438 /* Compatibility until drivers always set this */
1439 tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios); 1439 tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios);
1440 tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); 1440 tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
1441 driver->refcount++; 1441 tty_driver_kref_get(driver);
1442 tty->count++; 1442 tty->count++;
1443 1443
1444 /* 1444 /*
@@ -1530,8 +1530,7 @@ static void release_one_tty(struct kref *kref)
1530 else 1530 else
1531 tty_shutdown(tty); 1531 tty_shutdown(tty);
1532 tty->magic = 0; 1532 tty->magic = 0;
1533 /* FIXME: locking on tty->driver->refcount */ 1533 tty_driver_kref_put(driver);
1534 tty->driver->refcount--;
1535 module_put(driver->owner); 1534 module_put(driver->owner);
1536 1535
1537 file_list_lock(); 1536 file_list_lock();
@@ -1854,7 +1853,7 @@ retry_open:
1854 mutex_unlock(&tty_mutex); 1853 mutex_unlock(&tty_mutex);
1855 return -ENXIO; 1854 return -ENXIO;
1856 } 1855 }
1857 driver = tty->driver; 1856 driver = tty_driver_kref_get(tty->driver);
1858 index = tty->index; 1857 index = tty->index;
1859 filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ 1858 filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */
1860 /* noctty = 1; */ 1859 /* noctty = 1; */
@@ -1865,14 +1864,14 @@ retry_open:
1865#ifdef CONFIG_VT 1864#ifdef CONFIG_VT
1866 if (device == MKDEV(TTY_MAJOR, 0)) { 1865 if (device == MKDEV(TTY_MAJOR, 0)) {
1867 extern struct tty_driver *console_driver; 1866 extern struct tty_driver *console_driver;
1868 driver = console_driver; 1867 driver = tty_driver_kref_get(console_driver);
1869 index = fg_console; 1868 index = fg_console;
1870 noctty = 1; 1869 noctty = 1;
1871 goto got_driver; 1870 goto got_driver;
1872 } 1871 }
1873#endif 1872#endif
1874 if (device == MKDEV(TTYAUX_MAJOR, 1)) { 1873 if (device == MKDEV(TTYAUX_MAJOR, 1)) {
1875 driver = console_device(&index); 1874 driver = tty_driver_kref_get(console_device(&index));
1876 if (driver) { 1875 if (driver) {
1877 /* Don't let /dev/console block */ 1876 /* Don't let /dev/console block */
1878 filp->f_flags |= O_NONBLOCK; 1877 filp->f_flags |= O_NONBLOCK;
@@ -1891,6 +1890,7 @@ retry_open:
1891got_driver: 1890got_driver:
1892 retval = tty_init_dev(driver, index, &tty, 0); 1891 retval = tty_init_dev(driver, index, &tty, 0);
1893 mutex_unlock(&tty_mutex); 1892 mutex_unlock(&tty_mutex);
1893 tty_driver_kref_put(driver);
1894 if (retval) 1894 if (retval)
1895 return retval; 1895 return retval;
1896 1896
@@ -2866,7 +2866,6 @@ int tty_put_char(struct tty_struct *tty, unsigned char ch)
2866 return tty->ops->put_char(tty, ch); 2866 return tty->ops->put_char(tty, ch);
2867 return tty->ops->write(tty, &ch, 1); 2867 return tty->ops->write(tty, &ch, 1);
2868} 2868}
2869
2870EXPORT_SYMBOL_GPL(tty_put_char); 2869EXPORT_SYMBOL_GPL(tty_put_char);
2871 2870
2872struct class *tty_class; 2871struct class *tty_class;
@@ -2909,6 +2908,7 @@ struct device *tty_register_device(struct tty_driver *driver, unsigned index,
2909 2908
2910 return device_create_drvdata(tty_class, device, dev, NULL, name); 2909 return device_create_drvdata(tty_class, device, dev, NULL, name);
2911} 2910}
2911EXPORT_SYMBOL(tty_register_device);
2912 2912
2913/** 2913/**
2914 * tty_unregister_device - unregister a tty device 2914 * tty_unregister_device - unregister a tty device
@@ -2926,8 +2926,6 @@ void tty_unregister_device(struct tty_driver *driver, unsigned index)
2926 device_destroy(tty_class, 2926 device_destroy(tty_class,
2927 MKDEV(driver->major, driver->minor_start) + index); 2927 MKDEV(driver->major, driver->minor_start) + index);
2928} 2928}
2929
2930EXPORT_SYMBOL(tty_register_device);
2931EXPORT_SYMBOL(tty_unregister_device); 2929EXPORT_SYMBOL(tty_unregister_device);
2932 2930
2933struct tty_driver *alloc_tty_driver(int lines) 2931struct tty_driver *alloc_tty_driver(int lines)
@@ -2936,27 +2934,70 @@ struct tty_driver *alloc_tty_driver(int lines)
2936 2934
2937 driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL); 2935 driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL);
2938 if (driver) { 2936 if (driver) {
2937 kref_init(&driver->kref);
2939 driver->magic = TTY_DRIVER_MAGIC; 2938 driver->magic = TTY_DRIVER_MAGIC;
2940 driver->num = lines; 2939 driver->num = lines;
2941 /* later we'll move allocation of tables here */ 2940 /* later we'll move allocation of tables here */
2942 } 2941 }
2943 return driver; 2942 return driver;
2944} 2943}
2944EXPORT_SYMBOL(alloc_tty_driver);
2945 2945
2946void put_tty_driver(struct tty_driver *driver) 2946static void destruct_tty_driver(struct kref *kref)
2947{ 2947{
2948 struct tty_driver *driver = container_of(kref, struct tty_driver, kref);
2949 int i;
2950 struct ktermios *tp;
2951 void *p;
2952
2953 if (driver->flags & TTY_DRIVER_INSTALLED) {
2954 /*
2955 * Free the termios and termios_locked structures because
2956 * we don't want to get memory leaks when modular tty
2957 * drivers are removed from the kernel.
2958 */
2959 for (i = 0; i < driver->num; i++) {
2960 tp = driver->termios[i];
2961 if (tp) {
2962 driver->termios[i] = NULL;
2963 kfree(tp);
2964 }
2965 tp = driver->termios_locked[i];
2966 if (tp) {
2967 driver->termios_locked[i] = NULL;
2968 kfree(tp);
2969 }
2970 if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV))
2971 tty_unregister_device(driver, i);
2972 }
2973 p = driver->ttys;
2974 proc_tty_unregister_driver(driver);
2975 driver->ttys = NULL;
2976 driver->termios = driver->termios_locked = NULL;
2977 kfree(p);
2978 cdev_del(&driver->cdev);
2979 }
2948 kfree(driver); 2980 kfree(driver);
2949} 2981}
2950 2982
2983void tty_driver_kref_put(struct tty_driver *driver)
2984{
2985 kref_put(&driver->kref, destruct_tty_driver);
2986}
2987EXPORT_SYMBOL(tty_driver_kref_put);
2988
2951void tty_set_operations(struct tty_driver *driver, 2989void tty_set_operations(struct tty_driver *driver,
2952 const struct tty_operations *op) 2990 const struct tty_operations *op)
2953{ 2991{
2954 driver->ops = op; 2992 driver->ops = op;
2955}; 2993};
2994EXPORT_SYMBOL(tty_set_operations);
2956 2995
2957EXPORT_SYMBOL(alloc_tty_driver); 2996void put_tty_driver(struct tty_driver *d)
2997{
2998 tty_driver_kref_put(d);
2999}
2958EXPORT_SYMBOL(put_tty_driver); 3000EXPORT_SYMBOL(put_tty_driver);
2959EXPORT_SYMBOL(tty_set_operations);
2960 3001
2961/* 3002/*
2962 * Called by a tty driver to register itself. 3003 * Called by a tty driver to register itself.
@@ -2968,9 +3009,6 @@ int tty_register_driver(struct tty_driver *driver)
2968 dev_t dev; 3009 dev_t dev;
2969 void **p = NULL; 3010 void **p = NULL;
2970 3011
2971 if (driver->flags & TTY_DRIVER_INSTALLED)
2972 return 0;
2973
2974 if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) { 3012 if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) {
2975 p = kzalloc(driver->num * 3 * sizeof(void *), GFP_KERNEL); 3013 p = kzalloc(driver->num * 3 * sizeof(void *), GFP_KERNEL);
2976 if (!p) 3014 if (!p)
@@ -3024,6 +3062,7 @@ int tty_register_driver(struct tty_driver *driver)
3024 tty_register_device(driver, i, NULL); 3062 tty_register_device(driver, i, NULL);
3025 } 3063 }
3026 proc_tty_register_driver(driver); 3064 proc_tty_register_driver(driver);
3065 driver->flags |= TTY_DRIVER_INSTALLED;
3027 return 0; 3066 return 0;
3028} 3067}
3029 3068
@@ -3034,46 +3073,19 @@ EXPORT_SYMBOL(tty_register_driver);
3034 */ 3073 */
3035int tty_unregister_driver(struct tty_driver *driver) 3074int tty_unregister_driver(struct tty_driver *driver)
3036{ 3075{
3037 int i; 3076#if 0
3038 struct ktermios *tp; 3077 /* FIXME */
3039 void *p;
3040
3041 if (driver->refcount) 3078 if (driver->refcount)
3042 return -EBUSY; 3079 return -EBUSY;
3043 3080#endif
3044 unregister_chrdev_region(MKDEV(driver->major, driver->minor_start), 3081 unregister_chrdev_region(MKDEV(driver->major, driver->minor_start),
3045 driver->num); 3082 driver->num);
3046 mutex_lock(&tty_mutex); 3083 mutex_lock(&tty_mutex);
3047 list_del(&driver->tty_drivers); 3084 list_del(&driver->tty_drivers);
3048 mutex_unlock(&tty_mutex); 3085 mutex_unlock(&tty_mutex);
3049
3050 /*
3051 * Free the termios and termios_locked structures because
3052 * we don't want to get memory leaks when modular tty
3053 * drivers are removed from the kernel.
3054 */
3055 for (i = 0; i < driver->num; i++) {
3056 tp = driver->termios[i];
3057 if (tp) {
3058 driver->termios[i] = NULL;
3059 kfree(tp);
3060 }
3061 tp = driver->termios_locked[i];
3062 if (tp) {
3063 driver->termios_locked[i] = NULL;
3064 kfree(tp);
3065 }
3066 if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV))
3067 tty_unregister_device(driver, i);
3068 }
3069 p = driver->ttys;
3070 proc_tty_unregister_driver(driver);
3071 driver->ttys = NULL;
3072 driver->termios = driver->termios_locked = NULL;
3073 kfree(p);
3074 cdev_del(&driver->cdev);
3075 return 0; 3086 return 0;
3076} 3087}
3088
3077EXPORT_SYMBOL(tty_unregister_driver); 3089EXPORT_SYMBOL(tty_unregister_driver);
3078 3090
3079dev_t tty_devnum(struct tty_struct *tty) 3091dev_t tty_devnum(struct tty_struct *tty)