Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 19 Aug 2003 01:38:16 -0700 (PDT)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 36400 for review
Message-ID:  <200308190838.h7J8cG8W083946@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=36400

Change 36400 by marcel@marcel_nfs on 2003/08/19 01:37:51

	Keep track if the device is opened with sc_opened. This
	mirrors (tp->t_state & TS_ISOPEN). Sprinkle KASSERTs to
	make sure this is actually the case.
	Properly implement {ALT_|}BREAK_TO_DEBUGGER. We need to
	include the option headers for example.
	Don't let processes change the console speed for now.
	We need to come up with something that works well and
	isn't as silly as sio(4).
	Also force CLOCAL and HUPCL for the console.
	Create device uart%r (the dialout device) with mods 660,
	user uucp and group dialer. This is what sio(4) does as
	well.
	Some tweaks that I need to look at more closely.

Affected files ...

.. //depot/projects/uart/dev/uart/uart_bus.h#14 edit
.. //depot/projects/uart/dev/uart/uart_core.c#18 edit

Differences ...

==== //depot/projects/uart/dev/uart/uart_bus.h#14 (text+ko) ====

@@ -102,9 +102,12 @@
 	int		sc_fastintr:1;	/* This UART uses fast interrupts. */
 	int		sc_hasfifo:1;	/* This UART has FIFOs. */
 	int		sc_leaving:1;	/* This UART is going away. */
+	int		sc_opened:1;	/* This UART is open for business. */
 	int		sc_polled:1;	/* This UART has no interrupts. */
 	int		sc_txbusy:1;	/* This UART is transmitting. */
 
+	int		sc_altbrk;	/* State for alt break sequence. */
+
 	/* Receiver data. */
 	uint16_t	*sc_rxbuf;
 	int		sc_rxbufsz;

==== //depot/projects/uart/dev/uart/uart_core.c#18 (text+ko) ====

@@ -27,6 +27,9 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include "opt_comconsole.h"
+#include "opt_ddb.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/bus.h>
@@ -44,6 +47,8 @@
 #include <machine/resource.h>
 #include <machine/stdarg.h>
 
+#include <ddb/ddb.h>
+
 #include <dev/uart/uart.h>
 #include <dev/uart/uart_bus.h>
 #include <dev/uart/uart_cpu.h>
@@ -83,6 +88,17 @@
 	sc = tp->t_dev->si_drv1;
 	if (sc == NULL || sc->sc_leaving)
 		return;
+
+	if (tp->t_state & TS_TBLOCK)
+		UART_SETSIG(sc, UART_SIG_DRTS);
+	else
+		UART_SETSIG(sc, UART_SIG_DRTS|UART_SIG_RTS);
+
+	if (tp->t_state & (TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) {
+		ttwwakeup(tp);
+		return;
+	}
+
 	if (tp->t_outq.c_cc > 0 && !sc->sc_txbusy) {
 		sc->sc_txdatasz = q_to_b(&tp->t_outq, sc->sc_txbuf,
 		    sc->sc_txfifosz);
@@ -104,6 +120,9 @@
 		return (ENODEV);
 	if (t->c_ispeed != t->c_ospeed && t->c_ospeed != 0)
 		return (EINVAL);
+	/* Hardwire the console speed. */
+	if (sc->sc_console)
+		t->c_ispeed = t->c_ospeed = uart_console.baudrate;
 	if (t->c_ospeed == 0) {
 		UART_SETSIG(sc, UART_SIG_DDTR | UART_SIG_DRTS);
 		return (0);
@@ -125,6 +144,10 @@
 	if ((t->c_cflag & CRTS_IFLOW) == 0)
 		UART_SETSIG(sc, UART_SIG_DRTS | UART_SIG_RTS);
 	ttsetwater(tp);
+	if (sc->sc_console) {
+		tp->t_cflag |= CLOCAL;
+		tp->t_cflag &= ~HUPCL;
+	}
 	return (0);
 }
 
@@ -196,15 +219,20 @@
 static void
 uart_intr_break(struct uart_softc *sc)
 {
+
 #if defined(DDB) && defined(BREAK_TO_DEBUGGER)
-	breakpoint();
-#else
+	if (sc->sc_console || sc->sc_dbgport) {
+		breakpoint();
+		return;
+	}
+#endif
+	if (!sc->sc_opened)
+		return;
 	if (sc->sc_tty == NULL || sc->sc_tty->t_iflag & IGNBRK)
 		return;
 	if (uart_rx_put(sc, UART_STAT_BREAK))
 		sc->sc_rxbuf[sc->sc_rxput] |= UART_STAT_BREAK;
 	atomic_set_32(&sc->sc_ttypend, UART_IPEND_RXREADY);
-#endif
 }
 
 /*
@@ -225,11 +253,14 @@
 static void
 uart_intr_overrun(struct uart_softc *sc)
 {
-	UART_RECEIVE(sc);
+
+	if (sc->sc_opened) {
+		UART_RECEIVE(sc);
+		if (uart_rx_put(sc, UART_STAT_OVERRUN))
+			sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
+		atomic_set_32(&sc->sc_ttypend, UART_IPEND_RXREADY);
+	}
 	UART_FLUSH(sc, UART_FLUSH_RECEIVER);
-	if (uart_rx_put(sc, UART_STAT_OVERRUN))
-		sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
-	atomic_set_32(&sc->sc_ttypend, UART_IPEND_RXREADY);
 }
 
 /*
@@ -238,8 +269,24 @@
 static void
 uart_intr_rxready(struct uart_softc *sc)
 {
+	int rxp;
+
+	rxp = sc->sc_rxput;
 	UART_RECEIVE(sc);
-	atomic_set_32(&sc->sc_ttypend, UART_IPEND_RXREADY);
+#if defined(DDB) && defined(ALT_BREAK_TO_DEBUGGER)
+	if (sc->sc_console || sc->sc_dbgport) {
+		while (rxp != sc->sc_rxput) {
+			if (db_alt_break(sc->sc_rxbuf[rxp++], &sc->sc_altbrk))
+				breakpoint();
+			if (rxp == sc->sc_rxbufsz)
+				rxp = 0;
+		}
+	}
+#endif
+	if (sc->sc_opened)
+		atomic_set_32(&sc->sc_ttypend, UART_IPEND_RXREADY);
+	else
+		sc->sc_rxput = sc->sc_rxget;	/* Ignore received data. */
 }
 
 /*
@@ -274,6 +321,9 @@
 	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);
@@ -286,7 +336,7 @@
 	if (ipend & UART_IPEND_TXIDLE)
 		uart_intr_txidle(sc);
 
-	if (sc->sc_ttypend != 0)
+	if (sc->sc_opened && sc->sc_ttypend != 0)
 		swi_sched(sc->sc_softih, 0);
 }
 
@@ -465,8 +515,8 @@
 	sc->sc_si[0]->si_drv1 = sc;
 	sc->sc_si[0]->si_tty = tp;
 	sc->sc_si[1] = make_dev(&uart_cdevsw,
-	    device_get_unit(sc->sc_dev) | UART_MINOR_CALLOUT, UID_ROOT,
-	    GID_WHEEL, 0600, "uart%r", device_get_unit(sc->sc_dev));
+	    device_get_unit(sc->sc_dev) | UART_MINOR_CALLOUT, UID_UUCP,
+	    GID_DIALER, 0660, "uart%r", device_get_unit(sc->sc_dev));
 	sc->sc_si[1]->si_drv1 = sc;
 	sc->sc_si[1]->si_tty = tp;
 
@@ -483,6 +533,7 @@
 	    INTR_TYPE_TTY, &sc->sc_softih);
 
 	sc->sc_leaving = 0;
+	uart_intr(sc);
 	return (0);
 
  fail:
@@ -507,13 +558,13 @@
 
 	sc->sc_leaving = 1;
 
+	UART_DETACH(sc);
+
 	ithread_remove_handler(sc->sc_softih);
 	destroy_dev(sc->sc_si[0]);
 	destroy_dev(sc->sc_si[1]);
 	/* ttyfree(sc->sc_tty); */
 
-	UART_DETACH(sc);
-
 	free(sc->sc_txbuf, M_UART);
 	free(sc->sc_rxbuf, M_UART);
 
@@ -541,7 +592,8 @@
 	tp = dev->si_tty;
 
  loop:
-	if (tp->t_state & TS_ISOPEN) {
+	if (sc->sc_opened) {
+		KASSERT(tp->t_state & TS_ISOPEN, ("foo"));
 		/*
 		 * The device is open, so everything has been initialized.
 		 * Handle conflicts.
@@ -554,17 +606,18 @@
 				if (flags & O_NONBLOCK)
 					return (EBUSY);
 				error =	tsleep(sc, TTIPRI|PCATCH, "uartbi", 0);
+				if (error)
+					return (error);
 				sc = dev->si_drv1;
 				if (sc == NULL || sc->sc_leaving)
 					return (ENODEV);
-				if (error)
-					return (error);
 				goto loop;
 			}
 		}
 		if (tp->t_state & TS_XCLUDE && suser(td) != 0)
 			return (EBUSY);
 	} else {
+		KASSERT(!(tp->t_state & TS_ISOPEN), ("foo"));
 		/*
 		 * The device isn't open, so there are no conflicts.
 		 * Initialize it.  Initialization is done twice in many
@@ -578,11 +631,9 @@
 		tp->t_iflag = TTYDEF_IFLAG;
 		tp->t_lflag = TTYDEF_LFLAG;
 		tp->t_oflag = TTYDEF_OFLAG;
-		if (sc->sc_console) {
-			tp->t_cflag |= CLOCAL;
-			tp->t_cflag &= ~HUPCL;
+		if (sc->sc_console)
 			tp->t_ispeed = tp->t_ospeed = uart_console.baudrate;
-		} else
+		else
 			tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
 		ttychars(tp);
 		error = uart_tty_param(tp, &tp->t_termios);
@@ -600,17 +651,23 @@
 	if (!(tp->t_state & TS_CARR_ON) && !sc->sc_callout &&
 	    !(tp->t_cflag & CLOCAL) && !(flags & O_NONBLOCK)) {
 		error = tsleep(TSA_CARR_ON(tp), TTIPRI|PCATCH, "uartdcd", 0);
+		if (error)
+			return (error);
 		sc = dev->si_drv1;
 		if (sc == NULL || sc->sc_leaving)
 			return (ENODEV);
-		if (error)
-			return (error);
 		goto loop;
 	}
 	error = ttyopen(dev, tp);
-	if (!error)
-		error = (*linesw[tp->t_line].l_open)(dev, tp);
-	return (error);
+	if (error)
+		return (error);
+	error = (*linesw[tp->t_line].l_open)(dev, tp);
+	if (error)
+		return (error);
+
+	KASSERT(tp->t_state & TS_ISOPEN, ("foo"));
+	sc->sc_opened = 1;
+	return (0);
 }
 
 static int
@@ -622,10 +679,12 @@
 	sc = dev->si_drv1;
 	if (sc == NULL || sc->sc_leaving)
 		return (ENODEV);
-
 	tp = dev->si_tty;
-	if (!(tp->t_state & TS_ISOPEN))
+	if (!sc->sc_opened) {
+		KASSERT(!(tp->t_state & TS_ISOPEN), ("foo"));
 		return (0);
+	}
+	KASSERT(tp->t_state & TS_ISOPEN, ("foo"));
 
 	if (!sc->sc_console)
 		UART_SETSIG(sc, UART_SIG_DDTR | UART_SIG_DRTS);
@@ -634,6 +693,8 @@
 	ttyclose(tp);
 	wakeup(sc);
 	wakeup(TSA_CARR_ON(tp));
+	KASSERT(!(tp->t_state & TS_ISOPEN), ("foo"));
+	sc->sc_opened = 0;
 	return (0);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200308190838.h7J8cG8W083946>