Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 25 Aug 2003 00:23:40 -0700 (PDT)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 36871 for review
Message-ID:  <200308250723.h7P7Ne5B028798@repoman.freebsd.org>

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

Change 36871 by marcel@marcel_nfs on 2003/08/25 00:22:47

	Get the line settings from OpenFirmware. We assume 9600,n,8,1
	when something doesn't add up or isn't as we expect. The
	problem generally is that the line settings may or may not
	apply to the console currently active. For example, the current
	console device may not be the one defined by "output-device"
	in the environment. Also, the line settings in the environment
	(eg "ttya-mode") may not be the current settings. I don't know
	enough about OpenFirmware, so there may be a better way.
	
	Anyway: if you change the console speed in OpenFirmware, then
	uart(4) will adhere.

Affected files ...

.. //depot/projects/uart/dev/uart/uart_cpu_sparc64.c#3 edit

Differences ...

==== //depot/projects/uart/dev/uart/uart_cpu_sparc64.c#3 (text+ko) ====

@@ -45,11 +45,12 @@
 int
 uart_cpu_getdev(int devtype, struct uart_devinfo *di)
 {
-	char buffer[8];
-	phandle_t chosen, consin, consout;
+	char buffer[64];
+	phandle_t chosen, consin, consout, options;
 	ihandle_t stdin, stdout;
 	bus_addr_t addr;
-	int error, space;
+	int baud, bits, error, space, stop;
+	char flag, par;
 
 	/*
 	 * Get the address of the UART that is selected as the console, if
@@ -83,22 +84,51 @@
 	di->bas.bsh = sparc64_fake_bustag(space, addr, di->bas.bst);
 	di->bas.regshft = 0;
 	di->bas.rclk = 0;
+
+	/* Get the device class. */
+	if (OF_getprop(consout, "name", buffer, sizeof(buffer)) == -1)
+		return (ENXIO);
+	if (!strcmp(buffer, "se"))
+		di->ops = uart_sab82532_ops;
+	else if (!strcmp(buffer, "su"))
+		di->ops = uart_ns8250_ops;
+	else
+		return (ENXIO);
+
+	/*
+	 * Get the line settings. This is tricky because the settings are
+	 * stored under some (possibly) random alias as a property of
+	 * /options and we don't even know if they apply to the currently
+	 * selected device. We simply assume 9600,n,8,1 if something wrong.
+	 * Note that we always return success from here on.
+	 */
 	di->baudrate = 9600;
 	di->databits = 8;
 	di->stopbits = 1;
 	di->parity = UART_PARITY_NONE;
 
-	if (OF_getprop(consout, "name", buffer, sizeof(buffer)) == -1)
-		return (ENXIO);
-	if (!strcmp(buffer, "se")) {
-		di->ops = uart_sab82532_ops;
+	if ((options = OF_finddevice("/options")) == -1)
+		return (0);
+	if (OF_getprop(options, "output-device", buffer, sizeof(buffer)) == -1)
+		return (0);
+	if ((consout = OF_finddevice(buffer)) == -1)
+		return (0);
+	if (consout != consin)
+		return (0);
+	if (sizeof(buffer) - strlen(buffer) < 6)
+		return (0);
+	strcat(buffer, "-mode");
+	if (OF_getprop(options, buffer, buffer, sizeof(buffer)) == -1)
 		return (0);
-	}
-	if (!strcmp(buffer, "su")) {
-		di->ops = uart_ns8250_ops;
+	if (sscanf(buffer, "%d,%d,%c,%d,%c", &baud, &bits, &par, &stop,
+	    &flag) != 5)
 		return (0);
-	}
-	return (ENXIO);
+	di->baudrate = baud;
+	di->databits = bits;
+	di->stopbits = stop;
+	di->parity = (par == 'n') ? UART_PARITY_NONE :
+	    (par == 'o') ? UART_PARITY_ODD : UART_PARITY_EVEN;
+	return (0);
 }
 
 int



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