aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/tty_io.c23
-rw-r--r--drivers/char/tty_ioctl.c17
-rw-r--r--include/linux/tty.h2
3 files changed, 22 insertions, 20 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index b4f37c65b95c..142427c6e8f3 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -618,9 +618,9 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags);
618 618
619static void tty_set_termios_ldisc(struct tty_struct *tty, int num) 619static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
620{ 620{
621 down(&tty->termios_sem); 621 mutex_lock(&tty->termios_mutex);
622 tty->termios->c_line = num; 622 tty->termios->c_line = num;
623 up(&tty->termios_sem); 623 mutex_unlock(&tty->termios_mutex);
624} 624}
625 625
626/* 626/*
@@ -1338,9 +1338,9 @@ static void do_tty_hangup(void *data)
1338 */ 1338 */
1339 if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) 1339 if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS)
1340 { 1340 {
1341 down(&tty->termios_sem); 1341 mutex_lock(&tty->termios_mutex);
1342 *tty->termios = tty->driver->init_termios; 1342 *tty->termios = tty->driver->init_termios;
1343 up(&tty->termios_sem); 1343 mutex_unlock(&tty->termios_mutex);
1344 } 1344 }
1345 1345
1346 /* Defer ldisc switch */ 1346 /* Defer ldisc switch */
@@ -2750,9 +2750,9 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user * arg)
2750{ 2750{
2751 int err; 2751 int err;
2752 2752
2753 down(&tty->termios_sem); 2753 mutex_lock(&tty->termios_mutex);
2754 err = copy_to_user(arg, &tty->winsize, sizeof(*arg)); 2754 err = copy_to_user(arg, &tty->winsize, sizeof(*arg));
2755 up(&tty->termios_sem); 2755 mutex_unlock(&tty->termios_mutex);
2756 2756
2757 return err ? -EFAULT: 0; 2757 return err ? -EFAULT: 0;
2758} 2758}
@@ -2782,14 +2782,15 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
2782 if (copy_from_user(&tmp_ws, arg, sizeof(*arg))) 2782 if (copy_from_user(&tmp_ws, arg, sizeof(*arg)))
2783 return -EFAULT; 2783 return -EFAULT;
2784 2784
2785 down(&tty->termios_sem); 2785 mutex_lock(&tty->termios_mutex);
2786 if (!memcmp(&tmp_ws, &tty->winsize, sizeof(*arg))) 2786 if (!memcmp(&tmp_ws, &tty->winsize, sizeof(*arg)))
2787 goto done; 2787 goto done;
2788 2788
2789#ifdef CONFIG_VT 2789#ifdef CONFIG_VT
2790 if (tty->driver->type == TTY_DRIVER_TYPE_CONSOLE) { 2790 if (tty->driver->type == TTY_DRIVER_TYPE_CONSOLE) {
2791 if (vc_lock_resize(tty->driver_data, tmp_ws.ws_col, tmp_ws.ws_row)) { 2791 if (vc_lock_resize(tty->driver_data, tmp_ws.ws_col,
2792 up(&tty->termios_sem); 2792 tmp_ws.ws_row)) {
2793 mutex_unlock(&tty->termios_mutex);
2793 return -ENXIO; 2794 return -ENXIO;
2794 } 2795 }
2795 } 2796 }
@@ -2801,7 +2802,7 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
2801 tty->winsize = tmp_ws; 2802 tty->winsize = tmp_ws;
2802 real_tty->winsize = tmp_ws; 2803 real_tty->winsize = tmp_ws;
2803done: 2804done:
2804 up(&tty->termios_sem); 2805 mutex_unlock(&tty->termios_mutex);
2805 return 0; 2806 return 0;
2806} 2807}
2807 2808
@@ -3576,7 +3577,7 @@ static void initialize_tty_struct(struct tty_struct *tty)
3576 tty_buffer_init(tty); 3577 tty_buffer_init(tty);
3577 INIT_WORK(&tty->buf.work, flush_to_ldisc, tty); 3578 INIT_WORK(&tty->buf.work, flush_to_ldisc, tty);
3578 init_MUTEX(&tty->buf.pty_sem); 3579 init_MUTEX(&tty->buf.pty_sem);
3579 init_MUTEX(&tty->termios_sem); 3580 mutex_init(&tty->termios_mutex);
3580 init_waitqueue_head(&tty->write_wait); 3581 init_waitqueue_head(&tty->write_wait);
3581 init_waitqueue_head(&tty->read_wait); 3582 init_waitqueue_head(&tty->read_wait);
3582 INIT_WORK(&tty->hangup_work, do_tty_hangup, tty); 3583 INIT_WORK(&tty->hangup_work, do_tty_hangup, tty);
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index 4ad47d321bd4..4d540619ac84 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -20,6 +20,7 @@
20#include <linux/mm.h> 20#include <linux/mm.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/bitops.h> 22#include <linux/bitops.h>
23#include <linux/mutex.h>
23 24
24#include <asm/io.h> 25#include <asm/io.h>
25#include <asm/uaccess.h> 26#include <asm/uaccess.h>
@@ -131,7 +132,7 @@ static void change_termios(struct tty_struct * tty, struct termios * new_termios
131 132
132 /* FIXME: we need to decide on some locking/ordering semantics 133 /* FIXME: we need to decide on some locking/ordering semantics
133 for the set_termios notification eventually */ 134 for the set_termios notification eventually */
134 down(&tty->termios_sem); 135 mutex_lock(&tty->termios_mutex);
135 136
136 *tty->termios = *new_termios; 137 *tty->termios = *new_termios;
137 unset_locked_termios(tty->termios, &old_termios, tty->termios_locked); 138 unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
@@ -176,7 +177,7 @@ static void change_termios(struct tty_struct * tty, struct termios * new_termios
176 (ld->set_termios)(tty, &old_termios); 177 (ld->set_termios)(tty, &old_termios);
177 tty_ldisc_deref(ld); 178 tty_ldisc_deref(ld);
178 } 179 }
179 up(&tty->termios_sem); 180 mutex_unlock(&tty->termios_mutex);
180} 181}
181 182
182/** 183/**
@@ -284,13 +285,13 @@ static int get_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
284{ 285{
285 struct sgttyb tmp; 286 struct sgttyb tmp;
286 287
287 down(&tty->termios_sem); 288 mutex_lock(&tty->termios_mutex);
288 tmp.sg_ispeed = 0; 289 tmp.sg_ispeed = 0;
289 tmp.sg_ospeed = 0; 290 tmp.sg_ospeed = 0;
290 tmp.sg_erase = tty->termios->c_cc[VERASE]; 291 tmp.sg_erase = tty->termios->c_cc[VERASE];
291 tmp.sg_kill = tty->termios->c_cc[VKILL]; 292 tmp.sg_kill = tty->termios->c_cc[VKILL];
292 tmp.sg_flags = get_sgflags(tty); 293 tmp.sg_flags = get_sgflags(tty);
293 up(&tty->termios_sem); 294 mutex_unlock(&tty->termios_mutex);
294 295
295 return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0; 296 return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
296} 297}
@@ -345,12 +346,12 @@ static int set_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
345 if (copy_from_user(&tmp, sgttyb, sizeof(tmp))) 346 if (copy_from_user(&tmp, sgttyb, sizeof(tmp)))
346 return -EFAULT; 347 return -EFAULT;
347 348
348 down(&tty->termios_sem); 349 mutex_lock(&tty->termios_mutex);
349 termios = *tty->termios; 350 termios = *tty->termios;
350 termios.c_cc[VERASE] = tmp.sg_erase; 351 termios.c_cc[VERASE] = tmp.sg_erase;
351 termios.c_cc[VKILL] = tmp.sg_kill; 352 termios.c_cc[VKILL] = tmp.sg_kill;
352 set_sgflags(&termios, tmp.sg_flags); 353 set_sgflags(&termios, tmp.sg_flags);
353 up(&tty->termios_sem); 354 mutex_unlock(&tty->termios_mutex);
354 change_termios(tty, &termios); 355 change_termios(tty, &termios);
355 return 0; 356 return 0;
356} 357}
@@ -592,11 +593,11 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
592 case TIOCSSOFTCAR: 593 case TIOCSSOFTCAR:
593 if (get_user(arg, (unsigned int __user *) arg)) 594 if (get_user(arg, (unsigned int __user *) arg))
594 return -EFAULT; 595 return -EFAULT;
595 down(&tty->termios_sem); 596 mutex_lock(&tty->termios_mutex);
596 tty->termios->c_cflag = 597 tty->termios->c_cflag =
597 ((tty->termios->c_cflag & ~CLOCAL) | 598 ((tty->termios->c_cflag & ~CLOCAL) |
598 (arg ? CLOCAL : 0)); 599 (arg ? CLOCAL : 0));
599 up(&tty->termios_sem); 600 mutex_unlock(&tty->termios_mutex);
600 return 0; 601 return 0;
601 default: 602 default:
602 return -ENOIOCTLCMD; 603 return -ENOIOCTLCMD;
diff --git a/include/linux/tty.h b/include/linux/tty.h
index d1dec3d0c814..ea4c2605f8da 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -174,7 +174,7 @@ struct tty_struct {
174 struct tty_driver *driver; 174 struct tty_driver *driver;
175 int index; 175 int index;
176 struct tty_ldisc ldisc; 176 struct tty_ldisc ldisc;
177 struct semaphore termios_sem; 177 struct mutex termios_mutex;
178 struct termios *termios, *termios_locked; 178 struct termios *termios, *termios_locked;
179 char name[64]; 179 char name[64];
180 int pgrp; 180 int pgrp;