convert aruba to the new structure
[10.03/openwrt.git] / target / linux / aruba-2.6 / files / arch / mips / aruba / nvram / nvram434.c
1 /**************************************************************************
2  *
3  *  BRIEF MODULE DESCRIPTION
4  *     nvram interface routines.
5  *
6  *  Copyright 2004 IDT Inc. (rischelp@idt.com)
7  *         
8  *  This program is free software; you can redistribute  it and/or modify it
9  *  under  the terms of  the GNU General  Public License as published by the
10  *  Free Software Foundation;  either version 2 of the  License, or (at your
11  *  option) any later version.
12  *
13  *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
14  *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
15  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
16  *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
17  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18  *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
19  *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
21  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  *  You should have received a copy of the  GNU General Public License along
25  *  with this program; if not, write  to the Free Software Foundation, Inc.,
26  *  675 Mass Ave, Cambridge, MA 02139, USA.
27  *
28  *
29  **************************************************************************
30  * May 2004 rkt, neb
31  *
32  * Initial Release
33  *
34  * 
35  *
36  **************************************************************************
37  */
38
39 #include <linux/ctype.h>
40 #include <linux/string.h>
41
42 //#include <asm/ds1553rtc.h>
43 #include "nvram434.h"
44 #define  NVRAM_BASE 0xbfff8000
45
46 extern void setenv (char *e, char *v, int rewrite);
47 extern void unsetenv (char *e);
48 extern void mapenv (int (*func)(char *, char *));
49 extern char *getenv (char *s);
50 extern void purgeenv(void);
51
52 static void nvram_initenv(void);
53
54 static unsigned char
55 nvram_getbyte(int offs)
56 {
57   return(*((unsigned char*)(NVRAM_BASE + offs)));
58 }
59
60 static void
61 nvram_setbyte(int offs, unsigned char val)
62 {
63   unsigned char* nvramDataPointer = (unsigned char*)(NVRAM_BASE + offs);
64
65   *nvramDataPointer = val;
66 }
67
68 /*
69  * BigEndian!
70  */
71 static unsigned short
72 nvram_getshort(int offs)
73 {
74   return((nvram_getbyte(offs) << 8) | nvram_getbyte(offs + 1));
75 }
76
77 static void
78 nvram_setshort(int offs, unsigned short val)
79 {
80   nvram_setbyte(offs, (unsigned char)((val >> 8) & 0xff));
81   nvram_setbyte(offs + 1, (unsigned char)(val & 0xff));
82 }
83 #if 0
84 static unsigned int
85 nvram_getint(int offs)
86 {
87   unsigned int val;
88   val = nvram_getbyte(offs) << 24;
89   val |= nvram_getbyte(offs + 1) << 16;
90   val |= nvram_getbyte(offs + 2) << 8;
91   val |= nvram_getbyte(offs + 3);
92   return(val);
93 }
94
95 static void
96 nvram_setint(int offs, unsigned int val)
97 {
98   nvram_setbyte(offs, val >> 24);
99   nvram_setbyte(offs + 1, val >> 16);
100   nvram_setbyte(offs + 2, val >> 8);
101   nvram_setbyte(offs + 3, val);
102 }
103 #endif
104 /*
105  * calculate NVRAM checksum
106  */
107 static unsigned short
108 nvram_calcsum(void)
109 {
110   unsigned short sum = NV_MAGIC;
111   int     i;
112
113   for (i = ENV_BASE; i < ENV_TOP; i += 2)
114     sum += nvram_getshort(i);
115   return(sum);
116 }
117
118 /*
119  * update the nvram checksum
120  */
121 static void
122 nvram_updatesum (void)
123 {
124   nvram_setshort(NVOFF_CSUM, nvram_calcsum());
125 }
126
127 /*
128  * test validity of nvram by checksumming it
129  */
130 static int
131 nvram_isvalid(void)
132 {
133   static int  is_valid;
134
135   if (is_valid)
136     return(1);
137
138   if (nvram_getshort(NVOFF_MAGIC) != NV_MAGIC) {
139         printk("nvram_isvalid FAILED\n");
140     //nvram_initenv();
141   }
142   is_valid = 1;
143   return(1);
144 }
145
146 /* return nvram address of environment string */
147 static int
148 nvram_matchenv(char *s)
149 {
150   int envsize, envp, n, i, varsize;
151   char *var;
152
153   envsize = nvram_getshort(NVOFF_ENVSIZE);
154
155   if (envsize > ENV_AVAIL)
156     return(0);     /* sanity */
157     
158   envp = ENV_BASE;
159
160   if ((n = strlen (s)) > 255)
161     return(0);
162     
163   while (envsize > 0) {
164     varsize = nvram_getbyte(envp);
165     if (varsize == 0 || (envp + varsize) > ENV_TOP)
166       return(0);   /* sanity */
167     for (i = envp + 1, var = s; i <= envp + n; i++, var++) {
168       char c1 = nvram_getbyte(i);
169       char c2 = *var;
170       if (islower(c1))
171         c1 = toupper(c1);
172       if (islower(c2))
173         c2 = toupper(c2);
174       if (c1 != c2)
175         break;
176     }
177     if (i > envp + n) {       /* match so far */
178       if (n == varsize - 1)   /* match on boolean */
179         return(envp);
180       if (nvram_getbyte(i) == '=')  /* exact match on variable */
181         return(envp);
182     }
183     envsize -= varsize;
184     envp += varsize;
185   }
186   return(0);
187 }
188
189 static void nvram_initenv(void)
190 {
191   nvram_setshort(NVOFF_MAGIC, NV_MAGIC);
192   nvram_setshort(NVOFF_ENVSIZE, 0);
193
194   nvram_updatesum();
195 }
196
197 static void
198 nvram_delenv(char *s)
199 {
200   int nenvp, envp, envsize, nbytes;
201
202   envp = nvram_matchenv(s);
203   if (envp == 0)
204     return;
205
206   nenvp = envp + nvram_getbyte(envp);
207   envsize = nvram_getshort(NVOFF_ENVSIZE);
208   nbytes = envsize - (nenvp - ENV_BASE);
209   nvram_setshort(NVOFF_ENVSIZE, envsize - (nenvp - envp));
210   while (nbytes--) {
211     nvram_setbyte(envp, nvram_getbyte(nenvp));
212     envp++;
213     nenvp++;
214   }
215   nvram_updatesum();
216 }
217
218 static int
219 nvram_setenv(char *s, char *v)
220 {
221   int ns, nv, total;
222   int envp;
223
224   if (!nvram_isvalid())
225     return(-1);
226
227   nvram_delenv(s);
228   ns = strlen(s);
229   if (ns == 0)
230     return (-1);
231   if (v && *v) {
232     nv = strlen(v);
233     total = ns + nv + 2;
234   }
235   else {
236     nv = 0;
237     total = ns + 1;
238   }
239   if (total > 255 || total > ENV_AVAIL - nvram_getshort(NVOFF_ENVSIZE))
240     return(-1);
241
242   envp = ENV_BASE + nvram_getshort(NVOFF_ENVSIZE);
243
244   nvram_setbyte(envp, (unsigned char) total); 
245   envp++;
246
247   while (ns--) {
248     nvram_setbyte(envp, *s); 
249     envp++; 
250     s++;
251   }
252
253   if (nv) {
254     nvram_setbyte(envp, '='); 
255     envp++;
256     while (nv--) {
257       nvram_setbyte(envp, *v); 
258       envp++; 
259       v++;
260     }
261   }
262   nvram_setshort(NVOFF_ENVSIZE, envp-ENV_BASE);
263   nvram_updatesum();
264   return 0;
265 }
266
267 static char *
268 nvram_getenv(char *s)
269 {
270   static char buf[256];   /* FIXME: this cannot be static */
271   int envp, ns, nbytes, i;
272
273   if (!nvram_isvalid())
274     return "INVALID NVRAM"; //((char *)0);
275
276   envp = nvram_matchenv(s);
277   if (envp == 0)
278     return "NOT FOUND"; //((char *)0);
279   ns = strlen(s);
280   if (nvram_getbyte(envp) == ns + 1)  /* boolean */
281     buf[0] = '\0';
282   else {
283     nbytes = nvram_getbyte(envp) - (ns + 2);
284     envp += ns + 2;
285     for (i = 0; i < nbytes; i++)
286       buf[i] = nvram_getbyte(envp++);
287     buf[i] = '\0';
288   }
289   return(buf);
290 }
291
292 static void
293 nvram_unsetenv(char *s)
294 {
295   if (!nvram_isvalid())
296     return;
297
298   nvram_delenv(s);
299 }
300
301 /*
302  * apply func to each string in environment
303  */
304 static void
305 nvram_mapenv(int (*func)(char *, char *))
306 {
307   int envsize, envp, n, i, seeneql;
308   char name[256], value[256];
309   char c, *s;
310
311   if (!nvram_isvalid())
312     return;
313
314   envsize = nvram_getshort(NVOFF_ENVSIZE);
315   envp = ENV_BASE;
316
317   while (envsize > 0) {
318     value[0] = '\0';
319     seeneql = 0;
320     s = name;
321     n = nvram_getbyte(envp);
322     for (i = envp + 1; i < envp + n; i++) {
323       c = nvram_getbyte(i);
324       if ((c == '=') && !seeneql) {
325         *s = '\0';
326         s = value;
327         seeneql = 1;
328         continue;
329       }
330       *s++ = c;
331     }
332     *s = '\0';
333     (*func)(name, value);
334     envsize -= n;
335     envp += n;
336   }
337 }
338 #if 0
339 static unsigned int
340 digit(char c)
341 {
342   if ('0' <= c && c <= '9')
343     return (c - '0');
344   if ('A' <= c && c <= 'Z')
345     return (10 + c - 'A');
346   if ('a' <= c && c <= 'z')
347     return (10 + c - 'a');
348   return (~0);
349 }
350 #endif
351 /*
352  * Wrappers to allow 'special' environment variables to get processed
353  */
354 void
355 setenv(char *e, char *v, int rewrite)
356 {
357   if (nvram_getenv(e) && !rewrite)
358     return;
359     
360   nvram_setenv(e, v);
361 }
362
363 char *
364 getenv(char *e)
365 {
366   return(nvram_getenv(e));
367 }
368
369 void
370 unsetenv(char *e)
371 {
372   nvram_unsetenv(e);
373 }
374
375 void
376 purgeenv()
377 {
378   int i;
379   unsigned char* nvramDataPointer = (unsigned char*)(NVRAM_BASE);
380   
381   for (i = ENV_BASE; i < ENV_TOP; i++)
382     *nvramDataPointer++ = 0;
383   nvram_setshort(NVOFF_MAGIC, NV_MAGIC);
384   nvram_setshort(NVOFF_ENVSIZE, 0);
385   nvram_setshort(NVOFF_CSUM, NV_MAGIC);
386 }
387
388 void
389 mapenv(int (*func)(char *, char *))
390 {
391   nvram_mapenv(func);
392 }