diff options
Diffstat (limited to 'drivers/media/v4l2-core/v4l2-ioctl.c')
-rw-r--r-- | drivers/media/v4l2-core/v4l2-ioctl.c | 239 |
1 files changed, 188 insertions, 51 deletions
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index 16bffd851bf9..d15e16737eef 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c | |||
@@ -256,7 +256,8 @@ static void v4l_print_format(const void *arg, bool write_only) | |||
256 | pix = &p->fmt.pix; | 256 | pix = &p->fmt.pix; |
257 | pr_cont(", width=%u, height=%u, " | 257 | pr_cont(", width=%u, height=%u, " |
258 | "pixelformat=%c%c%c%c, field=%s, " | 258 | "pixelformat=%c%c%c%c, field=%s, " |
259 | "bytesperline=%u, sizeimage=%u, colorspace=%d\n", | 259 | "bytesperline=%u, sizeimage=%u, colorspace=%d, " |
260 | "flags %u\n", | ||
260 | pix->width, pix->height, | 261 | pix->width, pix->height, |
261 | (pix->pixelformat & 0xff), | 262 | (pix->pixelformat & 0xff), |
262 | (pix->pixelformat >> 8) & 0xff, | 263 | (pix->pixelformat >> 8) & 0xff, |
@@ -264,7 +265,7 @@ static void v4l_print_format(const void *arg, bool write_only) | |||
264 | (pix->pixelformat >> 24) & 0xff, | 265 | (pix->pixelformat >> 24) & 0xff, |
265 | prt_names(pix->field, v4l2_field_names), | 266 | prt_names(pix->field, v4l2_field_names), |
266 | pix->bytesperline, pix->sizeimage, | 267 | pix->bytesperline, pix->sizeimage, |
267 | pix->colorspace); | 268 | pix->colorspace, pix->flags); |
268 | break; | 269 | break; |
269 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: | 270 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
270 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: | 271 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: |
@@ -525,6 +526,20 @@ static void v4l_print_queryctrl(const void *arg, bool write_only) | |||
525 | p->step, p->default_value, p->flags); | 526 | p->step, p->default_value, p->flags); |
526 | } | 527 | } |
527 | 528 | ||
529 | static void v4l_print_query_ext_ctrl(const void *arg, bool write_only) | ||
530 | { | ||
531 | const struct v4l2_query_ext_ctrl *p = arg; | ||
532 | |||
533 | pr_cont("id=0x%x, type=%d, name=%.*s, min/max=%lld/%lld, " | ||
534 | "step=%lld, default=%lld, flags=0x%08x, elem_size=%u, elems=%u, " | ||
535 | "nr_of_dims=%u, dims=%u,%u,%u,%u\n", | ||
536 | p->id, p->type, (int)sizeof(p->name), p->name, | ||
537 | p->minimum, p->maximum, | ||
538 | p->step, p->default_value, p->flags, | ||
539 | p->elem_size, p->elems, p->nr_of_dims, | ||
540 | p->dims[0], p->dims[1], p->dims[2], p->dims[3]); | ||
541 | } | ||
542 | |||
528 | static void v4l_print_querymenu(const void *arg, bool write_only) | 543 | static void v4l_print_querymenu(const void *arg, bool write_only) |
529 | { | 544 | { |
530 | const struct v4l2_querymenu *p = arg; | 545 | const struct v4l2_querymenu *p = arg; |
@@ -959,13 +974,49 @@ static int check_fmt(struct file *file, enum v4l2_buf_type type) | |||
959 | return -EINVAL; | 974 | return -EINVAL; |
960 | } | 975 | } |
961 | 976 | ||
977 | static void v4l_sanitize_format(struct v4l2_format *fmt) | ||
978 | { | ||
979 | unsigned int offset; | ||
980 | |||
981 | /* | ||
982 | * The v4l2_pix_format structure has been extended with fields that were | ||
983 | * not previously required to be set to zero by applications. The priv | ||
984 | * field, when set to a magic value, indicates the the extended fields | ||
985 | * are valid. Otherwise they will contain undefined values. To simplify | ||
986 | * the API towards drivers zero the extended fields and set the priv | ||
987 | * field to the magic value when the extended pixel format structure | ||
988 | * isn't used by applications. | ||
989 | */ | ||
990 | |||
991 | if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && | ||
992 | fmt->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) | ||
993 | return; | ||
994 | |||
995 | if (fmt->fmt.pix.priv == V4L2_PIX_FMT_PRIV_MAGIC) | ||
996 | return; | ||
997 | |||
998 | fmt->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; | ||
999 | |||
1000 | offset = offsetof(struct v4l2_pix_format, priv) | ||
1001 | + sizeof(fmt->fmt.pix.priv); | ||
1002 | memset(((void *)&fmt->fmt.pix) + offset, 0, | ||
1003 | sizeof(fmt->fmt.pix) - offset); | ||
1004 | } | ||
1005 | |||
962 | static int v4l_querycap(const struct v4l2_ioctl_ops *ops, | 1006 | static int v4l_querycap(const struct v4l2_ioctl_ops *ops, |
963 | struct file *file, void *fh, void *arg) | 1007 | struct file *file, void *fh, void *arg) |
964 | { | 1008 | { |
965 | struct v4l2_capability *cap = (struct v4l2_capability *)arg; | 1009 | struct v4l2_capability *cap = (struct v4l2_capability *)arg; |
1010 | int ret; | ||
966 | 1011 | ||
967 | cap->version = LINUX_VERSION_CODE; | 1012 | cap->version = LINUX_VERSION_CODE; |
968 | return ops->vidioc_querycap(file, fh, cap); | 1013 | |
1014 | ret = ops->vidioc_querycap(file, fh, cap); | ||
1015 | |||
1016 | cap->capabilities |= V4L2_CAP_EXT_PIX_FORMAT; | ||
1017 | cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT; | ||
1018 | |||
1019 | return ret; | ||
969 | } | 1020 | } |
970 | 1021 | ||
971 | static int v4l_s_input(const struct v4l2_ioctl_ops *ops, | 1022 | static int v4l_s_input(const struct v4l2_ioctl_ops *ops, |
@@ -1048,32 +1099,34 @@ static int v4l_enum_fmt(const struct v4l2_ioctl_ops *ops, | |||
1048 | { | 1099 | { |
1049 | struct v4l2_fmtdesc *p = arg; | 1100 | struct v4l2_fmtdesc *p = arg; |
1050 | struct video_device *vfd = video_devdata(file); | 1101 | struct video_device *vfd = video_devdata(file); |
1102 | bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER; | ||
1103 | bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR; | ||
1051 | bool is_rx = vfd->vfl_dir != VFL_DIR_TX; | 1104 | bool is_rx = vfd->vfl_dir != VFL_DIR_TX; |
1052 | bool is_tx = vfd->vfl_dir != VFL_DIR_RX; | 1105 | bool is_tx = vfd->vfl_dir != VFL_DIR_RX; |
1053 | 1106 | ||
1054 | switch (p->type) { | 1107 | switch (p->type) { |
1055 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 1108 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
1056 | if (unlikely(!is_rx || !ops->vidioc_enum_fmt_vid_cap)) | 1109 | if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_cap)) |
1057 | break; | 1110 | break; |
1058 | return ops->vidioc_enum_fmt_vid_cap(file, fh, arg); | 1111 | return ops->vidioc_enum_fmt_vid_cap(file, fh, arg); |
1059 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: | 1112 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
1060 | if (unlikely(!is_rx || !ops->vidioc_enum_fmt_vid_cap_mplane)) | 1113 | if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_cap_mplane)) |
1061 | break; | 1114 | break; |
1062 | return ops->vidioc_enum_fmt_vid_cap_mplane(file, fh, arg); | 1115 | return ops->vidioc_enum_fmt_vid_cap_mplane(file, fh, arg); |
1063 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 1116 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: |
1064 | if (unlikely(!is_rx || !ops->vidioc_enum_fmt_vid_overlay)) | 1117 | if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_overlay)) |
1065 | break; | 1118 | break; |
1066 | return ops->vidioc_enum_fmt_vid_overlay(file, fh, arg); | 1119 | return ops->vidioc_enum_fmt_vid_overlay(file, fh, arg); |
1067 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | 1120 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: |
1068 | if (unlikely(!is_tx || !ops->vidioc_enum_fmt_vid_out)) | 1121 | if (unlikely(!is_tx || !is_vid || !ops->vidioc_enum_fmt_vid_out)) |
1069 | break; | 1122 | break; |
1070 | return ops->vidioc_enum_fmt_vid_out(file, fh, arg); | 1123 | return ops->vidioc_enum_fmt_vid_out(file, fh, arg); |
1071 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: | 1124 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: |
1072 | if (unlikely(!is_tx || !ops->vidioc_enum_fmt_vid_out_mplane)) | 1125 | if (unlikely(!is_tx || !is_vid || !ops->vidioc_enum_fmt_vid_out_mplane)) |
1073 | break; | 1126 | break; |
1074 | return ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg); | 1127 | return ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg); |
1075 | case V4L2_BUF_TYPE_SDR_CAPTURE: | 1128 | case V4L2_BUF_TYPE_SDR_CAPTURE: |
1076 | if (unlikely(!is_rx || !ops->vidioc_enum_fmt_sdr_cap)) | 1129 | if (unlikely(!is_rx || !is_sdr || !ops->vidioc_enum_fmt_sdr_cap)) |
1077 | break; | 1130 | break; |
1078 | return ops->vidioc_enum_fmt_sdr_cap(file, fh, arg); | 1131 | return ops->vidioc_enum_fmt_sdr_cap(file, fh, arg); |
1079 | } | 1132 | } |
@@ -1089,12 +1142,41 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops, | |||
1089 | bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR; | 1142 | bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR; |
1090 | bool is_rx = vfd->vfl_dir != VFL_DIR_TX; | 1143 | bool is_rx = vfd->vfl_dir != VFL_DIR_TX; |
1091 | bool is_tx = vfd->vfl_dir != VFL_DIR_RX; | 1144 | bool is_tx = vfd->vfl_dir != VFL_DIR_RX; |
1145 | int ret; | ||
1146 | |||
1147 | /* | ||
1148 | * fmt can't be cleared for these overlay types due to the 'clips' | ||
1149 | * 'clipcount' and 'bitmap' pointers in struct v4l2_window. | ||
1150 | * Those are provided by the user. So handle these two overlay types | ||
1151 | * first, and then just do a simple memset for the other types. | ||
1152 | */ | ||
1153 | switch (p->type) { | ||
1154 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | ||
1155 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: { | ||
1156 | struct v4l2_clip *clips = p->fmt.win.clips; | ||
1157 | u32 clipcount = p->fmt.win.clipcount; | ||
1158 | void *bitmap = p->fmt.win.bitmap; | ||
1159 | |||
1160 | memset(&p->fmt, 0, sizeof(p->fmt)); | ||
1161 | p->fmt.win.clips = clips; | ||
1162 | p->fmt.win.clipcount = clipcount; | ||
1163 | p->fmt.win.bitmap = bitmap; | ||
1164 | break; | ||
1165 | } | ||
1166 | default: | ||
1167 | memset(&p->fmt, 0, sizeof(p->fmt)); | ||
1168 | break; | ||
1169 | } | ||
1092 | 1170 | ||
1093 | switch (p->type) { | 1171 | switch (p->type) { |
1094 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 1172 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
1095 | if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap)) | 1173 | if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap)) |
1096 | break; | 1174 | break; |
1097 | return ops->vidioc_g_fmt_vid_cap(file, fh, arg); | 1175 | p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; |
1176 | ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg); | ||
1177 | /* just in case the driver zeroed it again */ | ||
1178 | p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; | ||
1179 | return ret; | ||
1098 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: | 1180 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
1099 | if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap_mplane)) | 1181 | if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_vid_cap_mplane)) |
1100 | break; | 1182 | break; |
@@ -1114,7 +1196,11 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops, | |||
1114 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: | 1196 | case V4L2_BUF_TYPE_VIDEO_OUTPUT: |
1115 | if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out)) | 1197 | if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out)) |
1116 | break; | 1198 | break; |
1117 | return ops->vidioc_g_fmt_vid_out(file, fh, arg); | 1199 | p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; |
1200 | ret = ops->vidioc_g_fmt_vid_out(file, fh, arg); | ||
1201 | /* just in case the driver zeroed it again */ | ||
1202 | p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; | ||
1203 | return ret; | ||
1118 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: | 1204 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: |
1119 | if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out_mplane)) | 1205 | if (unlikely(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out_mplane)) |
1120 | break; | 1206 | break; |
@@ -1148,13 +1234,19 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops, | |||
1148 | bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR; | 1234 | bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR; |
1149 | bool is_rx = vfd->vfl_dir != VFL_DIR_TX; | 1235 | bool is_rx = vfd->vfl_dir != VFL_DIR_TX; |
1150 | bool is_tx = vfd->vfl_dir != VFL_DIR_RX; | 1236 | bool is_tx = vfd->vfl_dir != VFL_DIR_RX; |
1237 | int ret; | ||
1238 | |||
1239 | v4l_sanitize_format(p); | ||
1151 | 1240 | ||
1152 | switch (p->type) { | 1241 | switch (p->type) { |
1153 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 1242 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
1154 | if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_cap)) | 1243 | if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_cap)) |
1155 | break; | 1244 | break; |
1156 | CLEAR_AFTER_FIELD(p, fmt.pix); | 1245 | CLEAR_AFTER_FIELD(p, fmt.pix); |
1157 | return ops->vidioc_s_fmt_vid_cap(file, fh, arg); | 1246 | ret = ops->vidioc_s_fmt_vid_cap(file, fh, arg); |
1247 | /* just in case the driver zeroed it again */ | ||
1248 | p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; | ||
1249 | return ret; | ||
1158 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: | 1250 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
1159 | if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_cap_mplane)) | 1251 | if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_cap_mplane)) |
1160 | break; | 1252 | break; |
@@ -1179,7 +1271,10 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops, | |||
1179 | if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out)) | 1271 | if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out)) |
1180 | break; | 1272 | break; |
1181 | CLEAR_AFTER_FIELD(p, fmt.pix); | 1273 | CLEAR_AFTER_FIELD(p, fmt.pix); |
1182 | return ops->vidioc_s_fmt_vid_out(file, fh, arg); | 1274 | ret = ops->vidioc_s_fmt_vid_out(file, fh, arg); |
1275 | /* just in case the driver zeroed it again */ | ||
1276 | p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; | ||
1277 | return ret; | ||
1183 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: | 1278 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: |
1184 | if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out_mplane)) | 1279 | if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out_mplane)) |
1185 | break; | 1280 | break; |
@@ -1218,13 +1313,19 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops, | |||
1218 | bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR; | 1313 | bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR; |
1219 | bool is_rx = vfd->vfl_dir != VFL_DIR_TX; | 1314 | bool is_rx = vfd->vfl_dir != VFL_DIR_TX; |
1220 | bool is_tx = vfd->vfl_dir != VFL_DIR_RX; | 1315 | bool is_tx = vfd->vfl_dir != VFL_DIR_RX; |
1316 | int ret; | ||
1317 | |||
1318 | v4l_sanitize_format(p); | ||
1221 | 1319 | ||
1222 | switch (p->type) { | 1320 | switch (p->type) { |
1223 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 1321 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
1224 | if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_cap)) | 1322 | if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_cap)) |
1225 | break; | 1323 | break; |
1226 | CLEAR_AFTER_FIELD(p, fmt.pix); | 1324 | CLEAR_AFTER_FIELD(p, fmt.pix); |
1227 | return ops->vidioc_try_fmt_vid_cap(file, fh, arg); | 1325 | ret = ops->vidioc_try_fmt_vid_cap(file, fh, arg); |
1326 | /* just in case the driver zeroed it again */ | ||
1327 | p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; | ||
1328 | return ret; | ||
1228 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: | 1329 | case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: |
1229 | if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_cap_mplane)) | 1330 | if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_cap_mplane)) |
1230 | break; | 1331 | break; |
@@ -1249,7 +1350,10 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops, | |||
1249 | if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out)) | 1350 | if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out)) |
1250 | break; | 1351 | break; |
1251 | CLEAR_AFTER_FIELD(p, fmt.pix); | 1352 | CLEAR_AFTER_FIELD(p, fmt.pix); |
1252 | return ops->vidioc_try_fmt_vid_out(file, fh, arg); | 1353 | ret = ops->vidioc_try_fmt_vid_out(file, fh, arg); |
1354 | /* just in case the driver zeroed it again */ | ||
1355 | p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; | ||
1356 | return ret; | ||
1253 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: | 1357 | case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: |
1254 | if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out_mplane)) | 1358 | if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out_mplane)) |
1255 | break; | 1359 | break; |
@@ -1502,7 +1606,18 @@ static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops, | |||
1502 | struct v4l2_create_buffers *create = arg; | 1606 | struct v4l2_create_buffers *create = arg; |
1503 | int ret = check_fmt(file, create->format.type); | 1607 | int ret = check_fmt(file, create->format.type); |
1504 | 1608 | ||
1505 | return ret ? ret : ops->vidioc_create_bufs(file, fh, create); | 1609 | if (ret) |
1610 | return ret; | ||
1611 | |||
1612 | v4l_sanitize_format(&create->format); | ||
1613 | |||
1614 | ret = ops->vidioc_create_bufs(file, fh, create); | ||
1615 | |||
1616 | if (create->format.type == V4L2_BUF_TYPE_VIDEO_CAPTURE || | ||
1617 | create->format.type == V4L2_BUF_TYPE_VIDEO_OUTPUT) | ||
1618 | create->format.fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC; | ||
1619 | |||
1620 | return ret; | ||
1506 | } | 1621 | } |
1507 | 1622 | ||
1508 | static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops, | 1623 | static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops, |
@@ -1561,6 +1676,23 @@ static int v4l_queryctrl(const struct v4l2_ioctl_ops *ops, | |||
1561 | return -ENOTTY; | 1676 | return -ENOTTY; |
1562 | } | 1677 | } |
1563 | 1678 | ||
1679 | static int v4l_query_ext_ctrl(const struct v4l2_ioctl_ops *ops, | ||
1680 | struct file *file, void *fh, void *arg) | ||
1681 | { | ||
1682 | struct video_device *vfd = video_devdata(file); | ||
1683 | struct v4l2_query_ext_ctrl *p = arg; | ||
1684 | struct v4l2_fh *vfh = | ||
1685 | test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL; | ||
1686 | |||
1687 | if (vfh && vfh->ctrl_handler) | ||
1688 | return v4l2_query_ext_ctrl(vfh->ctrl_handler, p); | ||
1689 | if (vfd->ctrl_handler) | ||
1690 | return v4l2_query_ext_ctrl(vfd->ctrl_handler, p); | ||
1691 | if (ops->vidioc_query_ext_ctrl) | ||
1692 | return ops->vidioc_query_ext_ctrl(file, fh, p); | ||
1693 | return -ENOTTY; | ||
1694 | } | ||
1695 | |||
1564 | static int v4l_querymenu(const struct v4l2_ioctl_ops *ops, | 1696 | static int v4l_querymenu(const struct v4l2_ioctl_ops *ops, |
1565 | struct file *file, void *fh, void *arg) | 1697 | struct file *file, void *fh, void *arg) |
1566 | { | 1698 | { |
@@ -1751,37 +1883,41 @@ static int v4l_cropcap(const struct v4l2_ioctl_ops *ops, | |||
1751 | struct file *file, void *fh, void *arg) | 1883 | struct file *file, void *fh, void *arg) |
1752 | { | 1884 | { |
1753 | struct v4l2_cropcap *p = arg; | 1885 | struct v4l2_cropcap *p = arg; |
1754 | struct v4l2_selection s = { .type = p->type }; | ||
1755 | int ret; | ||
1756 | 1886 | ||
1757 | if (ops->vidioc_cropcap) | 1887 | if (ops->vidioc_g_selection) { |
1758 | return ops->vidioc_cropcap(file, fh, p); | 1888 | struct v4l2_selection s = { .type = p->type }; |
1889 | int ret; | ||
1759 | 1890 | ||
1760 | /* obtaining bounds */ | 1891 | /* obtaining bounds */ |
1761 | if (V4L2_TYPE_IS_OUTPUT(p->type)) | 1892 | if (V4L2_TYPE_IS_OUTPUT(p->type)) |
1762 | s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS; | 1893 | s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS; |
1763 | else | 1894 | else |
1764 | s.target = V4L2_SEL_TGT_CROP_BOUNDS; | 1895 | s.target = V4L2_SEL_TGT_CROP_BOUNDS; |
1765 | 1896 | ||
1766 | ret = ops->vidioc_g_selection(file, fh, &s); | 1897 | ret = ops->vidioc_g_selection(file, fh, &s); |
1767 | if (ret) | 1898 | if (ret) |
1768 | return ret; | 1899 | return ret; |
1769 | p->bounds = s.r; | 1900 | p->bounds = s.r; |
1770 | 1901 | ||
1771 | /* obtaining defrect */ | 1902 | /* obtaining defrect */ |
1772 | if (V4L2_TYPE_IS_OUTPUT(p->type)) | 1903 | if (V4L2_TYPE_IS_OUTPUT(p->type)) |
1773 | s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT; | 1904 | s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT; |
1774 | else | 1905 | else |
1775 | s.target = V4L2_SEL_TGT_CROP_DEFAULT; | 1906 | s.target = V4L2_SEL_TGT_CROP_DEFAULT; |
1776 | 1907 | ||
1777 | ret = ops->vidioc_g_selection(file, fh, &s); | 1908 | ret = ops->vidioc_g_selection(file, fh, &s); |
1778 | if (ret) | 1909 | if (ret) |
1779 | return ret; | 1910 | return ret; |
1780 | p->defrect = s.r; | 1911 | p->defrect = s.r; |
1912 | } | ||
1781 | 1913 | ||
1782 | /* setting trivial pixelaspect */ | 1914 | /* setting trivial pixelaspect */ |
1783 | p->pixelaspect.numerator = 1; | 1915 | p->pixelaspect.numerator = 1; |
1784 | p->pixelaspect.denominator = 1; | 1916 | p->pixelaspect.denominator = 1; |
1917 | |||
1918 | if (ops->vidioc_cropcap) | ||
1919 | return ops->vidioc_cropcap(file, fh, p); | ||
1920 | |||
1785 | return 0; | 1921 | return 0; |
1786 | } | 1922 | } |
1787 | 1923 | ||
@@ -1951,8 +2087,11 @@ static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops, | |||
1951 | if (type != p->type) | 2087 | if (type != p->type) |
1952 | return -EINVAL; | 2088 | return -EINVAL; |
1953 | } | 2089 | } |
1954 | if (ops->vidioc_enum_freq_bands) | 2090 | if (ops->vidioc_enum_freq_bands) { |
1955 | return ops->vidioc_enum_freq_bands(file, fh, p); | 2091 | err = ops->vidioc_enum_freq_bands(file, fh, p); |
2092 | if (err != -ENOTTY) | ||
2093 | return err; | ||
2094 | } | ||
1956 | if (is_valid_ioctl(vfd, VIDIOC_G_TUNER)) { | 2095 | if (is_valid_ioctl(vfd, VIDIOC_G_TUNER)) { |
1957 | struct v4l2_tuner t = { | 2096 | struct v4l2_tuner t = { |
1958 | .index = p->tuner, | 2097 | .index = p->tuner, |
@@ -2042,7 +2181,7 @@ struct v4l2_ioctl_info { | |||
2042 | static struct v4l2_ioctl_info v4l2_ioctls[] = { | 2181 | static struct v4l2_ioctl_info v4l2_ioctls[] = { |
2043 | IOCTL_INFO_FNC(VIDIOC_QUERYCAP, v4l_querycap, v4l_print_querycap, 0), | 2182 | IOCTL_INFO_FNC(VIDIOC_QUERYCAP, v4l_querycap, v4l_print_querycap, 0), |
2044 | IOCTL_INFO_FNC(VIDIOC_ENUM_FMT, v4l_enum_fmt, v4l_print_fmtdesc, INFO_FL_CLEAR(v4l2_fmtdesc, type)), | 2183 | IOCTL_INFO_FNC(VIDIOC_ENUM_FMT, v4l_enum_fmt, v4l_print_fmtdesc, INFO_FL_CLEAR(v4l2_fmtdesc, type)), |
2045 | IOCTL_INFO_FNC(VIDIOC_G_FMT, v4l_g_fmt, v4l_print_format, INFO_FL_CLEAR(v4l2_format, type)), | 2184 | IOCTL_INFO_FNC(VIDIOC_G_FMT, v4l_g_fmt, v4l_print_format, 0), |
2046 | IOCTL_INFO_FNC(VIDIOC_S_FMT, v4l_s_fmt, v4l_print_format, INFO_FL_PRIO), | 2185 | IOCTL_INFO_FNC(VIDIOC_S_FMT, v4l_s_fmt, v4l_print_format, INFO_FL_PRIO), |
2047 | IOCTL_INFO_FNC(VIDIOC_REQBUFS, v4l_reqbufs, v4l_print_requestbuffers, INFO_FL_PRIO | INFO_FL_QUEUE), | 2186 | IOCTL_INFO_FNC(VIDIOC_REQBUFS, v4l_reqbufs, v4l_print_requestbuffers, INFO_FL_PRIO | INFO_FL_QUEUE), |
2048 | IOCTL_INFO_FNC(VIDIOC_QUERYBUF, v4l_querybuf, v4l_print_buffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_buffer, length)), | 2187 | IOCTL_INFO_FNC(VIDIOC_QUERYBUF, v4l_querybuf, v4l_print_buffer, INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_buffer, length)), |
@@ -2070,8 +2209,8 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = { | |||
2070 | IOCTL_INFO_FNC(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)), | 2209 | IOCTL_INFO_FNC(VIDIOC_QUERYMENU, v4l_querymenu, v4l_print_querymenu, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_querymenu, index)), |
2071 | IOCTL_INFO_STD(VIDIOC_G_INPUT, vidioc_g_input, v4l_print_u32, 0), | 2210 | IOCTL_INFO_STD(VIDIOC_G_INPUT, vidioc_g_input, v4l_print_u32, 0), |
2072 | IOCTL_INFO_FNC(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO), | 2211 | IOCTL_INFO_FNC(VIDIOC_S_INPUT, v4l_s_input, v4l_print_u32, INFO_FL_PRIO), |
2073 | IOCTL_INFO_STD(VIDIOC_G_EDID, vidioc_g_edid, v4l_print_edid, INFO_FL_CLEAR(v4l2_edid, edid)), | 2212 | IOCTL_INFO_STD(VIDIOC_G_EDID, vidioc_g_edid, v4l_print_edid, 0), |
2074 | IOCTL_INFO_STD(VIDIOC_S_EDID, vidioc_s_edid, v4l_print_edid, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_edid, edid)), | 2213 | IOCTL_INFO_STD(VIDIOC_S_EDID, vidioc_s_edid, v4l_print_edid, INFO_FL_PRIO), |
2075 | IOCTL_INFO_STD(VIDIOC_G_OUTPUT, vidioc_g_output, v4l_print_u32, 0), | 2214 | IOCTL_INFO_STD(VIDIOC_G_OUTPUT, vidioc_g_output, v4l_print_u32, 0), |
2076 | IOCTL_INFO_FNC(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO), | 2215 | IOCTL_INFO_FNC(VIDIOC_S_OUTPUT, v4l_s_output, v4l_print_u32, INFO_FL_PRIO), |
2077 | IOCTL_INFO_FNC(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)), | 2216 | IOCTL_INFO_FNC(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)), |
@@ -2084,8 +2223,8 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = { | |||
2084 | IOCTL_INFO_FNC(VIDIOC_CROPCAP, v4l_cropcap, v4l_print_cropcap, INFO_FL_CLEAR(v4l2_cropcap, type)), | 2223 | IOCTL_INFO_FNC(VIDIOC_CROPCAP, v4l_cropcap, v4l_print_cropcap, INFO_FL_CLEAR(v4l2_cropcap, type)), |
2085 | IOCTL_INFO_FNC(VIDIOC_G_CROP, v4l_g_crop, v4l_print_crop, INFO_FL_CLEAR(v4l2_crop, type)), | 2224 | IOCTL_INFO_FNC(VIDIOC_G_CROP, v4l_g_crop, v4l_print_crop, INFO_FL_CLEAR(v4l2_crop, type)), |
2086 | IOCTL_INFO_FNC(VIDIOC_S_CROP, v4l_s_crop, v4l_print_crop, INFO_FL_PRIO), | 2225 | IOCTL_INFO_FNC(VIDIOC_S_CROP, v4l_s_crop, v4l_print_crop, INFO_FL_PRIO), |
2087 | IOCTL_INFO_STD(VIDIOC_G_SELECTION, vidioc_g_selection, v4l_print_selection, 0), | 2226 | IOCTL_INFO_STD(VIDIOC_G_SELECTION, vidioc_g_selection, v4l_print_selection, INFO_FL_CLEAR(v4l2_selection, r)), |
2088 | IOCTL_INFO_STD(VIDIOC_S_SELECTION, vidioc_s_selection, v4l_print_selection, INFO_FL_PRIO), | 2227 | IOCTL_INFO_STD(VIDIOC_S_SELECTION, vidioc_s_selection, v4l_print_selection, INFO_FL_PRIO | INFO_FL_CLEAR(v4l2_selection, r)), |
2089 | IOCTL_INFO_STD(VIDIOC_G_JPEGCOMP, vidioc_g_jpegcomp, v4l_print_jpegcompression, 0), | 2228 | IOCTL_INFO_STD(VIDIOC_G_JPEGCOMP, vidioc_g_jpegcomp, v4l_print_jpegcompression, 0), |
2090 | IOCTL_INFO_STD(VIDIOC_S_JPEGCOMP, vidioc_s_jpegcomp, v4l_print_jpegcompression, INFO_FL_PRIO), | 2229 | IOCTL_INFO_STD(VIDIOC_S_JPEGCOMP, vidioc_s_jpegcomp, v4l_print_jpegcompression, INFO_FL_PRIO), |
2091 | IOCTL_INFO_FNC(VIDIOC_QUERYSTD, v4l_querystd, v4l_print_std, 0), | 2230 | IOCTL_INFO_FNC(VIDIOC_QUERYSTD, v4l_querystd, v4l_print_std, 0), |
@@ -2121,6 +2260,7 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = { | |||
2121 | IOCTL_INFO_STD(VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap, v4l_print_dv_timings_cap, INFO_FL_CLEAR(v4l2_dv_timings_cap, type)), | 2260 | IOCTL_INFO_STD(VIDIOC_DV_TIMINGS_CAP, vidioc_dv_timings_cap, v4l_print_dv_timings_cap, INFO_FL_CLEAR(v4l2_dv_timings_cap, type)), |
2122 | IOCTL_INFO_FNC(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, v4l_print_freq_band, 0), | 2261 | IOCTL_INFO_FNC(VIDIOC_ENUM_FREQ_BANDS, v4l_enum_freq_bands, v4l_print_freq_band, 0), |
2123 | IOCTL_INFO_FNC(VIDIOC_DBG_G_CHIP_INFO, v4l_dbg_g_chip_info, v4l_print_dbg_chip_info, INFO_FL_CLEAR(v4l2_dbg_chip_info, match)), | 2262 | IOCTL_INFO_FNC(VIDIOC_DBG_G_CHIP_INFO, v4l_dbg_g_chip_info, v4l_print_dbg_chip_info, INFO_FL_CLEAR(v4l2_dbg_chip_info, match)), |
2263 | IOCTL_INFO_FNC(VIDIOC_QUERY_EXT_CTRL, v4l_query_ext_ctrl, v4l_print_query_ext_ctrl, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_query_ext_ctrl, id)), | ||
2124 | }; | 2264 | }; |
2125 | #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) | 2265 | #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) |
2126 | 2266 | ||
@@ -2190,7 +2330,6 @@ static long __video_do_ioctl(struct file *file, | |||
2190 | const struct v4l2_ioctl_info *info; | 2330 | const struct v4l2_ioctl_info *info; |
2191 | void *fh = file->private_data; | 2331 | void *fh = file->private_data; |
2192 | struct v4l2_fh *vfh = NULL; | 2332 | struct v4l2_fh *vfh = NULL; |
2193 | int use_fh_prio = 0; | ||
2194 | int debug = vfd->debug; | 2333 | int debug = vfd->debug; |
2195 | long ret = -ENOTTY; | 2334 | long ret = -ENOTTY; |
2196 | 2335 | ||
@@ -2200,10 +2339,8 @@ static long __video_do_ioctl(struct file *file, | |||
2200 | return ret; | 2339 | return ret; |
2201 | } | 2340 | } |
2202 | 2341 | ||
2203 | if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) { | 2342 | if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) |
2204 | vfh = file->private_data; | 2343 | vfh = file->private_data; |
2205 | use_fh_prio = test_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags); | ||
2206 | } | ||
2207 | 2344 | ||
2208 | if (v4l2_is_known_ioctl(cmd)) { | 2345 | if (v4l2_is_known_ioctl(cmd)) { |
2209 | info = &v4l2_ioctls[_IOC_NR(cmd)]; | 2346 | info = &v4l2_ioctls[_IOC_NR(cmd)]; |
@@ -2212,7 +2349,7 @@ static long __video_do_ioctl(struct file *file, | |||
2212 | !((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler)) | 2349 | !((info->flags & INFO_FL_CTRL) && vfh && vfh->ctrl_handler)) |
2213 | goto done; | 2350 | goto done; |
2214 | 2351 | ||
2215 | if (use_fh_prio && (info->flags & INFO_FL_PRIO)) { | 2352 | if (vfh && (info->flags & INFO_FL_PRIO)) { |
2216 | ret = v4l2_prio_check(vfd->prio, vfh->prio); | 2353 | ret = v4l2_prio_check(vfd->prio, vfh->prio); |
2217 | if (ret) | 2354 | if (ret) |
2218 | goto done; | 2355 | goto done; |
@@ -2237,7 +2374,7 @@ static long __video_do_ioctl(struct file *file, | |||
2237 | ret = -ENOTTY; | 2374 | ret = -ENOTTY; |
2238 | } else { | 2375 | } else { |
2239 | ret = ops->vidioc_default(file, fh, | 2376 | ret = ops->vidioc_default(file, fh, |
2240 | use_fh_prio ? v4l2_prio_check(vfd->prio, vfh->prio) >= 0 : 0, | 2377 | vfh ? v4l2_prio_check(vfd->prio, vfh->prio) >= 0 : 0, |
2241 | cmd, arg); | 2378 | cmd, arg); |
2242 | } | 2379 | } |
2243 | 2380 | ||