aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorFelipe Balbi <balbi@ti.com>2011-03-21 06:25:08 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-04-22 20:31:53 -0400
commitb1c43f82c5aa265442f82dba31ce985ebb7aa71c (patch)
tree8b344d8d5355b30e8deff901180edc708a653227 /drivers/tty
parente9a470f445271eb157ee860a93b062324402fc3a (diff)
tty: make receive_buf() return the amout of bytes received
it makes it simpler to keep track of the amount of bytes received and simplifies how flush_to_ldisc counts the remaining bytes. It also fixes a bug of lost bytes on n_tty when flushing too many bytes via the USB serial gadget driver. Tested-by: Stefan Bigler <stefan.bigler@keymile.com> Tested-by: Toby Gray <toby.gray@realvnc.com> Signed-off-by: Felipe Balbi <balbi@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/n_gsm.c6
-rw-r--r--drivers/tty/n_hdlc.c18
-rw-r--r--drivers/tty/n_r3964.c10
-rw-r--r--drivers/tty/n_tty.c61
-rw-r--r--drivers/tty/tty_buffer.c15
-rw-r--r--drivers/tty/vt/selection.c3
6 files changed, 44 insertions, 69 deletions
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 47f8cdb207f..6abc7359884 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -2138,8 +2138,8 @@ static void gsmld_detach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
2138 gsm->tty = NULL; 2138 gsm->tty = NULL;
2139} 2139}
2140 2140
2141static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp, 2141static unsigned int gsmld_receive_buf(struct tty_struct *tty,
2142 char *fp, int count) 2142 const unsigned char *cp, char *fp, int count)
2143{ 2143{
2144 struct gsm_mux *gsm = tty->disc_data; 2144 struct gsm_mux *gsm = tty->disc_data;
2145 const unsigned char *dp; 2145 const unsigned char *dp;
@@ -2173,6 +2173,8 @@ static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp,
2173 } 2173 }
2174 /* FASYNC if needed ? */ 2174 /* FASYNC if needed ? */
2175 /* If clogged call tty_throttle(tty); */ 2175 /* If clogged call tty_throttle(tty); */
2176
2177 return count;
2176} 2178}
2177 2179
2178/** 2180/**
diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c
index cea56033b34..cac666314ae 100644
--- a/drivers/tty/n_hdlc.c
+++ b/drivers/tty/n_hdlc.c
@@ -188,8 +188,8 @@ static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp,
188 poll_table *wait); 188 poll_table *wait);
189static int n_hdlc_tty_open(struct tty_struct *tty); 189static int n_hdlc_tty_open(struct tty_struct *tty);
190static void n_hdlc_tty_close(struct tty_struct *tty); 190static void n_hdlc_tty_close(struct tty_struct *tty);
191static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *cp, 191static unsigned int n_hdlc_tty_receive(struct tty_struct *tty,
192 char *fp, int count); 192 const __u8 *cp, char *fp, int count);
193static void n_hdlc_tty_wakeup(struct tty_struct *tty); 193static void n_hdlc_tty_wakeup(struct tty_struct *tty);
194 194
195#define bset(p,b) ((p)[(b) >> 5] |= (1 << ((b) & 0x1f))) 195#define bset(p,b) ((p)[(b) >> 5] |= (1 << ((b) & 0x1f)))
@@ -509,8 +509,8 @@ static void n_hdlc_tty_wakeup(struct tty_struct *tty)
509 * Called by tty low level driver when receive data is available. Data is 509 * Called by tty low level driver when receive data is available. Data is
510 * interpreted as one HDLC frame. 510 * interpreted as one HDLC frame.
511 */ 511 */
512static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data, 512static unsigned int n_hdlc_tty_receive(struct tty_struct *tty,
513 char *flags, int count) 513 const __u8 *data, char *flags, int count)
514{ 514{
515 register struct n_hdlc *n_hdlc = tty2n_hdlc (tty); 515 register struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
516 register struct n_hdlc_buf *buf; 516 register struct n_hdlc_buf *buf;
@@ -521,20 +521,20 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data,
521 521
522 /* This can happen if stuff comes in on the backup tty */ 522 /* This can happen if stuff comes in on the backup tty */
523 if (!n_hdlc || tty != n_hdlc->tty) 523 if (!n_hdlc || tty != n_hdlc->tty)
524 return; 524 return -ENODEV;
525 525
526 /* verify line is using HDLC discipline */ 526 /* verify line is using HDLC discipline */
527 if (n_hdlc->magic != HDLC_MAGIC) { 527 if (n_hdlc->magic != HDLC_MAGIC) {
528 printk("%s(%d) line not using HDLC discipline\n", 528 printk("%s(%d) line not using HDLC discipline\n",
529 __FILE__,__LINE__); 529 __FILE__,__LINE__);
530 return; 530 return -EINVAL;
531 } 531 }
532 532
533 if ( count>maxframe ) { 533 if ( count>maxframe ) {
534 if (debuglevel >= DEBUG_LEVEL_INFO) 534 if (debuglevel >= DEBUG_LEVEL_INFO)
535 printk("%s(%d) rx count>maxframesize, data discarded\n", 535 printk("%s(%d) rx count>maxframesize, data discarded\n",
536 __FILE__,__LINE__); 536 __FILE__,__LINE__);
537 return; 537 return -EINVAL;
538 } 538 }
539 539
540 /* get a free HDLC buffer */ 540 /* get a free HDLC buffer */
@@ -550,7 +550,7 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data,
550 if (debuglevel >= DEBUG_LEVEL_INFO) 550 if (debuglevel >= DEBUG_LEVEL_INFO)
551 printk("%s(%d) no more rx buffers, data discarded\n", 551 printk("%s(%d) no more rx buffers, data discarded\n",
552 __FILE__,__LINE__); 552 __FILE__,__LINE__);
553 return; 553 return -EINVAL;
554 } 554 }
555 555
556 /* copy received data to HDLC buffer */ 556 /* copy received data to HDLC buffer */
@@ -565,6 +565,8 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data,
565 if (n_hdlc->tty->fasync != NULL) 565 if (n_hdlc->tty->fasync != NULL)
566 kill_fasync (&n_hdlc->tty->fasync, SIGIO, POLL_IN); 566 kill_fasync (&n_hdlc->tty->fasync, SIGIO, POLL_IN);
567 567
568 return count;
569
568} /* end of n_hdlc_tty_receive() */ 570} /* end of n_hdlc_tty_receive() */
569 571
570/** 572/**
diff --git a/drivers/tty/n_r3964.c b/drivers/tty/n_r3964.c
index 5c6c31459a2..a4bc39c21a4 100644
--- a/drivers/tty/n_r3964.c
+++ b/drivers/tty/n_r3964.c
@@ -139,8 +139,8 @@ static int r3964_ioctl(struct tty_struct *tty, struct file *file,
139static void r3964_set_termios(struct tty_struct *tty, struct ktermios *old); 139static void r3964_set_termios(struct tty_struct *tty, struct ktermios *old);
140static unsigned int r3964_poll(struct tty_struct *tty, struct file *file, 140static unsigned int r3964_poll(struct tty_struct *tty, struct file *file,
141 struct poll_table_struct *wait); 141 struct poll_table_struct *wait);
142static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, 142static unsigned int r3964_receive_buf(struct tty_struct *tty,
143 char *fp, int count); 143 const unsigned char *cp, char *fp, int count);
144 144
145static struct tty_ldisc_ops tty_ldisc_N_R3964 = { 145static struct tty_ldisc_ops tty_ldisc_N_R3964 = {
146 .owner = THIS_MODULE, 146 .owner = THIS_MODULE,
@@ -1239,8 +1239,8 @@ static unsigned int r3964_poll(struct tty_struct *tty, struct file *file,
1239 return result; 1239 return result;
1240} 1240}
1241 1241
1242static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, 1242static unsigned int r3964_receive_buf(struct tty_struct *tty,
1243 char *fp, int count) 1243 const unsigned char *cp, char *fp, int count)
1244{ 1244{
1245 struct r3964_info *pInfo = tty->disc_data; 1245 struct r3964_info *pInfo = tty->disc_data;
1246 const unsigned char *p; 1246 const unsigned char *p;
@@ -1257,6 +1257,8 @@ static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
1257 } 1257 }
1258 1258
1259 } 1259 }
1260
1261 return count;
1260} 1262}
1261 1263
1262MODULE_LICENSE("GPL"); 1264MODULE_LICENSE("GPL");
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index 0ad32888091..95d0a9c2dd1 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -81,38 +81,6 @@ 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
94static 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
116static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) 84static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty)
117{ 85{
118 if (tty->read_cnt < N_TTY_BUF_SIZE) { 86 if (tty->read_cnt < N_TTY_BUF_SIZE) {
@@ -184,7 +152,6 @@ static void reset_buffer_flags(struct tty_struct *tty)
184 152
185 tty->canon_head = tty->canon_data = tty->erasing = 0; 153 tty->canon_head = tty->canon_data = tty->erasing = 0;
186 memset(&tty->read_flags, 0, sizeof tty->read_flags); 154 memset(&tty->read_flags, 0, sizeof tty->read_flags);
187 n_tty_set_room(tty);
188 check_unthrottle(tty); 155 check_unthrottle(tty);
189} 156}
190 157
@@ -1360,17 +1327,19 @@ static void n_tty_write_wakeup(struct tty_struct *tty)
1360 * calls one at a time and in order (or using flush_to_ldisc) 1327 * calls one at a time and in order (or using flush_to_ldisc)
1361 */ 1328 */
1362 1329
1363static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, 1330static unsigned int n_tty_receive_buf(struct tty_struct *tty,
1364 char *fp, int count) 1331 const unsigned char *cp, char *fp, int count)
1365{ 1332{
1366 const unsigned char *p; 1333 const unsigned char *p;
1367 char *f, flags = TTY_NORMAL; 1334 char *f, flags = TTY_NORMAL;
1368 int i; 1335 int i;
1369 char buf[64]; 1336 char buf[64];
1370 unsigned long cpuflags; 1337 unsigned long cpuflags;
1338 int left;
1339 int ret = 0;
1371 1340
1372 if (!tty->read_buf) 1341 if (!tty->read_buf)
1373 return; 1342 return 0;
1374 1343
1375 if (tty->real_raw) { 1344 if (tty->real_raw) {
1376 spin_lock_irqsave(&tty->read_lock, cpuflags); 1345 spin_lock_irqsave(&tty->read_lock, cpuflags);
@@ -1380,6 +1349,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
1380 memcpy(tty->read_buf + tty->read_head, cp, i); 1349 memcpy(tty->read_buf + tty->read_head, cp, i);
1381 tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1); 1350 tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
1382 tty->read_cnt += i; 1351 tty->read_cnt += i;
1352 ret += i;
1383 cp += i; 1353 cp += i;
1384 count -= i; 1354 count -= i;
1385 1355
@@ -1389,8 +1359,10 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
1389 memcpy(tty->read_buf + tty->read_head, cp, i); 1359 memcpy(tty->read_buf + tty->read_head, cp, i);
1390 tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1); 1360 tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
1391 tty->read_cnt += i; 1361 tty->read_cnt += i;
1362 ret += i;
1392 spin_unlock_irqrestore(&tty->read_lock, cpuflags); 1363 spin_unlock_irqrestore(&tty->read_lock, cpuflags);
1393 } else { 1364 } else {
1365 ret = count;
1394 for (i = count, p = cp, f = fp; i; i--, p++) { 1366 for (i = count, p = cp, f = fp; i; i--, p++) {
1395 if (f) 1367 if (f)
1396 flags = *f++; 1368 flags = *f++;
@@ -1418,8 +1390,6 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
1418 tty->ops->flush_chars(tty); 1390 tty->ops->flush_chars(tty);
1419 } 1391 }
1420 1392
1421 n_tty_set_room(tty);
1422
1423 if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) || 1393 if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) ||
1424 L_EXTPROC(tty)) { 1394 L_EXTPROC(tty)) {
1425 kill_fasync(&tty->fasync, SIGIO, POLL_IN); 1395 kill_fasync(&tty->fasync, SIGIO, POLL_IN);
@@ -1432,8 +1402,12 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
1432 * mode. We don't want to throttle the driver if we're in 1402 * mode. We don't want to throttle the driver if we're in
1433 * canonical mode and don't have a newline yet! 1403 * canonical mode and don't have a newline yet!
1434 */ 1404 */
1435 if (tty->receive_room < TTY_THRESHOLD_THROTTLE) 1405 left = N_TTY_BUF_SIZE - tty->read_cnt - 1;
1406
1407 if (left < TTY_THRESHOLD_THROTTLE)
1436 tty_throttle(tty); 1408 tty_throttle(tty);
1409
1410 return ret;
1437} 1411}
1438 1412
1439int is_ignored(int sig) 1413int is_ignored(int sig)
@@ -1477,7 +1451,6 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
1477 if (test_bit(TTY_HW_COOK_IN, &tty->flags)) { 1451 if (test_bit(TTY_HW_COOK_IN, &tty->flags)) {
1478 tty->raw = 1; 1452 tty->raw = 1;
1479 tty->real_raw = 1; 1453 tty->real_raw = 1;
1480 n_tty_set_room(tty);
1481 return; 1454 return;
1482 } 1455 }
1483 if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) || 1456 if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) ||
@@ -1530,7 +1503,6 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
1530 else 1503 else
1531 tty->real_raw = 0; 1504 tty->real_raw = 0;
1532 } 1505 }
1533 n_tty_set_room(tty);
1534 /* The termios change make the tty ready for I/O */ 1506 /* The termios change make the tty ready for I/O */
1535 wake_up_interruptible(&tty->write_wait); 1507 wake_up_interruptible(&tty->write_wait);
1536 wake_up_interruptible(&tty->read_wait); 1508 wake_up_interruptible(&tty->read_wait);
@@ -1812,8 +1784,6 @@ do_it_again:
1812 retval = -ERESTARTSYS; 1784 retval = -ERESTARTSYS;
1813 break; 1785 break;
1814 } 1786 }
1815 /* FIXME: does n_tty_set_room need locking ? */
1816 n_tty_set_room(tty);
1817 timeout = schedule_timeout(timeout); 1787 timeout = schedule_timeout(timeout);
1818 continue; 1788 continue;
1819 } 1789 }
@@ -1885,10 +1855,8 @@ do_it_again:
1885 * longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode, 1855 * longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode,
1886 * we won't get any more characters. 1856 * we won't get any more characters.
1887 */ 1857 */
1888 if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) { 1858 if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE)
1889 n_tty_set_room(tty);
1890 check_unthrottle(tty); 1859 check_unthrottle(tty);
1891 }
1892 1860
1893 if (b - buf >= minimum) 1861 if (b - buf >= minimum)
1894 break; 1862 break;
@@ -1910,7 +1878,6 @@ do_it_again:
1910 } else if (test_and_clear_bit(TTY_PUSH, &tty->flags)) 1878 } else if (test_and_clear_bit(TTY_PUSH, &tty->flags))
1911 goto do_it_again; 1879 goto do_it_again;
1912 1880
1913 n_tty_set_room(tty);
1914 return retval; 1881 return retval;
1915} 1882}
1916 1883
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
index f1a7918d71a..46de2e075da 100644
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -416,6 +416,7 @@ static void flush_to_ldisc(struct work_struct *work)
416 struct tty_buffer *head, *tail = tty->buf.tail; 416 struct tty_buffer *head, *tail = tty->buf.tail;
417 int seen_tail = 0; 417 int seen_tail = 0;
418 while ((head = tty->buf.head) != NULL) { 418 while ((head = tty->buf.head) != NULL) {
419 int copied;
419 int count; 420 int count;
420 char *char_buf; 421 char *char_buf;
421 unsigned char *flag_buf; 422 unsigned char *flag_buf;
@@ -442,17 +443,19 @@ static void flush_to_ldisc(struct work_struct *work)
442 line discipline as we want to empty the queue */ 443 line discipline as we want to empty the queue */
443 if (test_bit(TTY_FLUSHPENDING, &tty->flags)) 444 if (test_bit(TTY_FLUSHPENDING, &tty->flags))
444 break; 445 break;
445 if (!tty->receive_room || seen_tail)
446 break;
447 if (count > tty->receive_room)
448 count = tty->receive_room;
449 char_buf = head->char_buf_ptr + head->read; 446 char_buf = head->char_buf_ptr + head->read;
450 flag_buf = head->flag_buf_ptr + head->read; 447 flag_buf = head->flag_buf_ptr + head->read;
451 head->read += count;
452 spin_unlock_irqrestore(&tty->buf.lock, flags); 448 spin_unlock_irqrestore(&tty->buf.lock, flags);
453 disc->ops->receive_buf(tty, char_buf, 449 copied = disc->ops->receive_buf(tty, char_buf,
454 flag_buf, count); 450 flag_buf, count);
455 spin_lock_irqsave(&tty->buf.lock, flags); 451 spin_lock_irqsave(&tty->buf.lock, flags);
452
453 head->read += copied;
454
455 if (copied == 0 || seen_tail) {
456 schedule_work(&tty->buf.work);
457 break;
458 }
456 } 459 }
457 clear_bit(TTY_FLUSHING, &tty->flags); 460 clear_bit(TTY_FLUSHING, &tty->flags);
458 } 461 }
diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c
index fb864e7fcd1..67b1d0d7c8a 100644
--- a/drivers/tty/vt/selection.c
+++ b/drivers/tty/vt/selection.c
@@ -332,8 +332,7 @@ int paste_selection(struct tty_struct *tty)
332 continue; 332 continue;
333 } 333 }
334 count = sel_buffer_lth - pasted; 334 count = sel_buffer_lth - pasted;
335 count = min(count, tty->receive_room); 335 count = tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted,
336 tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted,
337 NULL, count); 336 NULL, count);
338 pasted += count; 337 pasted += count;
339 } 338 }