diff options
Diffstat (limited to 'drivers/media/video/v4l2-dev.c')
| -rw-r--r-- | drivers/media/video/v4l2-dev.c | 218 |
1 files changed, 203 insertions, 15 deletions
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 70bec548d904..5ccbd4629f9c 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c | |||
| @@ -274,11 +274,12 @@ static ssize_t v4l2_read(struct file *filp, char __user *buf, | |||
| 274 | 274 | ||
| 275 | if (!vdev->fops->read) | 275 | if (!vdev->fops->read) |
| 276 | return -EINVAL; | 276 | return -EINVAL; |
| 277 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) | 277 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) && |
| 278 | mutex_lock_interruptible(vdev->lock)) | ||
| 278 | return -ERESTARTSYS; | 279 | return -ERESTARTSYS; |
| 279 | if (video_is_registered(vdev)) | 280 | if (video_is_registered(vdev)) |
| 280 | ret = vdev->fops->read(filp, buf, sz, off); | 281 | ret = vdev->fops->read(filp, buf, sz, off); |
| 281 | if (vdev->lock) | 282 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) |
| 282 | mutex_unlock(vdev->lock); | 283 | mutex_unlock(vdev->lock); |
| 283 | return ret; | 284 | return ret; |
| 284 | } | 285 | } |
| @@ -291,11 +292,12 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf, | |||
| 291 | 292 | ||
| 292 | if (!vdev->fops->write) | 293 | if (!vdev->fops->write) |
| 293 | return -EINVAL; | 294 | return -EINVAL; |
| 294 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) | 295 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) && |
| 296 | mutex_lock_interruptible(vdev->lock)) | ||
| 295 | return -ERESTARTSYS; | 297 | return -ERESTARTSYS; |
| 296 | if (video_is_registered(vdev)) | 298 | if (video_is_registered(vdev)) |
| 297 | ret = vdev->fops->write(filp, buf, sz, off); | 299 | ret = vdev->fops->write(filp, buf, sz, off); |
| 298 | if (vdev->lock) | 300 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) |
| 299 | mutex_unlock(vdev->lock); | 301 | mutex_unlock(vdev->lock); |
| 300 | return ret; | 302 | return ret; |
| 301 | } | 303 | } |
| @@ -307,11 +309,11 @@ static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll) | |||
| 307 | 309 | ||
| 308 | if (!vdev->fops->poll) | 310 | if (!vdev->fops->poll) |
| 309 | return DEFAULT_POLLMASK; | 311 | return DEFAULT_POLLMASK; |
| 310 | if (vdev->lock) | 312 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) |
| 311 | mutex_lock(vdev->lock); | 313 | mutex_lock(vdev->lock); |
| 312 | if (video_is_registered(vdev)) | 314 | if (video_is_registered(vdev)) |
| 313 | ret = vdev->fops->poll(filp, poll); | 315 | ret = vdev->fops->poll(filp, poll); |
| 314 | if (vdev->lock) | 316 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) |
| 315 | mutex_unlock(vdev->lock); | 317 | mutex_unlock(vdev->lock); |
| 316 | return ret; | 318 | return ret; |
| 317 | } | 319 | } |
| @@ -322,11 +324,19 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
| 322 | int ret = -ENODEV; | 324 | int ret = -ENODEV; |
| 323 | 325 | ||
| 324 | if (vdev->fops->unlocked_ioctl) { | 326 | if (vdev->fops->unlocked_ioctl) { |
| 325 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) | 327 | bool locked = false; |
| 326 | return -ERESTARTSYS; | 328 | |
| 329 | if (vdev->lock) { | ||
| 330 | /* always lock unless the cmd is marked as "don't use lock" */ | ||
| 331 | locked = !v4l2_is_known_ioctl(cmd) || | ||
| 332 | !test_bit(_IOC_NR(cmd), vdev->disable_locking); | ||
| 333 | |||
| 334 | if (locked && mutex_lock_interruptible(vdev->lock)) | ||
| 335 | return -ERESTARTSYS; | ||
| 336 | } | ||
| 327 | if (video_is_registered(vdev)) | 337 | if (video_is_registered(vdev)) |
| 328 | ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); | 338 | ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); |
| 329 | if (vdev->lock) | 339 | if (locked) |
| 330 | mutex_unlock(vdev->lock); | 340 | mutex_unlock(vdev->lock); |
| 331 | } else if (vdev->fops->ioctl) { | 341 | } else if (vdev->fops->ioctl) { |
| 332 | /* This code path is a replacement for the BKL. It is a major | 342 | /* This code path is a replacement for the BKL. It is a major |
| @@ -391,11 +401,12 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm) | |||
| 391 | 401 | ||
| 392 | if (!vdev->fops->mmap) | 402 | if (!vdev->fops->mmap) |
| 393 | return ret; | 403 | return ret; |
| 394 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) | 404 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) && |
| 405 | mutex_lock_interruptible(vdev->lock)) | ||
| 395 | return -ERESTARTSYS; | 406 | return -ERESTARTSYS; |
| 396 | if (video_is_registered(vdev)) | 407 | if (video_is_registered(vdev)) |
| 397 | ret = vdev->fops->mmap(filp, vm); | 408 | ret = vdev->fops->mmap(filp, vm); |
| 398 | if (vdev->lock) | 409 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) |
| 399 | mutex_unlock(vdev->lock); | 410 | mutex_unlock(vdev->lock); |
| 400 | return ret; | 411 | return ret; |
| 401 | } | 412 | } |
| @@ -418,7 +429,8 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
| 418 | video_get(vdev); | 429 | video_get(vdev); |
| 419 | mutex_unlock(&videodev_lock); | 430 | mutex_unlock(&videodev_lock); |
| 420 | if (vdev->fops->open) { | 431 | if (vdev->fops->open) { |
| 421 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) { | 432 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) && |
| 433 | mutex_lock_interruptible(vdev->lock)) { | ||
| 422 | ret = -ERESTARTSYS; | 434 | ret = -ERESTARTSYS; |
| 423 | goto err; | 435 | goto err; |
| 424 | } | 436 | } |
| @@ -426,7 +438,7 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
| 426 | ret = vdev->fops->open(filp); | 438 | ret = vdev->fops->open(filp); |
| 427 | else | 439 | else |
| 428 | ret = -ENODEV; | 440 | ret = -ENODEV; |
| 429 | if (vdev->lock) | 441 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) |
| 430 | mutex_unlock(vdev->lock); | 442 | mutex_unlock(vdev->lock); |
| 431 | } | 443 | } |
| 432 | 444 | ||
| @@ -444,10 +456,10 @@ static int v4l2_release(struct inode *inode, struct file *filp) | |||
| 444 | int ret = 0; | 456 | int ret = 0; |
| 445 | 457 | ||
| 446 | if (vdev->fops->release) { | 458 | if (vdev->fops->release) { |
| 447 | if (vdev->lock) | 459 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) |
| 448 | mutex_lock(vdev->lock); | 460 | mutex_lock(vdev->lock); |
| 449 | vdev->fops->release(filp); | 461 | vdev->fops->release(filp); |
| 450 | if (vdev->lock) | 462 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) |
| 451 | mutex_unlock(vdev->lock); | 463 | mutex_unlock(vdev->lock); |
| 452 | } | 464 | } |
| 453 | /* decrease the refcount unconditionally since the release() | 465 | /* decrease the refcount unconditionally since the release() |
| @@ -508,6 +520,175 @@ static int get_index(struct video_device *vdev) | |||
| 508 | return find_first_zero_bit(used, VIDEO_NUM_DEVICES); | 520 | return find_first_zero_bit(used, VIDEO_NUM_DEVICES); |
| 509 | } | 521 | } |
| 510 | 522 | ||
| 523 | #define SET_VALID_IOCTL(ops, cmd, op) \ | ||
| 524 | if (ops->op) \ | ||
| 525 | set_bit(_IOC_NR(cmd), valid_ioctls) | ||
| 526 | |||
| 527 | /* This determines which ioctls are actually implemented in the driver. | ||
| 528 | It's a one-time thing which simplifies video_ioctl2 as it can just do | ||
| 529 | a bit test. | ||
| 530 | |||
| 531 | Note that drivers can override this by setting bits to 1 in | ||
| 532 | vdev->valid_ioctls. If an ioctl is marked as 1 when this function is | ||
| 533 | called, then that ioctl will actually be marked as unimplemented. | ||
| 534 | |||
| 535 | It does that by first setting up the local valid_ioctls bitmap, and | ||
| 536 | at the end do a: | ||
| 537 | |||
| 538 | vdev->valid_ioctls = valid_ioctls & ~(vdev->valid_ioctls) | ||
| 539 | */ | ||
| 540 | static void determine_valid_ioctls(struct video_device *vdev) | ||
| 541 | { | ||
| 542 | DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE); | ||
| 543 | const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops; | ||
| 544 | |||
| 545 | bitmap_zero(valid_ioctls, BASE_VIDIOC_PRIVATE); | ||
| 546 | |||
| 547 | SET_VALID_IOCTL(ops, VIDIOC_QUERYCAP, vidioc_querycap); | ||
| 548 | if (ops->vidioc_g_priority || | ||
| 549 | test_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags)) | ||
| 550 | set_bit(_IOC_NR(VIDIOC_G_PRIORITY), valid_ioctls); | ||
| 551 | if (ops->vidioc_s_priority || | ||
| 552 | test_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags)) | ||
| 553 | set_bit(_IOC_NR(VIDIOC_S_PRIORITY), valid_ioctls); | ||
| 554 | if (ops->vidioc_enum_fmt_vid_cap || | ||
| 555 | ops->vidioc_enum_fmt_vid_out || | ||
| 556 | ops->vidioc_enum_fmt_vid_cap_mplane || | ||
| 557 | ops->vidioc_enum_fmt_vid_out_mplane || | ||
| 558 | ops->vidioc_enum_fmt_vid_overlay || | ||
| 559 | ops->vidioc_enum_fmt_type_private) | ||
| 560 | set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls); | ||
| 561 | if (ops->vidioc_g_fmt_vid_cap || | ||
| 562 | ops->vidioc_g_fmt_vid_out || | ||
| 563 | ops->vidioc_g_fmt_vid_cap_mplane || | ||
| 564 | ops->vidioc_g_fmt_vid_out_mplane || | ||
| 565 | ops->vidioc_g_fmt_vid_overlay || | ||
| 566 | ops->vidioc_g_fmt_vbi_cap || | ||
| 567 | ops->vidioc_g_fmt_vid_out_overlay || | ||
| 568 | ops->vidioc_g_fmt_vbi_out || | ||
| 569 | ops->vidioc_g_fmt_sliced_vbi_cap || | ||
| 570 | ops->vidioc_g_fmt_sliced_vbi_out || | ||
| 571 | ops->vidioc_g_fmt_type_private) | ||
| 572 | set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls); | ||
| 573 | if (ops->vidioc_s_fmt_vid_cap || | ||
| 574 | ops->vidioc_s_fmt_vid_out || | ||
| 575 | ops->vidioc_s_fmt_vid_cap_mplane || | ||
| 576 | ops->vidioc_s_fmt_vid_out_mplane || | ||
| 577 | ops->vidioc_s_fmt_vid_overlay || | ||
| 578 | ops->vidioc_s_fmt_vbi_cap || | ||
| 579 | ops->vidioc_s_fmt_vid_out_overlay || | ||
| 580 | ops->vidioc_s_fmt_vbi_out || | ||
| 581 | ops->vidioc_s_fmt_sliced_vbi_cap || | ||
| 582 | ops->vidioc_s_fmt_sliced_vbi_out || | ||
| 583 | ops->vidioc_s_fmt_type_private) | ||
| 584 | set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls); | ||
| 585 | if (ops->vidioc_try_fmt_vid_cap || | ||
| 586 | ops->vidioc_try_fmt_vid_out || | ||
| 587 | ops->vidioc_try_fmt_vid_cap_mplane || | ||
| 588 | ops->vidioc_try_fmt_vid_out_mplane || | ||
| 589 | ops->vidioc_try_fmt_vid_overlay || | ||
| 590 | ops->vidioc_try_fmt_vbi_cap || | ||
| 591 | ops->vidioc_try_fmt_vid_out_overlay || | ||
| 592 | ops->vidioc_try_fmt_vbi_out || | ||
| 593 | ops->vidioc_try_fmt_sliced_vbi_cap || | ||
| 594 | ops->vidioc_try_fmt_sliced_vbi_out || | ||
| 595 | ops->vidioc_try_fmt_type_private) | ||
| 596 | set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls); | ||
| 597 | SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs); | ||
| 598 | SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf); | ||
| 599 | SET_VALID_IOCTL(ops, VIDIOC_QBUF, vidioc_qbuf); | ||
| 600 | SET_VALID_IOCTL(ops, VIDIOC_DQBUF, vidioc_dqbuf); | ||
| 601 | SET_VALID_IOCTL(ops, VIDIOC_OVERLAY, vidioc_overlay); | ||
| 602 | SET_VALID_IOCTL(ops, VIDIOC_G_FBUF, vidioc_g_fbuf); | ||
| 603 | SET_VALID_IOCTL(ops, VIDIOC_S_FBUF, vidioc_s_fbuf); | ||
| 604 | SET_VALID_IOCTL(ops, VIDIOC_STREAMON, vidioc_streamon); | ||
| 605 | SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff); | ||
| 606 | if (vdev->tvnorms) | ||
| 607 | set_bit(_IOC_NR(VIDIOC_ENUMSTD), valid_ioctls); | ||
| 608 | if (ops->vidioc_g_std || vdev->current_norm) | ||
| 609 | set_bit(_IOC_NR(VIDIOC_G_STD), valid_ioctls); | ||
| 610 | SET_VALID_IOCTL(ops, VIDIOC_S_STD, vidioc_s_std); | ||
| 611 | SET_VALID_IOCTL(ops, VIDIOC_QUERYSTD, vidioc_querystd); | ||
| 612 | SET_VALID_IOCTL(ops, VIDIOC_ENUMINPUT, vidioc_enum_input); | ||
| 613 | SET_VALID_IOCTL(ops, VIDIOC_G_INPUT, vidioc_g_input); | ||
| 614 | SET_VALID_IOCTL(ops, VIDIOC_S_INPUT, vidioc_s_input); | ||
| 615 | SET_VALID_IOCTL(ops, VIDIOC_ENUMOUTPUT, vidioc_enum_output); | ||
| 616 | SET_VALID_IOCTL(ops, VIDIOC_G_OUTPUT, vidioc_g_output); | ||
| 617 | SET_VALID_IOCTL(ops, VIDIOC_S_OUTPUT, vidioc_s_output); | ||
| 618 | /* Note: the control handler can also be passed through the filehandle, | ||
| 619 | and that can't be tested here. If the bit for these control ioctls | ||
| 620 | is set, then the ioctl is valid. But if it is 0, then it can still | ||
| 621 | be valid if the filehandle passed the control handler. */ | ||
| 622 | if (vdev->ctrl_handler || ops->vidioc_queryctrl) | ||
| 623 | set_bit(_IOC_NR(VIDIOC_QUERYCTRL), valid_ioctls); | ||
| 624 | if (vdev->ctrl_handler || ops->vidioc_g_ctrl || ops->vidioc_g_ext_ctrls) | ||
| 625 | set_bit(_IOC_NR(VIDIOC_G_CTRL), valid_ioctls); | ||
| 626 | if (vdev->ctrl_handler || ops->vidioc_s_ctrl || ops->vidioc_s_ext_ctrls) | ||
| 627 | set_bit(_IOC_NR(VIDIOC_S_CTRL), valid_ioctls); | ||
| 628 | if (vdev->ctrl_handler || ops->vidioc_g_ext_ctrls) | ||
| 629 | set_bit(_IOC_NR(VIDIOC_G_EXT_CTRLS), valid_ioctls); | ||
| 630 | if (vdev->ctrl_handler || ops->vidioc_s_ext_ctrls) | ||
| 631 | set_bit(_IOC_NR(VIDIOC_S_EXT_CTRLS), valid_ioctls); | ||
| 632 | if (vdev->ctrl_handler || ops->vidioc_try_ext_ctrls) | ||
| 633 | set_bit(_IOC_NR(VIDIOC_TRY_EXT_CTRLS), valid_ioctls); | ||
| 634 | if (vdev->ctrl_handler || ops->vidioc_querymenu) | ||
| 635 | set_bit(_IOC_NR(VIDIOC_QUERYMENU), valid_ioctls); | ||
| 636 | SET_VALID_IOCTL(ops, VIDIOC_ENUMAUDIO, vidioc_enumaudio); | ||
| 637 | SET_VALID_IOCTL(ops, VIDIOC_G_AUDIO, vidioc_g_audio); | ||
| 638 | SET_VALID_IOCTL(ops, VIDIOC_S_AUDIO, vidioc_s_audio); | ||
| 639 | SET_VALID_IOCTL(ops, VIDIOC_ENUMAUDOUT, vidioc_enumaudout); | ||
| 640 | SET_VALID_IOCTL(ops, VIDIOC_G_AUDOUT, vidioc_g_audout); | ||
| 641 | SET_VALID_IOCTL(ops, VIDIOC_S_AUDOUT, vidioc_s_audout); | ||
| 642 | SET_VALID_IOCTL(ops, VIDIOC_G_MODULATOR, vidioc_g_modulator); | ||
| 643 | SET_VALID_IOCTL(ops, VIDIOC_S_MODULATOR, vidioc_s_modulator); | ||
| 644 | if (ops->vidioc_g_crop || ops->vidioc_g_selection) | ||
| 645 | set_bit(_IOC_NR(VIDIOC_G_CROP), valid_ioctls); | ||
| 646 | if (ops->vidioc_s_crop || ops->vidioc_s_selection) | ||
| 647 | set_bit(_IOC_NR(VIDIOC_S_CROP), valid_ioctls); | ||
| 648 | SET_VALID_IOCTL(ops, VIDIOC_G_SELECTION, vidioc_g_selection); | ||
| 649 | SET_VALID_IOCTL(ops, VIDIOC_S_SELECTION, vidioc_s_selection); | ||
| 650 | if (ops->vidioc_cropcap || ops->vidioc_g_selection) | ||
| 651 | set_bit(_IOC_NR(VIDIOC_CROPCAP), valid_ioctls); | ||
| 652 | SET_VALID_IOCTL(ops, VIDIOC_G_JPEGCOMP, vidioc_g_jpegcomp); | ||
| 653 | SET_VALID_IOCTL(ops, VIDIOC_S_JPEGCOMP, vidioc_s_jpegcomp); | ||
| 654 | SET_VALID_IOCTL(ops, VIDIOC_G_ENC_INDEX, vidioc_g_enc_index); | ||
| 655 | SET_VALID_IOCTL(ops, VIDIOC_ENCODER_CMD, vidioc_encoder_cmd); | ||
| 656 | SET_VALID_IOCTL(ops, VIDIOC_TRY_ENCODER_CMD, vidioc_try_encoder_cmd); | ||
| 657 | SET_VALID_IOCTL(ops, VIDIOC_DECODER_CMD, vidioc_decoder_cmd); | ||
| 658 | SET_VALID_IOCTL(ops, VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd); | ||
| 659 | if (ops->vidioc_g_parm || vdev->current_norm) | ||
| 660 | set_bit(_IOC_NR(VIDIOC_G_PARM), valid_ioctls); | ||
| 661 | SET_VALID_IOCTL(ops, VIDIOC_S_PARM, vidioc_s_parm); | ||
| 662 | SET_VALID_IOCTL(ops, VIDIOC_G_TUNER, vidioc_g_tuner); | ||
| 663 | SET_VALID_IOCTL(ops, VIDIOC_S_TUNER, vidioc_s_tuner); | ||
| 664 | SET_VALID_IOCTL(ops, VIDIOC_G_FREQUENCY, vidioc_g_frequency); | ||
| 665 | SET_VALID_IOCTL(ops, VIDIOC_S_FREQUENCY, vidioc_s_frequency); | ||
| 666 | SET_VALID_IOCTL(ops, VIDIOC_G_SLICED_VBI_CAP, vidioc_g_sliced_vbi_cap); | ||
| 667 | SET_VALID_IOCTL(ops, VIDIOC_LOG_STATUS, vidioc_log_status); | ||
| 668 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
| 669 | SET_VALID_IOCTL(ops, VIDIOC_DBG_G_REGISTER, vidioc_g_register); | ||
| 670 | SET_VALID_IOCTL(ops, VIDIOC_DBG_S_REGISTER, vidioc_s_register); | ||
| 671 | #endif | ||
| 672 | SET_VALID_IOCTL(ops, VIDIOC_DBG_G_CHIP_IDENT, vidioc_g_chip_ident); | ||
| 673 | SET_VALID_IOCTL(ops, VIDIOC_S_HW_FREQ_SEEK, vidioc_s_hw_freq_seek); | ||
| 674 | SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMESIZES, vidioc_enum_framesizes); | ||
| 675 | SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMEINTERVALS, vidioc_enum_frameintervals); | ||
| 676 | SET_VALID_IOCTL(ops, VIDIOC_ENUM_DV_PRESETS, vidioc_enum_dv_presets); | ||
| 677 | SET_VALID_IOCTL(ops, VIDIOC_S_DV_PRESET, vidioc_s_dv_preset); | ||
| 678 | SET_VALID_IOCTL(ops, VIDIOC_G_DV_PRESET, vidioc_g_dv_preset); | ||
| 679 | SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_PRESET, vidioc_query_dv_preset); | ||
| 680 | SET_VALID_IOCTL(ops, VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings); | ||
| 681 | SET_VALID_IOCTL(ops, VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings); | ||
| 682 | /* yes, really vidioc_subscribe_event */ | ||
| 683 | SET_VALID_IOCTL(ops, VIDIOC_DQEVENT, vidioc_subscribe_event); | ||
| 684 | SET_VALID_IOCTL(ops, VIDIOC_SUBSCRIBE_EVENT, vidioc_subscribe_event); | ||
| 685 | SET_VALID_IOCTL(ops, VIDIOC_UNSUBSCRIBE_EVENT, vidioc_unsubscribe_event); | ||
| 686 | SET_VALID_IOCTL(ops, VIDIOC_CREATE_BUFS, vidioc_create_bufs); | ||
| 687 | SET_VALID_IOCTL(ops, VIDIOC_PREPARE_BUF, vidioc_prepare_buf); | ||
| 688 | bitmap_andnot(vdev->valid_ioctls, valid_ioctls, vdev->valid_ioctls, | ||
| 689 | BASE_VIDIOC_PRIVATE); | ||
| 690 | } | ||
| 691 | |||
| 511 | /** | 692 | /** |
| 512 | * __video_register_device - register video4linux devices | 693 | * __video_register_device - register video4linux devices |
| 513 | * @vdev: video device structure we want to register | 694 | * @vdev: video device structure we want to register |
| @@ -654,6 +835,13 @@ int __video_register_device(struct video_device *vdev, int type, int nr, | |||
| 654 | WARN_ON(video_device[vdev->minor] != NULL); | 835 | WARN_ON(video_device[vdev->minor] != NULL); |
| 655 | vdev->index = get_index(vdev); | 836 | vdev->index = get_index(vdev); |
| 656 | mutex_unlock(&videodev_lock); | 837 | mutex_unlock(&videodev_lock); |
| 838 | /* if no lock was passed, then make sure the LOCK_ALL_FOPS bit is | ||
| 839 | clear and warn if it wasn't. */ | ||
| 840 | if (vdev->lock == NULL) | ||
| 841 | WARN_ON(test_and_clear_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)); | ||
| 842 | |||
| 843 | if (vdev->ioctl_ops) | ||
| 844 | determine_valid_ioctls(vdev); | ||
| 657 | 845 | ||
| 658 | /* Part 3: Initialize the character device */ | 846 | /* Part 3: Initialize the character device */ |
| 659 | vdev->cdev = cdev_alloc(); | 847 | vdev->cdev = cdev_alloc(); |
