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);