serial: clean up THRE/TEMT handling
commit0d931d706266d6ada3bf22d3afca1afdc8d12fa9
authorPaolo Bonzini <pbonzini@redhat.com>
Thu, 11 Dec 2014 16:01:39 +0000 (11 17:01 +0100)
committerPaolo Bonzini <pbonzini@redhat.com>
Mon, 15 Dec 2014 16:33:37 +0000 (15 17:33 +0100)
treeeb8d029396abfd3e5aa647d6bc76fec993dcc0bb
parent4e02b0fcf5c97579d0d3261c80c65abcf92870fe
serial: clean up THRE/TEMT handling

- assert TEMT is cleared before sending a character; we'll get one from
TSR if tsr_retry > 0, from the FIFO or THR otherwise

- assert THRE cleared and FIFO not empty (if enabled) before fetching a
character to send.  This effectively reverts dffacd46, but the check
makes no sense and commit f702e62 (serial: change retry logic to avoid
concurrency, 2014-07-11) must have made it unnecessary.  The commit
message for f702e62 talks about multiple calls to qemu_chr_fe_add_watch
triggering s->tsr_retry >= MAX_XMIT_RETRY, but other failures were
possible.  For example, if you have multiple calls, the subsequent ones
will see s->tsr_retry == 0 and will find THRE and/or TEMT on entry.

- for clarity, raise THRI immediately after the code sets THRE

- check THRE to see if another character has to be sent.  This makes
the assertions more obvious and also means TEMT has to be set as soon as
the loop ends.  It makes the loop send both TSR and THR if flow-control
happens in non-FIFO mode.  Previously, THR would be lost.

- clear TEMT together with THRE even in the non-FIFO case

The last two items are bugfixes, but they were just found by inspection
and do not squash known bugs.

Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
hw/char/serial.c