|
@@ -1032,79 +1032,14 @@ static ssize_t uvc_v4l2_read(struct file *file, char __user *data,
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * VMA operations.
|
|
|
- */
|
|
|
-static void uvc_vm_open(struct vm_area_struct *vma)
|
|
|
-{
|
|
|
- struct uvc_buffer *buffer = vma->vm_private_data;
|
|
|
- buffer->vma_use_count++;
|
|
|
-}
|
|
|
-
|
|
|
-static void uvc_vm_close(struct vm_area_struct *vma)
|
|
|
-{
|
|
|
- struct uvc_buffer *buffer = vma->vm_private_data;
|
|
|
- buffer->vma_use_count--;
|
|
|
-}
|
|
|
-
|
|
|
-static const struct vm_operations_struct uvc_vm_ops = {
|
|
|
- .open = uvc_vm_open,
|
|
|
- .close = uvc_vm_close,
|
|
|
-};
|
|
|
-
|
|
|
static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
|
|
|
{
|
|
|
struct uvc_fh *handle = file->private_data;
|
|
|
struct uvc_streaming *stream = handle->stream;
|
|
|
- struct uvc_video_queue *queue = &stream->queue;
|
|
|
- struct uvc_buffer *uninitialized_var(buffer);
|
|
|
- struct page *page;
|
|
|
- unsigned long addr, start, size;
|
|
|
- unsigned int i;
|
|
|
- int ret = 0;
|
|
|
|
|
|
uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_mmap\n");
|
|
|
|
|
|
- start = vma->vm_start;
|
|
|
- size = vma->vm_end - vma->vm_start;
|
|
|
-
|
|
|
- mutex_lock(&queue->mutex);
|
|
|
-
|
|
|
- for (i = 0; i < queue->count; ++i) {
|
|
|
- buffer = &queue->buffer[i];
|
|
|
- if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- if (i == queue->count || size != queue->buf_size) {
|
|
|
- ret = -EINVAL;
|
|
|
- goto done;
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
- * VM_IO marks the area as being an mmaped region for I/O to a
|
|
|
- * device. It also prevents the region from being core dumped.
|
|
|
- */
|
|
|
- vma->vm_flags |= VM_IO;
|
|
|
-
|
|
|
- addr = (unsigned long)queue->mem + buffer->buf.m.offset;
|
|
|
- while (size > 0) {
|
|
|
- page = vmalloc_to_page((void *)addr);
|
|
|
- if ((ret = vm_insert_page(vma, start, page)) < 0)
|
|
|
- goto done;
|
|
|
-
|
|
|
- start += PAGE_SIZE;
|
|
|
- addr += PAGE_SIZE;
|
|
|
- size -= PAGE_SIZE;
|
|
|
- }
|
|
|
-
|
|
|
- vma->vm_ops = &uvc_vm_ops;
|
|
|
- vma->vm_private_data = buffer;
|
|
|
- uvc_vm_open(vma);
|
|
|
-
|
|
|
-done:
|
|
|
- mutex_unlock(&queue->mutex);
|
|
|
- return ret;
|
|
|
+ return uvc_queue_mmap(&stream->queue, vma);
|
|
|
}
|
|
|
|
|
|
static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait)
|