Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 364254
b: refs/heads/master
c: 76bc35e
h: refs/heads/master
v: v3
  • Loading branch information
Peter Hurley authored and Greg Kroah-Hartman committed Mar 18, 2013
1 parent 9ee9013 commit f7f1c6f
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 21 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2276ad9765b395577442d6ddf748f72c329234ae
refs/heads/master: 76bc35e78fdf1065ffa2bb62fabe3e8423d378c8
39 changes: 19 additions & 20 deletions trunk/drivers/tty/tty_ldisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -551,22 +551,30 @@ static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout)
}

/**
* tty_ldisc_hangup_wait_idle - wait for the ldisc to become idle
* @tty: tty to wait for
*
* Wait for the line discipline to become idle. The discipline must
* have been halted for this to guarantee it remains idle.
* tty_ldisc_hangup_halt - halt the line discipline for hangup
* @tty: tty being hung up
*
* Shut down the line discipline and work queue for the tty device
* being hungup. Clear the TTY_LDISC flag to ensure no further
* references can be obtained, wait for remaining references to be
* released, and cancel pending buffer work to ensure no more
* data is fed to this ldisc.
* Caller must hold legacy and ->ldisc_mutex.
*
* NB: tty_set_ldisc() is prevented from changing the ldisc concurrently
* with this function by checking the TTY_HUPPING flag.
*
* NB: if tty->ldisc is NULL then buffer work does not need to be
* cancelled because it must already have done as a precondition
* of closing the ldisc and setting tty->ldisc to NULL
*/
static bool tty_ldisc_hangup_wait_idle(struct tty_struct *tty)
static bool tty_ldisc_hangup_halt(struct tty_struct *tty)
{
char cur_n[TASK_COMM_LEN], tty_n[64];
long timeout = 3 * HZ;

clear_bit(TTY_LDISC, &tty->flags);

if (tty->ldisc) { /* Not yet closed */
tty_unlock(tty);

Expand All @@ -577,6 +585,10 @@ static bool tty_ldisc_hangup_wait_idle(struct tty_struct *tty)
__func__, get_task_comm(cur_n, current),
tty_name(tty, tty_n));
}

cancel_work_sync(&tty->port->buf.work);
set_bit(TTY_LDISC_HALTED, &tty->flags);

/* must reacquire both locks and preserve lock order */
mutex_unlock(&tty->ldisc_mutex);
tty_lock(tty);
Expand Down Expand Up @@ -851,24 +863,11 @@ void tty_ldisc_hangup(struct tty_struct *tty)
*/
mutex_lock(&tty->ldisc_mutex);

/*
* this is like tty_ldisc_halt, but we need to give up
* the BTM before calling cancel_work_sync, which may
* need to wait for another function taking the BTM
*/
clear_bit(TTY_LDISC, &tty->flags);
tty_unlock(tty);
cancel_work_sync(&tty->port->buf.work);
set_bit(TTY_LDISC_HALTED, &tty->flags);
mutex_unlock(&tty->ldisc_mutex);
tty_lock(tty);
mutex_lock(&tty->ldisc_mutex);

/* At this point we have a closed ldisc and we want to
reopen it. We could defer this to the next open but
it means auditing a lot of other paths so this is
a FIXME */
if (tty_ldisc_hangup_wait_idle(tty)) {
if (tty_ldisc_hangup_halt(tty)) {
if (reset == 0) {

if (!tty_ldisc_reinit(tty, tty->termios.c_line))
Expand Down

0 comments on commit f7f1c6f

Please sign in to comment.