1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * uvc_v4l2.c -- USB Video Class driver - V4L2 API
4 *
5 * Copyright (C) 2005-2010
6 * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
7 */
8
9 #include <linux/compat.h>
10 #include <linux/kernel.h>
11 #include <linux/list.h>
12 #include <linux/module.h>
13 #include <linux/slab.h>
14 #include <linux/usb.h>
15 #include <linux/videodev2.h>
16 #include <linux/vmalloc.h>
17 #include <linux/mm.h>
18 #include <linux/wait.h>
19 #include <linux/atomic.h>
20
21 #include <media/v4l2-common.h>
22 #include <media/v4l2-ctrls.h>
23 #include <media/v4l2-event.h>
24 #include <media/v4l2-ioctl.h>
25
26 #include "uvcvideo.h"
27
28 /* ------------------------------------------------------------------------
29 * UVC ioctls
30 */
uvc_ioctl_ctrl_map(struct uvc_video_chain * chain,struct uvc_xu_control_mapping * xmap)31 static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain,
32 struct uvc_xu_control_mapping *xmap)
33 {
34 struct uvc_control_mapping *map;
35 unsigned int size;
36 int ret;
37
38 map = kzalloc(sizeof(*map), GFP_KERNEL);
39 if (map == NULL)
40 return -ENOMEM;
41
42 map->id = xmap->id;
43 memcpy(map->name, xmap->name, sizeof(map->name));
44 memcpy(map->entity, xmap->entity, sizeof(map->entity));
45 map->selector = xmap->selector;
46 map->size = xmap->size;
47 map->offset = xmap->offset;
48 map->v4l2_type = xmap->v4l2_type;
49 map->data_type = xmap->data_type;
50
51 switch (xmap->v4l2_type) {
52 case V4L2_CTRL_TYPE_INTEGER:
53 case V4L2_CTRL_TYPE_BOOLEAN:
54 case V4L2_CTRL_TYPE_BUTTON:
55 break;
56
57 case V4L2_CTRL_TYPE_MENU:
58 /* Prevent excessive memory consumption, as well as integer
59 * overflows.
60 */
61 if (xmap->menu_count == 0 ||
62 xmap->menu_count > UVC_MAX_CONTROL_MENU_ENTRIES) {
63 ret = -EINVAL;
64 goto free_map;
65 }
66
67 size = xmap->menu_count * sizeof(*map->menu_info);
68 map->menu_info = memdup_user(xmap->menu_info, size);
69 if (IS_ERR(map->menu_info)) {
70 ret = PTR_ERR(map->menu_info);
71 goto free_map;
72 }
73
74 map->menu_count = xmap->menu_count;
75 break;
76
77 default:
78 uvc_trace(UVC_TRACE_CONTROL, "Unsupported V4L2 control type "
79 "%u.\n", xmap->v4l2_type);
80 ret = -ENOTTY;
81 goto free_map;
82 }
83
84 ret = uvc_ctrl_add_mapping(chain, map);
85
86 kfree(map->menu_info);
87 free_map:
88 kfree(map);
89
90 return ret;
91 }
92
93 /* ------------------------------------------------------------------------
94 * V4L2 interface
95 */
96
97 /*
98 * Find the frame interval closest to the requested frame interval for the
99 * given frame format and size. This should be done by the device as part of
100 * the Video Probe and Commit negotiation, but some hardware don't implement
101 * that feature.
102 */
uvc_try_frame_interval(struct uvc_frame * frame,u32 interval)103 static u32 uvc_try_frame_interval(struct uvc_frame *frame, u32 interval)
104 {
105 unsigned int i;
106
107 if (frame->bFrameIntervalType) {
108 u32 best = -1, dist;
109
110 for (i = 0; i < frame->bFrameIntervalType; ++i) {
111 dist = interval > frame->dwFrameInterval[i]
112 ? interval - frame->dwFrameInterval[i]
113 : frame->dwFrameInterval[i] - interval;
114
115 if (dist > best)
116 break;
117
118 best = dist;
119 }
120
121 interval = frame->dwFrameInterval[i-1];
122 } else {
123 const u32 min = frame->dwFrameInterval[0];
124 const u32 max = frame->dwFrameInterval[1];
125 const u32 step = frame->dwFrameInterval[2];
126
127 interval = min + (interval - min + step/2) / step * step;
128 if (interval > max)
129 interval = max;
130 }
131
132 return interval;
133 }
134
uvc_v4l2_get_bytesperline(const struct uvc_format * format,const struct uvc_frame * frame)135 static u32 uvc_v4l2_get_bytesperline(const struct uvc_format *format,
136 const struct uvc_frame *frame)
137 {
138 switch (format->fcc) {
139 case V4L2_PIX_FMT_NV12:
140 case V4L2_PIX_FMT_YVU420:
141 case V4L2_PIX_FMT_YUV420:
142 case V4L2_PIX_FMT_M420:
143 return frame->wWidth;
144
145 default:
146 return format->bpp * frame->wWidth / 8;
147 }
148 }
149
uvc_v4l2_try_format(struct uvc_streaming * stream,struct v4l2_format * fmt,struct uvc_streaming_control * probe,struct uvc_format ** uvc_format,struct uvc_frame ** uvc_frame)150 static int uvc_v4l2_try_format(struct uvc_streaming *stream,
151 struct v4l2_format *fmt, struct uvc_streaming_control *probe,
152 struct uvc_format **uvc_format, struct uvc_frame **uvc_frame)
153 {
154 struct uvc_format *format = NULL;
155 struct uvc_frame *frame = NULL;
156 u16 rw, rh;
157 unsigned int d, maxd;
158 unsigned int i;
159 u32 interval;
160 int ret = 0;
161 u8 *fcc;
162
163 if (fmt->type != stream->type)
164 return -EINVAL;
165
166 fcc = (u8 *)&fmt->fmt.pix.pixelformat;
167 uvc_trace(UVC_TRACE_FORMAT, "Trying format 0x%08x (%c%c%c%c): %ux%u.\n",
168 fmt->fmt.pix.pixelformat,
169 fcc[0], fcc[1], fcc[2], fcc[3],
170 fmt->fmt.pix.width, fmt->fmt.pix.height);
171
172 /* Check if the hardware supports the requested format, use the default
173 * format otherwise.
174 */
175 for (i = 0; i < stream->nformats; ++i) {
176 format = &stream->format[i];
177 if (format->fcc == fmt->fmt.pix.pixelformat)
178 break;
179 }
180
181 if (i == stream->nformats) {
182 format = stream->def_format;
183 fmt->fmt.pix.pixelformat = format->fcc;
184 }
185
186 /* Find the closest image size. The distance between image sizes is
187 * the size in pixels of the non-overlapping regions between the
188 * requested size and the frame-specified size.
189 */
190 rw = fmt->fmt.pix.width;
191 rh = fmt->fmt.pix.height;
192 maxd = (unsigned int)-1;
193
194 for (i = 0; i < format->nframes; ++i) {
195 u16 w = format->frame[i].wWidth;
196 u16 h = format->frame[i].wHeight;
197
198 d = min(w, rw) * min(h, rh);
199 d = w*h + rw*rh - 2*d;
200 if (d < maxd) {
201 maxd = d;
202 frame = &format->frame[i];
203 }
204
205 if (maxd == 0)
206 break;
207 }
208
209 if (frame == NULL) {
210 uvc_trace(UVC_TRACE_FORMAT, "Unsupported size %ux%u.\n",
211 fmt->fmt.pix.width, fmt->fmt.pix.height);
212 return -EINVAL;
213 }
214
215 /* Use the default frame interval. */
216 interval = frame->dwDefaultFrameInterval;
217 uvc_trace(UVC_TRACE_FORMAT, "Using default frame interval %u.%u us "
218 "(%u.%u fps).\n", interval/10, interval%10, 10000000/interval,
219 (100000000/interval)%10);
220
221 /* Set the format index, frame index and frame interval. */
222 memset(probe, 0, sizeof(*probe));
223 probe->bmHint = 1; /* dwFrameInterval */
224 probe->bFormatIndex = format->index;
225 probe->bFrameIndex = frame->bFrameIndex;
226 probe->dwFrameInterval = uvc_try_frame_interval(frame, interval);
227 /* Some webcams stall the probe control set request when the
228 * dwMaxVideoFrameSize field is set to zero. The UVC specification
229 * clearly states that the field is read-only from the host, so this
230 * is a webcam bug. Set dwMaxVideoFrameSize to the value reported by
231 * the webcam to work around the problem.
232 *
233 * The workaround could probably be enabled for all webcams, so the
234 * quirk can be removed if needed. It's currently useful to detect
235 * webcam bugs and fix them before they hit the market (providing
236 * developers test their webcams with the Linux driver as well as with
237 * the Windows driver).
238 */
239 mutex_lock(&stream->mutex);
240 if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS)
241 probe->dwMaxVideoFrameSize =
242 stream->ctrl.dwMaxVideoFrameSize;
243
244 /* Probe the device. */
245 ret = uvc_probe_video(stream, probe);
246 mutex_unlock(&stream->mutex);
247 if (ret < 0)
248 goto done;
249
250 fmt->fmt.pix.width = frame->wWidth;
251 fmt->fmt.pix.height = frame->wHeight;
252 fmt->fmt.pix.field = V4L2_FIELD_NONE;
253 fmt->fmt.pix.bytesperline = uvc_v4l2_get_bytesperline(format, frame);
254 fmt->fmt.pix.sizeimage = probe->dwMaxVideoFrameSize;
255 fmt->fmt.pix.colorspace = format->colorspace;
256
257 if (uvc_format != NULL)
258 *uvc_format = format;
259 if (uvc_frame != NULL)
260 *uvc_frame = frame;
261
262 done:
263 return ret;
264 }
265
uvc_v4l2_get_format(struct uvc_streaming * stream,struct v4l2_format * fmt)266 static int uvc_v4l2_get_format(struct uvc_streaming *stream,
267 struct v4l2_format *fmt)
268 {
269 struct uvc_format *format;
270 struct uvc_frame *frame;
271 int ret = 0;
272
273 if (fmt->type != stream->type)
274 return -EINVAL;
275
276 mutex_lock(&stream->mutex);
277 format = stream->cur_format;
278 frame = stream->cur_frame;
279
280 if (format == NULL || frame == NULL) {
281 ret = -EINVAL;
282 goto done;
283 }
284
285 fmt->fmt.pix.pixelformat = format->fcc;
286 fmt->fmt.pix.width = frame->wWidth;
287 fmt->fmt.pix.height = frame->wHeight;
288 fmt->fmt.pix.field = V4L2_FIELD_NONE;
289 fmt->fmt.pix.bytesperline = uvc_v4l2_get_bytesperline(format, frame);
290 fmt->fmt.pix.sizeimage = stream->ctrl.dwMaxVideoFrameSize;
291 fmt->fmt.pix.colorspace = format->colorspace;
292
293 done:
294 mutex_unlock(&stream->mutex);
295 return ret;
296 }
297
uvc_v4l2_set_format(struct uvc_streaming * stream,struct v4l2_format * fmt)298 static int uvc_v4l2_set_format(struct uvc_streaming *stream,
299 struct v4l2_format *fmt)
300 {
301 struct uvc_streaming_control probe;
302 struct uvc_format *format;
303 struct uvc_frame *frame;
304 int ret;
305
306 if (fmt->type != stream->type)
307 return -EINVAL;
308
309 ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame);
310 if (ret < 0)
311 return ret;
312
313 mutex_lock(&stream->mutex);
314
315 if (uvc_queue_allocated(&stream->queue)) {
316 ret = -EBUSY;
317 goto done;
318 }
319
320 stream->ctrl = probe;
321 stream->cur_format = format;
322 stream->cur_frame = frame;
323
324 done:
325 mutex_unlock(&stream->mutex);
326 return ret;
327 }
328
uvc_v4l2_get_streamparm(struct uvc_streaming * stream,struct v4l2_streamparm * parm)329 static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream,
330 struct v4l2_streamparm *parm)
331 {
332 u32 numerator, denominator;
333
334 if (parm->type != stream->type)
335 return -EINVAL;
336
337 mutex_lock(&stream->mutex);
338 numerator = stream->ctrl.dwFrameInterval;
339 mutex_unlock(&stream->mutex);
340
341 denominator = 10000000;
342 uvc_simplify_fraction(&numerator, &denominator, 8, 333);
343
344 memset(parm, 0, sizeof(*parm));
345 parm->type = stream->type;
346
347 if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
348 parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
349 parm->parm.capture.capturemode = 0;
350 parm->parm.capture.timeperframe.numerator = numerator;
351 parm->parm.capture.timeperframe.denominator = denominator;
352 parm->parm.capture.extendedmode = 0;
353 parm->parm.capture.readbuffers = 0;
354 } else {
355 parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
356 parm->parm.output.outputmode = 0;
357 parm->parm.output.timeperframe.numerator = numerator;
358 parm->parm.output.timeperframe.denominator = denominator;
359 }
360
361 return 0;
362 }
363
uvc_v4l2_set_streamparm(struct uvc_streaming * stream,struct v4l2_streamparm * parm)364 static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream,
365 struct v4l2_streamparm *parm)
366 {
367 struct uvc_streaming_control probe;
368 struct v4l2_fract timeperframe;
369 struct uvc_format *format;
370 struct uvc_frame *frame;
371 u32 interval, maxd;
372 unsigned int i;
373 int ret;
374
375 if (parm->type != stream->type)
376 return -EINVAL;
377
378 if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
379 timeperframe = parm->parm.capture.timeperframe;
380 else
381 timeperframe = parm->parm.output.timeperframe;
382
383 interval = uvc_fraction_to_interval(timeperframe.numerator,
384 timeperframe.denominator);
385 uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n",
386 timeperframe.numerator, timeperframe.denominator, interval);
387
388 mutex_lock(&stream->mutex);
389
390 if (uvc_queue_streaming(&stream->queue)) {
391 mutex_unlock(&stream->mutex);
392 return -EBUSY;
393 }
394
395 format = stream->cur_format;
396 frame = stream->cur_frame;
397 probe = stream->ctrl;
398 probe.dwFrameInterval = uvc_try_frame_interval(frame, interval);
399 maxd = abs((s32)probe.dwFrameInterval - interval);
400
401 /* Try frames with matching size to find the best frame interval. */
402 for (i = 0; i < format->nframes && maxd != 0; i++) {
403 u32 d, ival;
404
405 if (&format->frame[i] == stream->cur_frame)
406 continue;
407
408 if (format->frame[i].wWidth != stream->cur_frame->wWidth ||
409 format->frame[i].wHeight != stream->cur_frame->wHeight)
410 continue;
411
412 ival = uvc_try_frame_interval(&format->frame[i], interval);
413 d = abs((s32)ival - interval);
414 if (d >= maxd)
415 continue;
416
417 frame = &format->frame[i];
418 probe.bFrameIndex = frame->bFrameIndex;
419 probe.dwFrameInterval = ival;
420 maxd = d;
421 }
422
423 /* Probe the device with the new settings. */
424 ret = uvc_probe_video(stream, &probe);
425 if (ret < 0) {
426 mutex_unlock(&stream->mutex);
427 return ret;
428 }
429
430 stream->ctrl = probe;
431 stream->cur_frame = frame;
432 mutex_unlock(&stream->mutex);
433
434 /* Return the actual frame period. */
435 timeperframe.numerator = probe.dwFrameInterval;
436 timeperframe.denominator = 10000000;
437 uvc_simplify_fraction(&timeperframe.numerator,
438 &timeperframe.denominator, 8, 333);
439
440 if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
441 parm->parm.capture.timeperframe = timeperframe;
442 else
443 parm->parm.output.timeperframe = timeperframe;
444
445 return 0;
446 }
447
448 /* ------------------------------------------------------------------------
449 * Privilege management
450 */
451
452 /*
453 * Privilege management is the multiple-open implementation basis. The current
454 * implementation is completely transparent for the end-user and doesn't
455 * require explicit use of the VIDIOC_G_PRIORITY and VIDIOC_S_PRIORITY ioctls.
456 * Those ioctls enable finer control on the device (by making possible for a
457 * user to request exclusive access to a device), but are not mature yet.
458 * Switching to the V4L2 priority mechanism might be considered in the future
459 * if this situation changes.
460 *
461 * Each open instance of a UVC device can either be in a privileged or
462 * unprivileged state. Only a single instance can be in a privileged state at
463 * a given time. Trying to perform an operation that requires privileges will
464 * automatically acquire the required privileges if possible, or return -EBUSY
465 * otherwise. Privileges are dismissed when closing the instance or when
466 * freeing the video buffers using VIDIOC_REQBUFS.
467 *
468 * Operations that require privileges are:
469 *
470 * - VIDIOC_S_INPUT
471 * - VIDIOC_S_PARM
472 * - VIDIOC_S_FMT
473 * - VIDIOC_REQBUFS
474 */
uvc_acquire_privileges(struct uvc_fh * handle)475 static int uvc_acquire_privileges(struct uvc_fh *handle)
476 {
477 /* Always succeed if the handle is already privileged. */
478 if (handle->state == UVC_HANDLE_ACTIVE)
479 return 0;
480
481 /* Check if the device already has a privileged handle. */
482 if (atomic_inc_return(&handle->stream->active) != 1) {
483 atomic_dec(&handle->stream->active);
484 return -EBUSY;
485 }
486
487 handle->state = UVC_HANDLE_ACTIVE;
488 return 0;
489 }
490
uvc_dismiss_privileges(struct uvc_fh * handle)491 static void uvc_dismiss_privileges(struct uvc_fh *handle)
492 {
493 if (handle->state == UVC_HANDLE_ACTIVE)
494 atomic_dec(&handle->stream->active);
495
496 handle->state = UVC_HANDLE_PASSIVE;
497 }
498
uvc_has_privileges(struct uvc_fh * handle)499 static int uvc_has_privileges(struct uvc_fh *handle)
500 {
501 return handle->state == UVC_HANDLE_ACTIVE;
502 }
503
504 /* ------------------------------------------------------------------------
505 * V4L2 file operations
506 */
507
uvc_v4l2_open(struct file * file)508 static int uvc_v4l2_open(struct file *file)
509 {
510 struct uvc_streaming *stream;
511 struct uvc_fh *handle;
512 int ret = 0;
513
514 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n");
515 stream = video_drvdata(file);
516
517 ret = usb_autopm_get_interface(stream->dev->intf);
518 if (ret < 0)
519 return ret;
520
521 /* Create the device handle. */
522 handle = kzalloc(sizeof(*handle), GFP_KERNEL);
523 if (handle == NULL) {
524 usb_autopm_put_interface(stream->dev->intf);
525 return -ENOMEM;
526 }
527
528 mutex_lock(&stream->dev->lock);
529 if (stream->dev->users == 0) {
530 ret = uvc_status_start(stream->dev, GFP_KERNEL);
531 if (ret < 0) {
532 mutex_unlock(&stream->dev->lock);
533 usb_autopm_put_interface(stream->dev->intf);
534 kfree(handle);
535 return ret;
536 }
537 }
538
539 stream->dev->users++;
540 mutex_unlock(&stream->dev->lock);
541
542 v4l2_fh_init(&handle->vfh, &stream->vdev);
543 v4l2_fh_add(&handle->vfh);
544 handle->chain = stream->chain;
545 handle->stream = stream;
546 handle->state = UVC_HANDLE_PASSIVE;
547 file->private_data = handle;
548
549 return 0;
550 }
551
uvc_v4l2_release(struct file * file)552 static int uvc_v4l2_release(struct file *file)
553 {
554 struct uvc_fh *handle = file->private_data;
555 struct uvc_streaming *stream = handle->stream;
556
557 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_release\n");
558
559 /* Only free resources if this is a privileged handle. */
560 if (uvc_has_privileges(handle))
561 uvc_queue_release(&stream->queue);
562
563 /* Release the file handle. */
564 uvc_dismiss_privileges(handle);
565 v4l2_fh_del(&handle->vfh);
566 v4l2_fh_exit(&handle->vfh);
567 kfree(handle);
568 file->private_data = NULL;
569
570 mutex_lock(&stream->dev->lock);
571 if (--stream->dev->users == 0)
572 uvc_status_stop(stream->dev);
573 mutex_unlock(&stream->dev->lock);
574
575 usb_autopm_put_interface(stream->dev->intf);
576 return 0;
577 }
578
uvc_ioctl_querycap(struct file * file,void * fh,struct v4l2_capability * cap)579 static int uvc_ioctl_querycap(struct file *file, void *fh,
580 struct v4l2_capability *cap)
581 {
582 struct video_device *vdev = video_devdata(file);
583 struct uvc_fh *handle = file->private_data;
584 struct uvc_video_chain *chain = handle->chain;
585 struct uvc_streaming *stream = handle->stream;
586
587 strscpy(cap->driver, "uvcvideo", sizeof(cap->driver));
588 strscpy(cap->card, vdev->name, sizeof(cap->card));
589 usb_make_path(stream->dev->udev, cap->bus_info, sizeof(cap->bus_info));
590 cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING
591 | chain->caps;
592
593 return 0;
594 }
595
uvc_ioctl_enum_fmt(struct uvc_streaming * stream,struct v4l2_fmtdesc * fmt)596 static int uvc_ioctl_enum_fmt(struct uvc_streaming *stream,
597 struct v4l2_fmtdesc *fmt)
598 {
599 struct uvc_format *format;
600 enum v4l2_buf_type type = fmt->type;
601 u32 index = fmt->index;
602
603 if (fmt->type != stream->type || fmt->index >= stream->nformats)
604 return -EINVAL;
605
606 memset(fmt, 0, sizeof(*fmt));
607 fmt->index = index;
608 fmt->type = type;
609
610 format = &stream->format[fmt->index];
611 fmt->flags = 0;
612 if (format->flags & UVC_FMT_FLAG_COMPRESSED)
613 fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
614 strscpy(fmt->description, format->name, sizeof(fmt->description));
615 fmt->description[sizeof(fmt->description) - 1] = 0;
616 fmt->pixelformat = format->fcc;
617 return 0;
618 }
619
uvc_ioctl_enum_fmt_vid_cap(struct file * file,void * fh,struct v4l2_fmtdesc * fmt)620 static int uvc_ioctl_enum_fmt_vid_cap(struct file *file, void *fh,
621 struct v4l2_fmtdesc *fmt)
622 {
623 struct uvc_fh *handle = fh;
624 struct uvc_streaming *stream = handle->stream;
625
626 return uvc_ioctl_enum_fmt(stream, fmt);
627 }
628
uvc_ioctl_enum_fmt_vid_out(struct file * file,void * fh,struct v4l2_fmtdesc * fmt)629 static int uvc_ioctl_enum_fmt_vid_out(struct file *file, void *fh,
630 struct v4l2_fmtdesc *fmt)
631 {
632 struct uvc_fh *handle = fh;
633 struct uvc_streaming *stream = handle->stream;
634
635 return uvc_ioctl_enum_fmt(stream, fmt);
636 }
637
uvc_ioctl_g_fmt_vid_cap(struct file * file,void * fh,struct v4l2_format * fmt)638 static int uvc_ioctl_g_fmt_vid_cap(struct file *file, void *fh,
639 struct v4l2_format *fmt)
640 {
641 struct uvc_fh *handle = fh;
642 struct uvc_streaming *stream = handle->stream;
643
644 return uvc_v4l2_get_format(stream, fmt);
645 }
646
uvc_ioctl_g_fmt_vid_out(struct file * file,void * fh,struct v4l2_format * fmt)647 static int uvc_ioctl_g_fmt_vid_out(struct file *file, void *fh,
648 struct v4l2_format *fmt)
649 {
650 struct uvc_fh *handle = fh;
651 struct uvc_streaming *stream = handle->stream;
652
653 return uvc_v4l2_get_format(stream, fmt);
654 }
655
uvc_ioctl_s_fmt_vid_cap(struct file * file,void * fh,struct v4l2_format * fmt)656 static int uvc_ioctl_s_fmt_vid_cap(struct file *file, void *fh,
657 struct v4l2_format *fmt)
658 {
659 struct uvc_fh *handle = fh;
660 struct uvc_streaming *stream = handle->stream;
661 int ret;
662
663 ret = uvc_acquire_privileges(handle);
664 if (ret < 0)
665 return ret;
666
667 return uvc_v4l2_set_format(stream, fmt);
668 }
669
uvc_ioctl_s_fmt_vid_out(struct file * file,void * fh,struct v4l2_format * fmt)670 static int uvc_ioctl_s_fmt_vid_out(struct file *file, void *fh,
671 struct v4l2_format *fmt)
672 {
673 struct uvc_fh *handle = fh;
674 struct uvc_streaming *stream = handle->stream;
675 int ret;
676
677 ret = uvc_acquire_privileges(handle);
678 if (ret < 0)
679 return ret;
680
681 return uvc_v4l2_set_format(stream, fmt);
682 }
683
uvc_ioctl_try_fmt_vid_cap(struct file * file,void * fh,struct v4l2_format * fmt)684 static int uvc_ioctl_try_fmt_vid_cap(struct file *file, void *fh,
685 struct v4l2_format *fmt)
686 {
687 struct uvc_fh *handle = fh;
688 struct uvc_streaming *stream = handle->stream;
689 struct uvc_streaming_control probe;
690
691 return uvc_v4l2_try_format(stream, fmt, &probe, NULL, NULL);
692 }
693
uvc_ioctl_try_fmt_vid_out(struct file * file,void * fh,struct v4l2_format * fmt)694 static int uvc_ioctl_try_fmt_vid_out(struct file *file, void *fh,
695 struct v4l2_format *fmt)
696 {
697 struct uvc_fh *handle = fh;
698 struct uvc_streaming *stream = handle->stream;
699 struct uvc_streaming_control probe;
700
701 return uvc_v4l2_try_format(stream, fmt, &probe, NULL, NULL);
702 }
703
uvc_ioctl_reqbufs(struct file * file,void * fh,struct v4l2_requestbuffers * rb)704 static int uvc_ioctl_reqbufs(struct file *file, void *fh,
705 struct v4l2_requestbuffers *rb)
706 {
707 struct uvc_fh *handle = fh;
708 struct uvc_streaming *stream = handle->stream;
709 int ret;
710
711 ret = uvc_acquire_privileges(handle);
712 if (ret < 0)
713 return ret;
714
715 mutex_lock(&stream->mutex);
716 ret = uvc_request_buffers(&stream->queue, rb);
717 mutex_unlock(&stream->mutex);
718 if (ret < 0)
719 return ret;
720
721 if (ret == 0)
722 uvc_dismiss_privileges(handle);
723
724 return 0;
725 }
726
uvc_ioctl_querybuf(struct file * file,void * fh,struct v4l2_buffer * buf)727 static int uvc_ioctl_querybuf(struct file *file, void *fh,
728 struct v4l2_buffer *buf)
729 {
730 struct uvc_fh *handle = fh;
731 struct uvc_streaming *stream = handle->stream;
732
733 if (!uvc_has_privileges(handle))
734 return -EBUSY;
735
736 return uvc_query_buffer(&stream->queue, buf);
737 }
738
uvc_ioctl_qbuf(struct file * file,void * fh,struct v4l2_buffer * buf)739 static int uvc_ioctl_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
740 {
741 struct uvc_fh *handle = fh;
742 struct uvc_streaming *stream = handle->stream;
743
744 if (!uvc_has_privileges(handle))
745 return -EBUSY;
746
747 return uvc_queue_buffer(&stream->queue,
748 stream->vdev.v4l2_dev->mdev, buf);
749 }
750
uvc_ioctl_expbuf(struct file * file,void * fh,struct v4l2_exportbuffer * exp)751 static int uvc_ioctl_expbuf(struct file *file, void *fh,
752 struct v4l2_exportbuffer *exp)
753 {
754 struct uvc_fh *handle = fh;
755 struct uvc_streaming *stream = handle->stream;
756
757 if (!uvc_has_privileges(handle))
758 return -EBUSY;
759
760 return uvc_export_buffer(&stream->queue, exp);
761 }
762
uvc_ioctl_dqbuf(struct file * file,void * fh,struct v4l2_buffer * buf)763 static int uvc_ioctl_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
764 {
765 struct uvc_fh *handle = fh;
766 struct uvc_streaming *stream = handle->stream;
767
768 if (!uvc_has_privileges(handle))
769 return -EBUSY;
770
771 return uvc_dequeue_buffer(&stream->queue, buf,
772 file->f_flags & O_NONBLOCK);
773 }
774
uvc_ioctl_create_bufs(struct file * file,void * fh,struct v4l2_create_buffers * cb)775 static int uvc_ioctl_create_bufs(struct file *file, void *fh,
776 struct v4l2_create_buffers *cb)
777 {
778 struct uvc_fh *handle = fh;
779 struct uvc_streaming *stream = handle->stream;
780 int ret;
781
782 ret = uvc_acquire_privileges(handle);
783 if (ret < 0)
784 return ret;
785
786 return uvc_create_buffers(&stream->queue, cb);
787 }
788
uvc_ioctl_streamon(struct file * file,void * fh,enum v4l2_buf_type type)789 static int uvc_ioctl_streamon(struct file *file, void *fh,
790 enum v4l2_buf_type type)
791 {
792 struct uvc_fh *handle = fh;
793 struct uvc_streaming *stream = handle->stream;
794 int ret;
795
796 if (!uvc_has_privileges(handle))
797 return -EBUSY;
798
799 mutex_lock(&stream->mutex);
800 ret = uvc_queue_streamon(&stream->queue, type);
801 mutex_unlock(&stream->mutex);
802
803 return ret;
804 }
805
uvc_ioctl_streamoff(struct file * file,void * fh,enum v4l2_buf_type type)806 static int uvc_ioctl_streamoff(struct file *file, void *fh,
807 enum v4l2_buf_type type)
808 {
809 struct uvc_fh *handle = fh;
810 struct uvc_streaming *stream = handle->stream;
811
812 if (!uvc_has_privileges(handle))
813 return -EBUSY;
814
815 mutex_lock(&stream->mutex);
816 uvc_queue_streamoff(&stream->queue, type);
817 mutex_unlock(&stream->mutex);
818
819 return 0;
820 }
821
uvc_ioctl_enum_input(struct file * file,void * fh,struct v4l2_input * input)822 static int uvc_ioctl_enum_input(struct file *file, void *fh,
823 struct v4l2_input *input)
824 {
825 struct uvc_fh *handle = fh;
826 struct uvc_video_chain *chain = handle->chain;
827 const struct uvc_entity *selector = chain->selector;
828 struct uvc_entity *iterm = NULL;
829 u32 index = input->index;
830 int pin = 0;
831
832 if (selector == NULL ||
833 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
834 if (index != 0)
835 return -EINVAL;
836 list_for_each_entry(iterm, &chain->entities, chain) {
837 if (UVC_ENTITY_IS_ITERM(iterm))
838 break;
839 }
840 pin = iterm->id;
841 } else if (index < selector->bNrInPins) {
842 pin = selector->baSourceID[index];
843 list_for_each_entry(iterm, &chain->entities, chain) {
844 if (!UVC_ENTITY_IS_ITERM(iterm))
845 continue;
846 if (iterm->id == pin)
847 break;
848 }
849 }
850
851 if (iterm == NULL || iterm->id != pin)
852 return -EINVAL;
853
854 memset(input, 0, sizeof(*input));
855 input->index = index;
856 strscpy(input->name, iterm->name, sizeof(input->name));
857 if (UVC_ENTITY_TYPE(iterm) == UVC_ITT_CAMERA)
858 input->type = V4L2_INPUT_TYPE_CAMERA;
859
860 return 0;
861 }
862
uvc_ioctl_g_input(struct file * file,void * fh,unsigned int * input)863 static int uvc_ioctl_g_input(struct file *file, void *fh, unsigned int *input)
864 {
865 struct uvc_fh *handle = fh;
866 struct uvc_video_chain *chain = handle->chain;
867 int ret;
868 u8 i;
869
870 if (chain->selector == NULL ||
871 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
872 *input = 0;
873 return 0;
874 }
875
876 ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, chain->selector->id,
877 chain->dev->intfnum, UVC_SU_INPUT_SELECT_CONTROL,
878 &i, 1);
879 if (ret < 0)
880 return ret;
881
882 *input = i - 1;
883 return 0;
884 }
885
uvc_ioctl_s_input(struct file * file,void * fh,unsigned int input)886 static int uvc_ioctl_s_input(struct file *file, void *fh, unsigned int input)
887 {
888 struct uvc_fh *handle = fh;
889 struct uvc_video_chain *chain = handle->chain;
890 int ret;
891 u32 i;
892
893 ret = uvc_acquire_privileges(handle);
894 if (ret < 0)
895 return ret;
896
897 if (chain->selector == NULL ||
898 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
899 if (input)
900 return -EINVAL;
901 return 0;
902 }
903
904 if (input >= chain->selector->bNrInPins)
905 return -EINVAL;
906
907 i = input + 1;
908 return uvc_query_ctrl(chain->dev, UVC_SET_CUR, chain->selector->id,
909 chain->dev->intfnum, UVC_SU_INPUT_SELECT_CONTROL,
910 &i, 1);
911 }
912
uvc_ioctl_queryctrl(struct file * file,void * fh,struct v4l2_queryctrl * qc)913 static int uvc_ioctl_queryctrl(struct file *file, void *fh,
914 struct v4l2_queryctrl *qc)
915 {
916 struct uvc_fh *handle = fh;
917 struct uvc_video_chain *chain = handle->chain;
918
919 return uvc_query_v4l2_ctrl(chain, qc);
920 }
921
uvc_ioctl_query_ext_ctrl(struct file * file,void * fh,struct v4l2_query_ext_ctrl * qec)922 static int uvc_ioctl_query_ext_ctrl(struct file *file, void *fh,
923 struct v4l2_query_ext_ctrl *qec)
924 {
925 struct uvc_fh *handle = fh;
926 struct uvc_video_chain *chain = handle->chain;
927 struct v4l2_queryctrl qc = { qec->id };
928 int ret;
929
930 ret = uvc_query_v4l2_ctrl(chain, &qc);
931 if (ret)
932 return ret;
933
934 qec->id = qc.id;
935 qec->type = qc.type;
936 strscpy(qec->name, qc.name, sizeof(qec->name));
937 qec->minimum = qc.minimum;
938 qec->maximum = qc.maximum;
939 qec->step = qc.step;
940 qec->default_value = qc.default_value;
941 qec->flags = qc.flags;
942 qec->elem_size = 4;
943 qec->elems = 1;
944 qec->nr_of_dims = 0;
945 memset(qec->dims, 0, sizeof(qec->dims));
946 memset(qec->reserved, 0, sizeof(qec->reserved));
947
948 return 0;
949 }
950
uvc_ioctl_g_ctrl(struct file * file,void * fh,struct v4l2_control * ctrl)951 static int uvc_ioctl_g_ctrl(struct file *file, void *fh,
952 struct v4l2_control *ctrl)
953 {
954 struct uvc_fh *handle = fh;
955 struct uvc_video_chain *chain = handle->chain;
956 struct v4l2_ext_control xctrl;
957 int ret;
958
959 memset(&xctrl, 0, sizeof(xctrl));
960 xctrl.id = ctrl->id;
961
962 ret = uvc_ctrl_begin(chain);
963 if (ret < 0)
964 return ret;
965
966 ret = uvc_ctrl_get(chain, &xctrl);
967 uvc_ctrl_rollback(handle);
968 if (ret < 0)
969 return ret;
970
971 ctrl->value = xctrl.value;
972 return 0;
973 }
974
uvc_ioctl_s_ctrl(struct file * file,void * fh,struct v4l2_control * ctrl)975 static int uvc_ioctl_s_ctrl(struct file *file, void *fh,
976 struct v4l2_control *ctrl)
977 {
978 struct uvc_fh *handle = fh;
979 struct uvc_video_chain *chain = handle->chain;
980 struct v4l2_ext_control xctrl;
981 int ret;
982
983 memset(&xctrl, 0, sizeof(xctrl));
984 xctrl.id = ctrl->id;
985 xctrl.value = ctrl->value;
986
987 ret = uvc_ctrl_begin(chain);
988 if (ret < 0)
989 return ret;
990
991 ret = uvc_ctrl_set(handle, &xctrl);
992 if (ret < 0) {
993 uvc_ctrl_rollback(handle);
994 return ret;
995 }
996
997 ret = uvc_ctrl_commit(handle, &xctrl, 1);
998 if (ret < 0)
999 return ret;
1000
1001 ctrl->value = xctrl.value;
1002 return 0;
1003 }
1004
uvc_ioctl_g_ext_ctrls(struct file * file,void * fh,struct v4l2_ext_controls * ctrls)1005 static int uvc_ioctl_g_ext_ctrls(struct file *file, void *fh,
1006 struct v4l2_ext_controls *ctrls)
1007 {
1008 struct uvc_fh *handle = fh;
1009 struct uvc_video_chain *chain = handle->chain;
1010 struct v4l2_ext_control *ctrl = ctrls->controls;
1011 unsigned int i;
1012 int ret;
1013
1014 if (ctrls->which == V4L2_CTRL_WHICH_DEF_VAL) {
1015 for (i = 0; i < ctrls->count; ++ctrl, ++i) {
1016 struct v4l2_queryctrl qc = { .id = ctrl->id };
1017
1018 ret = uvc_query_v4l2_ctrl(chain, &qc);
1019 if (ret < 0) {
1020 ctrls->error_idx = i;
1021 return ret;
1022 }
1023
1024 ctrl->value = qc.default_value;
1025 }
1026
1027 return 0;
1028 }
1029
1030 ret = uvc_ctrl_begin(chain);
1031 if (ret < 0)
1032 return ret;
1033
1034 for (i = 0; i < ctrls->count; ++ctrl, ++i) {
1035 ret = uvc_ctrl_get(chain, ctrl);
1036 if (ret < 0) {
1037 uvc_ctrl_rollback(handle);
1038 ctrls->error_idx = i;
1039 return ret;
1040 }
1041 }
1042
1043 ctrls->error_idx = 0;
1044
1045 return uvc_ctrl_rollback(handle);
1046 }
1047
uvc_ioctl_s_try_ext_ctrls(struct uvc_fh * handle,struct v4l2_ext_controls * ctrls,bool commit)1048 static int uvc_ioctl_s_try_ext_ctrls(struct uvc_fh *handle,
1049 struct v4l2_ext_controls *ctrls,
1050 bool commit)
1051 {
1052 struct v4l2_ext_control *ctrl = ctrls->controls;
1053 struct uvc_video_chain *chain = handle->chain;
1054 unsigned int i;
1055 int ret;
1056
1057 /* Default value cannot be changed */
1058 if (ctrls->which == V4L2_CTRL_WHICH_DEF_VAL)
1059 return -EINVAL;
1060
1061 ret = uvc_ctrl_begin(chain);
1062 if (ret < 0)
1063 return ret;
1064
1065 for (i = 0; i < ctrls->count; ++ctrl, ++i) {
1066 ret = uvc_ctrl_set(handle, ctrl);
1067 if (ret < 0) {
1068 uvc_ctrl_rollback(handle);
1069 ctrls->error_idx = commit ? ctrls->count : i;
1070 return ret;
1071 }
1072 }
1073
1074 ctrls->error_idx = 0;
1075
1076 if (commit)
1077 return uvc_ctrl_commit(handle, ctrls->controls, ctrls->count);
1078 else
1079 return uvc_ctrl_rollback(handle);
1080 }
1081
uvc_ioctl_s_ext_ctrls(struct file * file,void * fh,struct v4l2_ext_controls * ctrls)1082 static int uvc_ioctl_s_ext_ctrls(struct file *file, void *fh,
1083 struct v4l2_ext_controls *ctrls)
1084 {
1085 struct uvc_fh *handle = fh;
1086
1087 return uvc_ioctl_s_try_ext_ctrls(handle, ctrls, true);
1088 }
1089
uvc_ioctl_try_ext_ctrls(struct file * file,void * fh,struct v4l2_ext_controls * ctrls)1090 static int uvc_ioctl_try_ext_ctrls(struct file *file, void *fh,
1091 struct v4l2_ext_controls *ctrls)
1092 {
1093 struct uvc_fh *handle = fh;
1094
1095 return uvc_ioctl_s_try_ext_ctrls(handle, ctrls, false);
1096 }
1097
uvc_ioctl_querymenu(struct file * file,void * fh,struct v4l2_querymenu * qm)1098 static int uvc_ioctl_querymenu(struct file *file, void *fh,
1099 struct v4l2_querymenu *qm)
1100 {
1101 struct uvc_fh *handle = fh;
1102 struct uvc_video_chain *chain = handle->chain;
1103
1104 return uvc_query_v4l2_menu(chain, qm);
1105 }
1106
uvc_ioctl_g_selection(struct file * file,void * fh,struct v4l2_selection * sel)1107 static int uvc_ioctl_g_selection(struct file *file, void *fh,
1108 struct v4l2_selection *sel)
1109 {
1110 struct uvc_fh *handle = fh;
1111 struct uvc_streaming *stream = handle->stream;
1112
1113 if (sel->type != stream->type)
1114 return -EINVAL;
1115
1116 switch (sel->target) {
1117 case V4L2_SEL_TGT_CROP_DEFAULT:
1118 case V4L2_SEL_TGT_CROP_BOUNDS:
1119 if (stream->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1120 return -EINVAL;
1121 break;
1122 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1123 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1124 if (stream->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1125 return -EINVAL;
1126 break;
1127 default:
1128 return -EINVAL;
1129 }
1130
1131 sel->r.left = 0;
1132 sel->r.top = 0;
1133 mutex_lock(&stream->mutex);
1134 sel->r.width = stream->cur_frame->wWidth;
1135 sel->r.height = stream->cur_frame->wHeight;
1136 mutex_unlock(&stream->mutex);
1137
1138 return 0;
1139 }
1140
uvc_ioctl_g_parm(struct file * file,void * fh,struct v4l2_streamparm * parm)1141 static int uvc_ioctl_g_parm(struct file *file, void *fh,
1142 struct v4l2_streamparm *parm)
1143 {
1144 struct uvc_fh *handle = fh;
1145 struct uvc_streaming *stream = handle->stream;
1146
1147 return uvc_v4l2_get_streamparm(stream, parm);
1148 }
1149
uvc_ioctl_s_parm(struct file * file,void * fh,struct v4l2_streamparm * parm)1150 static int uvc_ioctl_s_parm(struct file *file, void *fh,
1151 struct v4l2_streamparm *parm)
1152 {
1153 struct uvc_fh *handle = fh;
1154 struct uvc_streaming *stream = handle->stream;
1155 int ret;
1156
1157 ret = uvc_acquire_privileges(handle);
1158 if (ret < 0)
1159 return ret;
1160
1161 return uvc_v4l2_set_streamparm(stream, parm);
1162 }
1163
uvc_ioctl_enum_framesizes(struct file * file,void * fh,struct v4l2_frmsizeenum * fsize)1164 static int uvc_ioctl_enum_framesizes(struct file *file, void *fh,
1165 struct v4l2_frmsizeenum *fsize)
1166 {
1167 struct uvc_fh *handle = fh;
1168 struct uvc_streaming *stream = handle->stream;
1169 struct uvc_format *format = NULL;
1170 struct uvc_frame *frame = NULL;
1171 unsigned int index;
1172 unsigned int i;
1173
1174 /* Look for the given pixel format */
1175 for (i = 0; i < stream->nformats; i++) {
1176 if (stream->format[i].fcc == fsize->pixel_format) {
1177 format = &stream->format[i];
1178 break;
1179 }
1180 }
1181 if (format == NULL)
1182 return -EINVAL;
1183
1184 /* Skip duplicate frame sizes */
1185 for (i = 0, index = 0; i < format->nframes; i++) {
1186 if (frame && frame->wWidth == format->frame[i].wWidth &&
1187 frame->wHeight == format->frame[i].wHeight)
1188 continue;
1189 frame = &format->frame[i];
1190 if (index == fsize->index)
1191 break;
1192 index++;
1193 }
1194
1195 if (i == format->nframes)
1196 return -EINVAL;
1197
1198 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1199 fsize->discrete.width = frame->wWidth;
1200 fsize->discrete.height = frame->wHeight;
1201 return 0;
1202 }
1203
uvc_ioctl_enum_frameintervals(struct file * file,void * fh,struct v4l2_frmivalenum * fival)1204 static int uvc_ioctl_enum_frameintervals(struct file *file, void *fh,
1205 struct v4l2_frmivalenum *fival)
1206 {
1207 struct uvc_fh *handle = fh;
1208 struct uvc_streaming *stream = handle->stream;
1209 struct uvc_format *format = NULL;
1210 struct uvc_frame *frame = NULL;
1211 unsigned int nintervals;
1212 unsigned int index;
1213 unsigned int i;
1214
1215 /* Look for the given pixel format and frame size */
1216 for (i = 0; i < stream->nformats; i++) {
1217 if (stream->format[i].fcc == fival->pixel_format) {
1218 format = &stream->format[i];
1219 break;
1220 }
1221 }
1222 if (format == NULL)
1223 return -EINVAL;
1224
1225 index = fival->index;
1226 for (i = 0; i < format->nframes; i++) {
1227 if (format->frame[i].wWidth == fival->width &&
1228 format->frame[i].wHeight == fival->height) {
1229 frame = &format->frame[i];
1230 nintervals = frame->bFrameIntervalType ?: 1;
1231 if (index < nintervals)
1232 break;
1233 index -= nintervals;
1234 }
1235 }
1236 if (i == format->nframes)
1237 return -EINVAL;
1238
1239 if (frame->bFrameIntervalType) {
1240 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1241 fival->discrete.numerator =
1242 frame->dwFrameInterval[index];
1243 fival->discrete.denominator = 10000000;
1244 uvc_simplify_fraction(&fival->discrete.numerator,
1245 &fival->discrete.denominator, 8, 333);
1246 } else {
1247 fival->type = V4L2_FRMIVAL_TYPE_STEPWISE;
1248 fival->stepwise.min.numerator = frame->dwFrameInterval[0];
1249 fival->stepwise.min.denominator = 10000000;
1250 fival->stepwise.max.numerator = frame->dwFrameInterval[1];
1251 fival->stepwise.max.denominator = 10000000;
1252 fival->stepwise.step.numerator = frame->dwFrameInterval[2];
1253 fival->stepwise.step.denominator = 10000000;
1254 uvc_simplify_fraction(&fival->stepwise.min.numerator,
1255 &fival->stepwise.min.denominator, 8, 333);
1256 uvc_simplify_fraction(&fival->stepwise.max.numerator,
1257 &fival->stepwise.max.denominator, 8, 333);
1258 uvc_simplify_fraction(&fival->stepwise.step.numerator,
1259 &fival->stepwise.step.denominator, 8, 333);
1260 }
1261
1262 return 0;
1263 }
1264
uvc_ioctl_subscribe_event(struct v4l2_fh * fh,const struct v4l2_event_subscription * sub)1265 static int uvc_ioctl_subscribe_event(struct v4l2_fh *fh,
1266 const struct v4l2_event_subscription *sub)
1267 {
1268 switch (sub->type) {
1269 case V4L2_EVENT_CTRL:
1270 return v4l2_event_subscribe(fh, sub, 0, &uvc_ctrl_sub_ev_ops);
1271 default:
1272 return -EINVAL;
1273 }
1274 }
1275
uvc_ioctl_default(struct file * file,void * fh,bool valid_prio,unsigned int cmd,void * arg)1276 static long uvc_ioctl_default(struct file *file, void *fh, bool valid_prio,
1277 unsigned int cmd, void *arg)
1278 {
1279 struct uvc_fh *handle = fh;
1280 struct uvc_video_chain *chain = handle->chain;
1281
1282 switch (cmd) {
1283 /* Dynamic controls. */
1284 case UVCIOC_CTRL_MAP:
1285 return uvc_ioctl_ctrl_map(chain, arg);
1286
1287 case UVCIOC_CTRL_QUERY:
1288 return uvc_xu_ctrl_query(chain, arg);
1289
1290 default:
1291 return -ENOTTY;
1292 }
1293 }
1294
1295 #ifdef CONFIG_COMPAT
1296 struct uvc_xu_control_mapping32 {
1297 u32 id;
1298 u8 name[32];
1299 u8 entity[16];
1300 u8 selector;
1301
1302 u8 size;
1303 u8 offset;
1304 u32 v4l2_type;
1305 u32 data_type;
1306
1307 compat_caddr_t menu_info;
1308 u32 menu_count;
1309
1310 u32 reserved[4];
1311 };
1312
uvc_v4l2_get_xu_mapping(struct uvc_xu_control_mapping * kp,const struct uvc_xu_control_mapping32 __user * up)1313 static int uvc_v4l2_get_xu_mapping(struct uvc_xu_control_mapping *kp,
1314 const struct uvc_xu_control_mapping32 __user *up)
1315 {
1316 struct uvc_xu_control_mapping32 *p = (void *)kp;
1317 compat_caddr_t info;
1318 u32 count;
1319
1320 if (copy_from_user(p, up, sizeof(*p)))
1321 return -EFAULT;
1322
1323 count = p->menu_count;
1324 info = p->menu_info;
1325
1326 memset(kp->reserved, 0, sizeof(kp->reserved));
1327 kp->menu_info = count ? compat_ptr(info) : NULL;
1328 kp->menu_count = count;
1329 return 0;
1330 }
1331
uvc_v4l2_put_xu_mapping(const struct uvc_xu_control_mapping * kp,struct uvc_xu_control_mapping32 __user * up)1332 static int uvc_v4l2_put_xu_mapping(const struct uvc_xu_control_mapping *kp,
1333 struct uvc_xu_control_mapping32 __user *up)
1334 {
1335 if (copy_to_user(up, kp, offsetof(typeof(*up), menu_info)) ||
1336 put_user(kp->menu_count, &up->menu_count))
1337 return -EFAULT;
1338
1339 if (clear_user(up->reserved, sizeof(up->reserved)))
1340 return -EFAULT;
1341
1342 return 0;
1343 }
1344
1345 struct uvc_xu_control_query32 {
1346 u8 unit;
1347 u8 selector;
1348 u8 query;
1349 u16 size;
1350 compat_caddr_t data;
1351 };
1352
uvc_v4l2_get_xu_query(struct uvc_xu_control_query * kp,const struct uvc_xu_control_query32 __user * up)1353 static int uvc_v4l2_get_xu_query(struct uvc_xu_control_query *kp,
1354 const struct uvc_xu_control_query32 __user *up)
1355 {
1356 struct uvc_xu_control_query32 v;
1357
1358 if (copy_from_user(&v, up, sizeof(v)))
1359 return -EFAULT;
1360
1361 *kp = (struct uvc_xu_control_query){
1362 .unit = v.unit,
1363 .selector = v.selector,
1364 .query = v.query,
1365 .size = v.size,
1366 .data = v.size ? compat_ptr(v.data) : NULL
1367 };
1368 return 0;
1369 }
1370
uvc_v4l2_put_xu_query(const struct uvc_xu_control_query * kp,struct uvc_xu_control_query32 __user * up)1371 static int uvc_v4l2_put_xu_query(const struct uvc_xu_control_query *kp,
1372 struct uvc_xu_control_query32 __user *up)
1373 {
1374 if (copy_to_user(up, kp, offsetof(typeof(*up), data)))
1375 return -EFAULT;
1376 return 0;
1377 }
1378
1379 #define UVCIOC_CTRL_MAP32 _IOWR('u', 0x20, struct uvc_xu_control_mapping32)
1380 #define UVCIOC_CTRL_QUERY32 _IOWR('u', 0x21, struct uvc_xu_control_query32)
1381
uvc_v4l2_compat_ioctl32(struct file * file,unsigned int cmd,unsigned long arg)1382 static long uvc_v4l2_compat_ioctl32(struct file *file,
1383 unsigned int cmd, unsigned long arg)
1384 {
1385 struct uvc_fh *handle = file->private_data;
1386 union {
1387 struct uvc_xu_control_mapping xmap;
1388 struct uvc_xu_control_query xqry;
1389 } karg;
1390 void __user *up = compat_ptr(arg);
1391 long ret;
1392
1393 switch (cmd) {
1394 case UVCIOC_CTRL_MAP32:
1395 ret = uvc_v4l2_get_xu_mapping(&karg.xmap, up);
1396 if (ret)
1397 return ret;
1398 ret = uvc_ioctl_ctrl_map(handle->chain, &karg.xmap);
1399 if (ret)
1400 return ret;
1401 ret = uvc_v4l2_put_xu_mapping(&karg.xmap, up);
1402 if (ret)
1403 return ret;
1404
1405 break;
1406
1407 case UVCIOC_CTRL_QUERY32:
1408 ret = uvc_v4l2_get_xu_query(&karg.xqry, up);
1409 if (ret)
1410 return ret;
1411 ret = uvc_xu_ctrl_query(handle->chain, &karg.xqry);
1412 if (ret)
1413 return ret;
1414 ret = uvc_v4l2_put_xu_query(&karg.xqry, up);
1415 if (ret)
1416 return ret;
1417 break;
1418
1419 default:
1420 return -ENOIOCTLCMD;
1421 }
1422
1423 return ret;
1424 }
1425 #endif
1426
uvc_v4l2_read(struct file * file,char __user * data,size_t count,loff_t * ppos)1427 static ssize_t uvc_v4l2_read(struct file *file, char __user *data,
1428 size_t count, loff_t *ppos)
1429 {
1430 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_read: not implemented.\n");
1431 return -EINVAL;
1432 }
1433
uvc_v4l2_mmap(struct file * file,struct vm_area_struct * vma)1434 static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
1435 {
1436 struct uvc_fh *handle = file->private_data;
1437 struct uvc_streaming *stream = handle->stream;
1438
1439 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_mmap\n");
1440
1441 return uvc_queue_mmap(&stream->queue, vma);
1442 }
1443
uvc_v4l2_poll(struct file * file,poll_table * wait)1444 static __poll_t uvc_v4l2_poll(struct file *file, poll_table *wait)
1445 {
1446 struct uvc_fh *handle = file->private_data;
1447 struct uvc_streaming *stream = handle->stream;
1448
1449 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_poll\n");
1450
1451 return uvc_queue_poll(&stream->queue, file, wait);
1452 }
1453
1454 #ifndef CONFIG_MMU
uvc_v4l2_get_unmapped_area(struct file * file,unsigned long addr,unsigned long len,unsigned long pgoff,unsigned long flags)1455 static unsigned long uvc_v4l2_get_unmapped_area(struct file *file,
1456 unsigned long addr, unsigned long len, unsigned long pgoff,
1457 unsigned long flags)
1458 {
1459 struct uvc_fh *handle = file->private_data;
1460 struct uvc_streaming *stream = handle->stream;
1461
1462 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_get_unmapped_area\n");
1463
1464 return uvc_queue_get_unmapped_area(&stream->queue, pgoff);
1465 }
1466 #endif
1467
1468 const struct v4l2_ioctl_ops uvc_ioctl_ops = {
1469 .vidioc_querycap = uvc_ioctl_querycap,
1470 .vidioc_enum_fmt_vid_cap = uvc_ioctl_enum_fmt_vid_cap,
1471 .vidioc_enum_fmt_vid_out = uvc_ioctl_enum_fmt_vid_out,
1472 .vidioc_g_fmt_vid_cap = uvc_ioctl_g_fmt_vid_cap,
1473 .vidioc_g_fmt_vid_out = uvc_ioctl_g_fmt_vid_out,
1474 .vidioc_s_fmt_vid_cap = uvc_ioctl_s_fmt_vid_cap,
1475 .vidioc_s_fmt_vid_out = uvc_ioctl_s_fmt_vid_out,
1476 .vidioc_try_fmt_vid_cap = uvc_ioctl_try_fmt_vid_cap,
1477 .vidioc_try_fmt_vid_out = uvc_ioctl_try_fmt_vid_out,
1478 .vidioc_reqbufs = uvc_ioctl_reqbufs,
1479 .vidioc_querybuf = uvc_ioctl_querybuf,
1480 .vidioc_qbuf = uvc_ioctl_qbuf,
1481 .vidioc_expbuf = uvc_ioctl_expbuf,
1482 .vidioc_dqbuf = uvc_ioctl_dqbuf,
1483 .vidioc_create_bufs = uvc_ioctl_create_bufs,
1484 .vidioc_streamon = uvc_ioctl_streamon,
1485 .vidioc_streamoff = uvc_ioctl_streamoff,
1486 .vidioc_enum_input = uvc_ioctl_enum_input,
1487 .vidioc_g_input = uvc_ioctl_g_input,
1488 .vidioc_s_input = uvc_ioctl_s_input,
1489 .vidioc_queryctrl = uvc_ioctl_queryctrl,
1490 .vidioc_query_ext_ctrl = uvc_ioctl_query_ext_ctrl,
1491 .vidioc_g_ctrl = uvc_ioctl_g_ctrl,
1492 .vidioc_s_ctrl = uvc_ioctl_s_ctrl,
1493 .vidioc_g_ext_ctrls = uvc_ioctl_g_ext_ctrls,
1494 .vidioc_s_ext_ctrls = uvc_ioctl_s_ext_ctrls,
1495 .vidioc_try_ext_ctrls = uvc_ioctl_try_ext_ctrls,
1496 .vidioc_querymenu = uvc_ioctl_querymenu,
1497 .vidioc_g_selection = uvc_ioctl_g_selection,
1498 .vidioc_g_parm = uvc_ioctl_g_parm,
1499 .vidioc_s_parm = uvc_ioctl_s_parm,
1500 .vidioc_enum_framesizes = uvc_ioctl_enum_framesizes,
1501 .vidioc_enum_frameintervals = uvc_ioctl_enum_frameintervals,
1502 .vidioc_subscribe_event = uvc_ioctl_subscribe_event,
1503 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1504 .vidioc_default = uvc_ioctl_default,
1505 };
1506
1507 const struct v4l2_file_operations uvc_fops = {
1508 .owner = THIS_MODULE,
1509 .open = uvc_v4l2_open,
1510 .release = uvc_v4l2_release,
1511 .unlocked_ioctl = video_ioctl2,
1512 #ifdef CONFIG_COMPAT
1513 .compat_ioctl32 = uvc_v4l2_compat_ioctl32,
1514 #endif
1515 .read = uvc_v4l2_read,
1516 .mmap = uvc_v4l2_mmap,
1517 .poll = uvc_v4l2_poll,
1518 #ifndef CONFIG_MMU
1519 .get_unmapped_area = uvc_v4l2_get_unmapped_area,
1520 #endif
1521 };
1522
1523