diff options
| author | Brandon Philips <brandon@ifup.org> | 2007-11-13 18:05:38 -0500 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-12-11 15:08:08 -0500 |
| commit | 19bc5133dae9562e8824ef101464061f9854c1d8 (patch) | |
| tree | 8395e2da25f3cf5291e24f972d31a215ddf421a5 | |
| parent | 63337dd3f5506628e4831b08e39e09d7f1407769 (diff) | |
V4L/DVB (6601): V4L: videobuf-core locking fixes and comments
- Add comments to functions that require that caller hold q->lock
- Add __videobuf_mmap_free that doesn't hold q->lock for use within videobuf
- Add locking to videobuf_mmap_free
- Fix linux/drivers/media/common/saa7146_video.c which was holding lock around
videobuf_read_stop
- Add locking to functions that operate on a queue
- Add videobuf_stop to take care of stopping in both the read and stream case
TODO: bttv still has an unsafe call to videobuf_queue_is_busy
Signed-off-by: Brandon Philips <bphilips@suse.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
| -rw-r--r-- | drivers/media/common/saa7146_video.c | 5 | ||||
| -rw-r--r-- | drivers/media/video/videobuf-core.c | 247 | ||||
| -rw-r--r-- | include/media/videobuf-core.h | 2 |
3 files changed, 161 insertions, 93 deletions
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c index f245a3b2ef47..7cc4213ba56b 100644 --- a/drivers/media/common/saa7146_video.c +++ b/drivers/media/common/saa7146_video.c | |||
| @@ -1440,10 +1440,7 @@ static void video_close(struct saa7146_dev *dev, struct file *file) | |||
| 1440 | err = saa7146_stop_preview(fh); | 1440 | err = saa7146_stop_preview(fh); |
| 1441 | } | 1441 | } |
| 1442 | 1442 | ||
| 1443 | // release all capture buffers | 1443 | videobuf_stop(q); |
| 1444 | mutex_lock(&q->lock); | ||
| 1445 | videobuf_read_stop(q); | ||
| 1446 | mutex_unlock(&q->lock); | ||
| 1447 | 1444 | ||
| 1448 | /* hmm, why is this function declared void? */ | 1445 | /* hmm, why is this function declared void? */ |
| 1449 | /* return err */ | 1446 | /* return err */ |
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c index 89a44f16f0ba..de2f56b19163 100644 --- a/drivers/media/video/videobuf-core.c +++ b/drivers/media/video/videobuf-core.c | |||
| @@ -141,6 +141,7 @@ void videobuf_queue_core_init(struct videobuf_queue* q, | |||
| 141 | INIT_LIST_HEAD(&q->stream); | 141 | INIT_LIST_HEAD(&q->stream); |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | /* Locking: Only usage in bttv unsafe find way to remove */ | ||
| 144 | int videobuf_queue_is_busy(struct videobuf_queue *q) | 145 | int videobuf_queue_is_busy(struct videobuf_queue *q) |
| 145 | { | 146 | { |
| 146 | int i; | 147 | int i; |
| @@ -178,6 +179,7 @@ int videobuf_queue_is_busy(struct videobuf_queue *q) | |||
| 178 | return 0; | 179 | return 0; |
| 179 | } | 180 | } |
| 180 | 181 | ||
| 182 | /* Locking: Caller holds q->lock */ | ||
| 181 | void videobuf_queue_cancel(struct videobuf_queue *q) | 183 | void videobuf_queue_cancel(struct videobuf_queue *q) |
| 182 | { | 184 | { |
| 183 | unsigned long flags=0; | 185 | unsigned long flags=0; |
| @@ -208,6 +210,7 @@ void videobuf_queue_cancel(struct videobuf_queue *q) | |||
| 208 | 210 | ||
| 209 | /* --------------------------------------------------------------------- */ | 211 | /* --------------------------------------------------------------------- */ |
| 210 | 212 | ||
| 213 | /* Locking: Caller holds q->lock */ | ||
| 211 | enum v4l2_field videobuf_next_field(struct videobuf_queue *q) | 214 | enum v4l2_field videobuf_next_field(struct videobuf_queue *q) |
| 212 | { | 215 | { |
| 213 | enum v4l2_field field = q->field; | 216 | enum v4l2_field field = q->field; |
| @@ -226,6 +229,7 @@ enum v4l2_field videobuf_next_field(struct videobuf_queue *q) | |||
| 226 | return field; | 229 | return field; |
| 227 | } | 230 | } |
| 228 | 231 | ||
| 232 | /* Locking: Caller holds q->lock */ | ||
| 229 | static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b, | 233 | static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b, |
| 230 | struct videobuf_buffer *vb, enum v4l2_buf_type type) | 234 | struct videobuf_buffer *vb, enum v4l2_buf_type type) |
| 231 | { | 235 | { |
| @@ -281,20 +285,108 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b, | |||
| 281 | b->sequence = vb->field_count >> 1; | 285 | b->sequence = vb->field_count >> 1; |
| 282 | } | 286 | } |
| 283 | 287 | ||
| 288 | /* Locking: Caller holds q->lock */ | ||
| 289 | static int __videobuf_mmap_free(struct videobuf_queue *q) | ||
| 290 | { | ||
| 291 | int i; | ||
| 292 | int rc; | ||
| 293 | |||
| 294 | if (!q) | ||
| 295 | return 0; | ||
| 296 | |||
| 297 | MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS); | ||
| 298 | |||
| 299 | rc = CALL(q,mmap_free,q); | ||
| 300 | if (rc<0) | ||
| 301 | return rc; | ||
| 302 | |||
| 303 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { | ||
| 304 | if (NULL == q->bufs[i]) | ||
| 305 | continue; | ||
| 306 | q->ops->buf_release(q,q->bufs[i]); | ||
| 307 | kfree(q->bufs[i]); | ||
| 308 | q->bufs[i] = NULL; | ||
| 309 | } | ||
| 310 | |||
| 311 | return rc; | ||
| 312 | } | ||
| 313 | |||
| 314 | int videobuf_mmap_free(struct videobuf_queue *q) | ||
| 315 | { | ||
| 316 | int ret; | ||
| 317 | mutex_lock(&q->lock); | ||
| 318 | ret = __videobuf_mmap_free(q); | ||
| 319 | mutex_unlock(&q->lock); | ||
| 320 | return ret; | ||
| 321 | } | ||
| 322 | |||
| 323 | /* Locking: Caller holds q->lock */ | ||
| 324 | static int __videobuf_mmap_setup(struct videobuf_queue *q, | ||
| 325 | unsigned int bcount, unsigned int bsize, | ||
| 326 | enum v4l2_memory memory) | ||
| 327 | { | ||
| 328 | unsigned int i; | ||
| 329 | int err; | ||
| 330 | |||
| 331 | MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS); | ||
| 332 | |||
| 333 | err = __videobuf_mmap_free(q); | ||
| 334 | if (0 != err) | ||
| 335 | return err; | ||
| 336 | |||
| 337 | /* Allocate and initialize buffers */ | ||
| 338 | for (i = 0; i < bcount; i++) { | ||
| 339 | q->bufs[i] = videobuf_alloc(q); | ||
| 340 | |||
| 341 | if (q->bufs[i] == NULL) | ||
| 342 | break; | ||
| 343 | |||
| 344 | q->bufs[i]->i = i; | ||
| 345 | q->bufs[i]->input = UNSET; | ||
| 346 | q->bufs[i]->memory = memory; | ||
| 347 | q->bufs[i]->bsize = bsize; | ||
| 348 | switch (memory) { | ||
| 349 | case V4L2_MEMORY_MMAP: | ||
| 350 | q->bufs[i]->boff = bsize * i; | ||
| 351 | break; | ||
| 352 | case V4L2_MEMORY_USERPTR: | ||
| 353 | case V4L2_MEMORY_OVERLAY: | ||
| 354 | /* nothing */ | ||
| 355 | break; | ||
| 356 | } | ||
| 357 | } | ||
| 358 | |||
| 359 | if (!i) | ||
| 360 | return -ENOMEM; | ||
| 361 | |||
| 362 | dprintk(1,"mmap setup: %d buffers, %d bytes each\n", | ||
| 363 | i, bsize); | ||
| 364 | |||
| 365 | return i; | ||
| 366 | } | ||
| 367 | |||
| 368 | int videobuf_mmap_setup(struct videobuf_queue *q, | ||
| 369 | unsigned int bcount, unsigned int bsize, | ||
| 370 | enum v4l2_memory memory) | ||
| 371 | { | ||
| 372 | int ret; | ||
| 373 | mutex_lock(&q->lock); | ||
| 374 | ret = __videobuf_mmap_setup(q, bcount, bsize, memory); | ||
| 375 | mutex_unlock(&q->lock); | ||
| 376 | return ret; | ||
| 377 | } | ||
| 378 | |||
| 284 | int videobuf_reqbufs(struct videobuf_queue *q, | 379 | int videobuf_reqbufs(struct videobuf_queue *q, |
| 285 | struct v4l2_requestbuffers *req) | 380 | struct v4l2_requestbuffers *req) |
| 286 | { | 381 | { |
| 287 | unsigned int size,count; | 382 | unsigned int size,count; |
| 288 | int retval; | 383 | int retval; |
| 289 | 384 | ||
| 290 | if (req->type != q->type) { | ||
| 291 | dprintk(1,"reqbufs: queue type invalid\n"); | ||
| 292 | return -EINVAL; | ||
| 293 | } | ||
| 294 | if (req->count < 1) { | 385 | if (req->count < 1) { |
| 295 | dprintk(1,"reqbufs: count invalid (%d)\n",req->count); | 386 | dprintk(1,"reqbufs: count invalid (%d)\n",req->count); |
| 296 | return -EINVAL; | 387 | return -EINVAL; |
| 297 | } | 388 | } |
| 389 | |||
| 298 | if (req->memory != V4L2_MEMORY_MMAP && | 390 | if (req->memory != V4L2_MEMORY_MMAP && |
| 299 | req->memory != V4L2_MEMORY_USERPTR && | 391 | req->memory != V4L2_MEMORY_USERPTR && |
| 300 | req->memory != V4L2_MEMORY_OVERLAY) { | 392 | req->memory != V4L2_MEMORY_OVERLAY) { |
| @@ -303,6 +395,12 @@ int videobuf_reqbufs(struct videobuf_queue *q, | |||
| 303 | } | 395 | } |
| 304 | 396 | ||
| 305 | mutex_lock(&q->lock); | 397 | mutex_lock(&q->lock); |
| 398 | if (req->type != q->type) { | ||
| 399 | dprintk(1,"reqbufs: queue type invalid\n"); | ||
| 400 | retval = -EINVAL; | ||
| 401 | goto done; | ||
| 402 | } | ||
| 403 | |||
| 306 | if (q->streaming) { | 404 | if (q->streaming) { |
| 307 | dprintk(1,"reqbufs: streaming already exists\n"); | 405 | dprintk(1,"reqbufs: streaming already exists\n"); |
| 308 | retval = -EBUSY; | 406 | retval = -EBUSY; |
| @@ -323,7 +421,7 @@ int videobuf_reqbufs(struct videobuf_queue *q, | |||
| 323 | dprintk(1,"reqbufs: bufs=%d, size=0x%x [%d pages total]\n", | 421 | dprintk(1,"reqbufs: bufs=%d, size=0x%x [%d pages total]\n", |
| 324 | count, size, (count*size)>>PAGE_SHIFT); | 422 | count, size, (count*size)>>PAGE_SHIFT); |
| 325 | 423 | ||
| 326 | retval = videobuf_mmap_setup(q,count,size,req->memory); | 424 | retval = __videobuf_mmap_setup(q,count,size,req->memory); |
| 327 | if (retval < 0) { | 425 | if (retval < 0) { |
| 328 | dprintk(1,"reqbufs: mmap setup returned %d\n",retval); | 426 | dprintk(1,"reqbufs: mmap setup returned %d\n",retval); |
| 329 | goto done; | 427 | goto done; |
| @@ -338,20 +436,28 @@ int videobuf_reqbufs(struct videobuf_queue *q, | |||
| 338 | 436 | ||
| 339 | int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b) | 437 | int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b) |
| 340 | { | 438 | { |
| 439 | int ret = -EINVAL; | ||
| 440 | |||
| 441 | mutex_lock(&q->lock); | ||
| 341 | if (unlikely(b->type != q->type)) { | 442 | if (unlikely(b->type != q->type)) { |
| 342 | dprintk(1,"querybuf: Wrong type.\n"); | 443 | dprintk(1,"querybuf: Wrong type.\n"); |
| 343 | return -EINVAL; | 444 | goto done; |
| 344 | } | 445 | } |
| 345 | if (unlikely(b->index < 0 || b->index >= VIDEO_MAX_FRAME)) { | 446 | if (unlikely(b->index < 0 || b->index >= VIDEO_MAX_FRAME)) { |
| 346 | dprintk(1,"querybuf: index out of range.\n"); | 447 | dprintk(1,"querybuf: index out of range.\n"); |
| 347 | return -EINVAL; | 448 | goto done; |
| 348 | } | 449 | } |
| 349 | if (unlikely(NULL == q->bufs[b->index])) { | 450 | if (unlikely(NULL == q->bufs[b->index])) { |
| 350 | dprintk(1,"querybuf: buffer is null.\n"); | 451 | dprintk(1,"querybuf: buffer is null.\n"); |
| 351 | return -EINVAL; | 452 | goto done; |
| 352 | } | 453 | } |
| 454 | |||
| 353 | videobuf_status(q,b,q->bufs[b->index],q->type); | 455 | videobuf_status(q,b,q->bufs[b->index],q->type); |
| 354 | return 0; | 456 | |
| 457 | ret = 0; | ||
| 458 | done: | ||
| 459 | mutex_unlock(&q->lock); | ||
| 460 | return ret; | ||
| 355 | } | 461 | } |
| 356 | 462 | ||
| 357 | int videobuf_qbuf(struct videobuf_queue *q, | 463 | int videobuf_qbuf(struct videobuf_queue *q, |
| @@ -541,22 +647,30 @@ int videobuf_streamon(struct videobuf_queue *q) | |||
| 541 | return retval; | 647 | return retval; |
| 542 | } | 648 | } |
| 543 | 649 | ||
| 544 | int videobuf_streamoff(struct videobuf_queue *q) | 650 | /* Locking: Caller holds q->lock */ |
| 651 | static int __videobuf_streamoff(struct videobuf_queue *q) | ||
| 545 | { | 652 | { |
| 546 | int retval = -EINVAL; | ||
| 547 | |||
| 548 | mutex_lock(&q->lock); | ||
| 549 | if (!q->streaming) | 653 | if (!q->streaming) |
| 550 | goto done; | 654 | return -EINVAL; |
| 655 | |||
| 551 | videobuf_queue_cancel(q); | 656 | videobuf_queue_cancel(q); |
| 552 | q->streaming = 0; | 657 | q->streaming = 0; |
| 553 | retval = 0; | ||
| 554 | 658 | ||
| 555 | done: | 659 | return 0; |
| 660 | } | ||
| 661 | |||
| 662 | int videobuf_streamoff(struct videobuf_queue *q) | ||
| 663 | { | ||
| 664 | int retval; | ||
| 665 | |||
| 666 | mutex_lock(&q->lock); | ||
| 667 | retval = __videobuf_streamoff(q); | ||
| 556 | mutex_unlock(&q->lock); | 668 | mutex_unlock(&q->lock); |
| 669 | |||
| 557 | return retval; | 670 | return retval; |
| 558 | } | 671 | } |
| 559 | 672 | ||
| 673 | /* Locking: Caller holds q->lock */ | ||
| 560 | static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q, | 674 | static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q, |
| 561 | char __user *data, | 675 | char __user *data, |
| 562 | size_t count, loff_t *ppos) | 676 | size_t count, loff_t *ppos) |
| @@ -691,6 +805,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q, | |||
| 691 | return retval; | 805 | return retval; |
| 692 | } | 806 | } |
| 693 | 807 | ||
| 808 | /* Locking: Caller holds q->lock */ | ||
| 694 | int videobuf_read_start(struct videobuf_queue *q) | 809 | int videobuf_read_start(struct videobuf_queue *q) |
| 695 | { | 810 | { |
| 696 | enum v4l2_field field; | 811 | enum v4l2_field field; |
| @@ -705,7 +820,7 @@ int videobuf_read_start(struct videobuf_queue *q) | |||
| 705 | count = VIDEO_MAX_FRAME; | 820 | count = VIDEO_MAX_FRAME; |
| 706 | size = PAGE_ALIGN(size); | 821 | size = PAGE_ALIGN(size); |
| 707 | 822 | ||
| 708 | err = videobuf_mmap_setup(q, count, size, V4L2_MEMORY_USERPTR); | 823 | err = __videobuf_mmap_setup(q, count, size, V4L2_MEMORY_USERPTR); |
| 709 | if (err < 0) | 824 | if (err < 0) |
| 710 | return err; | 825 | return err; |
| 711 | 826 | ||
| @@ -728,12 +843,13 @@ int videobuf_read_start(struct videobuf_queue *q) | |||
| 728 | return 0; | 843 | return 0; |
| 729 | } | 844 | } |
| 730 | 845 | ||
| 731 | void videobuf_read_stop(struct videobuf_queue *q) | 846 | static void __videobuf_read_stop(struct videobuf_queue *q) |
| 732 | { | 847 | { |
| 733 | int i; | 848 | int i; |
| 734 | 849 | ||
| 850 | |||
| 735 | videobuf_queue_cancel(q); | 851 | videobuf_queue_cancel(q); |
| 736 | videobuf_mmap_free(q); | 852 | __videobuf_mmap_free(q); |
| 737 | INIT_LIST_HEAD(&q->stream); | 853 | INIT_LIST_HEAD(&q->stream); |
| 738 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { | 854 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { |
| 739 | if (NULL == q->bufs[i]) | 855 | if (NULL == q->bufs[i]) |
| @@ -743,8 +859,30 @@ void videobuf_read_stop(struct videobuf_queue *q) | |||
| 743 | } | 859 | } |
| 744 | q->read_buf = NULL; | 860 | q->read_buf = NULL; |
| 745 | q->reading = 0; | 861 | q->reading = 0; |
| 862 | |||
| 863 | } | ||
| 864 | |||
| 865 | void videobuf_read_stop(struct videobuf_queue *q) | ||
| 866 | { | ||
| 867 | mutex_lock(&q->lock); | ||
| 868 | __videobuf_read_stop(q); | ||
| 869 | mutex_unlock(&q->lock); | ||
| 870 | } | ||
| 871 | |||
| 872 | void videobuf_stop(struct videobuf_queue *q) | ||
| 873 | { | ||
| 874 | mutex_lock(&q->lock); | ||
| 875 | |||
| 876 | if (q->streaming) | ||
| 877 | __videobuf_streamoff(q); | ||
| 878 | |||
| 879 | if (q->reading) | ||
| 880 | __videobuf_read_stop(q); | ||
| 881 | |||
| 882 | mutex_unlock(&q->lock); | ||
| 746 | } | 883 | } |
| 747 | 884 | ||
| 885 | |||
| 748 | ssize_t videobuf_read_stream(struct videobuf_queue *q, | 886 | ssize_t videobuf_read_stream(struct videobuf_queue *q, |
| 749 | char __user *data, size_t count, loff_t *ppos, | 887 | char __user *data, size_t count, loff_t *ppos, |
| 750 | int vbihack, int nonblocking) | 888 | int vbihack, int nonblocking) |
| @@ -858,75 +996,6 @@ unsigned int videobuf_poll_stream(struct file *file, | |||
| 858 | return rc; | 996 | return rc; |
| 859 | } | 997 | } |
| 860 | 998 | ||
| 861 | int videobuf_mmap_setup(struct videobuf_queue *q, | ||
| 862 | unsigned int bcount, unsigned int bsize, | ||
| 863 | enum v4l2_memory memory) | ||
| 864 | { | ||
| 865 | unsigned int i; | ||
| 866 | int err; | ||
| 867 | |||
| 868 | MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS); | ||
| 869 | |||
| 870 | err = videobuf_mmap_free(q); | ||
| 871 | if (0 != err) | ||
| 872 | return err; | ||
| 873 | |||
| 874 | /* Allocate and initialize buffers */ | ||
| 875 | for (i = 0; i < bcount; i++) { | ||
| 876 | q->bufs[i] = videobuf_alloc(q); | ||
| 877 | |||
| 878 | if (q->bufs[i] == NULL) | ||
| 879 | break; | ||
| 880 | |||
| 881 | q->bufs[i]->i = i; | ||
| 882 | q->bufs[i]->input = UNSET; | ||
| 883 | q->bufs[i]->memory = memory; | ||
| 884 | q->bufs[i]->bsize = bsize; | ||
| 885 | switch (memory) { | ||
| 886 | case V4L2_MEMORY_MMAP: | ||
| 887 | q->bufs[i]->boff = bsize * i; | ||
| 888 | break; | ||
| 889 | case V4L2_MEMORY_USERPTR: | ||
| 890 | case V4L2_MEMORY_OVERLAY: | ||
| 891 | /* nothing */ | ||
| 892 | break; | ||
| 893 | } | ||
| 894 | } | ||
| 895 | |||
| 896 | if (!i) | ||
| 897 | return -ENOMEM; | ||
| 898 | |||
| 899 | dprintk(1,"mmap setup: %d buffers, %d bytes each\n", | ||
| 900 | i, bsize); | ||
| 901 | |||
| 902 | return i; | ||
| 903 | } | ||
| 904 | |||
| 905 | int videobuf_mmap_free(struct videobuf_queue *q) | ||
| 906 | { | ||
| 907 | int i; | ||
| 908 | int rc; | ||
| 909 | |||
| 910 | if (!q) | ||
| 911 | return 0; | ||
| 912 | |||
| 913 | MAGIC_CHECK(q->int_ops->magic,MAGIC_QTYPE_OPS); | ||
| 914 | |||
| 915 | rc = CALL(q,mmap_free,q); | ||
| 916 | if (rc<0) | ||
| 917 | return rc; | ||
| 918 | |||
| 919 | for (i = 0; i < VIDEO_MAX_FRAME; i++) { | ||
| 920 | if (NULL == q->bufs[i]) | ||
| 921 | continue; | ||
| 922 | q->ops->buf_release(q,q->bufs[i]); | ||
| 923 | kfree(q->bufs[i]); | ||
| 924 | q->bufs[i] = NULL; | ||
| 925 | } | ||
| 926 | |||
| 927 | return rc; | ||
| 928 | } | ||
| 929 | |||
| 930 | int videobuf_mmap_mapper(struct videobuf_queue *q, | 999 | int videobuf_mmap_mapper(struct videobuf_queue *q, |
| 931 | struct vm_area_struct *vma) | 1000 | struct vm_area_struct *vma) |
| 932 | { | 1001 | { |
| @@ -989,8 +1058,8 @@ EXPORT_SYMBOL_GPL(videobuf_dqbuf); | |||
| 989 | EXPORT_SYMBOL_GPL(videobuf_streamon); | 1058 | EXPORT_SYMBOL_GPL(videobuf_streamon); |
| 990 | EXPORT_SYMBOL_GPL(videobuf_streamoff); | 1059 | EXPORT_SYMBOL_GPL(videobuf_streamoff); |
| 991 | 1060 | ||
| 992 | EXPORT_SYMBOL_GPL(videobuf_read_start); | ||
| 993 | EXPORT_SYMBOL_GPL(videobuf_read_stop); | 1061 | EXPORT_SYMBOL_GPL(videobuf_read_stop); |
| 1062 | EXPORT_SYMBOL_GPL(videobuf_stop); | ||
| 994 | EXPORT_SYMBOL_GPL(videobuf_read_stream); | 1063 | EXPORT_SYMBOL_GPL(videobuf_read_stream); |
| 995 | EXPORT_SYMBOL_GPL(videobuf_read_one); | 1064 | EXPORT_SYMBOL_GPL(videobuf_read_one); |
| 996 | EXPORT_SYMBOL_GPL(videobuf_poll_stream); | 1065 | EXPORT_SYMBOL_GPL(videobuf_poll_stream); |
diff --git a/include/media/videobuf-core.h b/include/media/videobuf-core.h index 0fa5d5912555..4fd5d0eaa935 100644 --- a/include/media/videobuf-core.h +++ b/include/media/videobuf-core.h | |||
| @@ -208,6 +208,8 @@ int videobuf_cgmbuf(struct videobuf_queue *q, | |||
| 208 | int videobuf_streamon(struct videobuf_queue *q); | 208 | int videobuf_streamon(struct videobuf_queue *q); |
| 209 | int videobuf_streamoff(struct videobuf_queue *q); | 209 | int videobuf_streamoff(struct videobuf_queue *q); |
| 210 | 210 | ||
| 211 | void videobuf_stop(struct videobuf_queue *q); | ||
| 212 | |||
| 211 | int videobuf_read_start(struct videobuf_queue *q); | 213 | int videobuf_read_start(struct videobuf_queue *q); |
| 212 | void videobuf_read_stop(struct videobuf_queue *q); | 214 | void videobuf_read_stop(struct videobuf_queue *q); |
| 213 | ssize_t videobuf_read_stream(struct videobuf_queue *q, | 215 | ssize_t videobuf_read_stream(struct videobuf_queue *q, |
