aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_ioctl.c
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2008-04-30 03:53:59 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-30 11:29:45 -0400
commit978e595f88a1fba5869aa42a4af4fba36f33ecac (patch)
tree60848f49949c5b7b518621ee36cdc6d500244539 /drivers/char/tty_ioctl.c
parentac0e4b7d319bf284bb64bc7e1c051417386b34a4 (diff)
tty/serial: lay the foundations for the next set of reworks
- Stop drivers calling their own flush method indirectly, it obfuscates code and it will change soon anyway - A few more lock_kernel paths temporarily needed in some driver internal waiting code - Remove private put_char method that does a write call for one char - we have that anyway - Most but not yet all of the termios copy under lock fixing (some has other dependencies to follow) - Note a few locking bugs in drivers found in the process - Kill remaining [ab]users of TIOCG/SSOFTCAR in the driver, these must go to fix the termios locking Signed-off-by: Alan Cox <alan@redhat.com> Cc: Jiri Slaby <jirislaby@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char/tty_ioctl.c')
-rw-r--r--drivers/char/tty_ioctl.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index d769e43f73fb..8c4bf3e48d5b 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -396,7 +396,7 @@ EXPORT_SYMBOL(tty_termios_hw_change);
396static void change_termios(struct tty_struct *tty, struct ktermios *new_termios) 396static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
397{ 397{
398 int canon_change; 398 int canon_change;
399 struct ktermios old_termios = *tty->termios; 399 struct ktermios old_termios;
400 struct tty_ldisc *ld; 400 struct tty_ldisc *ld;
401 unsigned long flags; 401 unsigned long flags;
402 402
@@ -408,7 +408,7 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
408 /* FIXME: we need to decide on some locking/ordering semantics 408 /* FIXME: we need to decide on some locking/ordering semantics
409 for the set_termios notification eventually */ 409 for the set_termios notification eventually */
410 mutex_lock(&tty->termios_mutex); 410 mutex_lock(&tty->termios_mutex);
411 411 old_termios = *tty->termios;
412 *tty->termios = *new_termios; 412 *tty->termios = *new_termios;
413 unset_locked_termios(tty->termios, &old_termios, tty->termios_locked); 413 unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
414 canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON; 414 canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON;
@@ -480,7 +480,9 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
480 if (retval) 480 if (retval)
481 return retval; 481 return retval;
482 482
483 mutex_lock(&tty->termios_mutex);
483 memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios)); 484 memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios));
485 mutex_unlock(&tty->termios_mutex);
484 486
485 if (opt & TERMIOS_TERMIO) { 487 if (opt & TERMIOS_TERMIO) {
486 if (user_termio_to_kernel_termios(&tmp_termios, 488 if (user_termio_to_kernel_termios(&tmp_termios,
@@ -666,12 +668,14 @@ static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars)
666{ 668{
667 struct tchars tmp; 669 struct tchars tmp;
668 670
671 mutex_lock(&tty->termios_mutex);
669 tmp.t_intrc = tty->termios->c_cc[VINTR]; 672 tmp.t_intrc = tty->termios->c_cc[VINTR];
670 tmp.t_quitc = tty->termios->c_cc[VQUIT]; 673 tmp.t_quitc = tty->termios->c_cc[VQUIT];
671 tmp.t_startc = tty->termios->c_cc[VSTART]; 674 tmp.t_startc = tty->termios->c_cc[VSTART];
672 tmp.t_stopc = tty->termios->c_cc[VSTOP]; 675 tmp.t_stopc = tty->termios->c_cc[VSTOP];
673 tmp.t_eofc = tty->termios->c_cc[VEOF]; 676 tmp.t_eofc = tty->termios->c_cc[VEOF];
674 tmp.t_brkc = tty->termios->c_cc[VEOL2]; /* what is brkc anyway? */ 677 tmp.t_brkc = tty->termios->c_cc[VEOL2]; /* what is brkc anyway? */
678 mutex_unlock(&tty->termios_mutex);
675 return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; 679 return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
676} 680}
677 681
@@ -681,12 +685,14 @@ static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars)
681 685
682 if (copy_from_user(&tmp, tchars, sizeof(tmp))) 686 if (copy_from_user(&tmp, tchars, sizeof(tmp)))
683 return -EFAULT; 687 return -EFAULT;
688 mutex_lock(&tty->termios_mutex);
684 tty->termios->c_cc[VINTR] = tmp.t_intrc; 689 tty->termios->c_cc[VINTR] = tmp.t_intrc;
685 tty->termios->c_cc[VQUIT] = tmp.t_quitc; 690 tty->termios->c_cc[VQUIT] = tmp.t_quitc;
686 tty->termios->c_cc[VSTART] = tmp.t_startc; 691 tty->termios->c_cc[VSTART] = tmp.t_startc;
687 tty->termios->c_cc[VSTOP] = tmp.t_stopc; 692 tty->termios->c_cc[VSTOP] = tmp.t_stopc;
688 tty->termios->c_cc[VEOF] = tmp.t_eofc; 693 tty->termios->c_cc[VEOF] = tmp.t_eofc;
689 tty->termios->c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */ 694 tty->termios->c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */
695 mutex_unlock(&tty->termios_mutex);
690 return 0; 696 return 0;
691} 697}
692#endif 698#endif
@@ -696,6 +702,7 @@ static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
696{ 702{
697 struct ltchars tmp; 703 struct ltchars tmp;
698 704
705 mutex_lock(&tty->termios_mutex);
699 tmp.t_suspc = tty->termios->c_cc[VSUSP]; 706 tmp.t_suspc = tty->termios->c_cc[VSUSP];
700 /* what is dsuspc anyway? */ 707 /* what is dsuspc anyway? */
701 tmp.t_dsuspc = tty->termios->c_cc[VSUSP]; 708 tmp.t_dsuspc = tty->termios->c_cc[VSUSP];
@@ -704,6 +711,7 @@ static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
704 tmp.t_flushc = tty->termios->c_cc[VEOL2]; 711 tmp.t_flushc = tty->termios->c_cc[VEOL2];
705 tmp.t_werasc = tty->termios->c_cc[VWERASE]; 712 tmp.t_werasc = tty->termios->c_cc[VWERASE];
706 tmp.t_lnextc = tty->termios->c_cc[VLNEXT]; 713 tmp.t_lnextc = tty->termios->c_cc[VLNEXT];
714 mutex_unlock(&tty->termios_mutex);
707 return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; 715 return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
708} 716}
709 717
@@ -714,6 +722,7 @@ static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
714 if (copy_from_user(&tmp, ltchars, sizeof(tmp))) 722 if (copy_from_user(&tmp, ltchars, sizeof(tmp)))
715 return -EFAULT; 723 return -EFAULT;
716 724
725 mutex_lock(&tty->termios_mutex);
717 tty->termios->c_cc[VSUSP] = tmp.t_suspc; 726 tty->termios->c_cc[VSUSP] = tmp.t_suspc;
718 /* what is dsuspc anyway? */ 727 /* what is dsuspc anyway? */
719 tty->termios->c_cc[VEOL2] = tmp.t_dsuspc; 728 tty->termios->c_cc[VEOL2] = tmp.t_dsuspc;
@@ -722,6 +731,7 @@ static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
722 tty->termios->c_cc[VEOL2] = tmp.t_flushc; 731 tty->termios->c_cc[VEOL2] = tmp.t_flushc;
723 tty->termios->c_cc[VWERASE] = tmp.t_werasc; 732 tty->termios->c_cc[VWERASE] = tmp.t_werasc;
724 tty->termios->c_cc[VLNEXT] = tmp.t_lnextc; 733 tty->termios->c_cc[VLNEXT] = tmp.t_lnextc;
734 mutex_unlock(&tty->termios_mutex);
725 return 0; 735 return 0;
726} 736}
727#endif 737#endif