[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>
This commit is contained in:
parent
790a19cd57
commit
bfb07599da
3 changed files with 26 additions and 14 deletions
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue