Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/uaccess.h>
- #include <linux/types.h>
- #include<linux/kdev_t.h>
- #include<linux/cdev.h>
- #include<linux/mutex.h>
- #include<linux/fs.h>
- #include<linux/slab.h>
- #include<linux/cdev.h>
- #include<linux/sched.h>
- //Marcin Olejnik, Przemyslaw Sylwestrzak
- static int __init chardev_init(void);
- static void __exit chardev_exit(void);
- static int device_open(struct inode *,struct file *);
- static int device_release(struct inode *,struct file * );
- static ssize_t device_read(struct file *,char *, size_t, loff_t *);
- static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
- //fops2
- static int device_open2(struct inode *,struct file *);
- static int device_release2(struct inode *,struct file * );
- static ssize_t device_read2(struct file *,char *, size_t, loff_t *);
- static ssize_t device_write2(struct file *, const char *, size_t, loff_t *);
- static int licznik_lanc=0;
- static int BufferSize=100;//
- module_param(BufferSize, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);//
- MODULE_PARM_DESC(BufferSize,"rozmiar bufora typu int");//
- static char *NewBuffer; //
- static int pozostalo=0;
- #define SUCCESS 0
- #define DEVICE_NAME "chardev"
- #define BUF_LEN 100
- #define LIST_LEN 100
- static int Major = 122;
- DEFINE_MUTEX (Device_Open);
- DEFINE_MUTEX (MutexLista);
- static char *msg_Ptr;
- //static int licznik=0;
- static struct cdev *chcdev;
- static struct file_operations fops = {
- .read = device_read,
- .write = device_write,
- .open = device_open,
- .release = device_release
- };
- static struct file_operations fops2 = {
- .read = device_read2,
- .write = device_write2,
- .open = device_open2,
- .release = device_release2
- };
- struct element{
- char dane[LIST_LEN];
- struct element *next;
- };
- struct element *glowa=NULL;
- struct element *kursor=NULL;
- static void wyczysc(struct element* lista)
- {
- struct element* wsk = lista->next;
- while(lista)
- {
- kfree(lista);
- lista = wsk->next;
- }
- }
- static int __init chardev_init(void){
- int ret;
- dev_t num;
- NewBuffer = kmalloc(BufferSize, GFP_KERNEL);//
- num = MKDEV(Major,0);
- ret = register_chrdev_region(num,3,DEVICE_NAME);
- if(ret<0){
- printk(KERN_ALERT "Nieudana proba przydzialu obszaru urzadzenia w jadrze-zwrocony numer %d\n",ret);
- return ret;
- }
- chcdev =cdev_alloc();
- chcdev->owner = THIS_MODULE;
- chcdev->ops = &fops;
- ret = cdev_add(chcdev, num, 3);
- if(ret<0){
- printk(KERN_ALERT "Nieudana proba zarejestrowania urzadzenia w jadrze-zwrocony numer %d\n",ret);
- return ret;
- }
- printk(KERN_INFO "Przydzielono mi numer urzadzenia %d. Otworz plik\n", Major);
- printk(KERN_INFO "urzadzenia za pomoca 'mknod /dev %s c %d 0' , a potem \n",DEVICE_NAME, Major);
- printk(KERN_INFO "z inna ostatnia cyfra. Probuj czytac i pisac do tego\n");
- printk(KERN_INFO "urzadzenia. Po usunieciu urzadzenia usun i plik\n");
- glowa=kmalloc(sizeof(struct element),GFP_KERNEL);
- glowa->next=NULL;
- kursor = glowa;
- return SUCCESS;
- }
- static void __exit chardev_exit(void){
- dev_t num;
- num=MKDEV(Major,0);
- cdev_del(chcdev);
- unregister_chrdev_region(num,3);
- NewBuffer=0;
- printk(KERN_INFO "Zegnaj, swiecie!\n");
- kfree(NewBuffer);
- if(glowa)
- wyczysc(glowa);
- }
- int otwarto=0;
- static int device_open(struct inode *inoda, struct file *plik){
- //Podmiana pliku urzadzenia
- int poboczny=iminor(inoda);
- if(poboczny == 1)
- {
- plik->f_op=&fops2;
- return plik->f_op->open(inoda,plik);
- }
- printk(KERN_INFO "Otwarcie pliku urzadzenia o numerze pobocznym %d\n",iminor(inoda));
- if(mutex_lock_interruptible(&Device_Open)){
- printk(KERN_INFO "Proba przejecia semafora przerwana!\n");
- return -ERESTARTSYS;
- }
- try_module_get(THIS_MODULE);
- //sprintf("%s\n",msg);
- //sprintf("%s\n",msg);
- //sprintf(NewBuffer,"Hello, world! mowie po raz ");
- //sprintf(msg,"Hello, world! mowie po raz ");
- msg_Ptr=NewBuffer;
- // msg_Ptr=msg;
- //licznik_lanc=strlen(msg);
- licznik_lanc=strlen(NewBuffer);
- mutex_unlock(&Device_Open);
- return SUCCESS;
- }
- static int device_release(struct inode *inoda, struct file *plik){
- mutex_unlock(&Device_Open);
- module_put(THIS_MODULE);
- return 0;
- }
- DECLARE_WAIT_QUEUE_HEAD(kolejkaPisania);
- DECLARE_WAIT_QUEUE_HEAD(kolejkaCzytania);
- static ssize_t device_read(struct file *plik, char *buforUz, size_t dlugosc, loff_t *offset)
- {
- while(pozostalo<=0)
- {
- mutex_unlock(&Device_Open);
- wait_event_interruptible(kolejkaPisania,pozostalo>0);
- mutex_lock(&Device_Open);
- }
- int odczytano = 0;
- while(dlugosc && licznik_lanc){
- put_user(*(msg_Ptr++), buforUz++);
- dlugosc--;
- odczytano++;
- licznik_lanc--; //
- }
- pozostalo--;
- mutex_unlock(&Device_Open);
- wake_up_interruptible(&kolejkaPisania); //
- *offset += odczytano;
- return odczytano;
- }
- static ssize_t device_write(struct file *plik,const char *bufor, size_t dlugosc, loff_t *offset){
- while(pozostalo+dlugosc>=1000)
- {
- mutex_unlock(&Device_Open);
- wait_event_interruptible(kolejkaCzytania,pozostalo+dlugosc<1000);
- mutex_lock_interruptible(&Device_Open);
- }
- int zapisano = 0;
- copy_from_user(NewBuffer,bufor,BufferSize);
- zapisano = strlen(NewBuffer);
- mutex_unlock(&Device_Open);
- wake_up_interruptible(&kolejkaCzytania);
- pozostalo+=zapisano;
- return zapisano;
- }
- //////////////////////////////////////////////////////////////
- static int device_open2(struct inode *inoda, struct file *plik){
- if(mutex_lock_interruptible(&MutexLista)){
- return -ERESTARTSYS;
- }
- try_module_get(THIS_MODULE);
- //dodawanie nowych elementow
- //struct element *wsk=kmalloc(sizeof(struct element),GFP_KERNEL);
- //if(!wsk) return;
- //wsk->dane =
- //wsk->next=glowa;
- //glowa=wsk;
- //przetwarzanie listy
- //struct element *kursor;
- //kursor=glowa;
- //while(kursor->dane !=0)
- //{
- //kursor = kursor->nast;
- //}
- if((plik->f_flags && O_ACCMODE) == O_RDONLY)
- {
- kursor = glowa;
- }
- if((plik->f_flags && O_ACCMODE) == O_WRONLY)
- {
- wyczysc(glowa->next);
- memset(glowa, 0, sizeof(*glowa));
- kursor = glowa;
- }
- return SUCCESS;
- }
- static int device_release2(struct inode *inoda, struct file *plik){
- mutex_unlock(&MutexLista);
- module_put(THIS_MODULE);
- return 0;
- }
- static ssize_t device_read2(struct file *plik, char *buforUz, size_t dlugosc, loff_t *offset)
- {
- int odczytano = 0;
- if(dlugosc>=BUF_LEN)
- return -EFAULT;
- if(kursor)
- {
- odczytano = BUF_LEN - copy_to_user(buforUz,kursor->dane,BUF_LEN);
- kursor=kursor->next;
- }
- *offset += odczytano;
- return odczytano;
- }
- static ssize_t device_write2(struct file *plik,const char *bufor, size_t dlugosc, loff_t *offset){
- // int zapisano = 0;
- int odczytano = 0;
- if(kursor)
- {
- if(dlugosc>BUF_LEN)
- {
- odczytano = BUF_LEN;
- }
- else
- {
- odczytano = dlugosc;
- }
- odczytano = odczytano - copy_from_user(kursor->dane, bufor,odczytano);
- kursor->next = kmalloc(sizeof(*kursor), GFP_KERNEL);
- if(kursor->next)
- {
- return -ENOMEM;
- }
- kursor=kursor->next;
- memset(kursor, 0, sizeof(*kursor));
- }
- *offset += odczytano;
- return odczytano;
- }
- module_init(chardev_init);
- module_exit(chardev_exit);
- MODULE_LICENSE("GPL v2");
- MODULE_AUTHOR("Dariusz Bismor <Dariusz.Bismor[at]polsl.pl>");
- MODULE_DESCRIPTION("Przyklad modulu z plikiem urzadzenia");
- MODULE_SUPPORTED_DEVICE(DEVICE_NAME);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement