diff options
Diffstat (limited to 'drivers/char/n_tty.c')
-rw-r--r-- | drivers/char/n_tty.c | 66 |
1 files changed, 37 insertions, 29 deletions
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index c556f4d3ccd7..ccad7ae94541 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c | |||
@@ -78,7 +78,32 @@ static inline void free_buf(unsigned char *buf) | |||
78 | free_page((unsigned long) buf); | 78 | free_page((unsigned long) buf); |
79 | } | 79 | } |
80 | 80 | ||
81 | static inline void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) | 81 | /** |
82 | * n_tty_set__room - receive space | ||
83 | * @tty: terminal | ||
84 | * | ||
85 | * Called by the driver to find out how much data it is | ||
86 | * permitted to feed to the line discipline without any being lost | ||
87 | * and thus to manage flow control. Not serialized. Answers for the | ||
88 | * "instant". | ||
89 | */ | ||
90 | |||
91 | static void n_tty_set_room(struct tty_struct *tty) | ||
92 | { | ||
93 | int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; | ||
94 | |||
95 | /* | ||
96 | * If we are doing input canonicalization, and there are no | ||
97 | * pending newlines, let characters through without limit, so | ||
98 | * that erase characters will be handled. Other excess | ||
99 | * characters will be beeped. | ||
100 | */ | ||
101 | if (left <= 0) | ||
102 | left = tty->icanon && !tty->canon_data; | ||
103 | tty->receive_room = left; | ||
104 | } | ||
105 | |||
106 | static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) | ||
82 | { | 107 | { |
83 | if (tty->read_cnt < N_TTY_BUF_SIZE) { | 108 | if (tty->read_cnt < N_TTY_BUF_SIZE) { |
84 | tty->read_buf[tty->read_head] = c; | 109 | tty->read_buf[tty->read_head] = c; |
@@ -87,7 +112,7 @@ static inline void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) | |||
87 | } | 112 | } |
88 | } | 113 | } |
89 | 114 | ||
90 | static inline void put_tty_queue(unsigned char c, struct tty_struct *tty) | 115 | static void put_tty_queue(unsigned char c, struct tty_struct *tty) |
91 | { | 116 | { |
92 | unsigned long flags; | 117 | unsigned long flags; |
93 | /* | 118 | /* |
@@ -136,6 +161,7 @@ static void reset_buffer_flags(struct tty_struct *tty) | |||
136 | spin_unlock_irqrestore(&tty->read_lock, flags); | 161 | spin_unlock_irqrestore(&tty->read_lock, flags); |
137 | tty->canon_head = tty->canon_data = tty->erasing = 0; | 162 | tty->canon_head = tty->canon_data = tty->erasing = 0; |
138 | memset(&tty->read_flags, 0, sizeof tty->read_flags); | 163 | memset(&tty->read_flags, 0, sizeof tty->read_flags); |
164 | n_tty_set_room(tty); | ||
139 | check_unthrottle(tty); | 165 | check_unthrottle(tty); |
140 | } | 166 | } |
141 | 167 | ||
@@ -838,30 +864,6 @@ send_signal: | |||
838 | put_tty_queue(c, tty); | 864 | put_tty_queue(c, tty); |
839 | } | 865 | } |
840 | 866 | ||
841 | /** | ||
842 | * n_tty_receive_room - receive space | ||
843 | * @tty: terminal | ||
844 | * | ||
845 | * Called by the driver to find out how much data it is | ||
846 | * permitted to feed to the line discipline without any being lost | ||
847 | * and thus to manage flow control. Not serialized. Answers for the | ||
848 | * "instant". | ||
849 | */ | ||
850 | |||
851 | static int n_tty_receive_room(struct tty_struct *tty) | ||
852 | { | ||
853 | int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; | ||
854 | |||
855 | /* | ||
856 | * If we are doing input canonicalization, and there are no | ||
857 | * pending newlines, let characters through without limit, so | ||
858 | * that erase characters will be handled. Other excess | ||
859 | * characters will be beeped. | ||
860 | */ | ||
861 | if (left <= 0) | ||
862 | left = tty->icanon && !tty->canon_data; | ||
863 | return left; | ||
864 | } | ||
865 | 867 | ||
866 | /** | 868 | /** |
867 | * n_tty_write_wakeup - asynchronous I/O notifier | 869 | * n_tty_write_wakeup - asynchronous I/O notifier |
@@ -953,6 +955,8 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
953 | tty->driver->flush_chars(tty); | 955 | tty->driver->flush_chars(tty); |
954 | } | 956 | } |
955 | 957 | ||
958 | n_tty_set_room(tty); | ||
959 | |||
956 | if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) { | 960 | if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) { |
957 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); | 961 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); |
958 | if (waitqueue_active(&tty->read_wait)) | 962 | if (waitqueue_active(&tty->read_wait)) |
@@ -964,7 +968,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
964 | * mode. We don't want to throttle the driver if we're in | 968 | * mode. We don't want to throttle the driver if we're in |
965 | * canonical mode and don't have a newline yet! | 969 | * canonical mode and don't have a newline yet! |
966 | */ | 970 | */ |
967 | if (n_tty_receive_room(tty) < TTY_THRESHOLD_THROTTLE) { | 971 | if (tty->receive_room < TTY_THRESHOLD_THROTTLE) { |
968 | /* check TTY_THROTTLED first so it indicates our state */ | 972 | /* check TTY_THROTTLED first so it indicates our state */ |
969 | if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) && | 973 | if (!test_and_set_bit(TTY_THROTTLED, &tty->flags) && |
970 | tty->driver->throttle) | 974 | tty->driver->throttle) |
@@ -999,6 +1003,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct termios * old) | |||
999 | if (test_bit(TTY_HW_COOK_IN, &tty->flags)) { | 1003 | if (test_bit(TTY_HW_COOK_IN, &tty->flags)) { |
1000 | tty->raw = 1; | 1004 | tty->raw = 1; |
1001 | tty->real_raw = 1; | 1005 | tty->real_raw = 1; |
1006 | n_tty_set_room(tty); | ||
1002 | return; | 1007 | return; |
1003 | } | 1008 | } |
1004 | if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) || | 1009 | if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) || |
@@ -1051,6 +1056,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct termios * old) | |||
1051 | else | 1056 | else |
1052 | tty->real_raw = 0; | 1057 | tty->real_raw = 0; |
1053 | } | 1058 | } |
1059 | n_tty_set_room(tty); | ||
1054 | } | 1060 | } |
1055 | 1061 | ||
1056 | /** | 1062 | /** |
@@ -1130,7 +1136,7 @@ static inline int input_available_p(struct tty_struct *tty, int amt) | |||
1130 | * | 1136 | * |
1131 | */ | 1137 | */ |
1132 | 1138 | ||
1133 | static inline int copy_from_read_buf(struct tty_struct *tty, | 1139 | static int copy_from_read_buf(struct tty_struct *tty, |
1134 | unsigned char __user **b, | 1140 | unsigned char __user **b, |
1135 | size_t *nr) | 1141 | size_t *nr) |
1136 | 1142 | ||
@@ -1308,6 +1314,7 @@ do_it_again: | |||
1308 | retval = -ERESTARTSYS; | 1314 | retval = -ERESTARTSYS; |
1309 | break; | 1315 | break; |
1310 | } | 1316 | } |
1317 | n_tty_set_room(tty); | ||
1311 | clear_bit(TTY_DONT_FLIP, &tty->flags); | 1318 | clear_bit(TTY_DONT_FLIP, &tty->flags); |
1312 | timeout = schedule_timeout(timeout); | 1319 | timeout = schedule_timeout(timeout); |
1313 | set_bit(TTY_DONT_FLIP, &tty->flags); | 1320 | set_bit(TTY_DONT_FLIP, &tty->flags); |
@@ -1401,6 +1408,8 @@ do_it_again: | |||
1401 | } else if (test_and_clear_bit(TTY_PUSH, &tty->flags)) | 1408 | } else if (test_and_clear_bit(TTY_PUSH, &tty->flags)) |
1402 | goto do_it_again; | 1409 | goto do_it_again; |
1403 | 1410 | ||
1411 | n_tty_set_room(tty); | ||
1412 | |||
1404 | return retval; | 1413 | return retval; |
1405 | } | 1414 | } |
1406 | 1415 | ||
@@ -1553,7 +1562,6 @@ struct tty_ldisc tty_ldisc_N_TTY = { | |||
1553 | normal_poll, /* poll */ | 1562 | normal_poll, /* poll */ |
1554 | NULL, /* hangup */ | 1563 | NULL, /* hangup */ |
1555 | n_tty_receive_buf, /* receive_buf */ | 1564 | n_tty_receive_buf, /* receive_buf */ |
1556 | n_tty_receive_room, /* receive_room */ | ||
1557 | n_tty_write_wakeup /* write_wakeup */ | 1565 | n_tty_write_wakeup /* write_wakeup */ |
1558 | }; | 1566 | }; |
1559 | 1567 | ||