it makes it simpler to keep track of the amount of bytes received and simplifies how flush_to_ldisc counts the remaining bytes. Signed-off-by: Felipe Balbi <felipe.balbi@xxxxxxxxx> --- I gave this a little test with n900 and seems to be fine, but a more extensive round of test would be really nice. drivers/bluetooth/hci_ldisc.c | 6 ++- drivers/char/n_hdlc.c | 4 +- drivers/char/n_r3964.c | 3 +- drivers/char/n_tty.c | 55 +++++++++-------------------------- drivers/char/tty_buffer.c | 9 ++--- drivers/char/tty_ldisc.c | 7 ---- drivers/input/serio/serport.c | 8 ++++- drivers/isdn/gigaset/ser-gigaset.c | 4 ++- drivers/net/hamradio/6pack.c | 5 ++- drivers/net/hamradio/mkiss.c | 7 ++-- drivers/net/irda/irtty-sir.c | 7 ++-- drivers/net/ppp_async.c | 5 ++- drivers/net/ppp_synctty.c | 5 ++- drivers/net/slip.c | 7 ++-- drivers/net/wan/x25_asy.c | 5 ++- drivers/staging/strip/strip.c | 7 ++-- include/linux/tty_ldisc.h | 6 ++-- 17 files changed, 66 insertions(+), 84 deletions(-) diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 76a1abb..3deb342 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -268,7 +268,6 @@ static int hci_uart_tty_open(struct tty_struct *tty) tty->disc_data = hu; hu->tty = tty; - tty->receive_room = 65536; spin_lock_init(&hu->rx_lock); @@ -350,7 +349,8 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty) * * Return Value: None */ -static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count) +static unsigned int hci_uart_tty_receive(struct tty_struct *tty, + const u8 *data, char *flags, int count) { struct hci_uart *hu = (void *)tty->disc_data; @@ -366,6 +366,8 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *f spin_unlock(&hu->rx_lock); tty_unthrottle(tty); + + return count; } static int hci_uart_register_dev(struct hci_uart *hu) diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c index c68118e..8b1f861 100644 --- a/drivers/char/n_hdlc.c +++ b/drivers/char/n_hdlc.c @@ -359,7 +359,6 @@ static int n_hdlc_tty_open (struct tty_struct *tty) tty->disc_data = n_hdlc; n_hdlc->tty = tty; - tty->receive_room = 65536; #if defined(TTY_NO_WRITE_SPLIT) /* change tty_io write() to not split large writes into 8K chunks */ @@ -510,7 +509,7 @@ static void n_hdlc_tty_wakeup(struct tty_struct *tty) * Called by tty low level driver when receive data is available. Data is * interpreted as one HDLC frame. */ -static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data, +static unsigned int n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data, char *flags, int count) { register struct n_hdlc *n_hdlc = tty2n_hdlc (tty); @@ -566,6 +565,7 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data, if (n_hdlc->tty->fasync != NULL) kill_fasync (&n_hdlc->tty->fasync, SIGIO, POLL_IN); + return count; } /* end of n_hdlc_tty_receive() */ /** diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c index c1d8b54..2249f42 100644 --- a/drivers/char/n_r3964.c +++ b/drivers/char/n_r3964.c @@ -995,7 +995,6 @@ static int r3964_open(struct tty_struct *tty) pInfo->nRetry = 0; tty->disc_data = pInfo; - tty->receive_room = 65536; setup_timer(&pInfo->tmr, on_timeout, (unsigned long)pInfo); @@ -1259,6 +1258,8 @@ static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, } } + + return count; } MODULE_LICENSE("GPL"); diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index bdae832..23d2eae 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c @@ -81,32 +81,6 @@ static inline int tty_put_user(struct tty_struct *tty, unsigned char x, return put_user(x, ptr); } -/** - * n_tty_set__room - receive space - * @tty: terminal - * - * Called by the driver to find out how much data it is - * permitted to feed to the line discipline without any being lost - * and thus to manage flow control. Not serialized. Answers for the - * "instant". - */ - -static void n_tty_set_room(struct tty_struct *tty) -{ - /* tty->read_cnt is not read locked ? */ - int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; - - /* - * If we are doing input canonicalization, and there are no - * pending newlines, let characters through without limit, so - * that erase characters will be handled. Other excess - * characters will be beeped. - */ - if (left <= 0) - left = tty->icanon && !tty->canon_data; - tty->receive_room = left; -} - static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty) { if (tty->read_cnt < N_TTY_BUF_SIZE) { @@ -178,7 +152,6 @@ static void reset_buffer_flags(struct tty_struct *tty) tty->canon_head = tty->canon_data = tty->erasing = 0; memset(&tty->read_flags, 0, sizeof tty->read_flags); - n_tty_set_room(tty); check_unthrottle(tty); } @@ -1349,17 +1322,19 @@ static void n_tty_write_wakeup(struct tty_struct *tty) * calls one at a time and in order (or using flush_to_ldisc) */ -static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) +static unsigned int n_tty_receive_buf(struct tty_struct *tty, + const unsigned char *cp, char *fp, int count) { const unsigned char *p; char *f, flags = TTY_NORMAL; int i; char buf[64]; unsigned long cpuflags; + int left = 0; + int ret = 0; if (!tty->read_buf) - return; + return 0; if (tty->real_raw) { spin_lock_irqsave(&tty->read_lock, cpuflags); @@ -1371,6 +1346,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, tty->read_cnt += i; cp += i; count -= i; + ret += i; i = min(N_TTY_BUF_SIZE - tty->read_cnt, N_TTY_BUF_SIZE - tty->read_head); @@ -1378,8 +1354,10 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, memcpy(tty->read_buf + tty->read_head, cp, i); tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1); tty->read_cnt += i; + ret += i; spin_unlock_irqrestore(&tty->read_lock, cpuflags); } else { + ret = count; for (i = count, p = cp, f = fp; i; i--, p++) { if (f) flags = *f++; @@ -1407,8 +1385,6 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, tty->ops->flush_chars(tty); } - n_tty_set_room(tty); - if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) { kill_fasync(&tty->fasync, SIGIO, POLL_IN); if (waitqueue_active(&tty->read_wait)) @@ -1420,8 +1396,12 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, * mode. We don't want to throttle the driver if we're in * canonical mode and don't have a newline yet! */ - if (tty->receive_room < TTY_THRESHOLD_THROTTLE) + left = N_TTY_BUF_SIZE - tty->read_cnt - 1; + + if (left < TTY_THRESHOLD_THROTTLE) tty_throttle(tty); + + return ret; } int is_ignored(int sig) @@ -1465,7 +1445,6 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) if (test_bit(TTY_HW_COOK_IN, &tty->flags)) { tty->raw = 1; tty->real_raw = 1; - n_tty_set_room(tty); return; } if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) || @@ -1518,7 +1497,6 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) else tty->real_raw = 0; } - n_tty_set_room(tty); /* The termios change make the tty ready for I/O */ wake_up_interruptible(&tty->write_wait); wake_up_interruptible(&tty->read_wait); @@ -1795,8 +1773,6 @@ do_it_again: retval = -ERESTARTSYS; break; } - /* FIXME: does n_tty_set_room need locking ? */ - n_tty_set_room(tty); timeout = schedule_timeout(timeout); continue; } @@ -1868,10 +1844,8 @@ do_it_again: * longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode, * we won't get any more characters. */ - if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) { - n_tty_set_room(tty); + if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) check_unthrottle(tty); - } if (b - buf >= minimum) break; @@ -1893,7 +1867,6 @@ do_it_again: } else if (test_and_clear_bit(TTY_PUSH, &tty->flags)) goto do_it_again; - n_tty_set_room(tty); return retval; } diff --git a/drivers/char/tty_buffer.c b/drivers/char/tty_buffer.c index af8d977..ba348a6 100644 --- a/drivers/char/tty_buffer.c +++ b/drivers/char/tty_buffer.c @@ -58,7 +58,7 @@ static struct tty_buffer *tty_buffer_alloc(struct tty_struct *tty, size_t size) { struct tty_buffer *p; - if (tty->buf.memory_used + size > 65536) + if (tty->buf.memory_used + size > 64 * 1024) return NULL; p = kmalloc(sizeof(struct tty_buffer) + 2 * size, GFP_ATOMIC); if (p == NULL) @@ -415,6 +415,7 @@ static void flush_to_ldisc(struct work_struct *work) if (!test_and_set_bit(TTY_FLUSHING, &tty->flags)) { struct tty_buffer *head; while ((head = tty->buf.head) != NULL) { + int copied; int count; char *char_buf; unsigned char *flag_buf; @@ -436,15 +437,13 @@ static void flush_to_ldisc(struct work_struct *work) schedule_delayed_work(&tty->buf.work, 1); break; } - if (count > tty->receive_room) - count = tty->receive_room; char_buf = head->char_buf_ptr + head->read; flag_buf = head->flag_buf_ptr + head->read; - head->read += count; spin_unlock_irqrestore(&tty->buf.lock, flags); - disc->ops->receive_buf(tty, char_buf, + copied = disc->ops->receive_buf(tty, char_buf, flag_buf, count); spin_lock_irqsave(&tty->buf.lock, flags); + head->read += copied; } clear_bit(TTY_FLUSHING, &tty->flags); } diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c index 500e740..dcac880 100644 --- a/drivers/char/tty_ldisc.c +++ b/drivers/char/tty_ldisc.c @@ -598,13 +598,6 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) set_bit(TTY_LDISC_CHANGING, &tty->flags); - /* - * No more input please, we are switching. The new ldisc - * will update this value in the ldisc open function - */ - - tty->receive_room = 0; - o_ldisc = tty->ldisc; unlock_kernel(); diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index 6d34511..9dbb3e8 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c @@ -97,7 +97,6 @@ static int serport_ldisc_open(struct tty_struct *tty) init_waitqueue_head(&serport->wait); tty->disc_data = serport; - tty->receive_room = 256; set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); return 0; @@ -124,6 +123,7 @@ static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *c { struct serport *serport = (struct serport*) tty->disc_data; unsigned long flags; + unsigned bytes = 0; int i; spin_lock_irqsave(&serport->lock, flags); @@ -131,11 +131,15 @@ static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *c if (!test_bit(SERPORT_ACTIVE, &serport->flags)) goto out; - for (i = 0; i < count; i++) + for (i = 0; i < count; i++) { serio_interrupt(serport->serio, cp[i], 0); + bytes++; + } out: spin_unlock_irqrestore(&serport->lock, flags); + + return bytes; } /* diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c index 168d585..3b81ef4 100644 --- a/drivers/isdn/gigaset/ser-gigaset.c +++ b/drivers/isdn/gigaset/ser-gigaset.c @@ -693,7 +693,7 @@ gigaset_tty_ioctl(struct tty_struct *tty, struct file *file, * cflags buffer containing error flags for received characters (ignored) * count number of received characters */ -static void +static unsigned int gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf, char *cflags, int count) { @@ -744,6 +744,8 @@ gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf, gig_dbg(DEBUG_INTR, "%s-->BH", __func__); gigaset_schedule_event(cs); cs_put(cs); + + return count; } /* diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 689b9bd..a39e5ba 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -455,7 +455,7 @@ out: * a block of 6pack data has been received, which can now be decapsulated * and sent on to some IP layer for further processing. */ -static void sixpack_receive_buf(struct tty_struct *tty, +static unsigned int sixpack_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) { struct sixpack *sp; @@ -486,6 +486,8 @@ static void sixpack_receive_buf(struct tty_struct *tty, sp_put(sp); tty_unthrottle(tty); + + return count < sizeof(buf) ? count : sizeof(buf); } /* @@ -659,7 +661,6 @@ static int sixpack_open(struct tty_struct *tty) /* Done. We have linked the TTY line to a channel. */ tty->disc_data = sp; - tty->receive_room = 65536; /* Now we're ready to register. */ if (register_netdev(dev)) diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 7db0a1c..cb78ce8 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -750,7 +750,6 @@ static int mkiss_open(struct tty_struct *tty) ax->tty = tty; tty->disc_data = ax; - tty->receive_room = 65535; tty_driver_flush_buffer(tty); @@ -922,8 +921,8 @@ static long mkiss_compat_ioctl(struct tty_struct *tty, struct file *file, * a block of data has been received, which can now be decapsulated * and sent on to the AX.25 layer for further processing. */ -static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) +static unsigned int mkiss_receive_buf(struct tty_struct *tty, + const unsigned char *cp, char *fp, int count) { struct mkiss *ax = mkiss_get(tty); @@ -951,6 +950,8 @@ static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp, mkiss_put(ax); tty_unthrottle(tty); + + return count; } /* diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index 20f9bc6..0bf62ff 100644 --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c @@ -215,8 +215,8 @@ static int irtty_do_write(struct sir_dev *dev, const unsigned char *ptr, size_t * usbserial: urb-complete-interrupt / softint */ -static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) +static unsigned int irtty_receive_buf(struct tty_struct *tty, + const unsigned char *cp, char *fp, int count) { struct sir_dev *dev; struct sirtty_cb *priv = tty->disc_data; @@ -246,6 +246,8 @@ static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp, } sirdev_receive(dev, cp, count); + + return count; } /* @@ -470,7 +472,6 @@ static int irtty_open(struct tty_struct *tty) dev->priv = priv; tty->disc_data = priv; - tty->receive_room = 65536; mutex_unlock(&irtty_mutex); diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c index 6a375ea..603f2d3 100644 --- a/drivers/net/ppp_async.c +++ b/drivers/net/ppp_async.c @@ -195,7 +195,6 @@ ppp_asynctty_open(struct tty_struct *tty) goto out_free; tty->disc_data = ap; - tty->receive_room = 65536; return 0; out_free: @@ -338,7 +337,7 @@ ppp_asynctty_poll(struct tty_struct *tty, struct file *file, poll_table *wait) } /* May sleep, don't call from interrupt level or with interrupts disabled */ -static void +static unsigned int ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf, char *cflags, int count) { @@ -354,6 +353,8 @@ ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf, tasklet_schedule(&ap->tsk); ap_put(ap); tty_unthrottle(tty); + + return count; } static void diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c index 3a13cec..9319ade 100644 --- a/drivers/net/ppp_synctty.c +++ b/drivers/net/ppp_synctty.c @@ -242,7 +242,6 @@ ppp_sync_open(struct tty_struct *tty) goto out_free; tty->disc_data = ap; - tty->receive_room = 65536; return 0; out_free: @@ -379,7 +378,7 @@ ppp_sync_poll(struct tty_struct *tty, struct file *file, poll_table *wait) } /* May sleep, don't call from interrupt level or with interrupts disabled */ -static void +static unsigned int ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf, char *cflags, int count) { @@ -395,6 +394,8 @@ ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf, tasklet_schedule(&ap->tsk); sp_put(ap); tty_unthrottle(tty); + + return count; } static void diff --git a/drivers/net/slip.c b/drivers/net/slip.c index ba5bbc5..285c7d9 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -668,8 +668,8 @@ static void sl_setup(struct net_device *dev) * in parallel */ -static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) +static unsigned int slip_receive_buf(struct tty_struct *tty, + const unsigned char *cp, char *fp, int count) { struct slip *sl = tty->disc_data; @@ -691,6 +691,8 @@ static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, #endif slip_unesc(sl, *cp++); } + + return count; } /************************************ @@ -850,7 +852,6 @@ static int slip_open(struct tty_struct *tty) /* Done. We have linked the TTY line to a channel. */ rtnl_unlock(); - tty->receive_room = 65536; /* We don't flow control */ return sl->dev->base_addr; err_free_bufs: diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index b9f520b..94b5170 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c @@ -523,7 +523,7 @@ static int x25_asy_close(struct net_device *dev) * and sent on to some IP layer for further processing. */ -static void x25_asy_receive_buf(struct tty_struct *tty, +static unsigned int x25_asy_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) { struct x25_asy *sl = tty->disc_data; @@ -542,6 +542,8 @@ static void x25_asy_receive_buf(struct tty_struct *tty, } x25_asy_unesc(sl, *cp++); } + + return count; } /* @@ -571,7 +573,6 @@ static int x25_asy_open_tty(struct tty_struct *tty) sl->tty = tty; tty->disc_data = sl; - tty->receive_room = 65536; tty_driver_flush_buffer(tty); tty_ldisc_flush(tty); diff --git a/drivers/staging/strip/strip.c b/drivers/staging/strip/strip.c index 698aade..17a553e 100644 --- a/drivers/staging/strip/strip.c +++ b/drivers/staging/strip/strip.c @@ -2262,8 +2262,8 @@ static void process_message(struct strip *strip_info) * and sent on to some IP layer for further processing. */ -static void strip_receive_buf(struct tty_struct *tty, const unsigned char *cp, - char *fp, int count) +static unsigned int strip_receive_buf(struct tty_struct *tty, + const unsigned char *cp, char *fp, int count) { struct strip *strip_info = tty->disc_data; const unsigned char *end = cp + count; @@ -2340,6 +2340,8 @@ static void strip_receive_buf(struct tty_struct *tty, const unsigned char *cp, cp++; } spin_unlock_bh(&strip_lock); + + return strip_info->sx_count; } @@ -2635,7 +2637,6 @@ static int strip_open(struct tty_struct *tty) strip_info->tty = tty; tty->disc_data = strip_info; - tty->receive_room = 65536; tty_driver_flush_buffer(tty); diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h index 526d66f..b62cff8 100644 --- a/include/linux/tty_ldisc.h +++ b/include/linux/tty_ldisc.h @@ -76,7 +76,7 @@ * tty device. It is solely the responsibility of the line * discipline to handle poll requests. * - * void (*receive_buf)(struct tty_struct *, const unsigned char *cp, + * unsigned int (*receive_buf)(struct tty_struct *, const unsigned char *cp, * char *fp, int count); * * This function is called by the low-level tty driver to send @@ -139,8 +139,8 @@ struct tty_ldisc_ops { /* * The following routines are called from below. */ - void (*receive_buf)(struct tty_struct *, const unsigned char *cp, - char *fp, int count); + unsigned int (*receive_buf)(struct tty_struct *, + const unsigned char *cp, char *fp, int count); void (*write_wakeup)(struct tty_struct *); void (*dcd_change)(struct tty_struct *, unsigned int, struct timespec *); -- 1.7.0.rc0.33.g7c3932 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html