1
2
3
4
5
6
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
30
31static 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
59
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);
87free_map:
88 kfree(map);
89
90 return ret;
91}
92
93
94
95
96
97
98
99
100
101
102
103static 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
135static 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
150static 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
173
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
187
188
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
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
222 memset(probe, 0, sizeof(*probe));
223 probe->bmHint = 1;
224 probe->bFormatIndex = format->index;
225 probe->bFrameIndex = frame->bFrameIndex;
226 probe->dwFrameInterval = uvc_try_frame_interval(frame, interval);
227
228
229
230
231
232
233
234
235
236
237
238
239 mutex_lock(&stream->mutex);
240 if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS)
241 probe->dwMaxVideoFrameSize =
242 stream->ctrl.dwMaxVideoFrameSize;
243
244
245 ret = uvc_probe_video(stream, probe);
246 mutex_unlock(&stream->mutex);
247 if (ret < 0)
248 goto done;
249
250
251
252
253 for (i = 0; i < stream->nformats; ++i) {
254 if (probe->bFormatIndex == stream->format[i].index) {
255 format = &stream->format[i];
256 break;
257 }
258 }
259
260 if (i == stream->nformats) {
261 uvc_trace(UVC_TRACE_FORMAT, "Unknown bFormatIndex %u\n",
262 probe->bFormatIndex);
263 return -EINVAL;
264 }
265
266 for (i = 0; i < format->nframes; ++i) {
267 if (probe->bFrameIndex == format->frame[i].bFrameIndex) {
268 frame = &format->frame[i];
269 break;
270 }
271 }
272
273 if (i == format->nframes) {
274 uvc_trace(UVC_TRACE_FORMAT, "Unknown bFrameIndex %u\n",
275 probe->bFrameIndex);
276 return -EINVAL;
277 }
278
279 fmt->fmt.pix.width = frame->wWidth;
280 fmt->fmt.pix.height = frame->wHeight;
281 fmt->fmt.pix.field = V4L2_FIELD_NONE;
282 fmt->fmt.pix.bytesperline = uvc_v4l2_get_bytesperline(format, frame);
283 fmt->fmt.pix.sizeimage = probe->dwMaxVideoFrameSize;
284 fmt->fmt.pix.pixelformat = format->fcc;
285 fmt->fmt.pix.colorspace = format->colorspace;
286 fmt->fmt.pix.xfer_func = format->xfer_func;
287 fmt->fmt.pix.ycbcr_enc = format->ycbcr_enc;
288
289 if (uvc_format != NULL)
290 *uvc_format = format;
291 if (uvc_frame != NULL)
292 *uvc_frame = frame;
293
294done:
295 return ret;
296}
297
298static int uvc_v4l2_get_format(struct uvc_streaming *stream,
299 struct v4l2_format *fmt)
300{
301 struct uvc_format *format;
302 struct uvc_frame *frame;
303 int ret = 0;
304
305 if (fmt->type != stream->type)
306 return -EINVAL;
307
308 mutex_lock(&stream->mutex);
309 format = stream->cur_format;
310 frame = stream->cur_frame;
311
312 if (format == NULL || frame == NULL) {
313 ret = -EINVAL;
314 goto done;
315 }
316
317 fmt->fmt.pix.pixelformat = format->fcc;
318 fmt->fmt.pix.width = frame->wWidth;
319 fmt->fmt.pix.height = frame->wHeight;
320 fmt->fmt.pix.field = V4L2_FIELD_NONE;
321 fmt->fmt.pix.bytesperline = uvc_v4l2_get_bytesperline(format, frame);
322 fmt->fmt.pix.sizeimage = stream->ctrl.dwMaxVideoFrameSize;
323 fmt->fmt.pix.colorspace = format->colorspace;
324 fmt->fmt.pix.xfer_func = format->xfer_func;
325 fmt->fmt.pix.ycbcr_enc = format->ycbcr_enc;
326
327done:
328 mutex_unlock(&stream->mutex);
329 return ret;
330}
331
332static int uvc_v4l2_set_format(struct uvc_streaming *stream,
333 struct v4l2_format *fmt)
334{
335 struct uvc_streaming_control probe;
336 struct uvc_format *format;
337 struct uvc_frame *frame;
338 int ret;
339
340 if (fmt->type != stream->type)
341 return -EINVAL;
342
343 ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame);
344 if (ret < 0)
345 return ret;
346
347 mutex_lock(&stream->mutex);
348
349 if (uvc_queue_allocated(&stream->queue)) {
350 ret = -EBUSY;
351 goto done;
352 }
353
354 stream->ctrl = probe;
355 stream->cur_format = format;
356 stream->cur_frame = frame;
357
358done:
359 mutex_unlock(&stream->mutex);
360 return ret;
361}
362
363static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream,
364 struct v4l2_streamparm *parm)
365{
366 u32 numerator, denominator;
367
368 if (parm->type != stream->type)
369 return -EINVAL;
370
371 mutex_lock(&stream->mutex);
372 numerator = stream->ctrl.dwFrameInterval;
373 mutex_unlock(&stream->mutex);
374
375 denominator = 10000000;
376 uvc_simplify_fraction(&numerator, &denominator, 8, 333);
377
378 memset(parm, 0, sizeof(*parm));
379 parm->type = stream->type;
380
381 if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
382 parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
383 parm->parm.capture.capturemode = 0;
384 parm->parm.capture.timeperframe.numerator = numerator;
385 parm->parm.capture.timeperframe.denominator = denominator;
386 parm->parm.capture.extendedmode = 0;
387 parm->parm.capture.readbuffers = 0;
388 } else {
389 parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
390 parm->parm.output.outputmode = 0;
391 parm->parm.output.timeperframe.numerator = numerator;
392 parm->parm.output.timeperframe.denominator = denominator;
393 }
394
395 return 0;
396}
397
398static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream,
399 struct v4l2_streamparm *parm)
400{
401 struct uvc_streaming_control probe;
402 struct v4l2_fract timeperframe;
403 struct uvc_format *format;
404 struct uvc_frame *frame;
405 u32 interval, maxd;
406 unsigned int i;
407 int ret;
408
409 if (parm->type != stream->type)
410 return -EINVAL;
411
412 if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
413 timeperframe = parm->parm.capture.timeperframe;
414 else
415 timeperframe = parm->parm.output.timeperframe;
416
417 interval = uvc_fraction_to_interval(timeperframe.numerator,
418 timeperframe.denominator);
419 uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n",
420 timeperframe.numerator, timeperframe.denominator, interval);
421
422 mutex_lock(&stream->mutex);
423
424 if (uvc_queue_streaming(&stream->queue)) {
425 mutex_unlock(&stream->mutex);
426 return -EBUSY;
427 }
428
429 format = stream->cur_format;
430 frame = stream->cur_frame;
431 probe = stream->ctrl;
432 probe.dwFrameInterval = uvc_try_frame_interval(frame, interval);
433 maxd = abs((s32)probe.dwFrameInterval - interval);
434
435
436 for (i = 0; i < format->nframes && maxd != 0; i++) {
437 u32 d, ival;
438
439 if (&format->frame[i] == stream->cur_frame)
440 continue;
441
442 if (format->frame[i].wWidth != stream->cur_frame->wWidth ||
443 format->frame[i].wHeight != stream->cur_frame->wHeight)
444 continue;
445
446 ival = uvc_try_frame_interval(&format->frame[i], interval);
447 d = abs((s32)ival - interval);
448 if (d >= maxd)
449 continue;
450
451 frame = &format->frame[i];
452 probe.bFrameIndex = frame->bFrameIndex;
453 probe.dwFrameInterval = ival;
454 maxd = d;
455 }
456
457
458 ret = uvc_probe_video(stream, &probe);
459 if (ret < 0) {
460 mutex_unlock(&stream->mutex);
461 return ret;
462 }
463
464 stream->ctrl = probe;
465 stream->cur_frame = frame;
466 mutex_unlock(&stream->mutex);
467
468
469 timeperframe.numerator = probe.dwFrameInterval;
470 timeperframe.denominator = 10000000;
471 uvc_simplify_fraction(&timeperframe.numerator,
472 &timeperframe.denominator, 8, 333);
473
474 if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
475 parm->parm.capture.timeperframe = timeperframe;
476 else
477 parm->parm.output.timeperframe = timeperframe;
478
479 return 0;
480}
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509static int uvc_acquire_privileges(struct uvc_fh *handle)
510{
511
512 if (handle->state == UVC_HANDLE_ACTIVE)
513 return 0;
514
515
516 if (atomic_inc_return(&handle->stream->active) != 1) {
517 atomic_dec(&handle->stream->active);
518 return -EBUSY;
519 }
520
521 handle->state = UVC_HANDLE_ACTIVE;
522 return 0;
523}
524
525static void uvc_dismiss_privileges(struct uvc_fh *handle)
526{
527 if (handle->state == UVC_HANDLE_ACTIVE)
528 atomic_dec(&handle->stream->active);
529
530 handle->state = UVC_HANDLE_PASSIVE;
531}
532
533static int uvc_has_privileges(struct uvc_fh *handle)
534{
535 return handle->state == UVC_HANDLE_ACTIVE;
536}
537
538
539
540
541
542static int uvc_v4l2_open(struct file *file)
543{
544 struct uvc_streaming *stream;
545 struct uvc_fh *handle;
546 int ret = 0;
547
548 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n");
549 stream = video_drvdata(file);
550
551 ret = usb_autopm_get_interface(stream->dev->intf);
552 if (ret < 0)
553 return ret;
554
555
556 handle = kzalloc(sizeof(*handle), GFP_KERNEL);
557 if (handle == NULL) {
558 usb_autopm_put_interface(stream->dev->intf);
559 return -ENOMEM;
560 }
561
562 mutex_lock(&stream->dev->lock);
563 if (stream->dev->users == 0) {
564 ret = uvc_status_start(stream->dev, GFP_KERNEL);
565 if (ret < 0) {
566 mutex_unlock(&stream->dev->lock);
567 usb_autopm_put_interface(stream->dev->intf);
568 kfree(handle);
569 return ret;
570 }
571 }
572
573 stream->dev->users++;
574 mutex_unlock(&stream->dev->lock);
575
576 v4l2_fh_init(&handle->vfh, &stream->vdev);
577 v4l2_fh_add(&handle->vfh);
578 handle->chain = stream->chain;
579 handle->stream = stream;
580 handle->state = UVC_HANDLE_PASSIVE;
581 file->private_data = handle;
582
583 return 0;
584}
585
586static int uvc_v4l2_release(struct file *file)
587{
588 struct uvc_fh *handle = file->private_data;
589 struct uvc_streaming *stream = handle->stream;
590
591 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_release\n");
592
593
594 if (uvc_has_privileges(handle))
595 uvc_queue_release(&stream->queue);
596
597
598 uvc_dismiss_privileges(handle);
599 v4l2_fh_del(&handle->vfh);
600 v4l2_fh_exit(&handle->vfh);
601 kfree(handle);
602 file->private_data = NULL;
603
604 mutex_lock(&stream->dev->lock);
605 if (--stream->dev->users == 0)
606 uvc_status_stop(stream->dev);
607 mutex_unlock(&stream->dev->lock);
608
609 usb_autopm_put_interface(stream->dev->intf);
610 return 0;
611}
612
613static int uvc_ioctl_querycap(struct file *file, void *fh,
614 struct v4l2_capability *cap)
615{
616 struct video_device *vdev = video_devdata(file);
617 struct uvc_fh *handle = file->private_data;
618 struct uvc_video_chain *chain = handle->chain;
619 struct uvc_streaming *stream = handle->stream;
620
621 strscpy(cap->driver, "uvcvideo", sizeof(cap->driver));
622 strscpy(cap->card, vdev->name, sizeof(cap->card));
623 usb_make_path(stream->dev->udev, cap->bus_info, sizeof(cap->bus_info));
624 cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING
625 | chain->caps;
626
627 return 0;
628}
629
630static int uvc_ioctl_enum_fmt(struct uvc_streaming *stream,
631 struct v4l2_fmtdesc *fmt)
632{
633 struct uvc_format *format;
634 enum v4l2_buf_type type = fmt->type;
635 u32 index = fmt->index;
636
637 if (fmt->type != stream->type || fmt->index >= stream->nformats)
638 return -EINVAL;
639
640 memset(fmt, 0, sizeof(*fmt));
641 fmt->index = index;
642 fmt->type = type;
643
644 format = &stream->format[fmt->index];
645 fmt->flags = 0;
646 if (format->flags & UVC_FMT_FLAG_COMPRESSED)
647 fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
648 strscpy(fmt->description, format->name, sizeof(fmt->description));
649 fmt->description[sizeof(fmt->description) - 1] = 0;
650 fmt->pixelformat = format->fcc;
651 return 0;
652}
653
654static int uvc_ioctl_enum_fmt_vid_cap(struct file *file, void *fh,
655 struct v4l2_fmtdesc *fmt)
656{
657 struct uvc_fh *handle = fh;
658 struct uvc_streaming *stream = handle->stream;
659
660 return uvc_ioctl_enum_fmt(stream, fmt);
661}
662
663static int uvc_ioctl_enum_fmt_vid_out(struct file *file, void *fh,
664 struct v4l2_fmtdesc *fmt)
665{
666 struct uvc_fh *handle = fh;
667 struct uvc_streaming *stream = handle->stream;
668
669 return uvc_ioctl_enum_fmt(stream, fmt);
670}
671
672static int uvc_ioctl_g_fmt_vid_cap(struct file *file, void *fh,
673 struct v4l2_format *fmt)
674{
675 struct uvc_fh *handle = fh;
676 struct uvc_streaming *stream = handle->stream;
677
678 return uvc_v4l2_get_format(stream, fmt);
679}
680
681static int uvc_ioctl_g_fmt_vid_out(struct file *file, void *fh,
682 struct v4l2_format *fmt)
683{
684 struct uvc_fh *handle = fh;
685 struct uvc_streaming *stream = handle->stream;
686
687 return uvc_v4l2_get_format(stream, fmt);
688}
689
690static int uvc_ioctl_s_fmt_vid_cap(struct file *file, void *fh,
691 struct v4l2_format *fmt)
692{
693 struct uvc_fh *handle = fh;
694 struct uvc_streaming *stream = handle->stream;
695 int ret;
696
697 ret = uvc_acquire_privileges(handle);
698 if (ret < 0)
699 return ret;
700
701 return uvc_v4l2_set_format(stream, fmt);
702}
703
704static int uvc_ioctl_s_fmt_vid_out(struct file *file, void *fh,
705 struct v4l2_format *fmt)
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 return uvc_v4l2_set_format(stream, fmt);
716}
717
718static int uvc_ioctl_try_fmt_vid_cap(struct file *file, void *fh,
719 struct v4l2_format *fmt)
720{
721 struct uvc_fh *handle = fh;
722 struct uvc_streaming *stream = handle->stream;
723 struct uvc_streaming_control probe;
724
725 return uvc_v4l2_try_format(stream, fmt, &probe, NULL, NULL);
726}
727
728static int uvc_ioctl_try_fmt_vid_out(struct file *file, void *fh,
729 struct v4l2_format *fmt)
730{
731 struct uvc_fh *handle = fh;
732 struct uvc_streaming *stream = handle->stream;
733 struct uvc_streaming_control probe;
734
735 return uvc_v4l2_try_format(stream, fmt, &probe, NULL, NULL);
736}
737
738static int uvc_ioctl_reqbufs(struct file *file, void *fh,
739 struct v4l2_requestbuffers *rb)
740{
741 struct uvc_fh *handle = fh;
742 struct uvc_streaming *stream = handle->stream;
743 int ret;
744
745 ret = uvc_acquire_privileges(handle);
746 if (ret < 0)
747 return ret;
748
749 mutex_lock(&stream->mutex);
750 ret = uvc_request_buffers(&stream->queue, rb);
751 mutex_unlock(&stream->mutex);
752 if (ret < 0)
753 return ret;
754
755 if (ret == 0)
756 uvc_dismiss_privileges(handle);
757
758 return 0;
759}
760
761static int uvc_ioctl_querybuf(struct file *file, void *fh,
762 struct v4l2_buffer *buf)
763{
764 struct uvc_fh *handle = fh;
765 struct uvc_streaming *stream = handle->stream;
766
767 if (!uvc_has_privileges(handle))
768 return -EBUSY;
769
770 return uvc_query_buffer(&stream->queue, buf);
771}
772
773static int uvc_ioctl_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
774{
775 struct uvc_fh *handle = fh;
776 struct uvc_streaming *stream = handle->stream;
777
778 if (!uvc_has_privileges(handle))
779 return -EBUSY;
780
781 return uvc_queue_buffer(&stream->queue,
782 stream->vdev.v4l2_dev->mdev, buf);
783}
784
785static int uvc_ioctl_expbuf(struct file *file, void *fh,
786 struct v4l2_exportbuffer *exp)
787{
788 struct uvc_fh *handle = fh;
789 struct uvc_streaming *stream = handle->stream;
790
791 if (!uvc_has_privileges(handle))
792 return -EBUSY;
793
794 return uvc_export_buffer(&stream->queue, exp);
795}
796
797static int uvc_ioctl_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
798{
799 struct uvc_fh *handle = fh;
800 struct uvc_streaming *stream = handle->stream;
801
802 if (!uvc_has_privileges(handle))
803 return -EBUSY;
804
805 return uvc_dequeue_buffer(&stream->queue, buf,
806 file->f_flags & O_NONBLOCK);
807}
808
809static int uvc_ioctl_create_bufs(struct file *file, void *fh,
810 struct v4l2_create_buffers *cb)
811{
812 struct uvc_fh *handle = fh;
813 struct uvc_streaming *stream = handle->stream;
814 int ret;
815
816 ret = uvc_acquire_privileges(handle);
817 if (ret < 0)
818 return ret;
819
820 return uvc_create_buffers(&stream->queue, cb);
821}
822
823static int uvc_ioctl_streamon(struct file *file, void *fh,
824 enum v4l2_buf_type type)
825{
826 struct uvc_fh *handle = fh;
827 struct uvc_streaming *stream = handle->stream;
828 int ret;
829
830 if (!uvc_has_privileges(handle))
831 return -EBUSY;
832
833 mutex_lock(&stream->mutex);
834 ret = uvc_queue_streamon(&stream->queue, type);
835 mutex_unlock(&stream->mutex);
836
837 return ret;
838}
839
840static int uvc_ioctl_streamoff(struct file *file, void *fh,
841 enum v4l2_buf_type type)
842{
843 struct uvc_fh *handle = fh;
844 struct uvc_streaming *stream = handle->stream;
845
846 if (!uvc_has_privileges(handle))
847 return -EBUSY;
848
849 mutex_lock(&stream->mutex);
850 uvc_queue_streamoff(&stream->queue, type);
851 mutex_unlock(&stream->mutex);
852
853 return 0;
854}
855
856static int uvc_ioctl_enum_input(struct file *file, void *fh,
857 struct v4l2_input *input)
858{
859 struct uvc_fh *handle = fh;
860 struct uvc_video_chain *chain = handle->chain;
861 const struct uvc_entity *selector = chain->selector;
862 struct uvc_entity *iterm = NULL;
863 u32 index = input->index;
864 int pin = 0;
865
866 if (selector == NULL ||
867 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
868 if (index != 0)
869 return -EINVAL;
870 list_for_each_entry(iterm, &chain->entities, chain) {
871 if (UVC_ENTITY_IS_ITERM(iterm))
872 break;
873 }
874 pin = iterm->id;
875 } else if (index < selector->bNrInPins) {
876 pin = selector->baSourceID[index];
877 list_for_each_entry(iterm, &chain->entities, chain) {
878 if (!UVC_ENTITY_IS_ITERM(iterm))
879 continue;
880 if (iterm->id == pin)
881 break;
882 }
883 }
884
885 if (iterm == NULL || iterm->id != pin)
886 return -EINVAL;
887
888 memset(input, 0, sizeof(*input));
889 input->index = index;
890 strscpy(input->name, iterm->name, sizeof(input->name));
891 if (UVC_ENTITY_TYPE(iterm) == UVC_ITT_CAMERA)
892 input->type = V4L2_INPUT_TYPE_CAMERA;
893
894 return 0;
895}
896
897static int uvc_ioctl_g_input(struct file *file, void *fh, unsigned int *input)
898{
899 struct uvc_fh *handle = fh;
900 struct uvc_video_chain *chain = handle->chain;
901 int ret;
902 u8 i;
903
904 if (chain->selector == NULL ||
905 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
906 *input = 0;
907 return 0;
908 }
909
910 ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, chain->selector->id,
911 chain->dev->intfnum, UVC_SU_INPUT_SELECT_CONTROL,
912 &i, 1);
913 if (ret < 0)
914 return ret;
915
916 *input = i - 1;
917 return 0;
918}
919
920static int uvc_ioctl_s_input(struct file *file, void *fh, unsigned int input)
921{
922 struct uvc_fh *handle = fh;
923 struct uvc_video_chain *chain = handle->chain;
924 int ret;
925 u32 i;
926
927 ret = uvc_acquire_privileges(handle);
928 if (ret < 0)
929 return ret;
930
931 if (chain->selector == NULL ||
932 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
933 if (input)
934 return -EINVAL;
935 return 0;
936 }
937
938 if (input >= chain->selector->bNrInPins)
939 return -EINVAL;
940
941 i = input + 1;
942 return uvc_query_ctrl(chain->dev, UVC_SET_CUR, chain->selector->id,
943 chain->dev->intfnum, UVC_SU_INPUT_SELECT_CONTROL,
944 &i, 1);
945}
946
947static int uvc_ioctl_queryctrl(struct file *file, void *fh,
948 struct v4l2_queryctrl *qc)
949{
950 struct uvc_fh *handle = fh;
951 struct uvc_video_chain *chain = handle->chain;
952
953 return uvc_query_v4l2_ctrl(chain, qc);
954}
955
956static int uvc_ioctl_query_ext_ctrl(struct file *file, void *fh,
957 struct v4l2_query_ext_ctrl *qec)
958{
959 struct uvc_fh *handle = fh;
960 struct uvc_video_chain *chain = handle->chain;
961 struct v4l2_queryctrl qc = { qec->id };
962 int ret;
963
964 ret = uvc_query_v4l2_ctrl(chain, &qc);
965 if (ret)
966 return ret;
967
968 qec->id = qc.id;
969 qec->type = qc.type;
970 strscpy(qec->name, qc.name, sizeof(qec->name));
971 qec->minimum = qc.minimum;
972 qec->maximum = qc.maximum;
973 qec->step = qc.step;
974 qec->default_value = qc.default_value;
975 qec->flags = qc.flags;
976 qec->elem_size = 4;
977 qec->elems = 1;
978 qec->nr_of_dims = 0;
979 memset(qec->dims, 0, sizeof(qec->dims));
980 memset(qec->reserved, 0, sizeof(qec->reserved));
981
982 return 0;
983}
984
985static int uvc_ioctl_g_ctrl(struct file *file, void *fh,
986 struct v4l2_control *ctrl)
987{
988 struct uvc_fh *handle = fh;
989 struct uvc_video_chain *chain = handle->chain;
990 struct v4l2_ext_control xctrl;
991 int ret;
992
993 memset(&xctrl, 0, sizeof(xctrl));
994 xctrl.id = ctrl->id;
995
996 ret = uvc_ctrl_begin(chain);
997 if (ret < 0)
998 return ret;
999
1000 ret = uvc_ctrl_get(chain, &xctrl);
1001 uvc_ctrl_rollback(handle);
1002 if (ret < 0)
1003 return ret;
1004
1005 ctrl->value = xctrl.value;
1006 return 0;
1007}
1008
1009static int uvc_ioctl_s_ctrl(struct file *file, void *fh,
1010 struct v4l2_control *ctrl)
1011{
1012 struct uvc_fh *handle = fh;
1013 struct uvc_video_chain *chain = handle->chain;
1014 struct v4l2_ext_control xctrl;
1015 int ret;
1016
1017 memset(&xctrl, 0, sizeof(xctrl));
1018 xctrl.id = ctrl->id;
1019 xctrl.value = ctrl->value;
1020
1021 ret = uvc_ctrl_begin(chain);
1022 if (ret < 0)
1023 return ret;
1024
1025 ret = uvc_ctrl_set(handle, &xctrl);
1026 if (ret < 0) {
1027 uvc_ctrl_rollback(handle);
1028 return ret;
1029 }
1030
1031 ret = uvc_ctrl_commit(handle, &xctrl, 1);
1032 if (ret < 0)
1033 return ret;
1034
1035 ctrl->value = xctrl.value;
1036 return 0;
1037}
1038
1039static int uvc_ioctl_g_ext_ctrls(struct file *file, void *fh,
1040 struct v4l2_ext_controls *ctrls)
1041{
1042 struct uvc_fh *handle = fh;
1043 struct uvc_video_chain *chain = handle->chain;
1044 struct v4l2_ext_control *ctrl = ctrls->controls;
1045 unsigned int i;
1046 int ret;
1047
1048 if (ctrls->which == V4L2_CTRL_WHICH_DEF_VAL) {
1049 for (i = 0; i < ctrls->count; ++ctrl, ++i) {
1050 struct v4l2_queryctrl qc = { .id = ctrl->id };
1051
1052 ret = uvc_query_v4l2_ctrl(chain, &qc);
1053 if (ret < 0) {
1054 ctrls->error_idx = i;
1055 return ret;
1056 }
1057
1058 ctrl->value = qc.default_value;
1059 }
1060
1061 return 0;
1062 }
1063
1064 ret = uvc_ctrl_begin(chain);
1065 if (ret < 0)
1066 return ret;
1067
1068 for (i = 0; i < ctrls->count; ++ctrl, ++i) {
1069 ret = uvc_ctrl_get(chain, ctrl);
1070 if (ret < 0) {
1071 uvc_ctrl_rollback(handle);
1072 ctrls->error_idx = i;
1073 return ret;
1074 }
1075 }
1076
1077 ctrls->error_idx = 0;
1078
1079 return uvc_ctrl_rollback(handle);
1080}
1081
1082static int uvc_ioctl_s_try_ext_ctrls(struct uvc_fh *handle,
1083 struct v4l2_ext_controls *ctrls,
1084 bool commit)
1085{
1086 struct v4l2_ext_control *ctrl = ctrls->controls;
1087 struct uvc_video_chain *chain = handle->chain;
1088 unsigned int i;
1089 int ret;
1090
1091
1092 if (ctrls->which == V4L2_CTRL_WHICH_DEF_VAL)
1093 return -EINVAL;
1094
1095 ret = uvc_ctrl_begin(chain);
1096 if (ret < 0)
1097 return ret;
1098
1099 for (i = 0; i < ctrls->count; ++ctrl, ++i) {
1100 ret = uvc_ctrl_set(handle, ctrl);
1101 if (ret < 0) {
1102 uvc_ctrl_rollback(handle);
1103 ctrls->error_idx = commit ? ctrls->count : i;
1104 return ret;
1105 }
1106 }
1107
1108 ctrls->error_idx = 0;
1109
1110 if (commit)
1111 return uvc_ctrl_commit(handle, ctrls->controls, ctrls->count);
1112 else
1113 return uvc_ctrl_rollback(handle);
1114}
1115
1116static int uvc_ioctl_s_ext_ctrls(struct file *file, void *fh,
1117 struct v4l2_ext_controls *ctrls)
1118{
1119 struct uvc_fh *handle = fh;
1120
1121 return uvc_ioctl_s_try_ext_ctrls(handle, ctrls, true);
1122}
1123
1124static int uvc_ioctl_try_ext_ctrls(struct file *file, void *fh,
1125 struct v4l2_ext_controls *ctrls)
1126{
1127 struct uvc_fh *handle = fh;
1128
1129 return uvc_ioctl_s_try_ext_ctrls(handle, ctrls, false);
1130}
1131
1132static int uvc_ioctl_querymenu(struct file *file, void *fh,
1133 struct v4l2_querymenu *qm)
1134{
1135 struct uvc_fh *handle = fh;
1136 struct uvc_video_chain *chain = handle->chain;
1137
1138 return uvc_query_v4l2_menu(chain, qm);
1139}
1140
1141static int uvc_ioctl_g_selection(struct file *file, void *fh,
1142 struct v4l2_selection *sel)
1143{
1144 struct uvc_fh *handle = fh;
1145 struct uvc_streaming *stream = handle->stream;
1146
1147 if (sel->type != stream->type)
1148 return -EINVAL;
1149
1150 switch (sel->target) {
1151 case V4L2_SEL_TGT_CROP_DEFAULT:
1152 case V4L2_SEL_TGT_CROP_BOUNDS:
1153 if (stream->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1154 return -EINVAL;
1155 break;
1156 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1157 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1158 if (stream->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1159 return -EINVAL;
1160 break;
1161 default:
1162 return -EINVAL;
1163 }
1164
1165 sel->r.left = 0;
1166 sel->r.top = 0;
1167 mutex_lock(&stream->mutex);
1168 sel->r.width = stream->cur_frame->wWidth;
1169 sel->r.height = stream->cur_frame->wHeight;
1170 mutex_unlock(&stream->mutex);
1171
1172 return 0;
1173}
1174
1175static int uvc_ioctl_g_parm(struct file *file, void *fh,
1176 struct v4l2_streamparm *parm)
1177{
1178 struct uvc_fh *handle = fh;
1179 struct uvc_streaming *stream = handle->stream;
1180
1181 return uvc_v4l2_get_streamparm(stream, parm);
1182}
1183
1184static int uvc_ioctl_s_parm(struct file *file, void *fh,
1185 struct v4l2_streamparm *parm)
1186{
1187 struct uvc_fh *handle = fh;
1188 struct uvc_streaming *stream = handle->stream;
1189 int ret;
1190
1191 ret = uvc_acquire_privileges(handle);
1192 if (ret < 0)
1193 return ret;
1194
1195 return uvc_v4l2_set_streamparm(stream, parm);
1196}
1197
1198static int uvc_ioctl_enum_framesizes(struct file *file, void *fh,
1199 struct v4l2_frmsizeenum *fsize)
1200{
1201 struct uvc_fh *handle = fh;
1202 struct uvc_streaming *stream = handle->stream;
1203 struct uvc_format *format = NULL;
1204 struct uvc_frame *frame = NULL;
1205 unsigned int index;
1206 unsigned int i;
1207
1208
1209 for (i = 0; i < stream->nformats; i++) {
1210 if (stream->format[i].fcc == fsize->pixel_format) {
1211 format = &stream->format[i];
1212 break;
1213 }
1214 }
1215 if (format == NULL)
1216 return -EINVAL;
1217
1218
1219 for (i = 0, index = 0; i < format->nframes; i++) {
1220 if (frame && frame->wWidth == format->frame[i].wWidth &&
1221 frame->wHeight == format->frame[i].wHeight)
1222 continue;
1223 frame = &format->frame[i];
1224 if (index == fsize->index)
1225 break;
1226 index++;
1227 }
1228
1229 if (i == format->nframes)
1230 return -EINVAL;
1231
1232 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1233 fsize->discrete.width = frame->wWidth;
1234 fsize->discrete.height = frame->wHeight;
1235 return 0;
1236}
1237
1238static int uvc_ioctl_enum_frameintervals(struct file *file, void *fh,
1239 struct v4l2_frmivalenum *fival)
1240{
1241 struct uvc_fh *handle = fh;
1242 struct uvc_streaming *stream = handle->stream;
1243 struct uvc_format *format = NULL;
1244 struct uvc_frame *frame = NULL;
1245 unsigned int nintervals;
1246 unsigned int index;
1247 unsigned int i;
1248
1249
1250 for (i = 0; i < stream->nformats; i++) {
1251 if (stream->format[i].fcc == fival->pixel_format) {
1252 format = &stream->format[i];
1253 break;
1254 }
1255 }
1256 if (format == NULL)
1257 return -EINVAL;
1258
1259 index = fival->index;
1260 for (i = 0; i < format->nframes; i++) {
1261 if (format->frame[i].wWidth == fival->width &&
1262 format->frame[i].wHeight == fival->height) {
1263 frame = &format->frame[i];
1264 nintervals = frame->bFrameIntervalType ?: 1;
1265 if (index < nintervals)
1266 break;
1267 index -= nintervals;
1268 }
1269 }
1270 if (i == format->nframes)
1271 return -EINVAL;
1272
1273 if (frame->bFrameIntervalType) {
1274 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1275 fival->discrete.numerator =
1276 frame->dwFrameInterval[index];
1277 fival->discrete.denominator = 10000000;
1278 uvc_simplify_fraction(&fival->discrete.numerator,
1279 &fival->discrete.denominator, 8, 333);
1280 } else {
1281 fival->type = V4L2_FRMIVAL_TYPE_STEPWISE;
1282 fival->stepwise.min.numerator = frame->dwFrameInterval[0];
1283 fival->stepwise.min.denominator = 10000000;
1284 fival->stepwise.max.numerator = frame->dwFrameInterval[1];
1285 fival->stepwise.max.denominator = 10000000;
1286 fival->stepwise.step.numerator = frame->dwFrameInterval[2];
1287 fival->stepwise.step.denominator = 10000000;
1288 uvc_simplify_fraction(&fival->stepwise.min.numerator,
1289 &fival->stepwise.min.denominator, 8, 333);
1290 uvc_simplify_fraction(&fival->stepwise.max.numerator,
1291 &fival->stepwise.max.denominator, 8, 333);
1292 uvc_simplify_fraction(&fival->stepwise.step.numerator,
1293 &fival->stepwise.step.denominator, 8, 333);
1294 }
1295
1296 return 0;
1297}
1298
1299static int uvc_ioctl_subscribe_event(struct v4l2_fh *fh,
1300 const struct v4l2_event_subscription *sub)
1301{
1302 switch (sub->type) {
1303 case V4L2_EVENT_CTRL:
1304 return v4l2_event_subscribe(fh, sub, 0, &uvc_ctrl_sub_ev_ops);
1305 default:
1306 return -EINVAL;
1307 }
1308}
1309
1310static long uvc_ioctl_default(struct file *file, void *fh, bool valid_prio,
1311 unsigned int cmd, void *arg)
1312{
1313 struct uvc_fh *handle = fh;
1314 struct uvc_video_chain *chain = handle->chain;
1315
1316 switch (cmd) {
1317
1318 case UVCIOC_CTRL_MAP:
1319 return uvc_ioctl_ctrl_map(chain, arg);
1320
1321 case UVCIOC_CTRL_QUERY:
1322 return uvc_xu_ctrl_query(chain, arg);
1323
1324 default:
1325 return -ENOTTY;
1326 }
1327}
1328
1329#ifdef CONFIG_COMPAT
1330struct uvc_xu_control_mapping32 {
1331 u32 id;
1332 u8 name[32];
1333 u8 entity[16];
1334 u8 selector;
1335
1336 u8 size;
1337 u8 offset;
1338 u32 v4l2_type;
1339 u32 data_type;
1340
1341 compat_caddr_t menu_info;
1342 u32 menu_count;
1343
1344 u32 reserved[4];
1345};
1346
1347static int uvc_v4l2_get_xu_mapping(struct uvc_xu_control_mapping *kp,
1348 const struct uvc_xu_control_mapping32 __user *up)
1349{
1350 struct uvc_xu_control_mapping32 *p = (void *)kp;
1351 compat_caddr_t info;
1352 u32 count;
1353
1354 if (copy_from_user(p, up, sizeof(*p)))
1355 return -EFAULT;
1356
1357 count = p->menu_count;
1358 info = p->menu_info;
1359
1360 memset(kp->reserved, 0, sizeof(kp->reserved));
1361 kp->menu_info = count ? compat_ptr(info) : NULL;
1362 kp->menu_count = count;
1363 return 0;
1364}
1365
1366static int uvc_v4l2_put_xu_mapping(const struct uvc_xu_control_mapping *kp,
1367 struct uvc_xu_control_mapping32 __user *up)
1368{
1369 if (copy_to_user(up, kp, offsetof(typeof(*up), menu_info)) ||
1370 put_user(kp->menu_count, &up->menu_count))
1371 return -EFAULT;
1372
1373 if (clear_user(up->reserved, sizeof(up->reserved)))
1374 return -EFAULT;
1375
1376 return 0;
1377}
1378
1379struct uvc_xu_control_query32 {
1380 u8 unit;
1381 u8 selector;
1382 u8 query;
1383 u16 size;
1384 compat_caddr_t data;
1385};
1386
1387static int uvc_v4l2_get_xu_query(struct uvc_xu_control_query *kp,
1388 const struct uvc_xu_control_query32 __user *up)
1389{
1390 struct uvc_xu_control_query32 v;
1391
1392 if (copy_from_user(&v, up, sizeof(v)))
1393 return -EFAULT;
1394
1395 *kp = (struct uvc_xu_control_query){
1396 .unit = v.unit,
1397 .selector = v.selector,
1398 .query = v.query,
1399 .size = v.size,
1400 .data = v.size ? compat_ptr(v.data) : NULL
1401 };
1402 return 0;
1403}
1404
1405static int uvc_v4l2_put_xu_query(const struct uvc_xu_control_query *kp,
1406 struct uvc_xu_control_query32 __user *up)
1407{
1408 if (copy_to_user(up, kp, offsetof(typeof(*up), data)))
1409 return -EFAULT;
1410 return 0;
1411}
1412
1413#define UVCIOC_CTRL_MAP32 _IOWR('u', 0x20, struct uvc_xu_control_mapping32)
1414#define UVCIOC_CTRL_QUERY32 _IOWR('u', 0x21, struct uvc_xu_control_query32)
1415
1416static long uvc_v4l2_compat_ioctl32(struct file *file,
1417 unsigned int cmd, unsigned long arg)
1418{
1419 struct uvc_fh *handle = file->private_data;
1420 union {
1421 struct uvc_xu_control_mapping xmap;
1422 struct uvc_xu_control_query xqry;
1423 } karg;
1424 void __user *up = compat_ptr(arg);
1425 long ret;
1426
1427 switch (cmd) {
1428 case UVCIOC_CTRL_MAP32:
1429 ret = uvc_v4l2_get_xu_mapping(&karg.xmap, up);
1430 if (ret)
1431 return ret;
1432 ret = uvc_ioctl_ctrl_map(handle->chain, &karg.xmap);
1433 if (ret)
1434 return ret;
1435 ret = uvc_v4l2_put_xu_mapping(&karg.xmap, up);
1436 if (ret)
1437 return ret;
1438
1439 break;
1440
1441 case UVCIOC_CTRL_QUERY32:
1442 ret = uvc_v4l2_get_xu_query(&karg.xqry, up);
1443 if (ret)
1444 return ret;
1445 ret = uvc_xu_ctrl_query(handle->chain, &karg.xqry);
1446 if (ret)
1447 return ret;
1448 ret = uvc_v4l2_put_xu_query(&karg.xqry, up);
1449 if (ret)
1450 return ret;
1451 break;
1452
1453 default:
1454 return -ENOIOCTLCMD;
1455 }
1456
1457 return ret;
1458}
1459#endif
1460
1461static ssize_t uvc_v4l2_read(struct file *file, char __user *data,
1462 size_t count, loff_t *ppos)
1463{
1464 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_read: not implemented.\n");
1465 return -EINVAL;
1466}
1467
1468static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
1469{
1470 struct uvc_fh *handle = file->private_data;
1471 struct uvc_streaming *stream = handle->stream;
1472
1473 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_mmap\n");
1474
1475 return uvc_queue_mmap(&stream->queue, vma);
1476}
1477
1478static __poll_t uvc_v4l2_poll(struct file *file, poll_table *wait)
1479{
1480 struct uvc_fh *handle = file->private_data;
1481 struct uvc_streaming *stream = handle->stream;
1482
1483 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_poll\n");
1484
1485 return uvc_queue_poll(&stream->queue, file, wait);
1486}
1487
1488#ifndef CONFIG_MMU
1489static unsigned long uvc_v4l2_get_unmapped_area(struct file *file,
1490 unsigned long addr, unsigned long len, unsigned long pgoff,
1491 unsigned long flags)
1492{
1493 struct uvc_fh *handle = file->private_data;
1494 struct uvc_streaming *stream = handle->stream;
1495
1496 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_get_unmapped_area\n");
1497
1498 return uvc_queue_get_unmapped_area(&stream->queue, pgoff);
1499}
1500#endif
1501
1502const struct v4l2_ioctl_ops uvc_ioctl_ops = {
1503 .vidioc_querycap = uvc_ioctl_querycap,
1504 .vidioc_enum_fmt_vid_cap = uvc_ioctl_enum_fmt_vid_cap,
1505 .vidioc_enum_fmt_vid_out = uvc_ioctl_enum_fmt_vid_out,
1506 .vidioc_g_fmt_vid_cap = uvc_ioctl_g_fmt_vid_cap,
1507 .vidioc_g_fmt_vid_out = uvc_ioctl_g_fmt_vid_out,
1508 .vidioc_s_fmt_vid_cap = uvc_ioctl_s_fmt_vid_cap,
1509 .vidioc_s_fmt_vid_out = uvc_ioctl_s_fmt_vid_out,
1510 .vidioc_try_fmt_vid_cap = uvc_ioctl_try_fmt_vid_cap,
1511 .vidioc_try_fmt_vid_out = uvc_ioctl_try_fmt_vid_out,
1512 .vidioc_reqbufs = uvc_ioctl_reqbufs,
1513 .vidioc_querybuf = uvc_ioctl_querybuf,
1514 .vidioc_qbuf = uvc_ioctl_qbuf,
1515 .vidioc_expbuf = uvc_ioctl_expbuf,
1516 .vidioc_dqbuf = uvc_ioctl_dqbuf,
1517 .vidioc_create_bufs = uvc_ioctl_create_bufs,
1518 .vidioc_streamon = uvc_ioctl_streamon,
1519 .vidioc_streamoff = uvc_ioctl_streamoff,
1520 .vidioc_enum_input = uvc_ioctl_enum_input,
1521 .vidioc_g_input = uvc_ioctl_g_input,
1522 .vidioc_s_input = uvc_ioctl_s_input,
1523 .vidioc_queryctrl = uvc_ioctl_queryctrl,
1524 .vidioc_query_ext_ctrl = uvc_ioctl_query_ext_ctrl,
1525 .vidioc_g_ctrl = uvc_ioctl_g_ctrl,
1526 .vidioc_s_ctrl = uvc_ioctl_s_ctrl,
1527 .vidioc_g_ext_ctrls = uvc_ioctl_g_ext_ctrls,
1528 .vidioc_s_ext_ctrls = uvc_ioctl_s_ext_ctrls,
1529 .vidioc_try_ext_ctrls = uvc_ioctl_try_ext_ctrls,
1530 .vidioc_querymenu = uvc_ioctl_querymenu,
1531 .vidioc_g_selection = uvc_ioctl_g_selection,
1532 .vidioc_g_parm = uvc_ioctl_g_parm,
1533 .vidioc_s_parm = uvc_ioctl_s_parm,
1534 .vidioc_enum_framesizes = uvc_ioctl_enum_framesizes,
1535 .vidioc_enum_frameintervals = uvc_ioctl_enum_frameintervals,
1536 .vidioc_subscribe_event = uvc_ioctl_subscribe_event,
1537 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1538 .vidioc_default = uvc_ioctl_default,
1539};
1540
1541const struct v4l2_file_operations uvc_fops = {
1542 .owner = THIS_MODULE,
1543 .open = uvc_v4l2_open,
1544 .release = uvc_v4l2_release,
1545 .unlocked_ioctl = video_ioctl2,
1546#ifdef CONFIG_COMPAT
1547 .compat_ioctl32 = uvc_v4l2_compat_ioctl32,
1548#endif
1549 .read = uvc_v4l2_read,
1550 .mmap = uvc_v4l2_mmap,
1551 .poll = uvc_v4l2_poll,
1552#ifndef CONFIG_MMU
1553 .get_unmapped_area = uvc_v4l2_get_unmapped_area,
1554#endif
1555};
1556
1557