summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Crosthwaite <peter.crosthwaite@xilinx.com>2014-01-06 10:16:39 +0000
committerPeter Maydell <peter.maydell@linaro.org>2014-01-08 19:07:21 +0000
commitd0ac820fe4152ea3a57fc3fa9f732cc9524017a4 (patch)
tree49684cdbdf08799f393e242cd221712f446e1d03 /hw
parent2152e08ad12180f307bc5b838134ab745767d2e5 (diff)
downloadqemu-d0ac820fe4152ea3a57fc3fa9f732cc9524017a4.tar.gz
qemu-d0ac820fe4152ea3a57fc3fa9f732cc9524017a4.tar.bz2
qemu-d0ac820fe4152ea3a57fc3fa9f732cc9524017a4.zip
char/cadence_uart: Fix can_receive logic
The can_receive logic was only taking into account the RxFIFO occupancy. RxFIFO population is only used for the echo and normal modes however. Improve the logic to correctly return the true number of receivable characters based on the current mode: Normal mode: RxFIFO vacancy. Remote loopback: TxFIFO vacancy. Echo mode: The min of the TxFIFO and RxFIFO vacancies. Local Loopback: Return non-zero (to implement droppage) Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com> Message-id: 36a58440c9ca5080151e95765c2c81342de8a8df.1388626249.git.peter.crosthwaite@xilinx.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/char/cadence_uart.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
index 3eeadb18fd..3bcaf2905d 100644
--- a/hw/char/cadence_uart.c
+++ b/hw/char/cadence_uart.c
@@ -233,8 +233,16 @@ static void uart_parameters_setup(UartState *s)
static int uart_can_receive(void *opaque)
{
UartState *s = (UartState *)opaque;
+ int ret = MAX(RX_FIFO_SIZE, TX_FIFO_SIZE);
+ uint32_t ch_mode = s->r[R_MR] & UART_MR_CHMODE;
- return RX_FIFO_SIZE - s->rx_count;
+ if (ch_mode == NORMAL_MODE || ch_mode == ECHO_MODE) {
+ ret = MIN(ret, RX_FIFO_SIZE - s->rx_count);
+ }
+ if (ch_mode == REMOTE_LOOPBACK || ch_mode == ECHO_MODE) {
+ ret = MIN(ret, TX_FIFO_SIZE - s->tx_count);
+ }
+ return ret;
}
static void uart_ctrl_update(UartState *s)