All of lore.kernel.org
 help / color / mirror / Atom feed
* How to disable the transmit FIFO?
@ 2010-11-18  9:15 Michael Haardt
  2010-11-18 16:41 ` Greg KH
  0 siblings, 1 reply; 10+ messages in thread
From: Michael Haardt @ 2010-11-18  9:15 UTC (permalink / raw)
  To: linux-serial

Hello,

I miss a way to disable the transmit FIFO.

UARTs that don't do hardware handshaking in hardware, but use a transmit
FIFO, can only be used if the peer can deal with the delayed handshaking
response.

If slow peers can not receive at line rate, hardware handshaking will
still cause overruns with Linux as sender, because Linux fills the
transmit FIFO and transmission continues at worst for 16 characters with
a 16550 after CTS was asserted.

So, how can I fix hardware flow control response to the non-delayed
behaviour as it worked with a 8250 or 16450 by disabling the transmit
FIFO?

Michael

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How to disable the transmit FIFO?
  2010-11-18  9:15 How to disable the transmit FIFO? Michael Haardt
@ 2010-11-18 16:41 ` Greg KH
  2010-11-18 20:01   ` Michael Haardt
  0 siblings, 1 reply; 10+ messages in thread
From: Greg KH @ 2010-11-18 16:41 UTC (permalink / raw)
  To: Michael Haardt; +Cc: linux-serial

On Thu, Nov 18, 2010 at 10:15:43AM +0100, Michael Haardt wrote:
> Hello,
> 
> I miss a way to disable the transmit FIFO.

>From userspace or from within a kernel driver?

> UARTs that don't do hardware handshaking in hardware, but use a transmit
> FIFO, can only be used if the peer can deal with the delayed handshaking
> response.
> 
> If slow peers can not receive at line rate, hardware handshaking will
> still cause overruns with Linux as sender, because Linux fills the
> transmit FIFO and transmission continues at worst for 16 characters with
> a 16550 after CTS was asserted.
> 
> So, how can I fix hardware flow control response to the non-delayed
> behaviour as it worked with a 8250 or 16450 by disabling the transmit
> FIFO?

So you are saying this used to work and now it doesn't?

confused,

greg k-h

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How to disable the transmit FIFO?
  2010-11-18 16:41 ` Greg KH
@ 2010-11-18 20:01   ` Michael Haardt
  2010-11-18 20:05     ` Grant Edwards
  2010-11-18 20:11     ` Greg KH
  0 siblings, 2 replies; 10+ messages in thread
From: Michael Haardt @ 2010-11-18 20:01 UTC (permalink / raw)
  To: greg; +Cc: linux-serial

> > I miss a way to disable the transmit FIFO.
>
> From userspace or from within a kernel driver?

>From userspace.

> > UARTs that don't do hardware handshaking in hardware, but use a transmit
> > FIFO, can only be used if the peer can deal with the delayed handshaking
> > response.
> > 
> > If slow peers can not receive at line rate, hardware handshaking will
> > still cause overruns with Linux as sender, because Linux fills the
> > transmit FIFO and transmission continues at worst for 16 characters with
> > a 16550 after CTS was asserted.
> > 
> > So, how can I fix hardware flow control response to the non-delayed
> > behaviour as it worked with a 8250 or 16450 by disabling the transmit
> > FIFO?
>
> So you are saying this used to work and now it doesn't?

It used to work with old non-FIFO UARTs (8250, 16450) and does not work
with the slightly newer FIFO-UARTs (16550 and up, probably excluding
those that can do RTS/CTS flow control in hardware).

A transmitter FIFO on a UART that can not do RTS/CTS flow control in
hardware delays the flow control response by the size of the FIFO.
By the time Linux notices CTS being set, the FIFO is already filled and
the transmitter keeps sending, despite the peer asking to pause.

It is desirable that flow control has minimal delays from seeing CTS
to pausing the flow.  Given a 16550 UART, you have to disable the
transmitter FIFO for that.  One could argue whether the default should
be high throughput (use the FIFO and delay handshaking) or correct flow
control (no FIFO and near instant handshaking).  Most systems default
to the first.

The admin has to know if the peer allows delayed flow control and
configure it for the affected UART ports.  Windows allows exactly that
and the MS knowledge base correctly describes that the FIFO size may
cause data overruns, suggesting to reduce it until the problem goes away.
A binary switch, as offered by BSD, probably suffices, though.

Michael

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How to disable the transmit FIFO?
  2010-11-18 20:01   ` Michael Haardt
@ 2010-11-18 20:05     ` Grant Edwards
  2010-11-19  1:25       ` Ted Ts'o
  2010-11-18 20:11     ` Greg KH
  1 sibling, 1 reply; 10+ messages in thread
From: Grant Edwards @ 2010-11-18 20:05 UTC (permalink / raw)
  To: linux-serial

On 2010-11-18, Michael Haardt <michael@moria.de> wrote:
>> > I miss a way to disable the transmit FIFO.
>>
>> From userspace or from within a kernel driver?
>
> From userspace.

$ man setserial

-- 
Grant Edwards               grant.b.edwards        Yow! FEELINGS are cascading
                                  at               over me!!!
                              gmail.com            


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How to disable the transmit FIFO?
  2010-11-18 20:01   ` Michael Haardt
  2010-11-18 20:05     ` Grant Edwards
@ 2010-11-18 20:11     ` Greg KH
  2010-11-18 20:58       ` Michael Haardt
  1 sibling, 1 reply; 10+ messages in thread
From: Greg KH @ 2010-11-18 20:11 UTC (permalink / raw)
  To: Michael Haardt; +Cc: linux-serial

On Thu, Nov 18, 2010 at 09:01:45PM +0100, Michael Haardt wrote:
> > > I miss a way to disable the transmit FIFO.
> >
> > From userspace or from within a kernel driver?
> 
> >From userspace.
> 
> > > UARTs that don't do hardware handshaking in hardware, but use a transmit
> > > FIFO, can only be used if the peer can deal with the delayed handshaking
> > > response.
> > > 
> > > If slow peers can not receive at line rate, hardware handshaking will
> > > still cause overruns with Linux as sender, because Linux fills the
> > > transmit FIFO and transmission continues at worst for 16 characters with
> > > a 16550 after CTS was asserted.
> > > 
> > > So, how can I fix hardware flow control response to the non-delayed
> > > behaviour as it worked with a 8250 or 16450 by disabling the transmit
> > > FIFO?
> >
> > So you are saying this used to work and now it doesn't?
> 
> It used to work with old non-FIFO UARTs (8250, 16450) and does not work
> with the slightly newer FIFO-UARTs (16550 and up, probably excluding
> those that can do RTS/CTS flow control in hardware).

It also breaks down massively with usb to serial devices where the delay
is a lot bigger :)

> A transmitter FIFO on a UART that can not do RTS/CTS flow control in
> hardware delays the flow control response by the size of the FIFO.
> By the time Linux notices CTS being set, the FIFO is already filled and
> the transmitter keeps sending, despite the peer asking to pause.
> 
> It is desirable that flow control has minimal delays from seeing CTS
> to pausing the flow.  Given a 16550 UART, you have to disable the
> transmitter FIFO for that.  One could argue whether the default should
> be high throughput (use the FIFO and delay handshaking) or correct flow
> control (no FIFO and near instant handshaking).  Most systems default
> to the first.
> 
> The admin has to know if the peer allows delayed flow control and
> configure it for the affected UART ports.  Windows allows exactly that
> and the MS knowledge base correctly describes that the FIFO size may
> cause data overruns, suggesting to reduce it until the problem goes away.
> A binary switch, as offered by BSD, probably suffices, though.

What is the BSD user/kernel api that they have to provide this?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How to disable the transmit FIFO?
  2010-11-18 20:11     ` Greg KH
@ 2010-11-18 20:58       ` Michael Haardt
  0 siblings, 0 replies; 10+ messages in thread
From: Michael Haardt @ 2010-11-18 20:58 UTC (permalink / raw)
  To: greg; +Cc: linux-serial

> What is the BSD user/kernel api that they have to provide this?

BSD uses port-specific driver flags, so changing them requires a
reboot.

>From sio(4):

     For standard ISA ports:
	   device sio

	   In /boot/device.hints:
	   hint.sio.0.at="isa"
	   hint.sio.0.port="0x3f8"
	   hint.sio.0.flags="0x10"
	   hint.sio.0.irq="4"
	   hint.sio.1.at="isa"
	   hint.sio.1.port="0x2f8"
	   hint.sio.1.flags="0x0"
	   hint.sio.1.irq="3"
[...]
     Meaning of flags:
	   0x00001   shared IRQs
	   0x00002   disable FIFO
[...]

It is important that the setting is port-specific, not global.

Michael

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How to disable the transmit FIFO?
  2010-11-18 20:05     ` Grant Edwards
@ 2010-11-19  1:25       ` Ted Ts'o
  2010-11-19  4:31         ` Grant Edwards
  2010-11-24 12:47         ` Michael Haardt
  0 siblings, 2 replies; 10+ messages in thread
From: Ted Ts'o @ 2010-11-19  1:25 UTC (permalink / raw)
  To: Grant Edwards, Michael Haardt; +Cc: linux-serial

On Thu, Nov 18, 2010 at 08:05:56PM +0000, Grant Edwards wrote:
> On 2010-11-18, Michael Haardt <michael@moria.de> wrote:
> >> > I miss a way to disable the transmit FIFO.
> >>
> >> From userspace or from within a kernel driver?
> >
> > From userspace.
> 
> $ man setserial

Specifically, if you use setserial to configure a serial port so that
its UART is a 16450, it will force the transmit FIFO to be unused.

    	      	     	     	   - Ted

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How to disable the transmit FIFO?
  2010-11-19  1:25       ` Ted Ts'o
@ 2010-11-19  4:31         ` Grant Edwards
  2010-11-24 12:47         ` Michael Haardt
  1 sibling, 0 replies; 10+ messages in thread
From: Grant Edwards @ 2010-11-19  4:31 UTC (permalink / raw)
  To: Ted Ts'o; +Cc: Michael Haardt, linux-serial

On Thu, Nov 18, 2010 at 08:25:23PM -0500, Ted Ts'o wrote:
> On Thu, Nov 18, 2010 at 08:05:56PM +0000, Grant Edwards wrote:
> > On 2010-11-18, Michael Haardt <michael@moria.de> wrote:
> > >> > I miss a way to disable the transmit FIFO.
> > >>
> > >> From userspace or from within a kernel driver?
> > >
> > > From userspace.
> > 
> > $ man setserial
> 
> Specifically, if you use setserial to configure a serial port so that
> its UART is a 16450, it will force the transmit FIFO to be unused.

You can also leave the UART type as 16[56]50 and set the tx fifo
threshold to 1.  That way you're only taking half the hit on interrupt
overhead.

-- 
Grant

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How to disable the transmit FIFO?
  2010-11-19  1:25       ` Ted Ts'o
  2010-11-19  4:31         ` Grant Edwards
@ 2010-11-24 12:47         ` Michael Haardt
  2010-11-24 14:56           ` Grant Edwards
  1 sibling, 1 reply; 10+ messages in thread
From: Michael Haardt @ 2010-11-24 12:47 UTC (permalink / raw)
  To: tytso, grant.b.edwards; +Cc: linux-serial

> Specifically, if you use setserial to configure a serial port so that
> its UART is a 16450, it will force the transmit FIFO to be unused.

I tried that, but no change.  Sending a line of 21 characters to the port,
I see only two trailing edges of CTS, which is consistent with receiving
three characters by the SBC.  The other characters are sent and lost.

The SBC on the other end clears RTS immediatly after receiving a
character.  Linux may send one character at this moment, but that would
be stored in the receiver buffer and the SBC only asserts RTS if the
receiver buffer is empty.  Instead it sends multiple characters, flooding
the SBC.

Michael

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: How to disable the transmit FIFO?
  2010-11-24 12:47         ` Michael Haardt
@ 2010-11-24 14:56           ` Grant Edwards
  0 siblings, 0 replies; 10+ messages in thread
From: Grant Edwards @ 2010-11-24 14:56 UTC (permalink / raw)
  To: linux-serial

On 2010-11-24, Michael Haardt <michael@moria.de> wrote:
>> Specifically, if you use setserial to configure a serial port so that
>> its UART is a 16450, it will force the transmit FIFO to be unused.
>
> I tried that, but no change.  Sending a line of 21 characters to the port,
> I see only two trailing edges of CTS, which is consistent with receiving
> three characters by the SBC.  The other characters are sent and lost.
>
> The SBC on the other end clears RTS immediatly after receiving a
> character.  Linux may send one character at this moment, but that would
> be stored in the receiver buffer and the SBC only asserts RTS if the
> receiver buffer is empty.  Instead it sends multiple characters, flooding
> the SBC.

But the Linux box does eventually stop sending, but it takes too long
to stop?

It sounds like you need to buy a serial card that does RTS/CTS flow
control in hardware.

-- 
Grant Edwards               grant.b.edwards        Yow! This PORCUPINE knows
                                  at               his ZIPCODE ... And he has
                              gmail.com            "VISA"!!


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2010-11-24 14:57 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-18  9:15 How to disable the transmit FIFO? Michael Haardt
2010-11-18 16:41 ` Greg KH
2010-11-18 20:01   ` Michael Haardt
2010-11-18 20:05     ` Grant Edwards
2010-11-19  1:25       ` Ted Ts'o
2010-11-19  4:31         ` Grant Edwards
2010-11-24 12:47         ` Michael Haardt
2010-11-24 14:56           ` Grant Edwards
2010-11-18 20:11     ` Greg KH
2010-11-18 20:58       ` Michael Haardt

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.