aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
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
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')
-rw-r--r--drivers/bluetooth/hci_ldisc.c12
-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, 120 insertions, 109 deletions
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 48ad2a7ab080..0d4da5e14ba0 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -357,22 +357,26 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty)
357 * 357 *
358 * Return Value: None 358 * Return Value: None
359 */ 359 */
360static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count) 360static unsigned int hci_uart_tty_receive(struct tty_struct *tty,
361 const u8 *data, char *flags, int count)
361{ 362{
362 struct hci_uart *hu = (void *)tty->disc_data; 363 struct hci_uart *hu = (void *)tty->disc_data;
364 int received;
363 365
364 if (!hu || tty != hu->tty) 366 if (!hu || tty != hu->tty)
365 return; 367 return -ENODEV;
366 368
367 if (!test_bit(HCI_UART_PROTO_SET, &hu->flags)) 369 if (!test_bit(HCI_UART_PROTO_SET, &hu->flags))
368 return; 370 return -EINVAL;
369 371
370 spin_lock(&hu->rx_lock); 372 spin_lock(&hu->rx_lock);
371 hu->proto->recv(hu, (void *) data, count); 373 received = hu->proto->recv(hu, (void *) data, count);
372 hu->hdev->stat.byte_rx += count; 374 hu->hdev->stat.byte_rx += count;
373 spin_unlock(&hu->rx_lock); 375 spin_unlock(&hu->rx_lock);
374 376
375 tty_unthrottle(tty); 377 tty_unthrottle(tty);
378
379 return received;
376} 380}
377 381
378static int hci_uart_register_dev(struct hci_uart *hu) 382static int hci_uart_register_dev(struct hci_uart *hu)
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
index 8755f5f3ad37..f3698967edf6 100644
--- a/drivers/input/serio/serport.c
+++ b/drivers/input/serio/serport.c
@@ -120,17 +120,21 @@ static void serport_ldisc_close(struct tty_struct *tty)
120 * 'interrupt' routine. 120 * 'interrupt' routine.
121 */ 121 */
122 122
123static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) 123static unsigned int serport_ldisc_receive(struct tty_struct *tty,
124 const unsigned char *cp, char *fp, int count)
124{ 125{
125 struct serport *serport = (struct serport*) tty->disc_data; 126 struct serport *serport = (struct serport*) tty->disc_data;
126 unsigned long flags; 127 unsigned long flags;
127 unsigned int ch_flags; 128 unsigned int ch_flags;
129 int ret = 0;
128 int i; 130 int i;
129 131
130 spin_lock_irqsave(&serport->lock, flags); 132 spin_lock_irqsave(&serport->lock, flags);
131 133
132 if (!test_bit(SERPORT_ACTIVE, &serport->flags)) 134 if (!test_bit(SERPORT_ACTIVE, &serport->flags)) {
135 ret = -EINVAL;
133 goto out; 136 goto out;
137 }
134 138
135 for (i = 0; i < count; i++) { 139 for (i = 0; i < count; i++) {
136 switch (fp[i]) { 140 switch (fp[i]) {
@@ -152,6 +156,8 @@ static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *c
152 156
153out: 157out:
154 spin_unlock_irqrestore(&serport->lock, flags); 158 spin_unlock_irqrestore(&serport->lock, flags);
159
160 return ret == 0 ? count : ret;
155} 161}
156 162
157/* 163/*
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c
index 86a5c4f7775e..1d44d470897c 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 void 677static unsigned int
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; 686 return -ENODEV;
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; 691 return -EINVAL;
692 } 692 }
693 693
694 tail = inbuf->tail; 694 tail = inbuf->tail;
@@ -725,6 +725,8 @@ 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;
728} 730}
729 731
730/* 732/*
diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c
index 486117f72c9f..cb98a7da98ef 100644
--- a/drivers/misc/ti-st/st_core.c
+++ b/drivers/misc/ti-st/st_core.c
@@ -744,8 +744,8 @@ static void st_tty_close(struct tty_struct *tty)
744 pr_debug("%s: done ", __func__); 744 pr_debug("%s: done ", __func__);
745} 745}
746 746
747static void st_tty_receive(struct tty_struct *tty, const unsigned char *data, 747static unsigned int st_tty_receive(struct tty_struct *tty,
748 char *tty_flags, int count) 748 const unsigned char *data, char *tty_flags, int count)
749{ 749{
750#ifdef VERBOSE 750#ifdef VERBOSE
751 print_hex_dump(KERN_DEBUG, ">in>", DUMP_PREFIX_NONE, 751 print_hex_dump(KERN_DEBUG, ">in>", DUMP_PREFIX_NONE,
@@ -758,6 +758,8 @@ static void st_tty_receive(struct tty_struct *tty, const unsigned char *data,
758 */ 758 */
759 st_recv(tty->disc_data, data, count); 759 st_recv(tty->disc_data, data, count);
760 pr_debug("done %s", __func__); 760 pr_debug("done %s", __func__);
761
762 return count;
761} 763}
762 764
763/* wake-up function called in from the TTY layer 765/* 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 3df0c0f8b8bf..73c7e03617ec 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 void ldisc_receive(struct tty_struct *tty, const u8 *data, 170static unsigned int ldisc_receive(struct tty_struct *tty,
171 char *flags, int count) 171 const u8 *data, 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,6 +215,8 @@ static void ldisc_receive(struct tty_struct *tty, const u8 *data,
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;
218} 220}
219 221
220static int handle_tx(struct ser_device *ser) 222static int handle_tx(struct ser_device *ser)
diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c
index b423965a78d1..c600954998d5 100644
--- a/drivers/net/can/slcan.c
+++ b/drivers/net/can/slcan.c
@@ -425,16 +425,17 @@ static void slc_setup(struct net_device *dev)
425 * in parallel 425 * in parallel
426 */ 426 */
427 427
428static void slcan_receive_buf(struct tty_struct *tty, 428static unsigned int 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;
432 433
433 if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev)) 434 if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev))
434 return; 435 return -ENODEV;
435 436
436 /* Read the characters out of the buffer */ 437 /* Read the characters out of the buffer */
437 while (count--) { 438 while (bytes--) {
438 if (fp && *fp++) { 439 if (fp && *fp++) {
439 if (!test_and_set_bit(SLF_ERROR, &sl->flags)) 440 if (!test_and_set_bit(SLF_ERROR, &sl->flags))
440 sl->dev->stats.rx_errors++; 441 sl->dev->stats.rx_errors++;
@@ -443,6 +444,8 @@ static void slcan_receive_buf(struct tty_struct *tty,
443 } 444 }
444 slcan_unesc(sl, *cp++); 445 slcan_unesc(sl, *cp++);
445 } 446 }
447
448 return count;
446} 449}
447 450
448/************************************ 451/************************************
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 3e5d0b6b6516..992089639ea4 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 void sixpack_receive_buf(struct tty_struct *tty, 459static unsigned int 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 void sixpack_receive_buf(struct tty_struct *tty,
464 int count1; 464 int count1;
465 465
466 if (!count) 466 if (!count)
467 return; 467 return 0;
468 468
469 sp = sp_get(tty); 469 sp = sp_get(tty);
470 if (!sp) 470 if (!sp)
471 return; 471 return -ENODEV;
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,6 +487,8 @@ static void 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;
490} 492}
491 493
492/* 494/*
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 4c628393c8b1..0e4f23531140 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -923,13 +923,14 @@ 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 void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp, 926static unsigned int mkiss_receive_buf(struct tty_struct *tty,
927 char *fp, int count) 927 const unsigned char *cp, char *fp, int count)
928{ 928{
929 struct mkiss *ax = mkiss_get(tty); 929 struct mkiss *ax = mkiss_get(tty);
930 int bytes = count;
930 931
931 if (!ax) 932 if (!ax)
932 return; 933 return -ENODEV;
933 934
934 /* 935 /*
935 * Argh! mtu change time! - costs us the packet part received 936 * Argh! mtu change time! - costs us the packet part received
@@ -939,7 +940,7 @@ static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp,
939 ax_changedmtu(ax); 940 ax_changedmtu(ax);
940 941
941 /* Read the characters out of the buffer */ 942 /* Read the characters out of the buffer */
942 while (count--) { 943 while (bytes--) {
943 if (fp != NULL && *fp++) { 944 if (fp != NULL && *fp++) {
944 if (!test_and_set_bit(AXF_ERROR, &ax->flags)) 945 if (!test_and_set_bit(AXF_ERROR, &ax->flags))
945 ax->dev->stats.rx_errors++; 946 ax->dev->stats.rx_errors++;
@@ -952,6 +953,8 @@ static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp,
952 953
953 mkiss_put(ax); 954 mkiss_put(ax);
954 tty_unthrottle(tty); 955 tty_unthrottle(tty);
956
957 return count;
955} 958}
956 959
957/* 960/*
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c
index 3352b2443e58..035861d8acb1 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 void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp, 219static unsigned int irtty_receive_buf(struct tty_struct *tty,
220 char *fp, int count) 220 const unsigned char *cp, 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;); 226 IRDA_ASSERT(priv != NULL, return -ENODEV;);
227 IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return;); 227 IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -EINVAL;);
228 228
229 if (unlikely(count==0)) /* yes, this happens */ 229 if (unlikely(count==0)) /* yes, this happens */
230 return; 230 return 0;
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; 235 return -ENODEV;
236 } 236 }
237 237
238 for (i = 0; i < count; i++) { 238 for (i = 0; i < count; i++) {
@@ -242,11 +242,13 @@ static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
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; 245 return -EINVAL;
246 } 246 }
247 } 247 }
248 248
249 sirdev_receive(dev, cp, count); 249 sirdev_receive(dev, cp, count);
250
251 return count;
250} 252}
251 253
252/* 254/*
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index a1b82c9c67d2..53872d7d7382 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 void 343static unsigned int
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; 351 return -ENODEV;
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,6 +356,8 @@ 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;
359} 361}
360 362
361static void 363static void
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c
index 2573f525f11c..0815790a5cf9 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 void 384static unsigned int
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; 392 return -ENODEV;
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,6 +397,8 @@ 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;
400} 402}
401 403
402static void 404static void
diff --git a/drivers/net/slip.c b/drivers/net/slip.c
index 86cbb9ea2f26..86718d358395 100644
--- a/drivers/net/slip.c
+++ b/drivers/net/slip.c
@@ -670,16 +670,17 @@ static void sl_setup(struct net_device *dev)
670 * in parallel 670 * in parallel
671 */ 671 */
672 672
673static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, 673static unsigned int slip_receive_buf(struct tty_struct *tty,
674 char *fp, int count) 674 const unsigned char *cp, char *fp, int count)
675{ 675{
676 struct slip *sl = tty->disc_data; 676 struct slip *sl = tty->disc_data;
677 int bytes = count;
677 678
678 if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev)) 679 if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev))
679 return; 680 return -ENODEV;
680 681
681 /* Read the characters out of the buffer */ 682 /* Read the characters out of the buffer */
682 while (count--) { 683 while (bytes--) {
683 if (fp && *fp++) { 684 if (fp && *fp++) {
684 if (!test_and_set_bit(SLF_ERROR, &sl->flags)) 685 if (!test_and_set_bit(SLF_ERROR, &sl->flags))
685 sl->dev->stats.rx_errors++; 686 sl->dev->stats.rx_errors++;
@@ -693,6 +694,8 @@ static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp,
693#endif 694#endif
694 slip_unesc(sl, *cp++); 695 slip_unesc(sl, *cp++);
695 } 696 }
697
698 return count;
696} 699}
697 700
698/************************************ 701/************************************
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index 24297b274cd4..40398bf7d036 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -517,17 +517,18 @@ 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 void x25_asy_receive_buf(struct tty_struct *tty, 520static unsigned int 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;
524 525
525 if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev)) 526 if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev))
526 return; 527 return;
527 528
528 529
529 /* Read the characters out of the buffer */ 530 /* Read the characters out of the buffer */
530 while (count--) { 531 while (bytes--) {
531 if (fp && *fp++) { 532 if (fp && *fp++) {
532 if (!test_and_set_bit(SLF_ERROR, &sl->flags)) 533 if (!test_and_set_bit(SLF_ERROR, &sl->flags))
533 sl->dev->stats.rx_errors++; 534 sl->dev->stats.rx_errors++;
@@ -536,6 +537,8 @@ static void x25_asy_receive_buf(struct tty_struct *tty,
536 } 537 }
537 x25_asy_unesc(sl, *cp++); 538 x25_asy_unesc(sl, *cp++);
538 } 539 }
540
541 return count;
539} 542}
540 543
541/* 544/*
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 47f8cdb207f1..6abc73598847 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 cea56033b34c..cac666314aef 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 5c6c31459a2f..a4bc39c21a43 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 0ad32888091c..95d0a9c2dd13 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 f1a7918d71aa..46de2e075dac 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 fb864e7fcd13..67b1d0d7c8ac 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 }