]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/media/video/videobuf-core.c
V4L/DVB (6600): V4L: videobuf: don't chew up namespace STATE_.*, convert to VIDEOBUF_
[linux-2.6-omap-h63xx.git] / drivers / media / video / videobuf-core.c
index 89a44f16f0ba50892be204f19f66c576cf46a2e1..26d1a5001738a8d301e59b3d6e8172de2bf7704e 100644 (file)
@@ -68,14 +68,14 @@ int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr)
 
        MAGIC_CHECK(vb->magic,MAGIC_BUFFER);
        add_wait_queue(&vb->done, &wait);
-       while (vb->state == STATE_ACTIVE || vb->state == STATE_QUEUED) {
+       while (vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) {
                if (non_blocking) {
                        retval = -EAGAIN;
                        break;
                }
                set_current_state(intr  ? TASK_INTERRUPTIBLE
                                        : TASK_UNINTERRUPTIBLE);
-               if (vb->state == STATE_ACTIVE || vb->state == STATE_QUEUED)
+               if (vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED)
                        schedule();
                set_current_state(TASK_RUNNING);
                if (intr && signal_pending(current)) {
@@ -141,6 +141,7 @@ void videobuf_queue_core_init(struct videobuf_queue* q,
        INIT_LIST_HEAD(&q->stream);
 }
 
+/* Locking: Only usage in bttv unsafe find way to remove */
 int videobuf_queue_is_busy(struct videobuf_queue *q)
 {
        int i;
@@ -166,11 +167,11 @@ int videobuf_queue_is_busy(struct videobuf_queue *q)
                        dprintk(1,"busy: buffer #%d mapped\n",i);
                        return 1;
                }
-               if (q->bufs[i]->state == STATE_QUEUED) {
+               if (q->bufs[i]->state == VIDEOBUF_QUEUED) {
                        dprintk(1,"busy: buffer #%d queued\n",i);
                        return 1;
                }
-               if (q->bufs[i]->state == STATE_ACTIVE) {
+               if (q->bufs[i]->state == VIDEOBUF_ACTIVE) {
                        dprintk(1,"busy: buffer #%d avtive\n",i);
                        return 1;
                }
@@ -178,6 +179,7 @@ int videobuf_queue_is_busy(struct videobuf_queue *q)
        return 0;
 }
 
+/* Locking: Caller holds q->lock */
 void videobuf_queue_cancel(struct videobuf_queue *q)
 {
        unsigned long flags=0;
@@ -189,9 +191,9 @@ void videobuf_queue_cancel(struct videobuf_queue *q)
        for (i = 0; i < VIDEO_MAX_FRAME; i++) {
                if (NULL == q->bufs[i])
                        continue;
-               if (q->bufs[i]->state == STATE_QUEUED) {
+               if (q->bufs[i]->state == VIDEOBUF_QUEUED) {
                        list_del(&q->bufs[i]->queue);
-                       q->bufs[i]->state = STATE_ERROR;
+                       q->bufs[i]->state = VIDEOBUF_ERROR;
                }
        }
        if (q->irqlock)
@@ -208,6 +210,7 @@ void videobuf_queue_cancel(struct videobuf_queue *q)
 
 /* --------------------------------------------------------------------- */
 
+/* Locking: Caller holds q->lock */
 enum v4l2_field videobuf_next_field(struct videobuf_queue *q)
 {
        enum v4l2_field field = q->field;
@@ -226,6 +229,7 @@ enum v4l2_field videobuf_next_field(struct videobuf_queue *q)
        return field;
 }
 
+/* Locking: Caller holds q->lock */
 static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b,
                            struct videobuf_buffer *vb, enum v4l2_buf_type type)
 {
@@ -255,17 +259,17 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b,
                b->flags |= V4L2_BUF_FLAG_MAPPED;
 
        switch (vb->state) {
-       case STATE_PREPARED:
-       case STATE_QUEUED:
-       case STATE_ACTIVE:
+       case VIDEOBUF_PREPARED:
+       case VIDEOBUF_QUEUED:
+       case VIDEOBUF_ACTIVE:
                b->flags |= V4L2_BUF_FLAG_QUEUED;
                break;
-       case STATE_DONE:
-       case STATE_ERROR:
+       case VIDEOBUF_DONE:
+       case VIDEOBUF_ERROR:
                b->flags |= V4L2_BUF_FLAG_DONE;
                break;
-       case STATE_NEEDS_INIT:
-       case STATE_IDLE:
+       case VIDEOBUF_NEEDS_INIT:
+       case VIDEOBUF_IDLE:
                /* nothing */
                break;
        }
@@ -281,20 +285,108 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b,
        b->sequence  = vb->field_count >> 1;
 }
 
+/* Locking: Caller holds q->lock */
+static int __videobuf_mmap_free(struct videobuf_queue *q)
+{
+       int i;
+       int rc;
+
+       if (!q)
+               return 0;
+
+       MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
+
+       rc  = CALL(q,mmap_free,q);
+       if (rc<0)
+               return rc;
+
+       for (i = 0; i < VIDEO_MAX_FRAME; i++) {
+               if (NULL == q->bufs[i])
+                       continue;
+               q->ops->buf_release(q,q->bufs[i]);
+               kfree(q->bufs[i]);
+               q->bufs[i] = NULL;
+       }
+
+       return rc;
+}
+
+int videobuf_mmap_free(struct videobuf_queue *q)
+{
+       int ret;
+       mutex_lock(&q->lock);
+       ret = __videobuf_mmap_free(q);
+       mutex_unlock(&q->lock);
+       return ret;
+}
+
+/* Locking: Caller holds q->lock */
+static int __videobuf_mmap_setup(struct videobuf_queue *q,
+                       unsigned int bcount, unsigned int bsize,
+                       enum v4l2_memory memory)
+{
+       unsigned int i;
+       int err;
+
+       MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
+
+       err = __videobuf_mmap_free(q);
+       if (0 != err)
+               return err;
+
+       /* Allocate and initialize buffers */
+       for (i = 0; i < bcount; i++) {
+               q->bufs[i] = videobuf_alloc(q);
+
+               if (q->bufs[i] == NULL)
+                       break;
+
+               q->bufs[i]->i      = i;
+               q->bufs[i]->input  = UNSET;
+               q->bufs[i]->memory = memory;
+               q->bufs[i]->bsize  = bsize;
+               switch (memory) {
+               case V4L2_MEMORY_MMAP:
+                       q->bufs[i]->boff  = bsize * i;
+                       break;
+               case V4L2_MEMORY_USERPTR:
+               case V4L2_MEMORY_OVERLAY:
+                       /* nothing */
+                       break;
+               }
+       }
+
+       if (!i)
+               return -ENOMEM;
+
+       dprintk(1,"mmap setup: %d buffers, %d bytes each\n",
+               i, bsize);
+
+       return i;
+}
+
+int videobuf_mmap_setup(struct videobuf_queue *q,
+                       unsigned int bcount, unsigned int bsize,
+                       enum v4l2_memory memory)
+{
+       int ret;
+       mutex_lock(&q->lock);
+       ret = __videobuf_mmap_setup(q, bcount, bsize, memory);
+       mutex_unlock(&q->lock);
+       return ret;
+}
+
 int videobuf_reqbufs(struct videobuf_queue *q,
                 struct v4l2_requestbuffers *req)
 {
        unsigned int size,count;
        int retval;
 
-       if (req->type != q->type) {
-               dprintk(1,"reqbufs: queue type invalid\n");
-               return -EINVAL;
-       }
        if (req->count < 1) {
                dprintk(1,"reqbufs: count invalid (%d)\n",req->count);
                return -EINVAL;
        }
+
        if (req->memory != V4L2_MEMORY_MMAP     &&
            req->memory != V4L2_MEMORY_USERPTR  &&
            req->memory != V4L2_MEMORY_OVERLAY) {
@@ -303,6 +395,12 @@ int videobuf_reqbufs(struct videobuf_queue *q,
        }
 
        mutex_lock(&q->lock);
+       if (req->type != q->type) {
+               dprintk(1,"reqbufs: queue type invalid\n");
+               retval = -EINVAL;
+               goto done;
+       }
+
        if (q->streaming) {
                dprintk(1,"reqbufs: streaming already exists\n");
                retval = -EBUSY;
@@ -323,7 +421,7 @@ int videobuf_reqbufs(struct videobuf_queue *q,
        dprintk(1,"reqbufs: bufs=%d, size=0x%x [%d pages total]\n",
                count, size, (count*size)>>PAGE_SHIFT);
 
-       retval = videobuf_mmap_setup(q,count,size,req->memory);
+       retval = __videobuf_mmap_setup(q,count,size,req->memory);
        if (retval < 0) {
                dprintk(1,"reqbufs: mmap setup returned %d\n",retval);
                goto done;
@@ -338,20 +436,28 @@ int videobuf_reqbufs(struct videobuf_queue *q,
 
 int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b)
 {
+       int ret = -EINVAL;
+
+       mutex_lock(&q->lock);
        if (unlikely(b->type != q->type)) {
                dprintk(1,"querybuf: Wrong type.\n");
-               return -EINVAL;
+               goto done;
        }
        if (unlikely(b->index < 0 || b->index >= VIDEO_MAX_FRAME)) {
                dprintk(1,"querybuf: index out of range.\n");
-               return -EINVAL;
+               goto done;
        }
        if (unlikely(NULL == q->bufs[b->index])) {
                dprintk(1,"querybuf: buffer is null.\n");
-               return -EINVAL;
+               goto done;
        }
+
        videobuf_status(q,b,q->bufs[b->index],q->type);
-       return 0;
+
+       ret = 0;
+done:
+       mutex_unlock(&q->lock);
+       return ret;
 }
 
 int videobuf_qbuf(struct videobuf_queue *q,
@@ -392,7 +498,7 @@ int videobuf_qbuf(struct videobuf_queue *q,
                dprintk(1,"qbuf: memory type is wrong.\n");
                goto done;
        }
-       if (buf->state != STATE_NEEDS_INIT && buf->state != STATE_IDLE) {
+       if (buf->state != VIDEOBUF_NEEDS_INIT && buf->state != VIDEOBUF_IDLE) {
                dprintk(1,"qbuf: buffer is already queued or active.\n");
                goto done;
        }
@@ -419,7 +525,7 @@ int videobuf_qbuf(struct videobuf_queue *q,
                        dprintk(1,"qbuf: buffer length is not enough\n");
                        goto done;
                }
-               if (STATE_NEEDS_INIT != buf->state && buf->baddr != b->m.userptr)
+               if (VIDEOBUF_NEEDS_INIT != buf->state && buf->baddr != b->m.userptr)
                        q->ops->buf_release(q,buf);
                buf->baddr = b->m.userptr;
                break;
@@ -489,16 +595,16 @@ int videobuf_dqbuf(struct videobuf_queue *q,
                goto done;
        }
        switch (buf->state) {
-       case STATE_ERROR:
+       case VIDEOBUF_ERROR:
                dprintk(1,"dqbuf: state is error\n");
                retval = -EIO;
                CALL(q,sync,q, buf);
-               buf->state = STATE_IDLE;
+               buf->state = VIDEOBUF_IDLE;
                break;
-       case STATE_DONE:
+       case VIDEOBUF_DONE:
                dprintk(1,"dqbuf: state is done\n");
                CALL(q,sync,q, buf);
-               buf->state = STATE_IDLE;
+               buf->state = VIDEOBUF_IDLE;
                break;
        default:
                dprintk(1,"dqbuf: state invalid\n");
@@ -531,7 +637,7 @@ int videobuf_streamon(struct videobuf_queue *q)
        if (q->irqlock)
                spin_lock_irqsave(q->irqlock,flags);
        list_for_each_entry(buf, &q->stream, stream)
-               if (buf->state == STATE_PREPARED)
+               if (buf->state == VIDEOBUF_PREPARED)
                        q->ops->buf_queue(q,buf);
        if (q->irqlock)
                spin_unlock_irqrestore(q->irqlock,flags);
@@ -541,22 +647,30 @@ int videobuf_streamon(struct videobuf_queue *q)
        return retval;
 }
 
-int videobuf_streamoff(struct videobuf_queue *q)
+/* Locking: Caller holds q->lock */
+static int __videobuf_streamoff(struct videobuf_queue *q)
 {
-       int retval = -EINVAL;
-
-       mutex_lock(&q->lock);
        if (!q->streaming)
-               goto done;
+               return -EINVAL;
+
        videobuf_queue_cancel(q);
        q->streaming = 0;
-       retval = 0;
 
- done:
+       return 0;
+}
+
+int videobuf_streamoff(struct videobuf_queue *q)
+{
+       int retval;
+
+       mutex_lock(&q->lock);
+       retval = __videobuf_streamoff(q);
        mutex_unlock(&q->lock);
+
        return retval;
 }
 
+/* Locking: Caller holds q->lock */
 static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q,
                                      char __user *data,
                                      size_t count, loff_t *ppos)
@@ -590,7 +704,7 @@ static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q,
        retval = videobuf_waiton(q->read_buf,0,0);
        if (0 == retval) {
                CALL(q,sync,q,q->read_buf);
-               if (STATE_ERROR == q->read_buf->state)
+               if (VIDEOBUF_ERROR == q->read_buf->state)
                        retval = -EIO;
                else
                        retval = q->read_buf->size;
@@ -664,7 +778,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
 
        CALL(q,sync,q,q->read_buf);
 
-       if (STATE_ERROR == q->read_buf->state) {
+       if (VIDEOBUF_ERROR == q->read_buf->state) {
                /* catch I/O errors */
                q->ops->buf_release(q,q->read_buf);
                kfree(q->read_buf);
@@ -691,7 +805,8 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
        return retval;
 }
 
-int videobuf_read_start(struct videobuf_queue *q)
+/* Locking: Caller holds q->lock */
+int __videobuf_read_start(struct videobuf_queue *q)
 {
        enum v4l2_field field;
        unsigned long flags=0;
@@ -705,7 +820,7 @@ int videobuf_read_start(struct videobuf_queue *q)
                count = VIDEO_MAX_FRAME;
        size = PAGE_ALIGN(size);
 
-       err = videobuf_mmap_setup(q, count, size, V4L2_MEMORY_USERPTR);
+       err = __videobuf_mmap_setup(q, count, size, V4L2_MEMORY_USERPTR);
        if (err < 0)
                return err;
 
@@ -728,12 +843,13 @@ int videobuf_read_start(struct videobuf_queue *q)
        return 0;
 }
 
-void videobuf_read_stop(struct videobuf_queue *q)
+static void __videobuf_read_stop(struct videobuf_queue *q)
 {
        int i;
 
+
        videobuf_queue_cancel(q);
-       videobuf_mmap_free(q);
+       __videobuf_mmap_free(q);
        INIT_LIST_HEAD(&q->stream);
        for (i = 0; i < VIDEO_MAX_FRAME; i++) {
                if (NULL == q->bufs[i])
@@ -743,8 +859,41 @@ void videobuf_read_stop(struct videobuf_queue *q)
        }
        q->read_buf = NULL;
        q->reading  = 0;
+       
 }
 
+int videobuf_read_start(struct videobuf_queue *q)
+{
+       int rc;
+
+       mutex_lock(&q->lock);
+       rc = __videobuf_read_start(q);
+       mutex_unlock(&q->lock);
+
+       return rc;
+}
+
+void videobuf_read_stop(struct videobuf_queue *q)
+{
+       mutex_lock(&q->lock);
+       __videobuf_read_stop(q);
+       mutex_unlock(&q->lock);
+}
+
+void videobuf_stop(struct videobuf_queue *q)
+{
+       mutex_lock(&q->lock);
+
+       if (q->streaming)
+               __videobuf_streamoff(q);
+
+       if (q->reading)
+               __videobuf_read_stop(q);
+
+       mutex_unlock(&q->lock);
+}
+
+
 ssize_t videobuf_read_stream(struct videobuf_queue *q,
                             char __user *data, size_t count, loff_t *ppos,
                             int vbihack, int nonblocking)
@@ -760,7 +909,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q,
        if (q->streaming)
                goto done;
        if (!q->reading) {
-               retval = videobuf_read_start(q);
+               retval = __videobuf_read_start(q);
                if (retval < 0)
                        goto done;
        }
@@ -782,7 +931,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q,
                        break;
                }
 
-               if (q->read_buf->state == STATE_DONE) {
+               if (q->read_buf->state == VIDEOBUF_DONE) {
                        rc = CALL (q,copy_stream, q, data + retval, count,
                                        retval, vbihack, nonblocking);
                        if (rc < 0) {
@@ -833,7 +982,7 @@ unsigned int videobuf_poll_stream(struct file *file,
                                         struct videobuf_buffer, stream);
        } else {
                if (!q->reading)
-                       videobuf_read_start(q);
+                       __videobuf_read_start(q);
                if (!q->reading) {
                        rc = POLLERR;
                } else if (NULL == q->read_buf) {
@@ -850,83 +999,14 @@ unsigned int videobuf_poll_stream(struct file *file,
 
        if (0 == rc) {
                poll_wait(file, &buf->done, wait);
-               if (buf->state == STATE_DONE ||
-                   buf->state == STATE_ERROR)
+               if (buf->state == VIDEOBUF_DONE ||
+                   buf->state == VIDEOBUF_ERROR)
                        rc = POLLIN|POLLRDNORM;
        }
        mutex_unlock(&q->lock);
        return rc;
 }
 
-int videobuf_mmap_setup(struct videobuf_queue *q,
-                       unsigned int bcount, unsigned int bsize,
-                       enum v4l2_memory memory)
-{
-       unsigned int i;
-       int err;
-
-       MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
-
-       err = videobuf_mmap_free(q);
-       if (0 != err)
-               return err;
-
-       /* Allocate and initialize buffers */
-       for (i = 0; i < bcount; i++) {
-               q->bufs[i] = videobuf_alloc(q);
-
-               if (q->bufs[i] == NULL)
-                       break;
-
-               q->bufs[i]->i      = i;
-               q->bufs[i]->input  = UNSET;
-               q->bufs[i]->memory = memory;
-               q->bufs[i]->bsize  = bsize;
-               switch (memory) {
-               case V4L2_MEMORY_MMAP:
-                       q->bufs[i]->boff  = bsize * i;
-                       break;
-               case V4L2_MEMORY_USERPTR:
-               case V4L2_MEMORY_OVERLAY:
-                       /* nothing */
-                       break;
-               }
-       }
-
-       if (!i)
-               return -ENOMEM;
-
-       dprintk(1,"mmap setup: %d buffers, %d bytes each\n",
-               i, bsize);
-
-       return i;
-}
-
-int videobuf_mmap_free(struct videobuf_queue *q)
-{
-       int i;
-       int rc;
-
-       if (!q)
-               return 0;
-
-       MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS);
-
-       rc  = CALL(q,mmap_free,q);
-       if (rc<0)
-               return rc;
-
-       for (i = 0; i < VIDEO_MAX_FRAME; i++) {
-               if (NULL == q->bufs[i])
-                       continue;
-               q->ops->buf_release(q,q->bufs[i]);
-               kfree(q->bufs[i]);
-               q->bufs[i] = NULL;
-       }
-
-       return rc;
-}
-
 int videobuf_mmap_mapper(struct videobuf_queue *q,
                         struct vm_area_struct *vma)
 {
@@ -991,6 +1071,7 @@ EXPORT_SYMBOL_GPL(videobuf_streamoff);
 
 EXPORT_SYMBOL_GPL(videobuf_read_start);
 EXPORT_SYMBOL_GPL(videobuf_read_stop);
+EXPORT_SYMBOL_GPL(videobuf_stop);
 EXPORT_SYMBOL_GPL(videobuf_read_stream);
 EXPORT_SYMBOL_GPL(videobuf_read_one);
 EXPORT_SYMBOL_GPL(videobuf_poll_stream);