aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-06-03 17:33:24 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-06-03 17:33:24 -0400
commit55db4c64eddf37e31279ec15fe90314713bc9cfa (patch)
tree4bd186333049c5fcc1eacdff0efc82ac8b80ff5e /drivers
parent1fa7b6a29c61358cc2ca6f64cef4aa0e1a7ca74c (diff)
Revert "tty: make receive_buf() return the amout of bytes received"
This reverts commit b1c43f82c5aa265442f82dba31ce985ebb7aa71c. It was broken in so many ways, and results in random odd pty issues. It re-introduced the buggy schedule_work() in flush_to_ldisc() that can cause endless work-loops (see commit a5660b41af6a: "tty: fix endless work loop when the buffer fills up"). It also used an "unsigned int" return value fo the ->receive_buf() function, but then made multiple functions return a negative error code, and didn't actually check for the error in the caller. And it didn't actually work at all. BenH bisected down odd tty behavior to it: "It looks like the patch is causing some major malfunctions of the X server for me, possibly related to PTYs. For example, cat'ing a large file in a gnome terminal hangs the kernel for -minutes- in a loop of what looks like flush_to_ldisc/workqueue code, (some ftrace data in the quoted bits further down). ... Some more data: It -looks- like what happens is that the flush_to_ldisc work queue entry constantly re-queues itself (because the PTY is full ?) and the workqueue thread will basically loop forver calling it without ever scheduling, thus starving the consumer process that could have emptied the PTY." which is pretty much exactly the problem we fixed in a5660b41af6a. Milton Miller pointed out the 'unsigned int' issue. Reported-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Reported-by: Milton Miller <miltonm@bga.com> Cc: Stefan Bigler <stefan.bigler@keymile.com> Cc: Toby Gray <toby.gray@realvnc.com> Cc: Felipe Balbi <balbi@ti.com> Cc: Greg Kroah-Hartman <gregkh@suse.de> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/bluetooth/hci_ldisc.c17
-rw-r--r--drivers/input/serio/serport.c10
-rw-r--r--drivers/isdn/gigaset/ser-gigaset.c8
-rw-r--r--drivers/misc/ti-st/st_core.c6
-rw-r--r--drivers/net/caif/caif_serial.c6
-rw-r--r--drivers/net/can/slcan.c9
-rw-r--r--drivers/net/hamradio/6pack.c8
-rw-r--r--drivers/net/hamradio/mkiss.c11
-rw-r--r--drivers/net/irda/irtty-sir.c16
-rw-r--r--drivers/net/ppp_async.c6
-rw-r--r--drivers/net/ppp_synctty.c6
-rw-r--r--drivers/net/slip.c11
-rw-r--r--drivers/net/wan/x25_asy.c7
-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
19 files changed, 111 insertions, 123 deletions
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index b3f01996318f..48ad2a7ab080 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -355,29 +355,24 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty)
355 * flags pointer to flags for data 355 * flags pointer to flags for data
356 * count count of received data in bytes 356 * count count of received data in bytes
357 * 357 *
358 * Return Value: Number of bytes received 358 * Return Value: None
359 */ 359 */
360static unsigned int hci_uart_tty_receive(struct tty_struct *tty, 360static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count)
361 const u8 *data, char *flags, int count)
362{ 361{
363 struct hci_uart *hu = (void *)tty->disc_data; 362 struct hci_uart *hu = (void *)tty->disc_data;
364 int received;
365 363
366 if (!hu || tty != hu->tty) 364 if (!hu || tty != hu->tty)
367 return -ENODEV; 365 return;
368 366
369 if (!test_bit(HCI_UART_PROTO_SET, &hu->flags)) 367 if (!test_bit(HCI_UART_PROTO_SET, &hu->flags))
370 return -EINVAL; 368 return;
371 369
372 spin_lock(&hu->rx_lock); 370 spin_lock(&hu->rx_lock);
373 received = hu->proto->recv(hu, (void *) data, count); 371 hu->proto->recv(hu, (void *) data, count);
374 if (received > 0) 372 hu->hdev->stat.byte_rx += count;
375 hu->hdev->stat.byte_rx += received;
376 spin_unlock(&hu->rx_lock); 373 spin_unlock(&hu->rx_lock);
377 374
378 tty_unthrottle(tty); 375 tty_unthrottle(tty);
379
380 return received;
381} 376}
382 377
383static int hci_uart_register_dev(struct hci_uart *hu) 378static int hci_uart_register_dev(struct hci_uart *hu)
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
index f3698967edf6..8755f5f3ad37 100644
--- a/drivers/input/serio/serport.c
+++ b/drivers/input/serio/serport.c
@@ -120,21 +120,17 @@ static void serport_ldisc_close(struct tty_struct *tty)
120 * 'interrupt' routine. 120 * 'interrupt' routine.
121 */ 121 */
122 122
123static unsigned int serport_ldisc_receive(struct tty_struct *tty, 123static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
124 const unsigned char *cp, char *fp, int count)
125{ 124{
126 struct serport *serport = (struct serport*) tty->disc_data; 125 struct serport *serport = (struct serport*) tty->disc_data;
127 unsigned long flags; 126 unsigned long flags;
128 unsigned int ch_flags; 127 unsigned int ch_flags;
129 int ret = 0;
130 int i; 128 int i;
131 129
132 spin_lock_irqsave(&serport->lock, flags); 130 spin_lock_irqsave(&serport->lock, flags);
133 131
134 if (!test_bit(SERPORT_ACTIVE, &serport->flags)) { 132 if (!test_bit(SERPORT_ACTIVE, &serport->flags))
135 ret = -EINVAL;
136 goto out; 133 goto out;
137 }
138 134
139 for (i = 0; i < count; i++) { 135 for (i = 0; i < count; i++) {
140 switch (fp[i]) { 136 switch (fp[i]) {
@@ -156,8 +152,6 @@ static unsigned int serport_ldisc_receive(struct tty_struct *tty,
156 152
157out: 153out:
158 spin_unlock_irqrestore(&serport->lock, flags); 154 spin_unlock_irqrestore(&serport->lock, flags);
159
160 return ret == 0 ? count : ret;
161} 155}
162 156
163/* 157/*
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c
index 1d44d470897c..86a5c4f7775e 100644
--- a/drivers/isdn/gigaset/ser-gigaset.c
+++ b/drivers/isdn/gigaset/ser-gigaset.c
@@ -674,7 +674,7 @@ gigaset_tty_ioctl(struct tty_struct *tty, struct file *file,
674 * cflags buffer containing error flags for received characters (ignored) 674 * cflags buffer containing error flags for received characters (ignored)
675 * count number of received characters 675 * count number of received characters
676 */ 676 */
677static unsigned int 677static void
678gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf, 678gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf,
679 char *cflags, int count) 679 char *cflags, int count)
680{ 680{
@@ -683,12 +683,12 @@ gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf,
683 struct inbuf_t *inbuf; 683 struct inbuf_t *inbuf;
684 684
685 if (!cs) 685 if (!cs)
686 return -ENODEV; 686 return;
687 inbuf = cs->inbuf; 687 inbuf = cs->inbuf;
688 if (!inbuf) { 688 if (!inbuf) {
689 dev_err(cs->dev, "%s: no inbuf\n", __func__); 689 dev_err(cs->dev, "%s: no inbuf\n", __func__);
690 cs_put(cs); 690 cs_put(cs);
691 return -EINVAL; 691 return;
692 } 692 }
693 693
694 tail = inbuf->tail; 694 tail = inbuf->tail;
@@ -725,8 +725,6 @@ gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf,
725 gig_dbg(DEBUG_INTR, "%s-->BH", __func__); 725 gig_dbg(DEBUG_INTR, "%s-->BH", __func__);
726 gigaset_schedule_event(cs); 726 gigaset_schedule_event(cs);
727 cs_put(cs); 727 cs_put(cs);
728
729 return count;
730} 728}
731 729
732/* 730/*
diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c
index 1a05fe08e2cb..f91f82eabda7 100644
--- a/drivers/misc/ti-st/st_core.c
+++ b/drivers/misc/ti-st/st_core.c
@@ -747,8 +747,8 @@ static void st_tty_close(struct tty_struct *tty)
747 pr_debug("%s: done ", __func__); 747 pr_debug("%s: done ", __func__);
748} 748}
749 749
750static unsigned int st_tty_receive(struct tty_struct *tty, 750static void st_tty_receive(struct tty_struct *tty, const unsigned char *data,
751 const unsigned char *data, char *tty_flags, int count) 751 char *tty_flags, int count)
752{ 752{
753#ifdef VERBOSE 753#ifdef VERBOSE
754 print_hex_dump(KERN_DEBUG, ">in>", DUMP_PREFIX_NONE, 754 print_hex_dump(KERN_DEBUG, ">in>", DUMP_PREFIX_NONE,
@@ -761,8 +761,6 @@ static unsigned int st_tty_receive(struct tty_struct *tty,
761 */ 761 */
762 st_recv(tty->disc_data, data, count); 762 st_recv(tty->disc_data, data, count);
763 pr_debug("done %s", __func__); 763 pr_debug("done %s", __func__);
764
765 return count;
766} 764}
767 765
768/* wake-up function called in from the TTY layer 766/* wake-up function called in from the TTY layer
diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c
index 73c7e03617ec..3df0c0f8b8bf 100644
--- a/drivers/net/caif/caif_serial.c
+++ b/drivers/net/caif/caif_serial.c
@@ -167,8 +167,8 @@ static inline void debugfs_tx(struct ser_device *ser, const u8 *data, int size)
167 167
168#endif 168#endif
169 169
170static unsigned int ldisc_receive(struct tty_struct *tty, 170static void ldisc_receive(struct tty_struct *tty, const u8 *data,
171 const u8 *data, char *flags, int count) 171 char *flags, int count)
172{ 172{
173 struct sk_buff *skb = NULL; 173 struct sk_buff *skb = NULL;
174 struct ser_device *ser; 174 struct ser_device *ser;
@@ -215,8 +215,6 @@ static unsigned int ldisc_receive(struct tty_struct *tty,
215 } else 215 } else
216 ++ser->dev->stats.rx_dropped; 216 ++ser->dev->stats.rx_dropped;
217 update_tty_status(ser); 217 update_tty_status(ser);
218
219 return count;
220} 218}
221 219
222static int handle_tx(struct ser_device *ser) 220static int handle_tx(struct ser_device *ser)
diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c
index 75622d54581f..1b49df6b2470 100644
--- a/drivers/net/can/slcan.c
+++ b/drivers/net/can/slcan.c
@@ -425,17 +425,16 @@ static void slc_setup(struct net_device *dev)
425 * in parallel 425 * in parallel
426 */ 426 */
427 427
428static unsigned int slcan_receive_buf(struct tty_struct *tty, 428static void slcan_receive_buf(struct tty_struct *tty,
429 const unsigned char *cp, char *fp, int count) 429 const unsigned char *cp, char *fp, int count)
430{ 430{
431 struct slcan *sl = (struct slcan *) tty->disc_data; 431 struct slcan *sl = (struct slcan *) tty->disc_data;
432 int bytes = count;
433 432
434 if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev)) 433 if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev))
435 return -ENODEV; 434 return;
436 435
437 /* Read the characters out of the buffer */ 436 /* Read the characters out of the buffer */
438 while (bytes--) { 437 while (count--) {
439 if (fp && *fp++) { 438 if (fp && *fp++) {
440 if (!test_and_set_bit(SLF_ERROR, &sl->flags)) 439 if (!test_and_set_bit(SLF_ERROR, &sl->flags))
441 sl->dev->stats.rx_errors++; 440 sl->dev->stats.rx_errors++;
@@ -444,8 +443,6 @@ static unsigned int slcan_receive_buf(struct tty_struct *tty,
444 } 443 }
445 slcan_unesc(sl, *cp++); 444 slcan_unesc(sl, *cp++);
446 } 445 }
447
448 return count;
449} 446}
450 447
451/************************************ 448/************************************
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 992089639ea4..3e5d0b6b6516 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -456,7 +456,7 @@ out:
456 * a block of 6pack data has been received, which can now be decapsulated 456 * a block of 6pack data has been received, which can now be decapsulated
457 * and sent on to some IP layer for further processing. 457 * and sent on to some IP layer for further processing.
458 */ 458 */
459static unsigned int sixpack_receive_buf(struct tty_struct *tty, 459static void sixpack_receive_buf(struct tty_struct *tty,
460 const unsigned char *cp, char *fp, int count) 460 const unsigned char *cp, char *fp, int count)
461{ 461{
462 struct sixpack *sp; 462 struct sixpack *sp;
@@ -464,11 +464,11 @@ static unsigned int sixpack_receive_buf(struct tty_struct *tty,
464 int count1; 464 int count1;
465 465
466 if (!count) 466 if (!count)
467 return 0; 467 return;
468 468
469 sp = sp_get(tty); 469 sp = sp_get(tty);
470 if (!sp) 470 if (!sp)
471 return -ENODEV; 471 return;
472 472
473 memcpy(buf, cp, count < sizeof(buf) ? count : sizeof(buf)); 473 memcpy(buf, cp, count < sizeof(buf) ? count : sizeof(buf));
474 474
@@ -487,8 +487,6 @@ static unsigned int sixpack_receive_buf(struct tty_struct *tty,
487 487
488 sp_put(sp); 488 sp_put(sp);
489 tty_unthrottle(tty); 489 tty_unthrottle(tty);
490
491 return count1;
492} 490}
493 491
494/* 492/*
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 0e4f23531140..4c628393c8b1 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -923,14 +923,13 @@ static long mkiss_compat_ioctl(struct tty_struct *tty, struct file *file,
923 * a block of data has been received, which can now be decapsulated 923 * a block of data has been received, which can now be decapsulated
924 * and sent on to the AX.25 layer for further processing. 924 * and sent on to the AX.25 layer for further processing.
925 */ 925 */
926static unsigned int mkiss_receive_buf(struct tty_struct *tty, 926static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp,
927 const unsigned char *cp, char *fp, int count) 927 char *fp, int count)
928{ 928{
929 struct mkiss *ax = mkiss_get(tty); 929 struct mkiss *ax = mkiss_get(tty);
930 int bytes = count;
931 930
932 if (!ax) 931 if (!ax)
933 return -ENODEV; 932 return;
934 933
935 /* 934 /*
936 * Argh! mtu change time! - costs us the packet part received 935 * Argh! mtu change time! - costs us the packet part received
@@ -940,7 +939,7 @@ static unsigned int mkiss_receive_buf(struct tty_struct *tty,
940 ax_changedmtu(ax); 939 ax_changedmtu(ax);
941 940
942 /* Read the characters out of the buffer */ 941 /* Read the characters out of the buffer */
943 while (bytes--) { 942 while (count--) {
944 if (fp != NULL && *fp++) { 943 if (fp != NULL && *fp++) {
945 if (!test_and_set_bit(AXF_ERROR, &ax->flags)) 944 if (!test_and_set_bit(AXF_ERROR, &ax->flags))
946 ax->dev->stats.rx_errors++; 945 ax->dev->stats.rx_errors++;
@@ -953,8 +952,6 @@ static unsigned int mkiss_receive_buf(struct tty_struct *tty,
953 952
954 mkiss_put(ax); 953 mkiss_put(ax);
955 tty_unthrottle(tty); 954 tty_unthrottle(tty);
956
957 return count;
958} 955}
959 956
960/* 957/*
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c
index 035861d8acb1..3352b2443e58 100644
--- a/drivers/net/irda/irtty-sir.c
+++ b/drivers/net/irda/irtty-sir.c
@@ -216,23 +216,23 @@ static int irtty_do_write(struct sir_dev *dev, const unsigned char *ptr, size_t
216 * usbserial: urb-complete-interrupt / softint 216 * usbserial: urb-complete-interrupt / softint
217 */ 217 */
218 218
219static unsigned int irtty_receive_buf(struct tty_struct *tty, 219static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
220 const unsigned char *cp, char *fp, int count) 220 char *fp, int count)
221{ 221{
222 struct sir_dev *dev; 222 struct sir_dev *dev;
223 struct sirtty_cb *priv = tty->disc_data; 223 struct sirtty_cb *priv = tty->disc_data;
224 int i; 224 int i;
225 225
226 IRDA_ASSERT(priv != NULL, return -ENODEV;); 226 IRDA_ASSERT(priv != NULL, return;);
227 IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -EINVAL;); 227 IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return;);
228 228
229 if (unlikely(count==0)) /* yes, this happens */ 229 if (unlikely(count==0)) /* yes, this happens */
230 return 0; 230 return;
231 231
232 dev = priv->dev; 232 dev = priv->dev;
233 if (!dev) { 233 if (!dev) {
234 IRDA_WARNING("%s(), not ready yet!\n", __func__); 234 IRDA_WARNING("%s(), not ready yet!\n", __func__);
235 return -ENODEV; 235 return;
236 } 236 }
237 237
238 for (i = 0; i < count; i++) { 238 for (i = 0; i < count; i++) {
@@ -242,13 +242,11 @@ static unsigned int irtty_receive_buf(struct tty_struct *tty,
242 if (fp && *fp++) { 242 if (fp && *fp++) {
243 IRDA_DEBUG(0, "Framing or parity error!\n"); 243 IRDA_DEBUG(0, "Framing or parity error!\n");
244 sirdev_receive(dev, NULL, 0); /* notify sir_dev (updating stats) */ 244 sirdev_receive(dev, NULL, 0); /* notify sir_dev (updating stats) */
245 return -EINVAL; 245 return;
246 } 246 }
247 } 247 }
248 248
249 sirdev_receive(dev, cp, count); 249 sirdev_receive(dev, cp, count);
250
251 return count;
252} 250}
253 251
254/* 252/*
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index 53872d7d7382..a1b82c9c67d2 100644
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -340,7 +340,7 @@ ppp_asynctty_poll(struct tty_struct *tty, struct file *file, poll_table *wait)
340} 340}
341 341
342/* May sleep, don't call from interrupt level or with interrupts disabled */ 342/* May sleep, don't call from interrupt level or with interrupts disabled */
343static unsigned int 343static void
344ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf, 344ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf,
345 char *cflags, int count) 345 char *cflags, int count)
346{ 346{
@@ -348,7 +348,7 @@ ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf,
348 unsigned long flags; 348 unsigned long flags;
349 349
350 if (!ap) 350 if (!ap)
351 return -ENODEV; 351 return;
352 spin_lock_irqsave(&ap->recv_lock, flags); 352 spin_lock_irqsave(&ap->recv_lock, flags);
353 ppp_async_input(ap, buf, cflags, count); 353 ppp_async_input(ap, buf, cflags, count);
354 spin_unlock_irqrestore(&ap->recv_lock, flags); 354 spin_unlock_irqrestore(&ap->recv_lock, flags);
@@ -356,8 +356,6 @@ ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf,
356 tasklet_schedule(&ap->tsk); 356 tasklet_schedule(&ap->tsk);
357 ap_put(ap); 357 ap_put(ap);
358 tty_unthrottle(tty); 358 tty_unthrottle(tty);
359
360 return count;
361} 359}
362 360
363static void 361static void
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c
index 0815790a5cf9..2573f525f11c 100644
--- a/drivers/net/ppp_synctty.c
+++ b/drivers/net/ppp_synctty.c
@@ -381,7 +381,7 @@ ppp_sync_poll(struct tty_struct *tty, struct file *file, poll_table *wait)
381} 381}
382 382
383/* May sleep, don't call from interrupt level or with interrupts disabled */ 383/* May sleep, don't call from interrupt level or with interrupts disabled */
384static unsigned int 384static void
385ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf, 385ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf,
386 char *cflags, int count) 386 char *cflags, int count)
387{ 387{
@@ -389,7 +389,7 @@ ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf,
389 unsigned long flags; 389 unsigned long flags;
390 390
391 if (!ap) 391 if (!ap)
392 return -ENODEV; 392 return;
393 spin_lock_irqsave(&ap->recv_lock, flags); 393 spin_lock_irqsave(&ap->recv_lock, flags);
394 ppp_sync_input(ap, buf, cflags, count); 394 ppp_sync_input(ap, buf, cflags, count);
395 spin_unlock_irqrestore(&ap->recv_lock, flags); 395 spin_unlock_irqrestore(&ap->recv_lock, flags);
@@ -397,8 +397,6 @@ ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf,
397 tasklet_schedule(&ap->tsk); 397 tasklet_schedule(&ap->tsk);
398 sp_put(ap); 398 sp_put(ap);
399 tty_unthrottle(tty); 399 tty_unthrottle(tty);
400
401 return count;
402} 400}
403 401
404static void 402static void
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index 584809c656d5..8ec1a9a0bb9a 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -670,17 +670,16 @@ static void sl_setup(struct net_device *dev)
670 * in parallel 670 * in parallel
671 */ 671 */
672 672
673static unsigned int slip_receive_buf(struct tty_struct *tty, 673static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp,
674 const unsigned char *cp, char *fp, int count) 674 char *fp, int count)
675{ 675{
676 struct slip *sl = tty->disc_data; 676 struct slip *sl = tty->disc_data;
677 int bytes = count;
678 677
679 if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev)) 678 if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev))
680 return -ENODEV; 679 return;
681 680
682 /* Read the characters out of the buffer */ 681 /* Read the characters out of the buffer */
683 while (bytes--) { 682 while (count--) {
684 if (fp && *fp++) { 683 if (fp && *fp++) {
685 if (!test_and_set_bit(SLF_ERROR, &sl->flags)) 684 if (!test_and_set_bit(SLF_ERROR, &sl->flags))
686 sl->dev->stats.rx_errors++; 685 sl->dev->stats.rx_errors++;
@@ -694,8 +693,6 @@ static unsigned int slip_receive_buf(struct tty_struct *tty,
694#endif 693#endif
695 slip_unesc(sl, *cp++); 694 slip_unesc(sl, *cp++);
696 } 695 }
697
698 return count;
699} 696}
700 697
701/************************************ 698/************************************
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index 40398bf7d036..24297b274cd4 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -517,18 +517,17 @@ static int x25_asy_close(struct net_device *dev)
517 * and sent on to some IP layer for further processing. 517 * and sent on to some IP layer for further processing.
518 */ 518 */
519 519
520static unsigned int x25_asy_receive_buf(struct tty_struct *tty, 520static void x25_asy_receive_buf(struct tty_struct *tty,
521 const unsigned char *cp, char *fp, int count) 521 const unsigned char *cp, char *fp, int count)
522{ 522{
523 struct x25_asy *sl = tty->disc_data; 523 struct x25_asy *sl = tty->disc_data;
524 int bytes = count;
525 524
526 if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev)) 525 if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev))
527 return; 526 return;
528 527
529 528
530 /* Read the characters out of the buffer */ 529 /* Read the characters out of the buffer */
531 while (bytes--) { 530 while (count--) {
532 if (fp && *fp++) { 531 if (fp && *fp++) {
533 if (!test_and_set_bit(SLF_ERROR, &sl->flags)) 532 if (!test_and_set_bit(SLF_ERROR, &sl->flags))
534 sl->dev->stats.rx_errors++; 533 sl->dev->stats.rx_errors++;
@@ -537,8 +536,6 @@ static unsigned int x25_asy_receive_buf(struct tty_struct *tty,
537 } 536 }
538 x25_asy_unesc(sl, *cp++); 537 x25_asy_unesc(sl, *cp++);
539 } 538 }
540
541 return count;
542} 539}
543 540
544/* 541/*
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index a4c42a75a3bf..09e8c7d53af3 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -2128,8 +2128,8 @@ static void gsmld_detach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
2128 gsm->tty = NULL; 2128 gsm->tty = NULL;
2129} 2129}
2130 2130
2131static unsigned int gsmld_receive_buf(struct tty_struct *tty, 2131static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp,
2132 const unsigned char *cp, char *fp, int count) 2132 char *fp, int count)
2133{ 2133{
2134 struct gsm_mux *gsm = tty->disc_data; 2134 struct gsm_mux *gsm = tty->disc_data;
2135 const unsigned char *dp; 2135 const unsigned char *dp;
@@ -2162,8 +2162,6 @@ static unsigned int gsmld_receive_buf(struct tty_struct *tty,
2162 } 2162 }
2163 /* FASYNC if needed ? */ 2163 /* FASYNC if needed ? */
2164 /* If clogged call tty_throttle(tty); */ 2164 /* If clogged call tty_throttle(tty); */
2165
2166 return count;
2167} 2165}
2168 2166
2169/** 2167/**
diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c
index cac666314aef..cea56033b34c 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 unsigned int n_hdlc_tty_receive(struct tty_struct *tty, 191static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *cp,
192 const __u8 *cp, char *fp, int count); 192 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 unsigned int n_hdlc_tty_receive(struct tty_struct *tty, 512static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data,
513 const __u8 *data, char *flags, int count) 513 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 unsigned int n_hdlc_tty_receive(struct tty_struct *tty,
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 -ENODEV; 524 return;
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 -EINVAL; 530 return;
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 -EINVAL; 537 return;
538 } 538 }
539 539
540 /* get a free HDLC buffer */ 540 /* get a free HDLC buffer */
@@ -550,7 +550,7 @@ static unsigned int n_hdlc_tty_receive(struct tty_struct *tty,
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 -EINVAL; 553 return;
554 } 554 }
555 555
556 /* copy received data to HDLC buffer */ 556 /* copy received data to HDLC buffer */
@@ -565,8 +565,6 @@ static unsigned int n_hdlc_tty_receive(struct tty_struct *tty,
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
570} /* end of n_hdlc_tty_receive() */ 568} /* end of n_hdlc_tty_receive() */
571 569
572/** 570/**
diff --git a/drivers/tty/n_r3964.c b/drivers/tty/n_r3964.c
index a4bc39c21a43..5c6c31459a2f 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 unsigned int r3964_receive_buf(struct tty_struct *tty, 142static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
143 const unsigned char *cp, char *fp, int count); 143 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 unsigned int r3964_receive_buf(struct tty_struct *tty, 1242static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
1243 const unsigned char *cp, char *fp, int count) 1243 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,8 +1257,6 @@ static unsigned int r3964_receive_buf(struct tty_struct *tty,
1257 } 1257 }
1258 1258
1259 } 1259 }
1260
1261 return count;
1262} 1260}
1263 1261
1264MODULE_LICENSE("GPL"); 1262MODULE_LICENSE("GPL");
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
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
84static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) 116static 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
1330static unsigned int n_tty_receive_buf(struct tty_struct *tty, 1363static 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
1413int is_ignored(int sig) 1439int 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
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
index 46de2e075dac..f1a7918d71aa 100644
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -416,7 +416,6 @@ 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;
420 int count; 419 int count;
421 char *char_buf; 420 char *char_buf;
422 unsigned char *flag_buf; 421 unsigned char *flag_buf;
@@ -443,19 +442,17 @@ static void flush_to_ldisc(struct work_struct *work)
443 line discipline as we want to empty the queue */ 442 line discipline as we want to empty the queue */
444 if (test_bit(TTY_FLUSHPENDING, &tty->flags)) 443 if (test_bit(TTY_FLUSHPENDING, &tty->flags))
445 break; 444 break;
445 if (!tty->receive_room || seen_tail)
446 break;
447 if (count > tty->receive_room)
448 count = tty->receive_room;
446 char_buf = head->char_buf_ptr + head->read; 449 char_buf = head->char_buf_ptr + head->read;
447 flag_buf = head->flag_buf_ptr + head->read; 450 flag_buf = head->flag_buf_ptr + head->read;
451 head->read += count;
448 spin_unlock_irqrestore(&tty->buf.lock, flags); 452 spin_unlock_irqrestore(&tty->buf.lock, flags);
449 copied = disc->ops->receive_buf(tty, char_buf, 453 disc->ops->receive_buf(tty, char_buf,
450 flag_buf, count); 454 flag_buf, count);
451 spin_lock_irqsave(&tty->buf.lock, flags); 455 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 }
459 } 456 }
460 clear_bit(TTY_FLUSHING, &tty->flags); 457 clear_bit(TTY_FLUSHING, &tty->flags);
461 } 458 }
diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c
index 67b1d0d7c8ac..fb864e7fcd13 100644
--- a/drivers/tty/vt/selection.c
+++ b/drivers/tty/vt/selection.c
@@ -332,7 +332,8 @@ 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 = tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted, 335 count = min(count, tty->receive_room);
336 tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted,
336 NULL, count); 337 NULL, count);
337 pasted += count; 338 pasted += count;
338 } 339 }