PERFORCE change 35114 for review
Marcel Moolenaar
marcel at FreeBSD.org
Sun Jul 27 19:18:38 PDT 2003
http://perforce.freebsd.org/chv.cgi?CH=35114
Change 35114 by marcel at marcel_nfs on 2003/07/27 19:17:34
o Make sure UART is the console before we compare resources.
This avoid false positives.
o Set sc_leaving until we're completely attached. This allows
spurous interrupts to be short-circuited.
o UART_IPEND is expected to return 0 when sc_leaving is set.
By still calling UART_IPEND, hardware drivers can do whatever
is required to avoid a lockup by clearing the interrupt source.
o Improve the ns8250 driver WRT interrupts.
Affected files ...
.. //depot/projects/uart/dev/uart/uart_core.c#11 edit
.. //depot/projects/uart/dev/uart/uart_dev_ns8250.c#11 edit
Differences ...
==== //depot/projects/uart/dev/uart/uart_core.c#11 (text+ko) ====
@@ -241,9 +241,6 @@
struct uart_softc *sc = arg;
int ipend;
- if (sc->sc_leaving)
- return;
-
ipend = UART_IPEND(sc);
if (ipend & UART_IPEND_OVERRUN)
uart_intr_overrun(sc);
@@ -255,6 +252,7 @@
uart_intr_sigchg(sc);
if (ipend & UART_IPEND_TXIDLE)
uart_intr_txidle(sc);
+
if (sc->sc_ttypend != 0)
swi_sched(sc->sc_softih, 0);
}
@@ -310,7 +308,8 @@
sc->sc_bas.regshft = regshft;
sc->sc_bas.rclk = (rclk == 0) ? sc->sc_class->uc_rclk : rclk;
- if (uart_cpu_eqres(&sc->sc_bas, &uart_console.bas)) {
+ if (uart_console.consdev != NULL &&
+ uart_cpu_eqres(&sc->sc_bas, &uart_console.bas)) {
sc->sc_console = 1;
/* XXX check if ops matches class. */
}
@@ -346,6 +345,13 @@
device_set_softc(dev, sc);
/*
+ * Protect ourselves against interrupts while we're not completely
+ * finished attaching and initializing. We don't expect interrupts
+ * until after UART_ATTACH() though.
+ */
+ sc->sc_leaving = 1;
+
+ /*
* Re-allocate. We expect that the softc contains the information
* collected by uart_bus_probe() intact.
*/
@@ -441,6 +447,7 @@
swi_add(&tty_ithd, uart_driver_name, uart_tty_intr, sc, SWI_TTY,
INTR_TYPE_TTY, &sc->sc_softih);
+ sc->sc_leaving = 0;
return (0);
fail:
==== //depot/projects/uart/dev/uart/uart_dev_ns8250.c#11 (text+ko) ====
@@ -370,14 +370,18 @@
ns8250->lcr = uart_getreg(bas, REG_LCR);
ns8250->fcr = FCR_ENABLE | FCR_RX_MEDL;
uart_setreg(bas, REG_FCR, ns8250->fcr);
- uart_setreg(bas, REG_IER,
- IER_ERXRDY | IER_ETXRDY | IER_ERLS | IER_EMSC);
uart_barrier(bas);
+ ns8250_flush(bas, UART_FLUSH_RECEIVER|UART_FLUSH_TRANSMITTER);
if (ns8250->mcr & MCR_DTR)
ns8250->signals |= UART_SIG_DTR;
if (ns8250->mcr & MCR_RTS)
ns8250->signals |= UART_SIG_RTS;
ns8250_bus_getsig(sc);
+
+ uart_setreg(bas, REG_IER,
+ IER_ERXRDY | IER_ETXRDY | IER_ERLS | IER_EMSC);
+ uart_barrier(bas);
+
return (0);
}
@@ -433,14 +437,16 @@
ipend |= UART_IPEND_BREAK;
if (lsr & LSR_RXRDY)
ipend |= UART_IPEND_RXREADY;
- if (lsr & LSR_TEMT)
+ if (lsr & LSR_TEMT) {
+ (void)uart_getreg(bas, REG_IIR);
ipend |= UART_IPEND_TXIDLE;
+ }
sig = ns8250_bus_getsig(sc);
if (sig & UART_SIGMASK_DELTA) {
ns8250->signals = sig; /* restore delta bits. */
ipend |= UART_IPEND_SIGCHG;
}
- return (ipend);
+ return ((sc->sc_leaving) ? 0 : ipend);
}
static int
More information about the p4-projects
mailing list