From: Arjan van de Ven Cc: Alan Cox Signed-off-by: Andrew Morton --- drivers/char/tty_io.c | 10 +++++----- drivers/char/tty_ioctl.c | 17 +++++++++-------- include/linux/tty.h | 2 +- 3 files changed, 15 insertions(+), 14 deletions(-) diff -puN drivers/char/tty_io.c~tty-make-termios_sem-a-mutex drivers/char/tty_io.c --- a/drivers/char/tty_io.c~tty-make-termios_sem-a-mutex +++ a/drivers/char/tty_io.c @@ -618,9 +618,9 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_strin static void tty_set_termios_ldisc(struct tty_struct *tty, int num) { - down(&tty->termios_sem); + mutex_lock(&tty->termios_mutex); tty->termios->c_line = num; - up(&tty->termios_sem); + mutex_unlock(&tty->termios_mutex); } /* @@ -1338,9 +1338,9 @@ static void do_tty_hangup(void *data) */ if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { - down(&tty->termios_sem); + mutex_lock(&tty->termios_mutex); *tty->termios = tty->driver->init_termios; - up(&tty->termios_sem); + mutex_unlock(&tty->termios_mutex); } /* Defer ldisc switch */ @@ -3576,7 +3576,7 @@ static void initialize_tty_struct(struct tty_buffer_init(tty); INIT_WORK(&tty->buf.work, flush_to_ldisc, tty); init_MUTEX(&tty->buf.pty_sem); - init_MUTEX(&tty->termios_sem); + mutex_init(&tty->termios_mutex); init_waitqueue_head(&tty->write_wait); init_waitqueue_head(&tty->read_wait); INIT_WORK(&tty->hangup_work, do_tty_hangup, tty); diff -puN drivers/char/tty_ioctl.c~tty-make-termios_sem-a-mutex drivers/char/tty_ioctl.c --- a/drivers/char/tty_ioctl.c~tty-make-termios_sem-a-mutex +++ a/drivers/char/tty_ioctl.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -131,7 +132,7 @@ static void change_termios(struct tty_st /* FIXME: we need to decide on some locking/ordering semantics for the set_termios notification eventually */ - down(&tty->termios_sem); + mutex_lock(&tty->termios_mutex); *tty->termios = *new_termios; unset_locked_termios(tty->termios, &old_termios, tty->termios_locked); @@ -176,7 +177,7 @@ static void change_termios(struct tty_st (ld->set_termios)(tty, &old_termios); tty_ldisc_deref(ld); } - up(&tty->termios_sem); + mutex_unlock(&tty->termios_mutex); } /** @@ -284,13 +285,13 @@ static int get_sgttyb(struct tty_struct { struct sgttyb tmp; - down(&tty->termios_sem); + mutex_lock(&tty->termios_mutex); tmp.sg_ispeed = 0; tmp.sg_ospeed = 0; tmp.sg_erase = tty->termios->c_cc[VERASE]; tmp.sg_kill = tty->termios->c_cc[VKILL]; tmp.sg_flags = get_sgflags(tty); - up(&tty->termios_sem); + mutex_unlock(&tty->termios_mutex); return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0; } @@ -345,12 +346,12 @@ static int set_sgttyb(struct tty_struct if (copy_from_user(&tmp, sgttyb, sizeof(tmp))) return -EFAULT; - down(&tty->termios_sem); + mutex_lock(&tty->termios_mutex); termios = *tty->termios; termios.c_cc[VERASE] = tmp.sg_erase; termios.c_cc[VKILL] = tmp.sg_kill; set_sgflags(&termios, tmp.sg_flags); - up(&tty->termios_sem); + mutex_unlock(&tty->termios_mutex); change_termios(tty, &termios); return 0; } @@ -592,11 +593,11 @@ int n_tty_ioctl(struct tty_struct * tty, case TIOCSSOFTCAR: if (get_user(arg, (unsigned int __user *) arg)) return -EFAULT; - down(&tty->termios_sem); + mutex_lock(&tty->termios_mutex); tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0)); - up(&tty->termios_sem); + mutex_unlock(&tty->termios_mutex); return 0; default: return -ENOIOCTLCMD; diff -puN include/linux/tty.h~tty-make-termios_sem-a-mutex include/linux/tty.h --- a/include/linux/tty.h~tty-make-termios_sem-a-mutex +++ a/include/linux/tty.h @@ -174,7 +174,7 @@ struct tty_struct { struct tty_driver *driver; int index; struct tty_ldisc ldisc; - struct semaphore termios_sem; + struct mutex termios_mutex; struct termios *termios, *termios_locked; char name[64]; int pgrp; _