All of lore.kernel.org
 help / color / mirror / Atom feed
From: Oliver Neukum <oneukum-IBi9RG/b67k@public.gmane.org>
To: Sven Brauch <mail-ITmcY+a7/CDoK6nBLMlh1Q@public.gmane.org>
Cc: linux-serial-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Peter Hurley
	<peter-WaGBZJeGNqdsbIuE7sb01tBPR1lH4CV8@public.gmane.org>
Subject: implement put_char() in cdc-acm
Date: Tue, 27 Oct 2015 16:07:59 +0100	[thread overview]
Message-ID: <1445958479.2043.6.camel@suse.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 211 bytes --]

Hi,

the theory that the lack of support for put_char() is a
major contributor to character loss in cdc-acm can be tested.
Sven, could you test the attached patch? It implements
the support.

	Regards
		Oliver


[-- Attachment #2: 0001-cdc-acm-implement-put_char-and-flush_chars.patch --]
[-- Type: text/x-patch, Size: 3292 bytes --]

From f3871a76d7e2876b0e6ad66aee91085ecf9b2785 Mon Sep 17 00:00:00 2001
From: Oliver Neukum <oneukum@suse.com>
Date: Wed, 21 Oct 2015 12:10:07 +0200
Subject: [PATCH] cdc-acm: implement put_char() and flush_chars()

This should cut down latencies and waste if the tty layer writes single bytes.

Signed-off-by: Oliver Neukum >oneukum@suse.com>
---
 drivers/usb/class/cdc-acm.c | 67 +++++++++++++++++++++++++++++++++++++++++++++
 drivers/usb/class/cdc-acm.h |  1 +
 2 files changed, 68 insertions(+)

diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index b30e742..1cb3124 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -712,9 +712,20 @@ static int acm_tty_write(struct tty_struct *tty,
 	}
 
 	if (acm->susp_count) {
+		if (acm->putbuffer) {
+			/* now to preserve order */
+			usb_anchor_urb(acm->putbuffer->urb, &acm->delayed);
+			acm->putbuffer = NULL;
+		}
 		usb_anchor_urb(wb->urb, &acm->delayed);
 		spin_unlock_irqrestore(&acm->write_lock, flags);
 		return count;
+	} else {
+		if (acm->putbuffer) {
+			/* at this point there is no good way to handle errors */
+			acm_start_wb(acm, acm->putbuffer);
+			acm->putbuffer = NULL;
+		}
 	}
 
 	stat = acm_start_wb(acm, wb);
@@ -725,6 +736,60 @@ static int acm_tty_write(struct tty_struct *tty,
 	return count;
 }
 
+static void acm_tty_flush_chars(struct tty_struct *tty)
+{
+	struct acm *acm = tty->driver_data;
+	struct acm_wb *cur = acm->putbuffer;
+	int err;
+	unsigned long flags;
+
+	acm->putbuffer = NULL;
+	err = usb_autopm_get_interface_async(acm->control);
+	spin_lock_irqsave(&acm->write_lock, flags);
+	if (err < 0) {
+		cur->use = 0;
+		goto out;
+	}
+
+	if (acm->susp_count)
+		usb_anchor_urb(cur->urb, &acm->delayed);
+	else
+		acm_start_wb(acm, cur);
+out:
+	spin_unlock_irqrestore(&acm->write_lock, flags);
+	return;
+}
+
+static int acm_tty_put_char(struct tty_struct *tty, unsigned char ch)
+{
+	struct acm *acm = tty->driver_data;
+	struct acm_wb *cur;
+	int wbn;
+	unsigned long flags;
+
+overflow:
+	cur = acm->putbuffer;
+	if (!cur) {
+		spin_lock_irqsave(&acm->write_lock, flags);
+		wbn = acm_wb_alloc(acm);
+		if (wbn >= 0) {
+			cur = &acm->wb[wbn];
+			acm->putbuffer = cur;
+		}
+		spin_unlock_irqrestore(&acm->write_lock, flags);
+		if (!cur)
+			return 0;
+	}
+
+	if (cur->len == acm->writesize) {
+		acm_tty_flush_chars(tty);
+		goto overflow;
+	}
+
+	cur->buf[cur->len++] = ch;
+	return 1;
+}
+
 static int acm_tty_write_room(struct tty_struct *tty)
 {
 	struct acm *acm = tty->driver_data;
@@ -1888,6 +1953,8 @@ static const struct tty_operations acm_ops = {
 	.cleanup =		acm_tty_cleanup,
 	.hangup =		acm_tty_hangup,
 	.write =		acm_tty_write,
+	.put_char =		acm_tty_put_char,
+	.flush_chars =		acm_tty_flush_chars,
 	.write_room =		acm_tty_write_room,
 	.ioctl =		acm_tty_ioctl,
 	.throttle =		acm_tty_throttle,
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h
index dd9af38..648a6f7 100644
--- a/drivers/usb/class/cdc-acm.h
+++ b/drivers/usb/class/cdc-acm.h
@@ -94,6 +94,7 @@ struct acm {
 	unsigned long read_urbs_free;
 	struct urb *read_urbs[ACM_NR];
 	struct acm_rb read_buffers[ACM_NR];
+	struct acm_wb *putbuffer;			/* for acm_tty_put_char() */
 	int rx_buflimit;
 	int rx_endpoint;
 	spinlock_t read_lock;
-- 
2.1.4


             reply	other threads:[~2015-10-27 15:07 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-27 15:07 Oliver Neukum [this message]
     [not found] ` <1445958479.2043.6.camel-IBi9RG/b67k@public.gmane.org>
2015-10-27 15:45   ` implement put_char() in cdc-acm Sven Brauch
     [not found]     ` <562F9C08.6050105-ITmcY+a7/CDoK6nBLMlh1Q@public.gmane.org>
2015-10-28 11:04       ` Oliver Neukum
     [not found]         ` <1446030280.15140.10.camel-IBi9RG/b67k@public.gmane.org>
2015-10-28 12:23           ` Peter Hurley
     [not found]             ` <5630BE5E.6040204-WaGBZJeGNqdsbIuE7sb01tBPR1lH4CV8@public.gmane.org>
2015-10-28 12:33               ` Oliver Neukum
     [not found]                 ` <1446035622.15140.17.camel-IBi9RG/b67k@public.gmane.org>
2015-10-28 12:49                   ` Peter Hurley
2015-11-01 19:28                   ` Sven Brauch
     [not found]                     ` <563667D9.9080401-ITmcY+a7/CDoK6nBLMlh1Q@public.gmane.org>
2015-11-01 19:59                       ` Peter Hurley
     [not found]                         ` <56366F19.90202-WaGBZJeGNqdsbIuE7sb01tBPR1lH4CV8@public.gmane.org>
2015-11-01 20:04                           ` Sven Brauch
2015-11-02 11:32                       ` Oliver Neukum
     [not found]                         ` <1446463972.25345.24.camel-IBi9RG/b67k@public.gmane.org>
2015-11-02 20:27                           ` Sven Brauch
     [not found]                             ` <5637C731.20409-ITmcY+a7/CDoK6nBLMlh1Q@public.gmane.org>
2015-11-03  8:58                               ` Oliver Neukum
     [not found]                                 ` <1446541094.27681.2.camel-IBi9RG/b67k@public.gmane.org>
2015-11-03 10:13                                   ` Sven Brauch
     [not found]                                     ` <563888BB.2080601-ITmcY+a7/CDoK6nBLMlh1Q@public.gmane.org>
2015-11-03 10:19                                       ` Oliver Neukum
2015-11-05  4:18                           ` Peter Hurley
2015-10-28 15:53               ` Sven Brauch
     [not found]                 ` <5630EF8A.8060904-ITmcY+a7/CDoK6nBLMlh1Q@public.gmane.org>
2015-10-28 16:20                   ` Peter Hurley
2015-10-28 16:23                   ` Oliver Neukum

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1445958479.2043.6.camel@suse.com \
    --to=oneukum-ibi9rg/b67k@public.gmane.org \
    --cc=linux-serial-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=mail-ITmcY+a7/CDoK6nBLMlh1Q@public.gmane.org \
    --cc=peter-WaGBZJeGNqdsbIuE7sb01tBPR1lH4CV8@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.