Advertisement
Guest User

Untitled

a guest
Oct 30th, 2014
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.56 KB | None | 0 0
  1. #include <linux/kernel.h>
  2. #include <linux/module.h>
  3. #include <linux/uaccess.h>
  4. #include <linux/types.h>
  5. #include<linux/kdev_t.h>
  6. #include<linux/cdev.h>
  7. #include<linux/mutex.h>
  8. #include<linux/fs.h>
  9. #include<linux/slab.h>
  10. #include<linux/cdev.h>
  11.  
  12. #include<linux/sched.h>
  13.  
  14. //Marcin Olejnik, Przemyslaw Sylwestrzak
  15.  
  16. static int __init chardev_init(void);
  17. static void __exit chardev_exit(void);
  18.  
  19. static int device_open(struct inode *,struct file *);
  20. static int device_release(struct inode *,struct file * );
  21. static ssize_t device_read(struct file *,char *, size_t, loff_t *);
  22. static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
  23.  
  24. //fops2
  25. static int device_open2(struct inode *,struct file *);
  26. static int device_release2(struct inode *,struct file * );
  27. static ssize_t device_read2(struct file *,char *, size_t, loff_t *);
  28. static ssize_t device_write2(struct file *, const char *, size_t, loff_t *);
  29.  
  30.  
  31. static int licznik_lanc=0;
  32.  
  33. static int BufferSize=100;//
  34.  
  35. module_param(BufferSize, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);//
  36. MODULE_PARM_DESC(BufferSize,"rozmiar bufora typu int");//
  37.  
  38. static char *NewBuffer; //
  39.  
  40. static int pozostalo=0;
  41.  
  42. #define SUCCESS 0
  43. #define DEVICE_NAME "chardev"
  44. #define BUF_LEN 100
  45. #define LIST_LEN 100
  46.  
  47.  
  48.  
  49.  
  50.  
  51. static int Major = 122;
  52. DEFINE_MUTEX (Device_Open);
  53. DEFINE_MUTEX (MutexLista);
  54.  
  55. static char *msg_Ptr;
  56. //static int licznik=0;
  57.  
  58. static struct cdev *chcdev;
  59.  
  60. static struct file_operations fops = {
  61. .read = device_read,
  62. .write = device_write,
  63. .open = device_open,
  64. .release = device_release
  65. };
  66. static struct file_operations fops2 = {
  67. .read = device_read2,
  68. .write = device_write2,
  69. .open = device_open2,
  70. .release = device_release2
  71. };
  72.  
  73.  
  74. struct element{
  75. char dane[LIST_LEN];
  76. struct element *next;
  77. };
  78.  
  79. struct element *glowa=NULL;
  80. struct element *kursor=NULL;
  81. static void wyczysc(struct element* lista)
  82. {
  83. struct element* wsk = lista->next;
  84. while(lista)
  85. {
  86. kfree(lista);
  87. lista = wsk->next;
  88. }
  89. }
  90.  
  91. static int __init chardev_init(void){
  92. int ret;
  93. dev_t num;
  94. NewBuffer = kmalloc(BufferSize, GFP_KERNEL);//
  95. num = MKDEV(Major,0);
  96. ret = register_chrdev_region(num,3,DEVICE_NAME);
  97.  
  98.  
  99.  
  100. if(ret<0){
  101. printk(KERN_ALERT "Nieudana proba przydzialu obszaru urzadzenia w jadrze-zwrocony numer %d\n",ret);
  102. return ret;
  103. }
  104. chcdev =cdev_alloc();
  105. chcdev->owner = THIS_MODULE;
  106. chcdev->ops = &fops;
  107.  
  108. ret = cdev_add(chcdev, num, 3);
  109.  
  110. if(ret<0){
  111. printk(KERN_ALERT "Nieudana proba zarejestrowania urzadzenia w jadrze-zwrocony numer %d\n",ret);
  112. return ret;
  113. }
  114. printk(KERN_INFO "Przydzielono mi numer urzadzenia %d. Otworz plik\n", Major);
  115. printk(KERN_INFO "urzadzenia za pomoca 'mknod /dev %s c %d 0' , a potem \n",DEVICE_NAME, Major);
  116. printk(KERN_INFO "z inna ostatnia cyfra. Probuj czytac i pisac do tego\n");
  117. printk(KERN_INFO "urzadzenia. Po usunieciu urzadzenia usun i plik\n");
  118.  
  119. glowa=kmalloc(sizeof(struct element),GFP_KERNEL);
  120. glowa->next=NULL;
  121. kursor = glowa;
  122.  
  123. return SUCCESS;
  124. }
  125. static void __exit chardev_exit(void){
  126.  
  127. dev_t num;
  128. num=MKDEV(Major,0);
  129. cdev_del(chcdev);
  130. unregister_chrdev_region(num,3);
  131. NewBuffer=0;
  132. printk(KERN_INFO "Zegnaj, swiecie!\n");
  133. kfree(NewBuffer);
  134. if(glowa)
  135. wyczysc(glowa);
  136. }
  137.  
  138. int otwarto=0;
  139.  
  140.  
  141. static int device_open(struct inode *inoda, struct file *plik){
  142.  
  143. //Podmiana pliku urzadzenia
  144. int poboczny=iminor(inoda);
  145. if(poboczny == 1)
  146. {
  147. plik->f_op=&fops2;
  148. return plik->f_op->open(inoda,plik);
  149. }
  150.  
  151.  
  152.  
  153. printk(KERN_INFO "Otwarcie pliku urzadzenia o numerze pobocznym %d\n",iminor(inoda));
  154. if(mutex_lock_interruptible(&Device_Open)){
  155. printk(KERN_INFO "Proba przejecia semafora przerwana!\n");
  156. return -ERESTARTSYS;
  157. }
  158. try_module_get(THIS_MODULE);
  159. //sprintf("%s\n",msg);
  160. //sprintf("%s\n",msg);
  161. //sprintf(NewBuffer,"Hello, world! mowie po raz ");
  162. //sprintf(msg,"Hello, world! mowie po raz ");
  163. msg_Ptr=NewBuffer;
  164. // msg_Ptr=msg;
  165. //licznik_lanc=strlen(msg);
  166.  
  167. licznik_lanc=strlen(NewBuffer);
  168. mutex_unlock(&Device_Open);
  169. return SUCCESS;
  170. }
  171.  
  172.  
  173.  
  174. static int device_release(struct inode *inoda, struct file *plik){
  175. mutex_unlock(&Device_Open);
  176. module_put(THIS_MODULE);
  177. return 0;
  178. }
  179.  
  180.  
  181.  
  182. DECLARE_WAIT_QUEUE_HEAD(kolejkaPisania);
  183. DECLARE_WAIT_QUEUE_HEAD(kolejkaCzytania);
  184.  
  185. static ssize_t device_read(struct file *plik, char *buforUz, size_t dlugosc, loff_t *offset)
  186. {
  187. while(pozostalo<=0)
  188. {
  189. mutex_unlock(&Device_Open);
  190. wait_event_interruptible(kolejkaPisania,pozostalo>0);
  191. mutex_lock(&Device_Open);
  192. }
  193. int odczytano = 0;
  194.  
  195. while(dlugosc && licznik_lanc){
  196. put_user(*(msg_Ptr++), buforUz++);
  197. dlugosc--;
  198. odczytano++;
  199. licznik_lanc--; //
  200. }
  201. pozostalo--;
  202.  
  203. mutex_unlock(&Device_Open);
  204. wake_up_interruptible(&kolejkaPisania); //
  205. *offset += odczytano;
  206. return odczytano;
  207. }
  208.  
  209. static ssize_t device_write(struct file *plik,const char *bufor, size_t dlugosc, loff_t *offset){
  210. while(pozostalo+dlugosc>=1000)
  211. {
  212. mutex_unlock(&Device_Open);
  213. wait_event_interruptible(kolejkaCzytania,pozostalo+dlugosc<1000);
  214. mutex_lock_interruptible(&Device_Open);
  215.  
  216. }
  217. int zapisano = 0;
  218. copy_from_user(NewBuffer,bufor,BufferSize);
  219. zapisano = strlen(NewBuffer);
  220. mutex_unlock(&Device_Open);
  221. wake_up_interruptible(&kolejkaCzytania);
  222.  
  223. pozostalo+=zapisano;
  224. return zapisano;
  225. }
  226.  
  227. //////////////////////////////////////////////////////////////
  228.  
  229.  
  230. static int device_open2(struct inode *inoda, struct file *plik){
  231. if(mutex_lock_interruptible(&MutexLista)){
  232. return -ERESTARTSYS;
  233. }
  234. try_module_get(THIS_MODULE);
  235.  
  236.  
  237. //dodawanie nowych elementow
  238. //struct element *wsk=kmalloc(sizeof(struct element),GFP_KERNEL);
  239. //if(!wsk) return;
  240. //wsk->dane =
  241. //wsk->next=glowa;
  242. //glowa=wsk;
  243.  
  244. //przetwarzanie listy
  245. //struct element *kursor;
  246. //kursor=glowa;
  247. //while(kursor->dane !=0)
  248. //{
  249. //kursor = kursor->nast;
  250. //}
  251.  
  252. if((plik->f_flags && O_ACCMODE) == O_RDONLY)
  253. {
  254. kursor = glowa;
  255. }
  256. if((plik->f_flags && O_ACCMODE) == O_WRONLY)
  257. {
  258. wyczysc(glowa->next);
  259. memset(glowa, 0, sizeof(*glowa));
  260. kursor = glowa;
  261. }
  262. return SUCCESS;
  263. }
  264.  
  265.  
  266.  
  267. static int device_release2(struct inode *inoda, struct file *plik){
  268. mutex_unlock(&MutexLista);
  269. module_put(THIS_MODULE);
  270. return 0;
  271. }
  272.  
  273. static ssize_t device_read2(struct file *plik, char *buforUz, size_t dlugosc, loff_t *offset)
  274. {
  275. int odczytano = 0;
  276. if(dlugosc>=BUF_LEN)
  277. return -EFAULT;
  278. if(kursor)
  279. {
  280. odczytano = BUF_LEN - copy_to_user(buforUz,kursor->dane,BUF_LEN);
  281. kursor=kursor->next;
  282. }
  283. *offset += odczytano;
  284. return odczytano;
  285. }
  286.  
  287. static ssize_t device_write2(struct file *plik,const char *bufor, size_t dlugosc, loff_t *offset){
  288. // int zapisano = 0;
  289. int odczytano = 0;
  290. if(kursor)
  291. {
  292. if(dlugosc>BUF_LEN)
  293. {
  294. odczytano = BUF_LEN;
  295. }
  296. else
  297. {
  298. odczytano = dlugosc;
  299. }
  300. odczytano = odczytano - copy_from_user(kursor->dane, bufor,odczytano);
  301. kursor->next = kmalloc(sizeof(*kursor), GFP_KERNEL);
  302. if(kursor->next)
  303. {
  304. return -ENOMEM;
  305. }
  306. kursor=kursor->next;
  307. memset(kursor, 0, sizeof(*kursor));
  308. }
  309. *offset += odczytano;
  310. return odczytano;
  311. }
  312.  
  313. module_init(chardev_init);
  314. module_exit(chardev_exit);
  315.  
  316. MODULE_LICENSE("GPL v2");
  317. MODULE_AUTHOR("Dariusz Bismor <Dariusz.Bismor[at]polsl.pl>");
  318. MODULE_DESCRIPTION("Przyklad modulu z plikiem urzadzenia");
  319. MODULE_SUPPORTED_DEVICE(DEVICE_NAME);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement