]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - common/env_eeprom.c
New implementation for internal handling of environment variables.
[karo-tx-uboot.git] / common / env_eeprom.c
index 95a7d0d3bc993d84fb5ade0b1a2642e45070d70f..792b44ffabb898f85cb15ec8ecb25656cc3efcd6 100644 (file)
@@ -1,10 +1,10 @@
 /*
- * (C) Copyright 2000-2002
+ * (C) Copyright 2000-2010
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
  * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  * Andreas Heppel <aheppel@sysgo.de>
-
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
 #if defined(CONFIG_I2C_ENV_EEPROM_BUS)
 #include <i2c.h>
 #endif
-
-#ifdef CONFIG_ENV_OFFSET_REDUND
-#define ACTIVE_FLAG   1
-#define OBSOLETE_FLAG 0
-#endif
+#include <search.h>
+#include <errno.h>
+#include <linux/compiler.h>    /* for BUG_ON */
 
 DECLARE_GLOBAL_DATA_PTR;
 
 env_t *env_ptr = NULL;
 
-char * env_name_spec = "EEPROM";
+char *env_name_spec = "EEPROM";
 int env_eeprom_bus = -1;
 
-static int eeprom_bus_read (unsigned dev_addr, unsigned offset, uchar *buffer,
-                               unsigned cnt)
+static int eeprom_bus_read(unsigned dev_addr, unsigned offset,
+       uchar *buffer, unsigned cnt)
 {
        int rcode;
 #if defined(CONFIG_I2C_ENV_EEPROM_BUS)
@@ -56,9 +54,9 @@ static int eeprom_bus_read (unsigned dev_addr, unsigned offset, uchar *buffer,
                        I2C_MUX_DEVICE *dev = NULL;
                        dev = i2c_mux_ident_muxstring(
                                (uchar *)CONFIG_I2C_ENV_EEPROM_BUS);
-                       if (dev != NULL) {
+                       if (dev != NULL)
                                env_eeprom_bus = dev->busid;
-                       else
+                       else
                                printf ("error adding env eeprom bus.\n");
                }
                if (old_bus != env_eeprom_bus) {
@@ -72,6 +70,7 @@ static int eeprom_bus_read (unsigned dev_addr, unsigned offset, uchar *buffer,
 #endif
 
        rcode = eeprom_read (dev_addr, offset, buffer, cnt);
+
 #if defined(CONFIG_I2C_ENV_EEPROM_BUS)
        if (old_bus != env_eeprom_bus)
                i2c_set_bus_num(old_bus);
@@ -79,8 +78,8 @@ static int eeprom_bus_read (unsigned dev_addr, unsigned offset, uchar *buffer,
        return rcode;
 }
 
-static int eeprom_bus_write (unsigned dev_addr, unsigned offset, uchar *buffer,
-                               unsigned cnt)
+static int eeprom_bus_write(unsigned dev_addr, unsigned offset,
+       uchar *buffer, unsigned cnt)
 {
        int rcode;
 #if defined(CONFIG_I2C_ENV_EEPROM_BUS)
@@ -88,7 +87,7 @@ static int eeprom_bus_write (unsigned dev_addr, unsigned offset, uchar *buffer,
 
        rcode = i2c_mux_ident_muxstring_f((uchar *)CONFIG_I2C_ENV_EEPROM_BUS);
 #endif
-       rcode = eeprom_write (dev_addr, offset, buffer, cnt);
+       rcode = eeprom_write(dev_addr, offset, buffer, cnt);
 #if defined(CONFIG_I2C_ENV_EEPROM_BUS)
        i2c_set_bus_num(old_bus);
 #endif
@@ -100,12 +99,12 @@ uchar env_get_char_spec (int index)
        uchar c;
        unsigned int off;
        off = CONFIG_ENV_OFFSET;
+
 #ifdef CONFIG_ENV_OFFSET_REDUND
        if (gd->env_valid == 2)
                off = CONFIG_ENV_OFFSET_REDUND;
 #endif
-
-       eeprom_bus_read (CONFIG_SYS_DEF_EEPROM_ADDR,
+       eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR,
                     off + index + offsetof(env_t,data),
                     &c, 1);
 
@@ -114,40 +113,60 @@ uchar env_get_char_spec (int index)
 
 void env_relocate_spec (void)
 {
+       char buf[CONFIG_ENV_SIZE];
        unsigned int off = CONFIG_ENV_OFFSET;
+
 #ifdef CONFIG_ENV_OFFSET_REDUND
        if (gd->env_valid == 2)
                off = CONFIG_ENV_OFFSET_REDUND;
 #endif
-       eeprom_bus_read (CONFIG_SYS_DEF_EEPROM_ADDR,
+       eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR,
                     off,
-                    (uchar*)env_ptr,
+                    (uchar *)buf,
                     CONFIG_ENV_SIZE);
+
+       env_import(buf, 1);
 }
 
 int saveenv(void)
 {
+       env_t   env_new;
+       ssize_t len;
+       char    *res;
        int rc;
        unsigned int off = CONFIG_ENV_OFFSET;
 #ifdef CONFIG_ENV_OFFSET_REDUND
        unsigned int off_red = CONFIG_ENV_OFFSET_REDUND;
        char flag_obsolete = OBSOLETE_FLAG;
+#endif
+
+       BUG_ON(env_ptr != NULL);
+
+       res = (char *)&env_new.data;
+       len = hexport('\0', &res, ENV_SIZE);
+       if (len < 0) {
+               error("Cannot export environment: errno = %d\n", errno);
+               return 1;
+       }
+       env_new.crc = crc32(0, env_new.data, ENV_SIZE);
+
+#ifdef CONFIG_ENV_OFFSET_REDUND
        if (gd->env_valid == 1) {
                off = CONFIG_ENV_OFFSET_REDUND;
                off_red = CONFIG_ENV_OFFSET;
        }
 
-       env_ptr->flags = ACTIVE_FLAG;
+       env_new.flags = ACTIVE_FLAG;
 #endif
 
-       rc = eeprom_bus_write (CONFIG_SYS_DEF_EEPROM_ADDR,
+       rc = eeprom_bus_write(CONFIG_SYS_DEF_EEPROM_ADDR,
                             off,
-                            (uchar *)env_ptr,
+                            (uchar *)&env_new,
                             CONFIG_ENV_SIZE);
 
 #ifdef CONFIG_ENV_OFFSET_REDUND
        if (rc == 0) {
-               eeprom_bus_write (CONFIG_SYS_DEF_EEPROM_ADDR,
+               eeprom_bus_write(CONFIG_SYS_DEF_EEPROM_ADDR,
                                  off_red + offsetof(env_t,flags),
                                  (uchar *)&flag_obsolete,
                                  1);
@@ -162,10 +181,10 @@ int saveenv(void)
        return rc;
 }
 
-/************************************************************************
+/*
  * Initialize Environment use
  *
- * We are still running from ROM, so data use is limited
+ * We are still running from ROM, so data use is limited.
  * Use a (moderately small) buffer on the stack
  */
 
@@ -180,31 +199,31 @@ int env_init(void)
        unsigned char flags[2];
        int i;
 
-       eeprom_init (); /* prepare for EEPROM read/write */
+       eeprom_init();  /* prepare for EEPROM read/write */
 
        off_env[0] = CONFIG_ENV_OFFSET;
        off_env[1] = CONFIG_ENV_OFFSET_REDUND;
 
        for (i = 0; i < 2; i++) {
                /* read CRC */
-               eeprom_bus_read (CONFIG_SYS_DEF_EEPROM_ADDR,
+               eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR,
                        off_env[i] + offsetof(env_t,crc),
                        (uchar *)&crc[i], sizeof(ulong));
                /* read FLAGS */
-               eeprom_bus_read (CONFIG_SYS_DEF_EEPROM_ADDR,
+               eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR,
                        off_env[i] + offsetof(env_t,flags),
                        (uchar *)&flags[i], sizeof(uchar));
 
-               crc_tmp= 0;
+               crc_tmp = 0;
                len = ENV_SIZE;
                off = off_env[i] + offsetof(env_t,data);
                while (len > 0) {
                        int n = (len > sizeof(buf)) ? sizeof(buf) : len;
 
-                       eeprom_bus_read (CONFIG_SYS_DEF_EEPROM_ADDR, off,
+                       eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR, off,
                                buf, n);
 
-                       crc_tmp = crc32 (crc_tmp, buf, n);
+                       crc_tmp = crc32(crc_tmp, buf, n);
                        len -= n;
                        off += n;
                }
@@ -250,22 +269,23 @@ int env_init(void)
        unsigned off;
        uchar buf[64];
 
-       eeprom_init (); /* prepare for EEPROM read/write */
+       eeprom_init();  /* prepare for EEPROM read/write */
 
        /* read old CRC */
-       eeprom_bus_read (CONFIG_SYS_DEF_EEPROM_ADDR,
+       eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR,
                     CONFIG_ENV_OFFSET+offsetof(env_t,crc),
                     (uchar *)&crc, sizeof(ulong));
 
        new = 0;
        len = ENV_SIZE;
        off = offsetof(env_t,data);
+
        while (len > 0) {
                int n = (len > sizeof(buf)) ? sizeof(buf) : len;
 
-               eeprom_bus_read (CONFIG_SYS_DEF_EEPROM_ADDR,
+               eeprom_bus_read(CONFIG_SYS_DEF_EEPROM_ADDR,
                                CONFIG_ENV_OFFSET + off, buf, n);
-               new = crc32 (new, buf, n);
+               new = crc32(new, buf, n);
                len -= n;
                off += n;
        }
@@ -281,4 +301,3 @@ int env_init(void)
        return (0);
 }
 #endif
-