#include<linux/init.h>
#include<linux/module.h>
#include<linux/types.h>
#include<linux/kdev_t.h>
#include<linux/fs.h>
#include<linux/slab.h>
#include<linux/cdev.h>
#include<asm/uaccess.h>
#include<linux/ioctl.h>
#define SCULL_IOCSQUANTUM
_IOW(SCULL_IOC_MAGIC, 1, int)
#define
SCULL_IOC_MAGIC 'k'
#define SCULL_IOCRESET _IO
(SCULL_IOC_MAGIC, 0)
#define SCULL_IOC_MAXNR 14
#define SCULL_IOCGQUANTUM _IOR(SCULL_IOC_MAGIC, 5,
int)
MODULE_LICENSE("Dual BSD/GPL");
int open1(struct
inode *inode, struct file *filp);
int close1(struct inode
*inode, struct file *filp);
int ioctl1(struct inode *inode,struct
file *filp,unsigned int cmd, unsigned long arg);
ssize_t
write1(struct file *filp,char __user *buf,size_t count,loff_t
*f_pos);
ssize_t read1(struct file *filp,char __user
*buf,size_t count,loff_t *f_pos);
int major=0;
int minor=0;
int
maxi=24;
struct file_operations scull_fops =
{
.owner =
THIS_MODULE,
.open = open1,
.read = read1,
.write = write1,
.ioctl = ioctl1,
.release=close1,
};
struct
scull_dev
{
void *data;
long int maxium;
unsigned int
long size;
struct cdev cdev;
};
struct scull_dev dev;
static void scull_setup_cdev(struct scull_dev *dev)
{
int
err, devno = MKDEV(major, minor);
cdev_init(&dev-
>cdev, &scull_fops);
dev->cdev.owner = THIS_MODULE;
dev->cdev.ops = &scull_fops;
err = cdev_add
(&dev->cdev, devno, 1);
if (err)
printk(KERN_NOTICE
"Error %d adding scull", err);
}
static int hello(void)
{
int result,devno;
if(major)
{
devno=MKDEV(major,minor);
result=register_chrdev_region(major,1,"ravi");
}
else
{
result=alloc_chrdev_region
(&devno,minor,1,"ravi");
major=MAJOR(devno);
}
if(result<0)
return -1;
dev.maxium=24;
scull_setup_cdev(&dev);
return 0;
}
int open1(struct
inode *inode, struct file *filp)
{
struct scull_dev
*ptr;
ptr=container_of(inode->i_cdev,struct scull_dev,
cdev);
filp->private_data=ptr;
return 0;
}
int close1
(struct inode *inode, struct file *filp)
{
return 0;
}
int
ioctl1(struct inode *inode,struct file *filp,unsigned int cmd,
unsigned long arg)
{
int err = 0;
int retval =
0;
struct scull_dev *ptr;
ptr=filp-
>private_data;
if (_IOC_TYPE(cmd) !=
SCULL_IOC_MAGIC)
return -1;
if
(_IOC_NR(cmd) > SCULL_IOC_MAXNR)
return -1;
if (_IOC_DIR(cmd) & _IOC_READ)
err = !access_ok(VERIFY_WRITE, (void __user *)arg,
_IOC_SIZE(cmd));
else if (_IOC_DIR(cmd) &
_IOC_WRITE)
err = !access_ok(VERIFY_READ,
(void __user *)arg, _IOC_SIZE(cmd));
if (err)
return -1;
switch(cmd)
{
case
SCULL_IOCSQUANTUM:
retval =
__get_user(ptr->maxium, (int __user *)arg);
break;
case SCULL_IOCGQUANTUM:
retval = __put_user(ptr->maxium, (int __user
*)arg);
break;
}
return retval;
}
ssize_t read1(struct file *filp,char __user
*buf,size_t count,loff_t *f_pos)
{
int retval=-1;
struct scull_dev *ptr;
ptr=filp->private_data;
if(*f_pos>=ptr->size)
goto out;
if((*f_pos+count)
>ptr->size)
count=(ptr->size)-(*f_pos);
if
(copy_to_user(buf,ptr->data,count))
{
retval=-1;
goto out;
}
*f_pos+=count;
retval=count;
out:
return retval;
}
ssize_t write1(struct file
*filp,char __user *buf,size_t count,loff_t *f_pos)
{
int retval=-1;
struct scull_dev *ptr;
ptr=filp->private_data;
ptr->data=kmalloc(ptr-
>maxium,GFP_KERNEL);
ptr->size=0;
memset
(ptr->data,0,ptr->maxium);
if(*f_pos>=ptr->maxium)
goto out;
if((*f_pos+count)>ptr->maxium)
count=
(ptr->maxium)-(*f_pos);
if(copy_from_user(ptr-
>data,buf,count))
{
retval=-1;
goto out;
}
*f_pos+=count;
retval=count;
if(ptr->size<*f_pos)
ptr->size=*f_pos;
out:
return retval;
}
static
void exit1(void)
{
//int result;
//kfree(ptr);
cdev_del(&dev.cdev);
unregister_chrdev
(major,"ravi");
}
module_init(hello);
module_exit(exit1);
#include<linux/module.h>
#include<linux/types.h>
#include<linux/kdev_t.h>
#include<linux/fs.h>
#include<linux/slab.h>
#include<linux/cdev.h>
#include<asm/uaccess.h>
#include<linux/ioctl.h>
#define SCULL_IOCSQUANTUM
_IOW(SCULL_IOC_MAGIC, 1, int)
#define
SCULL_IOC_MAGIC 'k'
#define SCULL_IOCRESET _IO
(SCULL_IOC_MAGIC, 0)
#define SCULL_IOC_MAXNR 14
#define SCULL_IOCGQUANTUM _IOR(SCULL_IOC_MAGIC, 5,
int)
MODULE_LICENSE("Dual BSD/GPL");
int open1(struct
inode *inode, struct file *filp);
int close1(struct inode
*inode, struct file *filp);
int ioctl1(struct inode *inode,struct
file *filp,unsigned int cmd, unsigned long arg);
ssize_t
write1(struct file *filp,char __user *buf,size_t count,loff_t
*f_pos);
ssize_t read1(struct file *filp,char __user
*buf,size_t count,loff_t *f_pos);
int major=0;
int minor=0;
int
maxi=24;
struct file_operations scull_fops =
{
.owner =
THIS_MODULE,
.open = open1,
.read = read1,
.write = write1,
.ioctl = ioctl1,
.release=close1,
};
struct
scull_dev
{
void *data;
long int maxium;
unsigned int
long size;
struct cdev cdev;
};
struct scull_dev dev;
static void scull_setup_cdev(struct scull_dev *dev)
{
int
err, devno = MKDEV(major, minor);
cdev_init(&dev-
>cdev, &scull_fops);
dev->cdev.owner = THIS_MODULE;
dev->cdev.ops = &scull_fops;
err = cdev_add
(&dev->cdev, devno, 1);
if (err)
printk(KERN_NOTICE
"Error %d adding scull", err);
}
static int hello(void)
{
int result,devno;
if(major)
{
devno=MKDEV(major,minor);
result=register_chrdev_region(major,1,"ravi");
}
else
{
result=alloc_chrdev_region
(&devno,minor,1,"ravi");
major=MAJOR(devno);
}
if(result<0)
return -1;
dev.maxium=24;
scull_setup_cdev(&dev);
return 0;
}
int open1(struct
inode *inode, struct file *filp)
{
struct scull_dev
*ptr;
ptr=container_of(inode->i_cdev,struct scull_dev,
cdev);
filp->private_data=ptr;
return 0;
}
int close1
(struct inode *inode, struct file *filp)
{
return 0;
}
int
ioctl1(struct inode *inode,struct file *filp,unsigned int cmd,
unsigned long arg)
{
int err = 0;
int retval =
0;
struct scull_dev *ptr;
ptr=filp-
>private_data;
if (_IOC_TYPE(cmd) !=
SCULL_IOC_MAGIC)
return -1;
if
(_IOC_NR(cmd) > SCULL_IOC_MAXNR)
return -1;
if (_IOC_DIR(cmd) & _IOC_READ)
err = !access_ok(VERIFY_WRITE, (void __user *)arg,
_IOC_SIZE(cmd));
else if (_IOC_DIR(cmd) &
_IOC_WRITE)
err = !access_ok(VERIFY_READ,
(void __user *)arg, _IOC_SIZE(cmd));
if (err)
return -1;
switch(cmd)
{
case
SCULL_IOCSQUANTUM:
retval =
__get_user(ptr->maxium, (int __user *)arg);
break;
case SCULL_IOCGQUANTUM:
retval = __put_user(ptr->maxium, (int __user
*)arg);
break;
}
return retval;
}
ssize_t read1(struct file *filp,char __user
*buf,size_t count,loff_t *f_pos)
{
int retval=-1;
struct scull_dev *ptr;
ptr=filp->private_data;
if(*f_pos>=ptr->size)
goto out;
if((*f_pos+count)
>ptr->size)
count=(ptr->size)-(*f_pos);
if
(copy_to_user(buf,ptr->data,count))
{
retval=-1;
goto out;
}
*f_pos+=count;
retval=count;
out:
return retval;
}
ssize_t write1(struct file
*filp,char __user *buf,size_t count,loff_t *f_pos)
{
int retval=-1;
struct scull_dev *ptr;
ptr=filp->private_data;
ptr->data=kmalloc(ptr-
>maxium,GFP_KERNEL);
ptr->size=0;
memset
(ptr->data,0,ptr->maxium);
if(*f_pos>=ptr->maxium)
goto out;
if((*f_pos+count)>ptr->maxium)
count=
(ptr->maxium)-(*f_pos);
if(copy_from_user(ptr-
>data,buf,count))
{
retval=-1;
goto out;
}
*f_pos+=count;
retval=count;
if(ptr->size<*f_pos)
ptr->size=*f_pos;
out:
return retval;
}
static
void exit1(void)
{
//int result;
//kfree(ptr);
cdev_del(&dev.cdev);
unregister_chrdev
(major,"ravi");
}
module_init(hello);
module_exit(exit1);
0 nhận xét:
Đăng nhận xét