aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/v4l2-core/v4l2-subdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/v4l2-core/v4l2-subdev.c')
-rw-r--r--drivers/media/v4l2-core/v4l2-subdev.c125
1 files changed, 79 insertions, 46 deletions
diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c
index 058c1a6e8392..b4d235c13fbf 100644
--- a/drivers/media/v4l2-core/v4l2-subdev.c
+++ b/drivers/media/v4l2-core/v4l2-subdev.c
@@ -126,6 +126,57 @@ static int subdev_close(struct file *file)
126 return 0; 126 return 0;
127} 127}
128 128
129#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
130static int check_format(struct v4l2_subdev *sd,
131 struct v4l2_subdev_format *format)
132{
133 if (format->which != V4L2_SUBDEV_FORMAT_TRY &&
134 format->which != V4L2_SUBDEV_FORMAT_ACTIVE)
135 return -EINVAL;
136
137 if (format->pad >= sd->entity.num_pads)
138 return -EINVAL;
139
140 return 0;
141}
142
143static int check_crop(struct v4l2_subdev *sd, struct v4l2_subdev_crop *crop)
144{
145 if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
146 crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)
147 return -EINVAL;
148
149 if (crop->pad >= sd->entity.num_pads)
150 return -EINVAL;
151
152 return 0;
153}
154
155static int check_selection(struct v4l2_subdev *sd,
156 struct v4l2_subdev_selection *sel)
157{
158 if (sel->which != V4L2_SUBDEV_FORMAT_TRY &&
159 sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
160 return -EINVAL;
161
162 if (sel->pad >= sd->entity.num_pads)
163 return -EINVAL;
164
165 return 0;
166}
167
168static int check_edid(struct v4l2_subdev *sd, struct v4l2_subdev_edid *edid)
169{
170 if (edid->pad >= sd->entity.num_pads)
171 return -EINVAL;
172
173 if (edid->blocks && edid->edid == NULL)
174 return -EINVAL;
175
176 return 0;
177}
178#endif
179
129static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) 180static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
130{ 181{
131 struct video_device *vdev = video_devdata(file); 182 struct video_device *vdev = video_devdata(file);
@@ -133,12 +184,16 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
133 struct v4l2_fh *vfh = file->private_data; 184 struct v4l2_fh *vfh = file->private_data;
134#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) 185#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
135 struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh); 186 struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
187 int rval;
136#endif 188#endif
137 189
138 switch (cmd) { 190 switch (cmd) {
139 case VIDIOC_QUERYCTRL: 191 case VIDIOC_QUERYCTRL:
140 return v4l2_queryctrl(vfh->ctrl_handler, arg); 192 return v4l2_queryctrl(vfh->ctrl_handler, arg);
141 193
194 case VIDIOC_QUERY_EXT_CTRL:
195 return v4l2_query_ext_ctrl(vfh->ctrl_handler, arg);
196
142 case VIDIOC_QUERYMENU: 197 case VIDIOC_QUERYMENU:
143 return v4l2_querymenu(vfh->ctrl_handler, arg); 198 return v4l2_querymenu(vfh->ctrl_handler, arg);
144 199
@@ -203,12 +258,9 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
203 case VIDIOC_SUBDEV_G_FMT: { 258 case VIDIOC_SUBDEV_G_FMT: {
204 struct v4l2_subdev_format *format = arg; 259 struct v4l2_subdev_format *format = arg;
205 260
206 if (format->which != V4L2_SUBDEV_FORMAT_TRY && 261 rval = check_format(sd, format);
207 format->which != V4L2_SUBDEV_FORMAT_ACTIVE) 262 if (rval)
208 return -EINVAL; 263 return rval;
209
210 if (format->pad >= sd->entity.num_pads)
211 return -EINVAL;
212 264
213 return v4l2_subdev_call(sd, pad, get_fmt, subdev_fh, format); 265 return v4l2_subdev_call(sd, pad, get_fmt, subdev_fh, format);
214 } 266 }
@@ -216,12 +268,9 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
216 case VIDIOC_SUBDEV_S_FMT: { 268 case VIDIOC_SUBDEV_S_FMT: {
217 struct v4l2_subdev_format *format = arg; 269 struct v4l2_subdev_format *format = arg;
218 270
219 if (format->which != V4L2_SUBDEV_FORMAT_TRY && 271 rval = check_format(sd, format);
220 format->which != V4L2_SUBDEV_FORMAT_ACTIVE) 272 if (rval)
221 return -EINVAL; 273 return rval;
222
223 if (format->pad >= sd->entity.num_pads)
224 return -EINVAL;
225 274
226 return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh, format); 275 return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh, format);
227 } 276 }
@@ -229,14 +278,10 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
229 case VIDIOC_SUBDEV_G_CROP: { 278 case VIDIOC_SUBDEV_G_CROP: {
230 struct v4l2_subdev_crop *crop = arg; 279 struct v4l2_subdev_crop *crop = arg;
231 struct v4l2_subdev_selection sel; 280 struct v4l2_subdev_selection sel;
232 int rval;
233
234 if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
235 crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)
236 return -EINVAL;
237 281
238 if (crop->pad >= sd->entity.num_pads) 282 rval = check_crop(sd, crop);
239 return -EINVAL; 283 if (rval)
284 return rval;
240 285
241 rval = v4l2_subdev_call(sd, pad, get_crop, subdev_fh, crop); 286 rval = v4l2_subdev_call(sd, pad, get_crop, subdev_fh, crop);
242 if (rval != -ENOIOCTLCMD) 287 if (rval != -ENOIOCTLCMD)
@@ -258,14 +303,10 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
258 case VIDIOC_SUBDEV_S_CROP: { 303 case VIDIOC_SUBDEV_S_CROP: {
259 struct v4l2_subdev_crop *crop = arg; 304 struct v4l2_subdev_crop *crop = arg;
260 struct v4l2_subdev_selection sel; 305 struct v4l2_subdev_selection sel;
261 int rval;
262
263 if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
264 crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)
265 return -EINVAL;
266 306
267 if (crop->pad >= sd->entity.num_pads) 307 rval = check_crop(sd, crop);
268 return -EINVAL; 308 if (rval)
309 return rval;
269 310
270 rval = v4l2_subdev_call(sd, pad, set_crop, subdev_fh, crop); 311 rval = v4l2_subdev_call(sd, pad, set_crop, subdev_fh, crop);
271 if (rval != -ENOIOCTLCMD) 312 if (rval != -ENOIOCTLCMD)
@@ -336,12 +377,9 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
336 case VIDIOC_SUBDEV_G_SELECTION: { 377 case VIDIOC_SUBDEV_G_SELECTION: {
337 struct v4l2_subdev_selection *sel = arg; 378 struct v4l2_subdev_selection *sel = arg;
338 379
339 if (sel->which != V4L2_SUBDEV_FORMAT_TRY && 380 rval = check_selection(sd, sel);
340 sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) 381 if (rval)
341 return -EINVAL; 382 return rval;
342
343 if (sel->pad >= sd->entity.num_pads)
344 return -EINVAL;
345 383
346 return v4l2_subdev_call( 384 return v4l2_subdev_call(
347 sd, pad, get_selection, subdev_fh, sel); 385 sd, pad, get_selection, subdev_fh, sel);
@@ -350,12 +388,9 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
350 case VIDIOC_SUBDEV_S_SELECTION: { 388 case VIDIOC_SUBDEV_S_SELECTION: {
351 struct v4l2_subdev_selection *sel = arg; 389 struct v4l2_subdev_selection *sel = arg;
352 390
353 if (sel->which != V4L2_SUBDEV_FORMAT_TRY && 391 rval = check_selection(sd, sel);
354 sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) 392 if (rval)
355 return -EINVAL; 393 return rval;
356
357 if (sel->pad >= sd->entity.num_pads)
358 return -EINVAL;
359 394
360 return v4l2_subdev_call( 395 return v4l2_subdev_call(
361 sd, pad, set_selection, subdev_fh, sel); 396 sd, pad, set_selection, subdev_fh, sel);
@@ -364,10 +399,9 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
364 case VIDIOC_G_EDID: { 399 case VIDIOC_G_EDID: {
365 struct v4l2_subdev_edid *edid = arg; 400 struct v4l2_subdev_edid *edid = arg;
366 401
367 if (edid->pad >= sd->entity.num_pads) 402 rval = check_edid(sd, edid);
368 return -EINVAL; 403 if (rval)
369 if (edid->blocks && edid->edid == NULL) 404 return rval;
370 return -EINVAL;
371 405
372 return v4l2_subdev_call(sd, pad, get_edid, edid); 406 return v4l2_subdev_call(sd, pad, get_edid, edid);
373 } 407 }
@@ -375,10 +409,9 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
375 case VIDIOC_S_EDID: { 409 case VIDIOC_S_EDID: {
376 struct v4l2_subdev_edid *edid = arg; 410 struct v4l2_subdev_edid *edid = arg;
377 411
378 if (edid->pad >= sd->entity.num_pads) 412 rval = check_edid(sd, edid);
379 return -EINVAL; 413 if (rval)
380 if (edid->blocks && edid->edid == NULL) 414 return rval;
381 return -EINVAL;
382 415
383 return v4l2_subdev_call(sd, pad, set_edid, edid); 416 return v4l2_subdev_call(sd, pad, set_edid, edid);
384 } 417 }