Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 223393
b: refs/heads/master
c: 4aa2759
h: refs/heads/master
i:
  223391: bd6ba77
v: v3
  • Loading branch information
Laurent Pinchart authored and Mauro Carvalho Chehab committed Dec 1, 2010
1 parent a621da9 commit 9ac7f47
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 67 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8e815e1763b8d4e5adf0dc14bde8c55329cf95a8
refs/heads/master: 4aa275975beee41fd542a0f6df8cd0fee06089bf
76 changes: 76 additions & 0 deletions trunk/drivers/media/video/uvc/uvc_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,82 @@ int uvc_dequeue_buffer(struct uvc_video_queue *queue,
return ret;
}

/*
* 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,
};

/*
* Memory-map a video buffer.
*
* This function implements video buffers memory mapping and is intended to be
* used by the device mmap handler.
*/
int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
{
struct uvc_buffer *uninitialized_var(buffer);
struct page *page;
unsigned long addr, start, size;
unsigned int i;
int ret = 0;

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;
}

/*
* Poll the video queue.
*
Expand Down
67 changes: 1 addition & 66 deletions trunk/drivers/media/video/uvc/uvc_v4l2.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/media/video/uvc/uvcvideo.h
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,8 @@ extern int uvc_queue_enable(struct uvc_video_queue *queue, int enable);
extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect);
extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue,
struct uvc_buffer *buf);
extern int uvc_queue_mmap(struct uvc_video_queue *queue,
struct vm_area_struct *vma);
extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue,
struct file *file, poll_table *wait);
extern int uvc_queue_allocated(struct uvc_video_queue *queue);
Expand Down

0 comments on commit 9ac7f47

Please sign in to comment.