aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2011-07-31 08:37:56 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-07-31 08:37:56 -0400
commita5f2db539bd2a977cdee3fecc5c15dd0941c1ab3 (patch)
treefaa650c008e8193612a610b4a78c641506da3f97
parent449d1a0ad1732476d394fb2b885092a5c554f983 (diff)
v4l2-ioctl: properly return -EINVAL when parameters are wrong
Whan an ioctl is implemented, but the parameters are invalid, the error code should be -EINVAL. However, if the ioctl is not defined, it should return -ENOTTY instead. Reported-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/v4l2-ioctl.c89
1 files changed, 52 insertions, 37 deletions
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 002ce1363443..9f80e9d1fdb7 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -55,6 +55,14 @@
55 memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \ 55 memset((u8 *)(p) + offsetof(typeof(*(p)), field) + sizeof((p)->field), \
56 0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field)) 56 0, sizeof(*(p)) - offsetof(typeof(*(p)), field) - sizeof((p)->field))
57 57
58#define no_ioctl_err(foo) ( ( \
59 ops->vidioc_##foo##_fmt_vid_cap || \
60 ops->vidioc_##foo##_fmt_vid_out || \
61 ops->vidioc_##foo##_fmt_vid_cap_mplane || \
62 ops->vidioc_##foo##_fmt_vid_out_mplane || \
63 ops->vidioc_##foo##_fmt_vid_overlay || \
64 ops->vidioc_##foo##_fmt_type_private) ? -EINVAL : -ENOTTY)
65
58struct std_descr { 66struct std_descr {
59 v4l2_std_id std; 67 v4l2_std_id std;
60 const char *descr; 68 const char *descr;
@@ -591,7 +599,7 @@ static long __video_do_ioctl(struct file *file,
591 ret = v4l2_prio_check(vfd->prio, vfh->prio); 599 ret = v4l2_prio_check(vfd->prio, vfh->prio);
592 if (ret) 600 if (ret)
593 goto exit_prio; 601 goto exit_prio;
594 ret = -EINVAL; 602 ret = -ENOTTY;
595 break; 603 break;
596 } 604 }
597 } 605 }
@@ -638,7 +646,7 @@ static long __video_do_ioctl(struct file *file,
638 enum v4l2_priority *p = arg; 646 enum v4l2_priority *p = arg;
639 647
640 if (!ops->vidioc_s_priority && !use_fh_prio) 648 if (!ops->vidioc_s_priority && !use_fh_prio)
641 break; 649 break;
642 dbgarg(cmd, "setting priority to %d\n", *p); 650 dbgarg(cmd, "setting priority to %d\n", *p);
643 if (ops->vidioc_s_priority) 651 if (ops->vidioc_s_priority)
644 ret = ops->vidioc_s_priority(file, fh, *p); 652 ret = ops->vidioc_s_priority(file, fh, *p);
@@ -654,37 +662,37 @@ static long __video_do_ioctl(struct file *file,
654 662
655 switch (f->type) { 663 switch (f->type) {
656 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 664 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
657 if (ops->vidioc_enum_fmt_vid_cap) 665 if (likely(ops->vidioc_enum_fmt_vid_cap))
658 ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f); 666 ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f);
659 break; 667 break;
660 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: 668 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
661 if (ops->vidioc_enum_fmt_vid_cap_mplane) 669 if (likely(ops->vidioc_enum_fmt_vid_cap_mplane))
662 ret = ops->vidioc_enum_fmt_vid_cap_mplane(file, 670 ret = ops->vidioc_enum_fmt_vid_cap_mplane(file,
663 fh, f); 671 fh, f);
664 break; 672 break;
665 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 673 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
666 if (ops->vidioc_enum_fmt_vid_overlay) 674 if (likely(ops->vidioc_enum_fmt_vid_overlay))
667 ret = ops->vidioc_enum_fmt_vid_overlay(file, 675 ret = ops->vidioc_enum_fmt_vid_overlay(file,
668 fh, f); 676 fh, f);
669 break; 677 break;
670 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 678 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
671 if (ops->vidioc_enum_fmt_vid_out) 679 if (likely(ops->vidioc_enum_fmt_vid_out))
672 ret = ops->vidioc_enum_fmt_vid_out(file, fh, f); 680 ret = ops->vidioc_enum_fmt_vid_out(file, fh, f);
673 break; 681 break;
674 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: 682 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
675 if (ops->vidioc_enum_fmt_vid_out_mplane) 683 if (likely(ops->vidioc_enum_fmt_vid_out_mplane))
676 ret = ops->vidioc_enum_fmt_vid_out_mplane(file, 684 ret = ops->vidioc_enum_fmt_vid_out_mplane(file,
677 fh, f); 685 fh, f);
678 break; 686 break;
679 case V4L2_BUF_TYPE_PRIVATE: 687 case V4L2_BUF_TYPE_PRIVATE:
680 if (ops->vidioc_enum_fmt_type_private) 688 if (likely(ops->vidioc_enum_fmt_type_private))
681 ret = ops->vidioc_enum_fmt_type_private(file, 689 ret = ops->vidioc_enum_fmt_type_private(file,
682 fh, f); 690 fh, f);
683 break; 691 break;
684 default: 692 default:
685 break; 693 break;
686 } 694 }
687 if (!ret) 695 if (likely (!ret))
688 dbgarg(cmd, "index=%d, type=%d, flags=%d, " 696 dbgarg(cmd, "index=%d, type=%d, flags=%d, "
689 "pixelformat=%c%c%c%c, description='%s'\n", 697 "pixelformat=%c%c%c%c, description='%s'\n",
690 f->index, f->type, f->flags, 698 f->index, f->type, f->flags,
@@ -693,6 +701,8 @@ static long __video_do_ioctl(struct file *file,
693 (f->pixelformat >> 16) & 0xff, 701 (f->pixelformat >> 16) & 0xff,
694 (f->pixelformat >> 24) & 0xff, 702 (f->pixelformat >> 24) & 0xff,
695 f->description); 703 f->description);
704 else if (ret == -ENOTTY)
705 ret = no_ioctl_err(enum);
696 break; 706 break;
697 } 707 }
698 case VIDIOC_G_FMT: 708 case VIDIOC_G_FMT:
@@ -744,7 +754,7 @@ static long __video_do_ioctl(struct file *file,
744 v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp); 754 v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp);
745 break; 755 break;
746 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 756 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
747 if (ops->vidioc_g_fmt_vid_overlay) 757 if (likely(ops->vidioc_g_fmt_vid_overlay))
748 ret = ops->vidioc_g_fmt_vid_overlay(file, 758 ret = ops->vidioc_g_fmt_vid_overlay(file,
749 fh, f); 759 fh, f);
750 break; 760 break;
@@ -789,34 +799,36 @@ static long __video_do_ioctl(struct file *file,
789 v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp); 799 v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp);
790 break; 800 break;
791 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 801 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
792 if (ops->vidioc_g_fmt_vid_out_overlay) 802 if (likely(ops->vidioc_g_fmt_vid_out_overlay))
793 ret = ops->vidioc_g_fmt_vid_out_overlay(file, 803 ret = ops->vidioc_g_fmt_vid_out_overlay(file,
794 fh, f); 804 fh, f);
795 break; 805 break;
796 case V4L2_BUF_TYPE_VBI_CAPTURE: 806 case V4L2_BUF_TYPE_VBI_CAPTURE:
797 if (ops->vidioc_g_fmt_vbi_cap) 807 if (likely(ops->vidioc_g_fmt_vbi_cap))
798 ret = ops->vidioc_g_fmt_vbi_cap(file, fh, f); 808 ret = ops->vidioc_g_fmt_vbi_cap(file, fh, f);
799 break; 809 break;
800 case V4L2_BUF_TYPE_VBI_OUTPUT: 810 case V4L2_BUF_TYPE_VBI_OUTPUT:
801 if (ops->vidioc_g_fmt_vbi_out) 811 if (likely(ops->vidioc_g_fmt_vbi_out))
802 ret = ops->vidioc_g_fmt_vbi_out(file, fh, f); 812 ret = ops->vidioc_g_fmt_vbi_out(file, fh, f);
803 break; 813 break;
804 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 814 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
805 if (ops->vidioc_g_fmt_sliced_vbi_cap) 815 if (likely(ops->vidioc_g_fmt_sliced_vbi_cap))
806 ret = ops->vidioc_g_fmt_sliced_vbi_cap(file, 816 ret = ops->vidioc_g_fmt_sliced_vbi_cap(file,
807 fh, f); 817 fh, f);
808 break; 818 break;
809 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: 819 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
810 if (ops->vidioc_g_fmt_sliced_vbi_out) 820 if (likely(ops->vidioc_g_fmt_sliced_vbi_out))
811 ret = ops->vidioc_g_fmt_sliced_vbi_out(file, 821 ret = ops->vidioc_g_fmt_sliced_vbi_out(file,
812 fh, f); 822 fh, f);
813 break; 823 break;
814 case V4L2_BUF_TYPE_PRIVATE: 824 case V4L2_BUF_TYPE_PRIVATE:
815 if (ops->vidioc_g_fmt_type_private) 825 if (likely(ops->vidioc_g_fmt_type_private))
816 ret = ops->vidioc_g_fmt_type_private(file, 826 ret = ops->vidioc_g_fmt_type_private(file,
817 fh, f); 827 fh, f);
818 break; 828 break;
819 } 829 }
830 if (unlikely(ret == -ENOTTY))
831 ret = no_ioctl_err(g);
820 832
821 break; 833 break;
822 } 834 }
@@ -926,33 +938,36 @@ static long __video_do_ioctl(struct file *file,
926 break; 938 break;
927 case V4L2_BUF_TYPE_VBI_CAPTURE: 939 case V4L2_BUF_TYPE_VBI_CAPTURE:
928 CLEAR_AFTER_FIELD(f, fmt.vbi); 940 CLEAR_AFTER_FIELD(f, fmt.vbi);
929 if (ops->vidioc_s_fmt_vbi_cap) 941 if (likely(ops->vidioc_s_fmt_vbi_cap))
930 ret = ops->vidioc_s_fmt_vbi_cap(file, fh, f); 942 ret = ops->vidioc_s_fmt_vbi_cap(file, fh, f);
931 break; 943 break;
932 case V4L2_BUF_TYPE_VBI_OUTPUT: 944 case V4L2_BUF_TYPE_VBI_OUTPUT:
933 CLEAR_AFTER_FIELD(f, fmt.vbi); 945 CLEAR_AFTER_FIELD(f, fmt.vbi);
934 if (ops->vidioc_s_fmt_vbi_out) 946 if (likely(ops->vidioc_s_fmt_vbi_out))
935 ret = ops->vidioc_s_fmt_vbi_out(file, fh, f); 947 ret = ops->vidioc_s_fmt_vbi_out(file, fh, f);
936 break; 948 break;
937 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 949 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
938 CLEAR_AFTER_FIELD(f, fmt.sliced); 950 CLEAR_AFTER_FIELD(f, fmt.sliced);
939 if (ops->vidioc_s_fmt_sliced_vbi_cap) 951 if (likely(ops->vidioc_s_fmt_sliced_vbi_cap))
940 ret = ops->vidioc_s_fmt_sliced_vbi_cap(file, 952 ret = ops->vidioc_s_fmt_sliced_vbi_cap(file,
941 fh, f); 953 fh, f);
942 break; 954 break;
943 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: 955 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
944 CLEAR_AFTER_FIELD(f, fmt.sliced); 956 CLEAR_AFTER_FIELD(f, fmt.sliced);
945 if (ops->vidioc_s_fmt_sliced_vbi_out) 957 if (likely(ops->vidioc_s_fmt_sliced_vbi_out))
946 ret = ops->vidioc_s_fmt_sliced_vbi_out(file, 958 ret = ops->vidioc_s_fmt_sliced_vbi_out(file,
947 fh, f); 959 fh, f);
960
948 break; 961 break;
949 case V4L2_BUF_TYPE_PRIVATE: 962 case V4L2_BUF_TYPE_PRIVATE:
950 /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */ 963 /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */
951 if (ops->vidioc_s_fmt_type_private) 964 if (likely(ops->vidioc_s_fmt_type_private))
952 ret = ops->vidioc_s_fmt_type_private(file, 965 ret = ops->vidioc_s_fmt_type_private(file,
953 fh, f); 966 fh, f);
954 break; 967 break;
955 } 968 }
969 if (unlikely(ret == -ENOTTY))
970 ret = no_ioctl_err(g);
956 break; 971 break;
957 } 972 }
958 case VIDIOC_TRY_FMT: 973 case VIDIOC_TRY_FMT:
@@ -1008,7 +1023,7 @@ static long __video_do_ioctl(struct file *file,
1008 break; 1023 break;
1009 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 1024 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1010 CLEAR_AFTER_FIELD(f, fmt.win); 1025 CLEAR_AFTER_FIELD(f, fmt.win);
1011 if (ops->vidioc_try_fmt_vid_overlay) 1026 if (likely(ops->vidioc_try_fmt_vid_overlay))
1012 ret = ops->vidioc_try_fmt_vid_overlay(file, 1027 ret = ops->vidioc_try_fmt_vid_overlay(file,
1013 fh, f); 1028 fh, f);
1014 break; 1029 break;
@@ -1057,40 +1072,43 @@ static long __video_do_ioctl(struct file *file,
1057 break; 1072 break;
1058 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 1073 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
1059 CLEAR_AFTER_FIELD(f, fmt.win); 1074 CLEAR_AFTER_FIELD(f, fmt.win);
1060 if (ops->vidioc_try_fmt_vid_out_overlay) 1075 if (likely(ops->vidioc_try_fmt_vid_out_overlay))
1061 ret = ops->vidioc_try_fmt_vid_out_overlay(file, 1076 ret = ops->vidioc_try_fmt_vid_out_overlay(file,
1062 fh, f); 1077 fh, f);
1063 break; 1078 break;
1064 case V4L2_BUF_TYPE_VBI_CAPTURE: 1079 case V4L2_BUF_TYPE_VBI_CAPTURE:
1065 CLEAR_AFTER_FIELD(f, fmt.vbi); 1080 CLEAR_AFTER_FIELD(f, fmt.vbi);
1066 if (ops->vidioc_try_fmt_vbi_cap) 1081 if (likely(ops->vidioc_try_fmt_vbi_cap))
1067 ret = ops->vidioc_try_fmt_vbi_cap(file, fh, f); 1082 ret = ops->vidioc_try_fmt_vbi_cap(file, fh, f);
1068 break; 1083 break;
1069 case V4L2_BUF_TYPE_VBI_OUTPUT: 1084 case V4L2_BUF_TYPE_VBI_OUTPUT:
1070 CLEAR_AFTER_FIELD(f, fmt.vbi); 1085 CLEAR_AFTER_FIELD(f, fmt.vbi);
1071 if (ops->vidioc_try_fmt_vbi_out) 1086 if (likely(ops->vidioc_try_fmt_vbi_out))
1072 ret = ops->vidioc_try_fmt_vbi_out(file, fh, f); 1087 ret = ops->vidioc_try_fmt_vbi_out(file, fh, f);
1073 break; 1088 break;
1074 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 1089 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
1075 CLEAR_AFTER_FIELD(f, fmt.sliced); 1090 CLEAR_AFTER_FIELD(f, fmt.sliced);
1076 if (ops->vidioc_try_fmt_sliced_vbi_cap) 1091 if (likely(ops->vidioc_try_fmt_sliced_vbi_cap))
1077 ret = ops->vidioc_try_fmt_sliced_vbi_cap(file, 1092 ret = ops->vidioc_try_fmt_sliced_vbi_cap(file,
1078 fh, f); 1093 fh, f);
1079 break; 1094 break;
1080 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: 1095 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
1081 CLEAR_AFTER_FIELD(f, fmt.sliced); 1096 CLEAR_AFTER_FIELD(f, fmt.sliced);
1082 if (ops->vidioc_try_fmt_sliced_vbi_out) 1097 if (likely(ops->vidioc_try_fmt_sliced_vbi_out))
1083 ret = ops->vidioc_try_fmt_sliced_vbi_out(file, 1098 ret = ops->vidioc_try_fmt_sliced_vbi_out(file,
1084 fh, f); 1099 fh, f);
1100 else
1101 ret = no_ioctl_err(try);
1085 break; 1102 break;
1086 case V4L2_BUF_TYPE_PRIVATE: 1103 case V4L2_BUF_TYPE_PRIVATE:
1087 /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */ 1104 /* CLEAR_AFTER_FIELD(f, fmt.raw_data); <- does nothing */
1088 if (ops->vidioc_try_fmt_type_private) 1105 if (likely(ops->vidioc_try_fmt_type_private))
1089 ret = ops->vidioc_try_fmt_type_private(file, 1106 ret = ops->vidioc_try_fmt_type_private(file,
1090 fh, f); 1107 fh, f);
1091 break; 1108 break;
1092 } 1109 }
1093 1110 if (unlikely(ret == -ENOTTY))
1111 ret = no_ioctl_err(g);
1094 break; 1112 break;
1095 } 1113 }
1096 /* FIXME: Those buf reqs could be handled here, 1114 /* FIXME: Those buf reqs could be handled here,
@@ -1262,16 +1280,15 @@ static long __video_do_ioctl(struct file *file,
1262 { 1280 {
1263 v4l2_std_id *id = arg; 1281 v4l2_std_id *id = arg;
1264 1282
1265 ret = 0;
1266 /* Calls the specific handler */ 1283 /* Calls the specific handler */
1267 if (ops->vidioc_g_std) 1284 if (ops->vidioc_g_std)
1268 ret = ops->vidioc_g_std(file, fh, id); 1285 ret = ops->vidioc_g_std(file, fh, id);
1269 else if (vfd->current_norm) 1286 else if (vfd->current_norm) {
1287 ret = 0;
1270 *id = vfd->current_norm; 1288 *id = vfd->current_norm;
1271 else 1289 }
1272 ret = -EINVAL;
1273 1290
1274 if (!ret) 1291 if (likely(!ret))
1275 dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id); 1292 dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id);
1276 break; 1293 break;
1277 } 1294 }
@@ -1288,8 +1305,6 @@ static long __video_do_ioctl(struct file *file,
1288 /* Calls the specific handler */ 1305 /* Calls the specific handler */
1289 if (ops->vidioc_s_std) 1306 if (ops->vidioc_s_std)
1290 ret = ops->vidioc_s_std(file, fh, &norm); 1307 ret = ops->vidioc_s_std(file, fh, &norm);
1291 else
1292 ret = -EINVAL;
1293 1308
1294 /* Updates standard information */ 1309 /* Updates standard information */
1295 if (ret >= 0) 1310 if (ret >= 0)
@@ -1812,7 +1827,7 @@ static long __video_do_ioctl(struct file *file,
1812 if (ops->vidioc_g_std) 1827 if (ops->vidioc_g_std)
1813 ret = ops->vidioc_g_std(file, fh, &std); 1828 ret = ops->vidioc_g_std(file, fh, &std);
1814 else if (std == 0) 1829 else if (std == 0)
1815 ret = -EINVAL; 1830 ret = -ENOTTY;
1816 if (ret == 0) 1831 if (ret == 0)
1817 v4l2_video_std_frame_period(std, 1832 v4l2_video_std_frame_period(std,
1818 &p->parm.capture.timeperframe); 1833 &p->parm.capture.timeperframe);