m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff
path: root/char.c
diff options
context:
space:
mode:
Diffstat (limited to 'char.c')
-rw-r--r--char.c84
1 files changed, 83 insertions, 1 deletions
diff --git a/char.c b/char.c
index 54fd8a3..c1c4f16 100644
--- a/char.c
+++ b/char.c
@@ -166,9 +166,91 @@ error_data:
return err;
}
+void free_flat(struct flat_data *flat_data);
+int flat_release(struct inode *inode, struct file *filp)
+{
+ struct flat_data *flat_data;
+
+ flat_data = filp->private_data;
+
+ free_flat(flat_data);
+
+ kfree(flat_data);
+
+ return 0;
+}
+
+struct file_operations flat_fops = {
+ .owner = THIS_MODULE,
+ .release = flat_release
+
+};
+
+int alloc_flat(struct doomdev_ioctl_create_flat *params,
+ struct flat_data *flat_data)
+{
+ int err;
+ int not_written;
+
+ flat_data->flat_cpu =
+ dma_alloc_coherent(flat_data->doom_data->pci_device,
+ HARDDOOM_FLAT_SIZE, &flat_data->flat_dev,
+ GFP_KERNEL);
+ ORFAIL_NULL(flat_data->flat_cpu, -ENOMEM, error_flat);
+
+ not_written = copy_from_user(flat_data->flat_cpu,
+ (void __user *) params->data_ptr, HARDDOOM_FLAT_SIZE);
+
+ if (not_written) {
+ p("some bytes not copied\n");
+ err = -EFAULT;
+ goto error_copy;
+ }
+
+ return 0;
+
+error_copy:
+ dma_free_coherent(flat_data->doom_data->pci_device, HARDDOOM_FLAT_SIZE,
+ flat_data->flat_cpu, flat_data->flat_dev);
+error_flat:
+ return err;
+
+}
+
+void free_flat(struct flat_data *flat_data)
+{
+ dma_free_coherent(flat_data->doom_data->pci_device, HARDDOOM_FLAT_SIZE,
+ flat_data->flat_cpu, flat_data->flat_dev);
+}
+
long doom_create_flat(struct file *filp, unsigned long arg)
{
- return -1;
+ int err;
+ struct doomdev_ioctl_create_flat *params;
+ struct flat_data *flat_data;
+ int fd;
+ struct doom_data *doom_data;
+
+ params = (struct doomdev_ioctl_create_flat *) arg;
+
+ flat_data = kmalloc(sizeof(*flat_data), GFP_KERNEL);
+ ORFAIL_NULL(flat_data, -ENOMEM, error_data);
+ doom_data = container_of(filp->f_inode->i_cdev, struct doom_data, cdev);
+ flat_data->doom_data = doom_data;
+
+ ORFAIL(alloc_flat(params, flat_data), error_flat);
+
+ fd = anon_inode_getfd("doom_texture", &flat_fops, flat_data, 0);
+ ORFAIL(fd, error_inode);
+
+ return fd;
+
+error_inode:
+ free_flat(flat_data);
+error_flat:
+ kfree(flat_data);
+error_data:
+ return err;
}
long doom_create_colormaps(struct file *filp, unsigned long arg)