diff options
author | Arjan van de Ven <arjan@infradead.org> | 2006-09-29 05:00:43 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-29 12:18:16 -0400 |
commit | 5785c95baede8459d70c4aa0f7becb6e8b5fde4b (patch) | |
tree | 17744eac694b4eab81cba4db28c4e083d779b753 | |
parent | 54306cf04c0ea0a8c432603dbc657ab62a438668 (diff) |
[PATCH] tty: make termios_sem a mutex
[akpm@osdl.org: fix]
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Arjan van de Ven <arjan@infradead.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | drivers/char/tty_io.c | 23 | ||||
-rw-r--r-- | drivers/char/tty_ioctl.c | 17 | ||||
-rw-r--r-- | include/linux/tty.h | 2 |
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 | ||
619 | static void tty_set_termios_ldisc(struct tty_struct *tty, int num) | 619 | static 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; |
2803 | done: | 2804 | done: |
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; |