diff options
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r-- | drivers/char/tty_io.c | 47 |
1 files changed, 29 insertions, 18 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 31831030f73f..6e4be3bb2d89 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -94,6 +94,7 @@ #include <linux/idr.h> #include <linux/wait.h> #include <linux/bitops.h> +#include <linux/delay.h> #include <asm/uaccess.h> #include <asm/system.h> @@ -251,7 +252,7 @@ static void tty_set_termios_ldisc(struct tty_struct *tty, int num) static DEFINE_SPINLOCK(tty_ldisc_lock); static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); -static struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table */ +static struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table */ int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) { @@ -262,24 +263,35 @@ int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) return -EINVAL; spin_lock_irqsave(&tty_ldisc_lock, flags); - if (new_ldisc) { - tty_ldiscs[disc] = *new_ldisc; - tty_ldiscs[disc].num = disc; - tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED; - tty_ldiscs[disc].refcount = 0; - } else { - if(tty_ldiscs[disc].refcount) - ret = -EBUSY; - else - tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED; - } + tty_ldiscs[disc] = *new_ldisc; + tty_ldiscs[disc].num = disc; + tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED; + tty_ldiscs[disc].refcount = 0; spin_unlock_irqrestore(&tty_ldisc_lock, flags); return ret; } - EXPORT_SYMBOL(tty_register_ldisc); +int tty_unregister_ldisc(int disc) +{ + unsigned long flags; + int ret = 0; + + if (disc < N_TTY || disc >= NR_LDISCS) + return -EINVAL; + + spin_lock_irqsave(&tty_ldisc_lock, flags); + if (tty_ldiscs[disc].refcount) + ret = -EBUSY; + else + tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED; + spin_unlock_irqrestore(&tty_ldisc_lock, flags); + + return ret; +} +EXPORT_SYMBOL(tty_unregister_ldisc); + struct tty_ldisc *tty_ldisc_get(int disc) { unsigned long flags; @@ -2169,12 +2181,11 @@ static int tiocsetd(struct tty_struct *tty, int __user *p) return tty_set_ldisc(tty, ldisc); } -static int send_break(struct tty_struct *tty, int duration) +static int send_break(struct tty_struct *tty, unsigned int duration) { tty->driver->break_ctl(tty, -1); if (!signal_pending(current)) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(duration); + msleep_interruptible(duration); } tty->driver->break_ctl(tty, 0); if (signal_pending(current)) @@ -2355,10 +2366,10 @@ int tty_ioctl(struct inode * inode, struct file * file, * all by anyone? */ if (!arg) - return send_break(tty, HZ/4); + return send_break(tty, 250); return 0; case TCSBRKP: /* support for POSIX tcsendbreak() */ - return send_break(tty, arg ? arg*(HZ/10) : HZ/4); + return send_break(tty, arg ? arg*100 : 250); case TIOCMGET: return tty_tiocmget(tty, file, p); |