nvram.c (437ace3777abc15d013d04e6644b100040bc613d) nvram.c (cb8d8006d43f22924e000c730d18862587a824ff)
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

--- 41 unchanged lines hidden (view full) ---

50
51static DEFINE_MUTEX(nvram_mutex);
52static DEFINE_SPINLOCK(nvram_state_lock);
53static int nvram_open_cnt; /* #times opened */
54static 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
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

--- 41 unchanged lines hidden (view full) ---

50
51static DEFINE_MUTEX(nvram_mutex);
52static DEFINE_SPINLOCK(nvram_state_lock);
53static int nvram_open_cnt; /* #times opened */
54static 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
59static 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

--- 95 unchanged lines hidden (view full) ---

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
58/*
59 * These functions are provided to be called internally or by other parts of
60 * the kernel. It's up to the caller to ensure correct checksum before reading
61 * or after writing (needs to be done only once).
62 *
63 * It is worth noting that these functions all access bytes of general
64 * purpose memory in the NVRAM - that is to say, they all add the
65 * NVRAM_FIRST_BYTE offset. Pass them offsets into NVRAM as if you did not

--- 95 unchanged lines hidden (view full) ---

161 spin_unlock_irqrestore(&rtc_lock, flags);
162}
163#endif /* 0 */
164
165/*
166 * The are the file operation function for user access to /dev/nvram
167 */
168
174static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
169static loff_t nvram_misc_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
170{
171 return generic_file_llseek_size(file, offset, origin, MAX_LFS_FILESIZE,
172 NVRAM_BYTES);
173}
174
180static ssize_t nvram_read(struct file *file, char __user *buf,
181 size_t count, loff_t *ppos)
175static ssize_t nvram_misc_read(struct file *file, char __user *buf,
176 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())

--- 11 unchanged lines hidden (view full) ---

201
202 return tmp - contents;
203
204checksum_err:
205 spin_unlock_irq(&rtc_lock);
206 return -EIO;
207}
208
177{
178 unsigned char contents[NVRAM_BYTES];
179 unsigned i = *ppos;
180 unsigned char *tmp;
181
182 spin_lock_irq(&rtc_lock);
183
184 if (!__nvram_check_checksum())

--- 11 unchanged lines hidden (view full) ---

196
197 return tmp - contents;
198
199checksum_err:
200 spin_unlock_irq(&rtc_lock);
201 return -EIO;
202}
203
209static ssize_t nvram_write(struct file *file, const char __user *buf,
210 size_t count, loff_t *ppos)
204static ssize_t nvram_misc_write(struct file *file, const char __user *buf,
205 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

--- 21 unchanged lines hidden (view full) ---

240
241 return tmp - contents;
242
243checksum_err:
244 spin_unlock_irq(&rtc_lock);
245 return -EIO;
246}
247
206{
207 unsigned char contents[NVRAM_BYTES];
208 unsigned i = *ppos;
209 unsigned char *tmp;
210
211 if (i >= NVRAM_BYTES)
212 return 0; /* Past EOF */
213

--- 21 unchanged lines hidden (view full) ---

235
236 return tmp - contents;
237
238checksum_err:
239 spin_unlock_irq(&rtc_lock);
240 return -EIO;
241}
242
248static long nvram_ioctl(struct file *file, unsigned int cmd,
249 unsigned long arg)
243static long nvram_misc_ioctl(struct file *file, unsigned int cmd,
244 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))

--- 23 unchanged lines hidden (view full) ---

281 mutex_unlock(&nvram_mutex);
282 return 0;
283
284 default:
285 return -ENOTTY;
286 }
287}
288
245{
246 int i;
247
248 switch (cmd) {
249
250 case NVRAM_INIT:
251 /* initialize NVRAM contents and checksum */
252 if (!capable(CAP_SYS_ADMIN))

--- 23 unchanged lines hidden (view full) ---

276 mutex_unlock(&nvram_mutex);
277 return 0;
278
279 default:
280 return -ENOTTY;
281 }
282}
283
289static int nvram_open(struct inode *inode, struct file *file)
284static int nvram_misc_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;

--- 5 unchanged lines hidden (view full) ---

303 nvram_open_mode |= NVRAM_WRITE;
304 nvram_open_cnt++;
305
306 spin_unlock(&nvram_state_lock);
307
308 return 0;
309}
310
285{
286 spin_lock(&nvram_state_lock);
287
288 if ((nvram_open_cnt && (file->f_flags & O_EXCL)) ||
289 (nvram_open_mode & NVRAM_EXCL) ||
290 ((file->f_mode & FMODE_WRITE) && (nvram_open_mode & NVRAM_WRITE))) {
291 spin_unlock(&nvram_state_lock);
292 return -EBUSY;

--- 5 unchanged lines hidden (view full) ---

298 nvram_open_mode |= NVRAM_WRITE;
299 nvram_open_cnt++;
300
301 spin_unlock(&nvram_state_lock);
302
303 return 0;
304}
305
311static int nvram_release(struct inode *inode, struct file *file)
306static int nvram_misc_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
307{
308 spin_lock(&nvram_state_lock);
309
310 nvram_open_cnt--;
311
312 /* if only one instance is open, clear the EXCL bit */
313 if (nvram_open_mode & NVRAM_EXCL)
314 nvram_open_mode &= ~NVRAM_EXCL;
315 if (file->f_mode & FMODE_WRITE)
316 nvram_open_mode &= ~NVRAM_WRITE;
317
318 spin_unlock(&nvram_state_lock);
319
320 return 0;
321}
322
328#ifndef CONFIG_PROC_FS
329static int nvram_add_proc_fs(void)
330{
331 return 0;
332}
333
334#else
335
336static 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
351static 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
360static 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
370static struct miscdevice nvram_dev = {
371 NVRAM_MINOR,
372 "nvram",
373 &nvram_fops
374};
375
376static 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");
393out:
394 return ret;
395outmisc:
396 misc_deregister(&nvram_dev);
397 goto out;
398}
399
400static void __exit nvram_cleanup_module(void)
401{
402 remove_proc_entry("driver/nvram", NULL);
403 misc_deregister(&nvram_dev);
404}
405
406module_init(nvram_init);
407module_exit(nvram_cleanup_module);
408
409#ifdef CONFIG_PROC_FS
410
411static 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
416static const char * const gfx_types[] = {

--- 61 unchanged lines hidden (view full) ---

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
323#ifdef CONFIG_PROC_FS
324
325static const char * const floppy_types[] = {
326 "none", "5.25'' 360k", "5.25'' 1.2M", "3.5'' 720k", "3.5'' 1.44M",
327 "3.5'' 2.88M", "3.5'' 2.88M"
328};
329
330static const char * const gfx_types[] = {

--- 61 unchanged lines hidden (view full) ---

392 gfx_types[(nvram[6] >> 4) & 3]);
393
394 seq_printf(seq, "FPU : %sinstalled\n",
395 (nvram[6] & 2) ? "" : "not ");
396
397 return;
398}
399
400static int nvram_proc_read(struct seq_file *seq, void *offset)
401{
402 unsigned char contents[NVRAM_BYTES];
403 int i = 0;
404
405 spin_lock_irq(&rtc_lock);
406 for (i = 0; i < NVRAM_BYTES; ++i)
407 contents[i] = __nvram_read_byte(i);
408 spin_unlock_irq(&rtc_lock);
409
410 pc_nvram_proc_read(contents, seq, offset);
411
412 return 0;
413}
486#endif /* CONFIG_PROC_FS */
487
414#endif /* CONFIG_PROC_FS */
415
416static const struct file_operations nvram_misc_fops = {
417 .owner = THIS_MODULE,
418 .llseek = nvram_misc_llseek,
419 .read = nvram_misc_read,
420 .write = nvram_misc_write,
421 .unlocked_ioctl = nvram_misc_ioctl,
422 .open = nvram_misc_open,
423 .release = nvram_misc_release,
424};
425
426static struct miscdevice nvram_misc = {
427 NVRAM_MINOR,
428 "nvram",
429 &nvram_misc_fops,
430};
431
432static int __init nvram_module_init(void)
433{
434 int ret;
435
436 ret = misc_register(&nvram_misc);
437 if (ret) {
438 pr_err("nvram: can't misc_register on minor=%d\n", NVRAM_MINOR);
439 return ret;
440 }
441
442#ifdef CONFIG_PROC_FS
443 if (!proc_create_single("driver/nvram", 0, NULL, nvram_proc_read)) {
444 pr_err("nvram: can't create /proc/driver/nvram\n");
445 misc_deregister(&nvram_misc);
446 return -ENOMEM;
447 }
448#endif
449
450 pr_info("Non-volatile memory driver v" NVRAM_VERSION "\n");
451 return 0;
452}
453
454static void __exit nvram_module_exit(void)
455{
456#ifdef CONFIG_PROC_FS
457 remove_proc_entry("driver/nvram", NULL);
458#endif
459 misc_deregister(&nvram_misc);
460}
461
462module_init(nvram_module_init);
463module_exit(nvram_module_exit);
464
488MODULE_LICENSE("GPL");
489MODULE_ALIAS_MISCDEV(NVRAM_MINOR);
465MODULE_LICENSE("GPL");
466MODULE_ALIAS_MISCDEV(NVRAM_MINOR);