Commit 8da730e9 authored by Gerd Knorr's avatar Gerd Knorr Committed by Linus Torvalds

[PATCH] v4l: video-buf update

This patch is a update for the video-buf mm helper module.  It has
some minor bugfixes and a number of signed/unsigned cleanups to make
gcc 3.3 happy.
parent 450b4497
...@@ -83,6 +83,8 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset) ...@@ -83,6 +83,8 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
return NULL; return NULL;
memset(sglist, 0, sizeof(*sglist) * nr_pages); memset(sglist, 0, sizeof(*sglist) * nr_pages);
if (NULL == pages[0])
goto nopage;
if (PageHighMem(pages[0])) if (PageHighMem(pages[0]))
/* DMA to highmem pages might not work */ /* DMA to highmem pages might not work */
goto highmem; goto highmem;
...@@ -118,7 +120,7 @@ int videobuf_lock(struct page **pages, int nr_pages) ...@@ -118,7 +120,7 @@ int videobuf_lock(struct page **pages, int nr_pages)
for (i = 0; i < nr_pages; i++) for (i = 0; i < nr_pages; i++)
if (TryLockPage(pages[i])) if (TryLockPage(pages[i]))
goto err; goto err;
dprintk(2,"lock ok\n"); dprintk(2,"lock ok [%d pages]\n",nr_pages);
return 0; return 0;
err: err:
...@@ -136,7 +138,7 @@ int videobuf_unlock(struct page **pages, int nr_pages) ...@@ -136,7 +138,7 @@ int videobuf_unlock(struct page **pages, int nr_pages)
dprintk(2,"unlock start ...\n"); dprintk(2,"unlock start ...\n");
for (i = 0; i < nr_pages; i++) for (i = 0; i < nr_pages; i++)
unlock_page(pages[i]); unlock_page(pages[i]);
dprintk(2,"unlock ok\n"); dprintk(2,"unlock ok [%d pages]\n",nr_pages);
return 0; return 0;
} }
...@@ -270,7 +272,7 @@ int videobuf_dma_free(struct videobuf_dmabuf *dma) ...@@ -270,7 +272,7 @@ int videobuf_dma_free(struct videobuf_dmabuf *dma)
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
void* videobuf_alloc(int size) void* videobuf_alloc(unsigned int size)
{ {
struct videobuf_buffer *vb; struct videobuf_buffer *vb;
...@@ -340,7 +342,7 @@ videobuf_queue_init(struct videobuf_queue *q, ...@@ -340,7 +342,7 @@ videobuf_queue_init(struct videobuf_queue *q,
spinlock_t *irqlock, spinlock_t *irqlock,
enum v4l2_buf_type type, enum v4l2_buf_type type,
enum v4l2_field field, enum v4l2_field field,
int msize) unsigned int msize)
{ {
memset(q,0,sizeof(*q)); memset(q,0,sizeof(*q));
...@@ -417,11 +419,11 @@ videobuf_next_field(struct videobuf_queue *q) ...@@ -417,11 +419,11 @@ videobuf_next_field(struct videobuf_queue *q)
if (V4L2_FIELD_ALTERNATE == field) { if (V4L2_FIELD_ALTERNATE == field) {
if (V4L2_FIELD_TOP == q->last) { if (V4L2_FIELD_TOP == q->last) {
field = V4L2_FIELD_TOP;
q->last = V4L2_FIELD_TOP;
} else {
field = V4L2_FIELD_BOTTOM; field = V4L2_FIELD_BOTTOM;
q->last = V4L2_FIELD_BOTTOM; q->last = V4L2_FIELD_BOTTOM;
} else {
field = V4L2_FIELD_TOP;
q->last = V4L2_FIELD_TOP;
} }
} }
return field; return field;
...@@ -463,7 +465,8 @@ int ...@@ -463,7 +465,8 @@ int
videobuf_reqbufs(struct file *file, struct videobuf_queue *q, videobuf_reqbufs(struct file *file, struct videobuf_queue *q,
struct v4l2_requestbuffers *req) struct v4l2_requestbuffers *req)
{ {
int size,count,retval; unsigned int size,count;
int retval;
if (req->type != q->type) if (req->type != q->type)
return -EINVAL; return -EINVAL;
...@@ -477,6 +480,8 @@ videobuf_reqbufs(struct file *file, struct videobuf_queue *q, ...@@ -477,6 +480,8 @@ videobuf_reqbufs(struct file *file, struct videobuf_queue *q,
size = 0; size = 0;
q->ops->buf_setup(file,&count,&size); q->ops->buf_setup(file,&count,&size);
size = PAGE_ALIGN(size); size = PAGE_ALIGN(size);
dprintk(1,"reqbufs: bufs=%d, size=0x%x [%d pages total]\n",
count, size, (count*size)>>PAGE_SHIFT);
retval = videobuf_mmap_setup(file,q,count,size); retval = videobuf_mmap_setup(file,q,count,size);
if (retval < 0) if (retval < 0)
...@@ -660,7 +665,10 @@ videobuf_read_zerocopy(struct file *file, struct videobuf_queue *q, ...@@ -660,7 +665,10 @@ videobuf_read_zerocopy(struct file *file, struct videobuf_queue *q,
retval = videobuf_waiton(q->read_buf,0,0); retval = videobuf_waiton(q->read_buf,0,0);
if (0 == retval) { if (0 == retval) {
videobuf_dma_pci_sync(q->pci,&q->read_buf->dma); videobuf_dma_pci_sync(q->pci,&q->read_buf->dma);
retval = q->read_buf->size; if (STATE_ERROR == q->read_buf->state)
retval = -EIO;
else
retval = q->read_buf->size;
} }
done: done:
...@@ -676,7 +684,8 @@ ssize_t videobuf_read_one(struct file *file, struct videobuf_queue *q, ...@@ -676,7 +684,8 @@ ssize_t videobuf_read_one(struct file *file, struct videobuf_queue *q,
{ {
enum v4l2_field field; enum v4l2_field field;
unsigned long flags; unsigned long flags;
int retval, bytes, size, nbufs; unsigned size, nbufs, bytes;
int retval;
down(&q->lock); down(&q->lock);
...@@ -686,7 +695,7 @@ ssize_t videobuf_read_one(struct file *file, struct videobuf_queue *q, ...@@ -686,7 +695,7 @@ ssize_t videobuf_read_one(struct file *file, struct videobuf_queue *q,
count >= size && count >= size &&
!(file->f_flags & O_NONBLOCK)) { !(file->f_flags & O_NONBLOCK)) {
retval = videobuf_read_zerocopy(file,q,data,count,ppos); retval = videobuf_read_zerocopy(file,q,data,count,ppos);
if (retval >= 0) if (retval >= 0 || retval == -EIO)
/* ok, all done */ /* ok, all done */
goto done; goto done;
/* fallback to kernel bounce buffer on failures */ /* fallback to kernel bounce buffer on failures */
...@@ -714,6 +723,15 @@ ssize_t videobuf_read_one(struct file *file, struct videobuf_queue *q, ...@@ -714,6 +723,15 @@ ssize_t videobuf_read_one(struct file *file, struct videobuf_queue *q,
goto done; goto done;
videobuf_dma_pci_sync(q->pci,&q->read_buf->dma); videobuf_dma_pci_sync(q->pci,&q->read_buf->dma);
if (STATE_ERROR == q->read_buf->state) {
/* catch I/O errors */
q->ops->buf_release(file,q->read_buf);
kfree(q->read_buf);
q->read_buf = NULL;
retval = -EIO;
goto done;
}
/* copy to userspace */ /* copy to userspace */
bytes = count; bytes = count;
if (bytes > q->read_buf->size - q->read_off) if (bytes > q->read_buf->size - q->read_off)
...@@ -788,8 +806,8 @@ ssize_t videobuf_read_stream(struct file *file, struct videobuf_queue *q, ...@@ -788,8 +806,8 @@ ssize_t videobuf_read_stream(struct file *file, struct videobuf_queue *q,
char *data, size_t count, loff_t *ppos, char *data, size_t count, loff_t *ppos,
int vbihack) int vbihack)
{ {
unsigned int *fc; unsigned int *fc, bytes;
int err, bytes, retval; int err, retval;
unsigned long flags; unsigned long flags;
down(&q->lock); down(&q->lock);
...@@ -968,9 +986,10 @@ static struct vm_operations_struct videobuf_vm_ops = ...@@ -968,9 +986,10 @@ static struct vm_operations_struct videobuf_vm_ops =
}; };
int videobuf_mmap_setup(struct file *file, struct videobuf_queue *q, int videobuf_mmap_setup(struct file *file, struct videobuf_queue *q,
int bcount, int bsize) unsigned int bcount, unsigned int bsize)
{ {
int i,err; unsigned int i;
int err;
err = videobuf_mmap_free(file,q); err = videobuf_mmap_free(file,q);
if (0 != err) if (0 != err)
...@@ -1008,7 +1027,8 @@ int videobuf_mmap_mapper(struct vm_area_struct *vma, ...@@ -1008,7 +1027,8 @@ int videobuf_mmap_mapper(struct vm_area_struct *vma,
struct videobuf_queue *q) struct videobuf_queue *q)
{ {
struct videobuf_mapping *map; struct videobuf_mapping *map;
int first,last,size,i,retval; unsigned int first,last,size,i;
int retval;
down(&q->lock); down(&q->lock);
retval = -EINVAL; retval = -EINVAL;
...@@ -1025,7 +1045,7 @@ int videobuf_mmap_mapper(struct vm_area_struct *vma, ...@@ -1025,7 +1045,7 @@ int videobuf_mmap_mapper(struct vm_area_struct *vma,
for (first = 0; first < VIDEO_MAX_FRAME; first++) { for (first = 0; first < VIDEO_MAX_FRAME; first++) {
if (NULL == q->bufs[first]) if (NULL == q->bufs[first])
continue; continue;
if (q->bufs[first]->boff == (vma->vm_pgoff << PAGE_SHIFT)) if (q->bufs[first]->boff == (vma->vm_pgoff << PAGE_SHIFT))
break; break;
} }
if (VIDEO_MAX_FRAME == first) { if (VIDEO_MAX_FRAME == first) {
......
...@@ -110,7 +110,7 @@ struct videobuf_buffer; ...@@ -110,7 +110,7 @@ struct videobuf_buffer;
struct videobuf_queue; struct videobuf_queue;
struct videobuf_mapping { struct videobuf_mapping {
int count; unsigned int count;
int highmem_ok; int highmem_ok;
unsigned long start; unsigned long start;
unsigned long end; unsigned long end;
...@@ -128,19 +128,19 @@ enum videobuf_state { ...@@ -128,19 +128,19 @@ enum videobuf_state {
}; };
struct videobuf_buffer { struct videobuf_buffer {
int i; unsigned int i;
/* info about the buffer */ /* info about the buffer */
int width; unsigned int width;
int height; unsigned int height;
long size; unsigned long size;
enum v4l2_field field; enum v4l2_field field;
enum videobuf_state state; enum videobuf_state state;
struct videobuf_dmabuf dma; struct videobuf_dmabuf dma;
struct list_head stream; /* QBUF/DQBUF list */ struct list_head stream; /* QBUF/DQBUF list */
/* for mmap'ed buffers */ /* for mmap'ed buffers */
off_t boff; /* buffer offset (mmap) */ size_t boff; /* buffer offset (mmap) */
size_t bsize; /* buffer size */ size_t bsize; /* buffer size */
unsigned long baddr; /* buffer addr (userland ptr!) */ unsigned long baddr; /* buffer addr (userland ptr!) */
struct videobuf_mapping *map; struct videobuf_mapping *map;
...@@ -148,12 +148,13 @@ struct videobuf_buffer { ...@@ -148,12 +148,13 @@ struct videobuf_buffer {
/* touched by irq handler */ /* touched by irq handler */
struct list_head queue; struct list_head queue;
wait_queue_head_t done; wait_queue_head_t done;
int field_count; unsigned int field_count;
struct timeval ts; struct timeval ts;
}; };
struct videobuf_queue_ops { struct videobuf_queue_ops {
int (*buf_setup)(struct file *file, int *count, int *size); int (*buf_setup)(struct file *file,
unsigned int *count, unsigned int *size);
int (*buf_prepare)(struct file *file,struct videobuf_buffer *vb, int (*buf_prepare)(struct file *file,struct videobuf_buffer *vb,
enum v4l2_field field); enum v4l2_field field);
void (*buf_queue)(struct file *file,struct videobuf_buffer *vb); void (*buf_queue)(struct file *file,struct videobuf_buffer *vb);
...@@ -166,23 +167,23 @@ struct videobuf_queue { ...@@ -166,23 +167,23 @@ struct videobuf_queue {
struct pci_dev *pci; struct pci_dev *pci;
enum v4l2_buf_type type; enum v4l2_buf_type type;
int msize; unsigned int msize;
enum v4l2_field field; enum v4l2_field field;
enum v4l2_field last; /* for field=V4L2_FIELD_ALTERNATE */ enum v4l2_field last; /* for field=V4L2_FIELD_ALTERNATE */
struct videobuf_buffer *bufs[VIDEO_MAX_FRAME]; struct videobuf_buffer *bufs[VIDEO_MAX_FRAME];
struct videobuf_queue_ops *ops; struct videobuf_queue_ops *ops;
/* capture via mmap() + ioctl(QBUF/DQBUF) */ /* capture via mmap() + ioctl(QBUF/DQBUF) */
int streaming; unsigned int streaming;
struct list_head stream; struct list_head stream;
/* capture via read() */ /* capture via read() */
int reading; unsigned int reading;
int read_off; unsigned int read_off;
struct videobuf_buffer *read_buf; struct videobuf_buffer *read_buf;
}; };
void* videobuf_alloc(int size); void* videobuf_alloc(unsigned int size);
int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr); int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr);
int videobuf_iolock(struct pci_dev *pci, struct videobuf_buffer *vb); int videobuf_iolock(struct pci_dev *pci, struct videobuf_buffer *vb);
...@@ -190,7 +191,8 @@ void videobuf_queue_init(struct videobuf_queue *q, ...@@ -190,7 +191,8 @@ void videobuf_queue_init(struct videobuf_queue *q,
struct videobuf_queue_ops *ops, struct videobuf_queue_ops *ops,
struct pci_dev *pci, spinlock_t *irqlock, struct pci_dev *pci, spinlock_t *irqlock,
enum v4l2_buf_type type, enum v4l2_buf_type type,
enum v4l2_field field, int msize); enum v4l2_field field,
unsigned int msize);
int videobuf_queue_is_busy(struct videobuf_queue *q); int videobuf_queue_is_busy(struct videobuf_queue *q);
void videobuf_queue_cancel(struct file *file, struct videobuf_queue *q); void videobuf_queue_cancel(struct file *file, struct videobuf_queue *q);
...@@ -218,7 +220,7 @@ unsigned int videobuf_poll_stream(struct file *file, ...@@ -218,7 +220,7 @@ unsigned int videobuf_poll_stream(struct file *file,
poll_table *wait); poll_table *wait);
int videobuf_mmap_setup(struct file *file, struct videobuf_queue *q, int videobuf_mmap_setup(struct file *file, struct videobuf_queue *q,
int bcount, int bsize); unsigned int bcount, unsigned int bsize);
int videobuf_mmap_free(struct file *file, struct videobuf_queue *q); int videobuf_mmap_free(struct file *file, struct videobuf_queue *q);
int videobuf_mmap_mapper(struct vm_area_struct *vma, int videobuf_mmap_mapper(struct vm_area_struct *vma,
struct videobuf_queue *q); struct videobuf_queue *q);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment