2 * NVRAM variable manipulation (Linux user mode half)
4 * Copyright 2004, Broadcom Corporation
7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
21 #include <sys/ioctl.h>
22 #include <sys/types.h>
29 #include <nvram_convert.h>
33 #define PATH_DEV_NVRAM "/dev/nvram"
36 static int nvram_fd = -1;
37 static char *nvram_buf = NULL;
38 int check_action(void);
39 int file_to_buf(char *path, char *buf, int len);
42 nvram_init(void *unused)
44 if ((nvram_fd = open(PATH_DEV_NVRAM, O_RDWR)) < 0)
47 /* Map kernel string buffer into user space */
48 if ((nvram_buf = mmap(NULL, NVRAM_SPACE, PROT_READ, MAP_SHARED, nvram_fd, 0)) == MAP_FAILED) {
57 perror(PATH_DEV_NVRAM);
62 nvram_get(const char *name)
64 size_t count = strlen(name) + 1;
65 char tmp[100], *value;
66 unsigned long *off = (unsigned long *) tmp;
72 if (count > sizeof(tmp)) {
73 if (!(off = malloc(count)))
77 /* Get offset into mmap() space */
78 strcpy((char *) off, name);
80 count = read(nvram_fd, off, count);
82 if (count == sizeof(unsigned long))
83 value = &nvram_buf[*off];
88 perror(PATH_DEV_NVRAM);
90 if (off != (unsigned long *) tmp)
97 nvram_getall(char *buf, int count)
102 if ((ret = nvram_init(NULL)))
108 /* Get all variables */
111 ret = read(nvram_fd, buf, count);
114 perror(PATH_DEV_NVRAM);
116 return (ret == count) ? 0 : ret;
120 _nvram_set(const char *name, const char *value)
122 size_t count = strlen(name) + 1;
123 char tmp[100], *buf = tmp;
127 if ((ret = nvram_init(NULL)))
130 /* Unset if value is NULL */
132 count += strlen(value) + 1;
134 if (count > sizeof(tmp)) {
135 if (!(buf = malloc(count)))
140 sprintf(buf, "%s=%s", name, value);
144 ret = write(nvram_fd, buf, count);
147 perror(PATH_DEV_NVRAM);
152 return (ret == count) ? 0 : ret;
156 nvram_set(const char *name, const char *value)
158 extern struct nvram_convert nvram_converts[];
159 struct nvram_convert *v;
162 ret = _nvram_set(name, value);
164 for(v = nvram_converts ; v->name ; v++) {
165 if(!strcmp(v->name, name)){
166 if(strcmp(v->wl0_name,"")) _nvram_set(v->wl0_name, value);
167 if(strcmp(v->d11g_name,"")) _nvram_set(v->d11g_name, value);
175 nvram_unset(const char *name)
177 return _nvram_set(name, NULL);
185 cprintf("nvram_commit(): start\n");
187 if((check_action() == ACT_IDLE) ||
188 (check_action() == ACT_SW_RESTORE) ||
189 (check_action() == ACT_HW_RESTORE)){
191 if ((ret = nvram_init(NULL)))
194 ret = ioctl(nvram_fd, NVRAM_MAGIC, NULL);
197 perror(PATH_DEV_NVRAM);
199 cprintf("nvram_commit(): end\n");
202 cprintf("nvram_commit(): nothing to do...\n");
207 int file2nvram(char *filename, char *varname) {
211 char mem[10000],buf[30000];
213 if ( !(fp=fopen(filename,"rb") ))
216 count=fread(mem,1,sizeof(mem),fp);
218 for (j=0;j<count;j++) {
219 if (i > sizeof(buf)-3 )
222 if (c >= 32 && c <= 126 && c != '\\' && c != '~') {
223 buf[i++]=(unsigned char) c;
228 sprintf(buf+i,"%02X",c);
234 //fprintf(stderr,"================ > file2nvram %s = [%s] \n",varname,buf);
235 nvram_set(varname,buf);
236 //nvram_commit(); //Barry adds for test
239 int nvram2file(char *varname, char *filename) {
246 if ( !(fp=fopen(filename,"wb") ))
249 buf=strdup(nvram_safe_get(varname));
250 //fprintf(stderr,"=================> nvram2file %s = [%s] \n",varname,buf);
251 while ( buf[i] && j < sizeof(mem)-3 ) {
252 if (buf[i] == '\\') {
256 sscanf(buf+i,"%02X",&c);
260 } else if (buf[i] == '~') {
269 j=fwrite(mem,1,j,fp);
280 if(file_to_buf(ACTION_FILE, buf, sizeof(buf))){
281 if(!strcmp(buf, "ACT_TFTP_UPGRADE")){
282 cprintf("Upgrading from tftp now, quiet exit....\n");
283 return ACT_TFTP_UPGRADE;
285 else if(!strcmp(buf, "ACT_WEBS_UPGRADE")){
286 cprintf("Upgrading from web (https) now, quiet exit....\n");
287 return ACT_WEBS_UPGRADE;
289 else if(!strcmp(buf, "ACT_WEB_UPGRADE")){
290 cprintf("Upgrading from web (http) now, quiet exit....\n");
291 return ACT_WEB_UPGRADE;
293 else if(!strcmp(buf, "ACT_SW_RESTORE")){
294 cprintf("Receive restore command from web, quiet exit....\n");
295 return ACT_SW_RESTORE;
297 else if(!strcmp(buf, "ACT_HW_RESTORE")){
298 cprintf("Receive restore commond from resetbutton, quiet exit....\n");
299 return ACT_HW_RESTORE;
302 //fprintf(stderr, "Waiting for upgrading....\n");
307 file_to_buf(char *path, char *buf, int len)
311 memset(buf, 0 , len);
313 if ((fp = fopen(path, "r"))) {