#include #include #include #include "surface.h" long surface_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { return -1; } ssize_t surface_read(struct file *filp, char __user *buf, size_t count, loff_t *offset) { return -1; } loff_t surface_llseek(struct file *filp, loff_t offset, int origin) { return -1; } struct file_operations surface_fops = { .owner = THIS_MODULE, .unlocked_ioctl = surface_ioctl, .compat_ioctl = surface_ioctl, .llseek = surface_llseek, .read = surface_read }; int verify_params(struct doomdev_ioctl_create_surface *params) { if (params->width < 64) { printk(KERN_DEBUG "Surface width too small\n"); return -EINVAL; } if (params->width > 2048) { printk(KERN_DEBUG "Surface width too large\n"); return -EOVERFLOW; } if (params->width % 64 != 0) { printk(KERN_DEBUG "Surface width not a multiple of 64\n"); return -EINVAL; } if (params->height < 1) { printk(KERN_DEBUG "Surface height too small\n"); return -EINVAL; } if (params->height > 2048) { printk(KERN_DEBUG "Surface height too large\n"); return -EOVERFLOW; } return 0; } int new_surface(struct doomdev_ioctl_create_surface *params) { int err; int fd; struct fd fd_s; err = verify_params(params); if (err < 0) { return err; } fd = anon_inode_getfd("doom_surface", &surface_fops, NULL, 0); fd_s = fdget(fd); if (fd_s.file->f_op != &surface_fops) { printk(KERN_DEBUG "fdget failed\n"); return -ENOENT; } fd_s.file->f_mode |= FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE; return fd; }