Advertisement
Guest User

Untitled

a guest
Jul 28th, 2015
217
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.86 KB | None | 0 0
  1. #include<linux/module.h>
  2. #include<linux/kernel.h>
  3. #include<linux/fs.h>
  4. #include<linux/interrupt.h>
  5. #include<linux/cdev.h>
  6. #include<asm/uaccess.h>
  7. #include<asm/io.h>
  8. #include<linux/semaphore.h>
  9. #include<linux/spinlock.h>
  10. #include<linux/sched.h>
  11. #include<linux/device.h>
  12.  
  13.  
  14.  
  15. #define DEVICE_NAME "klg_app"
  16. #define AUTHOR "morpheus15"
  17. #define LICENSE "GPL"
  18. #define CLASS_NAME "klg_class"
  19. #define FOR(i,x,n) for(i=x;i<n;i++)
  20. #define BUF_MAX_SIZE 10
  21. #define FIRST_MINOR_NUM 0
  22. #define MINOR_DEVICE_COUNT 1
  23.  
  24. typedef struct
  25. {
  26. char data[BUF_MAX_SIZE];
  27. }klg_device_t;
  28.  
  29.  
  30. static klg_device_t klgdev;
  31. static int ret,major;
  32. static dev_t dev_num;
  33. static struct cdev *kcdev = NULL;
  34. static struct class *klg_class = NULL;
  35. static struct semaphore semm;
  36.  
  37. static int klg_open(struct inode *klg_inode,struct file *filp)
  38. {
  39. filp->private_data = &klgdev;
  40. /*if(down_interruptible(&semm))
  41. {
  42. printk(KERN_INFO "could not open device %sn",DEVICE_NAME);
  43. return -ERESTARTSYS;
  44. }
  45. */
  46. printk(KERN_INFO "device %s called open()n",DEVICE_NAME);
  47. return 0;
  48. }
  49.  
  50. static int klg_close(struct inode *klg_inode,struct file *filp)
  51. {
  52. //up(&semm);
  53. printk(KERN_INFO "device %s called close()n",DEVICE_NAME);
  54. return 0;
  55. }
  56.  
  57. static ssize_t klg_read(struct file *filp,char __user *buf,size_t count,loff_t *pos)
  58. {
  59. printk(KERN_INFO "device %s called read()n",DEVICE_NAME);
  60. klg_device_t *klgp = filp->private_data;
  61. if (down_interruptible(&semm))
  62. {
  63. printk(KERN_INFO "device %s already in use. could not open for readingn",DEVICE_NAME);
  64. return -ERESTARTSYS;
  65. }
  66.  
  67. int len = strlen(klgp->data);
  68. if (!len || (*pos) > len)
  69. {
  70. up(&semm);
  71. return 0;
  72. }
  73.  
  74.  
  75. if (*pos + count > len)
  76. {
  77. count = len - *pos;
  78. }
  79.  
  80. ret = copy_to_user(buf,klgp->data,count);
  81. if (ret)
  82. {
  83. printk(KERN_INFO "copy_to_user() failed for device %s, exit with error %dn",DEVICE_NAME,ret);
  84. up(&semm);
  85. return -EFAULT;
  86. }
  87.  
  88. (*pos) += count;
  89. up(&semm);
  90. return count;
  91.  
  92. }
  93.  
  94. static ssize_t klg_write(struct file *filp,char __user *buf,size_t count,loff_t *pos)
  95. {
  96.  
  97.  
  98. printk(KERN_INFO "device %s called write()n",DEVICE_NAME);
  99. klg_device_t *klgp = filp->private_data;
  100. if (down_interruptible(&semm))
  101. {
  102. printk(KERN_INFO "device %s already in use. Could not open for writingn",DEVICE_NAME);
  103. return -ERESTARTSYS;
  104. }
  105.  
  106.  
  107. memset(klgp->data,0,BUF_MAX_SIZE);
  108.  
  109. if (count > BUF_MAX_SIZE)
  110. {
  111. count = BUF_MAX_SIZE;
  112. }
  113.  
  114. ret = copy_from_user(klgp->data,buf,count);
  115. if (ret)
  116. {
  117. printk(KERN_INFO "copy_from_user() failed for device %s, exit with error %dn",DEVICE_NAME,ret);
  118. up(&semm);
  119. return -EFAULT;
  120. }
  121.  
  122. up(&semm);
  123. return count;
  124.  
  125.  
  126. }
  127.  
  128.  
  129. static struct file_operations fops =
  130. {
  131. .owner = AUTHOR,
  132. .open = klg_open,
  133. .release = klg_close,
  134. .read = klg_read,
  135. .write = klg_write
  136. };
  137.  
  138.  
  139.  
  140. static void initialize_constructs(void)
  141. {
  142. sema_init(&semm,1);
  143. }
  144.  
  145. static int __init klg_init(void)
  146. {
  147. ret = alloc_chrdev_region(&dev_num,FIRST_MINOR_NUM,MINOR_DEVICE_COUNT,DEVICE_NAME);
  148. if (ret)
  149. {
  150. printk(KERN_INFO "could not alloc_chrdev_region for device %sn",DEVICE_NAME);
  151. return -1;
  152. }
  153. major = MAJOR(dev_num);
  154. printk(KERN_INFO "registered device %s with major number %dn",DEVICE_NAME,major);
  155.  
  156.  
  157. // add the device to /sys/class/CLASS_NAME
  158. klg_class = class_create(DEVICE_NAME,CLASS_NAME);
  159. if (!klg_class)
  160. {
  161. printk(KERN_INFO "could not add device %s to /sys/class/%sn",CLASS_NAME);
  162. unregister_chrdev_region(dev_num,MINOR_DEVICE_COUNT);
  163. return -2;
  164. }
  165.  
  166. // create an entry in /dev for the device file
  167. if (!device_create(klg_class,NULL,dev_num,NULL,DEVICE_NAME))
  168. {
  169. printk(KERN_INFO "could not create entry /dev/%s for device %sn",DEVICE_NAME,DEVICE_NAME);
  170. class_destroy(klg_class);
  171. unregister_chrdev_region(dev_num,MINOR_DEVICE_COUNT);
  172. return -2;
  173. }
  174.  
  175. // create the cdev struct for the character device
  176. kcdev = cdev_alloc();
  177. kcdev->owner = AUTHOR;
  178. kcdev->ops = &fops;
  179. ret = cdev_add(kcdev,dev_num,MINOR_DEVICE_COUNT);
  180. if (ret)
  181. {
  182. printk(KERN_INFO "could not allocate a char dev struct for device %sn",DEVICE_NAME);
  183. device_destroy(klg_class,dev_num);
  184. class_destroy(klg_class);
  185. unregister_chrdev_region(dev_num,MINOR_DEVICE_COUNT);
  186. return -1;
  187. }
  188.  
  189.  
  190. initialize_constructs();
  191. printk(KERN_INFO "successfully created a character device driver for device %sn",DEVICE_NAME);
  192. return 0;
  193. }
  194.  
  195. static void __exit klg_exit(void)
  196. {
  197. // destroy in the reverse order
  198. cdev_del(kcdev);
  199. device_destroy(klg_class,dev_num);
  200. class_destroy(klg_class);
  201. unregister_chrdev_region(dev_num,MINOR_DEVICE_COUNT);
  202. printk(KERN_INFO "successfully unregistered character device %s and all its componentsn",DEVICE_NAME);
  203. }
  204.  
  205.  
  206. module_init(klg_init);
  207. module_exit(klg_exit);
  208. MODULE_AUTHOR(AUTHOR);
  209. MODULE_LICENSE(LICENSE);
  210. MODULE_DESCRIPTION("this is a sample application");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement