diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2005-06-23 00:10:32 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-23 09:45:35 -0700 |
commit | bfb07599da289881d3bcbb601a110e997fc7444b (patch) | |
tree | 601c5e683c87e103de37bd68f014ec1f57d09bc7 | |
parent | 790a19cd5711133f40daad7c55bf148de2b1d12c (diff) | |
download | linux-3.10-bfb07599da289881d3bcbb601a110e997fc7444b.tar.gz linux-3.10-bfb07599da289881d3bcbb601a110e997fc7444b.tar.bz2 linux-3.10-bfb07599da289881d3bcbb601a110e997fc7444b.zip |
[PATCH] Introduce tty_unregister_ldisc()
It's a bit strange to see tty_register_ldisc call in modules' exit
functions.
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | Documentation/tty.txt | 2 | ||||
-rw-r--r-- | drivers/char/tty_io.c | 37 | ||||
-rw-r--r-- | include/linux/tty.h | 1 |
3 files changed, 26 insertions, 14 deletions
diff --git a/Documentation/tty.txt b/Documentation/tty.txt index 3958cf746dd..8ff7bc2a081 100644 --- a/Documentation/tty.txt +++ b/Documentation/tty.txt @@ -22,7 +22,7 @@ copy of the structure. You must not re-register over the top of the line discipline even with the same data or your computer again will be eaten by demons. -In order to remove a line discipline call tty_register_ldisc passing NULL. +In order to remove a line discipline call tty_unregister_ldisc(). In ancient times this always worked. In modern times the function will return -EBUSY if the ldisc is currently in use. Since the ldisc referencing code manages the module counts this should not usually be a concern. diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 31831030f73..cc4b43bad70 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -251,7 +251,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 +262,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; diff --git a/include/linux/tty.h b/include/linux/tty.h index 1b76106272d..59ff42c629e 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -345,6 +345,7 @@ extern int tty_check_change(struct tty_struct * tty); extern void stop_tty(struct tty_struct * tty); extern void start_tty(struct tty_struct * tty); extern int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc); +extern int tty_unregister_ldisc(int disc); extern int tty_register_driver(struct tty_driver *driver); extern int tty_unregister_driver(struct tty_driver *driver); extern void tty_register_device(struct tty_driver *driver, unsigned index, struct device *dev); |