diff options
author | Marcin Chrzanowski <marcin.j.chrzanowski@gmail.com> | 2018-05-16 11:19:13 +0200 |
---|---|---|
committer | Marcin Chrzanowski <marcin.j.chrzanowski@gmail.com> | 2018-05-16 11:19:13 +0200 |
commit | 1a8a5e5f7ec151c38eec7b4d0ca4835fc717e010 (patch) | |
tree | 010665d343ae62df4423112d3518258e33457f6a | |
parent | 8cbf32f110d47136d853ee88b74103445732a62e (diff) |
Create scaffold surface
-rw-r--r-- | surface.c | 76 |
1 files changed, 75 insertions, 1 deletions
@@ -1,8 +1,82 @@ +#include <linux/anon_inodes.h> +#include <linux/file.h> #include <linux/fs.h> #include "surface.h" -int new_surface(struct doomdev_ioctl_create_surface *params) +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; +} |