aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-12-02 15:58:16 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2010-12-02 15:58:16 -0500
commiteed5ee1a3ab3020168cd67fdde2500452b0628c9 (patch)
tree9548c5a4851b1a1e832b7800baf1e72b33bc7a66 /drivers/tty
parent435a5aebf609624bdf7c5a9a7705c260d0076195 (diff)
parenta5880a9e5bb40fbae55de60051d69a29091053c3 (diff)
Merge branch 'tty-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6
* 'tty-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6: serial: mfd: adjust the baud rate setting TTY: open/hangup race fixup TTY: don't allow reopen when ldisc is changing NET: wan/x25, fix ldisc->open retval TTY: ldisc, fix open flag handling serial8250: Mark console as CON_ANYTIME
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/tty_io.c13
-rw-r--r--drivers/tty/tty_ldisc.c2
2 files changed, 13 insertions, 2 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index c05c5af5aa04..35480dd57a30 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -559,6 +559,9 @@ void __tty_hangup(struct tty_struct *tty)
559 559
560 tty_lock(); 560 tty_lock();
561 561
562 /* some functions below drop BTM, so we need this bit */
563 set_bit(TTY_HUPPING, &tty->flags);
564
562 /* inuse_filps is protected by the single tty lock, 565 /* inuse_filps is protected by the single tty lock,
563 this really needs to change if we want to flush the 566 this really needs to change if we want to flush the
564 workqueue with the lock held */ 567 workqueue with the lock held */
@@ -578,6 +581,10 @@ void __tty_hangup(struct tty_struct *tty)
578 } 581 }
579 spin_unlock(&tty_files_lock); 582 spin_unlock(&tty_files_lock);
580 583
584 /*
585 * it drops BTM and thus races with reopen
586 * we protect the race by TTY_HUPPING
587 */
581 tty_ldisc_hangup(tty); 588 tty_ldisc_hangup(tty);
582 589
583 read_lock(&tasklist_lock); 590 read_lock(&tasklist_lock);
@@ -615,7 +622,6 @@ void __tty_hangup(struct tty_struct *tty)
615 tty->session = NULL; 622 tty->session = NULL;
616 tty->pgrp = NULL; 623 tty->pgrp = NULL;
617 tty->ctrl_status = 0; 624 tty->ctrl_status = 0;
618 set_bit(TTY_HUPPED, &tty->flags);
619 spin_unlock_irqrestore(&tty->ctrl_lock, flags); 625 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
620 626
621 /* Account for the p->signal references we killed */ 627 /* Account for the p->signal references we killed */
@@ -641,6 +647,7 @@ void __tty_hangup(struct tty_struct *tty)
641 * can't yet guarantee all that. 647 * can't yet guarantee all that.
642 */ 648 */
643 set_bit(TTY_HUPPED, &tty->flags); 649 set_bit(TTY_HUPPED, &tty->flags);
650 clear_bit(TTY_HUPPING, &tty->flags);
644 tty_ldisc_enable(tty); 651 tty_ldisc_enable(tty);
645 652
646 tty_unlock(); 653 tty_unlock();
@@ -1310,7 +1317,9 @@ static int tty_reopen(struct tty_struct *tty)
1310{ 1317{
1311 struct tty_driver *driver = tty->driver; 1318 struct tty_driver *driver = tty->driver;
1312 1319
1313 if (test_bit(TTY_CLOSING, &tty->flags)) 1320 if (test_bit(TTY_CLOSING, &tty->flags) ||
1321 test_bit(TTY_HUPPING, &tty->flags) ||
1322 test_bit(TTY_LDISC_CHANGING, &tty->flags))
1314 return -EIO; 1323 return -EIO;
1315 1324
1316 if (driver->type == TTY_DRIVER_TYPE_PTY && 1325 if (driver->type == TTY_DRIVER_TYPE_PTY &&
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c
index d8e96b005023..4214d58276f7 100644
--- a/drivers/tty/tty_ldisc.c
+++ b/drivers/tty/tty_ldisc.c
@@ -454,6 +454,8 @@ static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld)
454 /* BTM here locks versus a hangup event */ 454 /* BTM here locks versus a hangup event */
455 WARN_ON(!tty_locked()); 455 WARN_ON(!tty_locked());
456 ret = ld->ops->open(tty); 456 ret = ld->ops->open(tty);
457 if (ret)
458 clear_bit(TTY_LDISC_OPEN, &tty->flags);
457 return ret; 459 return ret;
458 } 460 }
459 return 0; 461 return 0;