diff options
-rw-r--r-- | arch/powerpc/include/asm/nvram.h | 3 | ||||
-rw-r--r-- | arch/powerpc/kernel/setup_32.c | 8 | ||||
-rw-r--r-- | drivers/char/generic_nvram.c | 27 |
3 files changed, 31 insertions, 7 deletions
diff --git a/arch/powerpc/include/asm/nvram.h b/arch/powerpc/include/asm/nvram.h index efde5ac82f7b..6c587eddee59 100644 --- a/arch/powerpc/include/asm/nvram.h +++ b/arch/powerpc/include/asm/nvram.h | |||
@@ -107,6 +107,9 @@ extern void pmac_xpram_write(int xpaddr, u8 data); | |||
107 | /* Synchronize NVRAM */ | 107 | /* Synchronize NVRAM */ |
108 | extern void nvram_sync(void); | 108 | extern void nvram_sync(void); |
109 | 109 | ||
110 | /* Determine NVRAM size */ | ||
111 | extern ssize_t nvram_get_size(void); | ||
112 | |||
110 | /* Normal access to NVRAM */ | 113 | /* Normal access to NVRAM */ |
111 | extern unsigned char nvram_read_byte(int i); | 114 | extern unsigned char nvram_read_byte(int i); |
112 | extern void nvram_write_byte(unsigned char c, int i); | 115 | extern void nvram_write_byte(unsigned char c, int i); |
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index e1e3059cf34b..53bcf3d792db 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c | |||
@@ -210,6 +210,14 @@ void nvram_write_byte(unsigned char val, int addr) | |||
210 | } | 210 | } |
211 | EXPORT_SYMBOL(nvram_write_byte); | 211 | EXPORT_SYMBOL(nvram_write_byte); |
212 | 212 | ||
213 | ssize_t nvram_get_size(void) | ||
214 | { | ||
215 | if (ppc_md.nvram_size) | ||
216 | return ppc_md.nvram_size(); | ||
217 | return -1; | ||
218 | } | ||
219 | EXPORT_SYMBOL(nvram_get_size); | ||
220 | |||
213 | void nvram_sync(void) | 221 | void nvram_sync(void) |
214 | { | 222 | { |
215 | if (ppc_md.nvram_sync) | 223 | if (ppc_md.nvram_sync) |
diff --git a/drivers/char/generic_nvram.c b/drivers/char/generic_nvram.c index a00869c650d5..ef31738c2cbe 100644 --- a/drivers/char/generic_nvram.c +++ b/drivers/char/generic_nvram.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Generic /dev/nvram driver for architectures providing some | 2 | * Generic /dev/nvram driver for architectures providing some |
3 | * "generic" hooks, that is : | 3 | * "generic" hooks, that is : |
4 | * | 4 | * |
5 | * nvram_read_byte, nvram_write_byte, nvram_sync | 5 | * nvram_read_byte, nvram_write_byte, nvram_sync, nvram_get_size |
6 | * | 6 | * |
7 | * Note that an additional hook is supported for PowerMac only | 7 | * Note that an additional hook is supported for PowerMac only |
8 | * for getting the nvram "partition" informations | 8 | * for getting the nvram "partition" informations |
@@ -28,6 +28,8 @@ | |||
28 | 28 | ||
29 | #define NVRAM_SIZE 8192 | 29 | #define NVRAM_SIZE 8192 |
30 | 30 | ||
31 | static ssize_t nvram_len; | ||
32 | |||
31 | static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) | 33 | static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) |
32 | { | 34 | { |
33 | lock_kernel(); | 35 | lock_kernel(); |
@@ -36,7 +38,7 @@ static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) | |||
36 | offset += file->f_pos; | 38 | offset += file->f_pos; |
37 | break; | 39 | break; |
38 | case 2: | 40 | case 2: |
39 | offset += NVRAM_SIZE; | 41 | offset += nvram_len; |
40 | break; | 42 | break; |
41 | } | 43 | } |
42 | if (offset < 0) { | 44 | if (offset < 0) { |
@@ -56,9 +58,9 @@ static ssize_t read_nvram(struct file *file, char __user *buf, | |||
56 | 58 | ||
57 | if (!access_ok(VERIFY_WRITE, buf, count)) | 59 | if (!access_ok(VERIFY_WRITE, buf, count)) |
58 | return -EFAULT; | 60 | return -EFAULT; |
59 | if (*ppos >= NVRAM_SIZE) | 61 | if (*ppos >= nvram_len) |
60 | return 0; | 62 | return 0; |
61 | for (i = *ppos; count > 0 && i < NVRAM_SIZE; ++i, ++p, --count) | 63 | for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count) |
62 | if (__put_user(nvram_read_byte(i), p)) | 64 | if (__put_user(nvram_read_byte(i), p)) |
63 | return -EFAULT; | 65 | return -EFAULT; |
64 | *ppos = i; | 66 | *ppos = i; |
@@ -74,9 +76,9 @@ static ssize_t write_nvram(struct file *file, const char __user *buf, | |||
74 | 76 | ||
75 | if (!access_ok(VERIFY_READ, buf, count)) | 77 | if (!access_ok(VERIFY_READ, buf, count)) |
76 | return -EFAULT; | 78 | return -EFAULT; |
77 | if (*ppos >= NVRAM_SIZE) | 79 | if (*ppos >= nvram_len) |
78 | return 0; | 80 | return 0; |
79 | for (i = *ppos; count > 0 && i < NVRAM_SIZE; ++i, ++p, --count) { | 81 | for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count) { |
80 | if (__get_user(c, p)) | 82 | if (__get_user(c, p)) |
81 | return -EFAULT; | 83 | return -EFAULT; |
82 | nvram_write_byte(c, i); | 84 | nvram_write_byte(c, i); |
@@ -133,9 +135,20 @@ static struct miscdevice nvram_dev = { | |||
133 | 135 | ||
134 | int __init nvram_init(void) | 136 | int __init nvram_init(void) |
135 | { | 137 | { |
138 | int ret = 0; | ||
139 | |||
136 | printk(KERN_INFO "Generic non-volatile memory driver v%s\n", | 140 | printk(KERN_INFO "Generic non-volatile memory driver v%s\n", |
137 | NVRAM_VERSION); | 141 | NVRAM_VERSION); |
138 | return misc_register(&nvram_dev); | 142 | ret = misc_register(&nvram_dev); |
143 | if (ret != 0) | ||
144 | goto out; | ||
145 | |||
146 | nvram_len = nvram_get_size(); | ||
147 | if (nvram_len < 0) | ||
148 | nvram_len = NVRAM_SIZE; | ||
149 | |||
150 | out: | ||
151 | return ret; | ||
139 | } | 152 | } |
140 | 153 | ||
141 | void __exit nvram_cleanup(void) | 154 | void __exit nvram_cleanup(void) |