hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/drivers/media/v4l2-core/v4l2-ioctl.c
....@@ -1,12 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Video capture interface for Linux version 2
34 *
45 * 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.
106 *
117 * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1)
128 * Mauro Carvalho Chehab <mchehab@kernel.org> (version 2)
....@@ -32,6 +28,8 @@
3228 #include <media/v4l2-mem2mem.h>
3329
3430 #include <trace/events/v4l2.h>
31
+#include <trace/hooks/v4l2core.h>
32
+
3533
3634 /* Zero out the end of the struct pointed to by p. Everything after, but
3735 * not including, the specified field is cleared. */
....@@ -80,6 +78,15 @@
8078 { 0, "Unknown" }
8179 };
8280
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
+
8390 /* video4linux standard ID conversion to standard name
8491 */
8592 const char *v4l2_norm_to_name(v4l2_std_id id)
....@@ -88,7 +95,7 @@
8895 int i;
8996
9097 /* 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
9299 variants, compilation fails. Currently, the max value is 30bit wide.
93100 */
94101 BUG_ON(myid != id);
....@@ -121,7 +128,7 @@
121128 vs->id = id;
122129 v4l2_video_std_frame_period(id, &vs->frameperiod);
123130 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));
125132 return 0;
126133 }
127134 EXPORT_SYMBOL(v4l2_video_std_construct);
....@@ -268,12 +275,13 @@
268275 {
269276 const struct v4l2_fmtdesc *p = arg;
270277
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",
272279 p->index, prt_names(p->type, v4l2_type_names),
273280 p->flags, (p->pixelformat & 0xff),
274281 (p->pixelformat >> 8) & 0xff,
275282 (p->pixelformat >> 16) & 0xff,
276283 (p->pixelformat >> 24) & 0xff,
284
+ p->mbus_code,
277285 (int)sizeof(p->description), p->description);
278286 }
279287
....@@ -478,13 +486,13 @@
478486 const struct v4l2_plane *plane;
479487 int i;
480488
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),
485493 (long)p->timestamp.tv_usec,
486494 p->index,
487
- prt_names(p->type, v4l2_type_names),
495
+ prt_names(p->type, v4l2_type_names), p->request_fd,
488496 p->flags, prt_names(p->field, v4l2_field_names),
489497 p->sequence, prt_names(p->memory, v4l2_memory_names));
490498
....@@ -585,7 +593,10 @@
585593 static void v4l_print_control(const void *arg, bool write_only)
586594 {
587595 const struct v4l2_control *p = arg;
596
+ const char *name = v4l2_ctrl_get_name(p->id);
588597
598
+ if (name)
599
+ pr_cont("name=%s, ", name);
589600 pr_cont("id=0x%x, value=%d\n", p->id, p->value);
590601 }
591602
....@@ -594,15 +605,18 @@
594605 const struct v4l2_ext_controls *p = arg;
595606 int i;
596607
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);
599610 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);
600616 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);
603618 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);
606620 }
607621 pr_cont("\n");
608622 }
....@@ -779,7 +793,6 @@
779793 p->stepwise.step_height);
780794 break;
781795 case V4L2_FRMSIZE_TYPE_CONTINUOUS:
782
- /* fall through */
783796 default:
784797 pr_cont("\n");
785798 break;
....@@ -813,7 +826,6 @@
813826 p->stepwise.step.denominator);
814827 break;
815828 case V4L2_FRMIVAL_TYPE_CONTINUOUS:
816
- /* fall through */
817829 default:
818830 pr_cont("\n");
819831 break;
....@@ -825,7 +837,7 @@
825837 const struct v4l2_event *p = arg;
826838 const struct v4l2_event_ctrl *c;
827839
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",
829841 p->type, p->pending, p->sequence, p->id,
830842 p->timestamp.tv_sec, p->timestamp.tv_nsec);
831843 switch (p->type) {
....@@ -906,42 +918,70 @@
906918 pr_cont("driver-specific ioctl\n");
907919 }
908920
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)
910922 {
911923 __u32 i;
912924
913925 /* zero the reserved fields */
914
- c->reserved[0] = c->reserved[1] = 0;
926
+ c->reserved[0] = 0;
915927 for (i = 0; i < c->count; i++)
916928 c->controls[i].reserved2[0] = 0;
917929
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
+
927956 /* Check that all controls are from the same control class. */
928957 for (i = 0; i < c->count; i++) {
929958 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;
932962 }
933963 }
934
- return 1;
964
+ return true;
935965 }
936966
937967 static int check_fmt(struct file *file, enum v4l2_buf_type type)
938968 {
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;
939976 struct video_device *vfd = video_devdata(file);
940977 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);
942980 bool is_vbi = vfd->vfl_type == VFL_TYPE_VBI;
943981 bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
944982 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);
945985 bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
946986 bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
947987
....@@ -955,7 +995,7 @@
955995 return 0;
956996 break;
957997 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)
959999 return 0;
9601000 break;
9611001 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
....@@ -1000,11 +1040,11 @@
10001040 return 0;
10011041 break;
10021042 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)
10041044 return 0;
10051045 break;
10061046 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)
10081048 return 0;
10091049 break;
10101050 default:
....@@ -1016,6 +1056,12 @@
10161056 static void v4l_sanitize_format(struct v4l2_format *fmt)
10171057 {
10181058 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);
10191065
10201066 /*
10211067 * The v4l2_pix_format structure has been extended with fields that were
....@@ -1055,17 +1101,48 @@
10551101
10561102 ret = ops->vidioc_querycap(file, fh, cap);
10571103
1058
- cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT;
10591104 /*
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.
10621107 */
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;
10661117 cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT;
10671118
10681119 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);
10691146 }
10701147
10711148 static int v4l_s_input(const struct v4l2_ioctl_ops *ops,
....@@ -1077,12 +1154,21 @@
10771154 ret = v4l_enable_media_source(vfd);
10781155 if (ret)
10791156 return ret;
1157
+
1158
+ if (vfd->device_caps & V4L2_CAP_IO_MC)
1159
+ return *(int *)arg ? -EINVAL : 0;
1160
+
10801161 return ops->vidioc_s_input(file, fh, *(unsigned int *)arg);
10811162 }
10821163
10831164 static int v4l_s_output(const struct v4l2_ioctl_ops *ops,
10841165 struct file *file, void *fh, void *arg)
10851166 {
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
+
10861172 return ops->vidioc_s_output(file, fh, *(unsigned int *)arg);
10871173 }
10881174
....@@ -1126,6 +1212,14 @@
11261212 if (is_valid_ioctl(vfd, VIDIOC_S_STD))
11271213 p->capabilities |= V4L2_IN_CAP_STD;
11281214
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
+
11291223 return ops->vidioc_enum_input(file, fh, p);
11301224 }
11311225
....@@ -1143,6 +1237,14 @@
11431237 */
11441238 if (is_valid_ioctl(vfd, VIDIOC_S_STD))
11451239 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
+ }
11461248
11471249 return ops->vidioc_enum_output(file, fh, p);
11481250 }
....@@ -1167,9 +1269,21 @@
11671269 case V4L2_PIX_FMT_RGB444: descr = "16-bit A/XRGB 4-4-4-4"; break;
11681270 case V4L2_PIX_FMT_ARGB444: descr = "16-bit ARGB 4-4-4-4"; break;
11691271 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;
11701278 case V4L2_PIX_FMT_RGB555: descr = "16-bit A/XRGB 1-5-5-5"; break;
11711279 case V4L2_PIX_FMT_ARGB555: descr = "16-bit ARGB 1-5-5-5"; break;
11721280 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;
11731287 case V4L2_PIX_FMT_RGB565: descr = "16-bit RGB 5-6-5"; break;
11741288 case V4L2_PIX_FMT_RGB555X: descr = "16-bit A/XRGB 1-5-5-5 BE"; break;
11751289 case V4L2_PIX_FMT_ARGB555X: descr = "16-bit ARGB 1-5-5-5 BE"; break;
....@@ -1184,11 +1298,16 @@
11841298 case V4L2_PIX_FMT_RGB32: descr = "32-bit A/XRGB 8-8-8-8"; break;
11851299 case V4L2_PIX_FMT_ARGB32: descr = "32-bit ARGB 8-8-8-8"; break;
11861300 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;
11871305 case V4L2_PIX_FMT_GREY: descr = "8-bit Greyscale"; break;
11881306 case V4L2_PIX_FMT_Y4: descr = "4-bit Greyscale"; break;
11891307 case V4L2_PIX_FMT_Y6: descr = "6-bit Greyscale"; break;
11901308 case V4L2_PIX_FMT_Y10: descr = "10-bit Greyscale"; break;
11911309 case V4L2_PIX_FMT_Y12: descr = "12-bit Greyscale"; break;
1310
+ case V4L2_PIX_FMT_Y14: descr = "14-bit Greyscale"; break;
11921311 case V4L2_PIX_FMT_Y16: descr = "16-bit Greyscale"; break;
11931312 case V4L2_PIX_FMT_Y16_BE: descr = "16-bit Greyscale BE"; break;
11941313 case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; break;
....@@ -1197,6 +1316,7 @@
11971316 case V4L2_PIX_FMT_Y12I: descr = "Interleaved 12-bit Greyscale"; break;
11981317 case V4L2_PIX_FMT_Z16: descr = "16-bit Depth"; break;
11991318 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;
12001320 case V4L2_PIX_FMT_PAL8: descr = "8-bit Palette"; break;
12011321 case V4L2_PIX_FMT_UV8: descr = "8-bit Chrominance UV 4-4"; break;
12021322 case V4L2_PIX_FMT_YVU410: descr = "Planar YVU 4:1:0"; break;
....@@ -1213,6 +1333,10 @@
12131333 case V4L2_PIX_FMT_YUV555: descr = "16-bit A/XYUV 1-5-5-5"; break;
12141334 case V4L2_PIX_FMT_YUV565: descr = "16-bit YUV 5-6-5"; break;
12151335 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;
12161340 case V4L2_PIX_FMT_YUV410: descr = "Planar YUV 4:1:0"; break;
12171341 case V4L2_PIX_FMT_YUV420: descr = "Planar YUV 4:2:0"; break;
12181342 case V4L2_PIX_FMT_HI240: descr = "8-bit Dithered RGB (BTTV)"; break;
....@@ -1268,6 +1392,10 @@
12681392 case V4L2_PIX_FMT_SGBRG12P: descr = "12-bit Bayer GBGB/RGRG Packed"; break;
12691393 case V4L2_PIX_FMT_SGRBG12P: descr = "12-bit Bayer GRGR/BGBG Packed"; break;
12701394 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;
12711399 case V4L2_PIX_FMT_SBGGR14P: descr = "14-bit Bayer BGBG/GRGR Packed"; break;
12721400 case V4L2_PIX_FMT_SGBRG14P: descr = "14-bit Bayer GBGB/RGRG Packed"; break;
12731401 case V4L2_PIX_FMT_SGRBG14P: descr = "14-bit Bayer GRGR/BGBG Packed"; break;
....@@ -1294,27 +1422,15 @@
12941422 case V4L2_SDR_FMT_PCU16BE: descr = "Planar Complex U16BE"; break;
12951423 case V4L2_SDR_FMT_PCU18BE: descr = "Planar Complex U18BE"; break;
12961424 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;
13011429 case V4L2_META_FMT_VSP1_HGO: descr = "R-Car VSP1 1-D Histogram"; break;
13021430 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;
13181434
13191435 default:
13201436 /* Compressed formats */
....@@ -1328,17 +1444,22 @@
13281444 case V4L2_PIX_FMT_H264: descr = "H.264"; break;
13291445 case V4L2_PIX_FMT_H264_NO_SC: descr = "H.264 (No Start Codes)"; break;
13301446 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;
13311448 case V4L2_PIX_FMT_H263: descr = "H.263"; break;
13321449 case V4L2_PIX_FMT_MPEG1: descr = "MPEG-1 ES"; break;
13331450 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;
13351453 case V4L2_PIX_FMT_XVID: descr = "Xvid"; break;
13361454 case V4L2_PIX_FMT_VC1_ANNEX_G: descr = "VC-1 (SMPTE 412M Annex G)"; break;
13371455 case V4L2_PIX_FMT_VC1_ANNEX_L: descr = "VC-1 (SMPTE 412M Annex L)"; break;
13381456 case V4L2_PIX_FMT_VP8: descr = "VP8"; break;
1457
+ case V4L2_PIX_FMT_VP8_FRAME: descr = "VP8 Frame"; break;
13391458 case V4L2_PIX_FMT_VP9: descr = "VP9"; break;
13401459 case V4L2_PIX_FMT_HEVC: descr = "HEVC"; break; /* aka H.265 */
1460
+ case V4L2_PIX_FMT_HEVC_SLICE: descr = "HEVC Parsed Slice Data"; break;
13411461 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 */
13421463 case V4L2_PIX_FMT_CPIA1: descr = "GSPCA CPiA YUV"; break;
13431464 case V4L2_PIX_FMT_WNVA: descr = "WNVA"; break;
13441465 case V4L2_PIX_FMT_SN9C10X: descr = "GSPCA SN9C10X"; break;
....@@ -1358,51 +1479,62 @@
13581479 case V4L2_PIX_FMT_SE401: descr = "GSPCA SE401"; break;
13591480 case V4L2_PIX_FMT_S5C_UYVY_JPG: descr = "S5C73MX interleaved UYVY/JPEG"; break;
13601481 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;
13661483 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;
13681487 if (fmt->description[0])
13691488 return;
1489
+ WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat);
13701490 flags = 0;
13711491 snprintf(fmt->description, sz, "%c%c%c%c%s",
13721492 (char)(fmt->pixelformat & 0x7f),
13731493 (char)((fmt->pixelformat >> 8) & 0x7f),
13741494 (char)((fmt->pixelformat >> 16) & 0x7f),
13751495 (char)((fmt->pixelformat >> 24) & 0x7f),
1376
- (fmt->pixelformat & (1 << 31)) ? "-BE" : "");
1496
+ (fmt->pixelformat & (1UL << 31)) ? "-BE" : "");
13771497 break;
13781498 }
13791499 }
13801500
13811501 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;
13841504 }
13851505
13861506 static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops,
13871507 struct file *file, void *fh, void *arg)
13881508 {
1509
+ struct video_device *vdev = video_devdata(file);
13891510 struct v4l2_fmtdesc *p = arg;
13901511 int ret = check_fmt(file, p->type);
1512
+ u32 mbus_code;
1513
+ u32 cap_mask;
13911514
13921515 if (ret)
13931516 return ret;
13941517 ret = -EINVAL;
13951518
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
+
13961526 switch (p->type) {
13971527 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
+
13981535 if (unlikely(!ops->vidioc_enum_fmt_vid_cap))
13991536 break;
14001537 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);
14061538 break;
14071539 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
14081540 if (unlikely(!ops->vidioc_enum_fmt_vid_overlay))
....@@ -1410,14 +1542,16 @@
14101542 ret = ops->vidioc_enum_fmt_vid_overlay(file, fh, arg);
14111543 break;
14121544 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
+
14131552 if (unlikely(!ops->vidioc_enum_fmt_vid_out))
14141553 break;
14151554 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);
14211555 break;
14221556 case V4L2_BUF_TYPE_SDR_CAPTURE:
14231557 if (unlikely(!ops->vidioc_enum_fmt_sdr_cap))
....@@ -1547,6 +1681,7 @@
15471681 struct v4l2_format *p = arg;
15481682 struct video_device *vfd = video_devdata(file);
15491683 int ret = check_fmt(file, p->type);
1684
+ unsigned int i;
15501685
15511686 if (ret)
15521687 return ret;
....@@ -1570,7 +1705,10 @@
15701705 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
15711706 if (unlikely(!ops->vidioc_s_fmt_vid_cap_mplane))
15721707 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);
15741712 return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg);
15751713 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
15761714 if (unlikely(!ops->vidioc_s_fmt_vid_overlay))
....@@ -1598,7 +1736,10 @@
15981736 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
15991737 if (unlikely(!ops->vidioc_s_fmt_vid_out_mplane))
16001738 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);
16021743 return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg);
16031744 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
16041745 if (unlikely(!ops->vidioc_s_fmt_vid_out_overlay))
....@@ -1643,7 +1784,9 @@
16431784 struct file *file, void *fh, void *arg)
16441785 {
16451786 struct v4l2_format *p = arg;
1787
+ struct video_device *vfd = video_devdata(file);
16461788 int ret = check_fmt(file, p->type);
1789
+ unsigned int i;
16471790
16481791 if (ret)
16491792 return ret;
....@@ -1658,11 +1801,16 @@
16581801 ret = ops->vidioc_try_fmt_vid_cap(file, fh, arg);
16591802 /* just in case the driver zeroed it again */
16601803 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);
16611806 return ret;
16621807 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
16631808 if (unlikely(!ops->vidioc_try_fmt_vid_cap_mplane))
16641809 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);
16661814 return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg);
16671815 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
16681816 if (unlikely(!ops->vidioc_try_fmt_vid_overlay))
....@@ -1690,7 +1838,10 @@
16901838 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
16911839 if (unlikely(!ops->vidioc_try_fmt_vid_out_mplane))
16921840 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);
16941845 return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg);
16951846 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
16961847 if (unlikely(!ops->vidioc_try_fmt_vid_out_overlay))
....@@ -1924,7 +2075,7 @@
19242075 if (ret)
19252076 return ret;
19262077
1927
- CLEAR_AFTER_FIELD(p, memory);
2078
+ CLEAR_AFTER_FIELD(p, capabilities);
19282079
19292080 return ops->vidioc_reqbufs(file, fh, p);
19302081 }
....@@ -1965,7 +2116,7 @@
19652116 if (ret)
19662117 return ret;
19672118
1968
- CLEAR_AFTER_FIELD(create, format);
2119
+ CLEAR_AFTER_FIELD(create, capabilities);
19692120
19702121 v4l_sanitize_format(&create->format);
19712122
....@@ -1990,6 +2141,7 @@
19902141 static int v4l_g_parm(const struct v4l2_ioctl_ops *ops,
19912142 struct file *file, void *fh, void *arg)
19922143 {
2144
+ struct video_device *vfd = video_devdata(file);
19932145 struct v4l2_streamparm *p = arg;
19942146 v4l2_std_id std;
19952147 int ret = check_fmt(file, p->type);
....@@ -2001,7 +2153,8 @@
20012153 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
20022154 p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
20032155 return -EINVAL;
2004
- p->parm.capture.readbuffers = 2;
2156
+ if (vfd->device_caps & V4L2_CAP_READWRITE)
2157
+ p->parm.capture.readbuffers = 2;
20052158 ret = ops->vidioc_g_std(file, fh, &std);
20062159 if (ret == 0)
20072160 v4l2_video_std_frame_period(std, &p->parm.capture.timeperframe);
....@@ -2107,7 +2260,7 @@
21072260 ctrls.controls = &ctrl;
21082261 ctrl.id = p->id;
21092262 ctrl.value = p->value;
2110
- if (check_ext_ctrls(&ctrls, 1)) {
2263
+ if (check_ext_ctrls(&ctrls, VIDIOC_G_CTRL)) {
21112264 int ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls);
21122265
21132266 if (ret == 0)
....@@ -2126,6 +2279,7 @@
21262279 test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
21272280 struct v4l2_ext_controls ctrls;
21282281 struct v4l2_ext_control ctrl;
2282
+ int ret;
21292283
21302284 if (vfh && vfh->ctrl_handler)
21312285 return v4l2_s_ctrl(vfh, vfh->ctrl_handler, p);
....@@ -2141,9 +2295,11 @@
21412295 ctrls.controls = &ctrl;
21422296 ctrl.id = p->id;
21432297 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;
21472303 }
21482304
21492305 static int v4l_g_ext_ctrls(const struct v4l2_ioctl_ops *ops,
....@@ -2156,13 +2312,15 @@
21562312
21572313 p->error_idx = p->count;
21582314 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);
21602317 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);
21622320 if (ops->vidioc_g_ext_ctrls == NULL)
21632321 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;
21662324 }
21672325
21682326 static int v4l_s_ext_ctrls(const struct v4l2_ioctl_ops *ops,
....@@ -2175,13 +2333,15 @@
21752333
21762334 p->error_idx = p->count;
21772335 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);
21792338 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);
21812341 if (ops->vidioc_s_ext_ctrls == NULL)
21822342 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;
21852345 }
21862346
21872347 static int v4l_try_ext_ctrls(const struct v4l2_ioctl_ops *ops,
....@@ -2194,13 +2354,15 @@
21942354
21952355 p->error_idx = p->count;
21962356 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);
21982359 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);
22002362 if (ops->vidioc_try_ext_ctrls == NULL)
22012363 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;
22042366 }
22052367
22062368 /*
....@@ -2247,21 +2409,24 @@
22472409 static int v4l_g_crop(const struct v4l2_ioctl_ops *ops,
22482410 struct file *file, void *fh, void *arg)
22492411 {
2412
+ struct video_device *vfd = video_devdata(file);
22502413 struct v4l2_crop *p = arg;
22512414 struct v4l2_selection s = {
22522415 .type = p->type,
22532416 };
22542417 int ret;
22552418
2256
- if (ops->vidioc_g_crop)
2257
- return ops->vidioc_g_crop(file, fh, p);
22582419 /* simulate capture crop using selection api */
22592420
22602421 /* crop means compose for output devices */
22612422 if (V4L2_TYPE_IS_OUTPUT(p->type))
2262
- s.target = V4L2_SEL_TGT_COMPOSE_ACTIVE;
2423
+ s.target = V4L2_SEL_TGT_COMPOSE;
22632424 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;
22652430
22662431 ret = v4l_g_selection(ops, file, fh, &s);
22672432
....@@ -2274,21 +2439,24 @@
22742439 static int v4l_s_crop(const struct v4l2_ioctl_ops *ops,
22752440 struct file *file, void *fh, void *arg)
22762441 {
2442
+ struct video_device *vfd = video_devdata(file);
22772443 struct v4l2_crop *p = arg;
22782444 struct v4l2_selection s = {
22792445 .type = p->type,
22802446 .r = p->c,
22812447 };
22822448
2283
- if (ops->vidioc_s_crop)
2284
- return ops->vidioc_s_crop(file, fh, p);
22852449 /* simulate capture crop using selection api */
22862450
22872451 /* crop means compose for output devices */
22882452 if (V4L2_TYPE_IS_OUTPUT(p->type))
2289
- s.target = V4L2_SEL_TGT_COMPOSE_ACTIVE;
2453
+ s.target = V4L2_SEL_TGT_COMPOSE;
22902454 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;
22922460
22932461 return v4l_s_selection(ops, file, fh, &s);
22942462 }
....@@ -2296,6 +2464,7 @@
22962464 static int v4l_cropcap(const struct v4l2_ioctl_ops *ops,
22972465 struct file *file, void *fh, void *arg)
22982466 {
2467
+ struct video_device *vfd = video_devdata(file);
22992468 struct v4l2_cropcap *p = arg;
23002469 struct v4l2_selection s = { .type = p->type };
23012470 int ret = 0;
....@@ -2304,18 +2473,21 @@
23042473 p->pixelaspect.numerator = 1;
23052474 p->pixelaspect.denominator = 1;
23062475
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
+
23072481 /*
23082482 * The determine_valid_ioctls() call already should ensure
23092483 * that this can never happen, but just in case...
23102484 */
2311
- if (WARN_ON(!ops->vidioc_cropcap && !ops->vidioc_g_selection))
2485
+ if (WARN_ON(!ops->vidioc_g_selection))
23122486 return -ENOTTY;
23132487
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);
23192491
23202492 /*
23212493 * Ignore ENOTTY or ENOIOCTLCMD error returns, just use the
....@@ -2332,13 +2504,17 @@
23322504 else
23332505 s.target = V4L2_SEL_TGT_CROP_BOUNDS;
23342506
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
+
23352511 ret = v4l_g_selection(ops, file, fh, &s);
23362512 if (ret)
23372513 return ret;
23382514 p->bounds = s.r;
23392515
23402516 /* obtaining defrect */
2341
- if (V4L2_TYPE_IS_OUTPUT(p->type))
2517
+ if (s.target == V4L2_SEL_TGT_COMPOSE_BOUNDS)
23422518 s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
23432519 else
23442520 s.target = V4L2_SEL_TGT_CROP_DEFAULT;
....@@ -2438,7 +2614,7 @@
24382614 p->flags |= V4L2_CHIP_FL_WRITABLE;
24392615 if (ops->vidioc_g_register)
24402616 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));
24422618 if (ops->vidioc_g_chip_info)
24432619 return ops->vidioc_g_chip_info(file, fh, arg);
24442620 if (p->match.addr)
....@@ -2455,7 +2631,7 @@
24552631 p->flags |= V4L2_CHIP_FL_WRITABLE;
24562632 if (sd->ops->core && sd->ops->core->g_register)
24572633 p->flags |= V4L2_CHIP_FL_READABLE;
2458
- strlcpy(p->name, sd->name, sizeof(p->name));
2634
+ strscpy(p->name, sd->name, sizeof(p->name));
24592635 return 0;
24602636 }
24612637 break;
....@@ -2582,7 +2758,7 @@
25822758 /* Zero struct from after the field to the end */
25832759 #define INFO_FL_CLEAR(v4l2_struct, field) \
25842760 ((offsetof(struct v4l2_struct, field) + \
2585
- sizeof(((struct v4l2_struct *)0)->field)) << 16)
2761
+ sizeof_field(struct v4l2_struct, field)) << 16)
25862762 #define INFO_FL_CLEAR_MASK (_IOC_SIZEMASK << 16)
25872763
25882764 #define DEFINE_V4L_STUB_FUNC(_vidioc) \
....@@ -2608,10 +2784,8 @@
26082784 DEFINE_V4L_STUB_FUNC(g_std)
26092785 DEFINE_V4L_STUB_FUNC(g_audio)
26102786 DEFINE_V4L_STUB_FUNC(s_audio)
2611
-DEFINE_V4L_STUB_FUNC(g_input)
26122787 DEFINE_V4L_STUB_FUNC(g_edid)
26132788 DEFINE_V4L_STUB_FUNC(s_edid)
2614
-DEFINE_V4L_STUB_FUNC(g_output)
26152789 DEFINE_V4L_STUB_FUNC(g_audout)
26162790 DEFINE_V4L_STUB_FUNC(s_audout)
26172791 DEFINE_V4L_STUB_FUNC(g_jpegcomp)
....@@ -2631,9 +2805,9 @@
26312805 DEFINE_V4L_STUB_FUNC(query_dv_timings)
26322806 DEFINE_V4L_STUB_FUNC(dv_timings_cap)
26332807
2634
-static struct v4l2_ioctl_info v4l2_ioctls[] = {
2808
+static const struct v4l2_ioctl_info v4l2_ioctls[] = {
26352809 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),
26372811 IOCTL_INFO(VIDIOC_G_FMT, v4l_g_fmt, v4l_print_format, 0),
26382812 IOCTL_INFO(VIDIOC_S_FMT, v4l_s_fmt, v4l_print_format, INFO_FL_PRIO),
26392813 IOCTL_INFO(VIDIOC_REQBUFS, v4l_reqbufs, v4l_print_requestbuffers, INFO_FL_PRIO | INFO_FL_QUEUE),
....@@ -2660,11 +2834,11 @@
26602834 IOCTL_INFO(VIDIOC_S_AUDIO, v4l_stub_s_audio, v4l_print_audio, INFO_FL_PRIO),
26612835 IOCTL_INFO(VIDIOC_QUERYCTRL, v4l_queryctrl, v4l_print_queryctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_queryctrl, id)),
26622836 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),
26642838 IOCTL_INFO(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO),
26652839 IOCTL_INFO(VIDIOC_G_EDID, v4l_stub_g_edid, v4l_print_edid, INFO_FL_ALWAYS_COPY),
26662840 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),
26682842 IOCTL_INFO(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO),
26692843 IOCTL_INFO(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)),
26702844 IOCTL_INFO(VIDIOC_G_AUDOUT, v4l_stub_g_audout, v4l_print_audioout, 0),
....@@ -2724,62 +2898,17 @@
27242898 return v4l2_ioctls[_IOC_NR(cmd)].ioctl == cmd;
27252899 }
27262900
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
-
27662901 static struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev,
27672902 struct v4l2_fh *vfh, unsigned int cmd,
27682903 void *arg)
27692904 {
27702905 if (_IOC_NR(cmd) >= V4L2_IOCTLS)
27712906 return vdev->lock;
2772
-#if IS_ENABLED(CONFIG_V4L2_MEM2MEM_DEV)
27732907 if (vfh && vfh->m2m_ctx &&
27742908 (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;
27812911 }
2782
-#endif
27832912 if (vdev->queue && vdev->queue->lock &&
27842913 (v4l2_ioctls[_IOC_NR(cmd)].flags & INFO_FL_QUEUE))
27852914 return vdev->queue->lock;
....@@ -2827,6 +2956,7 @@
28272956 unsigned int cmd, void *arg)
28282957 {
28292958 struct video_device *vfd = video_devdata(file);
2959
+ struct mutex *req_queue_lock = NULL;
28302960 struct mutex *lock; /* ioctl serialization mutex */
28312961 const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
28322962 bool write_only = false;
....@@ -2846,10 +2976,27 @@
28462976 if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags))
28472977 vfh = file->private_data;
28482978
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
+
28492993 lock = v4l2_ioctl_get_lock(vfd, vfh, cmd, arg);
28502994
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);
28522998 return -ERESTARTSYS;
2999
+ }
28533000
28543001 if (!video_is_registered(vfd)) {
28553002 ret = -ENODEV;
....@@ -2908,6 +3055,8 @@
29083055 unlock:
29093056 if (lock)
29103057 mutex_unlock(lock);
3058
+ if (req_queue_lock)
3059
+ mutex_unlock(req_queue_lock);
29113060 return ret;
29123061 }
29133062
....@@ -2976,8 +3125,170 @@
29763125 return ret;
29773126 }
29783127
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
+
29793290 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,
29813292 v4l2_kioctl func)
29823293 {
29833294 char sbuf[128];
....@@ -2989,6 +3300,7 @@
29893300 size_t array_size = 0;
29903301 void __user *user_ptr = NULL;
29913302 void **kernel_ptr = NULL;
3303
+ unsigned int cmd = video_translate_cmd(orig_cmd);
29923304 const size_t ioc_size = _IOC_SIZE(cmd);
29933305
29943306 /* Copy arguments into temp kernel buffer */
....@@ -3003,35 +3315,10 @@
30033315 parg = mbuf;
30043316 }
30053317
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;
30353322 }
30363323
30373324 err = check_array_args(cmd, parg, &array_size, &user_ptr, &kernel_ptr);
....@@ -3078,21 +3365,13 @@
30783365 goto out;
30793366
30803367 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;
30903370 out:
30913371 kvfree(array_buf);
30923372 kvfree(mbuf);
30933373 return err;
30943374 }
3095
-EXPORT_SYMBOL_GPL(video_usercopy);
30963375
30973376 long video_ioctl2(struct file *file,
30983377 unsigned int cmd, unsigned long arg)