diff options
author | Russell Currey <ruscur@russell.cc> | 2015-12-18 17:15:36 +1100 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2016-01-12 12:13:32 +1100 |
commit | f2efc652cbad6b32e1f0295aac819f6062777e31 (patch) | |
tree | ded31817c9ce70d1fb454134a45ffdbb13cb97b2 /core | |
parent | d4b142823e28deed097cf79b25d8d1e60b6f4e67 (diff) | |
download | talos-skiboot-f2efc652cbad6b32e1f0295aac819f6062777e31.tar.gz talos-skiboot-f2efc652cbad6b32e1f0295aac819f6062777e31.zip |
Add OPAL_CONSOLE_FLUSH to the OPAL API
uart consoles only flush output when polled. The Linux kernel calls
these pollers frequently, except when in a panic state. As such, panic
messages are not fully printed unless the system is configured to reboot
after panic.
This patch adds a new call to the OPAL API to flush the buffer. If the
system has a uart console (i.e. BMC machines), it will incrementally
flush the buffer, returning if there is more to be flushed or not. If
the system has a different console, the function will have no effect.
This will allow the Linux kernel to ensure that panic message have been
fully printed out.
The existing synchronous flushing mechanism used in OPAL's shutdown and
reboot routines has been refactored into a helper that repeatedly calls
the new partial flush function.
Signed-off-by: Russell Currey <ruscur@russell.cc>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core')
-rw-r--r-- | core/console.c | 25 | ||||
-rw-r--r-- | core/platform.c | 4 |
2 files changed, 24 insertions, 5 deletions
diff --git a/core/console.c b/core/console.c index 1cee5daf..e851fcf8 100644 --- a/core/console.c +++ b/core/console.c @@ -290,10 +290,29 @@ ssize_t read(int fd __unused, void *buf, size_t req_count) return count; } -void flush_console_driver(void) +static int64_t opal_console_flush(int64_t term_number) { - if (con_driver && con_driver->flush != NULL) - con_driver->flush(); + if (term_number != 0) + return OPAL_PARAMETER; + + if (con_driver == NULL || con_driver->flush == NULL) + return OPAL_UNSUPPORTED; + + return con_driver->flush(); +} +opal_call(OPAL_CONSOLE_FLUSH, opal_console_flush, 1); + +/* Helper function to perform a full synchronous flush */ +void console_complete_flush(void) +{ + int64_t ret = opal_console_flush(0); + + if (ret == OPAL_UNSUPPORTED || ret == OPAL_PARAMETER) + return; + + while (ret != OPAL_SUCCESS) { + ret = opal_console_flush(0); + } } void set_console(struct con_ops *driver) diff --git a/core/platform.c b/core/platform.c index 865d5b21..0dfbb882 100644 --- a/core/platform.c +++ b/core/platform.c @@ -37,7 +37,7 @@ static int64_t opal_cec_power_down(uint64_t request) { printf("OPAL: Shutdown request type 0x%llx...\n", request); - flush_console_driver(); + console_complete_flush(); if (platform.cec_power_down) return platform.cec_power_down(request); @@ -50,7 +50,7 @@ static int64_t opal_cec_reboot(void) { printf("OPAL: Reboot request...\n"); - flush_console_driver(); + console_complete_flush(); #ifdef ENABLE_FAST_RESET /* Try a fast reset first */ |