From 44ed791b92a2d5a5a2ec7dceeaac65e9749a8eda Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Wed, 17 Sep 2003 03:11:32 +0000 Subject: In uart_intr() loop until all interrupts have been handled. Previously an UART interface could get stuck when a new interrupt condition arose while servicing a previous interrupt. Since an interrupt was already pending, no new interrupt would be triggered. Avoid infinite recursion by flushing the Rx FIFO and marking an overrun condition when we could not move the data from the Rx FIFO to the receive buffer in toto. Failure to flush the Rx FIFO would leave the Rx ready condition pending. Note that the SAB 82532 already did this due to the nature of the chip. --- sys/dev/uart/uart_core.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'sys/dev/uart/uart_core.c') diff --git a/sys/dev/uart/uart_core.c b/sys/dev/uart/uart_core.c index dd4f91cd4a125..5889211c0dbf1 100644 --- a/sys/dev/uart/uart_core.c +++ b/sys/dev/uart/uart_core.c @@ -200,17 +200,21 @@ uart_intr(void *arg) if (sc->sc_leaving) return; - ipend = UART_IPEND(sc); - if (ipend & UART_IPEND_OVERRUN) - uart_intr_overrun(sc); - if (ipend & UART_IPEND_BREAK) - uart_intr_break(sc); - if (ipend & UART_IPEND_RXREADY) - uart_intr_rxready(sc); - if (ipend & UART_IPEND_SIGCHG) - uart_intr_sigchg(sc); - if (ipend & UART_IPEND_TXIDLE) - uart_intr_txidle(sc); + do { + ipend = UART_IPEND(sc); + if (ipend == 0) + break; + if (ipend & UART_IPEND_OVERRUN) + uart_intr_overrun(sc); + if (ipend & UART_IPEND_BREAK) + uart_intr_break(sc); + if (ipend & UART_IPEND_RXREADY) + uart_intr_rxready(sc); + if (ipend & UART_IPEND_SIGCHG) + uart_intr_sigchg(sc); + if (ipend & UART_IPEND_TXIDLE) + uart_intr_txidle(sc); + } while (1); if (sc->sc_opened && sc->sc_ttypend != 0) swi_sched(sc->sc_softih, 0); -- cgit v1.3