9
0
Fork 0

svn_rev_386

remove old saveenv, allow setenv/getenv to change device parameters
This commit is contained in:
Sascha Hauer 2007-07-05 18:01:49 +02:00 committed by Sascha Hauer
parent f6feb18cdc
commit 20294d061c
1 changed files with 40 additions and 176 deletions

View File

@ -2,11 +2,9 @@
#include <command.h>
#include <driver.h>
#include <malloc.h>
#include <xfuncs.h>
#include <errno.h>
static ulong env_size;
static char *env_name_spec;
struct variable_d {
struct variable_d *next;
char data[0];
@ -14,7 +12,8 @@ struct variable_d {
#define VARIABLE_D_SIZE(name, value) (sizeof(struct variable_d) + strlen(name) + strlen(value) + 2)
static struct variable_d *env_list;
static struct variable_d _env_list;
static struct variable_d *env_list = &_env_list;
static char *var_val(struct variable_d *var)
{
@ -30,10 +29,20 @@ char *getenv (const char *name)
{
struct variable_d *var;
if (!env_list) {
printf("getenv(%s): not initialized\n",name);
return NULL;
}
if (strchr(name, '.')) {
char *ret = 0;
char *devstr = strdup(name);
char *par = strchr(devstr, '.');
struct device_d *dev;
*par = 0;
dev = get_device_by_id(devstr);
if (dev) {
par++;
ret = dev_get_param(dev, par);
}
free(devstr);
return ret;
}
var = env_list->next;
@ -45,25 +54,32 @@ char *getenv (const char *name)
return 0;
}
void setenv (const char *name, const char *value)
int setenv (const char *name, const char *value)
{
struct variable_d *var = env_list;
struct variable_d *newvar = NULL;
char *par;
if (!env_list) {
printf("setenv(%s): not initialized\n",name);
return;
}
if ((par = strchr(name, '.'))) {
struct device_d *dev;
*par++ = 0;
dev = get_device_by_id(name);
if (dev) {
int ret = dev_set_param(dev, par, value);
if (ret < 0)
perror("set parameter");
errno = 0;
} else {
errno = -ENODEV;
perror("set parameter");
}
return errno;
}
if (value) {
newvar = malloc(VARIABLE_D_SIZE(name, value));
if (!newvar) {
printf("cannot setenv: out of mem\n");
return;
}
newvar = xzalloc(VARIABLE_D_SIZE(name, value));
strcpy(&newvar->data[0], name);
strcpy(&newvar->data[strlen(name) + 1], value);
newvar->next = NULL;
}
while (var->next) {
@ -72,161 +88,20 @@ void setenv (const char *name, const char *value)
newvar->next = var->next->next;
free(var->next);
var->next = newvar;
return;
return 0;
} else {
struct variable_d *tmp;
tmp = var->next;
var->next = var->next->next;
free(var->next);
return;
return 0;
}
}
var = var->next;
}
var->next = newvar;
}
int add_env_spec(char *spec)
{
char *env;
char *data;
int err;
unsigned long crc;
struct memarea_info info;
printf("%s\n",__FUNCTION__);
if (spec_str_to_info(spec, &info)) {
printf("-ENOPARSE\n");
return -1;
}
/* Do it the simple way for now: Assume that the whole
* environment sector plus the environment list fits in
* memory.
*/
env_size = info.size;
env_name_spec = spec;
env = malloc(env_size);
if (!env) {
err = -ENOMEM;
goto err_out;
}
env_list = malloc(sizeof(struct variable_d));
if (!env_list) {
err = -ENOMEM;
goto err_out;
}
env_list->next = NULL;
err = dev_read(info.device, env, env_size, info.start, 0);
if (err != env_size)
goto err_out;
/* Make sure we don't go crazy with a corrupted environment */
*(env + env_size - 1) = 0;
*(env + env_size - 2) = 0;
crc = *(ulong *)env;
if (crc != crc32(0, env + sizeof(ulong), env_size - sizeof(ulong))) {
printf("environment is corrupt\n");
err = -ENODEV;
goto err_out;
}
data = env + sizeof(env);
while(*data) {
char *delim = strchr(data, '=');
int len = strlen(data);
printf("data: %s\n", data);
if (!delim)
goto err_out;
*delim = 0;
setenv(data, delim + 1);
data += len + 1;
}
free(env);
return 0;
err_out:
printf("error\n");
return -1;
}
int saveenv(void)
{
struct variable_d *var = env_list->next;
struct memarea_info info;
unsigned char *env;
int left, ret = 0, ofs;
if (spec_str_to_info(env_name_spec, &info)) {
printf("-ENOPARSE\n");
return -1;
}
env = malloc(env_size);
if (!env) {
printf("out of memory\n");
ret = -ENOMEM;
goto err_out;
}
memset(env, 0, env_size);
left = env_size - 2;
ofs = 4;
while (var) {
int nlen = strlen(var_name(var));
int vlen = strlen(var_val(var));
if (ofs + nlen + 1 + vlen + 2 >= env_size) {
printf("no space left in environment\n");
ret = -ENOSPC;
goto err_out;
}
strcpy(env + ofs, var_name(var));
ofs += nlen;
*(env + ofs) = '=';
ofs++;
strcpy(env + ofs, var_val(var));
ofs += vlen + 1;
var = var->next;
}
*(ulong *)env = crc32(0, env + sizeof(ulong), env_size - sizeof(ulong));
ret = dev_erase(info.device, info.size, info.start);
if (ret) {
printf("unable to erase\n");
goto err_out;
}
ret = dev_write(info.device, env, info.size, info.start, 0);
if (ret < 0) {
printf("unable to write\n");
goto err_out;
}
free(env);
return 0;
err_out:
if (env)
free(env);
return ret;
return 0;
}
int do_printenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
@ -259,6 +134,7 @@ U_BOOT_CMD(
" - print value of environment variable 'name'\n"
);
#ifdef CONFIG_SIMPLE_PARSER
int do_setenv ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
if (argc < 2) {
@ -279,17 +155,5 @@ U_BOOT_CMD(
"setenv name\n"
" - delete environment variable 'name'\n"
);
int do_saveenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
printf ("Saving Environment to %s...\n", env_name_spec);
return saveenv();
}
U_BOOT_CMD(
saveenv, 1, 0, do_saveenv,
"saveenv - save environment variables to persistent storage\n",
NULL
);
#endif