forked from pool/u-boot
Guillaume GARDET
68026c8172
- Patch queue updated from git://github.com/openSUSE/u-boot.git tumbleweed-2019.01 * Fix bsc#1124137 by: * Patches dropped: 0008-Revert-efi_loader-query-serial-cons.patch 0009-zynqmp-generic-fix-compilation.patch * Patches added: 0008-zynqmp-generic-fix-compilation.patch 0009-efi_loader-Fix-serial-console-size-.patch OBS-URL: https://build.opensuse.org/request/show/686176 OBS-URL: https://build.opensuse.org/package/show/hardware:boot/u-boot?expand=0&rev=44
130 lines
3.1 KiB
Diff
130 lines
3.1 KiB
Diff
From 029eed9c0d3d43cfa043913254aa0aa904c92f13 Mon Sep 17 00:00:00 2001
|
|
From: Matthias Brugger <mbrugger@suse.com>
|
|
Date: Tue, 5 Mar 2019 12:50:18 +0100
|
|
Subject: [PATCH] efi_loader: Fix serial console size detection
|
|
|
|
Function term_read_reply tries to read from the serial console until
|
|
the end_char was read. This can hang forever if we are, for some reason,
|
|
not able to read the full response (e.g. serial buffer too small,
|
|
frame error). This patch moves the timeout detection into
|
|
term_read_reply() to assure we will make progress.
|
|
|
|
Fixes: 6bb591f704 ("efi_loader: query serial console size reliably")
|
|
Signed-off-by: Matthias Brugger <mbrugger@suse.com>
|
|
|
|
Throw missing error when an incomplete reply for the cursor position is
|
|
received.
|
|
|
|
Change type of argument of term_get_char() *s32. This renders the function
|
|
reusable in efi_cin_read_key().
|
|
|
|
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
|
|
---
|
|
lib/efi_loader/efi_console.c | 62 ++++++++++++++++++++----------------
|
|
1 file changed, 35 insertions(+), 27 deletions(-)
|
|
|
|
diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
|
|
index 66c33a551d..8e0965bfc8 100644
|
|
--- a/lib/efi_loader/efi_console.c
|
|
+++ b/lib/efi_loader/efi_console.c
|
|
@@ -62,6 +62,21 @@ static struct simple_text_output_mode efi_con_mode = {
|
|
.cursor_visible = 1,
|
|
};
|
|
|
|
+static int term_get_char(s32 *c)
|
|
+{
|
|
+ u64 timeout;
|
|
+
|
|
+ /* Wait up to 100 ms for a character */
|
|
+ timeout = timer_get_us() + 100000;
|
|
+
|
|
+ while (!tstc())
|
|
+ if (timer_get_us() > timeout)
|
|
+ return 1;
|
|
+
|
|
+ *c = getc();
|
|
+ return 0;
|
|
+}
|
|
+
|
|
/*
|
|
* Receive and parse a reply from the terminal.
|
|
*
|
|
@@ -72,34 +87,36 @@ static struct simple_text_output_mode efi_con_mode = {
|
|
*/
|
|
static int term_read_reply(int *n, int num, char end_char)
|
|
{
|
|
- char c;
|
|
+ s32 c;
|
|
int i = 0;
|
|
|
|
- c = getc();
|
|
- if (c != cESC)
|
|
+ if (term_get_char(&c) || c != cESC)
|
|
return -1;
|
|
- c = getc();
|
|
- if (c != '[')
|
|
+
|
|
+ if (term_get_char(&c) || c != '[')
|
|
return -1;
|
|
|
|
n[0] = 0;
|
|
while (1) {
|
|
- c = getc();
|
|
- if (c == ';') {
|
|
- i++;
|
|
- if (i >= num)
|
|
+ if (!term_get_char(&c)) {
|
|
+ if (c == ';') {
|
|
+ i++;
|
|
+ if (i >= num)
|
|
+ return -1;
|
|
+ n[i] = 0;
|
|
+ continue;
|
|
+ } else if (c == end_char) {
|
|
+ break;
|
|
+ } else if (c > '9' || c < '0') {
|
|
return -1;
|
|
- n[i] = 0;
|
|
- continue;
|
|
- } else if (c == end_char) {
|
|
- break;
|
|
- } else if (c > '9' || c < '0') {
|
|
+ }
|
|
+
|
|
+ /* Read one more decimal position */
|
|
+ n[i] *= 10;
|
|
+ n[i] += c - '0';
|
|
+ } else {
|
|
return -1;
|
|
}
|
|
-
|
|
- /* Read one more decimal position */
|
|
- n[i] *= 10;
|
|
- n[i] += c - '0';
|
|
}
|
|
if (i != num - 1)
|
|
return -1;
|
|
@@ -196,7 +213,6 @@ static int query_console_serial(int *rows, int *cols)
|
|
{
|
|
int ret = 0;
|
|
int n[2];
|
|
- u64 timeout;
|
|
|
|
/* Empty input buffer */
|
|
while (tstc())
|
|
@@ -216,14 +232,6 @@ static int query_console_serial(int *rows, int *cols)
|
|
ESC "[999;999H" /* Move to bottom right corner */
|
|
ESC "[6n"); /* Query cursor position */
|
|
|
|
- /* Allow up to one second for a response */
|
|
- timeout = timer_get_us() + 1000000;
|
|
- while (!tstc())
|
|
- if (timer_get_us() > timeout) {
|
|
- ret = -1;
|
|
- goto out;
|
|
- }
|
|
-
|
|
/* Read {rows,cols} */
|
|
if (term_read_reply(n, 2, 'R')) {
|
|
ret = 1;
|