All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ilias Apalodimas <ilias.apalodimas@linaro.org>
To: Masahisa Kojima <masahisa.kojima@linaro.org>
Cc: u-boot@lists.denx.de, Heinrich Schuchardt <xypron.glpk@gmx.de>
Subject: Re: [PATCH v4 2/4] eficonfig: refactor change boot order implementation
Date: Mon, 23 Jan 2023 16:57:55 +0200	[thread overview]
Message-ID: <Y86gc4LzlJql4uUr@hera> (raw)
In-Reply-To: <20230120084358.5919-3-masahisa.kojima@linaro.org>

On Fri, Jan 20, 2023 at 05:43:56PM +0900, Masahisa Kojima wrote:
> This commit removes the change boot order specific
> menu implementation. The change boot order implementation
> calls eficonfig_process_common() same as other menus.
>
> The change boot order menu requires own item_data_print
> and item_choice implementation, but display_statusline
> function can be a same function as other menus.
>
> Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
> Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
> ---
> No update since v3
>
> Changes in v3:
> - modify "reverse" local variable type to bool
>
> Changes in v2:
> - add comment when the user key press is not valid
> - add const qualifier to eficonfig_change_boot_order_desc
>
>  cmd/eficonfig.c | 246 +++++++++++++++++++++++++++++-------------------
>  1 file changed, 151 insertions(+), 95 deletions(-)
>
> diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c
> index 24d6bdb6bf..01bd1b05bc 100644
> --- a/cmd/eficonfig.c
> +++ b/cmd/eficonfig.c
> @@ -25,6 +25,11 @@ static struct efi_simple_text_input_protocol *cin;
>  const char *eficonfig_menu_desc =
>  	"  Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit";
>
> +static const char *eficonfig_change_boot_order_desc =
> +	"  Press UP/DOWN to move, +/- to change orde\n"
> +	"  Press SPACE to activate or deactivate the entry\n"
> +	"  Select [Save] to complete, ESC/CTRL+C to quit";
> +
>  #define EFICONFIG_DESCRIPTION_MAX 32
>  #define EFICONFIG_OPTIONAL_DATA_MAX 64
>
> @@ -106,6 +111,17 @@ struct eficonfig_boot_order_data {
>  	bool active;
>  };
>
> +/**
> + * struct eficonfig_save_boot_order_data - structure to be used to change boot order
> + *
> + * @efi_menu:		pointer to efimenu structure
> + * @selected:		flag to indicate user selects "Save" entry
> + */
> +struct eficonfig_save_boot_order_data {
> +	struct efimenu *efi_menu;
> +	bool selected;
> +};
> +
>  /**
>   * eficonfig_print_msg() - print message
>   *
> @@ -174,10 +190,9 @@ void eficonfig_display_statusline(struct menu *m)
>  	      "\n%s\n"
>  	       ANSI_CURSOR_POSITION ANSI_CLEAR_LINE ANSI_CURSOR_POSITION
>  	       "%s"
> -	       ANSI_CLEAR_LINE_TO_END ANSI_CURSOR_POSITION ANSI_CLEAR_LINE,
> +	       ANSI_CLEAR_LINE_TO_END,
>  	       1, 1, entry->efi_menu->menu_header, entry->efi_menu->count + 5, 1,
> -	       entry->efi_menu->count + 6, 1, entry->efi_menu->menu_desc,
> -	       entry->efi_menu->count + 7, 1);
> +	       entry->efi_menu->count + 6, 1, entry->efi_menu->menu_desc);
>  }
>
>  /**
> @@ -1844,63 +1859,44 @@ out:
>  }
>
>  /**
> - * eficonfig_display_change_boot_order() - display the BootOrder list
> + * eficonfig_print_change_boot_order_entry() - print the boot option entry
>   *
> - * @efi_menu:	pointer to the efimenu structure
> - * Return:	status code
> + * @data:	pointer to the data associated with each menu entry
>   */
> -static void eficonfig_display_change_boot_order(struct efimenu *efi_menu)
> +static void eficonfig_print_change_boot_order_entry(void *data)
>  {
> -	bool reverse;
> -	struct list_head *pos, *n;
> -	struct eficonfig_entry *entry;
> -
> -	printf(ANSI_CLEAR_CONSOLE ANSI_CURSOR_POSITION
> -	       "\n  ** Change Boot Order **\n"
> -	       ANSI_CURSOR_POSITION
> -	       "  Press UP/DOWN to move, +/- to change order"
> -	       ANSI_CURSOR_POSITION
> -	       "  Press SPACE to activate or deactivate the entry"
> -	       ANSI_CURSOR_POSITION
> -	       "  Select [Save] to complete, ESC/CTRL+C to quit"
> -	       ANSI_CURSOR_POSITION ANSI_CLEAR_LINE,
> -	       1, 1, efi_menu->count + 5, 1, efi_menu->count + 6, 1,
> -	       efi_menu->count + 7, 1,  efi_menu->count + 8, 1);
> -
> -	/* draw boot option list */
> -	list_for_each_safe(pos, n, &efi_menu->list) {
> -		entry = list_entry(pos, struct eficonfig_entry, list);
> -		reverse = (entry->num == efi_menu->active);
> +	struct eficonfig_entry *entry = data;
> +	bool reverse = (entry->efi_menu->active == entry->num);
>
> -		printf(ANSI_CURSOR_POSITION, entry->num + 4, 7);
> +	printf(ANSI_CURSOR_POSITION, entry->num + 4, 7);
>
> -		if (reverse)
> -			puts(ANSI_COLOR_REVERSE);
> +	if (reverse)
> +		puts(ANSI_COLOR_REVERSE);
>
> -		if (entry->num < efi_menu->count - 2) {
> -			if (((struct eficonfig_boot_order_data *)entry->data)->active)
> -				printf("[*]  ");
> -			else
> -				printf("[ ]  ");
> -		}
> +	if (entry->num < entry->efi_menu->count - 2) {
> +		if (((struct eficonfig_boot_order_data *)entry->data)->active)
> +			printf("[*]  ");
> +		else
> +			printf("[ ]  ");
> +	}
>
> -		printf("%s", entry->title);
> +	printf("%s", entry->title);
>
> -		if (reverse)
> -			puts(ANSI_COLOR_RESET);
> -	}
> +	if (reverse)
> +		puts(ANSI_COLOR_RESET);
>  }
>
>  /**
> - * eficonfig_choice_change_boot_order() - handle the BootOrder update
> + * eficonfig_choice_change_boot_order() - user key input handler
>   *
> - * @efi_menu:	pointer to the efimenu structure
> - * Return:	status code
> + * @data:	pointer to the menu entry
> + * Return:	key string to identify the selected entry
>   */
> -static efi_status_t eficonfig_choice_change_boot_order(struct efimenu *efi_menu)
> +char *eficonfig_choice_change_boot_order(void *data)
>  {
>  	struct cli_ch_state s_cch, *cch = &s_cch;
>  	struct list_head *pos, *n;
> +	struct efimenu *efi_menu = data;
>  	enum bootmenu_key key = BKEY_NONE;
>  	struct eficonfig_entry *entry, *tmp;
>
> @@ -1926,7 +1922,7 @@ static efi_status_t eficonfig_choice_change_boot_order(struct efimenu *efi_menu)
>  		case BKEY_UP:
>  			if (efi_menu->active > 0)
>  				--efi_menu->active;
> -			return EFI_NOT_READY;
> +			return NULL;
>  		case BKEY_MINUS:
>  			if (efi_menu->active < efi_menu->count - 3) {
>  				list_for_each_safe(pos, n, &efi_menu->list) {
> @@ -1942,20 +1938,29 @@ static efi_status_t eficonfig_choice_change_boot_order(struct efimenu *efi_menu)
>
>  				++efi_menu->active;
>  			}
> -			return EFI_NOT_READY;
> +			return NULL;
>  		case BKEY_DOWN:
>  			if (efi_menu->active < efi_menu->count - 1)
>  				++efi_menu->active;
> -			return EFI_NOT_READY;
> +			return NULL;
>  		case BKEY_SELECT:
>  			/* "Save" */
> -			if (efi_menu->active == efi_menu->count - 2)
> -				return EFI_SUCCESS;
> -
> +			if (efi_menu->active == efi_menu->count - 2) {
> +				list_for_each_prev_safe(pos, n, &efi_menu->list) {
> +					entry = list_entry(pos, struct eficonfig_entry, list);
> +					if (entry->num == efi_menu->active)
> +						break;
> +				}
> +				return entry->key;
> +			}
>  			/* "Quit" */
> -			if (efi_menu->active == efi_menu->count - 1)
> -				return EFI_ABORTED;
> -
> +			if (efi_menu->active == efi_menu->count - 1) {
> +				entry = list_last_entry(&efi_menu->list,
> +							struct eficonfig_entry,
> +							list);
> +				return entry->key;
> +			}
> +			/* Pressed key is not valid, wait next key press */
>  			break;
>  		case BKEY_SPACE:
>  			if (efi_menu->active < efi_menu->count - 2) {
> @@ -1965,20 +1970,84 @@ static efi_status_t eficonfig_choice_change_boot_order(struct efimenu *efi_menu)
>  						struct eficonfig_boot_order_data *data = entry->data;
>
>  						data->active = !data->active;
> -						return EFI_NOT_READY;
> +						return NULL;
>  					}
>  				}
>  			}
> +			/* Pressed key is not valid, wait next key press */
>  			break;
>  		case BKEY_QUIT:
> -			return EFI_ABORTED;
> +			entry = list_last_entry(&efi_menu->list,
> +						struct eficonfig_entry, list);
> +			return entry->key;
>  		default:
> -			/* Pressed key is not valid, no need to regenerate the menu */
> +			/* Pressed key is not valid, wait next key press */
>  			break;
>  		}
>  	}
>  }
>
> +/**
> + * eficonfig_process_save_boot_order() - callback function for "Save" entry
> + *
> + * @data:	pointer to the data
> + * Return:	status code
> + */
> +static efi_status_t eficonfig_process_save_boot_order(void *data)
> +{
> +	u32 count = 0;
> +	efi_status_t ret;
> +	efi_uintn_t size;
> +	struct list_head *pos, *n;
> +	u16 *new_bootorder;
> +	struct efimenu *efi_menu;
> +	struct eficonfig_entry *entry;
> +	struct eficonfig_save_boot_order_data *save_data = data;
> +
> +	efi_menu = save_data->efi_menu;
> +
> +	/*
> +	 * The change boot order menu always has "Save" and "Quit" entries.
> +	 * !(efi_menu->count - 2) means there is no user defined boot option.
> +	 */
> +	if (!(efi_menu->count - 2))
> +		return EFI_SUCCESS;
> +
> +	new_bootorder = calloc(1, (efi_menu->count - 2) * sizeof(u16));
> +	if (!new_bootorder) {
> +		ret = EFI_OUT_OF_RESOURCES;
> +		goto out;
> +	}
> +
> +	/* create new BootOrder */
> +	count = 0;
> +	list_for_each_safe(pos, n, &efi_menu->list) {
> +		struct eficonfig_boot_order_data *data;
> +
> +		entry = list_entry(pos, struct eficonfig_entry, list);
> +		/* exit the loop when iteration reaches "Save" */
> +		if (!strncmp(entry->title, "Save", strlen("Save")))
> +			break;
> +
> +		data = entry->data;
> +		if (data->active)
> +			new_bootorder[count++] = data->boot_index;
> +	}
> +
> +	size = count * sizeof(u16);
> +	ret = efi_set_variable_int(u"BootOrder", &efi_global_variable_guid,
> +				   EFI_VARIABLE_NON_VOLATILE |
> +				   EFI_VARIABLE_BOOTSERVICE_ACCESS |
> +				   EFI_VARIABLE_RUNTIME_ACCESS,
> +				   size, new_bootorder, false);
> +
> +	save_data->selected = true;
> +out:
> +	free(new_bootorder);
> +
> +	return ret;
> +}
> +
>  /**
>   * eficonfig_add_change_boot_order_entry() - add boot order entry
>   *
> @@ -2054,6 +2123,7 @@ static efi_status_t eficonfig_create_change_boot_order_entry(struct efimenu *efi
>  	efi_status_t ret;
>  	u16 *var_name16 = NULL;
>  	efi_uintn_t size, buf_size;
> +	struct eficonfig_save_boot_order_data *save_data;
>
>  	/* list the load option in the order of BootOrder variable */
>  	for (i = 0; i < num; i++) {
> @@ -2104,7 +2174,17 @@ static efi_status_t eficonfig_create_change_boot_order_entry(struct efimenu *efi
>  		goto out;
>  	}
>
> -	ret = eficonfig_append_menu_entry(efi_menu, title, NULL, NULL);
> +	save_data = malloc(sizeof(struct eficonfig_save_boot_order_data));
> +	if (!save_data) {
> +		ret = EFI_OUT_OF_RESOURCES;
> +		goto out;
> +	}
> +	save_data->efi_menu = efi_menu;
> +	save_data->selected = false;
> +
> +	ret = eficonfig_append_menu_entry(efi_menu, title,
> +					  eficonfig_process_save_boot_order,
> +					  save_data);
>  	if (ret != EFI_SUCCESS)
>  		goto out;
>
> @@ -2127,7 +2207,6 @@ out:
>   */
>  static efi_status_t eficonfig_process_change_boot_order(void *data)
>  {
> -	u32 count;
>  	u16 *bootorder;
>  	efi_status_t ret;
>  	efi_uintn_t num, size;
> @@ -2148,47 +2227,24 @@ static efi_status_t eficonfig_process_change_boot_order(void *data)
>  		goto out;
>
>  	while (1) {
> -		eficonfig_display_change_boot_order(efi_menu);
> -
> -		ret = eficonfig_choice_change_boot_order(efi_menu);
> -		if (ret == EFI_SUCCESS) {
> -			u16 *new_bootorder;
> -
> -			new_bootorder = calloc(1, (efi_menu->count - 2) * sizeof(u16));
> -			if (!new_bootorder) {
> -				ret = EFI_OUT_OF_RESOURCES;
> -				goto out;
> -			}
> -
> -			/* create new BootOrder  */
> -			count = 0;
> -			list_for_each_safe(pos, n, &efi_menu->list) {
> -				struct eficonfig_boot_order_data *data;
> -
> +		ret = eficonfig_process_common(efi_menu,
> +					       "  ** Change Boot Order **",
> +					       eficonfig_change_boot_order_desc,
> +					       eficonfig_display_statusline,
> +					       eficonfig_print_change_boot_order_entry,
> +					       eficonfig_choice_change_boot_order);
> +		/* exit from the menu if user selects the "Save" entry. */
> +		if (ret == EFI_SUCCESS && efi_menu->active == (efi_menu->count - 2)) {
> +			list_for_each_prev_safe(pos, n, &efi_menu->list) {
>  				entry = list_entry(pos, struct eficonfig_entry, list);
> -				/* exit the loop when iteration reaches "Save" */
> -				if (!strncmp(entry->title, "Save", strlen("Save")))
> +				if (entry->num == efi_menu->active)
>  					break;
> -
> -				data = entry->data;
> -				if (data->active)
> -					new_bootorder[count++] = data->boot_index;
>  			}
> -
> -			size = count * sizeof(u16);
> -			ret = efi_set_variable_int(u"BootOrder", &efi_global_variable_guid,
> -						   EFI_VARIABLE_NON_VOLATILE |
> -						   EFI_VARIABLE_BOOTSERVICE_ACCESS |
> -						   EFI_VARIABLE_RUNTIME_ACCESS,
> -						   size, new_bootorder, false);
> -
> -			free(new_bootorder);
> -			goto out;
> -		} else if (ret == EFI_NOT_READY) {
> -			continue;
> -		} else {
> -			goto out;
> +			if (((struct eficonfig_save_boot_order_data *)entry->data)->selected)
> +				break;
>  		}
> +		if (ret != EFI_SUCCESS)
> +			break;
>  	}
>  out:
>  	free(bootorder);
> --
> 2.17.1
>
Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>


  reply	other threads:[~2023-01-23 15:42 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-20  8:43 [PATCH v4 0/4] eficonfig: add vertical scroll support and refactoring Masahisa Kojima
2023-01-20  8:43 ` [PATCH v4 1/4] eficonfig: refactor eficonfig_process_common function Masahisa Kojima
2023-01-23 13:04   ` Ilias Apalodimas
2023-01-20  8:43 ` [PATCH v4 2/4] eficonfig: refactor change boot order implementation Masahisa Kojima
2023-01-23 14:57   ` Ilias Apalodimas [this message]
2023-01-20  8:43 ` [PATCH v4 3/4] eficonfig: add vertical scroll support Masahisa Kojima
2023-01-23 15:07   ` Ilias Apalodimas
2023-01-24  4:43     ` Masahisa Kojima
2023-01-20  8:43 ` [PATCH v4 4/4] eficonfig: increase the number of menu entries Masahisa Kojima
2023-01-23 15:08   ` Ilias Apalodimas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Y86gc4LzlJql4uUr@hera \
    --to=ilias.apalodimas@linaro.org \
    --cc=masahisa.kojima@linaro.org \
    --cc=u-boot@lists.denx.de \
    --cc=xypron.glpk@gmx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.