All of lore.kernel.org
 help / color / mirror / Atom feed
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);
+	}
 }
 
 /*



  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 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.