1/* 2 * /dev/nvram driver for Power Macintosh. 3 */ 4 5#define NVRAM_VERSION "1.0" 6 7#include <linux/module.h> 8 9#include <linux/types.h> 10#include <linux/errno.h> 11#include <linux/fs.h> 12#include <linux/miscdevice.h> 13#include <linux/fcntl.h> 14#include <linux/nvram.h> 15#include <linux/init.h> 16#include <asm/uaccess.h> 17#include <asm/nvram.h> 18 19#define NVRAM_SIZE 8192 20 21static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) 22{ 23 switch (origin) { 24 case 1: 25 offset += file->f_pos; 26 break; 27 case 2: 28 offset += NVRAM_SIZE; 29 break; 30 } 31 if (offset < 0) 32 return -EINVAL; 33 34 file->f_pos = offset; 35 return file->f_pos; 36} 37 38static ssize_t read_nvram(struct file *file, char __user *buf, 39 size_t count, loff_t *ppos) 40{ 41 unsigned int i; 42 char __user *p = buf; 43 44 if (!access_ok(VERIFY_WRITE, buf, count)) 45 return -EFAULT; 46 if (*ppos >= NVRAM_SIZE) 47 return 0; 48 for (i = *ppos; count > 0 && i < NVRAM_SIZE; ++i, ++p, --count) 49 if (__put_user(nvram_read_byte(i), p)) 50 return -EFAULT; 51 *ppos = i; 52 return p - buf; 53} 54 55static ssize_t write_nvram(struct file *file, const char __user *buf, 56 size_t count, loff_t *ppos) 57{ 58 unsigned int i; 59 const char __user *p = buf; 60 char c; 61 62 if (!access_ok(VERIFY_READ, buf, count)) 63 return -EFAULT; 64 if (*ppos >= NVRAM_SIZE) 65 return 0; 66 for (i = *ppos; count > 0 && i < NVRAM_SIZE; ++i, ++p, --count) { 67 if (__get_user(c, p)) 68 return -EFAULT; 69 nvram_write_byte(c, i); 70 } 71 *ppos = i; 72 return p - buf; 73} 74 75static long nvram_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 76{ 77 switch(cmd) { 78 case PMAC_NVRAM_GET_OFFSET: 79 { 80 int part, offset; 81 if (copy_from_user(&part, (void __user*)arg, sizeof(part)) != 0) 82 return -EFAULT; 83 if (part < pmac_nvram_OF || part > pmac_nvram_NR) 84 return -EINVAL; 85 offset = pmac_get_partition(part); 86 if (copy_to_user((void __user*)arg, &offset, sizeof(offset)) != 0) 87 return -EFAULT; 88 break; 89 } 90 91 default: 92 return -EINVAL; 93 } 94 95 return 0; 96} 97 98const struct file_operations nvram_fops = { 99 .owner = THIS_MODULE, 100 .llseek = nvram_llseek, 101 .read = read_nvram, 102 .write = write_nvram, 103 .unlocked_ioctl = nvram_ioctl, 104}; 105 106static struct miscdevice nvram_dev = { 107 NVRAM_MINOR, 108 "nvram", 109 &nvram_fops 110}; 111 112int __init nvram_init(void) 113{ 114 printk(KERN_INFO "Macintosh non-volatile memory driver v%s\n", 115 NVRAM_VERSION); 116 return misc_register(&nvram_dev); 117} 118 119void __exit nvram_cleanup(void) 120{ 121 misc_deregister( &nvram_dev ); 122} 123 124module_init(nvram_init); 125module_exit(nvram_cleanup); 126MODULE_LICENSE("GPL"); 127