svn commit: r190834 - head/sys/dev/uart
Marcel Moolenaar
marcel at FreeBSD.org
Tue Apr 7 17:14:07 PDT 2009
Author: marcel
Date: Wed Apr 8 00:14:06 2009
New Revision: 190834
URL: http://svn.freebsd.org/changeset/base/190834
Log:
Fix hangs caused by hardware that signals receive errors
(framing, parity, etc), but does not indicate characters
being received. Since no chracters have been received,
ignore the line errors.
PR: 131006
MFC after: 3 days
Modified:
head/sys/dev/uart/uart_dev_ns8250.c
Modified: head/sys/dev/uart/uart_dev_ns8250.c
==============================================================================
--- head/sys/dev/uart/uart_dev_ns8250.c Tue Apr 7 22:26:53 2009 (r190833)
+++ head/sys/dev/uart/uart_dev_ns8250.c Wed Apr 8 00:14:06 2009 (r190834)
@@ -50,14 +50,16 @@ __FBSDID("$FreeBSD$");
static void
ns8250_clrint(struct uart_bas *bas)
{
- uint8_t iir;
+ uint8_t iir, lsr;
iir = uart_getreg(bas, REG_IIR);
while ((iir & IIR_NOPEND) == 0) {
iir &= IIR_IMASK;
- if (iir == IIR_RLS)
- (void)uart_getreg(bas, REG_LSR);
- else if (iir == IIR_RXRDY || iir == IIR_RXTOUT)
+ if (iir == IIR_RLS) {
+ lsr = uart_getreg(bas, REG_LSR);
+ if (lsr & (LSR_BI|LSR_FE|LSR_PE))
+ (void)uart_getreg(bas, REG_DATA);
+ } else if (iir == IIR_RXRDY || iir == IIR_RXTOUT)
(void)uart_getreg(bas, REG_DATA);
else if (iir == IIR_MLSC)
(void)uart_getreg(bas, REG_MSR);
@@ -587,7 +589,6 @@ ns8250_bus_ipend(struct uart_softc *sc)
ipend = 0;
if (iir & IIR_RXRDY) {
lsr = uart_getreg(bas, REG_LSR);
- uart_unlock(sc->sc_hwmtx);
if (lsr & LSR_OE)
ipend |= SER_INT_OVERRUN;
if (lsr & LSR_BI)
@@ -595,12 +596,14 @@ ns8250_bus_ipend(struct uart_softc *sc)
if (lsr & LSR_RXRDY)
ipend |= SER_INT_RXREADY;
} else {
- uart_unlock(sc->sc_hwmtx);
if (iir & IIR_TXRDY)
ipend |= SER_INT_TXIDLE;
else
ipend |= SER_INT_SIGCHG;
}
+ if (ipend == 0)
+ ns8250_clrint(bas);
+ uart_unlock(sc->sc_hwmtx);
return ((sc->sc_leaving) ? 0 : ipend);
}
More information about the svn-src-head
mailing list