diff options
Diffstat (limited to 'drivers/tty/n_tty.c')
-rw-r--r-- | drivers/tty/n_tty.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 0f74945af624..34aacaaae14a 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c | |||
@@ -93,6 +93,7 @@ struct n_tty_data { | |||
93 | size_t canon_head; | 93 | size_t canon_head; |
94 | size_t echo_head; | 94 | size_t echo_head; |
95 | size_t echo_commit; | 95 | size_t echo_commit; |
96 | size_t echo_mark; | ||
96 | DECLARE_BITMAP(char_map, 256); | 97 | DECLARE_BITMAP(char_map, 256); |
97 | 98 | ||
98 | /* private to n_tty_receive_overrun (single-threaded) */ | 99 | /* private to n_tty_receive_overrun (single-threaded) */ |
@@ -336,6 +337,7 @@ static void reset_buffer_flags(struct n_tty_data *ldata) | |||
336 | { | 337 | { |
337 | ldata->read_head = ldata->canon_head = ldata->read_tail = 0; | 338 | ldata->read_head = ldata->canon_head = ldata->read_tail = 0; |
338 | ldata->echo_head = ldata->echo_tail = ldata->echo_commit = 0; | 339 | ldata->echo_head = ldata->echo_tail = ldata->echo_commit = 0; |
340 | ldata->echo_mark = 0; | ||
339 | ldata->line_start = 0; | 341 | ldata->line_start = 0; |
340 | 342 | ||
341 | ldata->erasing = 0; | 343 | ldata->erasing = 0; |
@@ -787,6 +789,7 @@ static void commit_echoes(struct tty_struct *tty) | |||
787 | size_t head; | 789 | size_t head; |
788 | 790 | ||
789 | head = ldata->echo_head; | 791 | head = ldata->echo_head; |
792 | ldata->echo_mark = head; | ||
790 | old = ldata->echo_commit - ldata->echo_tail; | 793 | old = ldata->echo_commit - ldata->echo_tail; |
791 | 794 | ||
792 | /* Process committed echoes if the accumulated # of bytes | 795 | /* Process committed echoes if the accumulated # of bytes |
@@ -810,10 +813,12 @@ static void process_echoes(struct tty_struct *tty) | |||
810 | struct n_tty_data *ldata = tty->disc_data; | 813 | struct n_tty_data *ldata = tty->disc_data; |
811 | size_t echoed; | 814 | size_t echoed; |
812 | 815 | ||
813 | if (!L_ECHO(tty) || ldata->echo_commit == ldata->echo_tail) | 816 | if ((!L_ECHO(tty) && !L_ECHONL(tty)) || |
817 | ldata->echo_mark == ldata->echo_tail) | ||
814 | return; | 818 | return; |
815 | 819 | ||
816 | mutex_lock(&ldata->output_lock); | 820 | mutex_lock(&ldata->output_lock); |
821 | ldata->echo_commit = ldata->echo_mark; | ||
817 | echoed = __process_echoes(tty); | 822 | echoed = __process_echoes(tty); |
818 | mutex_unlock(&ldata->output_lock); | 823 | mutex_unlock(&ldata->output_lock); |
819 | 824 | ||
@@ -821,11 +826,13 @@ static void process_echoes(struct tty_struct *tty) | |||
821 | tty->ops->flush_chars(tty); | 826 | tty->ops->flush_chars(tty); |
822 | } | 827 | } |
823 | 828 | ||
829 | /* NB: echo_mark and echo_head should be equivalent here */ | ||
824 | static void flush_echoes(struct tty_struct *tty) | 830 | static void flush_echoes(struct tty_struct *tty) |
825 | { | 831 | { |
826 | struct n_tty_data *ldata = tty->disc_data; | 832 | struct n_tty_data *ldata = tty->disc_data; |
827 | 833 | ||
828 | if (!L_ECHO(tty) || ldata->echo_commit == ldata->echo_head) | 834 | if ((!L_ECHO(tty) && !L_ECHONL(tty)) || |
835 | ldata->echo_commit == ldata->echo_head) | ||
829 | return; | 836 | return; |
830 | 837 | ||
831 | mutex_lock(&ldata->output_lock); | 838 | mutex_lock(&ldata->output_lock); |