Enable wl500gp workaround to enable 32MB ram (#864)
[openwrt-10.03/.git] / package / nvram / src / nvram.c
1 /*
2  * NVRAM variable manipulation (Linux user mode half)
3  *
4  * Copyright 2004, Broadcom Corporation
5  * All Rights Reserved.
6  * 
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.
11  *
12  * $Id$
13  */
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <unistd.h>
18 #include <errno.h>
19 #include <error.h>
20 #include <string.h>
21 #include <sys/ioctl.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25 #include <sys/mman.h>
26
27 #include <typedefs.h>
28 #include <bcmnvram.h>
29 #include <shutils.h>
30
31 #define PATH_DEV_NVRAM "/dev/nvram"
32
33 /* Globals */
34 static int nvram_fd = -1;
35 static char *nvram_buf = NULL;
36 int file_to_buf(char *path, char *buf, int len);
37
38 int
39 nvram_init(void *unused)
40 {
41         if ((nvram_fd = open(PATH_DEV_NVRAM, O_RDWR)) < 0)
42                 goto err;
43
44         /* Map kernel string buffer into user space */
45         if ((nvram_buf = mmap(NULL, NVRAM_SPACE, PROT_READ, MAP_SHARED, nvram_fd, 0)) == MAP_FAILED) {
46                 close(nvram_fd);
47                 nvram_fd = -1;
48                 goto err;
49         }
50
51         return 0;
52
53  err:
54         perror(PATH_DEV_NVRAM);
55         return errno;
56 }
57
58 char *
59 nvram_get(const char *name)
60 {
61         size_t count = strlen(name) + 1;
62         char tmp[100], *value;
63         unsigned long *off = (unsigned long *) tmp;
64
65         if (nvram_fd < 0)
66                 if (nvram_init(NULL))
67                         return NULL;
68
69         if (count > sizeof(tmp)) {
70                 if (!(off = malloc(count)))
71                         return NULL;
72         }
73
74         /* Get offset into mmap() space */
75         strcpy((char *) off, name);
76
77         count = read(nvram_fd, off, count);
78
79         if (count == sizeof(unsigned long))
80                 value = &nvram_buf[*off];
81         else
82                 value = NULL;
83
84         if (count < 0)
85                 perror(PATH_DEV_NVRAM);
86
87         if (off != (unsigned long *) tmp)
88                 free(off);
89
90         return value;
91 }
92
93 int
94 nvram_getall(char *buf, int count)
95 {
96         int ret;
97
98         if (nvram_fd < 0)
99                 if ((ret = nvram_init(NULL)))
100                         return ret;
101
102         if (count == 0)
103                 return 0;
104
105         /* Get all variables */
106         *buf = '\0';
107
108         ret = read(nvram_fd, buf, count);
109
110         if (ret < 0)
111                 perror(PATH_DEV_NVRAM);
112
113         return (ret == count) ? 0 : ret;
114 }
115
116 int
117 nvram_set(const char *name, const char *value)
118 {
119         size_t count = strlen(name) + 1;
120         char tmp[100], *buf = tmp;
121         int ret;
122
123         if (nvram_fd < 0)
124                 if ((ret = nvram_init(NULL)))
125                         return ret;
126
127         /* Unset if value is NULL */
128         if (value)
129                 count += strlen(value) + 1;
130
131         if (count > sizeof(tmp)) {
132                 if (!(buf = malloc(count)))
133                         return -ENOMEM;
134         }
135
136         if (value)
137                 sprintf(buf, "%s=%s", name, value);
138         else
139                 strcpy(buf, name);
140
141         ret = write(nvram_fd, buf, count);
142
143         if (ret < 0)
144                 perror(PATH_DEV_NVRAM);
145
146         if (buf != tmp)
147                 free(buf);
148
149         return (ret == count) ? 0 : ret;
150 }
151
152 int
153 nvram_unset(const char *name)
154 {
155         return nvram_set(name, NULL);
156 }
157
158 int
159 nvram_commit(void)
160 {
161         int ret;
162         
163         if (nvram_fd < 0)
164                 if ((ret = nvram_init(NULL)))
165                         return ret;
166
167         ret = ioctl(nvram_fd, NVRAM_MAGIC, NULL);
168
169         if (ret < 0)
170                 perror(PATH_DEV_NVRAM);
171
172         return ret;
173 }
174
175 int
176 file_to_buf(char *path, char *buf, int len)
177 {
178         FILE *fp;
179
180         memset(buf, 0 , len);
181
182         if ((fp = fopen(path, "r"))) {
183                 fgets(buf, len, fp);
184                 fclose(fp);
185                 return 1;
186         }
187
188         return 0;
189 }