summaryrefslogtreecommitdiffstats
path: root/sys/dev/uart/uart_cpu_sparc64.c
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2004-11-28 16:00:36 +0000
committermarius <marius@FreeBSD.org>2004-11-28 16:00:36 +0000
commit985a638215313f07acd97f9b647ff8f1006db270 (patch)
tree34509fd886857dce7a53dddb8504a31f39ac73fb /sys/dev/uart/uart_cpu_sparc64.c
parentb9b9205b8f5f3d577106a937dee83095d52d5b66 (diff)
downloadFreeBSD-src-985a638215313f07acd97f9b647ff8f1006db270.zip
FreeBSD-src-985a638215313f07acd97f9b647ff8f1006db270.tar.gz
- Don't blindly use the return value of uart_cpu_channel() to calculate
the address of a channel on a SCC, it returns 0 on failure. [1] - Hardcode channel 1 for the keyboard on Z8530, the information present in the Open Firmware device tree doesn't allow to determine this via uart_cpu_channel(). This makes the keyboard (if one backs out rev. 1.5 of sys/dev/puc/puc_sbus.c and has both keyboard and mouse plugged in to avoid the hang that revision works around) and consequently syscons(4) on Ultra 2 work. There's a problem with the keyboard LEDs similar to the one on Ultra 60 (LEDs don't get lit under X) though, instead of lighting just a specific single one all get lit and can't be turned off again. [1] - Add comments about what uart_cpu_channel() and uart_cpu_getdev_keyboard() do and their constraints. - Improve the comments about what uart_cpu_getdev_[console,dbgport]() do, they don't return an address (as in bus) but an Open Firmware package handle. Reviewed by: marcel (modulo the comments) [1]
Diffstat (limited to 'sys/dev/uart/uart_cpu_sparc64.c')
-rw-r--r--sys/dev/uart/uart_cpu_sparc64.c40
1 files changed, 33 insertions, 7 deletions
diff --git a/sys/dev/uart/uart_cpu_sparc64.c b/sys/dev/uart/uart_cpu_sparc64.c
index 0708bac..fcc2f1d 100644
--- a/sys/dev/uart/uart_cpu_sparc64.c
+++ b/sys/dev/uart/uart_cpu_sparc64.c
@@ -44,6 +44,14 @@ bus_space_tag_t uart_bus_space_mem;
static struct bus_space_tag bst_store[3];
+/*
+ * Determine which channel of a SCC a device referenced by an alias is.
+ * The information present in the OF device tree only allows to do this
+ * for "ttyX" aliases. If a device is a channel of a SCC its property
+ * in the /aliases node looks like one of these:
+ * ttya: '/central/fhc/zs@0,902000:a'
+ * ttyc: '/pci@1f,0/pci@1,1/ebus@1/se@14,400000:a'
+ */
static int
uart_cpu_channel(char *dev)
{
@@ -69,9 +77,9 @@ uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2)
}
/*
- * Get the address of the UART that is selected as the console, if the
- * console is an UART of course. Note that we enforce that both stdin and
- * stdout are selected.
+ * Get the package handle of the UART that is selected as the console, if
+ * the console is an UART of course. Note that we enforce that both stdin
+ * and stdout are selected.
* Note that the currently active console (i.e. /chosen/stdout and
* /chosen/stdin) may not be the same as the device selected in the
* environment (ie /options/output-device and /options/input-device) because
@@ -115,8 +123,8 @@ uart_cpu_getdev_console(phandle_t options, char *dev, size_t devsz)
}
/*
- * Get the address of the UART that's selected as the debug port. Since
- * there's no place for this in the OF, we use the kernel environment
+ * Get the package handle of the UART that's selected as the debug port.
+ * Since there's no place for this in the OF, we use the kernel environment
* variable "hw.uart.dbgport". Note however that the variable is not a
* list of attributes. It's single device name or alias, as known by
* the OF.
@@ -138,6 +146,12 @@ uart_cpu_getdev_dbgport(phandle_t options, char *dev, size_t devsz)
return (input);
}
+/*
+ * Get the package handle of the device that is selected as the keyboard
+ * port.
+ * XXX this also matches PS/2 keyboard controllers and most likely also
+ * USB keyboards.
+ */
static phandle_t
uart_cpu_getdev_keyboard(phandle_t root, char *dev, size_t devsz)
{
@@ -199,11 +213,23 @@ uart_cpu_getdev(int devtype, struct uart_devinfo *di)
di->bas.rclk = 0;
if (!strcmp(buf, "se")) {
di->ops = uart_sab82532_ops;
- di->bas.chan = uart_cpu_channel(dev);
+ /* SAB82532 are only known to be used for TTYs. */
+ if ((di->bas.chan = uart_cpu_channel(dev)) == 0)
+ return (ENXIO);
addr += 64 * (di->bas.chan - 1);
} else if (!strcmp(buf, "zs")) {
di->ops = uart_z8530_ops;
- di->bas.chan = uart_cpu_channel(dev);
+ if ((di->bas.chan = uart_cpu_channel(dev)) == 0) {
+ /*
+ * There's no way to determine from OF which
+ * channel has the keyboard. Should always be
+ * on channel 1 however.
+ */
+ if (devtype == UART_DEV_KEYBOARD)
+ di->bas.chan = 1;
+ else
+ return (ENXIO);
+ }
di->bas.regshft = 1;
addr += 4 - 4 * (di->bas.chan - 1);
} else if (!strcmp(buf, "su") || !strcmp(buf, "su_pnp") ||
OpenPOWER on IntegriCloud