diff options
-rw-r--r-- | drivers/tty/n_tty.c | 8 | ||||
-rw-r--r-- | drivers/tty/tty_ldisc.c | 7 | ||||
-rw-r--r-- | include/linux/tty.h | 1 |
3 files changed, 15 insertions, 1 deletions
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 68865d9af8a0..16793eccc6ae 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c | |||
@@ -153,6 +153,12 @@ static void n_tty_set_room(struct tty_struct *tty) | |||
153 | if (left && !old_left) { | 153 | if (left && !old_left) { |
154 | WARN_RATELIMIT(tty->port->itty == NULL, | 154 | WARN_RATELIMIT(tty->port->itty == NULL, |
155 | "scheduling with invalid itty\n"); | 155 | "scheduling with invalid itty\n"); |
156 | /* see if ldisc has been killed - if so, this means that | ||
157 | * even though the ldisc has been halted and ->buf.work | ||
158 | * cancelled, ->buf.work is about to be rescheduled | ||
159 | */ | ||
160 | WARN_RATELIMIT(test_bit(TTY_LDISC_HALTED, &tty->flags), | ||
161 | "scheduling buffer work for halted ldisc\n"); | ||
156 | schedule_work(&tty->port->buf.work); | 162 | schedule_work(&tty->port->buf.work); |
157 | } | 163 | } |
158 | } | 164 | } |
@@ -1624,6 +1630,8 @@ static int n_tty_open(struct tty_struct *tty) | |||
1624 | goto err_free_bufs; | 1630 | goto err_free_bufs; |
1625 | 1631 | ||
1626 | tty->disc_data = ldata; | 1632 | tty->disc_data = ldata; |
1633 | /* indicate buffer work may resume */ | ||
1634 | clear_bit(TTY_LDISC_HALTED, &tty->flags); | ||
1627 | reset_buffer_flags(tty); | 1635 | reset_buffer_flags(tty); |
1628 | tty_unthrottle(tty); | 1636 | tty_unthrottle(tty); |
1629 | ldata->column = 0; | 1637 | ldata->column = 0; |
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index d794087c327e..c641321b9404 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c | |||
@@ -375,6 +375,7 @@ static inline void tty_ldisc_put(struct tty_ldisc *ld) | |||
375 | 375 | ||
376 | void tty_ldisc_enable(struct tty_struct *tty) | 376 | void tty_ldisc_enable(struct tty_struct *tty) |
377 | { | 377 | { |
378 | clear_bit(TTY_LDISC_HALTED, &tty->flags); | ||
378 | set_bit(TTY_LDISC, &tty->flags); | 379 | set_bit(TTY_LDISC, &tty->flags); |
379 | clear_bit(TTY_LDISC_CHANGING, &tty->flags); | 380 | clear_bit(TTY_LDISC_CHANGING, &tty->flags); |
380 | wake_up(&tty_ldisc_wait); | 381 | wake_up(&tty_ldisc_wait); |
@@ -513,8 +514,11 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old) | |||
513 | 514 | ||
514 | static int tty_ldisc_halt(struct tty_struct *tty) | 515 | static int tty_ldisc_halt(struct tty_struct *tty) |
515 | { | 516 | { |
517 | int scheduled; | ||
516 | clear_bit(TTY_LDISC, &tty->flags); | 518 | clear_bit(TTY_LDISC, &tty->flags); |
517 | return cancel_work_sync(&tty->port->buf.work); | 519 | scheduled = cancel_work_sync(&tty->port->buf.work); |
520 | set_bit(TTY_LDISC_HALTED, &tty->flags); | ||
521 | return scheduled; | ||
518 | } | 522 | } |
519 | 523 | ||
520 | /** | 524 | /** |
@@ -820,6 +824,7 @@ void tty_ldisc_hangup(struct tty_struct *tty) | |||
820 | clear_bit(TTY_LDISC, &tty->flags); | 824 | clear_bit(TTY_LDISC, &tty->flags); |
821 | tty_unlock(tty); | 825 | tty_unlock(tty); |
822 | cancel_work_sync(&tty->port->buf.work); | 826 | cancel_work_sync(&tty->port->buf.work); |
827 | set_bit(TTY_LDISC_HALTED, &tty->flags); | ||
823 | mutex_unlock(&tty->ldisc_mutex); | 828 | mutex_unlock(&tty->ldisc_mutex); |
824 | retry: | 829 | retry: |
825 | tty_lock(tty); | 830 | tty_lock(tty); |
diff --git a/include/linux/tty.h b/include/linux/tty.h index d3548f871968..66ae020e8a98 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
@@ -315,6 +315,7 @@ struct tty_file_private { | |||
315 | #define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */ | 315 | #define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */ |
316 | #define TTY_HUPPED 18 /* Post driver->hangup() */ | 316 | #define TTY_HUPPED 18 /* Post driver->hangup() */ |
317 | #define TTY_HUPPING 21 /* ->hangup() in progress */ | 317 | #define TTY_HUPPING 21 /* ->hangup() in progress */ |
318 | #define TTY_LDISC_HALTED 22 /* Line discipline is halted */ | ||
318 | 319 | ||
319 | #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) | 320 | #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) |
320 | 321 | ||