From 3c822205812de2f9b9bfd17853f1b31f0693d3f8 Mon Sep 17 00:00:00 2001 From: Gerd Knorr Date: Tue, 19 Oct 2004 18:17:42 -0700 Subject: [PATCH] [PATCH] v4l: avoid using struct file ptrs in video-buf This patch makes the video-buf helper module pass through a void pointer instead of a struct file pointer, that makes the code also usable when no file pointer is available. This is needed for when using the video-buf infrastructure to manage DMA buffers for DVB cards. The file pointer was used by the videobuf_queue_ops callbacks to get the drivers private data via file->private_data, now a pointer to the drivers's private data can be passed directly. Adaptions of the drivers follow with separate patches. Signed-off-by: Gerd Knorr Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/video-buf.c | 101 ++++++++++++++++---------------- include/media/video-buf.h | 45 +++++++------- 2 files changed, 76 insertions(+), 70 deletions(-) diff --git a/drivers/media/video/video-buf.c b/drivers/media/video/video-buf.c index c7c7465508f03..e08f19f953c21 100644 --- a/drivers/media/video/video-buf.c +++ b/drivers/media/video/video-buf.c @@ -1,4 +1,6 @@ /* + * $Id: video-buf.c,v 1.12 2004/10/11 14:53:13 kraxel Exp $ + * * generic helper functions for video4linux capture buffers, to handle * memory management and PCI DMA. Right now bttv + saa7134 use it. * @@ -418,7 +420,7 @@ videobuf_queue_is_busy(struct videobuf_queue *q) } void -videobuf_queue_cancel(struct file *file, struct videobuf_queue *q) +videobuf_queue_cancel(void *priv, struct videobuf_queue *q) { unsigned long flags; int i; @@ -439,7 +441,7 @@ videobuf_queue_cancel(struct file *file, struct videobuf_queue *q) for (i = 0; i < VIDEO_MAX_FRAME; i++) { if (NULL == q->bufs[i]) continue; - q->ops->buf_release(file,q->bufs[i]); + q->ops->buf_release(priv,q->bufs[i]); } INIT_LIST_HEAD(&q->stream); } @@ -521,7 +523,7 @@ videobuf_status(struct v4l2_buffer *b, struct videobuf_buffer *vb, } int -videobuf_reqbufs(struct file *file, struct videobuf_queue *q, +videobuf_reqbufs(void *priv, struct videobuf_queue *q, struct v4l2_requestbuffers *req) { unsigned int size,count; @@ -546,12 +548,12 @@ videobuf_reqbufs(struct file *file, struct videobuf_queue *q, if (count > VIDEO_MAX_FRAME) count = VIDEO_MAX_FRAME; size = 0; - q->ops->buf_setup(file,&count,&size); + q->ops->buf_setup(priv,&count,&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,req->memory); + retval = videobuf_mmap_setup(priv,q,count,size,req->memory); if (retval < 0) goto done; @@ -576,7 +578,7 @@ videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b) } int -videobuf_qbuf(struct file *file, struct videobuf_queue *q, +videobuf_qbuf(void *priv, struct videobuf_queue *q, struct v4l2_buffer *b) { struct videobuf_buffer *buf; @@ -620,7 +622,7 @@ videobuf_qbuf(struct file *file, struct videobuf_queue *q, if (b->length < buf->bsize) goto done; if (STATE_NEEDS_INIT != buf->state && buf->baddr != b->m.userptr) - q->ops->buf_release(file,buf); + q->ops->buf_release(priv,buf); buf->baddr = b->m.userptr; break; case V4L2_MEMORY_OVERLAY: @@ -631,14 +633,14 @@ videobuf_qbuf(struct file *file, struct videobuf_queue *q, } field = videobuf_next_field(q); - retval = q->ops->buf_prepare(file,buf,field); + retval = q->ops->buf_prepare(priv,buf,field); if (0 != retval) goto done; list_add_tail(&buf->stream,&q->stream); if (q->streaming) { spin_lock_irqsave(q->irqlock,flags); - q->ops->buf_queue(file,buf); + q->ops->buf_queue(priv,buf); spin_unlock_irqrestore(q->irqlock,flags); } retval = 0; @@ -649,8 +651,8 @@ videobuf_qbuf(struct file *file, struct videobuf_queue *q, } int -videobuf_dqbuf(struct file *file, struct videobuf_queue *q, - struct v4l2_buffer *b) +videobuf_dqbuf(void *priv, struct videobuf_queue *q, + struct v4l2_buffer *b, int nonblocking) { struct videobuf_buffer *buf; int retval; @@ -665,7 +667,7 @@ videobuf_dqbuf(struct file *file, struct videobuf_queue *q, if (list_empty(&q->stream)) goto done; buf = list_entry(q->stream.next, struct videobuf_buffer, stream); - retval = videobuf_waiton(buf, file->f_flags & O_NONBLOCK, 1); + retval = videobuf_waiton(buf, nonblocking, 1); if (retval < 0) goto done; switch (buf->state) { @@ -689,7 +691,7 @@ videobuf_dqbuf(struct file *file, struct videobuf_queue *q, return retval; } -int videobuf_streamon(struct file *file, struct videobuf_queue *q) +int videobuf_streamon(void *priv, struct videobuf_queue *q) { struct videobuf_buffer *buf; struct list_head *list; @@ -708,7 +710,7 @@ int videobuf_streamon(struct file *file, struct videobuf_queue *q) list_for_each(list,&q->stream) { buf = list_entry(list, struct videobuf_buffer, stream); if (buf->state == STATE_PREPARED) - q->ops->buf_queue(file,buf); + q->ops->buf_queue(priv,buf); } spin_unlock_irqrestore(q->irqlock,flags); @@ -717,14 +719,14 @@ int videobuf_streamon(struct file *file, struct videobuf_queue *q) return retval; } -int videobuf_streamoff(struct file *file, struct videobuf_queue *q) +int videobuf_streamoff(void *priv, struct videobuf_queue *q) { int retval = -EINVAL; down(&q->lock); if (!q->streaming) goto done; - videobuf_queue_cancel(file,q); + videobuf_queue_cancel(priv,q); q->streaming = 0; retval = 0; @@ -734,7 +736,7 @@ int videobuf_streamoff(struct file *file, struct videobuf_queue *q) } static ssize_t -videobuf_read_zerocopy(struct file *file, struct videobuf_queue *q, +videobuf_read_zerocopy(void *priv, struct videobuf_queue *q, char __user *data, size_t count, loff_t *ppos) { enum v4l2_field field; @@ -751,13 +753,13 @@ videobuf_read_zerocopy(struct file *file, struct videobuf_queue *q, q->read_buf->baddr = (unsigned long)data; q->read_buf->bsize = count; field = videobuf_next_field(q); - retval = q->ops->buf_prepare(file,q->read_buf,field); + retval = q->ops->buf_prepare(priv,q->read_buf,field); if (0 != retval) goto done; /* start capture & wait */ spin_lock_irqsave(q->irqlock,flags); - q->ops->buf_queue(file,q->read_buf); + q->ops->buf_queue(priv,q->read_buf); spin_unlock_irqrestore(q->irqlock,flags); retval = videobuf_waiton(q->read_buf,0,0); if (0 == retval) { @@ -770,14 +772,15 @@ videobuf_read_zerocopy(struct file *file, struct videobuf_queue *q, done: /* cleanup */ - q->ops->buf_release(file,q->read_buf); + q->ops->buf_release(priv,q->read_buf); kfree(q->read_buf); q->read_buf = NULL; return retval; } -ssize_t videobuf_read_one(struct file *file, struct videobuf_queue *q, - char __user *data, size_t count, loff_t *ppos) +ssize_t videobuf_read_one(void *priv, struct videobuf_queue *q, + char __user *data, size_t count, loff_t *ppos, + int nonblocking) { enum v4l2_field field; unsigned long flags; @@ -787,11 +790,11 @@ ssize_t videobuf_read_one(struct file *file, struct videobuf_queue *q, down(&q->lock); nbufs = 1; size = 0; - q->ops->buf_setup(file,&nbufs,&size); + q->ops->buf_setup(priv,&nbufs,&size); if (NULL == q->read_buf && count >= size && - !(file->f_flags & O_NONBLOCK)) { - retval = videobuf_read_zerocopy(file,q,data,count,ppos); + !nonblocking) { + retval = videobuf_read_zerocopy(priv,q,data,count,ppos); if (retval >= 0 || retval == -EIO) /* ok, all done */ goto done; @@ -806,24 +809,24 @@ ssize_t videobuf_read_one(struct file *file, struct videobuf_queue *q, goto done; q->read_buf->memory = V4L2_MEMORY_USERPTR; field = videobuf_next_field(q); - retval = q->ops->buf_prepare(file,q->read_buf,field); + retval = q->ops->buf_prepare(priv,q->read_buf,field); if (0 != retval) goto done; spin_lock_irqsave(q->irqlock,flags); - q->ops->buf_queue(file,q->read_buf); + q->ops->buf_queue(priv,q->read_buf); spin_unlock_irqrestore(q->irqlock,flags); q->read_off = 0; } /* wait until capture is done */ - retval = videobuf_waiton(q->read_buf, file->f_flags & O_NONBLOCK, 1); + retval = videobuf_waiton(q->read_buf, nonblocking, 1); if (0 != retval) goto done; 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); + q->ops->buf_release(priv,q->read_buf); kfree(q->read_buf); q->read_buf = NULL; retval = -EIO; @@ -842,7 +845,7 @@ ssize_t videobuf_read_one(struct file *file, struct videobuf_queue *q, q->read_off += bytes; if (q->read_off == q->read_buf->size) { /* all data copied, cleanup */ - q->ops->buf_release(file,q->read_buf); + q->ops->buf_release(priv,q->read_buf); kfree(q->read_buf); q->read_buf = NULL; } @@ -852,43 +855,43 @@ ssize_t videobuf_read_one(struct file *file, struct videobuf_queue *q, return retval; } -int videobuf_read_start(struct file *file, struct videobuf_queue *q) +int videobuf_read_start(void *priv, struct videobuf_queue *q) { enum v4l2_field field; unsigned long flags; int count = 0, size = 0; int err, i; - q->ops->buf_setup(file,&count,&size); + q->ops->buf_setup(priv,&count,&size); if (count < 2) count = 2; if (count > VIDEO_MAX_FRAME) count = VIDEO_MAX_FRAME; size = PAGE_ALIGN(size); - err = videobuf_mmap_setup(file, q, count, size, V4L2_MEMORY_USERPTR); + err = videobuf_mmap_setup(priv, q, count, size, V4L2_MEMORY_USERPTR); if (err) return err; for (i = 0; i < count; i++) { field = videobuf_next_field(q); - err = q->ops->buf_prepare(file,q->bufs[i],field); + err = q->ops->buf_prepare(priv,q->bufs[i],field); if (err) return err; list_add_tail(&q->bufs[i]->stream, &q->stream); } spin_lock_irqsave(q->irqlock,flags); for (i = 0; i < count; i++) - q->ops->buf_queue(file,q->bufs[i]); + q->ops->buf_queue(priv,q->bufs[i]); spin_unlock_irqrestore(q->irqlock,flags); q->reading = 1; return 0; } -void videobuf_read_stop(struct file *file, struct videobuf_queue *q) +void videobuf_read_stop(void *priv, struct videobuf_queue *q) { int i; - videobuf_queue_cancel(file,q); + videobuf_queue_cancel(priv,q); INIT_LIST_HEAD(&q->stream); for (i = 0; i < VIDEO_MAX_FRAME; i++) { if (NULL == q->bufs[i]) @@ -900,20 +903,21 @@ void videobuf_read_stop(struct file *file, struct videobuf_queue *q) q->reading = 0; } -ssize_t videobuf_read_stream(struct file *file, struct videobuf_queue *q, +ssize_t videobuf_read_stream(void *priv, struct videobuf_queue *q, char __user *data, size_t count, loff_t *ppos, - int vbihack) + int vbihack, int nonblocking) { unsigned int *fc, bytes; int err, retval; unsigned long flags; + dprintk(2,"%s\n",__FUNCTION__); down(&q->lock); retval = -EBUSY; if (q->streaming) goto done; if (!q->reading) { - retval = videobuf_read_start(file,q); + retval = videobuf_read_start(priv,q); if (retval < 0) goto done; } @@ -928,8 +932,7 @@ ssize_t videobuf_read_stream(struct file *file, struct videobuf_queue *q, list_del(&q->read_buf->stream); q->read_off = 0; } - err = videobuf_waiton(q->read_buf, - file->f_flags & O_NONBLOCK,1); + err = videobuf_waiton(q->read_buf, nonblocking, 1); if (err < 0) { if (0 == retval) retval = err; @@ -974,7 +977,7 @@ ssize_t videobuf_read_stream(struct file *file, struct videobuf_queue *q, list_add_tail(&q->read_buf->stream, &q->stream); spin_lock_irqsave(q->irqlock,flags); - q->ops->buf_queue(file,q->read_buf); + q->ops->buf_queue(priv,q->read_buf); spin_unlock_irqrestore(q->irqlock,flags); q->read_buf = NULL; } @@ -987,7 +990,7 @@ ssize_t videobuf_read_stream(struct file *file, struct videobuf_queue *q, return retval; } -unsigned int videobuf_poll_stream(struct file *file, +unsigned int videobuf_poll_stream(struct file *file, void *priv, struct videobuf_queue *q, poll_table *wait) { @@ -1001,7 +1004,7 @@ unsigned int videobuf_poll_stream(struct file *file, struct videobuf_buffer, stream); } else { if (!q->reading) - videobuf_read_start(file,q); + videobuf_read_start(priv,q); if (!q->reading) { rc = POLLERR; } else if (NULL == q->read_buf) { @@ -1100,14 +1103,14 @@ static struct vm_operations_struct videobuf_vm_ops = .nopage = videobuf_vm_nopage, }; -int videobuf_mmap_setup(struct file *file, struct videobuf_queue *q, +int videobuf_mmap_setup(void *priv, struct videobuf_queue *q, unsigned int bcount, unsigned int bsize, enum v4l2_memory memory) { unsigned int i; int err; - err = videobuf_mmap_free(file,q); + err = videobuf_mmap_free(priv,q); if (0 != err) return err; @@ -1132,7 +1135,7 @@ int videobuf_mmap_setup(struct file *file, struct videobuf_queue *q, return 0; } -int videobuf_mmap_free(struct file *file, struct videobuf_queue *q) +int videobuf_mmap_free(void *priv, struct videobuf_queue *q) { int i; @@ -1142,7 +1145,7 @@ int videobuf_mmap_free(struct file *file, struct videobuf_queue *q) for (i = 0; i < VIDEO_MAX_FRAME; i++) { if (NULL == q->bufs[i]) continue; - q->ops->buf_release(file,q->bufs[i]); + q->ops->buf_release(priv,q->bufs[i]); kfree(q->bufs[i]); q->bufs[i] = NULL; } diff --git a/include/media/video-buf.h b/include/media/video-buf.h index 3c17bdf0b7903..3fd4d7db18e30 100644 --- a/include/media/video-buf.h +++ b/include/media/video-buf.h @@ -1,4 +1,6 @@ /* + * $Id: video-buf.h,v 1.7 2004/10/11 14:53:13 kraxel Exp $ + * * generic helper functions for video4linux capture buffers, to handle * memory management and PCI DMA. Right now bttv + saa7134 use it. * @@ -165,12 +167,12 @@ struct videobuf_buffer { }; struct videobuf_queue_ops { - int (*buf_setup)(struct file *file, + int (*buf_setup)(void *priv, unsigned int *count, unsigned int *size); - int (*buf_prepare)(struct file *file,struct videobuf_buffer *vb, + int (*buf_prepare)(void *priv,struct videobuf_buffer *vb, enum v4l2_field field); - void (*buf_queue)(struct file *file,struct videobuf_buffer *vb); - void (*buf_release)(struct file *file,struct videobuf_buffer *vb); + void (*buf_queue)(void *priv,struct videobuf_buffer *vb); + void (*buf_release)(void *priv,struct videobuf_buffer *vb); }; struct videobuf_queue { @@ -208,36 +210,37 @@ void videobuf_queue_init(struct videobuf_queue *q, enum v4l2_field field, unsigned int msize); int videobuf_queue_is_busy(struct videobuf_queue *q); -void videobuf_queue_cancel(struct file *file, struct videobuf_queue *q); +void videobuf_queue_cancel(void *priv, struct videobuf_queue *q); enum v4l2_field videobuf_next_field(struct videobuf_queue *q); void videobuf_status(struct v4l2_buffer *b, struct videobuf_buffer *vb, enum v4l2_buf_type type); -int videobuf_reqbufs(struct file *file, struct videobuf_queue *q, +int videobuf_reqbufs(void *priv, struct videobuf_queue *q, struct v4l2_requestbuffers *req); int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b); -int videobuf_qbuf(struct file *file, struct videobuf_queue *q, +int videobuf_qbuf(void *priv, struct videobuf_queue *q, struct v4l2_buffer *b); -int videobuf_dqbuf(struct file *file, struct videobuf_queue *q, - struct v4l2_buffer *b); -int videobuf_streamon(struct file *file, struct videobuf_queue *q); -int videobuf_streamoff(struct file *file, struct videobuf_queue *q); - -int videobuf_read_start(struct file *file, struct videobuf_queue *q); -void videobuf_read_stop(struct file *file, struct videobuf_queue *q); -ssize_t videobuf_read_stream(struct file *file, struct videobuf_queue *q, +int videobuf_dqbuf(void *priv, struct videobuf_queue *q, + struct v4l2_buffer *b, int nonblocking); +int videobuf_streamon(void *priv, struct videobuf_queue *q); +int videobuf_streamoff(void *priv, struct videobuf_queue *q); + +int videobuf_read_start(void *priv, struct videobuf_queue *q); +void videobuf_read_stop(void *priv, struct videobuf_queue *q); +ssize_t videobuf_read_stream(void *priv, struct videobuf_queue *q, char __user *data, size_t count, loff_t *ppos, - int vbihack); -ssize_t videobuf_read_one(struct file *file, struct videobuf_queue *q, - char __user *data, size_t count, loff_t *ppos); -unsigned int videobuf_poll_stream(struct file *file, + int vbihack, int nonblocking); +ssize_t videobuf_read_one(void *priv, struct videobuf_queue *q, + char __user *data, size_t count, loff_t *ppos, + int nonblocking); +unsigned int videobuf_poll_stream(struct file *file, void *priv, struct videobuf_queue *q, poll_table *wait); -int videobuf_mmap_setup(struct file *file, struct videobuf_queue *q, +int videobuf_mmap_setup(void *priv, struct videobuf_queue *q, unsigned int bcount, unsigned int bsize, enum v4l2_memory memory); -int videobuf_mmap_free(struct file *file, struct videobuf_queue *q); +int videobuf_mmap_free(void *priv, struct videobuf_queue *q); int videobuf_mmap_mapper(struct vm_area_struct *vma, struct videobuf_queue *q); -- 2.53.0