aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r--drivers/char/tty_io.c63
1 files changed, 37 insertions, 26 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 26e5e19ed854..6e4be3bb2d89 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -94,6 +94,7 @@
94#include <linux/idr.h> 94#include <linux/idr.h>
95#include <linux/wait.h> 95#include <linux/wait.h>
96#include <linux/bitops.h> 96#include <linux/bitops.h>
97#include <linux/delay.h>
97 98
98#include <asm/uaccess.h> 99#include <asm/uaccess.h>
99#include <asm/system.h> 100#include <asm/system.h>
@@ -251,7 +252,7 @@ static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
251 252
252static DEFINE_SPINLOCK(tty_ldisc_lock); 253static DEFINE_SPINLOCK(tty_ldisc_lock);
253static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); 254static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait);
254static struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table */ 255static struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table */
255 256
256int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) 257int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc)
257{ 258{
@@ -262,24 +263,35 @@ int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc)
262 return -EINVAL; 263 return -EINVAL;
263 264
264 spin_lock_irqsave(&tty_ldisc_lock, flags); 265 spin_lock_irqsave(&tty_ldisc_lock, flags);
265 if (new_ldisc) { 266 tty_ldiscs[disc] = *new_ldisc;
266 tty_ldiscs[disc] = *new_ldisc; 267 tty_ldiscs[disc].num = disc;
267 tty_ldiscs[disc].num = disc; 268 tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED;
268 tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED; 269 tty_ldiscs[disc].refcount = 0;
269 tty_ldiscs[disc].refcount = 0;
270 } else {
271 if(tty_ldiscs[disc].refcount)
272 ret = -EBUSY;
273 else
274 tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED;
275 }
276 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 270 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
277 271
278 return ret; 272 return ret;
279} 273}
280
281EXPORT_SYMBOL(tty_register_ldisc); 274EXPORT_SYMBOL(tty_register_ldisc);
282 275
276int tty_unregister_ldisc(int disc)
277{
278 unsigned long flags;
279 int ret = 0;
280
281 if (disc < N_TTY || disc >= NR_LDISCS)
282 return -EINVAL;
283
284 spin_lock_irqsave(&tty_ldisc_lock, flags);
285 if (tty_ldiscs[disc].refcount)
286 ret = -EBUSY;
287 else
288 tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED;
289 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
290
291 return ret;
292}
293EXPORT_SYMBOL(tty_unregister_ldisc);
294
283struct tty_ldisc *tty_ldisc_get(int disc) 295struct tty_ldisc *tty_ldisc_get(int disc)
284{ 296{
285 unsigned long flags; 297 unsigned long flags;
@@ -2169,12 +2181,11 @@ static int tiocsetd(struct tty_struct *tty, int __user *p)
2169 return tty_set_ldisc(tty, ldisc); 2181 return tty_set_ldisc(tty, ldisc);
2170} 2182}
2171 2183
2172static int send_break(struct tty_struct *tty, int duration) 2184static int send_break(struct tty_struct *tty, unsigned int duration)
2173{ 2185{
2174 tty->driver->break_ctl(tty, -1); 2186 tty->driver->break_ctl(tty, -1);
2175 if (!signal_pending(current)) { 2187 if (!signal_pending(current)) {
2176 set_current_state(TASK_INTERRUPTIBLE); 2188 msleep_interruptible(duration);
2177 schedule_timeout(duration);
2178 } 2189 }
2179 tty->driver->break_ctl(tty, 0); 2190 tty->driver->break_ctl(tty, 0);
2180 if (signal_pending(current)) 2191 if (signal_pending(current))
@@ -2355,10 +2366,10 @@ int tty_ioctl(struct inode * inode, struct file * file,
2355 * all by anyone? 2366 * all by anyone?
2356 */ 2367 */
2357 if (!arg) 2368 if (!arg)
2358 return send_break(tty, HZ/4); 2369 return send_break(tty, 250);
2359 return 0; 2370 return 0;
2360 case TCSBRKP: /* support for POSIX tcsendbreak() */ 2371 case TCSBRKP: /* support for POSIX tcsendbreak() */
2361 return send_break(tty, arg ? arg*(HZ/10) : HZ/4); 2372 return send_break(tty, arg ? arg*100 : 250);
2362 2373
2363 case TIOCMGET: 2374 case TIOCMGET:
2364 return tty_tiocmget(tty, file, p); 2375 return tty_tiocmget(tty, file, p);
@@ -2654,7 +2665,7 @@ static void tty_default_put_char(struct tty_struct *tty, unsigned char ch)
2654 tty->driver->write(tty, &ch, 1); 2665 tty->driver->write(tty, &ch, 1);
2655} 2666}
2656 2667
2657static struct class_simple *tty_class; 2668static struct class *tty_class;
2658 2669
2659/** 2670/**
2660 * tty_register_device - register a tty device 2671 * tty_register_device - register a tty device
@@ -2687,7 +2698,7 @@ void tty_register_device(struct tty_driver *driver, unsigned index,
2687 pty_line_name(driver, index, name); 2698 pty_line_name(driver, index, name);
2688 else 2699 else
2689 tty_line_name(driver, index, name); 2700 tty_line_name(driver, index, name);
2690 class_simple_device_add(tty_class, dev, device, name); 2701 class_device_create(tty_class, dev, device, name);
2691} 2702}
2692 2703
2693/** 2704/**
@@ -2701,7 +2712,7 @@ void tty_register_device(struct tty_driver *driver, unsigned index,
2701void tty_unregister_device(struct tty_driver *driver, unsigned index) 2712void tty_unregister_device(struct tty_driver *driver, unsigned index)
2702{ 2713{
2703 devfs_remove("%s%d", driver->devfs_name, index + driver->name_base); 2714 devfs_remove("%s%d", driver->devfs_name, index + driver->name_base);
2704 class_simple_device_remove(MKDEV(driver->major, driver->minor_start) + index); 2715 class_device_destroy(tty_class, MKDEV(driver->major, driver->minor_start) + index);
2705} 2716}
2706 2717
2707EXPORT_SYMBOL(tty_register_device); 2718EXPORT_SYMBOL(tty_register_device);
@@ -2918,7 +2929,7 @@ extern int vty_init(void);
2918 2929
2919static int __init tty_class_init(void) 2930static int __init tty_class_init(void)
2920{ 2931{
2921 tty_class = class_simple_create(THIS_MODULE, "tty"); 2932 tty_class = class_create(THIS_MODULE, "tty");
2922 if (IS_ERR(tty_class)) 2933 if (IS_ERR(tty_class))
2923 return PTR_ERR(tty_class); 2934 return PTR_ERR(tty_class);
2924 return 0; 2935 return 0;
@@ -2947,14 +2958,14 @@ static int __init tty_init(void)
2947 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) 2958 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
2948 panic("Couldn't register /dev/tty driver\n"); 2959 panic("Couldn't register /dev/tty driver\n");
2949 devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 0), S_IFCHR|S_IRUGO|S_IWUGO, "tty"); 2960 devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 0), S_IFCHR|S_IRUGO|S_IWUGO, "tty");
2950 class_simple_device_add(tty_class, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty"); 2961 class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty");
2951 2962
2952 cdev_init(&console_cdev, &console_fops); 2963 cdev_init(&console_cdev, &console_fops);
2953 if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || 2964 if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||
2954 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) 2965 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)
2955 panic("Couldn't register /dev/console driver\n"); 2966 panic("Couldn't register /dev/console driver\n");
2956 devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 1), S_IFCHR|S_IRUSR|S_IWUSR, "console"); 2967 devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 1), S_IFCHR|S_IRUSR|S_IWUSR, "console");
2957 class_simple_device_add(tty_class, MKDEV(TTYAUX_MAJOR, 1), NULL, "console"); 2968 class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 1), NULL, "console");
2958 2969
2959#ifdef CONFIG_UNIX98_PTYS 2970#ifdef CONFIG_UNIX98_PTYS
2960 cdev_init(&ptmx_cdev, &ptmx_fops); 2971 cdev_init(&ptmx_cdev, &ptmx_fops);
@@ -2962,7 +2973,7 @@ static int __init tty_init(void)
2962 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0) 2973 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
2963 panic("Couldn't register /dev/ptmx driver\n"); 2974 panic("Couldn't register /dev/ptmx driver\n");
2964 devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 2), S_IFCHR|S_IRUGO|S_IWUGO, "ptmx"); 2975 devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 2), S_IFCHR|S_IRUGO|S_IWUGO, "ptmx");
2965 class_simple_device_add(tty_class, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx"); 2976 class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
2966#endif 2977#endif
2967 2978
2968#ifdef CONFIG_VT 2979#ifdef CONFIG_VT
@@ -2971,7 +2982,7 @@ static int __init tty_init(void)
2971 register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0) 2982 register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
2972 panic("Couldn't register /dev/tty0 driver\n"); 2983 panic("Couldn't register /dev/tty0 driver\n");
2973 devfs_mk_cdev(MKDEV(TTY_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vc/0"); 2984 devfs_mk_cdev(MKDEV(TTY_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vc/0");
2974 class_simple_device_add(tty_class, MKDEV(TTY_MAJOR, 0), NULL, "tty0"); 2985 class_device_create(tty_class, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
2975 2986
2976 vty_init(); 2987 vty_init();
2977#endif 2988#endif