diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2012-09-14 06:03:35 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-09-26 13:41:54 -0400 |
commit | 4b20259fa642d6f7a2dabef0b3adc14ca9dadbde (patch) | |
tree | e508b4e27cb2d82c5e68ffd1ff5a184725b5944b /drivers/media/v4l2-core | |
parent | 954f340fc7f2fa2ae8812670da49e828d2686d8e (diff) |
[media] v4l2-dev: improve ioctl validity checks
The ioctl validity checks have been improved and now take vfl_type
and vfl_dir into account.
During the 2012 Media Workshop it was decided that these improved
v4l2 core checks should be added as they simplified drivers and
made drivers behave consistently.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/v4l2-core')
-rw-r--r-- | drivers/media/v4l2-core/v4l2-dev.c | 228 | ||||
-rw-r--r-- | drivers/media/v4l2-core/v4l2-ioctl.c | 182 |
2 files changed, 237 insertions, 173 deletions
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 498049fa43e4..b437daa1f7d6 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c | |||
@@ -551,6 +551,11 @@ static void determine_valid_ioctls(struct video_device *vdev) | |||
551 | { | 551 | { |
552 | DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE); | 552 | DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE); |
553 | const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops; | 553 | const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops; |
554 | bool is_vid = vdev->vfl_type == VFL_TYPE_GRABBER; | ||
555 | bool is_vbi = vdev->vfl_type == VFL_TYPE_VBI; | ||
556 | bool is_radio = vdev->vfl_type == VFL_TYPE_RADIO; | ||
557 | bool is_rx = vdev->vfl_dir != VFL_DIR_TX; | ||
558 | bool is_tx = vdev->vfl_dir != VFL_DIR_RX; | ||
554 | 559 | ||
555 | bitmap_zero(valid_ioctls, BASE_VIDIOC_PRIVATE); | 560 | bitmap_zero(valid_ioctls, BASE_VIDIOC_PRIVATE); |
556 | 561 | ||
@@ -561,66 +566,87 @@ static void determine_valid_ioctls(struct video_device *vdev) | |||
561 | if (ops->vidioc_s_priority || | 566 | if (ops->vidioc_s_priority || |
562 | test_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags)) | 567 | test_bit(V4L2_FL_USE_FH_PRIO, &vdev->flags)) |
563 | set_bit(_IOC_NR(VIDIOC_S_PRIORITY), valid_ioctls); | 568 | set_bit(_IOC_NR(VIDIOC_S_PRIORITY), valid_ioctls); |
564 | if (ops->vidioc_enum_fmt_vid_cap || | 569 | if (is_vid) { |
565 | ops->vidioc_enum_fmt_vid_out || | 570 | if ((is_rx && (ops->vidioc_enum_fmt_vid_cap || |
566 | ops->vidioc_enum_fmt_vid_cap_mplane || | 571 | ops->vidioc_enum_fmt_vid_cap_mplane || |
567 | ops->vidioc_enum_fmt_vid_out_mplane || | 572 | ops->vidioc_enum_fmt_vid_overlay)) || |
568 | ops->vidioc_enum_fmt_vid_overlay) | 573 | (is_tx && (ops->vidioc_enum_fmt_vid_out || |
569 | set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls); | 574 | ops->vidioc_enum_fmt_vid_out_mplane))) |
570 | if (ops->vidioc_g_fmt_vid_cap || | 575 | set_bit(_IOC_NR(VIDIOC_ENUM_FMT), valid_ioctls); |
571 | ops->vidioc_g_fmt_vid_out || | 576 | if ((is_rx && (ops->vidioc_g_fmt_vid_cap || |
572 | ops->vidioc_g_fmt_vid_cap_mplane || | 577 | ops->vidioc_g_fmt_vid_cap_mplane || |
573 | ops->vidioc_g_fmt_vid_out_mplane || | 578 | ops->vidioc_g_fmt_vid_overlay)) || |
574 | ops->vidioc_g_fmt_vid_overlay || | 579 | (is_tx && (ops->vidioc_g_fmt_vid_out || |
575 | ops->vidioc_g_fmt_vbi_cap || | 580 | ops->vidioc_g_fmt_vid_out_mplane || |
576 | ops->vidioc_g_fmt_vid_out_overlay || | 581 | ops->vidioc_g_fmt_vid_out_overlay))) |
577 | ops->vidioc_g_fmt_vbi_out || | 582 | set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls); |
578 | ops->vidioc_g_fmt_sliced_vbi_cap || | 583 | if ((is_rx && (ops->vidioc_s_fmt_vid_cap || |
579 | ops->vidioc_g_fmt_sliced_vbi_out) | 584 | ops->vidioc_s_fmt_vid_cap_mplane || |
580 | set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls); | 585 | ops->vidioc_s_fmt_vid_overlay)) || |
581 | if (ops->vidioc_s_fmt_vid_cap || | 586 | (is_tx && (ops->vidioc_s_fmt_vid_out || |
582 | ops->vidioc_s_fmt_vid_out || | 587 | ops->vidioc_s_fmt_vid_out_mplane || |
583 | ops->vidioc_s_fmt_vid_cap_mplane || | 588 | ops->vidioc_s_fmt_vid_out_overlay))) |
584 | ops->vidioc_s_fmt_vid_out_mplane || | 589 | set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls); |
585 | ops->vidioc_s_fmt_vid_overlay || | 590 | if ((is_rx && (ops->vidioc_try_fmt_vid_cap || |
586 | ops->vidioc_s_fmt_vbi_cap || | 591 | ops->vidioc_try_fmt_vid_cap_mplane || |
587 | ops->vidioc_s_fmt_vid_out_overlay || | 592 | ops->vidioc_try_fmt_vid_overlay)) || |
588 | ops->vidioc_s_fmt_vbi_out || | 593 | (is_tx && (ops->vidioc_try_fmt_vid_out || |
589 | ops->vidioc_s_fmt_sliced_vbi_cap || | 594 | ops->vidioc_try_fmt_vid_out_mplane || |
590 | ops->vidioc_s_fmt_sliced_vbi_out) | 595 | ops->vidioc_try_fmt_vid_out_overlay))) |
591 | set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls); | 596 | set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls); |
592 | if (ops->vidioc_try_fmt_vid_cap || | 597 | } else if (is_vbi) { |
593 | ops->vidioc_try_fmt_vid_out || | 598 | if ((is_rx && (ops->vidioc_g_fmt_vbi_cap || |
594 | ops->vidioc_try_fmt_vid_cap_mplane || | 599 | ops->vidioc_g_fmt_sliced_vbi_cap)) || |
595 | ops->vidioc_try_fmt_vid_out_mplane || | 600 | (is_tx && (ops->vidioc_g_fmt_vbi_out || |
596 | ops->vidioc_try_fmt_vid_overlay || | 601 | ops->vidioc_g_fmt_sliced_vbi_out))) |
597 | ops->vidioc_try_fmt_vbi_cap || | 602 | set_bit(_IOC_NR(VIDIOC_G_FMT), valid_ioctls); |
598 | ops->vidioc_try_fmt_vid_out_overlay || | 603 | if ((is_rx && (ops->vidioc_s_fmt_vbi_cap || |
599 | ops->vidioc_try_fmt_vbi_out || | 604 | ops->vidioc_s_fmt_sliced_vbi_cap)) || |
600 | ops->vidioc_try_fmt_sliced_vbi_cap || | 605 | (is_tx && (ops->vidioc_s_fmt_vbi_out || |
601 | ops->vidioc_try_fmt_sliced_vbi_out) | 606 | ops->vidioc_s_fmt_sliced_vbi_out))) |
602 | set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls); | 607 | set_bit(_IOC_NR(VIDIOC_S_FMT), valid_ioctls); |
608 | if ((is_rx && (ops->vidioc_try_fmt_vbi_cap || | ||
609 | ops->vidioc_try_fmt_sliced_vbi_cap)) || | ||
610 | (is_tx && (ops->vidioc_try_fmt_vbi_out || | ||
611 | ops->vidioc_try_fmt_sliced_vbi_out))) | ||
612 | set_bit(_IOC_NR(VIDIOC_TRY_FMT), valid_ioctls); | ||
613 | } | ||
603 | SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs); | 614 | SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs); |
604 | SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf); | 615 | SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf); |
605 | SET_VALID_IOCTL(ops, VIDIOC_QBUF, vidioc_qbuf); | 616 | SET_VALID_IOCTL(ops, VIDIOC_QBUF, vidioc_qbuf); |
606 | SET_VALID_IOCTL(ops, VIDIOC_DQBUF, vidioc_dqbuf); | 617 | SET_VALID_IOCTL(ops, VIDIOC_DQBUF, vidioc_dqbuf); |
607 | SET_VALID_IOCTL(ops, VIDIOC_OVERLAY, vidioc_overlay); | 618 | if (is_vid) { |
608 | SET_VALID_IOCTL(ops, VIDIOC_G_FBUF, vidioc_g_fbuf); | 619 | SET_VALID_IOCTL(ops, VIDIOC_OVERLAY, vidioc_overlay); |
609 | SET_VALID_IOCTL(ops, VIDIOC_S_FBUF, vidioc_s_fbuf); | 620 | SET_VALID_IOCTL(ops, VIDIOC_G_FBUF, vidioc_g_fbuf); |
621 | SET_VALID_IOCTL(ops, VIDIOC_S_FBUF, vidioc_s_fbuf); | ||
622 | } | ||
610 | SET_VALID_IOCTL(ops, VIDIOC_STREAMON, vidioc_streamon); | 623 | SET_VALID_IOCTL(ops, VIDIOC_STREAMON, vidioc_streamon); |
611 | SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff); | 624 | SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff); |
612 | if (ops->vidioc_s_std) | 625 | if (!is_radio) { |
613 | set_bit(_IOC_NR(VIDIOC_ENUMSTD), valid_ioctls); | 626 | if (ops->vidioc_s_std) |
614 | if (ops->vidioc_g_std || vdev->current_norm) | 627 | set_bit(_IOC_NR(VIDIOC_ENUMSTD), valid_ioctls); |
615 | set_bit(_IOC_NR(VIDIOC_G_STD), valid_ioctls); | 628 | if (ops->vidioc_g_std || vdev->current_norm) |
616 | SET_VALID_IOCTL(ops, VIDIOC_S_STD, vidioc_s_std); | 629 | set_bit(_IOC_NR(VIDIOC_G_STD), valid_ioctls); |
617 | SET_VALID_IOCTL(ops, VIDIOC_QUERYSTD, vidioc_querystd); | 630 | SET_VALID_IOCTL(ops, VIDIOC_S_STD, vidioc_s_std); |
618 | SET_VALID_IOCTL(ops, VIDIOC_ENUMINPUT, vidioc_enum_input); | 631 | if (is_rx) |
619 | SET_VALID_IOCTL(ops, VIDIOC_G_INPUT, vidioc_g_input); | 632 | SET_VALID_IOCTL(ops, VIDIOC_QUERYSTD, vidioc_querystd); |
620 | SET_VALID_IOCTL(ops, VIDIOC_S_INPUT, vidioc_s_input); | 633 | if (is_rx) { |
621 | SET_VALID_IOCTL(ops, VIDIOC_ENUMOUTPUT, vidioc_enum_output); | 634 | SET_VALID_IOCTL(ops, VIDIOC_ENUMINPUT, vidioc_enum_input); |
622 | SET_VALID_IOCTL(ops, VIDIOC_G_OUTPUT, vidioc_g_output); | 635 | SET_VALID_IOCTL(ops, VIDIOC_G_INPUT, vidioc_g_input); |
623 | SET_VALID_IOCTL(ops, VIDIOC_S_OUTPUT, vidioc_s_output); | 636 | SET_VALID_IOCTL(ops, VIDIOC_S_INPUT, vidioc_s_input); |
637 | SET_VALID_IOCTL(ops, VIDIOC_ENUMAUDIO, vidioc_enumaudio); | ||
638 | SET_VALID_IOCTL(ops, VIDIOC_G_AUDIO, vidioc_g_audio); | ||
639 | SET_VALID_IOCTL(ops, VIDIOC_S_AUDIO, vidioc_s_audio); | ||
640 | } | ||
641 | if (is_tx) { | ||
642 | SET_VALID_IOCTL(ops, VIDIOC_ENUMOUTPUT, vidioc_enum_output); | ||
643 | SET_VALID_IOCTL(ops, VIDIOC_G_OUTPUT, vidioc_g_output); | ||
644 | SET_VALID_IOCTL(ops, VIDIOC_S_OUTPUT, vidioc_s_output); | ||
645 | SET_VALID_IOCTL(ops, VIDIOC_ENUMAUDOUT, vidioc_enumaudout); | ||
646 | SET_VALID_IOCTL(ops, VIDIOC_G_AUDOUT, vidioc_g_audout); | ||
647 | SET_VALID_IOCTL(ops, VIDIOC_S_AUDOUT, vidioc_s_audout); | ||
648 | } | ||
649 | } | ||
624 | /* Note: the control handler can also be passed through the filehandle, | 650 | /* Note: the control handler can also be passed through the filehandle, |
625 | and that can't be tested here. If the bit for these control ioctls | 651 | and that can't be tested here. If the bit for these control ioctls |
626 | is set, then the ioctl is valid. But if it is 0, then it can still | 652 | is set, then the ioctl is valid. But if it is 0, then it can still |
@@ -639,56 +665,68 @@ static void determine_valid_ioctls(struct video_device *vdev) | |||
639 | set_bit(_IOC_NR(VIDIOC_TRY_EXT_CTRLS), valid_ioctls); | 665 | set_bit(_IOC_NR(VIDIOC_TRY_EXT_CTRLS), valid_ioctls); |
640 | if (vdev->ctrl_handler || ops->vidioc_querymenu) | 666 | if (vdev->ctrl_handler || ops->vidioc_querymenu) |
641 | set_bit(_IOC_NR(VIDIOC_QUERYMENU), valid_ioctls); | 667 | set_bit(_IOC_NR(VIDIOC_QUERYMENU), valid_ioctls); |
642 | SET_VALID_IOCTL(ops, VIDIOC_ENUMAUDIO, vidioc_enumaudio); | 668 | if (is_tx) { |
643 | SET_VALID_IOCTL(ops, VIDIOC_G_AUDIO, vidioc_g_audio); | 669 | SET_VALID_IOCTL(ops, VIDIOC_G_MODULATOR, vidioc_g_modulator); |
644 | SET_VALID_IOCTL(ops, VIDIOC_S_AUDIO, vidioc_s_audio); | 670 | SET_VALID_IOCTL(ops, VIDIOC_S_MODULATOR, vidioc_s_modulator); |
645 | SET_VALID_IOCTL(ops, VIDIOC_ENUMAUDOUT, vidioc_enumaudout); | 671 | } |
646 | SET_VALID_IOCTL(ops, VIDIOC_G_AUDOUT, vidioc_g_audout); | 672 | if (!is_radio) { |
647 | SET_VALID_IOCTL(ops, VIDIOC_S_AUDOUT, vidioc_s_audout); | 673 | if (ops->vidioc_g_crop || ops->vidioc_g_selection) |
648 | SET_VALID_IOCTL(ops, VIDIOC_G_MODULATOR, vidioc_g_modulator); | 674 | set_bit(_IOC_NR(VIDIOC_G_CROP), valid_ioctls); |
649 | SET_VALID_IOCTL(ops, VIDIOC_S_MODULATOR, vidioc_s_modulator); | 675 | if (ops->vidioc_s_crop || ops->vidioc_s_selection) |
650 | if (ops->vidioc_g_crop || ops->vidioc_g_selection) | 676 | set_bit(_IOC_NR(VIDIOC_S_CROP), valid_ioctls); |
651 | set_bit(_IOC_NR(VIDIOC_G_CROP), valid_ioctls); | 677 | SET_VALID_IOCTL(ops, VIDIOC_G_SELECTION, vidioc_g_selection); |
652 | if (ops->vidioc_s_crop || ops->vidioc_s_selection) | 678 | SET_VALID_IOCTL(ops, VIDIOC_S_SELECTION, vidioc_s_selection); |
653 | set_bit(_IOC_NR(VIDIOC_S_CROP), valid_ioctls); | 679 | if (ops->vidioc_cropcap || ops->vidioc_g_selection) |
654 | SET_VALID_IOCTL(ops, VIDIOC_G_SELECTION, vidioc_g_selection); | 680 | set_bit(_IOC_NR(VIDIOC_CROPCAP), valid_ioctls); |
655 | SET_VALID_IOCTL(ops, VIDIOC_S_SELECTION, vidioc_s_selection); | 681 | } |
656 | if (ops->vidioc_cropcap || ops->vidioc_g_selection) | 682 | if (is_vid) { |
657 | set_bit(_IOC_NR(VIDIOC_CROPCAP), valid_ioctls); | 683 | SET_VALID_IOCTL(ops, VIDIOC_G_JPEGCOMP, vidioc_g_jpegcomp); |
658 | SET_VALID_IOCTL(ops, VIDIOC_G_JPEGCOMP, vidioc_g_jpegcomp); | 684 | SET_VALID_IOCTL(ops, VIDIOC_S_JPEGCOMP, vidioc_s_jpegcomp); |
659 | SET_VALID_IOCTL(ops, VIDIOC_S_JPEGCOMP, vidioc_s_jpegcomp); | 685 | SET_VALID_IOCTL(ops, VIDIOC_G_ENC_INDEX, vidioc_g_enc_index); |
660 | SET_VALID_IOCTL(ops, VIDIOC_G_ENC_INDEX, vidioc_g_enc_index); | 686 | SET_VALID_IOCTL(ops, VIDIOC_ENCODER_CMD, vidioc_encoder_cmd); |
661 | SET_VALID_IOCTL(ops, VIDIOC_ENCODER_CMD, vidioc_encoder_cmd); | 687 | SET_VALID_IOCTL(ops, VIDIOC_TRY_ENCODER_CMD, vidioc_try_encoder_cmd); |
662 | SET_VALID_IOCTL(ops, VIDIOC_TRY_ENCODER_CMD, vidioc_try_encoder_cmd); | 688 | SET_VALID_IOCTL(ops, VIDIOC_DECODER_CMD, vidioc_decoder_cmd); |
663 | SET_VALID_IOCTL(ops, VIDIOC_DECODER_CMD, vidioc_decoder_cmd); | 689 | SET_VALID_IOCTL(ops, VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd); |
664 | SET_VALID_IOCTL(ops, VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd); | 690 | } |
665 | if (ops->vidioc_g_parm || (vdev->vfl_type == VFL_TYPE_GRABBER && | 691 | if (!is_radio) { |
692 | if (ops->vidioc_g_parm || (vdev->vfl_type == VFL_TYPE_GRABBER && | ||
666 | (ops->vidioc_g_std || vdev->current_norm))) | 693 | (ops->vidioc_g_std || vdev->current_norm))) |
667 | set_bit(_IOC_NR(VIDIOC_G_PARM), valid_ioctls); | 694 | set_bit(_IOC_NR(VIDIOC_G_PARM), valid_ioctls); |
668 | SET_VALID_IOCTL(ops, VIDIOC_S_PARM, vidioc_s_parm); | 695 | SET_VALID_IOCTL(ops, VIDIOC_S_PARM, vidioc_s_parm); |
669 | SET_VALID_IOCTL(ops, VIDIOC_G_TUNER, vidioc_g_tuner); | 696 | } |
670 | SET_VALID_IOCTL(ops, VIDIOC_S_TUNER, vidioc_s_tuner); | 697 | if (is_rx) { |
698 | SET_VALID_IOCTL(ops, VIDIOC_G_TUNER, vidioc_g_tuner); | ||
699 | SET_VALID_IOCTL(ops, VIDIOC_S_TUNER, vidioc_s_tuner); | ||
700 | } | ||
671 | SET_VALID_IOCTL(ops, VIDIOC_G_FREQUENCY, vidioc_g_frequency); | 701 | SET_VALID_IOCTL(ops, VIDIOC_G_FREQUENCY, vidioc_g_frequency); |
672 | SET_VALID_IOCTL(ops, VIDIOC_S_FREQUENCY, vidioc_s_frequency); | 702 | SET_VALID_IOCTL(ops, VIDIOC_S_FREQUENCY, vidioc_s_frequency); |
673 | SET_VALID_IOCTL(ops, VIDIOC_G_SLICED_VBI_CAP, vidioc_g_sliced_vbi_cap); | 703 | if (is_vbi) |
704 | SET_VALID_IOCTL(ops, VIDIOC_G_SLICED_VBI_CAP, vidioc_g_sliced_vbi_cap); | ||
674 | SET_VALID_IOCTL(ops, VIDIOC_LOG_STATUS, vidioc_log_status); | 705 | SET_VALID_IOCTL(ops, VIDIOC_LOG_STATUS, vidioc_log_status); |
675 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 706 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
676 | SET_VALID_IOCTL(ops, VIDIOC_DBG_G_REGISTER, vidioc_g_register); | 707 | SET_VALID_IOCTL(ops, VIDIOC_DBG_G_REGISTER, vidioc_g_register); |
677 | SET_VALID_IOCTL(ops, VIDIOC_DBG_S_REGISTER, vidioc_s_register); | 708 | SET_VALID_IOCTL(ops, VIDIOC_DBG_S_REGISTER, vidioc_s_register); |
678 | #endif | 709 | #endif |
679 | SET_VALID_IOCTL(ops, VIDIOC_DBG_G_CHIP_IDENT, vidioc_g_chip_ident); | 710 | SET_VALID_IOCTL(ops, VIDIOC_DBG_G_CHIP_IDENT, vidioc_g_chip_ident); |
680 | SET_VALID_IOCTL(ops, VIDIOC_S_HW_FREQ_SEEK, vidioc_s_hw_freq_seek); | 711 | if (is_rx) |
681 | SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMESIZES, vidioc_enum_framesizes); | 712 | SET_VALID_IOCTL(ops, VIDIOC_S_HW_FREQ_SEEK, vidioc_s_hw_freq_seek); |
682 | SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMEINTERVALS, vidioc_enum_frameintervals); | 713 | if (is_vid) { |
683 | SET_VALID_IOCTL(ops, VIDIOC_ENUM_DV_PRESETS, vidioc_enum_dv_presets); | 714 | SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMESIZES, vidioc_enum_framesizes); |
684 | SET_VALID_IOCTL(ops, VIDIOC_S_DV_PRESET, vidioc_s_dv_preset); | 715 | SET_VALID_IOCTL(ops, VIDIOC_ENUM_FRAMEINTERVALS, vidioc_enum_frameintervals); |
685 | SET_VALID_IOCTL(ops, VIDIOC_G_DV_PRESET, vidioc_g_dv_preset); | 716 | } |
686 | SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_PRESET, vidioc_query_dv_preset); | 717 | if (!is_radio) { |
687 | SET_VALID_IOCTL(ops, VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings); | 718 | SET_VALID_IOCTL(ops, VIDIOC_ENUM_DV_PRESETS, vidioc_enum_dv_presets); |
688 | SET_VALID_IOCTL(ops, VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings); | 719 | SET_VALID_IOCTL(ops, VIDIOC_S_DV_PRESET, vidioc_s_dv_preset); |
689 | SET_VALID_IOCTL(ops, VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings); | 720 | SET_VALID_IOCTL(ops, VIDIOC_G_DV_PRESET, vidioc_g_dv_preset); |
690 | SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings); | 721 | if (is_rx) |
691 | SET_VALID_IOCTL(ops, VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap); | 722 | SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_PRESET, vidioc_query_dv_preset); |
723 | SET_VALID_IOCTL(ops, VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings); | ||
724 | SET_VALID_IOCTL(ops, VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings); | ||
725 | SET_VALID_IOCTL(ops, VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings); | ||
726 | if (is_rx) | ||
727 | SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings); | ||
728 | SET_VALID_IOCTL(ops, VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap); | ||
729 | } | ||
692 | /* yes, really vidioc_subscribe_event */ | 730 | /* yes, really vidioc_subscribe_event */ |
693 | SET_VALID_IOCTL(ops, VIDIOC_DQEVENT, vidioc_subscribe_event); | 731 | SET_VALID_IOCTL(ops, VIDIOC_DQEVENT, vidioc_subscribe_event); |
694 | SET_VALID_IOCTL(ops, VIDIOC_SUBSCRIBE_EVENT, vidioc_subscribe_event); | 732 | SET_VALID_IOCTL(ops, VIDIOC_SUBSCRIBE_EVENT, vidioc_subscribe_event); |
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 7336363984c1..09512ebc6497 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c | |||
@@ -876,52 +876,59 @@ static int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv) | |||
876 | return 1; | 876 | return 1; |
877 | } | 877 | } |
878 | 878 | ||
879 | static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type) | 879 | static int check_fmt(struct file *file, enum v4l2_buf_type type) |
880 | { | 880 | { |
881 | struct video_device *vfd = video_devdata(file); | ||
882 | const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; | ||
883 | bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER; | ||
884 | bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI; | ||
885 | bool is_rx = vfd->vfl_dir != VFL_DIR_TX; | ||
886 | bool is_tx = vfd->vfl_dir != VFL_DIR_RX; | ||
887 | |||
881 | if (ops == NULL) | 888 | if (ops == NULL) |
882 | return -EINVAL; | 889 | return -EINVAL; |
883 | 890 | ||
884 | switch (type) { | 891 | switch (type) { |
885 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 892 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
886 | if (ops->vidioc_g_fmt_vid_cap || | 893 | if (is_vid && is_rx && |
887 | ops->vidioc_g_fmt_vid_cap_mplane) | 894 | (ops->vidioc_g_fmt_vid_cap || ops->vidioc_g_fmt_vid_cap_mplane)) |
888 | return 0; | 895 | return 0; |
889 | break; | 896 | break; |
890 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: | 897 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
891 | if (ops->vidioc_g_fmt_vid_cap_mplane) | 898 | if (is_vid && is_rx && ops->vidioc_g_fmt_vid_cap_mplane) |
892 | return 0; | 899 | return 0; |
893 | break; | 900 | break; |
894 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 901 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
895 | if (ops->vidioc_g_fmt_vid_overlay) | 902 | if (is_vid && is_rx && ops->vidioc_g_fmt_vid_overlay) |
896 | return 0; | 903 | return 0; |
897 | break; | 904 | break; |
898 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | 905 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: |
899 | if (ops->vidioc_g_fmt_vid_out || | 906 | if (is_vid && is_tx && |
900 | ops->vidioc_g_fmt_vid_out_mplane) | 907 | (ops->vidioc_g_fmt_vid_out || ops->vidioc_g_fmt_vid_out_mplane)) |
901 | return 0; | 908 | return 0; |
902 | break; | 909 | break; |
903 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: | 910 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: |
904 | if (ops->vidioc_g_fmt_vid_out_mplane) | 911 | if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_mplane) |
905 | return 0; | 912 | return 0; |
906 | break; | 913 | break; |
907 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: | 914 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: |
908 | if (ops->vidioc_g_fmt_vid_out_overlay) | 915 | if (is_vid && is_tx && ops->vidioc_g_fmt_vid_out_overlay) |
909 | return 0; | 916 | return 0; |
910 | break; | 917 | break; |
911 | case V4L2_BUF_TYPE_VBI_CAPTURE: | 918 | case V4L2_BUF_TYPE_VBI_CAPTURE: |
912 | if (ops->vidioc_g_fmt_vbi_cap) | 919 | if (is_vbi && is_rx && ops->vidioc_g_fmt_vbi_cap) |
913 | return 0; | 920 | return 0; |
914 | break; | 921 | break; |
915 | case V4L2_BUF_TYPE_VBI_OUTPUT: | 922 | case V4L2_BUF_TYPE_VBI_OUTPUT: |
916 | if (ops->vidioc_g_fmt_vbi_out) | 923 | if (is_vbi && is_tx && ops->vidioc_g_fmt_vbi_out) |
917 | return 0; | 924 | return 0; |
918 | break; | 925 | break; |
919 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | 926 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: |
920 | if (ops->vidioc_g_fmt_sliced_vbi_cap) | 927 | if (is_vbi && is_rx && ops->vidioc_g_fmt_sliced_vbi_cap) |
921 | return 0; | 928 | return 0; |
922 | break; | 929 | break; |
923 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: | 930 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: |
924 | if (ops->vidioc_g_fmt_sliced_vbi_out) | 931 | if (is_vbi && is_tx && ops->vidioc_g_fmt_sliced_vbi_out) |
925 | return 0; | 932 | return 0; |
926 | break; | 933 | break; |
927 | default: | 934 | default: |
@@ -1024,26 +1031,29 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops, | |||
1024 | struct file *file, void *fh, void *arg) | 1031 | struct file *file, void *fh, void *arg) |
1025 | { | 1032 | { |
1026 | struct v4l2_fmtdesc *p = arg; | 1033 | struct v4l2_fmtdesc *p = arg; |
1034 | struct video_device *vfd = video_devdata(file); | ||
1035 | bool is_rx = vfd->vfl_dir != VFL_DIR_TX; | ||
1036 | bool is_tx = vfd->vfl_dir != VFL_DIR_RX; | ||
1027 | 1037 | ||
1028 | switch (p->type) { | 1038 | switch (p->type) { |
1029 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 1039 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
1030 | if (unlikely(!ops->vidioc_enum_fmt_vid_cap)) | 1040 | if (unlikely(!is_rx || !ops->vidioc_enum_fmt_vid_cap)) |
1031 | break; | 1041 | break; |
1032 | return ops->vidioc_enum_fmt_vid_cap(file, fh, arg); | 1042 | return ops->vidioc_enum_fmt_vid_cap(file, fh, arg); |
1033 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: | 1043 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
1034 | if (unlikely(!ops->vidioc_enum_fmt_vid_cap_mplane)) | 1044 | if (unlikely(!is_rx || !ops->vidioc_enum_fmt_vid_cap_mplane)) |
1035 | break; | 1045 | break; |
1036 | return ops->vidioc_enum_fmt_vid_cap_mplane(file, fh, arg); | 1046 | return ops->vidioc_enum_fmt_vid_cap_mplane(file, fh, arg); |
1037 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 1047 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
1038 | if (unlikely(!ops->vidioc_enum_fmt_vid_overlay)) | 1048 | if (unlikely(!is_rx || !ops->vidioc_enum_fmt_vid_overlay)) |
1039 | break; | 1049 | break; |
1040 | return ops->vidioc_enum_fmt_vid_overlay(file, fh, arg); | 1050 | return ops->vidioc_enum_fmt_vid_overlay(file, fh, arg); |
1041 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | 1051 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: |
1042 | if (unlikely(!ops->vidioc_enum_fmt_vid_out)) | 1052 | if (unlikely(!is_tx || !ops->vidioc_enum_fmt_vid_out)) |
1043 | break; | 1053 | break; |
1044 | return ops->vidioc_enum_fmt_vid_out(file, fh, arg); | 1054 | return ops->vidioc_enum_fmt_vid_out(file, fh, arg); |
1045 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: | 1055 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: |
1046 | if (unlikely(!ops->vidioc_enum_fmt_vid_out_mplane)) | 1056 | if (unlikely(!is_tx || !ops->vidioc_enum_fmt_vid_out_mplane)) |
1047 | break; | 1057 | break; |
1048 | return ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg); | 1058 | return ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg); |
1049 | } | 1059 | } |
@@ -1054,46 +1064,50 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops, | |||
1054 | struct file *file, void *fh, void *arg) | 1064 | struct file *file, void *fh, void *arg) |
1055 | { | 1065 | { |
1056 | struct v4l2_format *p = arg; | 1066 | struct v4l2_format *p = arg; |
1067 | struct video_device *vfd = video_devdata(file); | ||
1068 | bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER; | ||
1069 | bool is_rx = vfd->vfl_dir != VFL_DIR_TX; | ||
1070 | bool is_tx = vfd->vfl_dir != VFL_DIR_RX; | ||
1057 | 1071 | ||
1058 | switch (p->type) { | 1072 | switch (p->type) { |
1059 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 1073 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
1060 | if (unlikely(!ops->vidioc_g_fmt_vid_cap)) | 1074 | if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap)) |
1061 | break; | 1075 | break; |
1062 | return ops->vidioc_g_fmt_vid_cap(file, fh, arg); | 1076 | return ops->vidioc_g_fmt_vid_cap(file, fh, arg); |
1063 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: | 1077 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
1064 | if (unlikely(!ops->vidioc_g_fmt_vid_cap_mplane)) | 1078 | if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap_mplane)) |
1065 | break; | 1079 | break; |
1066 | return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg); | 1080 | return ops->vidioc_g_fmt_vid_cap_mplane(file, fh, arg); |
1067 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 1081 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
1068 | if (unlikely(!ops->vidioc_g_fmt_vid_overlay)) | 1082 | if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_overlay)) |
1069 | break; | 1083 | break; |
1070 | return ops->vidioc_g_fmt_vid_overlay(file, fh, arg); | 1084 | return ops->vidioc_g_fmt_vid_overlay(file, fh, arg); |
1085 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
1086 | if (unlikely(!is_rx || is_vid || !ops->vidioc_g_fmt_vbi_cap)) | ||
1087 | break; | ||
1088 | return ops->vidioc_g_fmt_vbi_cap(file, fh, arg); | ||
1089 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | ||
1090 | if (unlikely(!is_rx || is_vid || !ops->vidioc_g_fmt_sliced_vbi_cap)) | ||
1091 | break; | ||
1092 | return ops->vidioc_g_fmt_sliced_vbi_cap(file, fh, arg); | ||
1071 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | 1093 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: |
1072 | if (unlikely(!ops->vidioc_g_fmt_vid_out)) | 1094 | if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out)) |
1073 | break; | 1095 | break; |
1074 | return ops->vidioc_g_fmt_vid_out(file, fh, arg); | 1096 | return ops->vidioc_g_fmt_vid_out(file, fh, arg); |
1075 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: | 1097 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: |
1076 | if (unlikely(!ops->vidioc_g_fmt_vid_out_mplane)) | 1098 | if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out_mplane)) |
1077 | break; | 1099 | break; |
1078 | return ops->vidioc_g_fmt_vid_out_mplane(file, fh, arg); | 1100 | return ops->vidioc_g_fmt_vid_out_mplane(file, fh, arg); |
1079 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: | 1101 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: |
1080 | if (unlikely(!ops->vidioc_g_fmt_vid_out_overlay)) | 1102 | if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out_overlay)) |
1081 | break; | 1103 | break; |
1082 | return ops->vidioc_g_fmt_vid_out_overlay(file, fh, arg); | 1104 | return ops->vidioc_g_fmt_vid_out_overlay(file, fh, arg); |
1083 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
1084 | if (unlikely(!ops->vidioc_g_fmt_vbi_cap)) | ||
1085 | break; | ||
1086 | return ops->vidioc_g_fmt_vbi_cap(file, fh, arg); | ||
1087 | case V4L2_BUF_TYPE_VBI_OUTPUT: | 1105 | case V4L2_BUF_TYPE_VBI_OUTPUT: |
1088 | if (unlikely(!ops->vidioc_g_fmt_vbi_out)) | 1106 | if (unlikely(!is_tx || is_vid || !ops->vidioc_g_fmt_vbi_out)) |
1089 | break; | 1107 | break; |
1090 | return ops->vidioc_g_fmt_vbi_out(file, fh, arg); | 1108 | return ops->vidioc_g_fmt_vbi_out(file, fh, arg); |
1091 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | ||
1092 | if (unlikely(!ops->vidioc_g_fmt_sliced_vbi_cap)) | ||
1093 | break; | ||
1094 | return ops->vidioc_g_fmt_sliced_vbi_cap(file, fh, arg); | ||
1095 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: | 1109 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: |
1096 | if (unlikely(!ops->vidioc_g_fmt_sliced_vbi_out)) | 1110 | if (unlikely(!is_tx || is_vid || !ops->vidioc_g_fmt_sliced_vbi_out)) |
1097 | break; | 1111 | break; |
1098 | return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg); | 1112 | return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg); |
1099 | } | 1113 | } |
@@ -1104,55 +1118,59 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops, | |||
1104 | struct file *file, void *fh, void *arg) | 1118 | struct file *file, void *fh, void *arg) |
1105 | { | 1119 | { |
1106 | struct v4l2_format *p = arg; | 1120 | struct v4l2_format *p = arg; |
1121 | struct video_device *vfd = video_devdata(file); | ||
1122 | bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER; | ||
1123 | bool is_rx = vfd->vfl_dir != VFL_DIR_TX; | ||
1124 | bool is_tx = vfd->vfl_dir != VFL_DIR_RX; | ||
1107 | 1125 | ||
1108 | switch (p->type) { | 1126 | switch (p->type) { |
1109 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 1127 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
1110 | if (unlikely(!ops->vidioc_s_fmt_vid_cap)) | 1128 | if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_cap)) |
1111 | break; | 1129 | break; |
1112 | CLEAR_AFTER_FIELD(p, fmt.pix); | 1130 | CLEAR_AFTER_FIELD(p, fmt.pix); |
1113 | return ops->vidioc_s_fmt_vid_cap(file, fh, arg); | 1131 | return ops->vidioc_s_fmt_vid_cap(file, fh, arg); |
1114 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: | 1132 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
1115 | if (unlikely(!ops->vidioc_s_fmt_vid_cap_mplane)) | 1133 | if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_cap_mplane)) |
1116 | break; | 1134 | break; |
1117 | CLEAR_AFTER_FIELD(p, fmt.pix_mp); | 1135 | CLEAR_AFTER_FIELD(p, fmt.pix_mp); |
1118 | return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg); | 1136 | return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg); |
1119 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 1137 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
1120 | if (unlikely(!ops->vidioc_s_fmt_vid_overlay)) | 1138 | if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_overlay)) |
1121 | break; | 1139 | break; |
1122 | CLEAR_AFTER_FIELD(p, fmt.win); | 1140 | CLEAR_AFTER_FIELD(p, fmt.win); |
1123 | return ops->vidioc_s_fmt_vid_overlay(file, fh, arg); | 1141 | return ops->vidioc_s_fmt_vid_overlay(file, fh, arg); |
1142 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
1143 | if (unlikely(!is_rx || is_vid || !ops->vidioc_s_fmt_vbi_cap)) | ||
1144 | break; | ||
1145 | CLEAR_AFTER_FIELD(p, fmt.vbi); | ||
1146 | return ops->vidioc_s_fmt_vbi_cap(file, fh, arg); | ||
1147 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | ||
1148 | if (unlikely(!is_rx || is_vid || !ops->vidioc_s_fmt_sliced_vbi_cap)) | ||
1149 | break; | ||
1150 | CLEAR_AFTER_FIELD(p, fmt.sliced); | ||
1151 | return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg); | ||
1124 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | 1152 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: |
1125 | if (unlikely(!ops->vidioc_s_fmt_vid_out)) | 1153 | if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out)) |
1126 | break; | 1154 | break; |
1127 | CLEAR_AFTER_FIELD(p, fmt.pix); | 1155 | CLEAR_AFTER_FIELD(p, fmt.pix); |
1128 | return ops->vidioc_s_fmt_vid_out(file, fh, arg); | 1156 | return ops->vidioc_s_fmt_vid_out(file, fh, arg); |
1129 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: | 1157 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: |
1130 | if (unlikely(!ops->vidioc_s_fmt_vid_out_mplane)) | 1158 | if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out_mplane)) |
1131 | break; | 1159 | break; |
1132 | CLEAR_AFTER_FIELD(p, fmt.pix_mp); | 1160 | CLEAR_AFTER_FIELD(p, fmt.pix_mp); |
1133 | return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg); | 1161 | return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg); |
1134 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: | 1162 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: |
1135 | if (unlikely(!ops->vidioc_s_fmt_vid_out_overlay)) | 1163 | if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out_overlay)) |
1136 | break; | 1164 | break; |
1137 | CLEAR_AFTER_FIELD(p, fmt.win); | 1165 | CLEAR_AFTER_FIELD(p, fmt.win); |
1138 | return ops->vidioc_s_fmt_vid_out_overlay(file, fh, arg); | 1166 | return ops->vidioc_s_fmt_vid_out_overlay(file, fh, arg); |
1139 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
1140 | if (unlikely(!ops->vidioc_s_fmt_vbi_cap)) | ||
1141 | break; | ||
1142 | CLEAR_AFTER_FIELD(p, fmt.vbi); | ||
1143 | return ops->vidioc_s_fmt_vbi_cap(file, fh, arg); | ||
1144 | case V4L2_BUF_TYPE_VBI_OUTPUT: | 1167 | case V4L2_BUF_TYPE_VBI_OUTPUT: |
1145 | if (unlikely(!ops->vidioc_s_fmt_vbi_out)) | 1168 | if (unlikely(!is_tx || is_vid || !ops->vidioc_s_fmt_vbi_out)) |
1146 | break; | 1169 | break; |
1147 | CLEAR_AFTER_FIELD(p, fmt.vbi); | 1170 | CLEAR_AFTER_FIELD(p, fmt.vbi); |
1148 | return ops->vidioc_s_fmt_vbi_out(file, fh, arg); | 1171 | return ops->vidioc_s_fmt_vbi_out(file, fh, arg); |
1149 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | ||
1150 | if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_cap)) | ||
1151 | break; | ||
1152 | CLEAR_AFTER_FIELD(p, fmt.sliced); | ||
1153 | return ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, arg); | ||
1154 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: | 1172 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: |
1155 | if (unlikely(!ops->vidioc_s_fmt_sliced_vbi_out)) | 1173 | if (unlikely(!is_tx || is_vid || !ops->vidioc_s_fmt_sliced_vbi_out)) |
1156 | break; | 1174 | break; |
1157 | CLEAR_AFTER_FIELD(p, fmt.sliced); | 1175 | CLEAR_AFTER_FIELD(p, fmt.sliced); |
1158 | return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg); | 1176 | return ops->vidioc_s_fmt_sliced_vbi_out(file, fh, arg); |
@@ -1164,55 +1182,59 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops, | |||
1164 | struct file *file, void *fh, void *arg) | 1182 | struct file *file, void *fh, void *arg) |
1165 | { | 1183 | { |
1166 | struct v4l2_format *p = arg; | 1184 | struct v4l2_format *p = arg; |
1185 | struct video_device *vfd = video_devdata(file); | ||
1186 | bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER; | ||
1187 | bool is_rx = vfd->vfl_dir != VFL_DIR_TX; | ||
1188 | bool is_tx = vfd->vfl_dir != VFL_DIR_RX; | ||
1167 | 1189 | ||
1168 | switch (p->type) { | 1190 | switch (p->type) { |
1169 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 1191 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
1170 | if (unlikely(!ops->vidioc_try_fmt_vid_cap)) | 1192 | if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_cap)) |
1171 | break; | 1193 | break; |
1172 | CLEAR_AFTER_FIELD(p, fmt.pix); | 1194 | CLEAR_AFTER_FIELD(p, fmt.pix); |
1173 | return ops->vidioc_try_fmt_vid_cap(file, fh, arg); | 1195 | return ops->vidioc_try_fmt_vid_cap(file, fh, arg); |
1174 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: | 1196 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
1175 | if (unlikely(!ops->vidioc_try_fmt_vid_cap_mplane)) | 1197 | if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_cap_mplane)) |
1176 | break; | 1198 | break; |
1177 | CLEAR_AFTER_FIELD(p, fmt.pix_mp); | 1199 | CLEAR_AFTER_FIELD(p, fmt.pix_mp); |
1178 | return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg); | 1200 | return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg); |
1179 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 1201 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
1180 | if (unlikely(!ops->vidioc_try_fmt_vid_overlay)) | 1202 | if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_overlay)) |
1181 | break; | 1203 | break; |
1182 | CLEAR_AFTER_FIELD(p, fmt.win); | 1204 | CLEAR_AFTER_FIELD(p, fmt.win); |
1183 | return ops->vidioc_try_fmt_vid_overlay(file, fh, arg); | 1205 | return ops->vidioc_try_fmt_vid_overlay(file, fh, arg); |
1206 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
1207 | if (unlikely(!is_rx || is_vid || !ops->vidioc_try_fmt_vbi_cap)) | ||
1208 | break; | ||
1209 | CLEAR_AFTER_FIELD(p, fmt.vbi); | ||
1210 | return ops->vidioc_try_fmt_vbi_cap(file, fh, arg); | ||
1211 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | ||
1212 | if (unlikely(!is_rx || is_vid || !ops->vidioc_try_fmt_sliced_vbi_cap)) | ||
1213 | break; | ||
1214 | CLEAR_AFTER_FIELD(p, fmt.sliced); | ||
1215 | return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg); | ||
1184 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | 1216 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: |
1185 | if (unlikely(!ops->vidioc_try_fmt_vid_out)) | 1217 | if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out)) |
1186 | break; | 1218 | break; |
1187 | CLEAR_AFTER_FIELD(p, fmt.pix); | 1219 | CLEAR_AFTER_FIELD(p, fmt.pix); |
1188 | return ops->vidioc_try_fmt_vid_out(file, fh, arg); | 1220 | return ops->vidioc_try_fmt_vid_out(file, fh, arg); |
1189 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: | 1221 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: |
1190 | if (unlikely(!ops->vidioc_try_fmt_vid_out_mplane)) | 1222 | if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out_mplane)) |
1191 | break; | 1223 | break; |
1192 | CLEAR_AFTER_FIELD(p, fmt.pix_mp); | 1224 | CLEAR_AFTER_FIELD(p, fmt.pix_mp); |
1193 | return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg); | 1225 | return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg); |
1194 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: | 1226 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: |
1195 | if (unlikely(!ops->vidioc_try_fmt_vid_out_overlay)) | 1227 | if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out_overlay)) |
1196 | break; | 1228 | break; |
1197 | CLEAR_AFTER_FIELD(p, fmt.win); | 1229 | CLEAR_AFTER_FIELD(p, fmt.win); |
1198 | return ops->vidioc_try_fmt_vid_out_overlay(file, fh, arg); | 1230 | return ops->vidioc_try_fmt_vid_out_overlay(file, fh, arg); |
1199 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
1200 | if (unlikely(!ops->vidioc_try_fmt_vbi_cap)) | ||
1201 | break; | ||
1202 | CLEAR_AFTER_FIELD(p, fmt.vbi); | ||
1203 | return ops->vidioc_try_fmt_vbi_cap(file, fh, arg); | ||
1204 | case V4L2_BUF_TYPE_VBI_OUTPUT: | 1231 | case V4L2_BUF_TYPE_VBI_OUTPUT: |
1205 | if (unlikely(!ops->vidioc_try_fmt_vbi_out)) | 1232 | if (unlikely(!is_tx || is_vid || !ops->vidioc_try_fmt_vbi_out)) |
1206 | break; | 1233 | break; |
1207 | CLEAR_AFTER_FIELD(p, fmt.vbi); | 1234 | CLEAR_AFTER_FIELD(p, fmt.vbi); |
1208 | return ops->vidioc_try_fmt_vbi_out(file, fh, arg); | 1235 | return ops->vidioc_try_fmt_vbi_out(file, fh, arg); |
1209 | case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: | ||
1210 | if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_cap)) | ||
1211 | break; | ||
1212 | CLEAR_AFTER_FIELD(p, fmt.sliced); | ||
1213 | return ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, arg); | ||
1214 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: | 1236 | case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: |
1215 | if (unlikely(!ops->vidioc_try_fmt_sliced_vbi_out)) | 1237 | if (unlikely(!is_tx || is_vid || !ops->vidioc_try_fmt_sliced_vbi_out)) |
1216 | break; | 1238 | break; |
1217 | CLEAR_AFTER_FIELD(p, fmt.sliced); | 1239 | CLEAR_AFTER_FIELD(p, fmt.sliced); |
1218 | return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg); | 1240 | return ops->vidioc_try_fmt_sliced_vbi_out(file, fh, arg); |
@@ -1404,7 +1426,7 @@ static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops, | |||
1404 | struct file *file, void *fh, void *arg) | 1426 | struct file *file, void *fh, void *arg) |
1405 | { | 1427 | { |
1406 | struct v4l2_requestbuffers *p = arg; | 1428 | struct v4l2_requestbuffers *p = arg; |
1407 | int ret = check_fmt(ops, p->type); | 1429 | int ret = check_fmt(file, p->type); |
1408 | 1430 | ||
1409 | if (ret) | 1431 | if (ret) |
1410 | return ret; | 1432 | return ret; |
@@ -1418,7 +1440,7 @@ static int v4l_querybuf(const struct v4l2_ioctl_ops *ops, | |||
1418 | struct file *file, void *fh, void *arg) | 1440 | struct file *file, void *fh, void *arg) |
1419 | { | 1441 | { |
1420 | struct v4l2_buffer *p = arg; | 1442 | struct v4l2_buffer *p = arg; |
1421 | int ret = check_fmt(ops, p->type); | 1443 | int ret = check_fmt(file, p->type); |
1422 | 1444 | ||
1423 | return ret ? ret : ops->vidioc_querybuf(file, fh, p); | 1445 | return ret ? ret : ops->vidioc_querybuf(file, fh, p); |
1424 | } | 1446 | } |
@@ -1427,7 +1449,7 @@ static int v4l_qbuf(const struct v4l2_ioctl_ops *ops, | |||
1427 | struct file *file, void *fh, void *arg) | 1449 | struct file *file, void *fh, void *arg) |
1428 | { | 1450 | { |
1429 | struct v4l2_buffer *p = arg; | 1451 | struct v4l2_buffer *p = arg; |
1430 | int ret = check_fmt(ops, p->type); | 1452 | int ret = check_fmt(file, p->type); |
1431 | 1453 | ||
1432 | return ret ? ret : ops->vidioc_qbuf(file, fh, p); | 1454 | return ret ? ret : ops->vidioc_qbuf(file, fh, p); |
1433 | } | 1455 | } |
@@ -1436,7 +1458,7 @@ static int v4l_dqbuf(const struct v4l2_ioctl_ops *ops, | |||
1436 | struct file *file, void *fh, void *arg) | 1458 | struct file *file, void *fh, void *arg) |
1437 | { | 1459 | { |
1438 | struct v4l2_buffer *p = arg; | 1460 | struct v4l2_buffer *p = arg; |
1439 | int ret = check_fmt(ops, p->type); | 1461 | int ret = check_fmt(file, p->type); |
1440 | 1462 | ||
1441 | return ret ? ret : ops->vidioc_dqbuf(file, fh, p); | 1463 | return ret ? ret : ops->vidioc_dqbuf(file, fh, p); |
1442 | } | 1464 | } |
@@ -1445,7 +1467,7 @@ static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops, | |||
1445 | struct file *file, void *fh, void *arg) | 1467 | struct file *file, void *fh, void *arg) |
1446 | { | 1468 | { |
1447 | struct v4l2_create_buffers *create = arg; | 1469 | struct v4l2_create_buffers *create = arg; |
1448 | int ret = check_fmt(ops, create->format.type); | 1470 | int ret = check_fmt(file, create->format.type); |
1449 | 1471 | ||
1450 | return ret ? ret : ops->vidioc_create_bufs(file, fh, create); | 1472 | return ret ? ret : ops->vidioc_create_bufs(file, fh, create); |
1451 | } | 1473 | } |
@@ -1454,7 +1476,7 @@ static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops, | |||
1454 | struct file *file, void *fh, void *arg) | 1476 | struct file *file, void *fh, void *arg) |
1455 | { | 1477 | { |
1456 | struct v4l2_buffer *b = arg; | 1478 | struct v4l2_buffer *b = arg; |
1457 | int ret = check_fmt(ops, b->type); | 1479 | int ret = check_fmt(file, b->type); |
1458 | 1480 | ||
1459 | return ret ? ret : ops->vidioc_prepare_buf(file, fh, b); | 1481 | return ret ? ret : ops->vidioc_prepare_buf(file, fh, b); |
1460 | } | 1482 | } |
@@ -1465,7 +1487,7 @@ static int v4l_g_parm(const struct v4l2_ioctl_ops *ops, | |||
1465 | struct video_device *vfd = video_devdata(file); | 1487 | struct video_device *vfd = video_devdata(file); |
1466 | struct v4l2_streamparm *p = arg; | 1488 | struct v4l2_streamparm *p = arg; |
1467 | v4l2_std_id std; | 1489 | v4l2_std_id std; |
1468 | int ret = check_fmt(ops, p->type); | 1490 | int ret = check_fmt(file, p->type); |
1469 | 1491 | ||
1470 | if (ret) | 1492 | if (ret) |
1471 | return ret; | 1493 | return ret; |
@@ -1488,7 +1510,7 @@ static int v4l_s_parm(const struct v4l2_ioctl_ops *ops, | |||
1488 | struct file *file, void *fh, void *arg) | 1510 | struct file *file, void *fh, void *arg) |
1489 | { | 1511 | { |
1490 | struct v4l2_streamparm *p = arg; | 1512 | struct v4l2_streamparm *p = arg; |
1491 | int ret = check_fmt(ops, p->type); | 1513 | int ret = check_fmt(file, p->type); |
1492 | 1514 | ||
1493 | return ret ? ret : ops->vidioc_s_parm(file, fh, p); | 1515 | return ret ? ret : ops->vidioc_s_parm(file, fh, p); |
1494 | } | 1516 | } |
@@ -1810,6 +1832,10 @@ static int v4l_g_sliced_vbi_cap(const struct v4l2_ioctl_ops *ops, | |||
1810 | struct file *file, void *fh, void *arg) | 1832 | struct file *file, void *fh, void *arg) |
1811 | { | 1833 | { |
1812 | struct v4l2_sliced_vbi_cap *p = arg; | 1834 | struct v4l2_sliced_vbi_cap *p = arg; |
1835 | int ret = check_fmt(file, p->type); | ||
1836 | |||
1837 | if (ret) | ||
1838 | return ret; | ||
1813 | 1839 | ||
1814 | /* Clear up to type, everything after type is zeroed already */ | 1840 | /* Clear up to type, everything after type is zeroed already */ |
1815 | memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type)); | 1841 | memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type)); |