diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/char/tty_io.c | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 31831030f73f..cc4b43bad703 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) | |||
| 251 | 251 | ||
| 252 | static DEFINE_SPINLOCK(tty_ldisc_lock); | 252 | static DEFINE_SPINLOCK(tty_ldisc_lock); |
| 253 | static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); | 253 | static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); |
| 254 | static struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table */ | 254 | static struct tty_ldisc tty_ldiscs[NR_LDISCS]; /* line disc dispatch table */ |
| 255 | 255 | ||
| 256 | int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) | 256 | int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) |
| 257 | { | 257 | { |
| @@ -262,24 +262,35 @@ int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) | |||
| 262 | return -EINVAL; | 262 | return -EINVAL; |
| 263 | 263 | ||
| 264 | spin_lock_irqsave(&tty_ldisc_lock, flags); | 264 | spin_lock_irqsave(&tty_ldisc_lock, flags); |
| 265 | if (new_ldisc) { | 265 | tty_ldiscs[disc] = *new_ldisc; |
| 266 | tty_ldiscs[disc] = *new_ldisc; | 266 | tty_ldiscs[disc].num = disc; |
| 267 | tty_ldiscs[disc].num = disc; | 267 | tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED; |
| 268 | tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED; | 268 | 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); | 269 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); |
| 277 | 270 | ||
| 278 | return ret; | 271 | return ret; |
| 279 | } | 272 | } |
| 280 | |||
| 281 | EXPORT_SYMBOL(tty_register_ldisc); | 273 | EXPORT_SYMBOL(tty_register_ldisc); |
| 282 | 274 | ||
| 275 | int tty_unregister_ldisc(int disc) | ||
| 276 | { | ||
| 277 | unsigned long flags; | ||
| 278 | int ret = 0; | ||
| 279 | |||
| 280 | if (disc < N_TTY || disc >= NR_LDISCS) | ||
| 281 | return -EINVAL; | ||
| 282 | |||
| 283 | spin_lock_irqsave(&tty_ldisc_lock, flags); | ||
| 284 | if (tty_ldiscs[disc].refcount) | ||
| 285 | ret = -EBUSY; | ||
| 286 | else | ||
| 287 | tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED; | ||
| 288 | spin_unlock_irqrestore(&tty_ldisc_lock, flags); | ||
| 289 | |||
| 290 | return ret; | ||
| 291 | } | ||
| 292 | EXPORT_SYMBOL(tty_unregister_ldisc); | ||
| 293 | |||
| 283 | struct tty_ldisc *tty_ldisc_get(int disc) | 294 | struct tty_ldisc *tty_ldisc_get(int disc) |
| 284 | { | 295 | { |
| 285 | unsigned long flags; | 296 | unsigned long flags; |
