Move the shared console-input helpers to efi_app_common:

* efi_drain_input() - drain the console input queue
* efi_input_yn()    - read a y/n/ESC key from the user
* efi_input()       - read a UTF-16 string from the console

The common efi_input_yn() calls efi_drain_input() once at entry,
replacing the open-coded cin->reset() calls that each application
previously duplicated.

dbginfodump and smbiosdump had no efi_drain_input() call in their
command loops; add the call so the console queue is drained before
each prompt, fixing a latent input-echo artefact.

The common state is extended with a cin pointer (initialized by
efi_app_init from sys_table->con_in) so the helpers can access the
console-input protocol without additional parameters.

Remove the now-duplicate static definitions from dtbdump, initrddump,
smbiosdump and dbginfodump.

smbiosdump: fix kernel-doc tag for command_loop() from "command_loop -"
to "command_loop() -" to follow the kernel-doc convention.

Signed-off-by: Heinrich Schuchardt <[email protected]>
---
v2:
        new patch
---
 lib/efi_loader/dbginfodump.c    |  61 ------------------
 lib/efi_loader/dtbdump.c        | 109 --------------------------------
 lib/efi_loader/efi_app_common.c |  88 ++++++++++++++++++++++++++
 lib/efi_loader/efi_app_common.h |  29 +++++++++
 lib/efi_loader/initrddump.c     | 109 --------------------------------
 lib/efi_loader/smbiosdump.c     | 108 +------------------------------
 6 files changed, 119 insertions(+), 385 deletions(-)

diff --git a/lib/efi_loader/dbginfodump.c b/lib/efi_loader/dbginfodump.c
index 2dcff2a11fe..8fa60a7f48e 100644
--- a/lib/efi_loader/dbginfodump.c
+++ b/lib/efi_loader/dbginfodump.c
@@ -14,7 +14,6 @@
 #define BUFFER_SIZE 64
 
 static struct efi_simple_text_output_protocol *cout;
-static struct efi_simple_text_input_protocol *cin;
 static efi_handle_t handle;
 static struct efi_system_table *systable;
 static struct efi_boot_services *bs;
@@ -83,65 +82,6 @@ static void printp(void *p)
        print(str);
 }
 
-/**
- * efi_input() - read string from console
- *
- * @buffer:            input buffer
- * @buffer_size:       buffer size
- * Return:             status code
- */
-static efi_status_t efi_input(u16 *buffer, efi_uintn_t buffer_size)
-{
-       struct efi_input_key key = {0};
-       efi_uintn_t index;
-       efi_uintn_t pos = 0;
-       u16 outbuf[2] = u" ";
-       efi_status_t ret;
-
-       /* Drain the console input */
-       ret = cin->reset(cin, true);
-       *buffer = 0;
-       for (;;) {
-               ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
-               if (ret != EFI_SUCCESS)
-                       continue;
-               ret = cin->read_key_stroke(cin, &key);
-               if (ret != EFI_SUCCESS)
-                       continue;
-               switch (key.scan_code) {
-               case 0x17: /* Escape */
-                       print(u"\r\nAborted\r\n");
-                       return EFI_ABORTED;
-               default:
-                       break;
-               }
-               switch (key.unicode_char) {
-               case 0x08: /* Backspace */
-                       if (pos) {
-                               buffer[pos--] = 0;
-                               print(u"\b \b");
-                       }
-                       break;
-               case 0x0a: /* Linefeed */
-               case 0x0d: /* Carriage return */
-                       print(u"\r\n");
-                       return EFI_SUCCESS;
-               default:
-                       break;
-               }
-               /* Ignore surrogate codes */
-               if (key.unicode_char >= 0xD800 && key.unicode_char <= 0xDBFF)
-                       continue;
-               if (key.unicode_char >= 0x20 &&
-                   pos < buffer_size - 1) {
-                       *outbuf = key.unicode_char;
-                       buffer[pos++] = key.unicode_char;
-                       buffer[pos] = 0;
-                       print(outbuf);
-               }
-       }
-}
-
 /**
  * skip_whitespace() - skip over leading whitespace
  *
@@ -277,7 +217,6 @@ efi_status_t EFIAPI efi_main(efi_handle_t image_handle,
        handle = image_handle;
        systable = systab;
        cout = systable->con_out;
-       cin = systable->con_in;
        bs = systable->boottime;
 
        cout->set_attribute(cout, EFI_LIGHTBLUE | EFI_BACKGROUND_BLACK);
diff --git a/lib/efi_loader/dtbdump.c b/lib/efi_loader/dtbdump.c
index 1468955eb8c..716daf4a90f 100644
--- a/lib/efi_loader/dtbdump.c
+++ b/lib/efi_loader/dtbdump.c
@@ -16,7 +16,6 @@
 
 #define efi_size_in_pages(size) ((size + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT)
 
-static struct efi_simple_text_input_protocol *cin;
 static struct efi_boot_services *bs;
 static const efi_guid_t fdt_guid = EFI_FDT_GUID;
 static const efi_guid_t loaded_image_guid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
@@ -50,113 +49,6 @@ static void print_char(unsigned char c)
        print(out);
 }
 
-/**
- * efi_drain_input() - drain console input
- */
-static void efi_drain_input(void)
-{
-       cin->reset(cin, true);
-}
-
-/**
- * efi_input_yn() - get answer to yes/no question
- *
- * Return:
- * y or Y
- *     EFI_SUCCESS
- * n or N
- *     EFI_ACCESS_DENIED
- * ESC
- *     EFI_ABORTED
- */
-static efi_status_t efi_input_yn(void)
-{
-       struct efi_input_key key = {0};
-       efi_uintn_t index;
-       efi_status_t ret;
-
-       for (;;) {
-               ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
-               if (ret != EFI_SUCCESS)
-                       continue;
-               ret = cin->read_key_stroke(cin, &key);
-               if (ret != EFI_SUCCESS)
-                       continue;
-               switch (key.scan_code) {
-               case 0x17: /* Escape */
-                       return EFI_ABORTED;
-               default:
-                       break;
-               }
-               /* Convert to lower case */
-               switch (key.unicode_char | 0x20) {
-               case 'y':
-                       return EFI_SUCCESS;
-               case 'n':
-                       return EFI_ACCESS_DENIED;
-               default:
-                       break;
-               }
-       }
-}
-
-/**
- * efi_input() - read string from console
- *
- * @buffer:            input buffer
- * @buffer_size:       buffer size
- * Return:             status code
- */
-static efi_status_t efi_input(u16 *buffer, efi_uintn_t buffer_size)
-{
-       struct efi_input_key key = {0};
-       efi_uintn_t index;
-       efi_uintn_t pos = 0;
-       u16 outbuf[2] = u" ";
-       efi_status_t ret;
-
-       *buffer = 0;
-       for (;;) {
-               ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
-               if (ret != EFI_SUCCESS)
-                       continue;
-               ret = cin->read_key_stroke(cin, &key);
-               if (ret != EFI_SUCCESS)
-                       continue;
-               switch (key.scan_code) {
-               case 0x17: /* Escape */
-                       print(u"\r\nAborted\r\n");
-                       return EFI_ABORTED;
-               default:
-                       break;
-               }
-               switch (key.unicode_char) {
-               case 0x08: /* Backspace */
-                       if (pos) {
-                               buffer[pos--] = 0;
-                               print(u"\b \b");
-                       }
-                       break;
-               case 0x0a: /* Linefeed */
-               case 0x0d: /* Carriage return */
-                       print(u"\r\n");
-                       return EFI_SUCCESS;
-               default:
-                       break;
-               }
-               /* Ignore surrogate codes */
-               if (key.unicode_char >= 0xD800 && key.unicode_char <= 0xDBFF)
-                       continue;
-               if (key.unicode_char >= 0x20 &&
-                   pos < buffer_size - 1) {
-                       *outbuf = key.unicode_char;
-                       buffer[pos++] = key.unicode_char;
-                       buffer[pos] = 0;
-                       print(outbuf);
-               }
-       }
-}
-
 /*
  * Convert FDT value to host endianness.
  *
@@ -702,7 +594,6 @@ efi_status_t EFIAPI efi_main(efi_handle_t image_handle,
 
        handle = image_handle;
        systable = systab;
-       cin = systable->con_in;
        bs = systable->boottime;
 
        color(EFI_LIGHTBLUE);
diff --git a/lib/efi_loader/efi_app_common.c b/lib/efi_loader/efi_app_common.c
index e9e9334acc7..406cd236f6f 100644
--- a/lib/efi_loader/efi_app_common.c
+++ b/lib/efi_loader/efi_app_common.c
@@ -9,6 +9,7 @@
 #include "efi_app_common.h"
 
 static efi_handle_t app_handle;
+static struct efi_simple_text_input_protocol *cin;
 static struct efi_simple_text_output_protocol *cout;
 struct efi_boot_services *bs;
 static bool nocolor;
@@ -40,6 +41,7 @@ void efi_app_init(struct efi_system_table *sys_table, 
efi_handle_t image_handle)
 
        app_handle = image_handle;
        systable = sys_table;
+       cin = sys_table->con_in;
        cout = sys_table->con_out;
        bs = sys_table->boottime;
 
@@ -104,3 +106,89 @@ bool starts_with(u16 *string, u16 *keyword)
        }
        return true;
 }
+
+void efi_drain_input(void)
+{
+       cin->reset(cin, true);
+}
+
+efi_status_t efi_input_yn(void)
+{
+       struct efi_input_key key = { 0 };
+       efi_uintn_t index;
+       efi_status_t ret;
+
+       efi_drain_input();
+       for (;;) {
+               ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
+               if (ret != EFI_SUCCESS)
+                       continue;
+               ret = cin->read_key_stroke(cin, &key);
+               if (ret != EFI_SUCCESS)
+                       continue;
+               switch (key.scan_code) {
+               case 0x17: /* Escape */
+                       return EFI_ABORTED;
+               default:
+                       break;
+               }
+               /* Convert to lower case */
+               switch (key.unicode_char | 0x20) {
+               case 'y':
+                       return EFI_SUCCESS;
+               case 'n':
+                       return EFI_ACCESS_DENIED;
+               default:
+                       break;
+               }
+       }
+}
+
+efi_status_t efi_input(u16 *buffer, efi_uintn_t buffer_size)
+{
+       struct efi_input_key key = { 0 };
+       efi_uintn_t index;
+       efi_uintn_t pos = 0;
+       u16 outbuf[2] = u" ";
+       efi_status_t ret;
+
+       *buffer = 0;
+       for (;;) {
+               ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
+               if (ret != EFI_SUCCESS)
+                       continue;
+               ret = cin->read_key_stroke(cin, &key);
+               if (ret != EFI_SUCCESS)
+                       continue;
+               switch (key.scan_code) {
+               case 0x17: /* Escape */
+                       print(u"\r\nAborted\r\n");
+                       return EFI_ABORTED;
+               default:
+                       break;
+               }
+               switch (key.unicode_char) {
+               case 0x08: /* Backspace */
+                       if (pos) {
+                               buffer[pos--] = 0;
+                               print(u"\b \b");
+                       }
+                       break;
+               case 0x0a: /* Linefeed */
+               case 0x0d: /* Carriage return */
+                       print(u"\r\n");
+                       return EFI_SUCCESS;
+               default:
+                       break;
+               }
+               /* Ignore surrogate codes */
+               if (key.unicode_char >= 0xD800 && key.unicode_char <= 0xDBFF)
+                       continue;
+               if (key.unicode_char >= 0x20 && pos < buffer_size - 1) {
+                       *outbuf = key.unicode_char;
+                       buffer[pos++] = key.unicode_char;
+                       buffer[pos] = 0;
+                       print(outbuf);
+               }
+       }
+}
diff --git a/lib/efi_loader/efi_app_common.h b/lib/efi_loader/efi_app_common.h
index 45c17a8ed99..4498607ef07 100644
--- a/lib/efi_loader/efi_app_common.h
+++ b/lib/efi_loader/efi_app_common.h
@@ -64,4 +64,33 @@ void error(u16 *string);
  */
 bool starts_with(u16 *string, u16 *keyword);
 
+/**
+ * efi_drain_input() - drain console input
+ */
+void efi_drain_input(void);
+
+/**
+ * efi_input_yn() - get answer to yes/no question
+ *
+ * Drains the console input before reading.
+ *
+ * Return:
+ * y or Y
+ *     EFI_SUCCESS
+ * n or N
+ *     EFI_ACCESS_DENIED
+ * ESC
+ *     EFI_ABORTED
+ */
+efi_status_t efi_input_yn(void);
+
+/**
+ * efi_input() - read string from console
+ *
+ * @buffer:             input buffer
+ * @buffer_size:        buffer size
+ * Return:              status code
+ */
+efi_status_t efi_input(u16 *buffer, efi_uintn_t buffer_size);
+
 #endif /* _EFI_APP_COMMON_H */
diff --git a/lib/efi_loader/initrddump.c b/lib/efi_loader/initrddump.c
index 60f8a020e8c..52562be048d 100644
--- a/lib/efi_loader/initrddump.c
+++ b/lib/efi_loader/initrddump.c
@@ -19,7 +19,6 @@
 
 static struct efi_system_table *systable;
 static struct efi_boot_services *bs;
-static struct efi_simple_text_input_protocol *cin;
 static const efi_guid_t loaded_image_guid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
 static const efi_guid_t guid_simple_file_system_protocol =
                                        EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
@@ -46,113 +45,6 @@ static const struct efi_lo_dp_prefix initrd_dp = {
        }
 };
 
-/**
- * efi_drain_input() - drain console input
- */
-static void efi_drain_input(void)
-{
-       cin->reset(cin, true);
-}
-
-/**
- * efi_input_yn() - get answer to yes/no question
- *
- * Return:
- * y or Y
- *     EFI_SUCCESS
- * n or N
- *     EFI_ACCESS_DENIED
- * ESC
- *     EFI_ABORTED
- */
-static efi_status_t efi_input_yn(void)
-{
-       struct efi_input_key key = {0};
-       efi_uintn_t index;
-       efi_status_t ret;
-
-       for (;;) {
-               ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
-               if (ret != EFI_SUCCESS)
-                       continue;
-               ret = cin->read_key_stroke(cin, &key);
-               if (ret != EFI_SUCCESS)
-                       continue;
-               switch (key.scan_code) {
-               case 0x17: /* Escape */
-                       return EFI_ABORTED;
-               default:
-                       break;
-               }
-               /* Convert to lower case */
-               switch (key.unicode_char | 0x20) {
-               case 'y':
-                       return EFI_SUCCESS;
-               case 'n':
-                       return EFI_ACCESS_DENIED;
-               default:
-                       break;
-               }
-       }
-}
-
-/**
- * efi_input() - read string from console
- *
- * @buffer:            input buffer
- * @buffer_size:       buffer size
- * Return:             status code
- */
-static efi_status_t efi_input(u16 *buffer, efi_uintn_t buffer_size)
-{
-       struct efi_input_key key = {0};
-       efi_uintn_t index;
-       efi_uintn_t pos = 0;
-       u16 outbuf[2] = u" ";
-       efi_status_t ret;
-
-       *buffer = 0;
-       for (;;) {
-               ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
-               if (ret != EFI_SUCCESS)
-                       continue;
-               ret = cin->read_key_stroke(cin, &key);
-               if (ret != EFI_SUCCESS)
-                       continue;
-               switch (key.scan_code) {
-               case 0x17: /* Escape */
-                       print(u"\r\nAborted\r\n");
-                       return EFI_ABORTED;
-               default:
-                       break;
-               }
-               switch (key.unicode_char) {
-               case 0x08: /* Backspace */
-                       if (pos) {
-                               buffer[pos--] = 0;
-                               print(u"\b \b");
-                       }
-                       break;
-               case 0x0a: /* Linefeed */
-               case 0x0d: /* Carriage return */
-                       print(u"\r\n");
-                       return EFI_SUCCESS;
-               default:
-                       break;
-               }
-               /* Ignore surrogate codes */
-               if (key.unicode_char >= 0xD800 && key.unicode_char <= 0xDBFF)
-                       continue;
-               if (key.unicode_char >= 0x20 &&
-                   pos < buffer_size - 1) {
-                       *outbuf = key.unicode_char;
-                       buffer[pos++] = key.unicode_char;
-                       buffer[pos] = 0;
-                       print(outbuf);
-               }
-       }
-}
-
 /**
  * skip_whitespace() - skip over leading whitespace
  *
@@ -356,7 +248,6 @@ efi_status_t EFIAPI efi_main(efi_handle_t image_handle,
 
        handle = image_handle;
        systable = systab;
-       cin = systable->con_in;
        bs = systable->boottime;
 
        color(EFI_WHITE);
diff --git a/lib/efi_loader/smbiosdump.c b/lib/efi_loader/smbiosdump.c
index e19214d798f..100e03294e5 100644
--- a/lib/efi_loader/smbiosdump.c
+++ b/lib/efi_loader/smbiosdump.c
@@ -15,7 +15,6 @@
 
 #define BUFFER_SIZE 64
 
-static struct efi_simple_text_input_protocol *cin;
 static struct efi_boot_services *bs;
 static efi_handle_t handle;
 static struct efi_system_table *systable;
@@ -26,109 +25,6 @@ static const efi_guid_t guid_simple_file_system_protocol =
                                        EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
 static const efi_guid_t efi_system_partition_guid = PARTITION_SYSTEM_GUID;
 
-/**
- * efi_input_yn() - get answer to yes/no question
- *
- * Return:
- * y or Y
- *     EFI_SUCCESS
- * n or N
- *     EFI_ACCESS_DENIED
- * ESC
- *     EFI_ABORTED
- */
-static efi_status_t efi_input_yn(void)
-{
-       struct efi_input_key key = {0};
-       efi_uintn_t index;
-       efi_status_t ret;
-
-       /* Drain the console input */
-       ret = cin->reset(cin, true);
-       for (;;) {
-               ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
-               if (ret != EFI_SUCCESS)
-                       continue;
-               ret = cin->read_key_stroke(cin, &key);
-               if (ret != EFI_SUCCESS)
-                       continue;
-               switch (key.scan_code) {
-               case 0x17: /* Escape */
-                       return EFI_ABORTED;
-               default:
-                       break;
-               }
-               /* Convert to lower case */
-               switch (key.unicode_char | 0x20) {
-               case 'y':
-                       return EFI_SUCCESS;
-               case 'n':
-                       return EFI_ACCESS_DENIED;
-               default:
-                       break;
-               }
-       }
-}
-
-/**
- * efi_input() - read string from console
- *
- * @buffer:            input buffer
- * @buffer_size:       buffer size
- * Return:             status code
- */
-static efi_status_t efi_input(u16 *buffer, efi_uintn_t buffer_size)
-{
-       struct efi_input_key key = {0};
-       efi_uintn_t index;
-       efi_uintn_t pos = 0;
-       u16 outbuf[2] = u" ";
-       efi_status_t ret;
-
-       /* Drain the console input */
-       ret = cin->reset(cin, true);
-       *buffer = 0;
-       for (;;) {
-               ret = bs->wait_for_event(1, &cin->wait_for_key, &index);
-               if (ret != EFI_SUCCESS)
-                       continue;
-               ret = cin->read_key_stroke(cin, &key);
-               if (ret != EFI_SUCCESS)
-                       continue;
-               switch (key.scan_code) {
-               case 0x17: /* Escape */
-                       print(u"\r\nAborted\r\n");
-                       return EFI_ABORTED;
-               default:
-                       break;
-               }
-               switch (key.unicode_char) {
-               case 0x08: /* Backspace */
-                       if (pos) {
-                               buffer[pos--] = 0;
-                               print(u"\b \b");
-                       }
-                       break;
-               case 0x0a: /* Linefeed */
-               case 0x0d: /* Carriage return */
-                       print(u"\r\n");
-                       return EFI_SUCCESS;
-               default:
-                       break;
-               }
-               /* Ignore surrogate codes */
-               if (key.unicode_char >= 0xD800 && key.unicode_char <= 0xDBFF)
-                       continue;
-               if (key.unicode_char >= 0x20 &&
-                   pos < buffer_size - 1) {
-                       *outbuf = key.unicode_char;
-                       buffer[pos++] = key.unicode_char;
-                       buffer[pos] = 0;
-                       print(outbuf);
-               }
-       }
-}
-
 /**
  * skip_whitespace() - skip over leading whitespace
  *
@@ -467,7 +363,7 @@ static efi_status_t do_save(u16 *filename)
 }
 
 /**
- * command_loop - process user commands
+ * command_loop() - process user commands
  */
 static void command_loop(void)
 {
@@ -476,6 +372,7 @@ static void command_loop(void)
                u16 *pos;
                efi_uintn_t ret;
 
+               efi_drain_input();
                print(u"=> ");
                ret = efi_input(command, sizeof(command));
                if (ret == EFI_ABORTED)
@@ -509,7 +406,6 @@ efi_status_t EFIAPI efi_main(efi_handle_t image_handle,
 
        handle = image_handle;
        systable = systab;
-       cin = systable->con_in;
        bs = systable->boottime;
 
        color(EFI_WHITE);
-- 
2.53.0

Reply via email to