diff options
Diffstat (limited to 'drivers/tty/n_tty.c')
-rw-r--r-- | drivers/tty/n_tty.c | 61 |
1 files changed, 47 insertions, 14 deletions
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 95d0a9c2dd13..0ad32888091c 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c | |||
@@ -81,6 +81,38 @@ static inline int tty_put_user(struct tty_struct *tty, unsigned char x, | |||
81 | return put_user(x, ptr); | 81 | return put_user(x, ptr); |
82 | } | 82 | } |
83 | 83 | ||
84 | /** | ||
85 | * n_tty_set__room - receive space | ||
86 | * @tty: terminal | ||
87 | * | ||
88 | * Called by the driver to find out how much data it is | ||
89 | * permitted to feed to the line discipline without any being lost | ||
90 | * and thus to manage flow control. Not serialized. Answers for the | ||
91 | * "instant". | ||
92 | */ | ||
93 | |||
94 | static void n_tty_set_room(struct tty_struct *tty) | ||
95 | { | ||
96 | /* tty->read_cnt is not read locked ? */ | ||
97 | int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; | ||
98 | int old_left; | ||
99 | |||
100 | /* | ||
101 | * If we are doing input canonicalization, and there are no | ||
102 | * pending newlines, let characters through without limit, so | ||
103 | * that erase characters will be handled. Other excess | ||
104 | * characters will be beeped. | ||
105 | */ | ||
106 | if (left <= 0) | ||
107 | left = tty->icanon && !tty->canon_data; | ||
108 | old_left = tty->receive_room; | ||
109 | tty->receive_room = left; | ||
110 | |||
111 | /* Did this open up the receive buffer? We may need to flip */ | ||
112 | if (left && !old_left) | ||
113 | schedule_work(&tty->buf.work); | ||
114 | } | ||
115 | |||
84 | static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) | 116 | static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) |
85 | { | 117 | { |
86 | if (tty->read_cnt < N_TTY_BUF_SIZE) { | 118 | if (tty->read_cnt < N_TTY_BUF_SIZE) { |
@@ -152,6 +184,7 @@ static void reset_buffer_flags(struct tty_struct *tty) | |||
152 | 184 | ||
153 | tty->canon_head = tty->canon_data = tty->erasing = 0; | 185 | tty->canon_head = tty->canon_data = tty->erasing = 0; |
154 | memset(&tty->read_flags, 0, sizeof tty->read_flags); | 186 | memset(&tty->read_flags, 0, sizeof tty->read_flags); |
187 | n_tty_set_room(tty); | ||
155 | check_unthrottle(tty); | 188 | check_unthrottle(tty); |
156 | } | 189 | } |
157 | 190 | ||
@@ -1327,19 +1360,17 @@ static void n_tty_write_wakeup(struct tty_struct *tty) | |||
1327 | * calls one at a time and in order (or using flush_to_ldisc) | 1360 | * calls one at a time and in order (or using flush_to_ldisc) |
1328 | */ | 1361 | */ |
1329 | 1362 | ||
1330 | static unsigned int n_tty_receive_buf(struct tty_struct *tty, | 1363 | static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, |
1331 | const unsigned char *cp, char *fp, int count) | 1364 | char *fp, int count) |
1332 | { | 1365 | { |
1333 | const unsigned char *p; | 1366 | const unsigned char *p; |
1334 | char *f, flags = TTY_NORMAL; | 1367 | char *f, flags = TTY_NORMAL; |
1335 | int i; | 1368 | int i; |
1336 | char buf[64]; | 1369 | char buf[64]; |
1337 | unsigned long cpuflags; | 1370 | unsigned long cpuflags; |
1338 | int left; | ||
1339 | int ret = 0; | ||
1340 | 1371 | ||
1341 | if (!tty->read_buf) | 1372 | if (!tty->read_buf) |
1342 | return 0; | 1373 | return; |
1343 | 1374 | ||
1344 | if (tty->real_raw) { | 1375 | if (tty->real_raw) { |
1345 | spin_lock_irqsave(&tty->read_lock, cpuflags); | 1376 | spin_lock_irqsave(&tty->read_lock, cpuflags); |
@@ -1349,7 +1380,6 @@ static unsigned int n_tty_receive_buf(struct tty_struct *tty, | |||
1349 | memcpy(tty->read_buf + tty->read_head, cp, i); | 1380 | memcpy(tty->read_buf + tty->read_head, cp, i); |
1350 | tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1); | 1381 | tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1); |
1351 | tty->read_cnt += i; | 1382 | tty->read_cnt += i; |
1352 | ret += i; | ||
1353 | cp += i; | 1383 | cp += i; |
1354 | count -= i; | 1384 | count -= i; |
1355 | 1385 | ||
@@ -1359,10 +1389,8 @@ static unsigned int n_tty_receive_buf(struct tty_struct *tty, | |||
1359 | memcpy(tty->read_buf + tty->read_head, cp, i); | 1389 | memcpy(tty->read_buf + tty->read_head, cp, i); |
1360 | tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1); | 1390 | tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1); |
1361 | tty->read_cnt += i; | 1391 | tty->read_cnt += i; |
1362 | ret += i; | ||
1363 | spin_unlock_irqrestore(&tty->read_lock, cpuflags); | 1392 | spin_unlock_irqrestore(&tty->read_lock, cpuflags); |
1364 | } else { | 1393 | } else { |
1365 | ret = count; | ||
1366 | for (i = count, p = cp, f = fp; i; i--, p++) { | 1394 | for (i = count, p = cp, f = fp; i; i--, p++) { |
1367 | if (f) | 1395 | if (f) |
1368 | flags = *f++; | 1396 | flags = *f++; |
@@ -1390,6 +1418,8 @@ static unsigned int n_tty_receive_buf(struct tty_struct *tty, | |||
1390 | tty->ops->flush_chars(tty); | 1418 | tty->ops->flush_chars(tty); |
1391 | } | 1419 | } |
1392 | 1420 | ||
1421 | n_tty_set_room(tty); | ||
1422 | |||
1393 | if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) || | 1423 | if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) || |
1394 | L_EXTPROC(tty)) { | 1424 | L_EXTPROC(tty)) { |
1395 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); | 1425 | kill_fasync(&tty->fasync, SIGIO, POLL_IN); |
@@ -1402,12 +1432,8 @@ static unsigned int n_tty_receive_buf(struct tty_struct *tty, | |||
1402 | * mode. We don't want to throttle the driver if we're in | 1432 | * mode. We don't want to throttle the driver if we're in |
1403 | * canonical mode and don't have a newline yet! | 1433 | * canonical mode and don't have a newline yet! |
1404 | */ | 1434 | */ |
1405 | left = N_TTY_BUF_SIZE - tty->read_cnt - 1; | 1435 | if (tty->receive_room < TTY_THRESHOLD_THROTTLE) |
1406 | |||
1407 | if (left < TTY_THRESHOLD_THROTTLE) | ||
1408 | tty_throttle(tty); | 1436 | tty_throttle(tty); |
1409 | |||
1410 | return ret; | ||
1411 | } | 1437 | } |
1412 | 1438 | ||
1413 | int is_ignored(int sig) | 1439 | int is_ignored(int sig) |
@@ -1451,6 +1477,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
1451 | if (test_bit(TTY_HW_COOK_IN, &tty->flags)) { | 1477 | if (test_bit(TTY_HW_COOK_IN, &tty->flags)) { |
1452 | tty->raw = 1; | 1478 | tty->raw = 1; |
1453 | tty->real_raw = 1; | 1479 | tty->real_raw = 1; |
1480 | n_tty_set_room(tty); | ||
1454 | return; | 1481 | return; |
1455 | } | 1482 | } |
1456 | if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) || | 1483 | if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) || |
@@ -1503,6 +1530,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
1503 | else | 1530 | else |
1504 | tty->real_raw = 0; | 1531 | tty->real_raw = 0; |
1505 | } | 1532 | } |
1533 | n_tty_set_room(tty); | ||
1506 | /* The termios change make the tty ready for I/O */ | 1534 | /* The termios change make the tty ready for I/O */ |
1507 | wake_up_interruptible(&tty->write_wait); | 1535 | wake_up_interruptible(&tty->write_wait); |
1508 | wake_up_interruptible(&tty->read_wait); | 1536 | wake_up_interruptible(&tty->read_wait); |
@@ -1784,6 +1812,8 @@ do_it_again: | |||
1784 | retval = -ERESTARTSYS; | 1812 | retval = -ERESTARTSYS; |
1785 | break; | 1813 | break; |
1786 | } | 1814 | } |
1815 | /* FIXME: does n_tty_set_room need locking ? */ | ||
1816 | n_tty_set_room(tty); | ||
1787 | timeout = schedule_timeout(timeout); | 1817 | timeout = schedule_timeout(timeout); |
1788 | continue; | 1818 | continue; |
1789 | } | 1819 | } |
@@ -1855,8 +1885,10 @@ do_it_again: | |||
1855 | * longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode, | 1885 | * longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode, |
1856 | * we won't get any more characters. | 1886 | * we won't get any more characters. |
1857 | */ | 1887 | */ |
1858 | if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) | 1888 | if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) { |
1889 | n_tty_set_room(tty); | ||
1859 | check_unthrottle(tty); | 1890 | check_unthrottle(tty); |
1891 | } | ||
1860 | 1892 | ||
1861 | if (b - buf >= minimum) | 1893 | if (b - buf >= minimum) |
1862 | break; | 1894 | break; |
@@ -1878,6 +1910,7 @@ do_it_again: | |||
1878 | } else if (test_and_clear_bit(TTY_PUSH, &tty->flags)) | 1910 | } else if (test_and_clear_bit(TTY_PUSH, &tty->flags)) |
1879 | goto do_it_again; | 1911 | goto do_it_again; |
1880 | 1912 | ||
1913 | n_tty_set_room(tty); | ||
1881 | return retval; | 1914 | return retval; |
1882 | } | 1915 | } |
1883 | 1916 | ||