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" 37#define PATH_DEV_NVRAM "/dev/nvram" 38 39#include <sys/types.h> 40#include <sys/ipc.h> 41#include <sys/sem.h> 42 43#define LOCK -1 44#define UNLOCK 1 45#define NVRAM_SAVE_KEY 0x12345678 46static int lock_shm (int semkey, int op) 47{ 48 struct sembuf lockop = { 0, 0, SEM_UNDO } /* sem operation */ ; 49 int semid; 50 51 if (semkey == 0) 52 return -1; 53 54 /* create/init sem */ 55 if ((semid = semget (semkey, 1, IPC_CREAT | IPC_EXCL | 0666)) >= 0) 56 { 57 /* initialize the sem vaule to 1 */ 58 if (semctl (semid, 0, SETVAL, 1) < 0) 59 { 60 return -1; 61 } 62 } 63 else 64 { 65 /* sem maybe has createdAget the semid */ 66 if ((semid = semget (semkey, 1, 0666)) < 0) 67 { 68 return -1; 69 } 70 } 71 72 lockop.sem_op = op; 73 if (semop (semid, &lockop, 1) < 0) 74 return -1; 75 76 return 0; 77} 78 79#define NVRAM_LOCK() //lock_shm(NVRAM_SAVE_KEY, LOCK) 80#define NVRAM_UNLOCK() //lock_shm(NVRAM_SAVE_KEY, UNLOCK) 81 82 83 84/* Globals */ 85static int nvram_fd = -1; 86static char *nvram_buf = NULL; 87 88int 89nvram_init(void *unused) 90{ 91 if (nvram_fd >= 0) 92 return 0; 93 94 if ((nvram_fd = open(PATH_DEV_NVRAM, O_RDWR)) < 0) 95 goto err; 96 97 /* Map kernel string buffer into user space */ 98 if ((nvram_buf = mmap(NULL, NVRAM_SPACE, PROT_READ, MAP_SHARED, nvram_fd, 0)) == MAP_FAILED) { 99 close(nvram_fd); 100 nvram_fd = -1; 101 goto err; 102 } 103 104 return 0; 105 106 err: 107 perror(PATH_DEV_NVRAM); 108 return errno; 109} 110 111char * 112nvram_get(const char *name) 113{ 114 size_t count = strlen(name) + 1; 115 char tmp[100], *value; 116 unsigned long *off = (unsigned long *) tmp; 117 118 if (nvram_init(NULL)) 119 return NULL; 120 121 if (count > sizeof(tmp)) { 122 if (!(off = malloc(count))) 123 return NULL; 124 } 125 126 /* Get offset into mmap() space */ 127 strcpy((char *) off, name); 128 129 count = read(nvram_fd, off, count); 130 131 if (count == sizeof(unsigned long)) 132 value = &nvram_buf[*off]; 133 else 134 value = NULL; 135 136 if (count < 0) 137 perror(PATH_DEV_NVRAM); 138 139 if (off != (unsigned long *) tmp) 140 free(off); 141 142 return value; 143} 144 145int 146nvram_getall(char *buf, int count) 147{ 148 int ret; 149 150 if (nvram_fd < 0) 151 if ((ret = nvram_init(NULL))) 152 return ret; 153 154 if (count == 0) 155 return 0; 156 157 /* Get all variables */ 158 *buf = '\0'; 159 160 ret = read(nvram_fd, buf, count); 161 162 if (ret < 0) 163 perror(PATH_DEV_NVRAM); 164 165 return (ret == count) ? 0 : ret; 166} 167 168static int 169_nvram_set(const char *name, const char *value) 170{ 171 size_t count = strlen(name) + 1; 172 char tmp[100], *buf = tmp; 173 int ret; 174 175 if ((ret = nvram_init(NULL))) 176 return ret; 177 178 /* Unset if value is NULL */ 179 if (value) 180 count += strlen(value) + 1; 181 182 if (count > sizeof(tmp)) { 183 if (!(buf = malloc(count))) 184 return -ENOMEM; 185 } 186 187 if (value) 188 sprintf(buf, "%s=%s", name, value); 189 else 190 strcpy(buf, name); 191 192 ret = write(nvram_fd, buf, count); 193 194 if (ret < 0) 195 perror(PATH_DEV_NVRAM); 196 197 if (buf != tmp) 198 free(buf); 199 200 return (ret == count) ? 0 : ret; 201} 202 203int 204nvram_set(const char *name, const char *value) 205{ 206 return _nvram_set(name, value); 207} 208 209int 210nvram_unset(const char *name) 211{ 212 return _nvram_set(name, NULL); 213} 214 215int 216nvram_commit(void) 217{ 218 int ret; 219 220 { 221 FILE *fp; 222 fp = fopen("/dev/console", "w"); 223 if (fp) { 224 fprintf(fp, "Doing nvram commit by pid %d !\n",getpid()); 225 fclose(fp); 226 } 227 } 228 229 if ((ret = nvram_init(NULL))) 230 return ret; 231 232 ret = ioctl(nvram_fd, NVRAM_MAGIC, NULL); 233 234 if (ret < 0) 235 perror(PATH_DEV_NVRAM); 236 237 return ret; 238} 239 240#ifdef ACOS_MODULES_ENABLE 241extern struct nvram_tuple router_defaults[]; 242 243int nvram_loaddefault (void) 244{ 245 char cmd[128]; 246 memset(cmd, 0, sizeof(cmd)); 247 248 system("rm /tmp/ppp/ip-down"); 249 250 sprintf(cmd, "erase %s", NVRAM_MTD_WR); 251 system(cmd); 252 253 printf("Load default done!\n"); 254 255 return (0); 256} 257#endif 258