Author: marcel
Date: Mon May 18 22:45:09 2009
New Revision: 192352
URL: http://svn.freebsd.org/changeset/base/192352

Log:
  MFC r190834:
  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

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/ath/ath_hal/   (props changed)
  stable/7/sys/dev/cxgb/   (props changed)
  stable/7/sys/dev/uart/uart_dev_ns8250.c

Modified: stable/7/sys/dev/uart/uart_dev_ns8250.c
==============================================================================
--- stable/7/sys/dev/uart/uart_dev_ns8250.c     Mon May 18 22:34:44 2009        
(r192351)
+++ stable/7/sys/dev/uart/uart_dev_ns8250.c     Mon May 18 22:45:09 2009        
(r192352)
@@ -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);
@@ -563,7 +565,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)
@@ -571,12 +572,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);
 }
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to