diff options
author | Marcin Chrzanowski <marcin.j.chrzanowski@gmail.com> | 2018-05-27 14:46:02 +0200 |
---|---|---|
committer | Marcin Chrzanowski <marcin.j.chrzanowski@gmail.com> | 2018-05-27 14:46:02 +0200 |
commit | 9eb310afc4a96304b47d4897c58ca3bb733362a9 (patch) | |
tree | 1da74a221faa69ca78ab1676e94b6cda4da62fc5 /char.c | |
parent | e1d57f01b2112a6415313c83fc300f94475db382 (diff) |
Add missing draw columns features
Diffstat (limited to 'char.c')
-rw-r--r-- | char.c | 89 |
1 files changed, 88 insertions, 1 deletions
@@ -251,9 +251,96 @@ error_data: return err; } +void free_colors(struct colors_data *colors_data); +int colors_release(struct inode *inode, struct file *filp) +{ + struct colors_data *colors_data; + + colors_data = filp->private_data; + + free_colors(colors_data); + + kfree(colors_data); + + return 0; +} + +struct file_operations colors_fops = { + .owner = THIS_MODULE, + .release = colors_release + +}; + +int alloc_colors(struct doomdev_ioctl_create_colormaps *params, + struct colors_data *colors_data) +{ + int err; + int not_written; + + colors_data->number = params->num; + + colors_data->colors_cpu = + dma_alloc_coherent(colors_data->doom_data->pci_device, + HARDDOOM_COLORMAP_SIZE * params->num, + &colors_data->colors_dev, + GFP_KERNEL); + ORFAIL_NULL(colors_data->colors_cpu, -ENOMEM, error_colors); + + not_written = copy_from_user(colors_data->colors_cpu, + (void __user *) params->data_ptr, + HARDDOOM_COLORMAP_SIZE * params->num); + + if (not_written) { + err = -EFAULT; + goto error_copy; + } + + return 0; + +error_copy: + dma_free_coherent(colors_data->doom_data->pci_device, + HARDDOOM_COLORMAP_SIZE * params->num, + colors_data->colors_cpu, colors_data->colors_dev); +error_colors: + return err; + +} + +void free_colors(struct colors_data *colors_data) +{ + dma_free_coherent(colors_data->doom_data->pci_device, + HARDDOOM_COLORMAP_SIZE * colors_data->number, + colors_data->colors_cpu, colors_data->colors_dev); +} + long doom_create_colormaps(struct file *filp, unsigned long arg) { - return -1; + int err; + struct doomdev_ioctl_create_colormaps *params; + struct colors_data *colors_data; + int fd; + struct doom_data *doom_data; + + params = (struct doomdev_ioctl_create_colormaps *) arg; + + colors_data = kmalloc(sizeof(*colors_data), GFP_KERNEL); + ORFAIL_NULL(colors_data, -ENOMEM, error_data); + doom_data = container_of(filp->f_inode->i_cdev, struct doom_data, cdev); + colors_data->doom_data = doom_data; + + ORFAIL(alloc_colors(params, colors_data), error_colors); + + fd = anon_inode_getfd("doom_colors", &colors_fops, colors_data, 0); + ORFAIL(fd, error_inode); + + return fd; + +error_inode: + free_colors(colors_data); +error_colors: + kfree(colors_data); +error_data: + return err; } long doom_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |