xref: /openbmc/linux/drivers/char/nvram.c (revision 437ace37)
1 /*
2  * CMOS/NV-RAM driver for Linux
3  *
4  * Copyright (C) 1997 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
5  * idea by and with help from Richard Jelinek <rj@suse.de>
6  * Portions copyright (c) 2001,2002 Sun Microsystems (thockin@sun.com)
7  *
8  * This driver allows you to access the contents of the non-volatile memory in
9  * the mc146818rtc.h real-time clock. This chip is built into all PCs and into
10  * many Atari machines. In the former it's called "CMOS-RAM", in the latter
11  * "NVRAM" (NV stands for non-volatile).
12  *
13  * The data are supplied as a (seekable) character device, /dev/nvram. The
14  * size of this file is dependent on the controller.  The usual size is 114,
15  * the number of freely available bytes in the memory (i.e., not used by the
16  * RTC itself).
17  *
18  * Checksums over the NVRAM contents are managed by this driver. In case of a
19  * bad checksum, reads and writes return -EIO. The checksum can be initialized
20  * to a sane state either by ioctl(NVRAM_INIT) (clear whole NVRAM) or
21  * ioctl(NVRAM_SETCKS) (doesn't change contents, just makes checksum valid
22  * again; use with care!)
23  *
24  * 	1.1	Cesar Barros: SMP locking fixes
25  * 		added changelog
26  * 	1.2	Erik Gilling: Cobalt Networks support
27  * 		Tim Hockin: general cleanup, Cobalt support
28  * 	1.3	Wim Van Sebroeck: convert PRINT_PROC to seq_file
29  */
30 
31 #define NVRAM_VERSION	"1.3"
32 
33 #include <linux/module.h>
34 #include <linux/nvram.h>
35 #include <linux/types.h>
36 #include <linux/errno.h>
37 #include <linux/miscdevice.h>
38 #include <linux/ioport.h>
39 #include <linux/fcntl.h>
40 #include <linux/mc146818rtc.h>
41 #include <linux/init.h>
42 #include <linux/proc_fs.h>
43 #include <linux/seq_file.h>
44 #include <linux/spinlock.h>
45 #include <linux/io.h>
46 #include <linux/uaccess.h>
47 #include <linux/mutex.h>
48 #include <linux/pagemap.h>
49 
50 
51 static DEFINE_MUTEX(nvram_mutex);
52 static DEFINE_SPINLOCK(nvram_state_lock);
53 static int nvram_open_cnt;	/* #times opened */
54 static int nvram_open_mode;	/* special open modes */
55 #define NVRAM_WRITE		1 /* opened for writing (exclusive) */
56 #define NVRAM_EXCL		2 /* opened with O_EXCL */
57 
58 #ifdef CONFIG_PROC_FS
59 static void pc_nvram_proc_read(unsigned char *contents, struct seq_file *seq,
60 			       void *offset);
61 #endif
62 
63 /*
64  * These functions are provided to be called internally or by other parts of
65  * the kernel. It's up to the caller to ensure correct checksum before reading
66  * or after writing (needs to be done only once).
67  *
68  * It is worth noting that these functions all access bytes of general
69  * purpose memory in the NVRAM - that is to say, they all add the
70  * NVRAM_FIRST_BYTE offset.  Pass them offsets into NVRAM as if you did not
71  * know about the RTC cruft.
72  */
73 
74 #define NVRAM_BYTES		(128 - NVRAM_FIRST_BYTE)
75 
76 /* Note that *all* calls to CMOS_READ and CMOS_WRITE must be done with
77  * rtc_lock held. Due to the index-port/data-port design of the RTC, we
78  * don't want two different things trying to get to it at once. (e.g. the
79  * periodic 11 min sync from kernel/time/ntp.c vs. this driver.)
80  */
81 
82 unsigned char __nvram_read_byte(int i)
83 {
84 	return CMOS_READ(NVRAM_FIRST_BYTE + i);
85 }
86 EXPORT_SYMBOL(__nvram_read_byte);
87 
88 unsigned char nvram_read_byte(int i)
89 {
90 	unsigned long flags;
91 	unsigned char c;
92 
93 	spin_lock_irqsave(&rtc_lock, flags);
94 	c = __nvram_read_byte(i);
95 	spin_unlock_irqrestore(&rtc_lock, flags);
96 	return c;
97 }
98 EXPORT_SYMBOL(nvram_read_byte);
99 
100 /* This races nicely with trying to read with checksum checking (nvram_read) */
101 void __nvram_write_byte(unsigned char c, int i)
102 {
103 	CMOS_WRITE(c, NVRAM_FIRST_BYTE + i);
104 }
105 EXPORT_SYMBOL(__nvram_write_byte);
106 
107 void nvram_write_byte(unsigned char c, int i)
108 {
109 	unsigned long flags;
110 
111 	spin_lock_irqsave(&rtc_lock, flags);
112 	__nvram_write_byte(c, i);
113 	spin_unlock_irqrestore(&rtc_lock, flags);
114 }
115 EXPORT_SYMBOL(nvram_write_byte);
116 
117 /* On PCs, the checksum is built only over bytes 2..31 */
118 #define PC_CKS_RANGE_START	2
119 #define PC_CKS_RANGE_END	31
120 #define PC_CKS_LOC		32
121 
122 int __nvram_check_checksum(void)
123 {
124 	int i;
125 	unsigned short sum = 0;
126 	unsigned short expect;
127 
128 	for (i = PC_CKS_RANGE_START; i <= PC_CKS_RANGE_END; ++i)
129 		sum += __nvram_read_byte(i);
130 	expect = __nvram_read_byte(PC_CKS_LOC)<<8 |
131 	    __nvram_read_byte(PC_CKS_LOC+1);
132 	return (sum & 0xffff) == expect;
133 }
134 EXPORT_SYMBOL(__nvram_check_checksum);
135 
136 int nvram_check_checksum(void)
137 {
138 	unsigned long flags;
139 	int rv;
140 
141 	spin_lock_irqsave(&rtc_lock, flags);
142 	rv = __nvram_check_checksum();
143 	spin_unlock_irqrestore(&rtc_lock, flags);
144 	return rv;
145 }
146 EXPORT_SYMBOL(nvram_check_checksum);
147 
148 static void __nvram_set_checksum(void)
149 {
150 	int i;
151 	unsigned short sum = 0;
152 
153 	for (i = PC_CKS_RANGE_START; i <= PC_CKS_RANGE_END; ++i)
154 		sum += __nvram_read_byte(i);
155 	__nvram_write_byte(sum >> 8, PC_CKS_LOC);
156 	__nvram_write_byte(sum & 0xff, PC_CKS_LOC + 1);
157 }
158 
159 #if 0
160 void nvram_set_checksum(void)
161 {
162 	unsigned long flags;
163 
164 	spin_lock_irqsave(&rtc_lock, flags);
165 	__nvram_set_checksum();
166 	spin_unlock_irqrestore(&rtc_lock, flags);
167 }
168 #endif  /*  0  */
169 
170 /*
171  * The are the file operation function for user access to /dev/nvram
172  */
173 
174 static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
175 {
176 	return generic_file_llseek_size(file, offset, origin, MAX_LFS_FILESIZE,
177 					NVRAM_BYTES);
178 }
179 
180 static ssize_t nvram_read(struct file *file, char __user *buf,
181 						size_t count, loff_t *ppos)
182 {
183 	unsigned char contents[NVRAM_BYTES];
184 	unsigned i = *ppos;
185 	unsigned char *tmp;
186 
187 	spin_lock_irq(&rtc_lock);
188 
189 	if (!__nvram_check_checksum())
190 		goto checksum_err;
191 
192 	for (tmp = contents; count-- > 0 && i < NVRAM_BYTES; ++i, ++tmp)
193 		*tmp = __nvram_read_byte(i);
194 
195 	spin_unlock_irq(&rtc_lock);
196 
197 	if (copy_to_user(buf, contents, tmp - contents))
198 		return -EFAULT;
199 
200 	*ppos = i;
201 
202 	return tmp - contents;
203 
204 checksum_err:
205 	spin_unlock_irq(&rtc_lock);
206 	return -EIO;
207 }
208 
209 static ssize_t nvram_write(struct file *file, const char __user *buf,
210 						size_t count, loff_t *ppos)
211 {
212 	unsigned char contents[NVRAM_BYTES];
213 	unsigned i = *ppos;
214 	unsigned char *tmp;
215 
216 	if (i >= NVRAM_BYTES)
217 		return 0;	/* Past EOF */
218 
219 	if (count > NVRAM_BYTES - i)
220 		count = NVRAM_BYTES - i;
221 	if (count > NVRAM_BYTES)
222 		return -EFAULT;	/* Can't happen, but prove it to gcc */
223 
224 	if (copy_from_user(contents, buf, count))
225 		return -EFAULT;
226 
227 	spin_lock_irq(&rtc_lock);
228 
229 	if (!__nvram_check_checksum())
230 		goto checksum_err;
231 
232 	for (tmp = contents; count--; ++i, ++tmp)
233 		__nvram_write_byte(*tmp, i);
234 
235 	__nvram_set_checksum();
236 
237 	spin_unlock_irq(&rtc_lock);
238 
239 	*ppos = i;
240 
241 	return tmp - contents;
242 
243 checksum_err:
244 	spin_unlock_irq(&rtc_lock);
245 	return -EIO;
246 }
247 
248 static long nvram_ioctl(struct file *file, unsigned int cmd,
249 			unsigned long arg)
250 {
251 	int i;
252 
253 	switch (cmd) {
254 
255 	case NVRAM_INIT:
256 		/* initialize NVRAM contents and checksum */
257 		if (!capable(CAP_SYS_ADMIN))
258 			return -EACCES;
259 
260 		mutex_lock(&nvram_mutex);
261 		spin_lock_irq(&rtc_lock);
262 
263 		for (i = 0; i < NVRAM_BYTES; ++i)
264 			__nvram_write_byte(0, i);
265 		__nvram_set_checksum();
266 
267 		spin_unlock_irq(&rtc_lock);
268 		mutex_unlock(&nvram_mutex);
269 		return 0;
270 
271 	case NVRAM_SETCKS:
272 		/* just set checksum, contents unchanged (maybe useful after
273 		 * checksum garbaged somehow...) */
274 		if (!capable(CAP_SYS_ADMIN))
275 			return -EACCES;
276 
277 		mutex_lock(&nvram_mutex);
278 		spin_lock_irq(&rtc_lock);
279 		__nvram_set_checksum();
280 		spin_unlock_irq(&rtc_lock);
281 		mutex_unlock(&nvram_mutex);
282 		return 0;
283 
284 	default:
285 		return -ENOTTY;
286 	}
287 }
288 
289 static int nvram_open(struct inode *inode, struct file *file)
290 {
291 	spin_lock(&nvram_state_lock);
292 
293 	if ((nvram_open_cnt && (file->f_flags & O_EXCL)) ||
294 	    (nvram_open_mode & NVRAM_EXCL) ||
295 	    ((file->f_mode & FMODE_WRITE) && (nvram_open_mode & NVRAM_WRITE))) {
296 		spin_unlock(&nvram_state_lock);
297 		return -EBUSY;
298 	}
299 
300 	if (file->f_flags & O_EXCL)
301 		nvram_open_mode |= NVRAM_EXCL;
302 	if (file->f_mode & FMODE_WRITE)
303 		nvram_open_mode |= NVRAM_WRITE;
304 	nvram_open_cnt++;
305 
306 	spin_unlock(&nvram_state_lock);
307 
308 	return 0;
309 }
310 
311 static int nvram_release(struct inode *inode, struct file *file)
312 {
313 	spin_lock(&nvram_state_lock);
314 
315 	nvram_open_cnt--;
316 
317 	/* if only one instance is open, clear the EXCL bit */
318 	if (nvram_open_mode & NVRAM_EXCL)
319 		nvram_open_mode &= ~NVRAM_EXCL;
320 	if (file->f_mode & FMODE_WRITE)
321 		nvram_open_mode &= ~NVRAM_WRITE;
322 
323 	spin_unlock(&nvram_state_lock);
324 
325 	return 0;
326 }
327 
328 #ifndef CONFIG_PROC_FS
329 static int nvram_add_proc_fs(void)
330 {
331 	return 0;
332 }
333 
334 #else
335 
336 static int nvram_proc_read(struct seq_file *seq, void *offset)
337 {
338 	unsigned char contents[NVRAM_BYTES];
339 	int i = 0;
340 
341 	spin_lock_irq(&rtc_lock);
342 	for (i = 0; i < NVRAM_BYTES; ++i)
343 		contents[i] = __nvram_read_byte(i);
344 	spin_unlock_irq(&rtc_lock);
345 
346 	pc_nvram_proc_read(contents, seq, offset);
347 
348 	return 0;
349 }
350 
351 static int nvram_add_proc_fs(void)
352 {
353 	if (!proc_create_single("driver/nvram", 0, NULL, nvram_proc_read))
354 		return -ENOMEM;
355 	return 0;
356 }
357 
358 #endif /* CONFIG_PROC_FS */
359 
360 static const struct file_operations nvram_fops = {
361 	.owner		= THIS_MODULE,
362 	.llseek		= nvram_llseek,
363 	.read		= nvram_read,
364 	.write		= nvram_write,
365 	.unlocked_ioctl	= nvram_ioctl,
366 	.open		= nvram_open,
367 	.release	= nvram_release,
368 };
369 
370 static struct miscdevice nvram_dev = {
371 	NVRAM_MINOR,
372 	"nvram",
373 	&nvram_fops
374 };
375 
376 static int __init nvram_init(void)
377 {
378 	int ret;
379 
380 	ret = misc_register(&nvram_dev);
381 	if (ret) {
382 		printk(KERN_ERR "nvram: can't misc_register on minor=%d\n",
383 		    NVRAM_MINOR);
384 		goto out;
385 	}
386 	ret = nvram_add_proc_fs();
387 	if (ret) {
388 		printk(KERN_ERR "nvram: can't create /proc/driver/nvram\n");
389 		goto outmisc;
390 	}
391 	ret = 0;
392 	printk(KERN_INFO "Non-volatile memory driver v" NVRAM_VERSION "\n");
393 out:
394 	return ret;
395 outmisc:
396 	misc_deregister(&nvram_dev);
397 	goto out;
398 }
399 
400 static void __exit nvram_cleanup_module(void)
401 {
402 	remove_proc_entry("driver/nvram", NULL);
403 	misc_deregister(&nvram_dev);
404 }
405 
406 module_init(nvram_init);
407 module_exit(nvram_cleanup_module);
408 
409 #ifdef CONFIG_PROC_FS
410 
411 static const char * const floppy_types[] = {
412 	"none", "5.25'' 360k", "5.25'' 1.2M", "3.5'' 720k", "3.5'' 1.44M",
413 	"3.5'' 2.88M", "3.5'' 2.88M"
414 };
415 
416 static const char * const gfx_types[] = {
417 	"EGA, VGA, ... (with BIOS)",
418 	"CGA (40 cols)",
419 	"CGA (80 cols)",
420 	"monochrome",
421 };
422 
423 static void pc_nvram_proc_read(unsigned char *nvram, struct seq_file *seq,
424 			       void *offset)
425 {
426 	int checksum;
427 	int type;
428 
429 	spin_lock_irq(&rtc_lock);
430 	checksum = __nvram_check_checksum();
431 	spin_unlock_irq(&rtc_lock);
432 
433 	seq_printf(seq, "Checksum status: %svalid\n", checksum ? "" : "not ");
434 
435 	seq_printf(seq, "# floppies     : %d\n",
436 	    (nvram[6] & 1) ? (nvram[6] >> 6) + 1 : 0);
437 	seq_printf(seq, "Floppy 0 type  : ");
438 	type = nvram[2] >> 4;
439 	if (type < ARRAY_SIZE(floppy_types))
440 		seq_printf(seq, "%s\n", floppy_types[type]);
441 	else
442 		seq_printf(seq, "%d (unknown)\n", type);
443 	seq_printf(seq, "Floppy 1 type  : ");
444 	type = nvram[2] & 0x0f;
445 	if (type < ARRAY_SIZE(floppy_types))
446 		seq_printf(seq, "%s\n", floppy_types[type]);
447 	else
448 		seq_printf(seq, "%d (unknown)\n", type);
449 
450 	seq_printf(seq, "HD 0 type      : ");
451 	type = nvram[4] >> 4;
452 	if (type)
453 		seq_printf(seq, "%02x\n", type == 0x0f ? nvram[11] : type);
454 	else
455 		seq_printf(seq, "none\n");
456 
457 	seq_printf(seq, "HD 1 type      : ");
458 	type = nvram[4] & 0x0f;
459 	if (type)
460 		seq_printf(seq, "%02x\n", type == 0x0f ? nvram[12] : type);
461 	else
462 		seq_printf(seq, "none\n");
463 
464 	seq_printf(seq, "HD type 48 data: %d/%d/%d C/H/S, precomp %d, lz %d\n",
465 	    nvram[18] | (nvram[19] << 8),
466 	    nvram[20], nvram[25],
467 	    nvram[21] | (nvram[22] << 8), nvram[23] | (nvram[24] << 8));
468 	seq_printf(seq, "HD type 49 data: %d/%d/%d C/H/S, precomp %d, lz %d\n",
469 	    nvram[39] | (nvram[40] << 8),
470 	    nvram[41], nvram[46],
471 	    nvram[42] | (nvram[43] << 8), nvram[44] | (nvram[45] << 8));
472 
473 	seq_printf(seq, "DOS base memory: %d kB\n", nvram[7] | (nvram[8] << 8));
474 	seq_printf(seq, "Extended memory: %d kB (configured), %d kB (tested)\n",
475 	    nvram[9] | (nvram[10] << 8), nvram[34] | (nvram[35] << 8));
476 
477 	seq_printf(seq, "Gfx adapter    : %s\n",
478 	    gfx_types[(nvram[6] >> 4) & 3]);
479 
480 	seq_printf(seq, "FPU            : %sinstalled\n",
481 	    (nvram[6] & 2) ? "" : "not ");
482 
483 	return;
484 }
485 
486 #endif /* CONFIG_PROC_FS */
487 
488 MODULE_LICENSE("GPL");
489 MODULE_ALIAS_MISCDEV(NVRAM_MINOR);
490