serial port data THRE comes too early

Bug #1086745 reported by Kees Schoenmakers
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
QEMU
Expired
Undecided
Unassigned

Bug Description

When using a serial port with a Linux guest (and host) and the application uses hardware handshake, this fails because the handling of TEMT and/or THRE is not operating properly in such cases.

As long as it takes _time_ for the 'real' port to output the data TEMT may not return true. After writing characters to a real port, the driver should timeout the transmission and after the total time expired, TEMT can be set.

Some applications i.e. with a simplex modem do: RTS_on, WRITE_data, repeat IOCTL(GET_LSR_INFO), RTS_off, READ_data.
At the moment this fails because very early in the transmission, GET_LSR_INFO returns true and the modem transmitter is switched off.

I looked in the source (git) and found that 'char_transmit_time' is present. My skills fail to implement it myself.
I build and ran the latest git version and found it to fail as decribed above. I hope someone can solve it.

Revision history for this message
Lei Li (matrixs-zero) wrote :

Could you please give more details, like the steps to reproduce this problems.

Thanks.

Revision history for this message
Kees Schoenmakers (kslinux) wrote : TEMT comes too early (QEMU/KVM)

Hello,

It is a Linux host and a Linux guest. One serial port (/dev/ttyS0) is
passed from the host to the guest.

The application (on the guest) does Hart (r) communication, This is
done with a 1200 baud simplex modem (one side at a time).

The application raises RTS so that the modem goes in transmit state,
it writes a couple of bytes. Only after _all_ bytes are written in
reality the RTS is to be de-activated which puts the modem in receive
state. Normally a loop like

int parm =0;

while (!parm)
       ioctl(devicefd,TIOCSERGETLSR , &parm);

is executed, The loop exits when parm is not zero (TEMT is set);

The current implementation of TIOCSERGETLSR only checks fifo count
which is nowhere a accurate way of checking if the device in the host
has written all its characters, thus the function
ioctl(devicefd,TIOCSERGETLSR , &parm) returns parms set already when
the second character is transmitted and thus the whole communication
cycle is disrupted.

One possible solution is having ioctl(.... TIOCSERGETLSR ...) in the
guest to check the result of ioctl(..... TIOCSERGETLSR....) in the
host. Another way is timing of the transmission, that is for each
character written the guest needs to add the charactertime to a timer
and only when the timer timesout TEMT is to be set.

does this help to understand the problem?

best regards

Kees

Revision history for this message
Kees Schoenmakers (kslinux) wrote : Re: [Bug 1086745] Re: serial port data THRE comes too early

Hello,

I have attached 2 scope shots, SCR0002.BMP shows a failing
communication cycle, the upper trace is the RTS signal on the port,
the lower trace shows the databytes wriiten.
SCR00004.BMP show how it had to be, RTS is active during the whole databytes.

In general an application will issue ioctl(<fdn>,TOICSERGETLSR,
&<bits>) and continue as soon as the 'bits' are set. Thus for this to
work the ioctl call should _only_ return 'bits' set if the _real
hardware_ has written the bytes.

Kees

On 12/5/12, Lei Li <email address hidden> wrote:
> Could you please give more details, like the steps to reproduce this
> problems.
>
> Thanks.
>
> --
> You received this bug notification because you are subscribed to the bug
> report.
> https://bugs.launchpad.net/bugs/1086745
>
> Title:
> serial port data THRE comes too early
>
> Status in QEMU:
> New
>
> Bug description:
> When using a serial port with a Linux guest (and host) and the
> application uses hardware handshake, this fails because the handling
> of TEMT and/or THRE is not operating properly in such cases.
>
> As long as it takes _time_ for the 'real' port to output the data TEMT
> may not return true. After writing characters to a real port, the
> driver should timeout the transmission and after the total time
> expired, TEMT can be set.
>
> Some applications i.e. with a simplex modem do: RTS_on, WRITE_data, repeat
> IOCTL(GET_LSR_INFO), RTS_off, READ_data.
> At the moment this fails because very early in the transmission,
> GET_LSR_INFO returns true and the modem transmitter is switched off.
>
> I looked in the source (git) and found that 'char_transmit_time' is
> present. My skills fail to implement it myself.
> I build and ran the latest git version and found it to fail as decribed
> above. I hope someone can solve it.
>
> To manage notifications about this bug go to:
> https://bugs.launchpad.net/qemu/+bug/1086745/+subscriptions
>

Revision history for this message
Koen Hendrix (koen-hendrix) wrote :
Revision history for this message
Kees Schoenmakers (kslinux) wrote :

Hello Friend,

I don't think so. He is referring to a normal modem with an AT command
set not responding
to incoming call, which is probably a setup issue.

I am referring to how the _hardware handshake_ signals from the guest
environment are passed to the host.

best regards

Kees

On 12/9/12, Koen Hendrix <email address hidden> wrote:
> could this be related? https://bugs.launchpad.net/ubuntu/+bug/1087519
>
> --
> You received this bug notification because you are subscribed to the bug
> report.
> https://bugs.launchpad.net/bugs/1086745
>
> Title:
> serial port data THRE comes too early
>
> Status in QEMU:
> New
>
> Bug description:
> When using a serial port with a Linux guest (and host) and the
> application uses hardware handshake, this fails because the handling
> of TEMT and/or THRE is not operating properly in such cases.
>
> As long as it takes _time_ for the 'real' port to output the data TEMT
> may not return true. After writing characters to a real port, the
> driver should timeout the transmission and after the total time
> expired, TEMT can be set.
>
> Some applications i.e. with a simplex modem do: RTS_on, WRITE_data, repeat
> IOCTL(GET_LSR_INFO), RTS_off, READ_data.
> At the moment this fails because very early in the transmission,
> GET_LSR_INFO returns true and the modem transmitter is switched off.
>
> I looked in the source (git) and found that 'char_transmit_time' is
> present. My skills fail to implement it myself.
> I build and ran the latest git version and found it to fail as decribed
> above. I hope someone can solve it.
>
> To manage notifications about this bug go to:
> https://bugs.launchpad.net/qemu/+bug/1086745/+subscriptions
>

Revision history for this message
Koen Hendrix (koen-hendrix) wrote :

>I don't think so. He is referring to a normal modem with an AT command
>set not responding
>to incoming call, which is probably a setup issue.
no. please read further on; i described another oddity in the same bugreport.

>I am referring to how the _hardware handshake_ signals from the guest
>environment are passed to the host.
you used a hardware scope. so you used real serial ports: one controlled by the host, one by qemu. what is the difference? in either instance, there is at least one native linux kernel involved in the handshake.

disregard this if i'm talking nonsense.

Revision history for this message
Kees Schoenmakers (kslinux) wrote :

Hello,

The scope traces that I sent are from 2 sources yes, the one with the
'short' RTS time is taken when the port was driven by the (Linux)
guest .

The trace with the correct RTS length was taken when the port was
driven by the (Linux) host.

Both times the same application. I looked in the sources for QEMU and
I am believing that the functionality of the ioctl(..., TIOCSERGETLSR
...) is not returning the correct status of the guest+host port.

I will look to the report again anyway.

best regards

Kees

On 12/9/12, Koen Hendrix <email address hidden> wrote:
>>I don't think so. He is referring to a normal modem with an AT command
>>set not responding
>>to incoming call, which is probably a setup issue.
> no. please read further on; i described another oddity in the same
> bugreport.
>
>>I am referring to how the _hardware handshake_ signals from the guest
>>environment are passed to the host.
> you used a hardware scope. so you used real serial ports: one controlled by
> the host, one by qemu. what is the difference? in either instance, there is
> at least one native linux kernel involved in the handshake.
>
> disregard this if i'm talking nonsense.
>
> --
> You received this bug notification because you are subscribed to the bug
> report.
> https://bugs.launchpad.net/bugs/1086745
>
> Title:
> serial port data THRE comes too early
>
> Status in QEMU:
> New
>
> Bug description:
> When using a serial port with a Linux guest (and host) and the
> application uses hardware handshake, this fails because the handling
> of TEMT and/or THRE is not operating properly in such cases.
>
> As long as it takes _time_ for the 'real' port to output the data TEMT
> may not return true. After writing characters to a real port, the
> driver should timeout the transmission and after the total time
> expired, TEMT can be set.
>
> Some applications i.e. with a simplex modem do: RTS_on, WRITE_data, repeat
> IOCTL(GET_LSR_INFO), RTS_off, READ_data.
> At the moment this fails because very early in the transmission,
> GET_LSR_INFO returns true and the modem transmitter is switched off.
>
> I looked in the source (git) and found that 'char_transmit_time' is
> present. My skills fail to implement it myself.
> I build and ran the latest git version and found it to fail as decribed
> above. I hope someone can solve it.
>
> To manage notifications about this bug go to:
> https://bugs.launchpad.net/qemu/+bug/1086745/+subscriptions
>

Revision history for this message
Thomas Huth (th-huth) wrote :

Triaging old bug tickets... can you still reproduce this issue with the latest version of QEMU? Or could we close this ticket nowadays?

Changed in qemu:
status: New → Incomplete
Revision history for this message
Launchpad Janitor (janitor) wrote :

[Expired for QEMU because there has been no activity for 60 days.]

Changed in qemu:
status: Incomplete → Expired
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.