diff options
-rw-r--r-- | drivers/media/v4l2-core/videobuf2-core.c | 39 | ||||
-rw-r--r-- | include/media/videobuf2-core.h | 17 |
2 files changed, 41 insertions, 15 deletions
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 60fbb17cc913..b80fd24debfa 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c | |||
@@ -828,7 +828,7 @@ static int __verify_memory_type(struct vb2_queue *q, | |||
828 | * create_bufs is called with count == 0, but count == 0 should still | 828 | * create_bufs is called with count == 0, but count == 0 should still |
829 | * do the memory and type validation. | 829 | * do the memory and type validation. |
830 | */ | 830 | */ |
831 | if (q->fileio) { | 831 | if (vb2_fileio_is_active(q)) { |
832 | dprintk(1, "file io in progress\n"); | 832 | dprintk(1, "file io in progress\n"); |
833 | return -EBUSY; | 833 | return -EBUSY; |
834 | } | 834 | } |
@@ -1670,7 +1670,7 @@ int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b) | |||
1670 | struct vb2_buffer *vb; | 1670 | struct vb2_buffer *vb; |
1671 | int ret; | 1671 | int ret; |
1672 | 1672 | ||
1673 | if (q->fileio) { | 1673 | if (vb2_fileio_is_active(q)) { |
1674 | dprintk(1, "file io in progress\n"); | 1674 | dprintk(1, "file io in progress\n"); |
1675 | return -EBUSY; | 1675 | return -EBUSY; |
1676 | } | 1676 | } |
@@ -1838,7 +1838,7 @@ static int vb2_internal_qbuf(struct vb2_queue *q, struct v4l2_buffer *b) | |||
1838 | */ | 1838 | */ |
1839 | int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b) | 1839 | int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b) |
1840 | { | 1840 | { |
1841 | if (q->fileio) { | 1841 | if (vb2_fileio_is_active(q)) { |
1842 | dprintk(1, "file io in progress\n"); | 1842 | dprintk(1, "file io in progress\n"); |
1843 | return -EBUSY; | 1843 | return -EBUSY; |
1844 | } | 1844 | } |
@@ -2058,7 +2058,7 @@ static int vb2_internal_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool n | |||
2058 | */ | 2058 | */ |
2059 | int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking) | 2059 | int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking) |
2060 | { | 2060 | { |
2061 | if (q->fileio) { | 2061 | if (vb2_fileio_is_active(q)) { |
2062 | dprintk(1, "file io in progress\n"); | 2062 | dprintk(1, "file io in progress\n"); |
2063 | return -EBUSY; | 2063 | return -EBUSY; |
2064 | } | 2064 | } |
@@ -2188,7 +2188,7 @@ static int vb2_internal_streamon(struct vb2_queue *q, enum v4l2_buf_type type) | |||
2188 | */ | 2188 | */ |
2189 | int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type) | 2189 | int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type) |
2190 | { | 2190 | { |
2191 | if (q->fileio) { | 2191 | if (vb2_fileio_is_active(q)) { |
2192 | dprintk(1, "file io in progress\n"); | 2192 | dprintk(1, "file io in progress\n"); |
2193 | return -EBUSY; | 2193 | return -EBUSY; |
2194 | } | 2194 | } |
@@ -2235,7 +2235,7 @@ static int vb2_internal_streamoff(struct vb2_queue *q, enum v4l2_buf_type type) | |||
2235 | */ | 2235 | */ |
2236 | int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type) | 2236 | int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type) |
2237 | { | 2237 | { |
2238 | if (q->fileio) { | 2238 | if (vb2_fileio_is_active(q)) { |
2239 | dprintk(1, "file io in progress\n"); | 2239 | dprintk(1, "file io in progress\n"); |
2240 | return -EBUSY; | 2240 | return -EBUSY; |
2241 | } | 2241 | } |
@@ -2320,6 +2320,11 @@ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb) | |||
2320 | return -EINVAL; | 2320 | return -EINVAL; |
2321 | } | 2321 | } |
2322 | 2322 | ||
2323 | if (vb2_fileio_is_active(q)) { | ||
2324 | dprintk(1, "expbuf: file io in progress\n"); | ||
2325 | return -EBUSY; | ||
2326 | } | ||
2327 | |||
2323 | vb_plane = &vb->planes[eb->plane]; | 2328 | vb_plane = &vb->planes[eb->plane]; |
2324 | 2329 | ||
2325 | dbuf = call_ptr_memop(vb, get_dmabuf, vb_plane->mem_priv, eb->flags & O_ACCMODE); | 2330 | dbuf = call_ptr_memop(vb, get_dmabuf, vb_plane->mem_priv, eb->flags & O_ACCMODE); |
@@ -2395,6 +2400,10 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma) | |||
2395 | return -EINVAL; | 2400 | return -EINVAL; |
2396 | } | 2401 | } |
2397 | } | 2402 | } |
2403 | if (vb2_fileio_is_active(q)) { | ||
2404 | dprintk(1, "mmap: file io in progress\n"); | ||
2405 | return -EBUSY; | ||
2406 | } | ||
2398 | 2407 | ||
2399 | /* | 2408 | /* |
2400 | * Find the plane corresponding to the offset passed by userspace. | 2409 | * Find the plane corresponding to the offset passed by userspace. |
@@ -2504,7 +2513,7 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait) | |||
2504 | /* | 2513 | /* |
2505 | * Start file I/O emulator only if streaming API has not been used yet. | 2514 | * Start file I/O emulator only if streaming API has not been used yet. |
2506 | */ | 2515 | */ |
2507 | if (q->num_buffers == 0 && q->fileio == NULL) { | 2516 | if (q->num_buffers == 0 && !vb2_fileio_is_active(q)) { |
2508 | if (!V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_READ) && | 2517 | if (!V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_READ) && |
2509 | (req_events & (POLLIN | POLLRDNORM))) { | 2518 | (req_events & (POLLIN | POLLRDNORM))) { |
2510 | if (__vb2_init_fileio(q, 1)) | 2519 | if (__vb2_init_fileio(q, 1)) |
@@ -2709,7 +2718,8 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read) | |||
2709 | fileio->req.count = count; | 2718 | fileio->req.count = count; |
2710 | fileio->req.memory = V4L2_MEMORY_MMAP; | 2719 | fileio->req.memory = V4L2_MEMORY_MMAP; |
2711 | fileio->req.type = q->type; | 2720 | fileio->req.type = q->type; |
2712 | ret = vb2_reqbufs(q, &fileio->req); | 2721 | q->fileio = fileio; |
2722 | ret = __reqbufs(q, &fileio->req); | ||
2713 | if (ret) | 2723 | if (ret) |
2714 | goto err_kfree; | 2724 | goto err_kfree; |
2715 | 2725 | ||
@@ -2747,7 +2757,7 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read) | |||
2747 | b->type = q->type; | 2757 | b->type = q->type; |
2748 | b->memory = q->memory; | 2758 | b->memory = q->memory; |
2749 | b->index = i; | 2759 | b->index = i; |
2750 | ret = vb2_qbuf(q, b); | 2760 | ret = vb2_internal_qbuf(q, b); |
2751 | if (ret) | 2761 | if (ret) |
2752 | goto err_reqbufs; | 2762 | goto err_reqbufs; |
2753 | fileio->bufs[i].queued = 1; | 2763 | fileio->bufs[i].queued = 1; |
@@ -2763,19 +2773,18 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read) | |||
2763 | /* | 2773 | /* |
2764 | * Start streaming. | 2774 | * Start streaming. |
2765 | */ | 2775 | */ |
2766 | ret = vb2_streamon(q, q->type); | 2776 | ret = vb2_internal_streamon(q, q->type); |
2767 | if (ret) | 2777 | if (ret) |
2768 | goto err_reqbufs; | 2778 | goto err_reqbufs; |
2769 | 2779 | ||
2770 | q->fileio = fileio; | ||
2771 | |||
2772 | return ret; | 2780 | return ret; |
2773 | 2781 | ||
2774 | err_reqbufs: | 2782 | err_reqbufs: |
2775 | fileio->req.count = 0; | 2783 | fileio->req.count = 0; |
2776 | vb2_reqbufs(q, &fileio->req); | 2784 | __reqbufs(q, &fileio->req); |
2777 | 2785 | ||
2778 | err_kfree: | 2786 | err_kfree: |
2787 | q->fileio = NULL; | ||
2779 | kfree(fileio); | 2788 | kfree(fileio); |
2780 | return ret; | 2789 | return ret; |
2781 | } | 2790 | } |
@@ -2833,7 +2842,7 @@ static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_ | |||
2833 | /* | 2842 | /* |
2834 | * Initialize emulator on first call. | 2843 | * Initialize emulator on first call. |
2835 | */ | 2844 | */ |
2836 | if (!q->fileio) { | 2845 | if (!vb2_fileio_is_active(q)) { |
2837 | ret = __vb2_init_fileio(q, read); | 2846 | ret = __vb2_init_fileio(q, read); |
2838 | dprintk(3, "vb2_init_fileio result: %d\n", ret); | 2847 | dprintk(3, "vb2_init_fileio result: %d\n", ret); |
2839 | if (ret) | 2848 | if (ret) |
@@ -3201,7 +3210,7 @@ unsigned int vb2_fop_poll(struct file *file, poll_table *wait) | |||
3201 | 3210 | ||
3202 | /* Try to be smart: only lock if polling might start fileio, | 3211 | /* Try to be smart: only lock if polling might start fileio, |
3203 | otherwise locking will only introduce unwanted delays. */ | 3212 | otherwise locking will only introduce unwanted delays. */ |
3204 | if (q->num_buffers == 0 && q->fileio == NULL) { | 3213 | if (q->num_buffers == 0 && !vb2_fileio_is_active(q)) { |
3205 | if (!V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_READ) && | 3214 | if (!V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_READ) && |
3206 | (req_events & (POLLIN | POLLRDNORM))) | 3215 | (req_events & (POLLIN | POLLRDNORM))) |
3207 | must_lock = true; | 3216 | must_lock = true; |
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index af4621109726..b1859f6953b2 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h | |||
@@ -472,6 +472,23 @@ static inline bool vb2_is_streaming(struct vb2_queue *q) | |||
472 | } | 472 | } |
473 | 473 | ||
474 | /** | 474 | /** |
475 | * vb2_fileio_is_active() - return true if fileio is active. | ||
476 | * @q: videobuf queue | ||
477 | * | ||
478 | * This returns true if read() or write() is used to stream the data | ||
479 | * as opposed to stream I/O. This is almost never an important distinction, | ||
480 | * except in rare cases. One such case is that using read() or write() to | ||
481 | * stream a format using V4L2_FIELD_ALTERNATE is not allowed since there | ||
482 | * is no way you can pass the field information of each buffer to/from | ||
483 | * userspace. A driver that supports this field format should check for | ||
484 | * this in the queue_setup op and reject it if this function returns true. | ||
485 | */ | ||
486 | static inline bool vb2_fileio_is_active(struct vb2_queue *q) | ||
487 | { | ||
488 | return q->fileio; | ||
489 | } | ||
490 | |||
491 | /** | ||
475 | * vb2_is_busy() - return busy status of the queue | 492 | * vb2_is_busy() - return busy status of the queue |
476 | * @q: videobuf queue | 493 | * @q: videobuf queue |
477 | * | 494 | * |