|
@@ -34,6 +34,8 @@
|
|
|
#include <linux/poll.h>
|
|
|
#include <linux/reservation.h>
|
|
|
|
|
|
+#include <uapi/linux/dma-buf.h>
|
|
|
+
|
|
|
static inline int is_dma_buf_file(struct file *);
|
|
|
|
|
|
struct dma_buf_list {
|
|
@@ -251,11 +253,54 @@ out:
|
|
|
return events;
|
|
|
}
|
|
|
|
|
|
+static long dma_buf_ioctl(struct file *file,
|
|
|
+ unsigned int cmd, unsigned long arg)
|
|
|
+{
|
|
|
+ struct dma_buf *dmabuf;
|
|
|
+ struct dma_buf_sync sync;
|
|
|
+ enum dma_data_direction direction;
|
|
|
+
|
|
|
+ dmabuf = file->private_data;
|
|
|
+
|
|
|
+ switch (cmd) {
|
|
|
+ case DMA_BUF_IOCTL_SYNC:
|
|
|
+ if (copy_from_user(&sync, (void __user *) arg, sizeof(sync)))
|
|
|
+ return -EFAULT;
|
|
|
+
|
|
|
+ if (sync.flags & ~DMA_BUF_SYNC_VALID_FLAGS_MASK)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ switch (sync.flags & DMA_BUF_SYNC_RW) {
|
|
|
+ case DMA_BUF_SYNC_READ:
|
|
|
+ direction = DMA_FROM_DEVICE;
|
|
|
+ break;
|
|
|
+ case DMA_BUF_SYNC_WRITE:
|
|
|
+ direction = DMA_TO_DEVICE;
|
|
|
+ break;
|
|
|
+ case DMA_BUF_SYNC_RW:
|
|
|
+ direction = DMA_BIDIRECTIONAL;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (sync.flags & DMA_BUF_SYNC_END)
|
|
|
+ dma_buf_end_cpu_access(dmabuf, direction);
|
|
|
+ else
|
|
|
+ dma_buf_begin_cpu_access(dmabuf, direction);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+ default:
|
|
|
+ return -ENOTTY;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static const struct file_operations dma_buf_fops = {
|
|
|
.release = dma_buf_release,
|
|
|
.mmap = dma_buf_mmap_internal,
|
|
|
.llseek = dma_buf_llseek,
|
|
|
.poll = dma_buf_poll,
|
|
|
+ .unlocked_ioctl = dma_buf_ioctl,
|
|
|
};
|
|
|
|
|
|
/*
|