PERFORCE change 37036 for review

Marcel Moolenaar marcel at FreeBSD.org
Wed Aug 27 13:03:13 PDT 2003


http://perforce.freebsd.org/chv.cgi?CH=37036

Change 37036 by marcel at marcel_nfs on 2003/08/27 13:02:20

	Introduce the notion of a system device as a way to abstract
	consoles, keyboards and debug ports. Key in this is the use
	of the already existent struct devinfo to represent a system
	device. It roughly works like this:
	o  Some low-level probing, possibly unknown to uart(4) itself
	   results in the creation of a devinfo structure, the details
	   of which vary per system device, architecture or setup. The
	   active system devices are put on an SLIST. An example can
	   be found in uart_tty.c where the system console is created.
	o  During bus enumeration when we probe the UART, we walk over
	   the SLIST to see if the current UART is also a system device
	   and update the sc_sysdev pointer in the softc to reflect
	   this.
	o  The devinfo structure contains 2 function pointers: attach
	   and detach that can be used to setup (and teardown) a high-
	   level interface other than TTY. For a keyboard you probably
	   want a kbd device with different ioctls than for a generic
	   TTY device.
	
	NOTE: the sc_console, sc_dbgport and sc_keyboard bit flags
	are gone and replaced by a type field in the devinfo structure.
	This means that a console cannot also serve as a debug port
	for example. This may eventually be a problem. However, before
	we can allow "doubling" we need to solve some structural
	problems first. The limitation is therefore real. For example:
	If both the console and the dbgport have attach functions,
	how do you handle that? Both will create a SWI, what's up with
	that?
	
	Liked by: jake

Affected files ...

.. //depot/projects/uart/dev/uart/uart_bus.h#19 edit
.. //depot/projects/uart/dev/uart/uart_core.c#25 edit
.. //depot/projects/uart/dev/uart/uart_cpu.h#5 edit
.. //depot/projects/uart/dev/uart/uart_dev_ns8250.c#21 edit
.. //depot/projects/uart/dev/uart/uart_dev_sab82532.c#17 edit
.. //depot/projects/uart/dev/uart/uart_tty.c#7 edit

Differences ...

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

@@ -105,16 +105,15 @@
 	int		sc_irid;
 
 	int		sc_callout:1;	/* This UART is opened for callout. */
-	int		sc_console:1;	/* This UART is a console. */
-	int		sc_dbgport:1;	/* This UART is a debug port. */
 	int		sc_fastintr:1;	/* This UART uses fast interrupts. */
 	int		sc_hasfifo:1;	/* This UART has FIFOs. */
-	int		sc_keyboard:1;	/* This UART is a keyboard. */
 	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. */
 
+	struct uart_devinfo *sc_sysdev;	/* System device (or NULL). */
+
 	int		sc_altbrk;	/* State for alt break sequence. */
 	int		sc_hwsig;	/* Signal state. Used by HW driver. */
 

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

@@ -41,6 +41,7 @@
 #include <sys/interrupt.h>
 #include <sys/kernel.h>
 #include <sys/malloc.h>
+#include <sys/queue.h>
 #include <sys/reboot.h>
 #include <machine/bus.h>
 #include <sys/rman.h>
@@ -60,8 +61,17 @@
 devclass_t uart_devclass;
 char uart_driver_name[] = "uart";
 
+SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs =
+    SLIST_HEAD_INITIALIZER(uart_sysdevs);
+
 MALLOC_DEFINE(M_UART, "UART", "UART driver");
 
+void
+uart_add_sysdev(struct uart_devinfo *di)
+{
+	SLIST_INSERT_HEAD(&uart_sysdevs, di, next);
+}
+
 /*
  * A break condition has been detected. We treat the break condition as
  * a special case that should not happen during normal operation. When
@@ -76,7 +86,7 @@
 {
 
 #if defined(DDB) && defined(BREAK_TO_DEBUGGER)
-	if (sc->sc_console || sc->sc_dbgport) {
+	if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
 		breakpoint();
 		return;
 	}
@@ -124,7 +134,7 @@
 	rxp = sc->sc_rxput;
 	UART_RECEIVE(sc);
 #if defined(DDB) && defined(ALT_BREAK_TO_DEBUGGER)
-	if (sc->sc_console || sc->sc_dbgport) {
+	if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
 		while (rxp != sc->sc_rxput) {
 			if (db_alt_break(sc->sc_rxbuf[rxp++], &sc->sc_altbrk))
 				breakpoint();
@@ -201,6 +211,7 @@
 uart_bus_probe(device_t dev, int regshft, int rclk, int rid)
 {
 	struct uart_softc *sc;
+	struct uart_devinfo *sysdev;
 	int error;
 
 	/*
@@ -248,21 +259,13 @@
 	sc->sc_bas.regshft = regshft;
 	sc->sc_bas.rclk = (rclk == 0) ? sc->sc_class->uc_rclk : rclk;
 
-	if (uart_console.consdev != NULL &&
-	    uart_cpu_eqres(&sc->sc_bas, &uart_console.bas)) {
-		sc->sc_console = 1;
-		/* XXX check if ops matches class. */
-	}
-#if NOTYET
-	if (uart_cpu_eqres(&sc->sc_bas, &uart_dbgport.bas)) {
-		sc->sc_dbgport = 1;
-		/* XXX check if ops matches class. */
+	SLIST_FOREACH(sysdev, &uart_sysdevs, next) {
+		if (uart_cpu_eqres(&sc->sc_bas, &sysdev->bas)) {
+			/* XXX check if ops matches class. */
+			sc->sc_sysdev = sysdev;
+			break;
+		}
 	}
-	if (uart_cpu_eqres(&sc->sc_bas, &uart_keyboard.bas)) {
-		sc->sc_keyboard = 1;
-		/* XXX check if ops matches class. */
-	}
-#endif
 
 	error = UART_PROBE(sc);
 	bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres);
@@ -342,22 +345,21 @@
 	if (error)
 		goto fail;
 
-	if (sc->sc_console || sc->sc_dbgport || sc->sc_keyboard) {
-		sep = "";
-		device_print_prettyname(dev);
-		if (sc->sc_console) {
-			printf("%sconsole", sep);
-			sep = ", ";
-		}
-		if (sc->sc_dbgport) {
-			printf("%sdebug port", sep);
-			sep = ", ";
-		}
-		if (sc->sc_keyboard) {
-			printf("%skeyboard", sep);
-			sep = ", ";
+	if (sc->sc_sysdev != NULL) {
+		switch (sc->sc_sysdev->type) {
+		case UART_DEV_CONSOLE:
+			device_printf(dev, "console\n");
+			break;
+		case UART_DEV_DBGPORT:
+			device_printf(dev, "debug port\n");
+			break;
+		case UART_DEV_KEYBOARD:
+			device_printf(dev, "keyboard\n");
+			break;
+		default:
+			device_printf(dev, "unknown system device\n");
+			break;
 		}
-		printf("\n");
 	}
 
 	if (bootverbose && (sc->sc_fastintr || sc->sc_polled)) {
@@ -374,11 +376,8 @@
 		printf("\n");
 	}
 
-	if (sc->sc_keyboard) {
-		/* Keyboard specific attachment. */
-	} else
-		error = uart_tty_attach(sc);
-
+	error = (sc->sc_sysdev != NULL && sc->sc_sysdev->attach != NULL)
+	    ? (*sc->sc_sysdev->attach)(sc) : uart_tty_attach(sc);
 	if (error)
 		goto fail;
 
@@ -411,9 +410,9 @@
 
 	UART_DETACH(sc);
 
-	if (sc->sc_keyboard) {
-		/* Keyboard specific detachment. */
-	} else
+	if (sc->sc_sysdev != NULL && sc->sc_sysdev->detach != NULL)
+		(*sc->sc_sysdev->detach)(sc);
+	else
 		uart_tty_detach(sc);
 
 	free(sc->sc_txbuf, M_UART);

==== //depot/projects/uart/dev/uart/uart_cpu.h#5 (text+ko) ====

@@ -47,27 +47,29 @@
 /*
  * Console and debug port device info.
  */
+struct uart_softc;
 struct uart_devinfo {
+	SLIST_ENTRY(uart_devinfo) next;
 	struct uart_ops ops;
 	struct uart_bas bas;
 	int	baudrate;
 	int	databits;
 	int	stopbits;
 	int	parity;
-	void	*consdev;		/* Yedi trick. See uart_cons.c */
-};
-
-extern struct uart_devinfo uart_console;
-extern struct uart_devinfo uart_dbgport;
-extern struct uart_devinfo uart_keyboard;
-
+	int	type;
 #define	UART_DEV_CONSOLE	0
 #define	UART_DEV_DBGPORT	1
 #define	UART_DEV_KEYBOARD	2
+	int	(*attach)(struct uart_softc*);
+	int	(*detach)(struct uart_softc*);
+	void	*consdev;		/* Yedi trick. See uart_cons.c */
+};
 
 int uart_cpu_getdev(int devtype, struct uart_devinfo *di);
 int uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2);
 
+void uart_add_sysdev(struct uart_devinfo*);
+
 /*
  * Operations for low-level access to the UART. Primarily for use
  * by console and debug port logic.

==== //depot/projects/uart/dev/uart/uart_dev_ns8250.c#21 (text+ko) ====

@@ -507,7 +507,7 @@
 		return (error);
 
 	mcr = MCR_IENABLE;
-	if (!sc->sc_console && !sc->sc_dbgport && !sc->sc_keyboard) {
+	if (sc->sc_sysdev == NULL) {
 		/* By using ns8250_init() we also set DTR and RTS. */
 		ns8250_init(bas, 9600, 8, 1, UART_PARITY_NONE);
 	} else

==== //depot/projects/uart/dev/uart/uart_dev_sab82532.c#17 (text+ko) ====

@@ -383,7 +383,7 @@
 	uint8_t imr0, imr1;
 
 	bas = &sc->sc_bas;
-	if (!sc->sc_console && !sc->sc_dbgport && !sc->sc_keyboard)
+	if (sc->sc_sysdev == NULL)
 		sab82532_init(bas, 9600, 8, 1, UART_PARITY_NONE);
 
 	sc->sc_rxfifosz = 32;

==== //depot/projects/uart/dev/uart/uart_tty.c#7 (text+ko) ====

@@ -79,7 +79,7 @@
 	.d_kqfilter = ttykqfilter,
 };
 
-struct uart_devinfo uart_console = { .consdev = NULL };
+struct uart_devinfo uart_console;
 
 static void
 uart_cnprobe(struct consdev *cp)
@@ -93,7 +93,7 @@
 	if (uart_cpu_getdev(UART_DEV_CONSOLE, &uart_console))
 		return;
 
-	if (uart_console.ops.probe(&uart_console.bas))
+	if (uart_probe(&uart_console))
 		return;
 
 	cp->cn_pri = (boothowto & RB_SERIAL) ? CN_REMOTE : CN_NORMAL;
@@ -117,7 +117,8 @@
 	di = cp->cn_arg;
 	KASSERT(di->consdev == NULL, ("foo"));
 	di->consdev = cp;
-
+	di->type = UART_DEV_CONSOLE;
+	uart_add_sysdev(di);
 	uart_init(di);
 }
 
@@ -190,9 +191,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;
+	/* Hardwire the speed of system devices. */
+	if (sc->sc_sysdev != NULL)
+		t->c_ispeed = t->c_ospeed = sc->sc_sysdev->baudrate;
 	if (t->c_ospeed == 0) {
 		UART_SETSIG(sc, UART_SIG_DDTR | UART_SIG_DRTS);
 		return (0);
@@ -214,7 +215,7 @@
 	if ((t->c_cflag & CRTS_IFLOW) == 0)
 		UART_SETSIG(sc, UART_SIG_DRTS | UART_SIG_RTS);
 	ttsetwater(tp);
-	if (sc->sc_console) {
+	if (sc->sc_sysdev != NULL) {
 		tp->t_cflag |= CLOCAL;
 		tp->t_cflag &= ~HUPCL;
 	}
@@ -311,8 +312,8 @@
 	tp->t_param = uart_tty_param;
 	tp->t_stop = uart_tty_stop;
 
-	if (sc->sc_console) {
-		((struct consdev *)uart_console.consdev)->cn_dev =
+	if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
+		((struct consdev *)sc->sc_sysdev->consdev)->cn_dev =
 		    makedev(uart_cdevsw.d_maj, device_get_unit(sc->sc_dev));
 	}
 
@@ -386,10 +387,7 @@
 		tp->t_iflag = TTYDEF_IFLAG;
 		tp->t_lflag = TTYDEF_LFLAG;
 		tp->t_oflag = TTYDEF_OFLAG;
-		if (sc->sc_console)
-			tp->t_ispeed = tp->t_ospeed = uart_console.baudrate;
-		else
-			tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
+		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
 		ttychars(tp);
 		error = uart_tty_param(tp, &tp->t_termios);
 		if (error)
@@ -441,7 +439,7 @@
 	}
 	KASSERT(tp->t_state & TS_ISOPEN, ("foo"));
 
-	if (!sc->sc_console)
+	if (sc->sc_sysdev == NULL)
 		UART_SETSIG(sc, UART_SIG_DDTR | UART_SIG_DRTS);
 
 	(*linesw[tp->t_line].l_close)(tp, flags);


More information about the p4-projects mailing list