Advertisement
Guest User

Untitled

a guest
Dec 9th, 2019
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.29 KB | None | 0 0
  1. /*
  2. * Ring buffer character device - example for Operating System course
  3. *
  4. * Copyright (C) 2016, 2017, 2018 Krzysztof Mazur <krzysiek@podlesie.net>
  5. *
  6. * Add your copyright here and change MODULE_AUTHOR.
  7. *
  8. * Copyright(C) 2019 Jakub Glowacki, Karolina Szotek, Jakub Berwid <jakuglo773@student.polsl.pl> <jakuber444@student.polsl.pl>
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version.
  14. */
  15.  
  16. #define pr_fmt(fmt) "ringdev: " fmt
  17. #include <linux/kernel.h>
  18. #include <linux/module.h>
  19. #include <linux/fs.h>
  20. #include <linux/miscdevice.h>
  21. #include <linux/sched.h>
  22. #include <linux/uaccess.h>
  23. #include <linux/slab.h>
  24.  
  25. /*
  26. * mutex used for access synchronization to buffer (ringdev_buf and ringdev_len)
  27. */
  28. static struct mutex ringdev_lock;
  29. #define BUFFOR 64
  30. static char ringdev_buf[BUFFOR];
  31. static DECLARE_WAIT_QUEUE_HEAD(queue);
  32. static size_t ringdev_len;
  33. static size_t HEAD;
  34. //static size_t TAIL;
  35.  
  36. static int ringdev_open(struct inode *inode, struct file *filp)
  37. {
  38. size_t *tail_p=kmalloc(sizeof(size_t),GFP_KERNEL);
  39. *tail_p = HEAD;
  40. filp->private_data=tail_p;
  41. return 0;
  42. }
  43.  
  44. static ssize_t ringdev_read(struct file *filp, char __user *buf, size_t count, loff_t *off)
  45. {
  46. ssize_t ret=0;
  47. size_t TAIL=0;
  48. size_t* read_p;
  49. read_p = filp->private_data;
  50. TAIL=*read_p;
  51.  
  52. turn_back:
  53. if ((filp->f_flags & O_NONBLOCK) && HEAD==TAIL)
  54. {
  55. return -EAGAIN;
  56. }
  57. else if(!(filp->f_flags & O_NONBLOCK) && HEAD!=TAIL)
  58. {
  59. wait_event_interruptible(queue, HEAD != TAIL);
  60. }
  61. if (HEAD==*read_p) goto turn_back;
  62. mutex_lock(&ringdev_lock);
  63. count=(count>HEAD-TAIL) ? (HEAD-TAIL):(BUFFOR-TAIL);
  64. //if (count>HEAD-TAIL)
  65. //{
  66. // count=HEAD-TAIL;
  67. //}
  68. ret=copy_to_user(buf,ringdev_buf+TAIL,count);
  69. TAIL+=count-ret;
  70. if (TAIL>=BUFFOR)
  71. {
  72. TAIL=0;
  73. }
  74. *read_p=TAIL;
  75. mutex_unlock(&ringdev_lock);
  76. return count -ret;
  77. /*
  78. * access to ringdev_buf i ringdev_len is protected by ringdev_lock,
  79. * take that lock
  80.  
  81. mutex_lock(&ringdev_lock);
  82. if (*off > ringdev_len)
  83. count = 0;
  84. else if (count >= ringdev_len - *off)
  85. count = ringdev_len - *off;
  86.  
  87.  
  88. * for access to user memory special functions must be used,
  89. * to copy to user memory copy_to_user must be used.
  90.  
  91. ret = -EFAULT;
  92. if (copy_to_user(buf, ringdev_buf + *off, count))
  93. goto out_unlock;
  94. ret = count;
  95. *off += ret;
  96.  
  97. out_unlock:
  98. mutex_unlock(&ringdev_lock);
  99. return ret;
  100. */
  101. }
  102.  
  103. static ssize_t ringdev_write(struct file *filp, const char __user *buf,
  104. size_t count, loff_t *off)
  105. {
  106.  
  107.  
  108. ssize_t ret = 0;
  109. mutex_lock(&ringdev_lock);
  110. if(count>=BUFFOR-HEAD)
  111. {
  112. count =BUFFOR-HEAD;
  113. }
  114. ret=copy_from_user(ringdev_buf+HEAD, buf, count);
  115. HEAD+=count-ret;
  116. if(HEAD>=BUFFOR)
  117. {
  118. HEAD=0;
  119. }
  120. mutex_unlock(&ringdev_lock);
  121. wake_up_interruptible(&queue);
  122. return count -ret;
  123.  
  124. /*
  125. ret = -EFAULT;
  126.  
  127.  
  128. if(copy_from_user(ringdev_buf, buf, count ))
  129. {
  130. goto out_unlock;
  131. }
  132. ret = count;
  133. ringdev_len = count;
  134.  
  135. out_unlock:
  136. mutex_unlock(&ringdev_lock);
  137. return ret;
  138. // return -EINVAL;
  139. */
  140. }
  141.  
  142. static int ringdev_release(struct inode *inode, struct file *filp)
  143. {
  144. return 0;
  145. }
  146.  
  147. static const struct file_operations ringdev_fops = {
  148. .owner = THIS_MODULE,
  149. .open = ringdev_open,
  150. .read = ringdev_read,
  151. .write = ringdev_write,
  152. .release = ringdev_release,
  153. };
  154.  
  155. static struct miscdevice ringdev_miscdevice = {
  156. .minor = MISC_DYNAMIC_MINOR,
  157. .name = "ringdev",
  158. .fops = &ringdev_fops
  159. };
  160.  
  161. static int __init ringdev_init(void)
  162. {
  163. int ret;
  164. init_waitqueue_head(&queue);
  165. mutex_init(&ringdev_lock);
  166. ringdev_len = snprintf(ringdev_buf, sizeof(ringdev_buf),
  167. "PAN TADEUSZ\n");
  168. ret = misc_register(&ringdev_miscdevice);
  169. if (ret < 0)
  170. {
  171. pr_err("can't register miscdevice.\n");
  172. return ret;
  173. }
  174.  
  175. pr_info("minor %d\n", ringdev_miscdevice.minor);
  176.  
  177. return 0;
  178.  
  179. }
  180.  
  181. static void __exit ringdev_exit(void)
  182. {
  183. misc_deregister(&ringdev_miscdevice);
  184. mutex_destroy(&ringdev_lock);
  185. }
  186.  
  187. module_init(ringdev_init);
  188. module_exit(ringdev_exit);
  189.  
  190. MODULE_DESCRIPTION("Ring buffer device");
  191. MODULE_AUTHOR("Jakub Glowacki Karolina Szotek Jakub Berwid");
  192. MODULE_LICENSE("GPL");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement