#include#include #include #include #include #include #define DEV_MINOR 0 #define DEV_CNT 1 #define DEV_DATA_SIZE 127 #define DEV_ONE _IO('j', 0) #define DEV_TWO _IO('j', 1) char data[DEV_DATA_SIZE + 1] = {0}; ssize_t myread (struct file * fp, char __user * buf, size_t size, loff_t * offset) { int ret; printk("enter myreadn"); if(size > DEV_DATA_SIZE) { size = DEV_DATA_SIZE; } ret = copy_to_user(buf, data, size); if(ret) { printk("copy to user error.n"); return -EFAULT; } return 0; } int myrelease (struct inode * pnode, struct file * fp) { printk("enter myreleasen"); return 0; } int myopen (struct inode * pnode, struct file * fp) { printk("enter myopenn"); return 0; } ssize_t mywrite (struct file * fp, const char __user *buf, size_t size, loff_t *offset) { int ret; printk("enter writen"); if(size > 127) { printk("size is invalid.n"); return -ENOMEM; } ret = copy_from_user(data, buf, size); if(ret) { printk("copy from user error.n"); return -EFAULT; } return 0; } long myioctl (struct file * fp, unsigned int cmd, unsigned long data) { switch(cmd) { case DEV_ONE: printk("DEV ONEn"); break; case DEV_TWO: printk("DEV WTOn"); break; default: printk("invalid input.n"); break; } return 0; } dev_t dev; const struct file_operations myfops ={ .owner = THIS_MODULE, .open = myopen, .read = myread, .write = mywrite, .release = myrelease, .unlocked_ioctl = myioctl }; struct cdev mycdev; struct class *chrdev_class; struct device *mydevice; int chrdev_init(void) { int ret; ret = alloc_chrdev_region(&dev, DEV_MINOR, DEV_CNT, "chrdev"); if(ret < 0) { printk("alloc_chrdev_region failed!n"); goto alloc_chrdev_fail; } cdev_init(&mycdev, &myfops); ret = cdev_add(&mycdev, dev, DEV_CNT); if(ret < 0) { printk("cdev_add failed!n"); goto alloc_chrdev_region_fail; } chrdev_class = class_create(THIS_MODULE, "chrdevs"); if(IS_ERR_OR_NULL(chrdev_class)) { printk("class_create failed.n"); goto class_create_fail; } mydevice = device_create(chrdev_class, NULL, dev, NULL, "mydevice" ); if(IS_ERR_OR_NULL(mydevice)) { printk("device_create failed.n"); goto device_create_fail; } printk("chrdev init completed.n"); return 0; device_create_fail: class_destroy(chrdev_class); class_create_fail: cdev_del(&mycdev); alloc_chrdev_region_fail: unregister_chrdev_region(dev, DEV_CNT); alloc_chrdev_fail: return -ENODEV; } void chrdev_exit(void) { device_destroy(chrdev_class, dev); class_destroy(chrdev_class); cdev_del(&mycdev); unregister_chrdev_region(dev, DEV_CNT); printk("device unregister completed.n"); } module_init(chrdev_init); module_exit(chrdev_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("David-Woo"); MODULE_DEscriptION("char device driver example");



