1/* 2 * NVRAM variable manipulation (Linux user mode half) 3 * 4 * Copyright (C) 2010, Broadcom Corporation. All Rights Reserved. 5 * 6 * Permission to use, copy, modify, and/or distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * 18 * $Id: nvram_linux.c,v 1.12 2008/04/03 02:55:46 Exp $ 19 */ 20 21#include <stdio.h> 22#include <stdlib.h> 23#include <unistd.h> 24#include <errno.h> 25#include <error.h> 26#include <string.h> 27#include <sys/ioctl.h> 28#include <sys/types.h> 29#include <sys/stat.h> 30#include <fcntl.h> 31#include <sys/mman.h> 32 33#include <typedefs.h> 34#include <bcmnvram.h> 35 36#include "ambitCfg.h" //Foxconn add, FredPeng, 04/17/2009 37#define PATH_DEV_NVRAM "/dev/nvram" 38 39/* wklin added, 12/13/2006 */ 40#include <sys/types.h> 41#include <sys/ipc.h> 42#include <sys/sem.h> 43 44#define LOCK -1 45#define UNLOCK 1 46#define NVRAM_SAVE_KEY 0x12345678 47static int lock_shm (int semkey, int op) 48{ 49 struct sembuf lockop = { 0, 0, SEM_UNDO } /* sem operation */ ; 50 int semid; 51 52 if (semkey == 0) 53 return -1; 54 55 /* create/init sem */ 56 if ((semid = semget (semkey, 1, IPC_CREAT | IPC_EXCL | 0666)) >= 0) 57 { 58 /* initialize the sem vaule to 1 */ 59 if (semctl (semid, 0, SETVAL, 1) < 0) 60 { 61 return -1; 62 } 63 } 64 else 65 { 66 /* sem maybe has createdAget the semid */ 67 if ((semid = semget (semkey, 1, 0666)) < 0) 68 { 69 return -1; 70 } 71 } 72 73 lockop.sem_op = op; 74 if (semop (semid, &lockop, 1) < 0) 75 return -1; 76 77 return 0; 78} 79 80#define NVRAM_LOCK() //lock_shm(NVRAM_SAVE_KEY, LOCK) 81#define NVRAM_UNLOCK() //lock_shm(NVRAM_SAVE_KEY, UNLOCK) 82/* wklin added, 12/13/2006 */ 83 84 85 86/* Globals */ 87static int nvram_fd = -1; 88static char *nvram_buf = NULL; 89 90int 91nvram_init(void *unused) 92{ 93 if (nvram_fd >= 0) 94 return 0; 95 96 if ((nvram_fd = open(PATH_DEV_NVRAM, O_RDWR)) < 0) 97 goto err; 98 99 /* Map kernel string buffer into user space */ 100 if ((nvram_buf = mmap(NULL, NVRAM_SPACE, PROT_READ, MAP_SHARED, nvram_fd, 0)) == MAP_FAILED) { 101 close(nvram_fd); 102 nvram_fd = -1; 103 goto err; 104 } 105 106 return 0; 107 108 err: 109 perror(PATH_DEV_NVRAM); 110 return errno; 111} 112 113char * 114nvram_get(const char *name) 115{ 116 size_t count = strlen(name) + 1; 117 char tmp[100], *value; 118 unsigned long *off = (unsigned long *) tmp; 119 120 if (nvram_init(NULL)) 121 return NULL; 122 123 if (count > sizeof(tmp)) { 124 if (!(off = malloc(count))) 125 return NULL; 126 } 127 128 /* Get offset into mmap() space */ 129 strcpy((char *) off, name); 130 131 count = read(nvram_fd, off, count); 132 133 if (count == sizeof(unsigned long)) 134 value = &nvram_buf[*off]; 135 else 136 value = NULL; 137 138 if (count < 0) 139 perror(PATH_DEV_NVRAM); 140 141 if (off != (unsigned long *) tmp) 142 free(off); 143 144 return value; 145} 146 147int 148nvram_getall(char *buf, int count) 149{ 150 int ret; 151 152 if (nvram_fd < 0) 153 if ((ret = nvram_init(NULL))) 154 return ret; 155 156 if (count == 0) 157 return 0; 158 159 /* Get all variables */ 160 *buf = '\0'; 161 162 ret = read(nvram_fd, buf, count); 163 164 if (ret < 0) 165 perror(PATH_DEV_NVRAM); 166 167 return (ret == count) ? 0 : ret; 168} 169 170static int 171_nvram_set(const char *name, const char *value) 172{ 173 size_t count = strlen(name) + 1; 174 char tmp[100], *buf = tmp; 175 int ret; 176 177 if ((ret = nvram_init(NULL))) 178 return ret; 179 180 /* Unset if value is NULL */ 181 if (value) 182 count += strlen(value) + 1; 183 184 if (count > sizeof(tmp)) { 185 if (!(buf = malloc(count))) 186 return -ENOMEM; 187 } 188 189 if (value) 190 sprintf(buf, "%s=%s", name, value); 191 else 192 strcpy(buf, name); 193 194 ret = write(nvram_fd, buf, count); 195 196 if (ret < 0) 197 perror(PATH_DEV_NVRAM); 198 199 if (buf != tmp) 200 free(buf); 201 202 return (ret == count) ? 0 : ret; 203} 204 205int 206nvram_set(const char *name, const char *value) 207{ 208 return _nvram_set(name, value); 209} 210 211int 212nvram_unset(const char *name) 213{ 214 return _nvram_set(name, NULL); 215} 216 217int 218nvram_commit(void) 219{ 220 int ret; 221 222 /* foxconn wklin added start, 11/02/2010, show messag when doing commit */ 223 { 224 FILE *fp; 225 fp = fopen("/dev/console", "w"); 226 if (fp) { 227 fprintf(fp, "Doing nvram commit by pid %d !\n",getpid()); 228 fclose(fp); 229 } 230 } 231 /* foxconn wklin added end , 11/02/2010 */ 232 if ((ret = nvram_init(NULL))) 233 return ret; 234 235 ret = ioctl(nvram_fd, NVRAM_MAGIC, NULL); 236 237 if (ret < 0) 238 perror(PATH_DEV_NVRAM); 239 240 return ret; 241} 242 243/* Foxconn added start Peter Ling 12/05/2005 */ 244#ifdef ACOS_MODULES_ENABLE 245extern struct nvram_tuple router_defaults[]; 246 247int nvram_loaddefault (void) 248{ 249 /* Foxconn add start, FredPeng, 04/14/2009 */ 250 char cmd[128]; 251 memset(cmd, 0, sizeof(cmd)); 252 /* Foxconn add end, FredPeng, 04/14/2009 */ 253 254 system("rm /tmp/ppp/ip-down"); /* added by EricHuang, 01/12/2007 */ 255 256 /* Foxconn modify start, FredPeng, 04/14/2009 */ 257 sprintf(cmd, "erase %s", NVRAM_MTD_WR); 258 system(cmd); 259 /* Foxconn modify end, FredPeng, 04/14/2009 */ 260 261 printf("Load default done!\n"); 262 263 return (0); 264} 265#endif 266/* Foxconn added end Peter Ling 12/05/2005 */ 267