From: Paul Fulghum <paulkf@microgate.com>
To: "Roland Caßebohm" <roland.cassebohm@VisionSystems.de>
Cc: linux-kernel <linux-kernel@vger.kernel.org>,
Alan Cox <alan@lxorguk.ukuu.org.uk>,
Russell King <rmk+lkml@arm.linux.org.uk>
Subject: Re: Serial driver hangs
Date: Fri, 01 Oct 2004 11:06:28 -0500 [thread overview]
Message-ID: <1096646788.2757.13.camel@deimos.microgate.com> (raw)
In-Reply-To: <200410011722.28877.roland.cassebohm@visionsystems.de>
On Fri, 2004-10-01 at 10:22, Roland Caßebohm wrote:
> Yes, I think you are right, if the system is to slow to fetch
> the data fast enough the buffer will be sometime full. And if
> it would be possible to use the second flip buffer then, this
> buffer would be full too sometime.
> It would just take a little longer till data got lost. But if
> I want that I could just make the buffers larger.
>
> ...
>
> I have just tested it, but unfortunately I've got a very bad
> result. :-( In my test case (2 port with 921600 baud) I get
> very much data loss.
Roland:
Can I impose on you to try the following patches?
The differences here are:
* don't call flush_to_ldisc() directly from ISR
* flush_to_ldisc() keeps flushing flip buffers until empty
These patches are for testing purposes only
and not intended for general use.
I would like to see how your high speed setup reacts.
Thanks in advance.
--
Paul Fulghum
paulkf@microgate.com
--- a/drivers/char/serial.c 2004-09-30 15:25:17.000000000 -0500
+++ b/drivers/char/serial.c 2004-10-01 10:42:33.000000000 -0500
@@ -572,9 +572,17 @@ static _INLINE_ void receive_chars(struc
icount = &info->state->icount;
do {
if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
- tty->flip.tqueue.routine((void *) tty);
- if (tty->flip.count >= TTY_FLIPBUF_SIZE)
- return; // if TTY_DONT_FLIP is set
+ /* no room in flip buffer, discard rx FIFO contents to clear IRQ
+ * *FIXME* Hardware with auto flow control
+ * would benefit from leaving the data in the FIFO and
+ * disabling the rx IRQ until space becomes available.
+ */
+ do {
+ serial_inp(info, UART_RX);
+ icount->overrun++;
+ *status = serial_inp(info, UART_LSR);
+ } while ((*status & UART_LSR_DR) && (max_count-- > 0));
+ return; // if TTY_DONT_FLIP is set
}
ch = serial_inp(info, UART_RX);
*tty->flip.char_buf_ptr = ch;
--- a/drivers/char/tty_io.c 2004-04-14 08:05:29.000000000 -0500
+++ b/drivers/char/tty_io.c 2004-10-01 10:49:45.000000000 -0500
@@ -1944,32 +1944,34 @@ static void flush_to_ldisc(void *private
int count;
unsigned long flags;
- if (test_bit(TTY_DONT_FLIP, &tty->flags)) {
- queue_task(&tty->flip.tqueue, &tq_timer);
- return;
- }
- if (tty->flip.buf_num) {
- cp = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
- fp = tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
- tty->flip.buf_num = 0;
-
- save_flags(flags); cli();
- tty->flip.char_buf_ptr = tty->flip.char_buf;
- tty->flip.flag_buf_ptr = tty->flip.flag_buf;
- } else {
- cp = tty->flip.char_buf;
- fp = tty->flip.flag_buf;
- tty->flip.buf_num = 1;
-
- save_flags(flags); cli();
- tty->flip.char_buf_ptr = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
- tty->flip.flag_buf_ptr = tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
- }
- count = tty->flip.count;
- tty->flip.count = 0;
- restore_flags(flags);
+ while(tty->flip.count) {
+ if (test_bit(TTY_DONT_FLIP, &tty->flags)) {
+ queue_task(&tty->flip.tqueue, &tq_timer);
+ return;
+ }
+ if (tty->flip.buf_num) {
+ cp = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
+ fp = tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
+ tty->flip.buf_num = 0;
+
+ save_flags(flags); cli();
+ tty->flip.char_buf_ptr = tty->flip.char_buf;
+ tty->flip.flag_buf_ptr = tty->flip.flag_buf;
+ } else {
+ cp = tty->flip.char_buf;
+ fp = tty->flip.flag_buf;
+ tty->flip.buf_num = 1;
+
+ save_flags(flags); cli();
+ tty->flip.char_buf_ptr = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
+ tty->flip.flag_buf_ptr = tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
+ }
+ count = tty->flip.count;
+ tty->flip.count = 0;
+ restore_flags(flags);
- tty->ldisc.receive_buf(tty, cp, fp, count);
+ tty->ldisc.receive_buf(tty, cp, fp, count);
+ }
}
/*
next prev parent reply other threads:[~2004-10-01 16:08 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-09-28 15:34 Serial driver hangs Roland Caßebohm
2004-09-28 21:10 ` Paul Fulghum
2004-09-28 21:16 ` Russell King
2004-09-28 23:03 ` Paul Fulghum
2004-09-28 22:12 ` Alan Cox
2004-09-29 1:12 ` Paul Fulghum
2004-09-29 13:09 ` Roland Caßebohm
2004-09-29 13:17 ` Paul Fulghum
2004-09-29 14:07 ` Roland Caßebohm
2004-09-29 14:25 ` Paul Fulghum
2004-09-30 16:16 ` Roland Caßebohm
2004-09-30 19:09 ` Paul Fulghum
2004-09-30 18:34 ` Alan Cox
2004-09-30 19:51 ` Paul Fulghum
2004-09-30 19:59 ` Russell King
2004-09-30 20:05 ` Paul Fulghum
2004-09-30 20:30 ` Paul Fulghum
2004-09-30 20:10 ` Alan Cox
2004-09-30 21:25 ` Paul Fulghum
2004-10-01 0:47 ` Paul Fulghum
2004-10-01 15:22 ` Roland Caßebohm
2004-10-01 16:06 ` Paul Fulghum [this message]
2004-10-01 20:13 ` Stuart MacDonald
2004-10-01 20:36 ` Paul Fulghum
2004-09-29 14:13 ` Paul Fulghum
2004-10-01 15:25 ` Roland Caßebohm
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=1096646788.2757.13.camel@deimos.microgate.com \
--to=paulkf@microgate.com \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=linux-kernel@vger.kernel.org \
--cc=rmk+lkml@arm.linux.org.uk \
--cc=roland.cassebohm@VisionSystems.de \
/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