.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Video capture interface for Linux version 2 |
---|
3 | 4 | * |
---|
4 | 5 | * A generic framework to process V4L2 ioctl commands. |
---|
5 | | - * |
---|
6 | | - * This program is free software; you can redistribute it and/or |
---|
7 | | - * modify it under the terms of the GNU General Public License |
---|
8 | | - * as published by the Free Software Foundation; either version |
---|
9 | | - * 2 of the License, or (at your option) any later version. |
---|
10 | 6 | * |
---|
11 | 7 | * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1) |
---|
12 | 8 | * Mauro Carvalho Chehab <mchehab@kernel.org> (version 2) |
---|
.. | .. |
---|
32 | 28 | #include <media/v4l2-mem2mem.h> |
---|
33 | 29 | |
---|
34 | 30 | #include <trace/events/v4l2.h> |
---|
| 31 | +#include <trace/hooks/v4l2core.h> |
---|
| 32 | + |
---|
35 | 33 | |
---|
36 | 34 | /* Zero out the end of the struct pointed to by p. Everything after, but |
---|
37 | 35 | * not including, the specified field is cleared. */ |
---|
.. | .. |
---|
80 | 78 | { 0, "Unknown" } |
---|
81 | 79 | }; |
---|
82 | 80 | |
---|
| 81 | +static void clear_reserved(struct v4l2_format *p) |
---|
| 82 | +{ |
---|
| 83 | + int ret = 0; |
---|
| 84 | + |
---|
| 85 | + trace_android_vh_clear_reserved_fmt_fields(p, &ret); |
---|
| 86 | + if (!ret) |
---|
| 87 | + CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func); |
---|
| 88 | +} |
---|
| 89 | + |
---|
83 | 90 | /* video4linux standard ID conversion to standard name |
---|
84 | 91 | */ |
---|
85 | 92 | const char *v4l2_norm_to_name(v4l2_std_id id) |
---|
.. | .. |
---|
88 | 95 | int i; |
---|
89 | 96 | |
---|
90 | 97 | /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle |
---|
91 | | - 64 bit comparations. So, on that architecture, with some gcc |
---|
| 98 | + 64 bit comparisons. So, on that architecture, with some gcc |
---|
92 | 99 | variants, compilation fails. Currently, the max value is 30bit wide. |
---|
93 | 100 | */ |
---|
94 | 101 | BUG_ON(myid != id); |
---|
.. | .. |
---|
121 | 128 | vs->id = id; |
---|
122 | 129 | v4l2_video_std_frame_period(id, &vs->frameperiod); |
---|
123 | 130 | vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625; |
---|
124 | | - strlcpy(vs->name, name, sizeof(vs->name)); |
---|
| 131 | + strscpy(vs->name, name, sizeof(vs->name)); |
---|
125 | 132 | return 0; |
---|
126 | 133 | } |
---|
127 | 134 | EXPORT_SYMBOL(v4l2_video_std_construct); |
---|
.. | .. |
---|
268 | 275 | { |
---|
269 | 276 | const struct v4l2_fmtdesc *p = arg; |
---|
270 | 277 | |
---|
271 | | - pr_cont("index=%u, type=%s, flags=0x%x, pixelformat=%c%c%c%c, description='%.*s'\n", |
---|
| 278 | + pr_cont("index=%u, type=%s, flags=0x%x, pixelformat=%c%c%c%c, mbus_code=0x%04x, description='%.*s'\n", |
---|
272 | 279 | p->index, prt_names(p->type, v4l2_type_names), |
---|
273 | 280 | p->flags, (p->pixelformat & 0xff), |
---|
274 | 281 | (p->pixelformat >> 8) & 0xff, |
---|
275 | 282 | (p->pixelformat >> 16) & 0xff, |
---|
276 | 283 | (p->pixelformat >> 24) & 0xff, |
---|
| 284 | + p->mbus_code, |
---|
277 | 285 | (int)sizeof(p->description), p->description); |
---|
278 | 286 | } |
---|
279 | 287 | |
---|
.. | .. |
---|
478 | 486 | const struct v4l2_plane *plane; |
---|
479 | 487 | int i; |
---|
480 | 488 | |
---|
481 | | - pr_cont("%02ld:%02d:%02d.%08ld index=%d, type=%s, flags=0x%08x, field=%s, sequence=%d, memory=%s", |
---|
482 | | - p->timestamp.tv_sec / 3600, |
---|
483 | | - (int)(p->timestamp.tv_sec / 60) % 60, |
---|
484 | | - (int)(p->timestamp.tv_sec % 60), |
---|
| 489 | + pr_cont("%02d:%02d:%02d.%09ld index=%d, type=%s, request_fd=%d, flags=0x%08x, field=%s, sequence=%d, memory=%s", |
---|
| 490 | + (int)p->timestamp.tv_sec / 3600, |
---|
| 491 | + ((int)p->timestamp.tv_sec / 60) % 60, |
---|
| 492 | + ((int)p->timestamp.tv_sec % 60), |
---|
485 | 493 | (long)p->timestamp.tv_usec, |
---|
486 | 494 | p->index, |
---|
487 | | - prt_names(p->type, v4l2_type_names), |
---|
| 495 | + prt_names(p->type, v4l2_type_names), p->request_fd, |
---|
488 | 496 | p->flags, prt_names(p->field, v4l2_field_names), |
---|
489 | 497 | p->sequence, prt_names(p->memory, v4l2_memory_names)); |
---|
490 | 498 | |
---|
.. | .. |
---|
585 | 593 | static void v4l_print_control(const void *arg, bool write_only) |
---|
586 | 594 | { |
---|
587 | 595 | const struct v4l2_control *p = arg; |
---|
| 596 | + const char *name = v4l2_ctrl_get_name(p->id); |
---|
588 | 597 | |
---|
| 598 | + if (name) |
---|
| 599 | + pr_cont("name=%s, ", name); |
---|
589 | 600 | pr_cont("id=0x%x, value=%d\n", p->id, p->value); |
---|
590 | 601 | } |
---|
591 | 602 | |
---|
.. | .. |
---|
594 | 605 | const struct v4l2_ext_controls *p = arg; |
---|
595 | 606 | int i; |
---|
596 | 607 | |
---|
597 | | - pr_cont("which=0x%x, count=%d, error_idx=%d", |
---|
598 | | - p->which, p->count, p->error_idx); |
---|
| 608 | + pr_cont("which=0x%x, count=%d, error_idx=%d, request_fd=%d", |
---|
| 609 | + p->which, p->count, p->error_idx, p->request_fd); |
---|
599 | 610 | for (i = 0; i < p->count; i++) { |
---|
| 611 | + unsigned int id = p->controls[i].id; |
---|
| 612 | + const char *name = v4l2_ctrl_get_name(id); |
---|
| 613 | + |
---|
| 614 | + if (name) |
---|
| 615 | + pr_cont(", name=%s", name); |
---|
600 | 616 | if (!p->controls[i].size) |
---|
601 | | - pr_cont(", id/val=0x%x/0x%x", |
---|
602 | | - p->controls[i].id, p->controls[i].value); |
---|
| 617 | + pr_cont(", id/val=0x%x/0x%x", id, p->controls[i].value); |
---|
603 | 618 | else |
---|
604 | | - pr_cont(", id/size=0x%x/%u", |
---|
605 | | - p->controls[i].id, p->controls[i].size); |
---|
| 619 | + pr_cont(", id/size=0x%x/%u", id, p->controls[i].size); |
---|
606 | 620 | } |
---|
607 | 621 | pr_cont("\n"); |
---|
608 | 622 | } |
---|
.. | .. |
---|
779 | 793 | p->stepwise.step_height); |
---|
780 | 794 | break; |
---|
781 | 795 | case V4L2_FRMSIZE_TYPE_CONTINUOUS: |
---|
782 | | - /* fall through */ |
---|
783 | 796 | default: |
---|
784 | 797 | pr_cont("\n"); |
---|
785 | 798 | break; |
---|
.. | .. |
---|
813 | 826 | p->stepwise.step.denominator); |
---|
814 | 827 | break; |
---|
815 | 828 | case V4L2_FRMIVAL_TYPE_CONTINUOUS: |
---|
816 | | - /* fall through */ |
---|
817 | 829 | default: |
---|
818 | 830 | pr_cont("\n"); |
---|
819 | 831 | break; |
---|
.. | .. |
---|
825 | 837 | const struct v4l2_event *p = arg; |
---|
826 | 838 | const struct v4l2_event_ctrl *c; |
---|
827 | 839 | |
---|
828 | | - pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, timestamp=%lu.%9.9lu\n", |
---|
| 840 | + pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, timestamp=%llu.%9.9llu\n", |
---|
829 | 841 | p->type, p->pending, p->sequence, p->id, |
---|
830 | 842 | p->timestamp.tv_sec, p->timestamp.tv_nsec); |
---|
831 | 843 | switch (p->type) { |
---|
.. | .. |
---|
906 | 918 | pr_cont("driver-specific ioctl\n"); |
---|
907 | 919 | } |
---|
908 | 920 | |
---|
909 | | -static int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv) |
---|
| 921 | +static bool check_ext_ctrls(struct v4l2_ext_controls *c, unsigned long ioctl) |
---|
910 | 922 | { |
---|
911 | 923 | __u32 i; |
---|
912 | 924 | |
---|
913 | 925 | /* zero the reserved fields */ |
---|
914 | | - c->reserved[0] = c->reserved[1] = 0; |
---|
| 926 | + c->reserved[0] = 0; |
---|
915 | 927 | for (i = 0; i < c->count; i++) |
---|
916 | 928 | c->controls[i].reserved2[0] = 0; |
---|
917 | 929 | |
---|
918 | | - /* V4L2_CID_PRIVATE_BASE cannot be used as control class |
---|
919 | | - when using extended controls. |
---|
920 | | - Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL |
---|
921 | | - is it allowed for backwards compatibility. |
---|
922 | | - */ |
---|
923 | | - if (!allow_priv && c->which == V4L2_CID_PRIVATE_BASE) |
---|
924 | | - return 0; |
---|
925 | | - if (!c->which) |
---|
926 | | - return 1; |
---|
| 930 | + switch (c->which) { |
---|
| 931 | + case V4L2_CID_PRIVATE_BASE: |
---|
| 932 | + /* |
---|
| 933 | + * V4L2_CID_PRIVATE_BASE cannot be used as control class |
---|
| 934 | + * when using extended controls. |
---|
| 935 | + * Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL |
---|
| 936 | + * is it allowed for backwards compatibility. |
---|
| 937 | + */ |
---|
| 938 | + if (ioctl == VIDIOC_G_CTRL || ioctl == VIDIOC_S_CTRL) |
---|
| 939 | + return false; |
---|
| 940 | + break; |
---|
| 941 | + case V4L2_CTRL_WHICH_DEF_VAL: |
---|
| 942 | + /* Default value cannot be changed */ |
---|
| 943 | + if (ioctl == VIDIOC_S_EXT_CTRLS || |
---|
| 944 | + ioctl == VIDIOC_TRY_EXT_CTRLS) { |
---|
| 945 | + c->error_idx = c->count; |
---|
| 946 | + return false; |
---|
| 947 | + } |
---|
| 948 | + return true; |
---|
| 949 | + case V4L2_CTRL_WHICH_CUR_VAL: |
---|
| 950 | + return true; |
---|
| 951 | + case V4L2_CTRL_WHICH_REQUEST_VAL: |
---|
| 952 | + c->error_idx = c->count; |
---|
| 953 | + return false; |
---|
| 954 | + } |
---|
| 955 | + |
---|
927 | 956 | /* Check that all controls are from the same control class. */ |
---|
928 | 957 | for (i = 0; i < c->count; i++) { |
---|
929 | 958 | if (V4L2_CTRL_ID2WHICH(c->controls[i].id) != c->which) { |
---|
930 | | - c->error_idx = i; |
---|
931 | | - return 0; |
---|
| 959 | + c->error_idx = ioctl == VIDIOC_TRY_EXT_CTRLS ? i : |
---|
| 960 | + c->count; |
---|
| 961 | + return false; |
---|
932 | 962 | } |
---|
933 | 963 | } |
---|
934 | | - return 1; |
---|
| 964 | + return true; |
---|
935 | 965 | } |
---|
936 | 966 | |
---|
937 | 967 | static int check_fmt(struct file *file, enum v4l2_buf_type type) |
---|
938 | 968 | { |
---|
| 969 | + const u32 vid_caps = V4L2_CAP_VIDEO_CAPTURE | |
---|
| 970 | + V4L2_CAP_VIDEO_CAPTURE_MPLANE | |
---|
| 971 | + V4L2_CAP_VIDEO_OUTPUT | |
---|
| 972 | + V4L2_CAP_VIDEO_OUTPUT_MPLANE | |
---|
| 973 | + V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE; |
---|
| 974 | + const u32 meta_caps = V4L2_CAP_META_CAPTURE | |
---|
| 975 | + V4L2_CAP_META_OUTPUT; |
---|
939 | 976 | struct video_device *vfd = video_devdata(file); |
---|
940 | 977 | const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; |
---|
941 | | - bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER; |
---|
| 978 | + bool is_vid = vfd->vfl_type == VFL_TYPE_VIDEO && |
---|
| 979 | + (vfd->device_caps & vid_caps); |
---|
942 | 980 | bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI; |
---|
943 | 981 | bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR; |
---|
944 | 982 | bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH; |
---|
| 983 | + bool is_meta = vfd->vfl_type == VFL_TYPE_VIDEO && |
---|
| 984 | + (vfd->device_caps & meta_caps); |
---|
945 | 985 | bool is_rx = vfd->vfl_dir != VFL_DIR_TX; |
---|
946 | 986 | bool is_tx = vfd->vfl_dir != VFL_DIR_RX; |
---|
947 | 987 | |
---|
.. | .. |
---|
955 | 995 | return 0; |
---|
956 | 996 | break; |
---|
957 | 997 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
---|
958 | | - if (is_vid && is_rx && ops->vidioc_g_fmt_vid_cap_mplane) |
---|
| 998 | + if ((is_vid || is_tch) && is_rx && ops->vidioc_g_fmt_vid_cap_mplane) |
---|
959 | 999 | return 0; |
---|
960 | 1000 | break; |
---|
961 | 1001 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
---|
.. | .. |
---|
1000 | 1040 | return 0; |
---|
1001 | 1041 | break; |
---|
1002 | 1042 | case V4L2_BUF_TYPE_META_CAPTURE: |
---|
1003 | | - if (is_vid && is_rx && ops->vidioc_g_fmt_meta_cap) |
---|
| 1043 | + if (is_meta && is_rx && ops->vidioc_g_fmt_meta_cap) |
---|
1004 | 1044 | return 0; |
---|
1005 | 1045 | break; |
---|
1006 | 1046 | case V4L2_BUF_TYPE_META_OUTPUT: |
---|
1007 | | - if (is_vid && is_tx && ops->vidioc_g_fmt_meta_out) |
---|
| 1047 | + if (is_meta && is_tx && ops->vidioc_g_fmt_meta_out) |
---|
1008 | 1048 | return 0; |
---|
1009 | 1049 | break; |
---|
1010 | 1050 | default: |
---|
.. | .. |
---|
1016 | 1056 | static void v4l_sanitize_format(struct v4l2_format *fmt) |
---|
1017 | 1057 | { |
---|
1018 | 1058 | unsigned int offset; |
---|
| 1059 | + |
---|
| 1060 | + /* Make sure num_planes is not bogus */ |
---|
| 1061 | + if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE || |
---|
| 1062 | + fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) |
---|
| 1063 | + fmt->fmt.pix_mp.num_planes = min_t(u32, fmt->fmt.pix_mp.num_planes, |
---|
| 1064 | + VIDEO_MAX_PLANES); |
---|
1019 | 1065 | |
---|
1020 | 1066 | /* |
---|
1021 | 1067 | * The v4l2_pix_format structure has been extended with fields that were |
---|
.. | .. |
---|
1055 | 1101 | |
---|
1056 | 1102 | ret = ops->vidioc_querycap(file, fh, cap); |
---|
1057 | 1103 | |
---|
1058 | | - cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT; |
---|
1059 | 1104 | /* |
---|
1060 | | - * Drivers MUST fill in device_caps, so check for this and |
---|
1061 | | - * warn if it was forgotten. |
---|
| 1105 | + * Drivers must not change device_caps, so check for this and |
---|
| 1106 | + * warn if this happened. |
---|
1062 | 1107 | */ |
---|
1063 | | - WARN(!(cap->capabilities & V4L2_CAP_DEVICE_CAPS) || |
---|
1064 | | - !cap->device_caps, "Bad caps for driver %s, %x %x", |
---|
1065 | | - cap->driver, cap->capabilities, cap->device_caps); |
---|
| 1108 | + WARN_ON(cap->device_caps != vfd->device_caps); |
---|
| 1109 | + /* |
---|
| 1110 | + * Check that capabilities is a superset of |
---|
| 1111 | + * vfd->device_caps | V4L2_CAP_DEVICE_CAPS |
---|
| 1112 | + */ |
---|
| 1113 | + WARN_ON((cap->capabilities & |
---|
| 1114 | + (vfd->device_caps | V4L2_CAP_DEVICE_CAPS)) != |
---|
| 1115 | + (vfd->device_caps | V4L2_CAP_DEVICE_CAPS)); |
---|
| 1116 | + cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT; |
---|
1066 | 1117 | cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT; |
---|
1067 | 1118 | |
---|
1068 | 1119 | return ret; |
---|
| 1120 | +} |
---|
| 1121 | + |
---|
| 1122 | +static int v4l_g_input(const struct v4l2_ioctl_ops *ops, |
---|
| 1123 | + struct file *file, void *fh, void *arg) |
---|
| 1124 | +{ |
---|
| 1125 | + struct video_device *vfd = video_devdata(file); |
---|
| 1126 | + |
---|
| 1127 | + if (vfd->device_caps & V4L2_CAP_IO_MC) { |
---|
| 1128 | + *(int *)arg = 0; |
---|
| 1129 | + return 0; |
---|
| 1130 | + } |
---|
| 1131 | + |
---|
| 1132 | + return ops->vidioc_g_input(file, fh, arg); |
---|
| 1133 | +} |
---|
| 1134 | + |
---|
| 1135 | +static int v4l_g_output(const struct v4l2_ioctl_ops *ops, |
---|
| 1136 | + struct file *file, void *fh, void *arg) |
---|
| 1137 | +{ |
---|
| 1138 | + struct video_device *vfd = video_devdata(file); |
---|
| 1139 | + |
---|
| 1140 | + if (vfd->device_caps & V4L2_CAP_IO_MC) { |
---|
| 1141 | + *(int *)arg = 0; |
---|
| 1142 | + return 0; |
---|
| 1143 | + } |
---|
| 1144 | + |
---|
| 1145 | + return ops->vidioc_g_output(file, fh, arg); |
---|
1069 | 1146 | } |
---|
1070 | 1147 | |
---|
1071 | 1148 | static int v4l_s_input(const struct v4l2_ioctl_ops *ops, |
---|
.. | .. |
---|
1077 | 1154 | ret = v4l_enable_media_source(vfd); |
---|
1078 | 1155 | if (ret) |
---|
1079 | 1156 | return ret; |
---|
| 1157 | + |
---|
| 1158 | + if (vfd->device_caps & V4L2_CAP_IO_MC) |
---|
| 1159 | + return *(int *)arg ? -EINVAL : 0; |
---|
| 1160 | + |
---|
1080 | 1161 | return ops->vidioc_s_input(file, fh, *(unsigned int *)arg); |
---|
1081 | 1162 | } |
---|
1082 | 1163 | |
---|
1083 | 1164 | static int v4l_s_output(const struct v4l2_ioctl_ops *ops, |
---|
1084 | 1165 | struct file *file, void *fh, void *arg) |
---|
1085 | 1166 | { |
---|
| 1167 | + struct video_device *vfd = video_devdata(file); |
---|
| 1168 | + |
---|
| 1169 | + if (vfd->device_caps & V4L2_CAP_IO_MC) |
---|
| 1170 | + return *(int *)arg ? -EINVAL : 0; |
---|
| 1171 | + |
---|
1086 | 1172 | return ops->vidioc_s_output(file, fh, *(unsigned int *)arg); |
---|
1087 | 1173 | } |
---|
1088 | 1174 | |
---|
.. | .. |
---|
1126 | 1212 | if (is_valid_ioctl(vfd, VIDIOC_S_STD)) |
---|
1127 | 1213 | p->capabilities |= V4L2_IN_CAP_STD; |
---|
1128 | 1214 | |
---|
| 1215 | + if (vfd->device_caps & V4L2_CAP_IO_MC) { |
---|
| 1216 | + if (p->index) |
---|
| 1217 | + return -EINVAL; |
---|
| 1218 | + strscpy(p->name, vfd->name, sizeof(p->name)); |
---|
| 1219 | + p->type = V4L2_INPUT_TYPE_CAMERA; |
---|
| 1220 | + return 0; |
---|
| 1221 | + } |
---|
| 1222 | + |
---|
1129 | 1223 | return ops->vidioc_enum_input(file, fh, p); |
---|
1130 | 1224 | } |
---|
1131 | 1225 | |
---|
.. | .. |
---|
1143 | 1237 | */ |
---|
1144 | 1238 | if (is_valid_ioctl(vfd, VIDIOC_S_STD)) |
---|
1145 | 1239 | p->capabilities |= V4L2_OUT_CAP_STD; |
---|
| 1240 | + |
---|
| 1241 | + if (vfd->device_caps & V4L2_CAP_IO_MC) { |
---|
| 1242 | + if (p->index) |
---|
| 1243 | + return -EINVAL; |
---|
| 1244 | + strscpy(p->name, vfd->name, sizeof(p->name)); |
---|
| 1245 | + p->type = V4L2_OUTPUT_TYPE_ANALOG; |
---|
| 1246 | + return 0; |
---|
| 1247 | + } |
---|
1146 | 1248 | |
---|
1147 | 1249 | return ops->vidioc_enum_output(file, fh, p); |
---|
1148 | 1250 | } |
---|
.. | .. |
---|
1167 | 1269 | case V4L2_PIX_FMT_RGB444: descr = "16-bit A/XRGB 4-4-4-4"; break; |
---|
1168 | 1270 | case V4L2_PIX_FMT_ARGB444: descr = "16-bit ARGB 4-4-4-4"; break; |
---|
1169 | 1271 | case V4L2_PIX_FMT_XRGB444: descr = "16-bit XRGB 4-4-4-4"; break; |
---|
| 1272 | + case V4L2_PIX_FMT_RGBA444: descr = "16-bit RGBA 4-4-4-4"; break; |
---|
| 1273 | + case V4L2_PIX_FMT_RGBX444: descr = "16-bit RGBX 4-4-4-4"; break; |
---|
| 1274 | + case V4L2_PIX_FMT_ABGR444: descr = "16-bit ABGR 4-4-4-4"; break; |
---|
| 1275 | + case V4L2_PIX_FMT_XBGR444: descr = "16-bit XBGR 4-4-4-4"; break; |
---|
| 1276 | + case V4L2_PIX_FMT_BGRA444: descr = "16-bit BGRA 4-4-4-4"; break; |
---|
| 1277 | + case V4L2_PIX_FMT_BGRX444: descr = "16-bit BGRX 4-4-4-4"; break; |
---|
1170 | 1278 | case V4L2_PIX_FMT_RGB555: descr = "16-bit A/XRGB 1-5-5-5"; break; |
---|
1171 | 1279 | case V4L2_PIX_FMT_ARGB555: descr = "16-bit ARGB 1-5-5-5"; break; |
---|
1172 | 1280 | case V4L2_PIX_FMT_XRGB555: descr = "16-bit XRGB 1-5-5-5"; break; |
---|
| 1281 | + case V4L2_PIX_FMT_ABGR555: descr = "16-bit ABGR 1-5-5-5"; break; |
---|
| 1282 | + case V4L2_PIX_FMT_XBGR555: descr = "16-bit XBGR 1-5-5-5"; break; |
---|
| 1283 | + case V4L2_PIX_FMT_RGBA555: descr = "16-bit RGBA 5-5-5-1"; break; |
---|
| 1284 | + case V4L2_PIX_FMT_RGBX555: descr = "16-bit RGBX 5-5-5-1"; break; |
---|
| 1285 | + case V4L2_PIX_FMT_BGRA555: descr = "16-bit BGRA 5-5-5-1"; break; |
---|
| 1286 | + case V4L2_PIX_FMT_BGRX555: descr = "16-bit BGRX 5-5-5-1"; break; |
---|
1173 | 1287 | case V4L2_PIX_FMT_RGB565: descr = "16-bit RGB 5-6-5"; break; |
---|
1174 | 1288 | case V4L2_PIX_FMT_RGB555X: descr = "16-bit A/XRGB 1-5-5-5 BE"; break; |
---|
1175 | 1289 | case V4L2_PIX_FMT_ARGB555X: descr = "16-bit ARGB 1-5-5-5 BE"; break; |
---|
.. | .. |
---|
1184 | 1298 | case V4L2_PIX_FMT_RGB32: descr = "32-bit A/XRGB 8-8-8-8"; break; |
---|
1185 | 1299 | case V4L2_PIX_FMT_ARGB32: descr = "32-bit ARGB 8-8-8-8"; break; |
---|
1186 | 1300 | case V4L2_PIX_FMT_XRGB32: descr = "32-bit XRGB 8-8-8-8"; break; |
---|
| 1301 | + case V4L2_PIX_FMT_BGRA32: descr = "32-bit ABGR 8-8-8-8"; break; |
---|
| 1302 | + case V4L2_PIX_FMT_BGRX32: descr = "32-bit XBGR 8-8-8-8"; break; |
---|
| 1303 | + case V4L2_PIX_FMT_RGBA32: descr = "32-bit RGBA 8-8-8-8"; break; |
---|
| 1304 | + case V4L2_PIX_FMT_RGBX32: descr = "32-bit RGBX 8-8-8-8"; break; |
---|
1187 | 1305 | case V4L2_PIX_FMT_GREY: descr = "8-bit Greyscale"; break; |
---|
1188 | 1306 | case V4L2_PIX_FMT_Y4: descr = "4-bit Greyscale"; break; |
---|
1189 | 1307 | case V4L2_PIX_FMT_Y6: descr = "6-bit Greyscale"; break; |
---|
1190 | 1308 | case V4L2_PIX_FMT_Y10: descr = "10-bit Greyscale"; break; |
---|
1191 | 1309 | case V4L2_PIX_FMT_Y12: descr = "12-bit Greyscale"; break; |
---|
| 1310 | + case V4L2_PIX_FMT_Y14: descr = "14-bit Greyscale"; break; |
---|
1192 | 1311 | case V4L2_PIX_FMT_Y16: descr = "16-bit Greyscale"; break; |
---|
1193 | 1312 | case V4L2_PIX_FMT_Y16_BE: descr = "16-bit Greyscale BE"; break; |
---|
1194 | 1313 | case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; break; |
---|
.. | .. |
---|
1197 | 1316 | case V4L2_PIX_FMT_Y12I: descr = "Interleaved 12-bit Greyscale"; break; |
---|
1198 | 1317 | case V4L2_PIX_FMT_Z16: descr = "16-bit Depth"; break; |
---|
1199 | 1318 | case V4L2_PIX_FMT_INZI: descr = "Planar 10:16 Greyscale Depth"; break; |
---|
| 1319 | + case V4L2_PIX_FMT_CNF4: descr = "4-bit Depth Confidence (Packed)"; break; |
---|
1200 | 1320 | case V4L2_PIX_FMT_PAL8: descr = "8-bit Palette"; break; |
---|
1201 | 1321 | case V4L2_PIX_FMT_UV8: descr = "8-bit Chrominance UV 4-4"; break; |
---|
1202 | 1322 | case V4L2_PIX_FMT_YVU410: descr = "Planar YVU 4:1:0"; break; |
---|
.. | .. |
---|
1213 | 1333 | case V4L2_PIX_FMT_YUV555: descr = "16-bit A/XYUV 1-5-5-5"; break; |
---|
1214 | 1334 | case V4L2_PIX_FMT_YUV565: descr = "16-bit YUV 5-6-5"; break; |
---|
1215 | 1335 | case V4L2_PIX_FMT_YUV32: descr = "32-bit A/XYUV 8-8-8-8"; break; |
---|
| 1336 | + case V4L2_PIX_FMT_AYUV32: descr = "32-bit AYUV 8-8-8-8"; break; |
---|
| 1337 | + case V4L2_PIX_FMT_XYUV32: descr = "32-bit XYUV 8-8-8-8"; break; |
---|
| 1338 | + case V4L2_PIX_FMT_VUYA32: descr = "32-bit VUYA 8-8-8-8"; break; |
---|
| 1339 | + case V4L2_PIX_FMT_VUYX32: descr = "32-bit VUYX 8-8-8-8"; break; |
---|
1216 | 1340 | case V4L2_PIX_FMT_YUV410: descr = "Planar YUV 4:1:0"; break; |
---|
1217 | 1341 | case V4L2_PIX_FMT_YUV420: descr = "Planar YUV 4:2:0"; break; |
---|
1218 | 1342 | case V4L2_PIX_FMT_HI240: descr = "8-bit Dithered RGB (BTTV)"; break; |
---|
.. | .. |
---|
1268 | 1392 | case V4L2_PIX_FMT_SGBRG12P: descr = "12-bit Bayer GBGB/RGRG Packed"; break; |
---|
1269 | 1393 | case V4L2_PIX_FMT_SGRBG12P: descr = "12-bit Bayer GRGR/BGBG Packed"; break; |
---|
1270 | 1394 | case V4L2_PIX_FMT_SRGGB12P: descr = "12-bit Bayer RGRG/GBGB Packed"; break; |
---|
| 1395 | + case V4L2_PIX_FMT_SBGGR14: descr = "14-bit Bayer BGBG/GRGR"; break; |
---|
| 1396 | + case V4L2_PIX_FMT_SGBRG14: descr = "14-bit Bayer GBGB/RGRG"; break; |
---|
| 1397 | + case V4L2_PIX_FMT_SGRBG14: descr = "14-bit Bayer GRGR/BGBG"; break; |
---|
| 1398 | + case V4L2_PIX_FMT_SRGGB14: descr = "14-bit Bayer RGRG/GBGB"; break; |
---|
1271 | 1399 | case V4L2_PIX_FMT_SBGGR14P: descr = "14-bit Bayer BGBG/GRGR Packed"; break; |
---|
1272 | 1400 | case V4L2_PIX_FMT_SGBRG14P: descr = "14-bit Bayer GBGB/RGRG Packed"; break; |
---|
1273 | 1401 | case V4L2_PIX_FMT_SGRBG14P: descr = "14-bit Bayer GRGR/BGBG Packed"; break; |
---|
.. | .. |
---|
1294 | 1422 | case V4L2_SDR_FMT_PCU16BE: descr = "Planar Complex U16BE"; break; |
---|
1295 | 1423 | case V4L2_SDR_FMT_PCU18BE: descr = "Planar Complex U18BE"; break; |
---|
1296 | 1424 | case V4L2_SDR_FMT_PCU20BE: descr = "Planar Complex U20BE"; break; |
---|
1297 | | - case V4L2_TCH_FMT_DELTA_TD16: descr = "16-bit signed deltas"; break; |
---|
1298 | | - case V4L2_TCH_FMT_DELTA_TD08: descr = "8-bit signed deltas"; break; |
---|
1299 | | - case V4L2_TCH_FMT_TU16: descr = "16-bit unsigned touch data"; break; |
---|
1300 | | - case V4L2_TCH_FMT_TU08: descr = "8-bit unsigned touch data"; break; |
---|
| 1425 | + case V4L2_TCH_FMT_DELTA_TD16: descr = "16-bit Signed Deltas"; break; |
---|
| 1426 | + case V4L2_TCH_FMT_DELTA_TD08: descr = "8-bit Signed Deltas"; break; |
---|
| 1427 | + case V4L2_TCH_FMT_TU16: descr = "16-bit Unsigned Touch Data"; break; |
---|
| 1428 | + case V4L2_TCH_FMT_TU08: descr = "8-bit Unsigned Touch Data"; break; |
---|
1301 | 1429 | case V4L2_META_FMT_VSP1_HGO: descr = "R-Car VSP1 1-D Histogram"; break; |
---|
1302 | 1430 | case V4L2_META_FMT_VSP1_HGT: descr = "R-Car VSP1 2-D Histogram"; break; |
---|
1303 | | - case V4L2_META_FMT_UVC: descr = "UVC payload header metadata"; break; |
---|
1304 | | - case V4L2_PIX_FMT_NV12_UBWC: |
---|
1305 | | - descr = "NV12 UBWC"; break; |
---|
1306 | | - case V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010_VENUS: |
---|
1307 | | - descr = "Y/CbCr 4:2:0 P10 Venus"; break; |
---|
1308 | | - case V4L2_PIX_FMT_NV12_TP10_UBWC: |
---|
1309 | | - descr = "Y/CbCr 4:2:0 TP10 UBWC"; break; |
---|
1310 | | - case V4L2_PIX_FMT_NV12_512: |
---|
1311 | | - descr = "Y/CbCr 4:2:0 (512 align)"; break; |
---|
1312 | | - case V4L2_META_FMT_RK_ISP1_PARAMS: |
---|
1313 | | - descr = "Rockchip ISP1 3A params"; |
---|
1314 | | - break; |
---|
1315 | | - case V4L2_META_FMT_RK_ISP1_STAT_3A: |
---|
1316 | | - descr = "Rockchip ISP1 3A statistics"; |
---|
1317 | | - break; |
---|
| 1431 | + case V4L2_META_FMT_UVC: descr = "UVC Payload Header Metadata"; break; |
---|
| 1432 | + case V4L2_META_FMT_D4XX: descr = "Intel D4xx UVC Metadata"; break; |
---|
| 1433 | + case V4L2_META_FMT_VIVID: descr = "Vivid Metadata"; break; |
---|
1318 | 1434 | |
---|
1319 | 1435 | default: |
---|
1320 | 1436 | /* Compressed formats */ |
---|
.. | .. |
---|
1328 | 1444 | case V4L2_PIX_FMT_H264: descr = "H.264"; break; |
---|
1329 | 1445 | case V4L2_PIX_FMT_H264_NO_SC: descr = "H.264 (No Start Codes)"; break; |
---|
1330 | 1446 | case V4L2_PIX_FMT_H264_MVC: descr = "H.264 MVC"; break; |
---|
| 1447 | + case V4L2_PIX_FMT_H264_SLICE: descr = "H.264 Parsed Slice Data"; break; |
---|
1331 | 1448 | case V4L2_PIX_FMT_H263: descr = "H.263"; break; |
---|
1332 | 1449 | case V4L2_PIX_FMT_MPEG1: descr = "MPEG-1 ES"; break; |
---|
1333 | 1450 | case V4L2_PIX_FMT_MPEG2: descr = "MPEG-2 ES"; break; |
---|
1334 | | - case V4L2_PIX_FMT_MPEG4: descr = "MPEG-4 part 2 ES"; break; |
---|
| 1451 | + case V4L2_PIX_FMT_MPEG2_SLICE: descr = "MPEG-2 Parsed Slice Data"; break; |
---|
| 1452 | + case V4L2_PIX_FMT_MPEG4: descr = "MPEG-4 Part 2 ES"; break; |
---|
1335 | 1453 | case V4L2_PIX_FMT_XVID: descr = "Xvid"; break; |
---|
1336 | 1454 | case V4L2_PIX_FMT_VC1_ANNEX_G: descr = "VC-1 (SMPTE 412M Annex G)"; break; |
---|
1337 | 1455 | case V4L2_PIX_FMT_VC1_ANNEX_L: descr = "VC-1 (SMPTE 412M Annex L)"; break; |
---|
1338 | 1456 | case V4L2_PIX_FMT_VP8: descr = "VP8"; break; |
---|
| 1457 | + case V4L2_PIX_FMT_VP8_FRAME: descr = "VP8 Frame"; break; |
---|
1339 | 1458 | case V4L2_PIX_FMT_VP9: descr = "VP9"; break; |
---|
1340 | 1459 | case V4L2_PIX_FMT_HEVC: descr = "HEVC"; break; /* aka H.265 */ |
---|
| 1460 | + case V4L2_PIX_FMT_HEVC_SLICE: descr = "HEVC Parsed Slice Data"; break; |
---|
1341 | 1461 | case V4L2_PIX_FMT_FWHT: descr = "FWHT"; break; /* used in vicodec */ |
---|
| 1462 | + case V4L2_PIX_FMT_FWHT_STATELESS: descr = "FWHT Stateless"; break; /* used in vicodec */ |
---|
1342 | 1463 | case V4L2_PIX_FMT_CPIA1: descr = "GSPCA CPiA YUV"; break; |
---|
1343 | 1464 | case V4L2_PIX_FMT_WNVA: descr = "WNVA"; break; |
---|
1344 | 1465 | case V4L2_PIX_FMT_SN9C10X: descr = "GSPCA SN9C10X"; break; |
---|
.. | .. |
---|
1358 | 1479 | case V4L2_PIX_FMT_SE401: descr = "GSPCA SE401"; break; |
---|
1359 | 1480 | case V4L2_PIX_FMT_S5C_UYVY_JPG: descr = "S5C73MX interleaved UYVY/JPEG"; break; |
---|
1360 | 1481 | case V4L2_PIX_FMT_MT21C: descr = "Mediatek Compressed Format"; break; |
---|
1361 | | - case V4L2_PIX_FMT_FBC2: descr = "Rockchip yuv422sp fbc encoder"; break; |
---|
1362 | | - case V4L2_PIX_FMT_FBC0: descr = "Rockchip yuv420sp fbc encoder"; break; |
---|
1363 | | - case V4L2_PIX_FMT_FBCG: descr = "Rockchip fbc gain"; break; |
---|
1364 | | - case V4l2_PIX_FMT_EBD8: descr = "Embedded data 8-bit"; break; |
---|
1365 | | - case V4l2_PIX_FMT_SPD16: descr = "Shield pix data 16-bit"; break; |
---|
| 1482 | + case V4L2_PIX_FMT_SUNXI_TILED_NV12: descr = "Sunxi Tiled NV12 Format"; break; |
---|
1366 | 1483 | default: |
---|
1367 | | - WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat); |
---|
| 1484 | + trace_android_vh_fill_ext_fmtdesc(fmt, &descr); |
---|
| 1485 | + if (descr) |
---|
| 1486 | + break; |
---|
1368 | 1487 | if (fmt->description[0]) |
---|
1369 | 1488 | return; |
---|
| 1489 | + WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat); |
---|
1370 | 1490 | flags = 0; |
---|
1371 | 1491 | snprintf(fmt->description, sz, "%c%c%c%c%s", |
---|
1372 | 1492 | (char)(fmt->pixelformat & 0x7f), |
---|
1373 | 1493 | (char)((fmt->pixelformat >> 8) & 0x7f), |
---|
1374 | 1494 | (char)((fmt->pixelformat >> 16) & 0x7f), |
---|
1375 | 1495 | (char)((fmt->pixelformat >> 24) & 0x7f), |
---|
1376 | | - (fmt->pixelformat & (1 << 31)) ? "-BE" : ""); |
---|
| 1496 | + (fmt->pixelformat & (1UL << 31)) ? "-BE" : ""); |
---|
1377 | 1497 | break; |
---|
1378 | 1498 | } |
---|
1379 | 1499 | } |
---|
1380 | 1500 | |
---|
1381 | 1501 | if (descr) |
---|
1382 | | - WARN_ON(strlcpy(fmt->description, descr, sz) >= sz); |
---|
1383 | | - fmt->flags = flags; |
---|
| 1502 | + WARN_ON(strscpy(fmt->description, descr, sz) < 0); |
---|
| 1503 | + fmt->flags |= flags; |
---|
1384 | 1504 | } |
---|
1385 | 1505 | |
---|
1386 | 1506 | static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops, |
---|
1387 | 1507 | struct file *file, void *fh, void *arg) |
---|
1388 | 1508 | { |
---|
| 1509 | + struct video_device *vdev = video_devdata(file); |
---|
1389 | 1510 | struct v4l2_fmtdesc *p = arg; |
---|
1390 | 1511 | int ret = check_fmt(file, p->type); |
---|
| 1512 | + u32 mbus_code; |
---|
| 1513 | + u32 cap_mask; |
---|
1391 | 1514 | |
---|
1392 | 1515 | if (ret) |
---|
1393 | 1516 | return ret; |
---|
1394 | 1517 | ret = -EINVAL; |
---|
1395 | 1518 | |
---|
| 1519 | + if (!(vdev->device_caps & V4L2_CAP_IO_MC)) |
---|
| 1520 | + p->mbus_code = 0; |
---|
| 1521 | + |
---|
| 1522 | + mbus_code = p->mbus_code; |
---|
| 1523 | + CLEAR_AFTER_FIELD(p, type); |
---|
| 1524 | + p->mbus_code = mbus_code; |
---|
| 1525 | + |
---|
1396 | 1526 | switch (p->type) { |
---|
1397 | 1527 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
---|
| 1528 | + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
---|
| 1529 | + cap_mask = V4L2_CAP_VIDEO_CAPTURE_MPLANE | |
---|
| 1530 | + V4L2_CAP_VIDEO_M2M_MPLANE; |
---|
| 1531 | + if (!!(vdev->device_caps & cap_mask) != |
---|
| 1532 | + (p->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)) |
---|
| 1533 | + break; |
---|
| 1534 | + |
---|
1398 | 1535 | if (unlikely(!ops->vidioc_enum_fmt_vid_cap)) |
---|
1399 | 1536 | break; |
---|
1400 | 1537 | ret = ops->vidioc_enum_fmt_vid_cap(file, fh, arg); |
---|
1401 | | - break; |
---|
1402 | | - case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
---|
1403 | | - if (unlikely(!ops->vidioc_enum_fmt_vid_cap_mplane)) |
---|
1404 | | - break; |
---|
1405 | | - ret = ops->vidioc_enum_fmt_vid_cap_mplane(file, fh, arg); |
---|
1406 | 1538 | break; |
---|
1407 | 1539 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
---|
1408 | 1540 | if (unlikely(!ops->vidioc_enum_fmt_vid_overlay)) |
---|
.. | .. |
---|
1410 | 1542 | ret = ops->vidioc_enum_fmt_vid_overlay(file, fh, arg); |
---|
1411 | 1543 | break; |
---|
1412 | 1544 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: |
---|
| 1545 | + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: |
---|
| 1546 | + cap_mask = V4L2_CAP_VIDEO_OUTPUT_MPLANE | |
---|
| 1547 | + V4L2_CAP_VIDEO_M2M_MPLANE; |
---|
| 1548 | + if (!!(vdev->device_caps & cap_mask) != |
---|
| 1549 | + (p->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)) |
---|
| 1550 | + break; |
---|
| 1551 | + |
---|
1413 | 1552 | if (unlikely(!ops->vidioc_enum_fmt_vid_out)) |
---|
1414 | 1553 | break; |
---|
1415 | 1554 | ret = ops->vidioc_enum_fmt_vid_out(file, fh, arg); |
---|
1416 | | - break; |
---|
1417 | | - case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: |
---|
1418 | | - if (unlikely(!ops->vidioc_enum_fmt_vid_out_mplane)) |
---|
1419 | | - break; |
---|
1420 | | - ret = ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg); |
---|
1421 | 1555 | break; |
---|
1422 | 1556 | case V4L2_BUF_TYPE_SDR_CAPTURE: |
---|
1423 | 1557 | if (unlikely(!ops->vidioc_enum_fmt_sdr_cap)) |
---|
.. | .. |
---|
1547 | 1681 | struct v4l2_format *p = arg; |
---|
1548 | 1682 | struct video_device *vfd = video_devdata(file); |
---|
1549 | 1683 | int ret = check_fmt(file, p->type); |
---|
| 1684 | + unsigned int i; |
---|
1550 | 1685 | |
---|
1551 | 1686 | if (ret) |
---|
1552 | 1687 | return ret; |
---|
.. | .. |
---|
1570 | 1705 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
---|
1571 | 1706 | if (unlikely(!ops->vidioc_s_fmt_vid_cap_mplane)) |
---|
1572 | 1707 | break; |
---|
1573 | | - CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func); |
---|
| 1708 | + clear_reserved(p); |
---|
| 1709 | + for (i = 0; i < p->fmt.pix_mp.num_planes; i++) |
---|
| 1710 | + CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i], |
---|
| 1711 | + bytesperline); |
---|
1574 | 1712 | return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg); |
---|
1575 | 1713 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
---|
1576 | 1714 | if (unlikely(!ops->vidioc_s_fmt_vid_overlay)) |
---|
.. | .. |
---|
1598 | 1736 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: |
---|
1599 | 1737 | if (unlikely(!ops->vidioc_s_fmt_vid_out_mplane)) |
---|
1600 | 1738 | break; |
---|
1601 | | - CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func); |
---|
| 1739 | + clear_reserved(p); |
---|
| 1740 | + for (i = 0; i < p->fmt.pix_mp.num_planes; i++) |
---|
| 1741 | + CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i], |
---|
| 1742 | + bytesperline); |
---|
1602 | 1743 | return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg); |
---|
1603 | 1744 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: |
---|
1604 | 1745 | if (unlikely(!ops->vidioc_s_fmt_vid_out_overlay)) |
---|
.. | .. |
---|
1643 | 1784 | struct file *file, void *fh, void *arg) |
---|
1644 | 1785 | { |
---|
1645 | 1786 | struct v4l2_format *p = arg; |
---|
| 1787 | + struct video_device *vfd = video_devdata(file); |
---|
1646 | 1788 | int ret = check_fmt(file, p->type); |
---|
| 1789 | + unsigned int i; |
---|
1647 | 1790 | |
---|
1648 | 1791 | if (ret) |
---|
1649 | 1792 | return ret; |
---|
.. | .. |
---|
1658 | 1801 | ret = ops->vidioc_try_fmt_vid_cap(file, fh, arg); |
---|
1659 | 1802 | /* just in case the driver zeroed it again */ |
---|
1660 | 1803 | p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; |
---|
| 1804 | + if (vfd->vfl_type == VFL_TYPE_TOUCH) |
---|
| 1805 | + v4l_pix_format_touch(&p->fmt.pix); |
---|
1661 | 1806 | return ret; |
---|
1662 | 1807 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
---|
1663 | 1808 | if (unlikely(!ops->vidioc_try_fmt_vid_cap_mplane)) |
---|
1664 | 1809 | break; |
---|
1665 | | - CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func); |
---|
| 1810 | + clear_reserved(p); |
---|
| 1811 | + for (i = 0; i < p->fmt.pix_mp.num_planes; i++) |
---|
| 1812 | + CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i], |
---|
| 1813 | + bytesperline); |
---|
1666 | 1814 | return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg); |
---|
1667 | 1815 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
---|
1668 | 1816 | if (unlikely(!ops->vidioc_try_fmt_vid_overlay)) |
---|
.. | .. |
---|
1690 | 1838 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: |
---|
1691 | 1839 | if (unlikely(!ops->vidioc_try_fmt_vid_out_mplane)) |
---|
1692 | 1840 | break; |
---|
1693 | | - CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func); |
---|
| 1841 | + clear_reserved(p); |
---|
| 1842 | + for (i = 0; i < p->fmt.pix_mp.num_planes; i++) |
---|
| 1843 | + CLEAR_AFTER_FIELD(&p->fmt.pix_mp.plane_fmt[i], |
---|
| 1844 | + bytesperline); |
---|
1694 | 1845 | return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg); |
---|
1695 | 1846 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: |
---|
1696 | 1847 | if (unlikely(!ops->vidioc_try_fmt_vid_out_overlay)) |
---|
.. | .. |
---|
1924 | 2075 | if (ret) |
---|
1925 | 2076 | return ret; |
---|
1926 | 2077 | |
---|
1927 | | - CLEAR_AFTER_FIELD(p, memory); |
---|
| 2078 | + CLEAR_AFTER_FIELD(p, capabilities); |
---|
1928 | 2079 | |
---|
1929 | 2080 | return ops->vidioc_reqbufs(file, fh, p); |
---|
1930 | 2081 | } |
---|
.. | .. |
---|
1965 | 2116 | if (ret) |
---|
1966 | 2117 | return ret; |
---|
1967 | 2118 | |
---|
1968 | | - CLEAR_AFTER_FIELD(create, format); |
---|
| 2119 | + CLEAR_AFTER_FIELD(create, capabilities); |
---|
1969 | 2120 | |
---|
1970 | 2121 | v4l_sanitize_format(&create->format); |
---|
1971 | 2122 | |
---|
.. | .. |
---|
1990 | 2141 | static int v4l_g_parm(const struct v4l2_ioctl_ops *ops, |
---|
1991 | 2142 | struct file *file, void *fh, void *arg) |
---|
1992 | 2143 | { |
---|
| 2144 | + struct video_device *vfd = video_devdata(file); |
---|
1993 | 2145 | struct v4l2_streamparm *p = arg; |
---|
1994 | 2146 | v4l2_std_id std; |
---|
1995 | 2147 | int ret = check_fmt(file, p->type); |
---|
.. | .. |
---|
2001 | 2153 | if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && |
---|
2002 | 2154 | p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) |
---|
2003 | 2155 | return -EINVAL; |
---|
2004 | | - p->parm.capture.readbuffers = 2; |
---|
| 2156 | + if (vfd->device_caps & V4L2_CAP_READWRITE) |
---|
| 2157 | + p->parm.capture.readbuffers = 2; |
---|
2005 | 2158 | ret = ops->vidioc_g_std(file, fh, &std); |
---|
2006 | 2159 | if (ret == 0) |
---|
2007 | 2160 | v4l2_video_std_frame_period(std, &p->parm.capture.timeperframe); |
---|
.. | .. |
---|
2107 | 2260 | ctrls.controls = &ctrl; |
---|
2108 | 2261 | ctrl.id = p->id; |
---|
2109 | 2262 | ctrl.value = p->value; |
---|
2110 | | - if (check_ext_ctrls(&ctrls, 1)) { |
---|
| 2263 | + if (check_ext_ctrls(&ctrls, VIDIOC_G_CTRL)) { |
---|
2111 | 2264 | int ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls); |
---|
2112 | 2265 | |
---|
2113 | 2266 | if (ret == 0) |
---|
.. | .. |
---|
2126 | 2279 | test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; |
---|
2127 | 2280 | struct v4l2_ext_controls ctrls; |
---|
2128 | 2281 | struct v4l2_ext_control ctrl; |
---|
| 2282 | + int ret; |
---|
2129 | 2283 | |
---|
2130 | 2284 | if (vfh && vfh->ctrl_handler) |
---|
2131 | 2285 | return v4l2_s_ctrl(vfh, vfh->ctrl_handler, p); |
---|
.. | .. |
---|
2141 | 2295 | ctrls.controls = &ctrl; |
---|
2142 | 2296 | ctrl.id = p->id; |
---|
2143 | 2297 | ctrl.value = p->value; |
---|
2144 | | - if (check_ext_ctrls(&ctrls, 1)) |
---|
2145 | | - return ops->vidioc_s_ext_ctrls(file, fh, &ctrls); |
---|
2146 | | - return -EINVAL; |
---|
| 2298 | + if (!check_ext_ctrls(&ctrls, VIDIOC_S_CTRL)) |
---|
| 2299 | + return -EINVAL; |
---|
| 2300 | + ret = ops->vidioc_s_ext_ctrls(file, fh, &ctrls); |
---|
| 2301 | + p->value = ctrl.value; |
---|
| 2302 | + return ret; |
---|
2147 | 2303 | } |
---|
2148 | 2304 | |
---|
2149 | 2305 | static int v4l_g_ext_ctrls(const struct v4l2_ioctl_ops *ops, |
---|
.. | .. |
---|
2156 | 2312 | |
---|
2157 | 2313 | p->error_idx = p->count; |
---|
2158 | 2314 | if (vfh && vfh->ctrl_handler) |
---|
2159 | | - return v4l2_g_ext_ctrls(vfh->ctrl_handler, p); |
---|
| 2315 | + return v4l2_g_ext_ctrls(vfh->ctrl_handler, |
---|
| 2316 | + vfd, vfd->v4l2_dev->mdev, p); |
---|
2160 | 2317 | if (vfd->ctrl_handler) |
---|
2161 | | - return v4l2_g_ext_ctrls(vfd->ctrl_handler, p); |
---|
| 2318 | + return v4l2_g_ext_ctrls(vfd->ctrl_handler, |
---|
| 2319 | + vfd, vfd->v4l2_dev->mdev, p); |
---|
2162 | 2320 | if (ops->vidioc_g_ext_ctrls == NULL) |
---|
2163 | 2321 | return -ENOTTY; |
---|
2164 | | - return check_ext_ctrls(p, 0) ? ops->vidioc_g_ext_ctrls(file, fh, p) : |
---|
2165 | | - -EINVAL; |
---|
| 2322 | + return check_ext_ctrls(p, VIDIOC_G_EXT_CTRLS) ? |
---|
| 2323 | + ops->vidioc_g_ext_ctrls(file, fh, p) : -EINVAL; |
---|
2166 | 2324 | } |
---|
2167 | 2325 | |
---|
2168 | 2326 | static int v4l_s_ext_ctrls(const struct v4l2_ioctl_ops *ops, |
---|
.. | .. |
---|
2175 | 2333 | |
---|
2176 | 2334 | p->error_idx = p->count; |
---|
2177 | 2335 | if (vfh && vfh->ctrl_handler) |
---|
2178 | | - return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, p); |
---|
| 2336 | + return v4l2_s_ext_ctrls(vfh, vfh->ctrl_handler, |
---|
| 2337 | + vfd, vfd->v4l2_dev->mdev, p); |
---|
2179 | 2338 | if (vfd->ctrl_handler) |
---|
2180 | | - return v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler, p); |
---|
| 2339 | + return v4l2_s_ext_ctrls(NULL, vfd->ctrl_handler, |
---|
| 2340 | + vfd, vfd->v4l2_dev->mdev, p); |
---|
2181 | 2341 | if (ops->vidioc_s_ext_ctrls == NULL) |
---|
2182 | 2342 | return -ENOTTY; |
---|
2183 | | - return check_ext_ctrls(p, 0) ? ops->vidioc_s_ext_ctrls(file, fh, p) : |
---|
2184 | | - -EINVAL; |
---|
| 2343 | + return check_ext_ctrls(p, VIDIOC_S_EXT_CTRLS) ? |
---|
| 2344 | + ops->vidioc_s_ext_ctrls(file, fh, p) : -EINVAL; |
---|
2185 | 2345 | } |
---|
2186 | 2346 | |
---|
2187 | 2347 | static int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops, |
---|
.. | .. |
---|
2194 | 2354 | |
---|
2195 | 2355 | p->error_idx = p->count; |
---|
2196 | 2356 | if (vfh && vfh->ctrl_handler) |
---|
2197 | | - return v4l2_try_ext_ctrls(vfh->ctrl_handler, p); |
---|
| 2357 | + return v4l2_try_ext_ctrls(vfh->ctrl_handler, |
---|
| 2358 | + vfd, vfd->v4l2_dev->mdev, p); |
---|
2198 | 2359 | if (vfd->ctrl_handler) |
---|
2199 | | - return v4l2_try_ext_ctrls(vfd->ctrl_handler, p); |
---|
| 2360 | + return v4l2_try_ext_ctrls(vfd->ctrl_handler, |
---|
| 2361 | + vfd, vfd->v4l2_dev->mdev, p); |
---|
2200 | 2362 | if (ops->vidioc_try_ext_ctrls == NULL) |
---|
2201 | 2363 | return -ENOTTY; |
---|
2202 | | - return check_ext_ctrls(p, 0) ? ops->vidioc_try_ext_ctrls(file, fh, p) : |
---|
2203 | | - -EINVAL; |
---|
| 2364 | + return check_ext_ctrls(p, VIDIOC_TRY_EXT_CTRLS) ? |
---|
| 2365 | + ops->vidioc_try_ext_ctrls(file, fh, p) : -EINVAL; |
---|
2204 | 2366 | } |
---|
2205 | 2367 | |
---|
2206 | 2368 | /* |
---|
.. | .. |
---|
2247 | 2409 | static int v4l_g_crop(const struct v4l2_ioctl_ops *ops, |
---|
2248 | 2410 | struct file *file, void *fh, void *arg) |
---|
2249 | 2411 | { |
---|
| 2412 | + struct video_device *vfd = video_devdata(file); |
---|
2250 | 2413 | struct v4l2_crop *p = arg; |
---|
2251 | 2414 | struct v4l2_selection s = { |
---|
2252 | 2415 | .type = p->type, |
---|
2253 | 2416 | }; |
---|
2254 | 2417 | int ret; |
---|
2255 | 2418 | |
---|
2256 | | - if (ops->vidioc_g_crop) |
---|
2257 | | - return ops->vidioc_g_crop(file, fh, p); |
---|
2258 | 2419 | /* simulate capture crop using selection api */ |
---|
2259 | 2420 | |
---|
2260 | 2421 | /* crop means compose for output devices */ |
---|
2261 | 2422 | if (V4L2_TYPE_IS_OUTPUT(p->type)) |
---|
2262 | | - s.target = V4L2_SEL_TGT_COMPOSE_ACTIVE; |
---|
| 2423 | + s.target = V4L2_SEL_TGT_COMPOSE; |
---|
2263 | 2424 | else |
---|
2264 | | - s.target = V4L2_SEL_TGT_CROP_ACTIVE; |
---|
| 2425 | + s.target = V4L2_SEL_TGT_CROP; |
---|
| 2426 | + |
---|
| 2427 | + if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags)) |
---|
| 2428 | + s.target = s.target == V4L2_SEL_TGT_COMPOSE ? |
---|
| 2429 | + V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE; |
---|
2265 | 2430 | |
---|
2266 | 2431 | ret = v4l_g_selection(ops, file, fh, &s); |
---|
2267 | 2432 | |
---|
.. | .. |
---|
2274 | 2439 | static int v4l_s_crop(const struct v4l2_ioctl_ops *ops, |
---|
2275 | 2440 | struct file *file, void *fh, void *arg) |
---|
2276 | 2441 | { |
---|
| 2442 | + struct video_device *vfd = video_devdata(file); |
---|
2277 | 2443 | struct v4l2_crop *p = arg; |
---|
2278 | 2444 | struct v4l2_selection s = { |
---|
2279 | 2445 | .type = p->type, |
---|
2280 | 2446 | .r = p->c, |
---|
2281 | 2447 | }; |
---|
2282 | 2448 | |
---|
2283 | | - if (ops->vidioc_s_crop) |
---|
2284 | | - return ops->vidioc_s_crop(file, fh, p); |
---|
2285 | 2449 | /* simulate capture crop using selection api */ |
---|
2286 | 2450 | |
---|
2287 | 2451 | /* crop means compose for output devices */ |
---|
2288 | 2452 | if (V4L2_TYPE_IS_OUTPUT(p->type)) |
---|
2289 | | - s.target = V4L2_SEL_TGT_COMPOSE_ACTIVE; |
---|
| 2453 | + s.target = V4L2_SEL_TGT_COMPOSE; |
---|
2290 | 2454 | else |
---|
2291 | | - s.target = V4L2_SEL_TGT_CROP_ACTIVE; |
---|
| 2455 | + s.target = V4L2_SEL_TGT_CROP; |
---|
| 2456 | + |
---|
| 2457 | + if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags)) |
---|
| 2458 | + s.target = s.target == V4L2_SEL_TGT_COMPOSE ? |
---|
| 2459 | + V4L2_SEL_TGT_CROP : V4L2_SEL_TGT_COMPOSE; |
---|
2292 | 2460 | |
---|
2293 | 2461 | return v4l_s_selection(ops, file, fh, &s); |
---|
2294 | 2462 | } |
---|
.. | .. |
---|
2296 | 2464 | static int v4l_cropcap(const struct v4l2_ioctl_ops *ops, |
---|
2297 | 2465 | struct file *file, void *fh, void *arg) |
---|
2298 | 2466 | { |
---|
| 2467 | + struct video_device *vfd = video_devdata(file); |
---|
2299 | 2468 | struct v4l2_cropcap *p = arg; |
---|
2300 | 2469 | struct v4l2_selection s = { .type = p->type }; |
---|
2301 | 2470 | int ret = 0; |
---|
.. | .. |
---|
2304 | 2473 | p->pixelaspect.numerator = 1; |
---|
2305 | 2474 | p->pixelaspect.denominator = 1; |
---|
2306 | 2475 | |
---|
| 2476 | + if (s.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) |
---|
| 2477 | + s.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
---|
| 2478 | + else if (s.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) |
---|
| 2479 | + s.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; |
---|
| 2480 | + |
---|
2307 | 2481 | /* |
---|
2308 | 2482 | * The determine_valid_ioctls() call already should ensure |
---|
2309 | 2483 | * that this can never happen, but just in case... |
---|
2310 | 2484 | */ |
---|
2311 | | - if (WARN_ON(!ops->vidioc_cropcap && !ops->vidioc_g_selection)) |
---|
| 2485 | + if (WARN_ON(!ops->vidioc_g_selection)) |
---|
2312 | 2486 | return -ENOTTY; |
---|
2313 | 2487 | |
---|
2314 | | - if (ops->vidioc_cropcap) |
---|
2315 | | - ret = ops->vidioc_cropcap(file, fh, p); |
---|
2316 | | - |
---|
2317 | | - if (!ops->vidioc_g_selection) |
---|
2318 | | - return ret; |
---|
| 2488 | + if (ops->vidioc_g_pixelaspect) |
---|
| 2489 | + ret = ops->vidioc_g_pixelaspect(file, fh, s.type, |
---|
| 2490 | + &p->pixelaspect); |
---|
2319 | 2491 | |
---|
2320 | 2492 | /* |
---|
2321 | 2493 | * Ignore ENOTTY or ENOIOCTLCMD error returns, just use the |
---|
.. | .. |
---|
2332 | 2504 | else |
---|
2333 | 2505 | s.target = V4L2_SEL_TGT_CROP_BOUNDS; |
---|
2334 | 2506 | |
---|
| 2507 | + if (test_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags)) |
---|
| 2508 | + s.target = s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS ? |
---|
| 2509 | + V4L2_SEL_TGT_CROP_BOUNDS : V4L2_SEL_TGT_COMPOSE_BOUNDS; |
---|
| 2510 | + |
---|
2335 | 2511 | ret = v4l_g_selection(ops, file, fh, &s); |
---|
2336 | 2512 | if (ret) |
---|
2337 | 2513 | return ret; |
---|
2338 | 2514 | p->bounds = s.r; |
---|
2339 | 2515 | |
---|
2340 | 2516 | /* obtaining defrect */ |
---|
2341 | | - if (V4L2_TYPE_IS_OUTPUT(p->type)) |
---|
| 2517 | + if (s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS) |
---|
2342 | 2518 | s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT; |
---|
2343 | 2519 | else |
---|
2344 | 2520 | s.target = V4L2_SEL_TGT_CROP_DEFAULT; |
---|
.. | .. |
---|
2438 | 2614 | p->flags |= V4L2_CHIP_FL_WRITABLE; |
---|
2439 | 2615 | if (ops->vidioc_g_register) |
---|
2440 | 2616 | p->flags |= V4L2_CHIP_FL_READABLE; |
---|
2441 | | - strlcpy(p->name, vfd->v4l2_dev->name, sizeof(p->name)); |
---|
| 2617 | + strscpy(p->name, vfd->v4l2_dev->name, sizeof(p->name)); |
---|
2442 | 2618 | if (ops->vidioc_g_chip_info) |
---|
2443 | 2619 | return ops->vidioc_g_chip_info(file, fh, arg); |
---|
2444 | 2620 | if (p->match.addr) |
---|
.. | .. |
---|
2455 | 2631 | p->flags |= V4L2_CHIP_FL_WRITABLE; |
---|
2456 | 2632 | if (sd->ops->core && sd->ops->core->g_register) |
---|
2457 | 2633 | p->flags |= V4L2_CHIP_FL_READABLE; |
---|
2458 | | - strlcpy(p->name, sd->name, sizeof(p->name)); |
---|
| 2634 | + strscpy(p->name, sd->name, sizeof(p->name)); |
---|
2459 | 2635 | return 0; |
---|
2460 | 2636 | } |
---|
2461 | 2637 | break; |
---|
.. | .. |
---|
2582 | 2758 | /* Zero struct from after the field to the end */ |
---|
2583 | 2759 | #define INFO_FL_CLEAR(v4l2_struct, field) \ |
---|
2584 | 2760 | ((offsetof(struct v4l2_struct, field) + \ |
---|
2585 | | - sizeof(((struct v4l2_struct *)0)->field)) << 16) |
---|
| 2761 | + sizeof_field(struct v4l2_struct, field)) << 16) |
---|
2586 | 2762 | #define INFO_FL_CLEAR_MASK (_IOC_SIZEMASK << 16) |
---|
2587 | 2763 | |
---|
2588 | 2764 | #define DEFINE_V4L_STUB_FUNC(_vidioc) \ |
---|
.. | .. |
---|
2608 | 2784 | DEFINE_V4L_STUB_FUNC(g_std) |
---|
2609 | 2785 | DEFINE_V4L_STUB_FUNC(g_audio) |
---|
2610 | 2786 | DEFINE_V4L_STUB_FUNC(s_audio) |
---|
2611 | | -DEFINE_V4L_STUB_FUNC(g_input) |
---|
2612 | 2787 | DEFINE_V4L_STUB_FUNC(g_edid) |
---|
2613 | 2788 | DEFINE_V4L_STUB_FUNC(s_edid) |
---|
2614 | | -DEFINE_V4L_STUB_FUNC(g_output) |
---|
2615 | 2789 | DEFINE_V4L_STUB_FUNC(g_audout) |
---|
2616 | 2790 | DEFINE_V4L_STUB_FUNC(s_audout) |
---|
2617 | 2791 | DEFINE_V4L_STUB_FUNC(g_jpegcomp) |
---|
.. | .. |
---|
2631 | 2805 | DEFINE_V4L_STUB_FUNC(query_dv_timings) |
---|
2632 | 2806 | DEFINE_V4L_STUB_FUNC(dv_timings_cap) |
---|
2633 | 2807 | |
---|
2634 | | -static struct v4l2_ioctl_info v4l2_ioctls[] = { |
---|
| 2808 | +static const struct v4l2_ioctl_info v4l2_ioctls[] = { |
---|
2635 | 2809 | IOCTL_INFO(VIDIOC_QUERYCAP, v4l_querycap, v4l_print_querycap, 0), |
---|
2636 | | - IOCTL_INFO(VIDIOC_ENUM_FMT, v4l_enum_fmt, v4l_print_fmtdesc, INFO_FL_CLEAR(v4l2_fmtdesc, type)), |
---|
| 2810 | + IOCTL_INFO(VIDIOC_ENUM_FMT, v4l_enum_fmt, v4l_print_fmtdesc, 0), |
---|
2637 | 2811 | IOCTL_INFO(VIDIOC_G_FMT, v4l_g_fmt, v4l_print_format, 0), |
---|
2638 | 2812 | IOCTL_INFO(VIDIOC_S_FMT, v4l_s_fmt, v4l_print_format, INFO_FL_PRIO), |
---|
2639 | 2813 | IOCTL_INFO(VIDIOC_REQBUFS, v4l_reqbufs, v4l_print_requestbuffers, INFO_FL_PRIO | INFO_FL_QUEUE), |
---|
.. | .. |
---|
2660 | 2834 | IOCTL_INFO(VIDIOC_S_AUDIO, v4l_stub_s_audio, v4l_print_audio, INFO_FL_PRIO), |
---|
2661 | 2835 | IOCTL_INFO(VIDIOC_QUERYCTRL, v4l_queryctrl, v4l_print_queryctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_queryctrl, id)), |
---|
2662 | 2836 | IOCTL_INFO(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)), |
---|
2663 | | - IOCTL_INFO(VIDIOC_G_INPUT, v4l_stub_g_input, v4l_print_u32, 0), |
---|
| 2837 | + IOCTL_INFO(VIDIOC_G_INPUT, v4l_g_input, v4l_print_u32, 0), |
---|
2664 | 2838 | IOCTL_INFO(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO), |
---|
2665 | 2839 | IOCTL_INFO(VIDIOC_G_EDID, v4l_stub_g_edid, v4l_print_edid, INFO_FL_ALWAYS_COPY), |
---|
2666 | 2840 | IOCTL_INFO(VIDIOC_S_EDID, v4l_stub_s_edid, v4l_print_edid, INFO_FL_PRIO | INFO_FL_ALWAYS_COPY), |
---|
2667 | | - IOCTL_INFO(VIDIOC_G_OUTPUT, v4l_stub_g_output, v4l_print_u32, 0), |
---|
| 2841 | + IOCTL_INFO(VIDIOC_G_OUTPUT, v4l_g_output, v4l_print_u32, 0), |
---|
2668 | 2842 | IOCTL_INFO(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO), |
---|
2669 | 2843 | IOCTL_INFO(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)), |
---|
2670 | 2844 | IOCTL_INFO(VIDIOC_G_AUDOUT, v4l_stub_g_audout, v4l_print_audioout, 0), |
---|
.. | .. |
---|
2724 | 2898 | return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd; |
---|
2725 | 2899 | } |
---|
2726 | 2900 | |
---|
2727 | | -#if IS_ENABLED(CONFIG_V4L2_MEM2MEM_DEV) |
---|
2728 | | -static bool v4l2_ioctl_m2m_queue_is_output(unsigned int cmd, void *arg) |
---|
2729 | | -{ |
---|
2730 | | - switch (cmd) { |
---|
2731 | | - case VIDIOC_CREATE_BUFS: { |
---|
2732 | | - struct v4l2_create_buffers *cbufs = arg; |
---|
2733 | | - |
---|
2734 | | - return V4L2_TYPE_IS_OUTPUT(cbufs->format.type); |
---|
2735 | | - } |
---|
2736 | | - case VIDIOC_REQBUFS: { |
---|
2737 | | - struct v4l2_requestbuffers *rbufs = arg; |
---|
2738 | | - |
---|
2739 | | - return V4L2_TYPE_IS_OUTPUT(rbufs->type); |
---|
2740 | | - } |
---|
2741 | | - case VIDIOC_QBUF: |
---|
2742 | | - case VIDIOC_DQBUF: |
---|
2743 | | - case VIDIOC_QUERYBUF: |
---|
2744 | | - case VIDIOC_PREPARE_BUF: { |
---|
2745 | | - struct v4l2_buffer *buf = arg; |
---|
2746 | | - |
---|
2747 | | - return V4L2_TYPE_IS_OUTPUT(buf->type); |
---|
2748 | | - } |
---|
2749 | | - case VIDIOC_EXPBUF: { |
---|
2750 | | - struct v4l2_exportbuffer *expbuf = arg; |
---|
2751 | | - |
---|
2752 | | - return V4L2_TYPE_IS_OUTPUT(expbuf->type); |
---|
2753 | | - } |
---|
2754 | | - case VIDIOC_STREAMON: |
---|
2755 | | - case VIDIOC_STREAMOFF: { |
---|
2756 | | - int *type = arg; |
---|
2757 | | - |
---|
2758 | | - return V4L2_TYPE_IS_OUTPUT(*type); |
---|
2759 | | - } |
---|
2760 | | - default: |
---|
2761 | | - return false; |
---|
2762 | | - } |
---|
2763 | | -} |
---|
2764 | | -#endif |
---|
2765 | | - |
---|
2766 | 2901 | static struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev, |
---|
2767 | 2902 | struct v4l2_fh *vfh, unsigned int cmd, |
---|
2768 | 2903 | void *arg) |
---|
2769 | 2904 | { |
---|
2770 | 2905 | if (_IOC_NR(cmd) >= V4L2_IOCTLS) |
---|
2771 | 2906 | return vdev->lock; |
---|
2772 | | -#if IS_ENABLED(CONFIG_V4L2_MEM2MEM_DEV) |
---|
2773 | 2907 | if (vfh && vfh->m2m_ctx && |
---|
2774 | 2908 | (v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE)) { |
---|
2775 | | - bool is_output = v4l2_ioctl_m2m_queue_is_output(cmd, arg); |
---|
2776 | | - struct v4l2_m2m_queue_ctx *ctx = is_output ? |
---|
2777 | | - &vfh->m2m_ctx->out_q_ctx : &vfh->m2m_ctx->cap_q_ctx; |
---|
2778 | | - |
---|
2779 | | - if (ctx->q.lock) |
---|
2780 | | - return ctx->q.lock; |
---|
| 2909 | + if (vfh->m2m_ctx->q_lock) |
---|
| 2910 | + return vfh->m2m_ctx->q_lock; |
---|
2781 | 2911 | } |
---|
2782 | | -#endif |
---|
2783 | 2912 | if (vdev->queue && vdev->queue->lock && |
---|
2784 | 2913 | (v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE)) |
---|
2785 | 2914 | return vdev->queue->lock; |
---|
.. | .. |
---|
2827 | 2956 | unsigned int cmd, void *arg) |
---|
2828 | 2957 | { |
---|
2829 | 2958 | struct video_device *vfd = video_devdata(file); |
---|
| 2959 | + struct mutex *req_queue_lock = NULL; |
---|
2830 | 2960 | struct mutex *lock; /* ioctl serialization mutex */ |
---|
2831 | 2961 | const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; |
---|
2832 | 2962 | bool write_only = false; |
---|
.. | .. |
---|
2846 | 2976 | if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) |
---|
2847 | 2977 | vfh = file->private_data; |
---|
2848 | 2978 | |
---|
| 2979 | + /* |
---|
| 2980 | + * We need to serialize streamon/off with queueing new requests. |
---|
| 2981 | + * These ioctls may trigger the cancellation of a streaming |
---|
| 2982 | + * operation, and that should not be mixed with queueing a new |
---|
| 2983 | + * request at the same time. |
---|
| 2984 | + */ |
---|
| 2985 | + if (v4l2_device_supports_requests(vfd->v4l2_dev) && |
---|
| 2986 | + (cmd == VIDIOC_STREAMON || cmd == VIDIOC_STREAMOFF)) { |
---|
| 2987 | + req_queue_lock = &vfd->v4l2_dev->mdev->req_queue_mutex; |
---|
| 2988 | + |
---|
| 2989 | + if (mutex_lock_interruptible(req_queue_lock)) |
---|
| 2990 | + return -ERESTARTSYS; |
---|
| 2991 | + } |
---|
| 2992 | + |
---|
2849 | 2993 | lock = v4l2_ioctl_get_lock(vfd, vfh, cmd, arg); |
---|
2850 | 2994 | |
---|
2851 | | - if (lock && mutex_lock_interruptible(lock)) |
---|
| 2995 | + if (lock && mutex_lock_interruptible(lock)) { |
---|
| 2996 | + if (req_queue_lock) |
---|
| 2997 | + mutex_unlock(req_queue_lock); |
---|
2852 | 2998 | return -ERESTARTSYS; |
---|
| 2999 | + } |
---|
2853 | 3000 | |
---|
2854 | 3001 | if (!video_is_registered(vfd)) { |
---|
2855 | 3002 | ret = -ENODEV; |
---|
.. | .. |
---|
2908 | 3055 | unlock: |
---|
2909 | 3056 | if (lock) |
---|
2910 | 3057 | mutex_unlock(lock); |
---|
| 3058 | + if (req_queue_lock) |
---|
| 3059 | + mutex_unlock(req_queue_lock); |
---|
2911 | 3060 | return ret; |
---|
2912 | 3061 | } |
---|
2913 | 3062 | |
---|
.. | .. |
---|
2976 | 3125 | return ret; |
---|
2977 | 3126 | } |
---|
2978 | 3127 | |
---|
| 3128 | +static unsigned int video_translate_cmd(unsigned int cmd) |
---|
| 3129 | +{ |
---|
| 3130 | + switch (cmd) { |
---|
| 3131 | +#ifdef CONFIG_COMPAT_32BIT_TIME |
---|
| 3132 | + case VIDIOC_DQEVENT_TIME32: |
---|
| 3133 | + return VIDIOC_DQEVENT; |
---|
| 3134 | + case VIDIOC_QUERYBUF_TIME32: |
---|
| 3135 | + return VIDIOC_QUERYBUF; |
---|
| 3136 | + case VIDIOC_QBUF_TIME32: |
---|
| 3137 | + return VIDIOC_QBUF; |
---|
| 3138 | + case VIDIOC_DQBUF_TIME32: |
---|
| 3139 | + return VIDIOC_DQBUF; |
---|
| 3140 | + case VIDIOC_PREPARE_BUF_TIME32: |
---|
| 3141 | + return VIDIOC_PREPARE_BUF; |
---|
| 3142 | +#endif |
---|
| 3143 | + } |
---|
| 3144 | + |
---|
| 3145 | + return cmd; |
---|
| 3146 | +} |
---|
| 3147 | + |
---|
| 3148 | +static int video_get_user(void __user *arg, void *parg, unsigned int cmd, |
---|
| 3149 | + bool *always_copy) |
---|
| 3150 | +{ |
---|
| 3151 | + unsigned int n = _IOC_SIZE(cmd); |
---|
| 3152 | + |
---|
| 3153 | + if (!(_IOC_DIR(cmd) & _IOC_WRITE)) { |
---|
| 3154 | + /* read-only ioctl */ |
---|
| 3155 | + memset(parg, 0, n); |
---|
| 3156 | + return 0; |
---|
| 3157 | + } |
---|
| 3158 | + |
---|
| 3159 | + switch (cmd) { |
---|
| 3160 | +#ifdef CONFIG_COMPAT_32BIT_TIME |
---|
| 3161 | + case VIDIOC_QUERYBUF_TIME32: |
---|
| 3162 | + case VIDIOC_QBUF_TIME32: |
---|
| 3163 | + case VIDIOC_DQBUF_TIME32: |
---|
| 3164 | + case VIDIOC_PREPARE_BUF_TIME32: { |
---|
| 3165 | + struct v4l2_buffer_time32 vb32; |
---|
| 3166 | + struct v4l2_buffer *vb = parg; |
---|
| 3167 | + |
---|
| 3168 | + if (copy_from_user(&vb32, arg, sizeof(vb32))) |
---|
| 3169 | + return -EFAULT; |
---|
| 3170 | + |
---|
| 3171 | + *vb = (struct v4l2_buffer) { |
---|
| 3172 | + .index = vb32.index, |
---|
| 3173 | + .type = vb32.type, |
---|
| 3174 | + .bytesused = vb32.bytesused, |
---|
| 3175 | + .flags = vb32.flags, |
---|
| 3176 | + .field = vb32.field, |
---|
| 3177 | + .timestamp.tv_sec = vb32.timestamp.tv_sec, |
---|
| 3178 | + .timestamp.tv_usec = vb32.timestamp.tv_usec, |
---|
| 3179 | + .timecode = vb32.timecode, |
---|
| 3180 | + .sequence = vb32.sequence, |
---|
| 3181 | + .memory = vb32.memory, |
---|
| 3182 | + .m.userptr = vb32.m.userptr, |
---|
| 3183 | + .length = vb32.length, |
---|
| 3184 | + .request_fd = vb32.request_fd, |
---|
| 3185 | +#if defined(CONFIG_ARCH_ROCKCHIP) && IS_ENABLED(CONFIG_USB_F_UVC) |
---|
| 3186 | + .reserved2 = vb32.reserved2, |
---|
| 3187 | +#endif |
---|
| 3188 | + }; |
---|
| 3189 | + |
---|
| 3190 | + if (cmd == VIDIOC_QUERYBUF_TIME32) |
---|
| 3191 | + vb->request_fd = 0; |
---|
| 3192 | + |
---|
| 3193 | + break; |
---|
| 3194 | + } |
---|
| 3195 | +#endif |
---|
| 3196 | + default: |
---|
| 3197 | + /* |
---|
| 3198 | + * In some cases, only a few fields are used as input, |
---|
| 3199 | + * i.e. when the app sets "index" and then the driver |
---|
| 3200 | + * fills in the rest of the structure for the thing |
---|
| 3201 | + * with that index. We only need to copy up the first |
---|
| 3202 | + * non-input field. |
---|
| 3203 | + */ |
---|
| 3204 | + if (v4l2_is_known_ioctl(cmd)) { |
---|
| 3205 | + u32 flags = v4l2_ioctls[_IOC_NR(cmd)].flags; |
---|
| 3206 | + |
---|
| 3207 | + if (flags & INFO_FL_CLEAR_MASK) |
---|
| 3208 | + n = (flags & INFO_FL_CLEAR_MASK) >> 16; |
---|
| 3209 | + *always_copy = flags & INFO_FL_ALWAYS_COPY; |
---|
| 3210 | + trace_android_vh_clear_mask_adjust(v4l2_ioctls[_IOC_NR(cmd)].ioctl, &n); |
---|
| 3211 | + } |
---|
| 3212 | + |
---|
| 3213 | + if (copy_from_user(parg, (void __user *)arg, n)) |
---|
| 3214 | + return -EFAULT; |
---|
| 3215 | + |
---|
| 3216 | + /* zero out anything we don't copy from userspace */ |
---|
| 3217 | + if (n < _IOC_SIZE(cmd)) |
---|
| 3218 | + memset((u8 *)parg + n, 0, _IOC_SIZE(cmd) - n); |
---|
| 3219 | + break; |
---|
| 3220 | + } |
---|
| 3221 | + |
---|
| 3222 | + return 0; |
---|
| 3223 | +} |
---|
| 3224 | + |
---|
| 3225 | +static int video_put_user(void __user *arg, void *parg, unsigned int cmd) |
---|
| 3226 | +{ |
---|
| 3227 | + if (!(_IOC_DIR(cmd) & _IOC_READ)) |
---|
| 3228 | + return 0; |
---|
| 3229 | + |
---|
| 3230 | + switch (cmd) { |
---|
| 3231 | +#ifdef CONFIG_COMPAT_32BIT_TIME |
---|
| 3232 | + case VIDIOC_DQEVENT_TIME32: { |
---|
| 3233 | + struct v4l2_event *ev = parg; |
---|
| 3234 | + struct v4l2_event_time32 ev32; |
---|
| 3235 | + |
---|
| 3236 | + memset(&ev32, 0, sizeof(ev32)); |
---|
| 3237 | + |
---|
| 3238 | + ev32.type = ev->type; |
---|
| 3239 | + ev32.pending = ev->pending; |
---|
| 3240 | + ev32.sequence = ev->sequence; |
---|
| 3241 | + ev32.timestamp.tv_sec = ev->timestamp.tv_sec; |
---|
| 3242 | + ev32.timestamp.tv_nsec = ev->timestamp.tv_nsec; |
---|
| 3243 | + ev32.id = ev->id; |
---|
| 3244 | + |
---|
| 3245 | + memcpy(&ev32.u, &ev->u, sizeof(ev->u)); |
---|
| 3246 | + memcpy(&ev32.reserved, &ev->reserved, sizeof(ev->reserved)); |
---|
| 3247 | + |
---|
| 3248 | + if (copy_to_user(arg, &ev32, sizeof(ev32))) |
---|
| 3249 | + return -EFAULT; |
---|
| 3250 | + break; |
---|
| 3251 | + } |
---|
| 3252 | + case VIDIOC_QUERYBUF_TIME32: |
---|
| 3253 | + case VIDIOC_QBUF_TIME32: |
---|
| 3254 | + case VIDIOC_DQBUF_TIME32: |
---|
| 3255 | + case VIDIOC_PREPARE_BUF_TIME32: { |
---|
| 3256 | + struct v4l2_buffer *vb = parg; |
---|
| 3257 | + struct v4l2_buffer_time32 vb32; |
---|
| 3258 | + |
---|
| 3259 | + memset(&vb32, 0, sizeof(vb32)); |
---|
| 3260 | + |
---|
| 3261 | + vb32.index = vb->index; |
---|
| 3262 | + vb32.type = vb->type; |
---|
| 3263 | + vb32.bytesused = vb->bytesused; |
---|
| 3264 | + vb32.flags = vb->flags; |
---|
| 3265 | + vb32.field = vb->field; |
---|
| 3266 | + vb32.timestamp.tv_sec = vb->timestamp.tv_sec; |
---|
| 3267 | + vb32.timestamp.tv_usec = vb->timestamp.tv_usec; |
---|
| 3268 | + vb32.timecode = vb->timecode; |
---|
| 3269 | + vb32.sequence = vb->sequence; |
---|
| 3270 | + vb32.memory = vb->memory; |
---|
| 3271 | + vb32.m.userptr = vb->m.userptr; |
---|
| 3272 | + vb32.length = vb->length; |
---|
| 3273 | + vb32.request_fd = vb->request_fd; |
---|
| 3274 | + |
---|
| 3275 | + if (copy_to_user(arg, &vb32, sizeof(vb32))) |
---|
| 3276 | + return -EFAULT; |
---|
| 3277 | + break; |
---|
| 3278 | + } |
---|
| 3279 | +#endif |
---|
| 3280 | + default: |
---|
| 3281 | + /* Copy results into user buffer */ |
---|
| 3282 | + if (copy_to_user(arg, parg, _IOC_SIZE(cmd))) |
---|
| 3283 | + return -EFAULT; |
---|
| 3284 | + break; |
---|
| 3285 | + } |
---|
| 3286 | + |
---|
| 3287 | + return 0; |
---|
| 3288 | +} |
---|
| 3289 | + |
---|
2979 | 3290 | long |
---|
2980 | | -video_usercopy(struct file *file, unsigned int cmd, unsigned long arg, |
---|
| 3291 | +video_usercopy(struct file *file, unsigned int orig_cmd, unsigned long arg, |
---|
2981 | 3292 | v4l2_kioctl func) |
---|
2982 | 3293 | { |
---|
2983 | 3294 | char sbuf[128]; |
---|
.. | .. |
---|
2989 | 3300 | size_t array_size = 0; |
---|
2990 | 3301 | void __user *user_ptr = NULL; |
---|
2991 | 3302 | void **kernel_ptr = NULL; |
---|
| 3303 | + unsigned int cmd = video_translate_cmd(orig_cmd); |
---|
2992 | 3304 | const size_t ioc_size = _IOC_SIZE(cmd); |
---|
2993 | 3305 | |
---|
2994 | 3306 | /* Copy arguments into temp kernel buffer */ |
---|
.. | .. |
---|
3003 | 3315 | parg = mbuf; |
---|
3004 | 3316 | } |
---|
3005 | 3317 | |
---|
3006 | | - err = -EFAULT; |
---|
3007 | | - if (_IOC_DIR(cmd) & _IOC_WRITE) { |
---|
3008 | | - unsigned int n = ioc_size; |
---|
3009 | | - |
---|
3010 | | - /* |
---|
3011 | | - * In some cases, only a few fields are used as input, |
---|
3012 | | - * i.e. when the app sets "index" and then the driver |
---|
3013 | | - * fills in the rest of the structure for the thing |
---|
3014 | | - * with that index. We only need to copy up the first |
---|
3015 | | - * non-input field. |
---|
3016 | | - */ |
---|
3017 | | - if (v4l2_is_known_ioctl(cmd)) { |
---|
3018 | | - u32 flags = v4l2_ioctls[_IOC_NR(cmd)].flags; |
---|
3019 | | - |
---|
3020 | | - if (flags & INFO_FL_CLEAR_MASK) |
---|
3021 | | - n = (flags & INFO_FL_CLEAR_MASK) >> 16; |
---|
3022 | | - always_copy = flags & INFO_FL_ALWAYS_COPY; |
---|
3023 | | - } |
---|
3024 | | - |
---|
3025 | | - if (copy_from_user(parg, (void __user *)arg, n)) |
---|
3026 | | - goto out; |
---|
3027 | | - |
---|
3028 | | - /* zero out anything we don't copy from userspace */ |
---|
3029 | | - if (n < ioc_size) |
---|
3030 | | - memset((u8 *)parg + n, 0, ioc_size - n); |
---|
3031 | | - } else { |
---|
3032 | | - /* read-only ioctl */ |
---|
3033 | | - memset(parg, 0, ioc_size); |
---|
3034 | | - } |
---|
| 3318 | + err = video_get_user((void __user *)arg, parg, orig_cmd, |
---|
| 3319 | + &always_copy); |
---|
| 3320 | + if (err) |
---|
| 3321 | + goto out; |
---|
3035 | 3322 | } |
---|
3036 | 3323 | |
---|
3037 | 3324 | err = check_array_args(cmd, parg, &array_size, &user_ptr, &kernel_ptr); |
---|
.. | .. |
---|
3078 | 3365 | goto out; |
---|
3079 | 3366 | |
---|
3080 | 3367 | out_array_args: |
---|
3081 | | - /* Copy results into user buffer */ |
---|
3082 | | - switch (_IOC_DIR(cmd)) { |
---|
3083 | | - case _IOC_READ: |
---|
3084 | | - case (_IOC_WRITE | _IOC_READ): |
---|
3085 | | - if (copy_to_user((void __user *)arg, parg, ioc_size)) |
---|
3086 | | - err = -EFAULT; |
---|
3087 | | - break; |
---|
3088 | | - } |
---|
3089 | | - |
---|
| 3368 | + if (video_put_user((void __user *)arg, parg, orig_cmd)) |
---|
| 3369 | + err = -EFAULT; |
---|
3090 | 3370 | out: |
---|
3091 | 3371 | kvfree(array_buf); |
---|
3092 | 3372 | kvfree(mbuf); |
---|
3093 | 3373 | return err; |
---|
3094 | 3374 | } |
---|
3095 | | -EXPORT_SYMBOL_GPL(video_usercopy); |
---|
3096 | 3375 | |
---|
3097 | 3376 | long video_ioctl2(struct file *file, |
---|
3098 | 3377 | unsigned int cmd, unsigned long arg) |
---|