Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 185204
b: refs/heads/master
c: 638b964
h: refs/heads/master
v: v3
  • Loading branch information
Alan Cox authored and Greg Kroah-Hartman committed Mar 2, 2010
1 parent 97f69c2 commit 81c7ea3
Show file tree
Hide file tree
Showing 2 changed files with 31 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: 97c22394bb5dc89683ac150f1003d47e6e9418d9
refs/heads/master: 638b9648ab51c9c549ff5735d3de519ef6199df3
50 changes: 30 additions & 20 deletions trunk/drivers/char/tty_ldisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -706,12 +706,13 @@ static void tty_reset_termios(struct tty_struct *tty)
/**
* tty_ldisc_reinit - reinitialise the tty ldisc
* @tty: tty to reinit
* @ldisc: line discipline to reinitialize
*
* Switch the tty back to N_TTY line discipline and leave the
* ldisc state closed
* Switch the tty to a line discipline and leave the ldisc
* state closed
*/

static void tty_ldisc_reinit(struct tty_struct *tty)
static void tty_ldisc_reinit(struct tty_struct *tty, int ldisc)
{
struct tty_ldisc *ld;

Expand All @@ -721,10 +722,10 @@ static void tty_ldisc_reinit(struct tty_struct *tty)
/*
* Switch the line discipline back
*/
ld = tty_ldisc_get(N_TTY);
ld = tty_ldisc_get(ldisc);
BUG_ON(IS_ERR(ld));
tty_ldisc_assign(tty, ld);
tty_set_termios_ldisc(tty, N_TTY);
tty_set_termios_ldisc(tty, ldisc);
}

/**
Expand All @@ -745,6 +746,8 @@ static void tty_ldisc_reinit(struct tty_struct *tty)
void tty_ldisc_hangup(struct tty_struct *tty)
{
struct tty_ldisc *ld;
int reset = tty->driver->flags & TTY_DRIVER_RESET_TERMIOS;
int err = 0;

/*
* FIXME! What are the locking issues here? This may me overdoing
Expand Down Expand Up @@ -772,25 +775,32 @@ void tty_ldisc_hangup(struct tty_struct *tty)
wake_up_interruptible_poll(&tty->read_wait, POLLIN);
/*
* Shutdown the current line discipline, and reset it to
* N_TTY.
* N_TTY if need be.
*
* Avoid racing set_ldisc or tty_ldisc_release
*/
if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) {
/* Avoid racing set_ldisc or tty_ldisc_release */
mutex_lock(&tty->ldisc_mutex);
tty_ldisc_halt(tty);
if (tty->ldisc) { /* Not yet closed */
/* Switch back to N_TTY */
tty_ldisc_reinit(tty);
/* 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 */
mutex_lock(&tty->ldisc_mutex);
tty_ldisc_halt(tty);
/* 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) { /* Not yet closed */
if (reset == 0) {
tty_ldisc_reinit(tty, tty->termios->c_line);
err = tty_ldisc_open(tty, tty->ldisc);
}
/* If the re-open fails or we reset then go to N_TTY. The
N_TTY open cannot fail */
if (reset || err) {
tty_ldisc_reinit(tty, N_TTY);
WARN_ON(tty_ldisc_open(tty, tty->ldisc));
tty_ldisc_enable(tty);
}
mutex_unlock(&tty->ldisc_mutex);
tty_reset_termios(tty);
tty_ldisc_enable(tty);
}
mutex_unlock(&tty->ldisc_mutex);
if (reset)
tty_reset_termios(tty);
}

/**
Expand Down

0 comments on commit 81c7ea3

Please sign in to comment.