aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/nvram.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/nvram.c')
-rw-r--r--drivers/char/nvram.c126
1 files changed, 52 insertions, 74 deletions
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index 8054ee839b3c..1a04f3df91ed 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -46,7 +46,7 @@
46/* select machine configuration */ 46/* select machine configuration */
47#if defined(CONFIG_ATARI) 47#if defined(CONFIG_ATARI)
48# define MACH ATARI 48# define MACH ATARI
49#elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) /* and others?? */ 49#elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) /* and ?? */
50# define MACH PC 50# define MACH PC
51#else 51#else
52# error Cannot build nvram driver for this machine configuration. 52# error Cannot build nvram driver for this machine configuration.
@@ -107,9 +107,9 @@
107#include <linux/init.h> 107#include <linux/init.h>
108#include <linux/proc_fs.h> 108#include <linux/proc_fs.h>
109#include <linux/spinlock.h> 109#include <linux/spinlock.h>
110#include <linux/io.h>
111#include <linux/uaccess.h>
110 112
111#include <asm/io.h>
112#include <asm/uaccess.h>
113#include <asm/system.h> 113#include <asm/system.h>
114 114
115static DEFINE_SPINLOCK(nvram_state_lock); 115static DEFINE_SPINLOCK(nvram_state_lock);
@@ -123,7 +123,7 @@ static void mach_set_checksum(void);
123 123
124#ifdef CONFIG_PROC_FS 124#ifdef CONFIG_PROC_FS
125static int mach_proc_infos(unsigned char *contents, char *buffer, int *len, 125static int mach_proc_infos(unsigned char *contents, char *buffer, int *len,
126 off_t *begin, off_t offset, int size); 126 off_t *begin, off_t offset, int size);
127#endif 127#endif
128 128
129/* 129/*
@@ -133,18 +133,17 @@ static int mach_proc_infos(unsigned char *contents, char *buffer, int *len,
133 * 133 *
134 * It is worth noting that these functions all access bytes of general 134 * It is worth noting that these functions all access bytes of general
135 * purpose memory in the NVRAM - that is to say, they all add the 135 * purpose memory in the NVRAM - that is to say, they all add the
136 * NVRAM_FIRST_BYTE offset. Pass them offsets into NVRAM as if you did not 136 * NVRAM_FIRST_BYTE offset. Pass them offsets into NVRAM as if you did not
137 * know about the RTC cruft. 137 * know about the RTC cruft.
138 */ 138 */
139 139
140unsigned char 140unsigned char __nvram_read_byte(int i)
141__nvram_read_byte(int i)
142{ 141{
143 return CMOS_READ(NVRAM_FIRST_BYTE + i); 142 return CMOS_READ(NVRAM_FIRST_BYTE + i);
144} 143}
144EXPORT_SYMBOL(__nvram_read_byte);
145 145
146unsigned char 146unsigned char nvram_read_byte(int i)
147nvram_read_byte(int i)
148{ 147{
149 unsigned long flags; 148 unsigned long flags;
150 unsigned char c; 149 unsigned char c;
@@ -154,16 +153,16 @@ nvram_read_byte(int i)
154 spin_unlock_irqrestore(&rtc_lock, flags); 153 spin_unlock_irqrestore(&rtc_lock, flags);
155 return c; 154 return c;
156} 155}
156EXPORT_SYMBOL(nvram_read_byte);
157 157
158/* This races nicely with trying to read with checksum checking (nvram_read) */ 158/* This races nicely with trying to read with checksum checking (nvram_read) */
159void 159void __nvram_write_byte(unsigned char c, int i)
160__nvram_write_byte(unsigned char c, int i)
161{ 160{
162 CMOS_WRITE(c, NVRAM_FIRST_BYTE + i); 161 CMOS_WRITE(c, NVRAM_FIRST_BYTE + i);
163} 162}
163EXPORT_SYMBOL(__nvram_write_byte);
164 164
165void 165void nvram_write_byte(unsigned char c, int i)
166nvram_write_byte(unsigned char c, int i)
167{ 166{
168 unsigned long flags; 167 unsigned long flags;
169 168
@@ -171,15 +170,15 @@ nvram_write_byte(unsigned char c, int i)
171 __nvram_write_byte(c, i); 170 __nvram_write_byte(c, i);
172 spin_unlock_irqrestore(&rtc_lock, flags); 171 spin_unlock_irqrestore(&rtc_lock, flags);
173} 172}
173EXPORT_SYMBOL(nvram_write_byte);
174 174
175int 175int __nvram_check_checksum(void)
176__nvram_check_checksum(void)
177{ 176{
178 return mach_check_checksum(); 177 return mach_check_checksum();
179} 178}
179EXPORT_SYMBOL(__nvram_check_checksum);
180 180
181int 181int nvram_check_checksum(void)
182nvram_check_checksum(void)
183{ 182{
184 unsigned long flags; 183 unsigned long flags;
185 int rv; 184 int rv;
@@ -189,16 +188,15 @@ nvram_check_checksum(void)
189 spin_unlock_irqrestore(&rtc_lock, flags); 188 spin_unlock_irqrestore(&rtc_lock, flags);
190 return rv; 189 return rv;
191} 190}
191EXPORT_SYMBOL(nvram_check_checksum);
192 192
193static void 193static void __nvram_set_checksum(void)
194__nvram_set_checksum(void)
195{ 194{
196 mach_set_checksum(); 195 mach_set_checksum();
197} 196}
198 197
199#if 0 198#if 0
200void 199void nvram_set_checksum(void)
201nvram_set_checksum(void)
202{ 200{
203 unsigned long flags; 201 unsigned long flags;
204 202
@@ -212,7 +210,7 @@ nvram_set_checksum(void)
212 * The are the file operation function for user access to /dev/nvram 210 * The are the file operation function for user access to /dev/nvram
213 */ 211 */
214 212
215static loff_t nvram_llseek(struct file *file,loff_t offset, int origin ) 213static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
216{ 214{
217 lock_kernel(); 215 lock_kernel();
218 switch (origin) { 216 switch (origin) {
@@ -230,8 +228,8 @@ static loff_t nvram_llseek(struct file *file,loff_t offset, int origin )
230 return (offset >= 0) ? (file->f_pos = offset) : -EINVAL; 228 return (offset >= 0) ? (file->f_pos = offset) : -EINVAL;
231} 229}
232 230
233static ssize_t 231static ssize_t nvram_read(struct file *file, char __user *buf,
234nvram_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) 232 size_t count, loff_t *ppos)
235{ 233{
236 unsigned char contents[NVRAM_BYTES]; 234 unsigned char contents[NVRAM_BYTES];
237 unsigned i = *ppos; 235 unsigned i = *ppos;
@@ -254,13 +252,13 @@ nvram_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
254 252
255 return tmp - contents; 253 return tmp - contents;
256 254
257 checksum_err: 255checksum_err:
258 spin_unlock_irq(&rtc_lock); 256 spin_unlock_irq(&rtc_lock);
259 return -EIO; 257 return -EIO;
260} 258}
261 259
262static ssize_t 260static ssize_t nvram_write(struct file *file, const char __user *buf,
263nvram_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 261 size_t count, loff_t *ppos)
264{ 262{
265 unsigned char contents[NVRAM_BYTES]; 263 unsigned char contents[NVRAM_BYTES];
266 unsigned i = *ppos; 264 unsigned i = *ppos;
@@ -287,14 +285,13 @@ nvram_write(struct file *file, const char __user *buf, size_t count, loff_t *ppo
287 285
288 return tmp - contents; 286 return tmp - contents;
289 287
290 checksum_err: 288checksum_err:
291 spin_unlock_irq(&rtc_lock); 289 spin_unlock_irq(&rtc_lock);
292 return -EIO; 290 return -EIO;
293} 291}
294 292
295static int 293static int nvram_ioctl(struct inode *inode, struct file *file,
296nvram_ioctl(struct inode *inode, struct file *file, 294 unsigned int cmd, unsigned long arg)
297 unsigned int cmd, unsigned long arg)
298{ 295{
299 int i; 296 int i;
300 297
@@ -315,7 +312,7 @@ nvram_ioctl(struct inode *inode, struct file *file,
315 return 0; 312 return 0;
316 313
317 case NVRAM_SETCKS: 314 case NVRAM_SETCKS:
318 /* just set checksum, contents unchanged (maybe useful after 315 /* just set checksum, contents unchanged (maybe useful after
319 * checksum garbaged somehow...) */ 316 * checksum garbaged somehow...) */
320 if (!capable(CAP_SYS_ADMIN)) 317 if (!capable(CAP_SYS_ADMIN))
321 return -EACCES; 318 return -EACCES;
@@ -330,8 +327,7 @@ nvram_ioctl(struct inode *inode, struct file *file,
330 } 327 }
331} 328}
332 329
333static int 330static int nvram_open(struct inode *inode, struct file *file)
334nvram_open(struct inode *inode, struct file *file)
335{ 331{
336 lock_kernel(); 332 lock_kernel();
337 spin_lock(&nvram_state_lock); 333 spin_lock(&nvram_state_lock);
@@ -356,8 +352,7 @@ nvram_open(struct inode *inode, struct file *file)
356 return 0; 352 return 0;
357} 353}
358 354
359static int 355static int nvram_release(struct inode *inode, struct file *file)
360nvram_release(struct inode *inode, struct file *file)
361{ 356{
362 spin_lock(&nvram_state_lock); 357 spin_lock(&nvram_state_lock);
363 358
@@ -375,17 +370,15 @@ nvram_release(struct inode *inode, struct file *file)
375} 370}
376 371
377#ifndef CONFIG_PROC_FS 372#ifndef CONFIG_PROC_FS
378static int 373static int nvram_read_proc(char *buffer, char **start, off_t offset,
379nvram_read_proc(char *buffer, char **start, off_t offset, 374 int size, int *eof, void *data)
380 int size, int *eof, void *data)
381{ 375{
382 return 0; 376 return 0;
383} 377}
384#else 378#else
385 379
386static int 380static int nvram_read_proc(char *buffer, char **start, off_t offset,
387nvram_read_proc(char *buffer, char **start, off_t offset, 381 int size, int *eof, void *data)
388 int size, int *eof, void *data)
389{ 382{
390 unsigned char contents[NVRAM_BYTES]; 383 unsigned char contents[NVRAM_BYTES];
391 int i, len = 0; 384 int i, len = 0;
@@ -409,14 +402,14 @@ nvram_read_proc(char *buffer, char **start, off_t offset,
409 * this like that... */ 402 * this like that... */
410#define PRINT_PROC(fmt,args...) \ 403#define PRINT_PROC(fmt,args...) \
411 do { \ 404 do { \
412 *len += sprintf(buffer+*len, fmt, ##args); \ 405 *len += sprintf(buffer + *len, fmt, ##args); \
413 if (*begin + *len > offset + size) \ 406 if (*begin + *len > offset + size) \
414 return 0; \ 407 return 0; \
415 if (*begin + *len < offset) { \ 408 if (*begin + *len < offset) { \
416 *begin += *len; \ 409 *begin += *len; \
417 *len = 0; \ 410 *len = 0; \
418 } \ 411 } \
419 } while(0) 412 } while (0)
420 413
421#endif /* CONFIG_PROC_FS */ 414#endif /* CONFIG_PROC_FS */
422 415
@@ -436,8 +429,7 @@ static struct miscdevice nvram_dev = {
436 &nvram_fops 429 &nvram_fops
437}; 430};
438 431
439static int __init 432static int __init nvram_init(void)
440nvram_init(void)
441{ 433{
442 int ret; 434 int ret;
443 435
@@ -459,15 +451,14 @@ nvram_init(void)
459 } 451 }
460 ret = 0; 452 ret = 0;
461 printk(KERN_INFO "Non-volatile memory driver v" NVRAM_VERSION "\n"); 453 printk(KERN_INFO "Non-volatile memory driver v" NVRAM_VERSION "\n");
462 out: 454out:
463 return ret; 455 return ret;
464 outmisc: 456outmisc:
465 misc_deregister(&nvram_dev); 457 misc_deregister(&nvram_dev);
466 goto out; 458 goto out;
467} 459}
468 460
469static void __exit 461static void __exit nvram_cleanup_module(void)
470nvram_cleanup_module(void)
471{ 462{
472 remove_proc_entry("driver/nvram", NULL); 463 remove_proc_entry("driver/nvram", NULL);
473 misc_deregister(&nvram_dev); 464 misc_deregister(&nvram_dev);
@@ -482,8 +473,7 @@ module_exit(nvram_cleanup_module);
482 473
483#if MACH == PC 474#if MACH == PC
484 475
485static int 476static int pc_check_checksum(void)
486pc_check_checksum(void)
487{ 477{
488 int i; 478 int i;
489 unsigned short sum = 0; 479 unsigned short sum = 0;
@@ -493,11 +483,10 @@ pc_check_checksum(void)
493 sum += __nvram_read_byte(i); 483 sum += __nvram_read_byte(i);
494 expect = __nvram_read_byte(PC_CKS_LOC)<<8 | 484 expect = __nvram_read_byte(PC_CKS_LOC)<<8 |
495 __nvram_read_byte(PC_CKS_LOC+1); 485 __nvram_read_byte(PC_CKS_LOC+1);
496 return ((sum & 0xffff) == expect); 486 return (sum & 0xffff) == expect;
497} 487}
498 488
499static void 489static void pc_set_checksum(void)
500pc_set_checksum(void)
501{ 490{
502 int i; 491 int i;
503 unsigned short sum = 0; 492 unsigned short sum = 0;
@@ -522,9 +511,8 @@ static char *gfx_types[] = {
522 "monochrome", 511 "monochrome",
523}; 512};
524 513
525static int 514static int pc_proc_infos(unsigned char *nvram, char *buffer, int *len,
526pc_proc_infos(unsigned char *nvram, char *buffer, int *len, 515 off_t *begin, off_t offset, int size)
527 off_t *begin, off_t offset, int size)
528{ 516{
529 int checksum; 517 int checksum;
530 int type; 518 int type;
@@ -590,20 +578,18 @@ pc_proc_infos(unsigned char *nvram, char *buffer, int *len,
590 578
591#if MACH == ATARI 579#if MACH == ATARI
592 580
593static int 581static int atari_check_checksum(void)
594atari_check_checksum(void)
595{ 582{
596 int i; 583 int i;
597 unsigned char sum = 0; 584 unsigned char sum = 0;
598 585
599 for (i = ATARI_CKS_RANGE_START; i <= ATARI_CKS_RANGE_END; ++i) 586 for (i = ATARI_CKS_RANGE_START; i <= ATARI_CKS_RANGE_END; ++i)
600 sum += __nvram_read_byte(i); 587 sum += __nvram_read_byte(i);
601 return (__nvram_read_byte(ATARI_CKS_LOC) == (~sum & 0xff) && 588 return (__nvram_read_byte(ATARI_CKS_LOC) == (~sum & 0xff)) &&
602 __nvram_read_byte(ATARI_CKS_LOC + 1) == (sum & 0xff)); 589 (__nvram_read_byte(ATARI_CKS_LOC + 1) == (sum & 0xff));
603} 590}
604 591
605static void 592static void atari_set_checksum(void)
606atari_set_checksum(void)
607{ 593{
608 int i; 594 int i;
609 unsigned char sum = 0; 595 unsigned char sum = 0;
@@ -654,9 +640,8 @@ static char *colors[] = {
654 "2", "4", "16", "256", "65536", "??", "??", "??" 640 "2", "4", "16", "256", "65536", "??", "??", "??"
655}; 641};
656 642
657static int 643static int atari_proc_infos(unsigned char *nvram, char *buffer, int *len,
658atari_proc_infos(unsigned char *nvram, char *buffer, int *len, 644 off_t *begin, off_t offset, int size)
659 off_t *begin, off_t offset, int size)
660{ 645{
661 int checksum = nvram_check_checksum(); 646 int checksum = nvram_check_checksum();
662 int i; 647 int i;
@@ -725,11 +710,4 @@ atari_proc_infos(unsigned char *nvram, char *buffer, int *len,
725#endif /* MACH == ATARI */ 710#endif /* MACH == ATARI */
726 711
727MODULE_LICENSE("GPL"); 712MODULE_LICENSE("GPL");
728
729EXPORT_SYMBOL(__nvram_read_byte);
730EXPORT_SYMBOL(nvram_read_byte);
731EXPORT_SYMBOL(__nvram_write_byte);
732EXPORT_SYMBOL(nvram_write_byte);
733EXPORT_SYMBOL(__nvram_check_checksum);
734EXPORT_SYMBOL(nvram_check_checksum);
735MODULE_ALIAS_MISCDEV(NVRAM_MINOR); 713MODULE_ALIAS_MISCDEV(NVRAM_MINOR);