文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>一个测试用的驱动--循环池!

一个测试用的驱动--循环池!

时间:2006-10-15  来源:jiok

test.h
#define MAJOR 126
#define NR    4
#define SIZE 1024
struct test_dev{
char *data;
unsigned int size;
struct semaphore sem;
struct cdev cdev;
};
test.c
#include<linux/init.h>
#include<linux/module.h>
#include<linux/fs.h>
#include<linux/types.h>
#include<linux/slab.h>
#include<linux/errno.h>
#include<linux/cdev.h>
#include<asm/uaccess.h>
#include"test.h"
///////////////////////////////////////////
int test_major=MAJOR;
int test_minor=0;
int test_nr=NR;
int test_size=SIZE;
module_param(test_major,int,S_IRUGO);
MODULE_AUTHOR("jiok");
MODULE_DESCRIPTION("This is a test driver");
MODULE_LICENSE("GPL");
/////////////////////////////////////////
struct test_dev *test_device;
/////////////////////////////////////////
void test_clear(struct test_dev *dev)
{
 kfree(dev->data);
 dev->size=0;
 dev->data=NULL;
}
static int test_open(struct inode *inode,struct file *filp)
{
 struct test_dev *dev;
 dev=container_of(inode->i_cdev,struct test_dev,cdev);
 filp->private_data=dev;
 if((filp->f_flags & O_ACCMODE)==O_WRONLY){
 test_clear(dev);
 }
 return 0;
}
static int test_release(struct inode *inode,struct file *filp)
{
 return 0;
}
static ssize_t test_read(struct file *filp,char __user *buf,size_t count,loff_t *f_pos)
{
 struct test_dev *dev=filp->private_data;
 int reval=0,pos=0;
 if(down_interruptible(&dev->sem))
 return -ERESTARTSYS;
 pos=(long)*f_pos%test_size;
 if(count>dev->size)
 count=dev->size;
 if(copy_to_user(buf,dev->data+pos,count)){
 reval=-EFAULT;
 goto fail;
 }
 *f_pos+=count;
 reval=count;
 fail:
 up(&dev->sem);
 return count;
}
static ssize_t test_write(struct file *filp,char __user *buf,size_t count,loff_t *f_pos)
{
 struct test_dev *dev=filp->private_data;
 char *test_data=NULL;
 int pos=0;
 int reval=0;
 if(down_interruptible(&dev->sem))
 return -ERESTARTSYS;
 pos=(long)*f_pos%test_size;
 if(dev->data==NULL){
 test_data=kmalloc(dev->size*sizeof(char),GFP_KERNEL);
 dev->data=test_data;
 }
 if(!test_data){
 reval=-ENOMEM;
 goto fail;
 }
 if(pos+count>test_size)
 count=test_size-pos;
 if(copy_from_user(dev->data+pos,buf,count)){
 reval=-EFAULT;
 goto fail;
 }
 dev->size+=count;
 *f_pos+=count;
 reval=count;
 fail:
 up(&dev->sem);
 return reval;
}
/////////////////////////////////////////
struct file_operations test_fops = {
 .owner =    THIS_MODULE,
 .read =     test_read,
 .write =    test_write,
 .open =     test_open,
 .release =  test_release,
};
//////////////////////////////////////////
static int test_init(void)
{
 unsigned int result;
 dev_t devno;
 int i;
 if(test_major){
 devno=MKDEV(test_major,test_minor);
 result=register_chrdev_region(devno,test_nr,"test");
 }else{
  result=alloc_chrdev_region(&devno,test_minor,test_nr,"test");
//  test_major=MAJOR(devno); 
  }
 if(result<0){
 printk("test can't get major");
 return 0;
 }
 test_device=kmalloc(test_nr*sizeof(struct test_dev),GFP_KERNEL);
 if(!test_device) {
 result=-ENOMEM;
 goto fail;
 }
 memset(test_device,0,test_nr*sizeof(struct test_dev));
 for(i=0;i<test_nr;i++){
 devno=MKDEV(test_major,test_minor+i);
 (test_device+i)->size=test_size;
 init_MUTEX(&test_device[i].sem);
 cdev_init(&test_device[i].cdev,&test_fops);
 test_device[i].cdev.owner=THIS_MODULE;
 test_device[i].cdev.ops=&test_fops;
 if(cdev_add(&test_device[i].cdev,devno,1))
  printk("error adding testdevice%d",i);
 }
 return 0;
   fail:
 return result;
}
static void test_cleanup(void)
{
 dev_t devno=MKDEV(test_major,test_minor);
 int i;
 for(i=0;i<test_nr;i++){
 cdev_del(&test_device[i].cdev);
 }
 kfree(test_device);
 unregister_chrdev_region(devno,test_nr);
}
module_init(test_init);
module_exit(test_cleanup);
相关阅读 更多 +
排行榜 更多 +
鱼群进化跑

鱼群进化跑

休闲益智 下载
收纳物语暑假作业

收纳物语暑假作业

休闲益智 下载
航海战纪

航海战纪

动作格斗 下载