linux 中字符设备结构体,linux驱动开发( 五) 字符设备驱动框架的填充file_operations结构体中的操作函数(read write llseek unlocked_ioctl)...

/** a simple char device driver: globalmem without mutex

*

* Copyright (C) 2014 Barry Song (baohua@kernel.org)

*

* Licensed under GPLv2 or later.*/#include#include#include#include#include#include

#define GLOBALMEM_SIZE 0x1000

#define MEM_CLEAR 0x1

#define GLOBALMEM_MAJOR 230

static int globalmem_major =GLOBALMEM_MAJOR;

module_param(globalmem_major,int, S_IRUGO);structglobalmem_dev {structcdev cdev;

unsignedcharmem[GLOBALMEM_SIZE];

};struct globalmem_dev *globalmem_devp;static int globalmem_open(struct inode *inode, struct file *filp)

{

filp->private_data =globalmem_devp;return 0;

}static int globalmem_release(struct inode *inode, struct file *filp)

{return 0;

}static long globalmem_ioctl(struct file *filp, unsigned intcmd,

unsignedlongarg)

{struct globalmem_dev *dev = filp->private_data;switch(cmd) {caseMEM_CLEAR:

memset(dev->mem, 0, GLOBALMEM_SIZE);

printk(KERN_INFO"globalmem is set to zero");break;default:return -EINVAL;

}return 0;

}static ssize_t globalmem_read(struct file *filp, char __user *buf, size_t size,

loff_t*ppos)

{

unsignedlong p = *ppos;

unsignedint count =size;int ret = 0;struct globalmem_dev *dev = filp->private_data;if (p >=GLOBALMEM_SIZE)return 0;if (count > GLOBALMEM_SIZE -p)

count= GLOBALMEM_SIZE -p;if (copy_to_user(buf, dev->mem +p, count)) {

ret= -EFAULT;

}else{*ppos +=count;

ret=count;

printk(KERN_INFO"read %u bytes(s) from %lu", count, p);

}returnret;

}static ssize_t globalmem_write(struct file *filp, const char __user *buf,

size_t size, loff_t*ppos)

{

unsignedlong p = *ppos;

unsignedint count =size;int ret = 0;struct globalmem_dev *dev = filp->private_data;if (p >=GLOBALMEM_SIZE)return 0;if (count > GLOBALMEM_SIZE -p)

count= GLOBALMEM_SIZE -p;if (copy_from_user(dev->mem +p, buf, count))

ret= -EFAULT;else{*ppos +=count;

ret=count;

printk(KERN_INFO"written %u bytes(s) from %lu", count, p);

}returnret;

}static loff_t globalmem_llseek(struct file *filp, loff_t offset, intorig)

{

loff_t ret= 0;switch(orig) {case 0:if (offset < 0) {

ret= -EINVAL;break;

}if ((unsigned int)offset >GLOBALMEM_SIZE) {

ret= -EINVAL;break;

}

filp->f_pos = (unsigned int)offset;

ret= filp->f_pos;break;case 1:if ((filp->f_pos + offset) >GLOBALMEM_SIZE) {

ret= -EINVAL;break;

}if ((filp->f_pos + offset) < 0) {

ret= -EINVAL;break;

}

filp->f_pos +=offset;

ret= filp->f_pos;break;default:

ret= -EINVAL;break;

}returnret;

}static const struct file_operations globalmem_fops ={

.owner=THIS_MODULE,

.llseek=globalmem_llseek,

.read=globalmem_read,

.write=globalmem_write,

.unlocked_ioctl=globalmem_ioctl,

.open=globalmem_open,

.release=globalmem_release,

};static void globalmem_setup_cdev(struct globalmem_dev *dev, intindex)

{int err, devno =MKDEV(globalmem_major, index);

cdev_init(&dev->cdev, &globalmem_fops);

dev->cdev.owner =THIS_MODULE;

err= cdev_add(&dev->cdev, devno, 1);if(err)

printk(KERN_NOTICE"Error %d adding globalmem%d", err, index);

}static int __init globalmem_init(void)

{intret;

dev_t devno= MKDEV(globalmem_major, 0);if(globalmem_major)

ret= register_chrdev_region(devno, 1, "globalmem");else{

ret= alloc_chrdev_region(&devno, 0, 1, "globalmem");

globalmem_major=MAJOR(devno);

}if (ret < 0)returnret;

globalmem_devp= kzalloc(sizeof(structglobalmem_dev), GFP_KERNEL);if (!globalmem_devp) {

ret= -ENOMEM;gotofail_malloc;

}

globalmem_setup_cdev(globalmem_devp,0);return 0;

fail_malloc:

unregister_chrdev_region(devno,1);returnret;

}

module_init(globalmem_init);static void __exit globalmem_exit(void)

{

cdev_del(&globalmem_devp->cdev);

kfree(globalmem_devp);

unregister_chrdev_region(MKDEV(globalmem_major,0), 1);

}

module_exit(globalmem_exit);

MODULE_AUTHOR("Barry Song ");

MODULE_LICENSE("GPL v2");

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值