aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/n_tty.c
diff options
context:
space:
mode:
authorPeter Hurley <peter@hurleysoftware.com>2013-07-24 08:29:54 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-07-24 12:28:52 -0400
commit19e2ad6a09f0c06dbca19c98e5f4584269d913dd (patch)
tree4aabbdd03f991b642d0c08afe9d7b3284b6fb1d6 /drivers/tty/n_tty.c
parent7de971b05055d31589955feb0f50963b78fe697a (diff)
n_tty: Remove overflow tests from receive_buf() path
Always pre-figure the space available in the read_buf and limit the inbound receive request to that amount. For compatibility reasons with the non-flow-controlled interface, n_tty_receive_buf() will continue filling read_buf until all data has been received or receive_room() returns 0. Signed-off-by: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/n_tty.c')
-rw-r--r--drivers/tty/n_tty.c85
1 files changed, 37 insertions, 48 deletions
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index adc06af3a075..f66d95f949d1 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -316,12 +316,9 @@ static inline void n_tty_check_unthrottle(struct tty_struct *tty)
316 * not active. 316 * not active.
317 */ 317 */
318 318
319static void put_tty_queue(unsigned char c, struct n_tty_data *ldata) 319static inline void put_tty_queue(unsigned char c, struct n_tty_data *ldata)
320{ 320{
321 if (read_cnt(ldata) < N_TTY_BUF_SIZE) { 321 *read_buf_addr(ldata, ldata->read_head++) = c;
322 *read_buf_addr(ldata, ldata->read_head) = c;
323 ldata->read_head++;
324 }
325} 322}
326 323
327/** 324/**
@@ -1333,11 +1330,6 @@ n_tty_receive_char_special(struct tty_struct *tty, unsigned char c)
1333 return; 1330 return;
1334 } 1331 }
1335 if (c == '\n') { 1332 if (c == '\n') {
1336 if (read_cnt(ldata) >= N_TTY_BUF_SIZE) {
1337 if (L_ECHO(tty))
1338 process_output('\a', tty);
1339 return;
1340 }
1341 if (L_ECHO(tty) || L_ECHONL(tty)) { 1333 if (L_ECHO(tty) || L_ECHONL(tty)) {
1342 echo_char_raw('\n', ldata); 1334 echo_char_raw('\n', ldata);
1343 commit_echoes(tty); 1335 commit_echoes(tty);
@@ -1345,8 +1337,6 @@ n_tty_receive_char_special(struct tty_struct *tty, unsigned char c)
1345 goto handle_newline; 1337 goto handle_newline;
1346 } 1338 }
1347 if (c == EOF_CHAR(tty)) { 1339 if (c == EOF_CHAR(tty)) {
1348 if (read_cnt(ldata) >= N_TTY_BUF_SIZE)
1349 return;
1350 c = __DISABLED_CHAR; 1340 c = __DISABLED_CHAR;
1351 goto handle_newline; 1341 goto handle_newline;
1352 } 1342 }
@@ -1354,11 +1344,6 @@ n_tty_receive_char_special(struct tty_struct *tty, unsigned char c)
1354 (c == EOL2_CHAR(tty) && L_IEXTEN(tty))) { 1344 (c == EOL2_CHAR(tty) && L_IEXTEN(tty))) {
1355 parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) 1345 parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty))
1356 ? 1 : 0; 1346 ? 1 : 0;
1357 if (read_cnt(ldata) >= (N_TTY_BUF_SIZE - parmrk)) {
1358 if (L_ECHO(tty))
1359 process_output('\a', tty);
1360 return;
1361 }
1362 /* 1347 /*
1363 * XXX are EOL_CHAR and EOL2_CHAR echoed?!? 1348 * XXX are EOL_CHAR and EOL2_CHAR echoed?!?
1364 */ 1349 */
@@ -1388,12 +1373,6 @@ handle_newline:
1388 } 1373 }
1389 1374
1390 parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0; 1375 parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0;
1391 if (read_cnt(ldata) >= (N_TTY_BUF_SIZE - parmrk - 1)) {
1392 /* beep if no space */
1393 if (L_ECHO(tty))
1394 process_output('\a', tty);
1395 return;
1396 }
1397 if (L_ECHO(tty)) { 1376 if (L_ECHO(tty)) {
1398 finish_erasing(ldata); 1377 finish_erasing(ldata);
1399 if (c == '\n') 1378 if (c == '\n')
@@ -1432,14 +1411,6 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
1432 start_tty(tty); 1411 start_tty(tty);
1433 process_echoes(tty); 1412 process_echoes(tty);
1434 } 1413 }
1435
1436 parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0;
1437 if (read_cnt(ldata) >= (N_TTY_BUF_SIZE - parmrk - 1)) {
1438 /* beep if no space */
1439 if (L_ECHO(tty))
1440 process_output('\a', tty);
1441 return;
1442 }
1443 if (L_ECHO(tty)) { 1414 if (L_ECHO(tty)) {
1444 finish_erasing(ldata); 1415 finish_erasing(ldata);
1445 /* Record the column of first canon char. */ 1416 /* Record the column of first canon char. */
@@ -1448,6 +1419,7 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
1448 echo_char(c, tty); 1419 echo_char(c, tty);
1449 commit_echoes(tty); 1420 commit_echoes(tty);
1450 } 1421 }
1422 parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0;
1451 if (parmrk) 1423 if (parmrk)
1452 put_tty_queue(c, ldata); 1424 put_tty_queue(c, ldata);
1453 put_tty_queue(c, ldata); 1425 put_tty_queue(c, ldata);
@@ -1476,13 +1448,6 @@ n_tty_receive_char_fast(struct tty_struct *tty, unsigned char c)
1476 start_tty(tty); 1448 start_tty(tty);
1477 process_echoes(tty); 1449 process_echoes(tty);
1478 } 1450 }
1479
1480 if (read_cnt(ldata) >= (N_TTY_BUF_SIZE - 1)) {
1481 /* beep if no space */
1482 if (L_ECHO(tty))
1483 process_output('\a', tty);
1484 return;
1485 }
1486 if (L_ECHO(tty)) { 1451 if (L_ECHO(tty)) {
1487 finish_erasing(ldata); 1452 finish_erasing(ldata);
1488 /* Record the column of first canon char. */ 1453 /* Record the column of first canon char. */
@@ -1691,8 +1656,23 @@ static void __receive_buf(struct tty_struct *tty, const unsigned char *cp,
1691static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, 1656static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
1692 char *fp, int count) 1657 char *fp, int count)
1693{ 1658{
1659 int room, n;
1660
1694 down_read(&tty->termios_rwsem); 1661 down_read(&tty->termios_rwsem);
1695 __receive_buf(tty, cp, fp, count); 1662
1663 while (1) {
1664 room = receive_room(tty);
1665 n = min(count, room);
1666 if (!n)
1667 break;
1668 __receive_buf(tty, cp, fp, n);
1669 cp += n;
1670 if (fp)
1671 fp += n;
1672 count -= n;
1673 }
1674
1675 tty->receive_room = room;
1696 n_tty_check_throttle(tty); 1676 n_tty_check_throttle(tty);
1697 up_read(&tty->termios_rwsem); 1677 up_read(&tty->termios_rwsem);
1698} 1678}
@@ -1701,22 +1681,31 @@ static int n_tty_receive_buf2(struct tty_struct *tty, const unsigned char *cp,
1701 char *fp, int count) 1681 char *fp, int count)
1702{ 1682{
1703 struct n_tty_data *ldata = tty->disc_data; 1683 struct n_tty_data *ldata = tty->disc_data;
1704 int room; 1684 int room, n, rcvd = 0;
1705 1685
1706 down_read(&tty->termios_rwsem); 1686 down_read(&tty->termios_rwsem);
1707 1687
1708 tty->receive_room = room = receive_room(tty); 1688 while (1) {
1709 if (!room) 1689 room = receive_room(tty);
1710 ldata->no_room = 1; 1690 n = min(count, room);
1711 count = min(count, room); 1691 if (!n) {
1712 if (count) { 1692 if (!room)
1713 __receive_buf(tty, cp, fp, count); 1693 ldata->no_room = 1;
1714 n_tty_check_throttle(tty); 1694 break;
1695 }
1696 __receive_buf(tty, cp, fp, n);
1697 cp += n;
1698 if (fp)
1699 fp += n;
1700 count -= n;
1701 rcvd += n;
1715 } 1702 }
1716 1703
1704 tty->receive_room = room;
1705 n_tty_check_throttle(tty);
1717 up_read(&tty->termios_rwsem); 1706 up_read(&tty->termios_rwsem);
1718 1707
1719 return count; 1708 return rcvd;
1720} 1709}
1721 1710
1722int is_ignored(int sig) 1711int is_ignored(int sig)