Skip to content

Commit

Permalink
V4L/DVB: v4l videobuf: move video_copy_to_user and copy_stream to core
Browse files Browse the repository at this point in the history
The video_copy_to_user and copy_stream ops are almost identical for all
videobuf memtype variants. All that is needed is to use the new vaddr
op and these functions can be moved into the core, ensuring we have just
one single implementation instead of three.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Hans Verkuil authored and Mauro Carvalho Chehab committed May 19, 2010
1 parent f4fce60 commit 3711103
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 167 deletions.
47 changes: 45 additions & 2 deletions drivers/media/video/videobuf-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,49 @@ static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q,
return retval;
}

static int __videobuf_copy_to_user(struct videobuf_queue *q,
struct videobuf_buffer *buf,
char __user *data, size_t count,
int nonblocking)
{
void *vaddr = CALL(q, vaddr, buf);

/* copy to userspace */
if (count > buf->size - q->read_off)
count = buf->size - q->read_off;

if (copy_to_user(data, vaddr + q->read_off, count))
return -EFAULT;

return count;
}

static int __videobuf_copy_stream(struct videobuf_queue *q,
struct videobuf_buffer *buf,
char __user *data, size_t count, size_t pos,
int vbihack, int nonblocking)
{
unsigned int *fc = CALL(q, vaddr, buf);

if (vbihack) {
/* dirty, undocumented hack -- pass the frame counter
* within the last four bytes of each vbi data block.
* We need that one to maintain backward compatibility
* to all vbi decoding software out there ... */
fc += (buf->size >> 2) - 1;
*fc = buf->field_count >> 1;
dprintk(1, "vbihack: %d\n", *fc);
}

/* copy stuff using the common method */
count = __videobuf_copy_to_user(q, buf, data, count, nonblocking);

if ((count == -EFAULT) && (pos == 0))
return -EFAULT;

return count;
}

ssize_t videobuf_read_one(struct videobuf_queue *q,
char __user *data, size_t count, loff_t *ppos,
int nonblocking)
Expand Down Expand Up @@ -861,7 +904,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
}

/* Copy to userspace */
retval = CALL(q, video_copy_to_user, q, data, count, nonblocking);
retval = __videobuf_copy_to_user(q, q->read_buf, data, count, nonblocking);
if (retval < 0)
goto done;

Expand Down Expand Up @@ -1003,7 +1046,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q,
}

if (q->read_buf->state == VIDEOBUF_DONE) {
rc = CALL(q, copy_stream, q, data + retval, count,
rc = __videobuf_copy_stream(q, q->read_buf, data + retval, count,
retval, vbihack, nonblocking);
if (rc < 0) {
retval = rc;
Expand Down
55 changes: 0 additions & 55 deletions drivers/media/video/videobuf-dma-contig.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,67 +353,12 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
return -ENOMEM;
}

static int __videobuf_copy_to_user(struct videobuf_queue *q,
char __user *data, size_t count,
int nonblocking)
{
struct videobuf_dma_contig_memory *mem = q->read_buf->priv;
void *vaddr;

BUG_ON(!mem);
MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
BUG_ON(!mem->vaddr);

/* copy to userspace */
if (count > q->read_buf->size - q->read_off)
count = q->read_buf->size - q->read_off;

vaddr = mem->vaddr;

if (copy_to_user(data, vaddr + q->read_off, count))
return -EFAULT;

return count;
}

static int __videobuf_copy_stream(struct videobuf_queue *q,
char __user *data, size_t count, size_t pos,
int vbihack, int nonblocking)
{
unsigned int *fc;
struct videobuf_dma_contig_memory *mem = q->read_buf->priv;

BUG_ON(!mem);
MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);

if (vbihack) {
/* dirty, undocumented hack -- pass the frame counter
* within the last four bytes of each vbi data block.
* We need that one to maintain backward compatibility
* to all vbi decoding software out there ... */
fc = (unsigned int *)mem->vaddr;
fc += (q->read_buf->size >> 2) - 1;
*fc = q->read_buf->field_count >> 1;
dev_dbg(q->dev, "vbihack: %d\n", *fc);
}

/* copy stuff using the common method */
count = __videobuf_copy_to_user(q, data, count, nonblocking);

if ((count == -EFAULT) && (pos == 0))
return -EFAULT;

return count;
}

static struct videobuf_qtype_ops qops = {
.magic = MAGIC_QTYPE_OPS,

.alloc = __videobuf_alloc,
.iolock = __videobuf_iolock,
.mmap_mapper = __videobuf_mmap_mapper,
.video_copy_to_user = __videobuf_copy_to_user,
.copy_stream = __videobuf_copy_stream,
.vaddr = __videobuf_to_vaddr,
};

Expand Down
49 changes: 0 additions & 49 deletions drivers/media/video/videobuf-dma-sg.c
Original file line number Diff line number Diff line change
Expand Up @@ -644,62 +644,13 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
return retval;
}

static int __videobuf_copy_to_user(struct videobuf_queue *q,
char __user *data, size_t count,
int nonblocking)
{
struct videobuf_dma_sg_memory *mem = q->read_buf->priv;
BUG_ON(!mem);
MAGIC_CHECK(mem->magic, MAGIC_SG_MEM);

/* copy to userspace */
if (count > q->read_buf->size - q->read_off)
count = q->read_buf->size - q->read_off;

if (copy_to_user(data, mem->dma.vmalloc+q->read_off, count))
return -EFAULT;

return count;
}

static int __videobuf_copy_stream(struct videobuf_queue *q,
char __user *data, size_t count, size_t pos,
int vbihack, int nonblocking)
{
unsigned int *fc;
struct videobuf_dma_sg_memory *mem = q->read_buf->priv;
BUG_ON(!mem);
MAGIC_CHECK(mem->magic, MAGIC_SG_MEM);

if (vbihack) {
/* dirty, undocumented hack -- pass the frame counter
* within the last four bytes of each vbi data block.
* We need that one to maintain backward compatibility
* to all vbi decoding software out there ... */
fc = (unsigned int *)mem->dma.vmalloc;
fc += (q->read_buf->size >> 2) - 1;
*fc = q->read_buf->field_count >> 1;
dprintk(1, "vbihack: %d\n", *fc);
}

/* copy stuff using the common method */
count = __videobuf_copy_to_user(q, data, count, nonblocking);

if ((count == -EFAULT) && (0 == pos))
return -EFAULT;

return count;
}

static struct videobuf_qtype_ops sg_ops = {
.magic = MAGIC_QTYPE_OPS,

.alloc = __videobuf_alloc,
.iolock = __videobuf_iolock,
.sync = __videobuf_sync,
.mmap_mapper = __videobuf_mmap_mapper,
.video_copy_to_user = __videobuf_copy_to_user,
.copy_stream = __videobuf_copy_stream,
.vaddr = __videobuf_to_vaddr,
};

Expand Down
51 changes: 0 additions & 51 deletions drivers/media/video/videobuf-vmalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,64 +315,13 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
return -ENOMEM;
}

static int __videobuf_copy_to_user(struct videobuf_queue *q,
char __user *data, size_t count,
int nonblocking)
{
struct videobuf_vmalloc_memory *mem = q->read_buf->priv;
BUG_ON(!mem);
MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);

BUG_ON(!mem->vmalloc);

/* copy to userspace */
if (count > q->read_buf->size - q->read_off)
count = q->read_buf->size - q->read_off;

if (copy_to_user(data, mem->vmalloc+q->read_off, count))
return -EFAULT;

return count;
}

static int __videobuf_copy_stream(struct videobuf_queue *q,
char __user *data, size_t count, size_t pos,
int vbihack, int nonblocking)
{
unsigned int *fc;
struct videobuf_vmalloc_memory *mem = q->read_buf->priv;
BUG_ON(!mem);
MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);

if (vbihack) {
/* dirty, undocumented hack -- pass the frame counter
* within the last four bytes of each vbi data block.
* We need that one to maintain backward compatibility
* to all vbi decoding software out there ... */
fc = (unsigned int *)mem->vmalloc;
fc += (q->read_buf->size >> 2) - 1;
*fc = q->read_buf->field_count >> 1;
dprintk(1, "vbihack: %d\n", *fc);
}

/* copy stuff using the common method */
count = __videobuf_copy_to_user(q, data, count, nonblocking);

if ((count == -EFAULT) && (0 == pos))
return -EFAULT;

return count;
}

static struct videobuf_qtype_ops qops = {
.magic = MAGIC_QTYPE_OPS,

.alloc = __videobuf_alloc,
.iolock = __videobuf_iolock,
.sync = __videobuf_sync,
.mmap_mapper = __videobuf_mmap_mapper,
.video_copy_to_user = __videobuf_copy_to_user,
.copy_stream = __videobuf_copy_stream,
.vaddr = videobuf_to_vmalloc,
};

Expand Down
10 changes: 0 additions & 10 deletions include/media/videobuf-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,16 +134,6 @@ struct videobuf_qtype_ops {
struct v4l2_framebuffer *fbuf);
int (*sync) (struct videobuf_queue *q,
struct videobuf_buffer *buf);
int (*video_copy_to_user)(struct videobuf_queue *q,
char __user *data,
size_t count,
int nonblocking);
int (*copy_stream) (struct videobuf_queue *q,
char __user *data,
size_t count,
size_t pos,
int vbihack,
int nonblocking);
int (*mmap_mapper) (struct videobuf_queue *q,
struct vm_area_struct *vma);
};
Expand Down

0 comments on commit 3711103

Please sign in to comment.