GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / cfe / cfe / arch / mips / board / carmel / src / carmel_env.c
blob11ada96ecef48dff4897e0ad1be3361a4b5d0cb4
1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
3 *
4 * Environment variable subroutines File: carmel_env.c
5 *
6 * This is a special hacked copy of env_subr.c to store environment
7 * variables in the ID EEPROM. Sure, we could go and enhance
8 * CFE to support multiple environment devices, but this is
9 * easier.
11 * Author: Mitch Lichtenberg (mpl@broadcom.com)
13 *********************************************************************
15 * Copyright 2000,2001,2002,2003
16 * Broadcom Corporation. All rights reserved.
18 * This software is furnished under license and may be used and
19 * copied only in accordance with the following terms and
20 * conditions. Subject to these conditions, you may download,
21 * copy, install, use, modify and distribute modified or unmodified
22 * copies of this software in source and/or binary form. No title
23 * or ownership is transferred hereby.
25 * 1) Any source code used, modified or distributed must reproduce
26 * and retain this copyright notice and list of conditions
27 * as they appear in the source file.
29 * 2) No right is granted to use any trade name, trademark, or
30 * logo of Broadcom Corporation. The "Broadcom Corporation"
31 * name may not be used to endorse or promote products derived
32 * from this software without the prior written permission of
33 * Broadcom Corporation.
35 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
36 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
37 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
38 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
39 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
40 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
41 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
42 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
43 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
44 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
45 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
46 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
47 * THE POSSIBILITY OF SUCH DAMAGE.
48 ********************************************************************* */
50 #include "lib_types.h"
51 #include "lib_string.h"
52 #include "lib_queue.h"
53 #include "lib_malloc.h"
54 #include "lib_printf.h"
56 #include "env_subr.h"
57 #include "carmel_env.h"
59 #include "cfe_iocb.h"
60 #include "cfe_devfuncs.h"
61 #include "cfe_ioctl.h"
63 #include "cfe_error.h"
64 #include "cfe.h"
66 /* *********************************************************************
67 * Types
68 ********************************************************************* */
70 typedef struct cfe_envvar_s {
71 queue_t qb;
72 int flags;
73 char *name;
74 char *value;
75 /* name and value go here */
76 } cfe_envvar_t;
78 /* *********************************************************************
79 * Globals
80 ********************************************************************* */
82 queue_t carmel_envvars = {&carmel_envvars,&carmel_envvars};
83 extern unsigned int cfe_startflags;
84 char *carmel_envdev = NULL;
86 /* *********************************************************************
87 * carmel_findenv(name)
89 * Locate an environment variable in the in-memory list
91 * Input parameters:
92 * name - name of env var to find
94 * Return value:
95 * cfe_envvar_t pointer, or NULL if not found
96 ********************************************************************* */
98 static cfe_envvar_t *carmel_findenv(const char *name)
100 queue_t *qb;
101 cfe_envvar_t *env;
103 for (qb = carmel_envvars.q_next; qb != &carmel_envvars; qb = qb->q_next) {
104 env = (cfe_envvar_t *) qb;
105 if (strcmp(env->name,name) == 0) break;
108 if (qb == &carmel_envvars) return NULL;
110 return (cfe_envvar_t *) qb;
114 /* *********************************************************************
115 * carmel_enumenv(idx,name,namelen,val,vallen)
117 * Enumerate environment variables. This routine locates
118 * the nth environment variable and copies its name and value
119 * to user buffers.
121 * The namelen and vallen variables must be preinitialized to
122 * the maximum size of the output buffer.
124 * Input parameters:
125 * idx - variable index to find (starting with zero)
126 * name,namelen - name buffer and length
127 * val,vallen - value buffer and length
129 * Return value:
130 * 0 if ok
131 * else error code
132 ********************************************************************* */
134 int carmel_enumenv(int idx,char *name,int *namelen,char *val,int *vallen)
136 queue_t *qb;
137 cfe_envvar_t *env;
139 for (qb = carmel_envvars.q_next; qb != &carmel_envvars; qb = qb->q_next) {
140 if (idx == 0) break;
141 idx--;
144 if (qb == &carmel_envvars) return CFE_ERR_ENVNOTFOUND;
145 env = (cfe_envvar_t *) qb;
147 *namelen = xstrncpy(name,env->name,*namelen);
148 *vallen = xstrncpy(val,env->value,*vallen);
150 return 0;
155 /* *********************************************************************
156 * carmel_delenv(name)
158 * Delete an environment variable
160 * Input parameters:
161 * name - environment variable to delete
163 * Return value:
164 * 0 if ok
165 * else error code
166 ********************************************************************* */
168 int carmel_delenv(const char *name)
170 cfe_envvar_t *env;
172 env = carmel_findenv(name);
174 if (!env) return 0;
176 q_dequeue((queue_t *) env);
177 KFREE(env);
178 return 0;
181 /* *********************************************************************
182 * carmel_getenv(name)
184 * Retrieve the value of an environment variable
186 * Input parameters:
187 * name - name of environment variable to find
189 * Return value:
190 * value, or NULL if variable is not found
191 ********************************************************************* */
193 char *carmel_getenv(const char *name)
195 cfe_envvar_t *env;
197 env = carmel_findenv(name);
199 if (env) {
200 return env->value;
203 return NULL;
207 /* *********************************************************************
208 * carmel_setenv(name,value,flags)
210 * Set the value of an environment variable
212 * Input parameters:
213 * name - name of variable
214 * value - value of variable
215 * flags - flags for variable (ENV_FLG_xxx)
217 * Return value:
218 * 0 if ok
219 * else error code
220 ********************************************************************* */
222 int carmel_setenv(const char *name,char *value,int flags)
224 cfe_envvar_t *env;
225 int namelen;
227 env = carmel_findenv(name);
228 if (env) {
229 q_dequeue((queue_t *) env);
230 KFREE(env);
233 namelen = strlen(name);
235 env = KMALLOC(sizeof(cfe_envvar_t) + namelen + 1 + strlen(value) + 1,0);
236 if (!env) return CFE_ERR_NOMEM;
238 env->name = (char *) (env+1);
239 env->value = env->name + namelen + 1;
240 env->flags = (flags & ENV_FLG_MASK);
242 strcpy(env->name,name);
243 strcpy(env->value,value);
245 q_enqueue(&carmel_envvars,(queue_t *) env);
247 return 0;
251 /* *********************************************************************
252 * carmel_load()
254 * Load the environment from the NVRAM device.
256 * Input parameters:
257 * nothing
259 * Return value:
260 * 0 if ok
261 * else error code
262 ********************************************************************* */
265 int carmel_loadenv(void)
267 int size;
268 unsigned char *buffer;
269 unsigned char *ptr;
270 unsigned char *envval;
271 unsigned int reclen;
272 unsigned int rectype;
273 int offset;
274 int fh;
275 int retval = -1;
276 unsigned char flg;
277 char valuestr[256];
280 * If in 'safe mode', don't read the environment the first time.
283 if (cfe_startflags & CFE_INIT_SAFE) {
284 cfe_startflags &= ~CFE_INIT_SAFE;
285 return 0;
288 if (!carmel_envdev) return -1;
289 fh = cfe_open(carmel_envdev);
290 if (fh < 0) return fh;
292 size = 16384;
293 buffer = KMALLOC(size,0);
295 if (buffer == NULL) return CFE_ERR_NOMEM;
297 ptr = buffer;
298 offset = 0;
300 /* Read the record type and length */
301 if (cfe_readblk(fh,offset,ptr,1) != 1) {
302 retval = CFE_ERR_IOERR;
303 goto error;
306 while ((*ptr != ENV_TLV_TYPE_END) && (size > 1)) {
308 /* Adjust pointer for TLV type */
309 rectype = *(ptr);
310 offset++;
311 size--;
314 * Read the length. It can be either 1 or 2 bytes
315 * depending on the code
317 if (rectype & ENV_LENGTH_8BITS) {
318 /* Read the record type and length - 8 bits */
319 if (cfe_readblk(fh,offset,ptr,1) != 1) {
320 retval = CFE_ERR_IOERR;
321 goto error;
323 reclen = *(ptr);
324 size--;
325 offset++;
327 else {
328 /* Read the record type and length - 16 bits, MSB first */
329 if (cfe_readblk(fh,offset,ptr,2) != 2) {
330 retval = CFE_ERR_IOERR;
331 goto error;
333 reclen = (((unsigned int) *(ptr)) << 8) + (unsigned int) *(ptr+1);
334 size -= 2;
335 offset += 2;
338 if (reclen > size) break; /* should not happen, bad NVRAM */
340 switch (rectype) {
341 case ENV_TLV_TYPE_ENV:
342 /* Read the TLV data */
343 if (cfe_readblk(fh,offset,ptr,reclen) != reclen) goto error;
344 flg = *ptr++;
345 envval = (unsigned char *) strnchr(ptr,'=',(reclen-1));
346 if (envval) {
347 *envval++ = '\0';
348 memcpy(valuestr,envval,(reclen-1)-(envval-ptr));
349 valuestr[(reclen-1)-(envval-ptr)] = '\0';
350 carmel_setenv(ptr,valuestr,flg);
352 break;
354 default:
355 /* Unknown TLV type, skip it. */
356 break;
360 * Advance to next TLV
363 size -= (int)reclen;
364 offset += reclen;
366 /* Read the next record type */
367 ptr = buffer;
368 if (cfe_readblk(fh,offset,ptr,1) != 1) goto error;
371 retval = 0; /* success! */
373 error:
374 KFREE(buffer);
376 cfe_close(fh);
378 return retval;
383 /* *********************************************************************
384 * carmel_saveenv()
386 * Write the environment to the NVRAM device.
388 * Input parameters:
389 * nothing
391 * Return value:
392 * 0 if ok, else error code
393 ********************************************************************* */
395 int carmel_saveenv(void)
397 int size;
398 unsigned char *buffer;
399 unsigned char *buffer_end;
400 unsigned char *ptr;
401 queue_t *qb;
402 cfe_envvar_t *env;
403 int namelen;
404 int valuelen;
405 int fh;
407 if (carmel_envdev == NULL) return -1;
408 fh = cfe_open(carmel_envdev);
409 if (fh < 0) return fh;
411 size = 16384;
412 buffer = KMALLOC(size,0);
414 if (buffer == NULL) return CFE_ERR_NOMEM;
416 buffer_end = buffer + size;
418 ptr = buffer;
420 for (qb = carmel_envvars.q_next; qb != &carmel_envvars; qb = qb->q_next) {
421 env = (cfe_envvar_t *) qb;
423 if (env->flags & (ENV_FLG_BUILTIN)) continue;
425 namelen = strlen(env->name);
426 valuelen = strlen(env->value);
428 if ((ptr + 2 + namelen + valuelen + 1 + 1 + 1) > buffer_end) break;
430 *ptr++ = ENV_TLV_TYPE_ENV; /* TLV record type */
431 *ptr++ = (namelen + valuelen + 1 + 1); /* TLV record length */
433 *ptr++ = (unsigned char)env->flags;
434 memcpy(ptr,env->name,namelen); /* TLV record data */
435 ptr += namelen;
436 *ptr++ = '=';
437 memcpy(ptr,env->value,valuelen);
438 ptr += valuelen;
442 *ptr++ = ENV_TLV_TYPE_END;
444 size = cfe_writeblk(fh,0,buffer,ptr-buffer);
446 KFREE(buffer);
448 cfe_close(fh);
450 return (size == (ptr-buffer)) ? 0 : CFE_ERR_IOERR;
454 /* *********************************************************************
455 * carmel_envtype(name)
457 * Return the type of the environment variable
459 * Input parameters:
460 * name - name of environment variable
462 * Return value:
463 * flags, or <0 if error occured
464 ********************************************************************* */
465 int carmel_envtype(const char *name)
467 cfe_envvar_t *env;
469 env = carmel_findenv(name);
471 if (env) {
472 return env->flags;
475 return CFE_ERR_ENVNOTFOUND;