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