git://git.onelab.eu
/
linux-2.6.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git]
/
drivers
/
media
/
video
/
video-buf.c
diff --git
a/drivers/media/video/video-buf.c
b/drivers/media/video/video-buf.c
index
f541a06
..
c7c7465
100644
(file)
--- a/
drivers/media/video/video-buf.c
+++ b/
drivers/media/video/video-buf.c
@@
-5,10
+5,10
@@
* The functions expect the hardware being able to scatter gatter
* (i.e. the buffers are not linear in physical memory, but fragmented
* into PAGE_SIZE chunks). They also assume the driver does not need
* The functions expect the hardware being able to scatter gatter
* (i.e. the buffers are not linear in physical memory, but fragmented
* into PAGE_SIZE chunks). They also assume the driver does not need
- * to touch the video data (thus it is probably not useful for USB
as
- * data often must be uncompressed by the drivers).
+ * to touch the video data (thus it is probably not useful for USB
1.1
+ *
as
data often must be uncompressed by the drivers).
*
*
- * (c) 2001
,02 Gerd Knorr <kraxel@bytesex.org>
+ * (c) 2001
-2004 Gerd Knorr <kraxel@bytesex.org> [SUSE Labs]
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@
-28,6
+28,11
@@
#include <media/video-buf.h>
#include <media/video-buf.h>
+#define MAGIC_DMABUF 0x19721112
+#define MAGIC_BUFFER 0x20040302
+#define MAGIC_CHECK(is,should) if (unlikely((is) != (should))) \
+ { printk(KERN_ERR "magic mismatch: %x (expected %x)\n",is,should); BUG(); }
+
static int debug = 0;
MODULE_DESCRIPTION("helper module to manage video4linux pci dma buffers");
static int debug = 0;
MODULE_DESCRIPTION("helper module to manage video4linux pci dma buffers");
@@
-109,6
+114,12
@@
videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
/* --------------------------------------------------------------------- */
/* --------------------------------------------------------------------- */
+void videobuf_dma_init(struct videobuf_dmabuf *dma)
+{
+ memset(dma,0,sizeof(*dma));
+ dma->magic = MAGIC_DMABUF;
+}
+
int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction,
unsigned long data, unsigned long size)
{
int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction,
unsigned long data, unsigned long size)
{
@@
-178,8
+189,8
@@
int videobuf_dma_init_overlay(struct videobuf_dmabuf *dma, int direction,
int videobuf_dma_pci_map(struct pci_dev *dev, struct videobuf_dmabuf *dma)
{
int videobuf_dma_pci_map(struct pci_dev *dev, struct videobuf_dmabuf *dma)
{
- if (0 == dma->nr_pages)
-
BUG(
);
+ MAGIC_CHECK(dma->magic,MAGIC_DMABUF);
+
BUG_ON(0 == dma->nr_pages
);
if (dma->pages) {
dma->sglist = videobuf_pages_to_sg(dma->pages, dma->nr_pages,
if (dma->pages) {
dma->sglist = videobuf_pages_to_sg(dma->pages, dma->nr_pages,
@@
-211,8
+222,8
@@
int videobuf_dma_pci_map(struct pci_dev *dev, struct videobuf_dmabuf *dma)
int videobuf_dma_pci_sync(struct pci_dev *dev, struct videobuf_dmabuf *dma)
{
int videobuf_dma_pci_sync(struct pci_dev *dev, struct videobuf_dmabuf *dma)
{
- if (!dma->sglen)
-
BUG(
);
+ MAGIC_CHECK(dma->magic,MAGIC_DMABUF);
+
BUG_ON(!dma->sglen
);
if (!dma->bus_addr)
pci_dma_sync_sg_for_cpu(dev,dma->sglist,dma->nr_pages,dma->direction);
if (!dma->bus_addr)
pci_dma_sync_sg_for_cpu(dev,dma->sglist,dma->nr_pages,dma->direction);
@@
-221,6
+232,7
@@
int videobuf_dma_pci_sync(struct pci_dev *dev, struct videobuf_dmabuf *dma)
int videobuf_dma_pci_unmap(struct pci_dev *dev, struct videobuf_dmabuf *dma)
{
int videobuf_dma_pci_unmap(struct pci_dev *dev, struct videobuf_dmabuf *dma)
{
+ MAGIC_CHECK(dma->magic,MAGIC_DMABUF);
if (!dma->sglen)
return 0;
if (!dma->sglen)
return 0;
@@
-234,8
+246,8
@@
int videobuf_dma_pci_unmap(struct pci_dev *dev, struct videobuf_dmabuf *dma)
int videobuf_dma_free(struct videobuf_dmabuf *dma)
{
int videobuf_dma_free(struct videobuf_dmabuf *dma)
{
- if (dma->sglen)
-
BUG(
);
+ MAGIC_CHECK(dma->magic,MAGIC_DMABUF);
+
BUG_ON(dma->sglen
);
if (dma->pages) {
int i;
if (dma->pages) {
int i;
@@
-264,7
+276,9
@@
void* videobuf_alloc(unsigned int size)
vb = kmalloc(size,GFP_KERNEL);
if (NULL != vb) {
memset(vb,0,size);
vb = kmalloc(size,GFP_KERNEL);
if (NULL != vb) {
memset(vb,0,size);
+ videobuf_dma_init(&vb->dma);
init_waitqueue_head(&vb->done);
init_waitqueue_head(&vb->done);
+ vb->magic = MAGIC_BUFFER;
}
return vb;
}
}
return vb;
}
@@
-274,6
+288,7
@@
int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr)
int retval = 0;
DECLARE_WAITQUEUE(wait, current);
int retval = 0;
DECLARE_WAITQUEUE(wait, current);
+ MAGIC_CHECK(vb->magic,MAGIC_BUFFER);
add_wait_queue(&vb->done, &wait);
while (vb->state == STATE_ACTIVE || vb->state == STATE_QUEUED) {
if (non_blocking) {
add_wait_queue(&vb->done, &wait);
while (vb->state == STATE_ACTIVE || vb->state == STATE_QUEUED) {
if (non_blocking) {
@@
-302,6
+317,7
@@
videobuf_iolock(struct pci_dev *pci, struct videobuf_buffer *vb,
int err,pages;
dma_addr_t bus;
int err,pages;
dma_addr_t bus;
+ MAGIC_CHECK(vb->magic,MAGIC_BUFFER);
switch (vb->memory) {
case V4L2_MEMORY_MMAP:
case V4L2_MEMORY_USERPTR:
switch (vb->memory) {
case V4L2_MEMORY_MMAP:
case V4L2_MEMORY_USERPTR:
@@
-453,6
+469,8
@@
void
videobuf_status(struct v4l2_buffer *b, struct videobuf_buffer *vb,
enum v4l2_buf_type type)
{
videobuf_status(struct v4l2_buffer *b, struct videobuf_buffer *vb,
enum v4l2_buf_type type)
{
+ MAGIC_CHECK(vb->magic,MAGIC_BUFFER);
+
b->index = vb->i;
b->type = type;
b->index = vb->i;
b->type = type;
@@
-491,6
+509,11
@@
videobuf_status(struct v4l2_buffer *b, struct videobuf_buffer *vb,
break;
}
break;
}
+ if (vb->input != UNSET) {
+ b->flags |= V4L2_BUF_FLAG_INPUT;
+ b->input = vb->input;
+ }
+
b->field = vb->field;
b->timestamp = vb->ts;
b->bytesused = vb->size;
b->field = vb->field;
b->timestamp = vb->ts;
b->bytesused = vb->size;
@@
-513,6
+536,11
@@
videobuf_reqbufs(struct file *file, struct videobuf_queue *q,
req->memory != V4L2_MEMORY_OVERLAY)
return -EINVAL;
req->memory != V4L2_MEMORY_OVERLAY)
return -EINVAL;
+ if (q->streaming)
+ return -EBUSY;
+ if (!list_empty(&q->stream))
+ return -EBUSY;
+
down(&q->lock);
count = req->count;
if (count > VIDEO_MAX_FRAME)
down(&q->lock);
count = req->count;
if (count > VIDEO_MAX_FRAME)
@@
-568,12
+596,21
@@
videobuf_qbuf(struct file *file, struct videobuf_queue *q,
buf = q->bufs[b->index];
if (NULL == buf)
goto done;
buf = q->bufs[b->index];
if (NULL == buf)
goto done;
+ MAGIC_CHECK(buf->magic,MAGIC_BUFFER);
if (buf->memory != b->memory)
goto done;
if (buf->state == STATE_QUEUED ||
buf->state == STATE_ACTIVE)
goto done;
if (buf->memory != b->memory)
goto done;
if (buf->state == STATE_QUEUED ||
buf->state == STATE_ACTIVE)
goto done;
+ if (b->flags & V4L2_BUF_FLAG_INPUT) {
+ if (b->input >= q->inputs)
+ goto done;
+ buf->input = b->input;
+ } else {
+ buf->input = UNSET;
+ }
+
switch (b->memory) {
case V4L2_MEMORY_MMAP:
if (0 == buf->baddr)
switch (b->memory) {
case V4L2_MEMORY_MMAP:
if (0 == buf->baddr)
@@
-582,6
+619,8
@@
videobuf_qbuf(struct file *file, struct videobuf_queue *q,
case V4L2_MEMORY_USERPTR:
if (b->length < buf->bsize)
goto done;
case V4L2_MEMORY_USERPTR:
if (b->length < buf->bsize)
goto done;
+ if (STATE_NEEDS_INIT != buf->state && buf->baddr != b->m.userptr)
+ q->ops->buf_release(file,buf);
buf->baddr = b->m.userptr;
break;
case V4L2_MEMORY_OVERLAY:
buf->baddr = b->m.userptr;
break;
case V4L2_MEMORY_OVERLAY:
@@
-696,7
+735,7
@@
int videobuf_streamoff(struct file *file, struct videobuf_queue *q)
static ssize_t
videobuf_read_zerocopy(struct file *file, struct videobuf_queue *q,
static ssize_t
videobuf_read_zerocopy(struct file *file, struct videobuf_queue *q,
- char *data, size_t count, loff_t *ppos)
+ char
__user
*data, size_t count, loff_t *ppos)
{
enum v4l2_field field;
unsigned long flags;
{
enum v4l2_field field;
unsigned long flags;
@@
-738,7
+777,7
@@
videobuf_read_zerocopy(struct file *file, struct videobuf_queue *q,
}
ssize_t videobuf_read_one(struct file *file, struct videobuf_queue *q,
}
ssize_t videobuf_read_one(struct file *file, struct videobuf_queue *q,
- char *data, size_t count, loff_t *ppos)
+ char
__user
*data, size_t count, loff_t *ppos)
{
enum v4l2_field field;
unsigned long flags;
{
enum v4l2_field field;
unsigned long flags;
@@
-862,7
+901,7
@@
void videobuf_read_stop(struct file *file, struct videobuf_queue *q)
}
ssize_t videobuf_read_stream(struct file *file, struct videobuf_queue *q,
}
ssize_t videobuf_read_stream(struct file *file, struct videobuf_queue *q,
- char *data, size_t count, loff_t *ppos,
+ char
__user
*data, size_t count, loff_t *ppos,
int vbihack)
{
unsigned int *fc, bytes;
int vbihack)
{
unsigned int *fc, bytes;
@@
-1075,6
+1114,7
@@
int videobuf_mmap_setup(struct file *file, struct videobuf_queue *q,
for (i = 0; i < bcount; i++) {
q->bufs[i] = videobuf_alloc(q->msize);
q->bufs[i]->i = i;
for (i = 0; i < bcount; i++) {
q->bufs[i] = videobuf_alloc(q->msize);
q->bufs[i]->i = i;
+ q->bufs[i]->input = UNSET;
q->bufs[i]->memory = memory;
q->bufs[i]->bsize = bsize;
switch (memory) {
q->bufs[i]->memory = memory;
q->bufs[i]->bsize = bsize;
switch (memory) {
@@
-1085,7
+1125,7
@@
int videobuf_mmap_setup(struct file *file, struct videobuf_queue *q,
case V4L2_MEMORY_OVERLAY:
/* nothing */
break;
case V4L2_MEMORY_OVERLAY:
/* nothing */
break;
- }
;
+ }
}
dprintk(1,"mmap setup: %d buffers, %d bytes each\n",
bcount,bsize);
}
dprintk(1,"mmap setup: %d buffers, %d bytes each\n",
bcount,bsize);
@@
-1192,6
+1232,7
@@
int videobuf_mmap_mapper(struct vm_area_struct *vma,
EXPORT_SYMBOL_GPL(videobuf_vmalloc_to_sg);
EXPORT_SYMBOL_GPL(videobuf_vmalloc_to_sg);
+EXPORT_SYMBOL_GPL(videobuf_dma_init);
EXPORT_SYMBOL_GPL(videobuf_dma_init_user);
EXPORT_SYMBOL_GPL(videobuf_dma_init_kernel);
EXPORT_SYMBOL_GPL(videobuf_dma_init_overlay);
EXPORT_SYMBOL_GPL(videobuf_dma_init_user);
EXPORT_SYMBOL_GPL(videobuf_dma_init_kernel);
EXPORT_SYMBOL_GPL(videobuf_dma_init_overlay);