1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/compat.h>
15#include <linux/kernel.h>
16#include <linux/version.h>
17#include <linux/list.h>
18#include <linux/module.h>
19#include <linux/slab.h>
20#include <linux/usb.h>
21#include <linux/videodev2.h>
22#include <linux/vmalloc.h>
23#include <linux/mm.h>
24#include <linux/wait.h>
25#include <linux/atomic.h>
26
27#include <media/v4l2-common.h>
28#include <media/v4l2-ctrls.h>
29#include <media/v4l2-event.h>
30#include <media/v4l2-ioctl.h>
31
32#include "uvcvideo.h"
33
34
35
36
37static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain,
38 struct uvc_xu_control_mapping *xmap)
39{
40 struct uvc_control_mapping *map;
41 unsigned int size;
42 int ret;
43
44 map = kzalloc(sizeof *map, GFP_KERNEL);
45 if (map == NULL)
46 return -ENOMEM;
47
48 map->id = xmap->id;
49 memcpy(map->name, xmap->name, sizeof map->name);
50 memcpy(map->entity, xmap->entity, sizeof map->entity);
51 map->selector = xmap->selector;
52 map->size = xmap->size;
53 map->offset = xmap->offset;
54 map->v4l2_type = xmap->v4l2_type;
55 map->data_type = xmap->data_type;
56
57 switch (xmap->v4l2_type) {
58 case V4L2_CTRL_TYPE_INTEGER:
59 case V4L2_CTRL_TYPE_BOOLEAN:
60 case V4L2_CTRL_TYPE_BUTTON:
61 break;
62
63 case V4L2_CTRL_TYPE_MENU:
64
65
66
67 if (xmap->menu_count == 0 ||
68 xmap->menu_count > UVC_MAX_CONTROL_MENU_ENTRIES) {
69 ret = -EINVAL;
70 goto done;
71 }
72
73 size = xmap->menu_count * sizeof(*map->menu_info);
74 map->menu_info = kmalloc(size, GFP_KERNEL);
75 if (map->menu_info == NULL) {
76 ret = -ENOMEM;
77 goto done;
78 }
79
80 if (copy_from_user(map->menu_info, xmap->menu_info, size)) {
81 ret = -EFAULT;
82 goto done;
83 }
84
85 map->menu_count = xmap->menu_count;
86 break;
87
88 default:
89 uvc_trace(UVC_TRACE_CONTROL, "Unsupported V4L2 control type "
90 "%u.\n", xmap->v4l2_type);
91 ret = -ENOTTY;
92 goto done;
93 }
94
95 ret = uvc_ctrl_add_mapping(chain, map);
96
97done:
98 kfree(map->menu_info);
99 kfree(map);
100
101 return ret;
102}
103
104
105
106
107
108
109
110
111
112
113
114static __u32 uvc_try_frame_interval(struct uvc_frame *frame, __u32 interval)
115{
116 unsigned int i;
117
118 if (frame->bFrameIntervalType) {
119 __u32 best = -1, dist;
120
121 for (i = 0; i < frame->bFrameIntervalType; ++i) {
122 dist = interval > frame->dwFrameInterval[i]
123 ? interval - frame->dwFrameInterval[i]
124 : frame->dwFrameInterval[i] - interval;
125
126 if (dist > best)
127 break;
128
129 best = dist;
130 }
131
132 interval = frame->dwFrameInterval[i-1];
133 } else {
134 const __u32 min = frame->dwFrameInterval[0];
135 const __u32 max = frame->dwFrameInterval[1];
136 const __u32 step = frame->dwFrameInterval[2];
137
138 interval = min + (interval - min + step/2) / step * step;
139 if (interval > max)
140 interval = max;
141 }
142
143 return interval;
144}
145
146static int uvc_v4l2_try_format(struct uvc_streaming *stream,
147 struct v4l2_format *fmt, struct uvc_streaming_control *probe,
148 struct uvc_format **uvc_format, struct uvc_frame **uvc_frame)
149{
150 struct uvc_format *format = NULL;
151 struct uvc_frame *frame = NULL;
152 __u16 rw, rh;
153 unsigned int d, maxd;
154 unsigned int i;
155 __u32 interval;
156 int ret = 0;
157 __u8 *fcc;
158
159 if (fmt->type != stream->type)
160 return -EINVAL;
161
162 fcc = (__u8 *)&fmt->fmt.pix.pixelformat;
163 uvc_trace(UVC_TRACE_FORMAT, "Trying format 0x%08x (%c%c%c%c): %ux%u.\n",
164 fmt->fmt.pix.pixelformat,
165 fcc[0], fcc[1], fcc[2], fcc[3],
166 fmt->fmt.pix.width, fmt->fmt.pix.height);
167
168
169
170
171 for (i = 0; i < stream->nformats; ++i) {
172 format = &stream->format[i];
173 if (format->fcc == fmt->fmt.pix.pixelformat)
174 break;
175 }
176
177 if (i == stream->nformats) {
178 format = stream->def_format;
179 fmt->fmt.pix.pixelformat = format->fcc;
180 }
181
182
183
184
185
186 rw = fmt->fmt.pix.width;
187 rh = fmt->fmt.pix.height;
188 maxd = (unsigned int)-1;
189
190 for (i = 0; i < format->nframes; ++i) {
191 __u16 w = format->frame[i].wWidth;
192 __u16 h = format->frame[i].wHeight;
193
194 d = min(w, rw) * min(h, rh);
195 d = w*h + rw*rh - 2*d;
196 if (d < maxd) {
197 maxd = d;
198 frame = &format->frame[i];
199 }
200
201 if (maxd == 0)
202 break;
203 }
204
205 if (frame == NULL) {
206 uvc_trace(UVC_TRACE_FORMAT, "Unsupported size %ux%u.\n",
207 fmt->fmt.pix.width, fmt->fmt.pix.height);
208 return -EINVAL;
209 }
210
211
212 interval = frame->dwDefaultFrameInterval;
213 uvc_trace(UVC_TRACE_FORMAT, "Using default frame interval %u.%u us "
214 "(%u.%u fps).\n", interval/10, interval%10, 10000000/interval,
215 (100000000/interval)%10);
216
217
218 memset(probe, 0, sizeof *probe);
219 probe->bmHint = 1;
220 probe->bFormatIndex = format->index;
221 probe->bFrameIndex = frame->bFrameIndex;
222 probe->dwFrameInterval = uvc_try_frame_interval(frame, interval);
223
224
225
226
227
228
229
230
231
232
233
234
235 mutex_lock(&stream->mutex);
236 if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS)
237 probe->dwMaxVideoFrameSize =
238 stream->ctrl.dwMaxVideoFrameSize;
239
240
241 ret = uvc_probe_video(stream, probe);
242 mutex_unlock(&stream->mutex);
243 if (ret < 0)
244 goto done;
245
246 fmt->fmt.pix.width = frame->wWidth;
247 fmt->fmt.pix.height = frame->wHeight;
248 fmt->fmt.pix.field = V4L2_FIELD_NONE;
249 fmt->fmt.pix.bytesperline = format->bpp * frame->wWidth / 8;
250 fmt->fmt.pix.sizeimage = probe->dwMaxVideoFrameSize;
251 fmt->fmt.pix.colorspace = format->colorspace;
252 fmt->fmt.pix.priv = 0;
253
254 if (uvc_format != NULL)
255 *uvc_format = format;
256 if (uvc_frame != NULL)
257 *uvc_frame = frame;
258
259done:
260 return ret;
261}
262
263static int uvc_v4l2_get_format(struct uvc_streaming *stream,
264 struct v4l2_format *fmt)
265{
266 struct uvc_format *format;
267 struct uvc_frame *frame;
268 int ret = 0;
269
270 if (fmt->type != stream->type)
271 return -EINVAL;
272
273 mutex_lock(&stream->mutex);
274 format = stream->cur_format;
275 frame = stream->cur_frame;
276
277 if (format == NULL || frame == NULL) {
278 ret = -EINVAL;
279 goto done;
280 }
281
282 fmt->fmt.pix.pixelformat = format->fcc;
283 fmt->fmt.pix.width = frame->wWidth;
284 fmt->fmt.pix.height = frame->wHeight;
285 fmt->fmt.pix.field = V4L2_FIELD_NONE;
286 fmt->fmt.pix.bytesperline = format->bpp * frame->wWidth / 8;
287 fmt->fmt.pix.sizeimage = stream->ctrl.dwMaxVideoFrameSize;
288 fmt->fmt.pix.colorspace = format->colorspace;
289 fmt->fmt.pix.priv = 0;
290
291done:
292 mutex_unlock(&stream->mutex);
293 return ret;
294}
295
296static int uvc_v4l2_set_format(struct uvc_streaming *stream,
297 struct v4l2_format *fmt)
298{
299 struct uvc_streaming_control probe;
300 struct uvc_format *format;
301 struct uvc_frame *frame;
302 int ret;
303
304 if (fmt->type != stream->type)
305 return -EINVAL;
306
307 ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame);
308 if (ret < 0)
309 return ret;
310
311 mutex_lock(&stream->mutex);
312
313 if (uvc_queue_allocated(&stream->queue)) {
314 ret = -EBUSY;
315 goto done;
316 }
317
318 stream->ctrl = probe;
319 stream->cur_format = format;
320 stream->cur_frame = frame;
321
322done:
323 mutex_unlock(&stream->mutex);
324 return ret;
325}
326
327static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream,
328 struct v4l2_streamparm *parm)
329{
330 uint32_t numerator, denominator;
331
332 if (parm->type != stream->type)
333 return -EINVAL;
334
335 mutex_lock(&stream->mutex);
336 numerator = stream->ctrl.dwFrameInterval;
337 mutex_unlock(&stream->mutex);
338
339 denominator = 10000000;
340 uvc_simplify_fraction(&numerator, &denominator, 8, 333);
341
342 memset(parm, 0, sizeof *parm);
343 parm->type = stream->type;
344
345 if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
346 parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
347 parm->parm.capture.capturemode = 0;
348 parm->parm.capture.timeperframe.numerator = numerator;
349 parm->parm.capture.timeperframe.denominator = denominator;
350 parm->parm.capture.extendedmode = 0;
351 parm->parm.capture.readbuffers = 0;
352 } else {
353 parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
354 parm->parm.output.outputmode = 0;
355 parm->parm.output.timeperframe.numerator = numerator;
356 parm->parm.output.timeperframe.denominator = denominator;
357 }
358
359 return 0;
360}
361
362static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream,
363 struct v4l2_streamparm *parm)
364{
365 struct uvc_streaming_control probe;
366 struct v4l2_fract timeperframe;
367 uint32_t interval;
368 int ret;
369
370 if (parm->type != stream->type)
371 return -EINVAL;
372
373 if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
374 timeperframe = parm->parm.capture.timeperframe;
375 else
376 timeperframe = parm->parm.output.timeperframe;
377
378 interval = uvc_fraction_to_interval(timeperframe.numerator,
379 timeperframe.denominator);
380 uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n",
381 timeperframe.numerator, timeperframe.denominator, interval);
382
383 mutex_lock(&stream->mutex);
384
385 if (uvc_queue_streaming(&stream->queue)) {
386 mutex_unlock(&stream->mutex);
387 return -EBUSY;
388 }
389
390 probe = stream->ctrl;
391 probe.dwFrameInterval =
392 uvc_try_frame_interval(stream->cur_frame, interval);
393
394
395 ret = uvc_probe_video(stream, &probe);
396 if (ret < 0) {
397 mutex_unlock(&stream->mutex);
398 return ret;
399 }
400
401 stream->ctrl = probe;
402 mutex_unlock(&stream->mutex);
403
404
405 timeperframe.numerator = probe.dwFrameInterval;
406 timeperframe.denominator = 10000000;
407 uvc_simplify_fraction(&timeperframe.numerator,
408 &timeperframe.denominator, 8, 333);
409
410 if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
411 parm->parm.capture.timeperframe = timeperframe;
412 else
413 parm->parm.output.timeperframe = timeperframe;
414
415 return 0;
416}
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445static int uvc_acquire_privileges(struct uvc_fh *handle)
446{
447
448 if (handle->state == UVC_HANDLE_ACTIVE)
449 return 0;
450
451
452 if (atomic_inc_return(&handle->stream->active) != 1) {
453 atomic_dec(&handle->stream->active);
454 return -EBUSY;
455 }
456
457 handle->state = UVC_HANDLE_ACTIVE;
458 return 0;
459}
460
461static void uvc_dismiss_privileges(struct uvc_fh *handle)
462{
463 if (handle->state == UVC_HANDLE_ACTIVE)
464 atomic_dec(&handle->stream->active);
465
466 handle->state = UVC_HANDLE_PASSIVE;
467}
468
469static int uvc_has_privileges(struct uvc_fh *handle)
470{
471 return handle->state == UVC_HANDLE_ACTIVE;
472}
473
474
475
476
477
478static int uvc_v4l2_open(struct file *file)
479{
480 struct uvc_streaming *stream;
481 struct uvc_fh *handle;
482 int ret = 0;
483
484 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n");
485 stream = video_drvdata(file);
486
487 if (stream->dev->state & UVC_DEV_DISCONNECTED)
488 return -ENODEV;
489
490 ret = usb_autopm_get_interface(stream->dev->intf);
491 if (ret < 0)
492 return ret;
493
494
495 handle = kzalloc(sizeof *handle, GFP_KERNEL);
496 if (handle == NULL) {
497 usb_autopm_put_interface(stream->dev->intf);
498 return -ENOMEM;
499 }
500
501 mutex_lock(&stream->dev->lock);
502 if (stream->dev->users == 0) {
503 ret = uvc_status_start(stream->dev, GFP_KERNEL);
504 if (ret < 0) {
505 mutex_unlock(&stream->dev->lock);
506 usb_autopm_put_interface(stream->dev->intf);
507 kfree(handle);
508 return ret;
509 }
510 }
511
512 stream->dev->users++;
513 mutex_unlock(&stream->dev->lock);
514
515 v4l2_fh_init(&handle->vfh, stream->vdev);
516 v4l2_fh_add(&handle->vfh);
517 handle->chain = stream->chain;
518 handle->stream = stream;
519 handle->state = UVC_HANDLE_PASSIVE;
520 file->private_data = handle;
521
522 return 0;
523}
524
525static int uvc_v4l2_release(struct file *file)
526{
527 struct uvc_fh *handle = file->private_data;
528 struct uvc_streaming *stream = handle->stream;
529
530 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_release\n");
531
532
533 if (uvc_has_privileges(handle)) {
534 uvc_video_enable(stream, 0);
535 uvc_free_buffers(&stream->queue);
536 }
537
538
539 uvc_dismiss_privileges(handle);
540 v4l2_fh_del(&handle->vfh);
541 v4l2_fh_exit(&handle->vfh);
542 kfree(handle);
543 file->private_data = NULL;
544
545 mutex_lock(&stream->dev->lock);
546 if (--stream->dev->users == 0)
547 uvc_status_stop(stream->dev);
548 mutex_unlock(&stream->dev->lock);
549
550 usb_autopm_put_interface(stream->dev->intf);
551 return 0;
552}
553
554static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
555{
556 struct video_device *vdev = video_devdata(file);
557 struct uvc_fh *handle = file->private_data;
558 struct uvc_video_chain *chain = handle->chain;
559 struct uvc_streaming *stream = handle->stream;
560 long ret = 0;
561
562 switch (cmd) {
563
564 case VIDIOC_QUERYCAP:
565 {
566 struct v4l2_capability *cap = arg;
567
568 memset(cap, 0, sizeof *cap);
569 strlcpy(cap->driver, "uvcvideo", sizeof cap->driver);
570 strlcpy(cap->card, vdev->name, sizeof cap->card);
571 usb_make_path(stream->dev->udev,
572 cap->bus_info, sizeof(cap->bus_info));
573 cap->version = LINUX_VERSION_CODE;
574 cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING
575 | chain->caps;
576 if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
577 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE
578 | V4L2_CAP_STREAMING;
579 else
580 cap->device_caps = V4L2_CAP_VIDEO_OUTPUT
581 | V4L2_CAP_STREAMING;
582 break;
583 }
584
585
586 case VIDIOC_G_PRIORITY:
587 *(u32 *)arg = v4l2_prio_max(vdev->prio);
588 break;
589
590 case VIDIOC_S_PRIORITY:
591 ret = v4l2_prio_check(vdev->prio, handle->vfh.prio);
592 if (ret < 0)
593 return ret;
594
595 return v4l2_prio_change(vdev->prio, &handle->vfh.prio,
596 *(u32 *)arg);
597
598
599 case VIDIOC_QUERYCTRL:
600 return uvc_query_v4l2_ctrl(chain, arg);
601
602 case VIDIOC_G_CTRL:
603 {
604 struct v4l2_control *ctrl = arg;
605 struct v4l2_ext_control xctrl;
606
607 memset(&xctrl, 0, sizeof xctrl);
608 xctrl.id = ctrl->id;
609
610 ret = uvc_ctrl_begin(chain);
611 if (ret < 0)
612 return ret;
613
614 ret = uvc_ctrl_get(chain, &xctrl);
615 uvc_ctrl_rollback(handle);
616 if (ret >= 0)
617 ctrl->value = xctrl.value;
618 break;
619 }
620
621 case VIDIOC_S_CTRL:
622 {
623 struct v4l2_control *ctrl = arg;
624 struct v4l2_ext_control xctrl;
625
626 ret = v4l2_prio_check(vdev->prio, handle->vfh.prio);
627 if (ret < 0)
628 return ret;
629
630 memset(&xctrl, 0, sizeof xctrl);
631 xctrl.id = ctrl->id;
632 xctrl.value = ctrl->value;
633
634 ret = uvc_ctrl_begin(chain);
635 if (ret < 0)
636 return ret;
637
638 ret = uvc_ctrl_set(chain, &xctrl);
639 if (ret < 0) {
640 uvc_ctrl_rollback(handle);
641 return ret;
642 }
643 ret = uvc_ctrl_commit(handle, &xctrl, 1);
644 if (ret == 0)
645 ctrl->value = xctrl.value;
646 break;
647 }
648
649 case VIDIOC_QUERYMENU:
650 return uvc_query_v4l2_menu(chain, arg);
651
652 case VIDIOC_G_EXT_CTRLS:
653 {
654 struct v4l2_ext_controls *ctrls = arg;
655 struct v4l2_ext_control *ctrl = ctrls->controls;
656 unsigned int i;
657
658 ret = uvc_ctrl_begin(chain);
659 if (ret < 0)
660 return ret;
661
662 for (i = 0; i < ctrls->count; ++ctrl, ++i) {
663 ret = uvc_ctrl_get(chain, ctrl);
664 if (ret < 0) {
665 uvc_ctrl_rollback(handle);
666 ctrls->error_idx = i;
667 return ret;
668 }
669 }
670 ctrls->error_idx = 0;
671 ret = uvc_ctrl_rollback(handle);
672 break;
673 }
674
675 case VIDIOC_S_EXT_CTRLS:
676 ret = v4l2_prio_check(vdev->prio, handle->vfh.prio);
677 if (ret < 0)
678 return ret;
679
680 case VIDIOC_TRY_EXT_CTRLS:
681 {
682 struct v4l2_ext_controls *ctrls = arg;
683 struct v4l2_ext_control *ctrl = ctrls->controls;
684 unsigned int i;
685
686 ret = uvc_ctrl_begin(chain);
687 if (ret < 0)
688 return ret;
689
690 for (i = 0; i < ctrls->count; ++ctrl, ++i) {
691 ret = uvc_ctrl_set(chain, ctrl);
692 if (ret < 0) {
693 uvc_ctrl_rollback(handle);
694 ctrls->error_idx = cmd == VIDIOC_S_EXT_CTRLS
695 ? ctrls->count : i;
696 return ret;
697 }
698 }
699
700 ctrls->error_idx = 0;
701
702 if (cmd == VIDIOC_S_EXT_CTRLS)
703 ret = uvc_ctrl_commit(handle,
704 ctrls->controls, ctrls->count);
705 else
706 ret = uvc_ctrl_rollback(handle);
707 break;
708 }
709
710
711 case VIDIOC_ENUMINPUT:
712 {
713 const struct uvc_entity *selector = chain->selector;
714 struct v4l2_input *input = arg;
715 struct uvc_entity *iterm = NULL;
716 u32 index = input->index;
717 int pin = 0;
718
719 if (selector == NULL ||
720 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
721 if (index != 0)
722 return -EINVAL;
723 list_for_each_entry(iterm, &chain->entities, chain) {
724 if (UVC_ENTITY_IS_ITERM(iterm))
725 break;
726 }
727 pin = iterm->id;
728 } else if (index < selector->bNrInPins) {
729 pin = selector->baSourceID[index];
730 list_for_each_entry(iterm, &chain->entities, chain) {
731 if (!UVC_ENTITY_IS_ITERM(iterm))
732 continue;
733 if (iterm->id == pin)
734 break;
735 }
736 }
737
738 if (iterm == NULL || iterm->id != pin)
739 return -EINVAL;
740
741 memset(input, 0, sizeof *input);
742 input->index = index;
743 strlcpy(input->name, iterm->name, sizeof input->name);
744 if (UVC_ENTITY_TYPE(iterm) == UVC_ITT_CAMERA)
745 input->type = V4L2_INPUT_TYPE_CAMERA;
746 break;
747 }
748
749 case VIDIOC_G_INPUT:
750 {
751 u8 input;
752
753 if (chain->selector == NULL ||
754 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
755 *(int *)arg = 0;
756 break;
757 }
758
759 ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
760 chain->selector->id, chain->dev->intfnum,
761 UVC_SU_INPUT_SELECT_CONTROL, &input, 1);
762 if (ret < 0)
763 return ret;
764
765 *(int *)arg = input - 1;
766 break;
767 }
768
769 case VIDIOC_S_INPUT:
770 {
771 u32 input = *(u32 *)arg + 1;
772
773 ret = v4l2_prio_check(vdev->prio, handle->vfh.prio);
774 if (ret < 0)
775 return ret;
776
777 if ((ret = uvc_acquire_privileges(handle)) < 0)
778 return ret;
779
780 if (chain->selector == NULL ||
781 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
782 if (input != 1)
783 return -EINVAL;
784 break;
785 }
786
787 if (input == 0 || input > chain->selector->bNrInPins)
788 return -EINVAL;
789
790 return uvc_query_ctrl(chain->dev, UVC_SET_CUR,
791 chain->selector->id, chain->dev->intfnum,
792 UVC_SU_INPUT_SELECT_CONTROL, &input, 1);
793 }
794
795
796 case VIDIOC_ENUM_FMT:
797 {
798 struct v4l2_fmtdesc *fmt = arg;
799 struct uvc_format *format;
800 enum v4l2_buf_type type = fmt->type;
801 __u32 index = fmt->index;
802
803 if (fmt->type != stream->type ||
804 fmt->index >= stream->nformats)
805 return -EINVAL;
806
807 memset(fmt, 0, sizeof(*fmt));
808 fmt->index = index;
809 fmt->type = type;
810
811 format = &stream->format[fmt->index];
812 fmt->flags = 0;
813 if (format->flags & UVC_FMT_FLAG_COMPRESSED)
814 fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
815 strlcpy(fmt->description, format->name,
816 sizeof fmt->description);
817 fmt->description[sizeof fmt->description - 1] = 0;
818 fmt->pixelformat = format->fcc;
819 break;
820 }
821
822 case VIDIOC_TRY_FMT:
823 {
824 struct uvc_streaming_control probe;
825
826 return uvc_v4l2_try_format(stream, arg, &probe, NULL, NULL);
827 }
828
829 case VIDIOC_S_FMT:
830 ret = v4l2_prio_check(vdev->prio, handle->vfh.prio);
831 if (ret < 0)
832 return ret;
833
834 if ((ret = uvc_acquire_privileges(handle)) < 0)
835 return ret;
836
837 return uvc_v4l2_set_format(stream, arg);
838
839 case VIDIOC_G_FMT:
840 return uvc_v4l2_get_format(stream, arg);
841
842
843 case VIDIOC_ENUM_FRAMESIZES:
844 {
845 struct v4l2_frmsizeenum *fsize = arg;
846 struct uvc_format *format = NULL;
847 struct uvc_frame *frame;
848 int i;
849
850
851 for (i = 0; i < stream->nformats; i++) {
852 if (stream->format[i].fcc ==
853 fsize->pixel_format) {
854 format = &stream->format[i];
855 break;
856 }
857 }
858 if (format == NULL)
859 return -EINVAL;
860
861 if (fsize->index >= format->nframes)
862 return -EINVAL;
863
864 frame = &format->frame[fsize->index];
865 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
866 fsize->discrete.width = frame->wWidth;
867 fsize->discrete.height = frame->wHeight;
868 break;
869 }
870
871
872 case VIDIOC_ENUM_FRAMEINTERVALS:
873 {
874 struct v4l2_frmivalenum *fival = arg;
875 struct uvc_format *format = NULL;
876 struct uvc_frame *frame = NULL;
877 int i;
878
879
880 for (i = 0; i < stream->nformats; i++) {
881 if (stream->format[i].fcc ==
882 fival->pixel_format) {
883 format = &stream->format[i];
884 break;
885 }
886 }
887 if (format == NULL)
888 return -EINVAL;
889
890 for (i = 0; i < format->nframes; i++) {
891 if (format->frame[i].wWidth == fival->width &&
892 format->frame[i].wHeight == fival->height) {
893 frame = &format->frame[i];
894 break;
895 }
896 }
897 if (frame == NULL)
898 return -EINVAL;
899
900 if (frame->bFrameIntervalType) {
901 if (fival->index >= frame->bFrameIntervalType)
902 return -EINVAL;
903
904 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
905 fival->discrete.numerator =
906 frame->dwFrameInterval[fival->index];
907 fival->discrete.denominator = 10000000;
908 uvc_simplify_fraction(&fival->discrete.numerator,
909 &fival->discrete.denominator, 8, 333);
910 } else {
911 fival->type = V4L2_FRMIVAL_TYPE_STEPWISE;
912 fival->stepwise.min.numerator =
913 frame->dwFrameInterval[0];
914 fival->stepwise.min.denominator = 10000000;
915 fival->stepwise.max.numerator =
916 frame->dwFrameInterval[1];
917 fival->stepwise.max.denominator = 10000000;
918 fival->stepwise.step.numerator =
919 frame->dwFrameInterval[2];
920 fival->stepwise.step.denominator = 10000000;
921 uvc_simplify_fraction(&fival->stepwise.min.numerator,
922 &fival->stepwise.min.denominator, 8, 333);
923 uvc_simplify_fraction(&fival->stepwise.max.numerator,
924 &fival->stepwise.max.denominator, 8, 333);
925 uvc_simplify_fraction(&fival->stepwise.step.numerator,
926 &fival->stepwise.step.denominator, 8, 333);
927 }
928 break;
929 }
930
931
932 case VIDIOC_G_PARM:
933 return uvc_v4l2_get_streamparm(stream, arg);
934
935 case VIDIOC_S_PARM:
936 ret = v4l2_prio_check(vdev->prio, handle->vfh.prio);
937 if (ret < 0)
938 return ret;
939
940 if ((ret = uvc_acquire_privileges(handle)) < 0)
941 return ret;
942
943 return uvc_v4l2_set_streamparm(stream, arg);
944
945
946 case VIDIOC_CROPCAP:
947 {
948 struct v4l2_cropcap *ccap = arg;
949
950 if (ccap->type != stream->type)
951 return -EINVAL;
952
953 ccap->bounds.left = 0;
954 ccap->bounds.top = 0;
955
956 mutex_lock(&stream->mutex);
957 ccap->bounds.width = stream->cur_frame->wWidth;
958 ccap->bounds.height = stream->cur_frame->wHeight;
959 mutex_unlock(&stream->mutex);
960
961 ccap->defrect = ccap->bounds;
962
963 ccap->pixelaspect.numerator = 1;
964 ccap->pixelaspect.denominator = 1;
965 break;
966 }
967
968 case VIDIOC_G_CROP:
969 case VIDIOC_S_CROP:
970 return -ENOTTY;
971
972
973 case VIDIOC_REQBUFS:
974 ret = v4l2_prio_check(vdev->prio, handle->vfh.prio);
975 if (ret < 0)
976 return ret;
977
978 if ((ret = uvc_acquire_privileges(handle)) < 0)
979 return ret;
980
981 mutex_lock(&stream->mutex);
982 ret = uvc_alloc_buffers(&stream->queue, arg);
983 mutex_unlock(&stream->mutex);
984 if (ret < 0)
985 return ret;
986
987 if (ret == 0)
988 uvc_dismiss_privileges(handle);
989
990 ret = 0;
991 break;
992
993 case VIDIOC_QUERYBUF:
994 {
995 struct v4l2_buffer *buf = arg;
996
997 if (!uvc_has_privileges(handle))
998 return -EBUSY;
999
1000 return uvc_query_buffer(&stream->queue, buf);
1001 }
1002
1003 case VIDIOC_QBUF:
1004 if (!uvc_has_privileges(handle))
1005 return -EBUSY;
1006
1007 return uvc_queue_buffer(&stream->queue, arg);
1008
1009 case VIDIOC_DQBUF:
1010 if (!uvc_has_privileges(handle))
1011 return -EBUSY;
1012
1013 return uvc_dequeue_buffer(&stream->queue, arg,
1014 file->f_flags & O_NONBLOCK);
1015
1016 case VIDIOC_STREAMON:
1017 {
1018 int *type = arg;
1019
1020 if (*type != stream->type)
1021 return -EINVAL;
1022
1023 ret = v4l2_prio_check(vdev->prio, handle->vfh.prio);
1024 if (ret < 0)
1025 return ret;
1026
1027 if (!uvc_has_privileges(handle))
1028 return -EBUSY;
1029
1030 mutex_lock(&stream->mutex);
1031 ret = uvc_video_enable(stream, 1);
1032 mutex_unlock(&stream->mutex);
1033 if (ret < 0)
1034 return ret;
1035 break;
1036 }
1037
1038 case VIDIOC_STREAMOFF:
1039 {
1040 int *type = arg;
1041
1042 if (*type != stream->type)
1043 return -EINVAL;
1044
1045 ret = v4l2_prio_check(vdev->prio, handle->vfh.prio);
1046 if (ret < 0)
1047 return ret;
1048
1049 if (!uvc_has_privileges(handle))
1050 return -EBUSY;
1051
1052 return uvc_video_enable(stream, 0);
1053 }
1054
1055 case VIDIOC_SUBSCRIBE_EVENT:
1056 {
1057 struct v4l2_event_subscription *sub = arg;
1058
1059 switch (sub->type) {
1060 case V4L2_EVENT_CTRL:
1061 return v4l2_event_subscribe(&handle->vfh, sub, 0,
1062 &uvc_ctrl_sub_ev_ops);
1063 default:
1064 return -EINVAL;
1065 }
1066 }
1067
1068 case VIDIOC_UNSUBSCRIBE_EVENT:
1069 return v4l2_event_unsubscribe(&handle->vfh, arg);
1070
1071 case VIDIOC_DQEVENT:
1072 return v4l2_event_dequeue(&handle->vfh, arg,
1073 file->f_flags & O_NONBLOCK);
1074
1075
1076 case VIDIOC_ENUMSTD:
1077 case VIDIOC_QUERYSTD:
1078 case VIDIOC_G_STD:
1079 case VIDIOC_S_STD:
1080
1081 case VIDIOC_OVERLAY:
1082
1083 case VIDIOC_ENUMAUDIO:
1084 case VIDIOC_ENUMAUDOUT:
1085
1086 case VIDIOC_ENUMOUTPUT:
1087 uvc_trace(UVC_TRACE_IOCTL, "Unsupported ioctl 0x%08x\n", cmd);
1088 return -ENOTTY;
1089
1090 case UVCIOC_CTRL_MAP:
1091 return uvc_ioctl_ctrl_map(chain, arg);
1092
1093 case UVCIOC_CTRL_QUERY:
1094 return uvc_xu_ctrl_query(chain, arg);
1095
1096 default:
1097 uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n", cmd);
1098 return -ENOTTY;
1099 }
1100
1101 return ret;
1102}
1103
1104static long uvc_v4l2_ioctl(struct file *file,
1105 unsigned int cmd, unsigned long arg)
1106{
1107 if (uvc_trace_param & UVC_TRACE_IOCTL) {
1108 uvc_printk(KERN_DEBUG, "uvc_v4l2_ioctl(");
1109 v4l_printk_ioctl(NULL, cmd);
1110 printk(")\n");
1111 }
1112
1113 return video_usercopy(file, cmd, arg, uvc_v4l2_do_ioctl);
1114}
1115
1116#ifdef CONFIG_COMPAT
1117struct uvc_xu_control_mapping32 {
1118 __u32 id;
1119 __u8 name[32];
1120 __u8 entity[16];
1121 __u8 selector;
1122
1123 __u8 size;
1124 __u8 offset;
1125 __u32 v4l2_type;
1126 __u32 data_type;
1127
1128 compat_caddr_t menu_info;
1129 __u32 menu_count;
1130
1131 __u32 reserved[4];
1132};
1133
1134static int uvc_v4l2_get_xu_mapping(struct uvc_xu_control_mapping *kp,
1135 const struct uvc_xu_control_mapping32 __user *up)
1136{
1137 struct uvc_menu_info __user *umenus;
1138 struct uvc_menu_info __user *kmenus;
1139 compat_caddr_t p;
1140
1141 if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
1142 __copy_from_user(kp, up, offsetof(typeof(*up), menu_info)) ||
1143 __get_user(kp->menu_count, &up->menu_count))
1144 return -EFAULT;
1145
1146 memset(kp->reserved, 0, sizeof(kp->reserved));
1147
1148 if (kp->menu_count == 0) {
1149 kp->menu_info = NULL;
1150 return 0;
1151 }
1152
1153 if (__get_user(p, &up->menu_info))
1154 return -EFAULT;
1155 umenus = compat_ptr(p);
1156 if (!access_ok(VERIFY_READ, umenus, kp->menu_count * sizeof(*umenus)))
1157 return -EFAULT;
1158
1159 kmenus = compat_alloc_user_space(kp->menu_count * sizeof(*kmenus));
1160 if (kmenus == NULL)
1161 return -EFAULT;
1162 kp->menu_info = kmenus;
1163
1164 if (copy_in_user(kmenus, umenus, kp->menu_count * sizeof(*umenus)))
1165 return -EFAULT;
1166
1167 return 0;
1168}
1169
1170static int uvc_v4l2_put_xu_mapping(const struct uvc_xu_control_mapping *kp,
1171 struct uvc_xu_control_mapping32 __user *up)
1172{
1173 struct uvc_menu_info __user *umenus;
1174 struct uvc_menu_info __user *kmenus = kp->menu_info;
1175 compat_caddr_t p;
1176
1177 if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
1178 __copy_to_user(up, kp, offsetof(typeof(*up), menu_info)) ||
1179 __put_user(kp->menu_count, &up->menu_count))
1180 return -EFAULT;
1181
1182 if (__clear_user(up->reserved, sizeof(up->reserved)))
1183 return -EFAULT;
1184
1185 if (kp->menu_count == 0)
1186 return 0;
1187
1188 if (get_user(p, &up->menu_info))
1189 return -EFAULT;
1190 umenus = compat_ptr(p);
1191
1192 if (copy_in_user(umenus, kmenus, kp->menu_count * sizeof(*umenus)))
1193 return -EFAULT;
1194
1195 return 0;
1196}
1197
1198struct uvc_xu_control_query32 {
1199 __u8 unit;
1200 __u8 selector;
1201 __u8 query;
1202 __u16 size;
1203 compat_caddr_t data;
1204};
1205
1206static int uvc_v4l2_get_xu_query(struct uvc_xu_control_query *kp,
1207 const struct uvc_xu_control_query32 __user *up)
1208{
1209 u8 __user *udata;
1210 u8 __user *kdata;
1211 compat_caddr_t p;
1212
1213 if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
1214 __copy_from_user(kp, up, offsetof(typeof(*up), data)))
1215 return -EFAULT;
1216
1217 if (kp->size == 0) {
1218 kp->data = NULL;
1219 return 0;
1220 }
1221
1222 if (__get_user(p, &up->data))
1223 return -EFAULT;
1224 udata = compat_ptr(p);
1225 if (!access_ok(VERIFY_READ, udata, kp->size))
1226 return -EFAULT;
1227
1228 kdata = compat_alloc_user_space(kp->size);
1229 if (kdata == NULL)
1230 return -EFAULT;
1231 kp->data = kdata;
1232
1233 if (copy_in_user(kdata, udata, kp->size))
1234 return -EFAULT;
1235
1236 return 0;
1237}
1238
1239static int uvc_v4l2_put_xu_query(const struct uvc_xu_control_query *kp,
1240 struct uvc_xu_control_query32 __user *up)
1241{
1242 u8 __user *udata;
1243 u8 __user *kdata = kp->data;
1244 compat_caddr_t p;
1245
1246 if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
1247 __copy_to_user(up, kp, offsetof(typeof(*up), data)))
1248 return -EFAULT;
1249
1250 if (kp->size == 0)
1251 return 0;
1252
1253 if (get_user(p, &up->data))
1254 return -EFAULT;
1255 udata = compat_ptr(p);
1256 if (!access_ok(VERIFY_READ, udata, kp->size))
1257 return -EFAULT;
1258
1259 if (copy_in_user(udata, kdata, kp->size))
1260 return -EFAULT;
1261
1262 return 0;
1263}
1264
1265#define UVCIOC_CTRL_MAP32 _IOWR('u', 0x20, struct uvc_xu_control_mapping32)
1266#define UVCIOC_CTRL_QUERY32 _IOWR('u', 0x21, struct uvc_xu_control_query32)
1267
1268static long uvc_v4l2_compat_ioctl32(struct file *file,
1269 unsigned int cmd, unsigned long arg)
1270{
1271 union {
1272 struct uvc_xu_control_mapping xmap;
1273 struct uvc_xu_control_query xqry;
1274 } karg;
1275 void __user *up = compat_ptr(arg);
1276 mm_segment_t old_fs;
1277 long ret;
1278
1279 switch (cmd) {
1280 case UVCIOC_CTRL_MAP32:
1281 cmd = UVCIOC_CTRL_MAP;
1282 ret = uvc_v4l2_get_xu_mapping(&karg.xmap, up);
1283 break;
1284
1285 case UVCIOC_CTRL_QUERY32:
1286 cmd = UVCIOC_CTRL_QUERY;
1287 ret = uvc_v4l2_get_xu_query(&karg.xqry, up);
1288 break;
1289
1290 default:
1291 return -ENOIOCTLCMD;
1292 }
1293
1294 old_fs = get_fs();
1295 set_fs(KERNEL_DS);
1296 ret = uvc_v4l2_ioctl(file, cmd, (unsigned long)&karg);
1297 set_fs(old_fs);
1298
1299 if (ret < 0)
1300 return ret;
1301
1302 switch (cmd) {
1303 case UVCIOC_CTRL_MAP:
1304 ret = uvc_v4l2_put_xu_mapping(&karg.xmap, up);
1305 break;
1306
1307 case UVCIOC_CTRL_QUERY:
1308 ret = uvc_v4l2_put_xu_query(&karg.xqry, up);
1309 break;
1310 }
1311
1312 return ret;
1313}
1314#endif
1315
1316static ssize_t uvc_v4l2_read(struct file *file, char __user *data,
1317 size_t count, loff_t *ppos)
1318{
1319 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_read: not implemented.\n");
1320 return -EINVAL;
1321}
1322
1323static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
1324{
1325 struct uvc_fh *handle = file->private_data;
1326 struct uvc_streaming *stream = handle->stream;
1327
1328 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_mmap\n");
1329
1330 return uvc_queue_mmap(&stream->queue, vma);
1331}
1332
1333static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait)
1334{
1335 struct uvc_fh *handle = file->private_data;
1336 struct uvc_streaming *stream = handle->stream;
1337
1338 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_poll\n");
1339
1340 return uvc_queue_poll(&stream->queue, file, wait);
1341}
1342
1343#ifndef CONFIG_MMU
1344static unsigned long uvc_v4l2_get_unmapped_area(struct file *file,
1345 unsigned long addr, unsigned long len, unsigned long pgoff,
1346 unsigned long flags)
1347{
1348 struct uvc_fh *handle = file->private_data;
1349 struct uvc_streaming *stream = handle->stream;
1350
1351 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_get_unmapped_area\n");
1352
1353 return uvc_queue_get_unmapped_area(&stream->queue, pgoff);
1354}
1355#endif
1356
1357const struct v4l2_file_operations uvc_fops = {
1358 .owner = THIS_MODULE,
1359 .open = uvc_v4l2_open,
1360 .release = uvc_v4l2_release,
1361 .unlocked_ioctl = uvc_v4l2_ioctl,
1362#ifdef CONFIG_COMPAT
1363 .compat_ioctl32 = uvc_v4l2_compat_ioctl32,
1364#endif
1365 .read = uvc_v4l2_read,
1366 .mmap = uvc_v4l2_mmap,
1367 .poll = uvc_v4l2_poll,
1368#ifndef CONFIG_MMU
1369 .get_unmapped_area = uvc_v4l2_get_unmapped_area,
1370#endif
1371};
1372
1373