WindCharger: Fixes up shared variable behavior.
Before if clearing sysvar, everything that COULD be shared with uboot
env would be deleted. Now it only deletes variables that are shared.
Change-Id: Icf51ed24d803eb0a8ce4fb1f25945e83c1664832
diff --git a/common/cmd_sysvar.c b/common/cmd_sysvar.c
index 0353835..99a6664 100644
--- a/common/cmd_sysvar.c
+++ b/common/cmd_sysvar.c
@@ -309,6 +309,131 @@
}
////////////////////////////////////////////////////////////////////////////////
+// Sysvar/Uboot Integration
+////////////////////////////////////////////////////////////////////////////////
+
+/*
+ * sysvar_buf_init - Initializes a sysvar_buf struct.
+ */
+static int sysvar_buf_init(struct sysvar_buf *buf, bool is_ro) {
+ if (buf == NULL) {
+ return SYSVAR_PARAM_ERR;
+ }
+ memset(buf, 0, sizeof(*buf));
+ buf->list = (struct sysvar_list *)malloc(sizeof(struct sysvar_list));
+ if (buf->list == NULL) {
+ printf("list allocation ");
+ return SYSVAR_MEMORY_ERR;
+ }
+ buf->data = (uchar *) map_physmem(is_ro ? SYSVAR_RO_MEM : SYSVAR_RW_MEM);
+ if (buf->data == NULL) {
+ printf("data allocation ");
+ free(buf->list);
+ return SYSVAR_MEMORY_ERR;
+ }
+
+ buf->data_len = SYSVAR_BLOCK_SIZE;
+ buf->total_len = SYSVAR_BLOCK_SIZE - SYSVAR_HEAD;
+ buf->free_len = buf->total_len;
+ buf->readonly = is_ro;
+
+ strncpy(buf->list->name, is_ro ? "ro" : "rw", SYSVAR_NAME);
+ buf->list->value = NULL;
+ buf->list->len = SYSVAR_NAME + 2;
+ buf->list->next = NULL;
+ buf->loaded = false;
+ return SYSVAR_SUCCESS;
+}
+
+/*
+ * sysvar_env_clear_shared - Takes sysvar buf and clears anything that may be
+ * mapped to the uboot env. Does not delete any sysvar variables.
+ */
+static void sysvar_env_clear_shared(struct sysvar_buf *buf) {
+ struct sysvar_list *curr = buf->list->next;
+ while (curr != NULL) {
+ /* Only clear env variables for shared vars. */
+ set_sysvar_uboot(curr->name, NULL);
+ curr = curr->next;
+ }
+}
+
+/*
+ * sysvar_uboot_env_clear - Clears all potential uboot shared variables
+ * from the environment.
+ */
+void sysvar_uboot_env_clear(void) {
+ int i;
+ for (i = 0; i < ARRAY_SIZE(su_mappings); ++i) {
+ setenv(su_mappings[i].uboot_name, NULL);
+ }
+}
+
+/* Helper function for sysvar_uboot_env_load. */
+static void _sysvar_uboot_env_load(struct sysvar_buf *buf) {
+ struct sysvar_list *curr = buf->list->next;
+ while (curr != NULL) {
+ /* Should only set env variables for special vars. */
+ set_sysvar_uboot(curr->name, curr->value);
+ curr = curr->next;
+ }
+}
+
+/*
+ * sysvar_uboot_env_load - Loads sysvar/uboot shared variables to the
+ * uboot environment.
+ */
+void sysvar_uboot_env_load(void) {
+ _sysvar_uboot_env_load(&ro_buf);
+ _sysvar_uboot_env_load(&rw_buf);
+}
+
+int sysvar_init(void) {
+ printf("sysvar_init. . . ");
+ if (sysvar_buf_init(&rw_buf, false) || sysvar_buf_init(&ro_buf, true) ||
+ sf_loadvar(&rw_buf, SYSVAR_RW_BUF) ||
+ sf_loadvar(&ro_buf, SYSVAR_RO_BUF)) {
+ printf("init failure!\n");
+ return SYSVAR_MEMORY_ERR;
+ }
+ sysvar_uboot_env_load();
+ printf("success!\n");
+ return SYSVAR_SUCCESS;
+}
+
+int is_sysvar_shared(const char *var) {
+ int i;
+ for (i = 0; i < ARRAY_SIZE(su_mappings); ++i) {
+ if (strcmp(var, su_mappings[i].uboot_name) == 0 ||
+ strcmp(var, su_mappings[i].sysvar_name) == 0) {
+ return true;
+ }
+ }
+ return false;
+}
+
+const char *get_uboot_name(const char *sysvar_name) {
+ int i;
+ for (i = 0; i < ARRAY_SIZE(su_mappings); ++i) {
+ if (strcmp(sysvar_name, su_mappings[i].sysvar_name) == 0) {
+ return su_mappings[i].uboot_name;
+ }
+ }
+ return NULL;
+}
+
+/*
+ * set_sysvar_uboot - Sets the given variable to the value specified in the
+ * uboot env if sysvar name is shared with uboot.
+ */
+void set_sysvar_uboot(const char *var, const char *value) {
+ char *uboot_name = get_uboot_name(var);
+ if (uboot_name) {
+ setenv(uboot_name, value);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
// Sysvar Flash Impl Functions
////////////////////////////////////////////////////////////////////////////////
@@ -537,13 +662,6 @@
" - print value of system variable 'name'\n"
);
-void set_sysvar_uboot(const char *var, const char *name) {
- char *uboot_name = get_uboot_name(var);
- if (uboot_name) {
- setenv(uboot_name, name);
- }
-}
-
/*
* do_flsetvar - add or delete system variables(RW)
*
@@ -572,8 +690,8 @@
} else {
/* delete all system variables(RW) */
printf("SV: deleting all RW vars. . .\n");
+ sysvar_env_clear_shared(&rw_buf);
ret = sf_setvar(&rw_buf, SYSVAR_RW_BUF, NULL, NULL);
- delete_uboot_vars();
}
print_err(ret, argc > 1 ? argv[1] : NULL);
return ret;
@@ -612,6 +730,7 @@
} else if (argc == 2) {
/* delete all system variables(RO) */
printf("SV: deleting all RO vars. . .\n");
+ sysvar_env_clear_shared(&ro_buf);
ret = sf_setvar(&ro_buf, SYSVAR_RO_BUF, NULL, NULL);
} else {
goto usage;
@@ -680,93 +799,3 @@
"sysvar erase 0|1|2|3\n"
" - erase data on SPI flash 0|1|2|3\n"
);
-
-////////////////////////////////////////////////////////////////////////////////
-// Sysvar/Uboot Integration
-////////////////////////////////////////////////////////////////////////////////
-
-/*
- * sysvar_buf_init - Initializes a sysvar_buf struct.
- */
-static int sysvar_buf_init(struct sysvar_buf *buf, bool is_ro) {
- if (buf == NULL) {
- return SYSVAR_PARAM_ERR;
- }
- memset(buf, 0, sizeof(*buf));
- buf->list = (struct sysvar_list *)malloc(sizeof(struct sysvar_list));
- if (buf->list == NULL) {
- printf("list allocation ");
- return SYSVAR_MEMORY_ERR;
- }
- buf->data = (uchar *) map_physmem(is_ro ? SYSVAR_RO_MEM : SYSVAR_RW_MEM);
- if (buf->data == NULL) {
- printf("data allocation ");
- free(buf->list);
- return SYSVAR_MEMORY_ERR;
- }
-
- buf->data_len = SYSVAR_BLOCK_SIZE;
- buf->total_len = SYSVAR_BLOCK_SIZE - SYSVAR_HEAD;
- buf->free_len = buf->total_len;
- buf->readonly = is_ro;
-
- strncpy(buf->list->name, is_ro ? "ro" : "rw", SYSVAR_NAME);
- buf->list->value = NULL;
- buf->list->len = SYSVAR_NAME + 2;
- buf->list->next = NULL;
- buf->loaded = false;
- return SYSVAR_SUCCESS;
-}
-
-static void sysvar_env_init(struct sysvar_buf *buf) {
- struct sysvar_list *curr = buf->list->next;
- while (curr != NULL) {
- /* Should only set env variables for special vars. */
- set_sysvar_uboot(curr->name, curr->value);
- curr = curr->next;
- }
-}
-
-int sysvar_init(void) {
- printf("sysvar_init. . . ");
- if (sysvar_buf_init(&rw_buf, false) || sysvar_buf_init(&ro_buf, true) ||
- sf_loadvar(&rw_buf, SYSVAR_RW_BUF) ||
- sf_loadvar(&ro_buf, SYSVAR_RO_BUF)) {
- printf("init failure!\n");
- return SYSVAR_MEMORY_ERR;
- }
- sysvar_env_init(&rw_buf);
- sysvar_env_init(&ro_buf);
- printf("success!\n");
- return SYSVAR_SUCCESS;
-}
-
-int is_sysvar_shared(const char *var) {
- int i;
- for (i = 0; i < ARRAY_SIZE(su_mappings); ++i) {
- if (strcmp(var, su_mappings[i].uboot_name) == 0 ||
- strcmp(var, su_mappings[i].sysvar_name) == 0) {
- return true;
- }
- }
- return false;
-}
-
-const char *get_uboot_name(const char *sysvar_name) {
- int i;
- for (i = 0; i < ARRAY_SIZE(su_mappings); ++i) {
- if (strcmp(sysvar_name, su_mappings[i].sysvar_name) == 0) {
- return su_mappings[i].uboot_name;
- }
- }
- return NULL;
-}
-
-void delete_uboot_vars(void) {
- int i;
- for (i = 0; i < ARRAY_SIZE(su_mappings); ++i) {
- setenv(su_mappings[i].sysvar_name, NULL);
- setenv(su_mappings[i].uboot_name, NULL);
- }
-}
-
diff --git a/common/env_dataflash.c b/common/env_dataflash.c
index 0b77d99..aa4f4fa 100755
--- a/common/env_dataflash.c
+++ b/common/env_dataflash.c
@@ -58,9 +58,11 @@
/* env must be copied to do not alter env structure in memory*/
unsigned char temp[CFG_ENV_SIZE];
int i;
- /* Delete special sysvar-only variables. */
- delete_uboot_vars();
+ /* Deletes anything that can be shared with sysvar, then restores it. */
+ sysvar_uboot_env_clear();
memcpy(temp, env_ptr, CFG_ENV_SIZE);
+ env_restore_defaults();
+ sysvar_uboot_env_load();
return write_dataflash (CFG_ENV_ADDR, (unsigned long)temp, CFG_ENV_SIZE);
}
diff --git a/include/common.h b/include/common.h
index 2d7aa6c..4a43e59 100755
--- a/include/common.h
+++ b/include/common.h
@@ -221,7 +221,8 @@
int sysvar_init(void);
int is_sysvar_shared(const char *var);
const char *get_uboot_name(const char *sysvar_name);
-void delete_uboot_vars(void);
+void sysvar_uboot_env_clear(void);
+void sysvar_uboot_env_load(void);
/* common/env_common.c */
int env_restore_defaults(void);