nvram.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:3k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  c 2001 PPC 64 Team, IBM Corp
  3.  *
  4.  *      This program is free software; you can redistribute it and/or
  5.  *      modify it under the terms of the GNU General Public License
  6.  *      as published by the Free Software Foundation; either version
  7.  *      2 of the License, or (at your option) any later version.
  8.  *
  9.  * /dev/nvram driver for PPC64
  10.  *
  11.  * This perhaps should live in drivers/char
  12.  */
  13. #include <linux/module.h>
  14. #include <linux/types.h>
  15. #include <linux/errno.h>
  16. #include <linux/fs.h>
  17. #include <linux/miscdevice.h>
  18. #include <linux/fcntl.h>
  19. #include <linux/nvram.h>
  20. #include <linux/init.h>
  21. #include <asm/uaccess.h>
  22. #include <asm/nvram.h>
  23. #include <asm/rtas.h>
  24. #include <asm/prom.h>
  25. static unsigned int rtas_nvram_size;
  26. static unsigned int nvram_fetch, nvram_store;
  27. static char nvram_buf[4]; /* assume this is in the first 4GB */
  28. static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
  29. {
  30. switch (origin) {
  31. case 1:
  32. offset += file->f_pos;
  33. break;
  34. case 2:
  35. offset += rtas_nvram_size;
  36. break;
  37. }
  38. if (offset < 0)
  39. return -EINVAL;
  40. file->f_pos = offset;
  41. return file->f_pos;
  42. }
  43. static ssize_t read_nvram(struct file *file, char *buf,
  44.   size_t count, loff_t *ppos)
  45. {
  46. unsigned int i;
  47. unsigned long len;
  48. char *p = buf;
  49. if (verify_area(VERIFY_WRITE, buf, count))
  50. return -EFAULT;
  51. if (*ppos >= rtas_nvram_size)
  52. return 0;
  53. for (i = *ppos; count > 0 && i < rtas_nvram_size; ++i, ++p, --count) {
  54. if ((rtas_call(nvram_fetch, 3, 2, &len, i, __pa(nvram_buf), 1) != 0) ||
  55.     len != 1)
  56. return -EIO;
  57. if (__put_user(nvram_buf[0], p))
  58. return -EFAULT;
  59. }
  60. *ppos = i;
  61. return p - buf;
  62. }
  63. static ssize_t write_nvram(struct file *file, const char *buf,
  64.    size_t count, loff_t *ppos)
  65. {
  66. unsigned int i;
  67. unsigned long len;
  68. const char *p = buf;
  69. char c;
  70. if (verify_area(VERIFY_READ, buf, count))
  71. return -EFAULT;
  72. if (*ppos >= rtas_nvram_size)
  73. return 0;
  74. for (i = *ppos; count > 0 && i < rtas_nvram_size; ++i, ++p, --count) {
  75. if (__get_user(c, p))
  76. return -EFAULT;
  77. nvram_buf[0] = c;
  78. if ((rtas_call(nvram_store, 3, 2, &len, i, __pa(nvram_buf), 1) != 0) ||
  79.     len != 1)
  80. return -EIO;
  81. }
  82. *ppos = i;
  83. return p - buf;
  84. }
  85. static int nvram_ioctl(struct inode *inode, struct file *file,
  86. unsigned int cmd, unsigned long arg)
  87. {
  88. return -EINVAL;
  89. }
  90. struct file_operations nvram_fops = {
  91. owner: THIS_MODULE,
  92. llseek: nvram_llseek,
  93. read: read_nvram,
  94. write: write_nvram,
  95. ioctl: nvram_ioctl,
  96. };
  97. static struct miscdevice nvram_dev = {
  98. NVRAM_MINOR,
  99. "nvram",
  100. &nvram_fops
  101. };
  102. int __init nvram_init(void)
  103. {
  104. struct device_node *nvram;
  105. unsigned int *nbytes_p, proplen;
  106. if ((nvram = find_type_devices("nvram")) != NULL) {
  107. nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen);
  108. if (nbytes_p && proplen == sizeof(unsigned int)) {
  109. rtas_nvram_size = *nbytes_p;
  110. }
  111. }
  112. nvram_fetch = rtas_token("nvram-fetch");
  113. nvram_store = rtas_token("nvram-store");
  114. printk(KERN_INFO "PPC64 nvram contains %d bytesn", rtas_nvram_size);
  115. misc_register(&nvram_dev);
  116. return 0;
  117. }
  118. void __exit nvram_cleanup(void)
  119. {
  120.         misc_deregister( &nvram_dev );
  121. }
  122. module_init(nvram_init);
  123. module_exit(nvram_cleanup);
  124. MODULE_LICENSE("GPL");