From: David Newall <davidn@davidnewall.com>
To: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Greg KH <greg@kroah.com>,
linux-usb@vger.kernel.org,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: Handshaking on USB serial devices
Date: Fri, 15 Feb 2008 04:34:36 +1030 [thread overview]
Message-ID: <47B482B4.9010208@davidnewall.com> (raw)
In-Reply-To: <20080214121026.16a9c510@core>
Alan Cox wrote:
>> To make it clear: Even aside from the buffer in 2.6's pl2303.c, there's
>> a race: An in-flight write URB can fill all hardware buffers, making
>> unsafe what previously appeared to be a safe write. I think it's
>> essential to delay submission of the URB on a stop-transmit condition.
>>
>
> Hardware flow control *is* a race, and always will be. The remote end has
> a delay in signalling 'stop' there is a propogation delay and a response
> delay. This is why most implementations assert stop a bit *before* they
> run out.
>
That's a very good point. Even so: on the 2.4 driver, write_room isn't
implemented (refer to a previous message by Alan); and in 2.6, a 1k
buffer is built into the driver, with nothing to prevent it being sent
when the hardware buffer fills. These could be bugs in the two versions
of pl2303, if you like; in fact I suppose they are; but there's a wider
problem: The same weakness can be found in aircable.c, airprime.c,
cyberjack.c, cypress_m8.c (I think), empeg.c, ftdi_sio (I think),
io_ti.c, and that's where I stop checking, and declare it's widespread.
> Given the size of transfers and the internal buffering one would hope the
> USB devices do their own flow control if told to properly.
>
RS232 is (normally) so much slower than USB that, on an extended
transmission, the buffer internal to the local hardware can fill well
before the remote device has demanded that transmission stop. In fact,
now that you've mentioned it, I can't see that anything to stop the
driver from overflowing the internal buffer, which is very perplexing.
Would that be right? That seems a pretty dramatic weakness; how do you
write a large report to a slow printer without losing data?
I'm beginning to realise that overflowing the internal buffer is the
greatest risk of data loss. Hardware flow control almost seems
serendipitous. It gives us a reason to stop submitting bulk writes.
This is the essence of the change that I looking at for pl2303.c.
(Patch relative to kernel 2.6.23.14.) Does it make sense?
--- pl2303.c 2008-01-15 07:19:56.000000000 +1030
+++ pl2303.c.new 2008-02-15 04:22:12.000000000 +1030
@@ -370,6 +370,18 @@
spin_lock_irqsave(&priv->lock, flags);
+ /*
+ * there's a limit to how much we can buffer, so don't accept data while
+ * CTS or DSR are low. XXX I don't know what to do about XON/XOFF.
+ */
+ if ((priv->line_control | CONTROL_RTS && !(priv->line_status & UART_CTS)) || \
+ (priv->line_control | CONTROL_DTR && !(priv->line_status & UART_DSR))) {
+ /*
+ spin_unlock_irqrestore(&priv->lock, flags);
+ dbg("%s: send paused by remote flow control", __FUNCTION__);
+ return;
+ }
+
if (priv->write_urb_in_use) {
spin_unlock_irqrestore(&priv->lock, flags);
return;
@@ -957,6 +969,9 @@
pl2303_update_line_status(port, data, actual_length);
+ /* send any buffered data */
+ pl2303_send(port);
+
exit:
retval = usb_submit_urb(urb, GFP_ATOMIC);
if (retval)
next prev parent reply other threads:[~2008-02-14 18:05 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-02-13 14:45 Handshaking on USB serial devices David Newall
2008-02-14 5:02 ` Greg KH
2008-02-14 9:25 ` David Newall
2008-02-14 12:10 ` Alan Cox
2008-02-14 16:16 ` Gene Heskett
2008-02-14 16:31 ` Alan Cox
2008-02-14 17:55 ` Gene Heskett
2008-02-14 19:37 ` Alan Cox
2008-02-14 20:04 ` Gene Heskett
2008-02-14 20:52 ` Greg KH
2008-02-14 21:32 ` Gene Heskett
2008-02-15 5:08 ` David Newall
2008-02-14 22:39 ` Krzysztof Halasa
2008-02-14 23:09 ` Gene Heskett
2008-02-14 18:04 ` David Newall [this message]
2008-02-14 18:53 ` David Brownell
2008-02-14 19:36 ` Alan Cox
2008-02-21 15:22 ` David Newall
2008-02-21 15:15 ` Alan Cox
2008-02-21 19:35 ` David Newall
2008-02-21 20:58 ` Greg KH
2008-02-14 20:47 ` Greg KH
2008-02-15 5:19 ` David Newall
2008-02-14 11:55 ` Alan Cox
[not found] <9Wr5Z-7cw-1@gated-at.bofh.it>
[not found] ` <9WSJ4-222-21@gated-at.bofh.it>
[not found] ` <9WTlN-2T0-7@gated-at.bofh.it>
[not found] ` <9WTYn-3Zb-29@gated-at.bofh.it>
2008-02-15 12:00 ` Bodo Eggert
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=47B482B4.9010208@davidnewall.com \
--to=davidn@davidnewall.com \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=greg@kroah.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox