On Sun, 28 Jun 2026 at 11:28, Heinrich Schuchardt <[email protected]> wrote: > > 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. > > Reviewed-by: Simon Glass <[email protected]> > Signed-off-by: Heinrich Schuchardt <[email protected]>
Acked-by: Ilias Apalodimas <[email protected]> > --- > v3: > actually add drain_input() to dbginfodump > v2: > new patch > --- > lib/efi_loader/dbginfodump.c | 62 +----------------- > 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, 120 insertions(+), 385 deletions(-) > > diff --git a/lib/efi_loader/dbginfodump.c b/lib/efi_loader/dbginfodump.c > index 2dcff2a11fe..b39d47ff9bb 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); > @@ -298,6 +237,7 @@ efi_status_t EFIAPI efi_main(efi_handle_t image_handle, > u16 *pos; > efi_uintn_t ret; > > + efi_drain_input(); > print(u"=> "); > ret = efi_input(command, sizeof(command)); > if (ret == EFI_ABORTED) > 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 >

