1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/kernel.h>
15#include <linux/version.h>
16#include <linux/list.h>
17#include <linux/module.h>
18#include <linux/usb.h>
19#include <linux/videodev2.h>
20#include <linux/vmalloc.h>
21#include <linux/mm.h>
22#include <linux/wait.h>
23#include <asm/atomic.h>
24
25#include <media/v4l2-common.h>
26#include <media/v4l2-ioctl.h>
27
28#include "uvcvideo.h"
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43static int uvc_v4l2_query_menu(struct uvc_video_chain *chain,
44 struct v4l2_querymenu *query_menu)
45{
46 struct uvc_menu_info *menu_info;
47 struct uvc_control_mapping *mapping;
48 struct uvc_control *ctrl;
49 u32 index = query_menu->index;
50 u32 id = query_menu->id;
51
52 ctrl = uvc_find_control(chain, query_menu->id, &mapping);
53 if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU)
54 return -EINVAL;
55
56 if (query_menu->index >= mapping->menu_count)
57 return -EINVAL;
58
59 memset(query_menu, 0, sizeof(*query_menu));
60 query_menu->id = id;
61 query_menu->index = index;
62
63 menu_info = &mapping->menu_info[query_menu->index];
64 strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name);
65 return 0;
66}
67
68
69
70
71
72
73
74static __u32 uvc_try_frame_interval(struct uvc_frame *frame, __u32 interval)
75{
76 unsigned int i;
77
78 if (frame->bFrameIntervalType) {
79 __u32 best = -1, dist;
80
81 for (i = 0; i < frame->bFrameIntervalType; ++i) {
82 dist = interval > frame->dwFrameInterval[i]
83 ? interval - frame->dwFrameInterval[i]
84 : frame->dwFrameInterval[i] - interval;
85
86 if (dist > best)
87 break;
88
89 best = dist;
90 }
91
92 interval = frame->dwFrameInterval[i-1];
93 } else {
94 const __u32 min = frame->dwFrameInterval[0];
95 const __u32 max = frame->dwFrameInterval[1];
96 const __u32 step = frame->dwFrameInterval[2];
97
98 interval = min + (interval - min + step/2) / step * step;
99 if (interval > max)
100 interval = max;
101 }
102
103 return interval;
104}
105
106static int uvc_v4l2_try_format(struct uvc_streaming *stream,
107 struct v4l2_format *fmt, struct uvc_streaming_control *probe,
108 struct uvc_format **uvc_format, struct uvc_frame **uvc_frame)
109{
110 struct uvc_format *format = NULL;
111 struct uvc_frame *frame = NULL;
112 __u16 rw, rh;
113 unsigned int d, maxd;
114 unsigned int i;
115 __u32 interval;
116 int ret = 0;
117 __u8 *fcc;
118
119 if (fmt->type != stream->type)
120 return -EINVAL;
121
122 fcc = (__u8 *)&fmt->fmt.pix.pixelformat;
123 uvc_trace(UVC_TRACE_FORMAT, "Trying format 0x%08x (%c%c%c%c): %ux%u.\n",
124 fmt->fmt.pix.pixelformat,
125 fcc[0], fcc[1], fcc[2], fcc[3],
126 fmt->fmt.pix.width, fmt->fmt.pix.height);
127
128
129 for (i = 0; i < stream->nformats; ++i) {
130 format = &stream->format[i];
131 if (format->fcc == fmt->fmt.pix.pixelformat)
132 break;
133 }
134
135 if (format == NULL || format->fcc != fmt->fmt.pix.pixelformat) {
136 uvc_trace(UVC_TRACE_FORMAT, "Unsupported format 0x%08x.\n",
137 fmt->fmt.pix.pixelformat);
138 return -EINVAL;
139 }
140
141
142
143
144
145 rw = fmt->fmt.pix.width;
146 rh = fmt->fmt.pix.height;
147 maxd = (unsigned int)-1;
148
149 for (i = 0; i < format->nframes; ++i) {
150 __u16 w = format->frame[i].wWidth;
151 __u16 h = format->frame[i].wHeight;
152
153 d = min(w, rw) * min(h, rh);
154 d = w*h + rw*rh - 2*d;
155 if (d < maxd) {
156 maxd = d;
157 frame = &format->frame[i];
158 }
159
160 if (maxd == 0)
161 break;
162 }
163
164 if (frame == NULL) {
165 uvc_trace(UVC_TRACE_FORMAT, "Unsupported size %ux%u.\n",
166 fmt->fmt.pix.width, fmt->fmt.pix.height);
167 return -EINVAL;
168 }
169
170
171 interval = frame->dwDefaultFrameInterval;
172 uvc_trace(UVC_TRACE_FORMAT, "Using default frame interval %u.%u us "
173 "(%u.%u fps).\n", interval/10, interval%10, 10000000/interval,
174 (100000000/interval)%10);
175
176
177 memset(probe, 0, sizeof *probe);
178 probe->bmHint = 1;
179 probe->bFormatIndex = format->index;
180 probe->bFrameIndex = frame->bFrameIndex;
181 probe->dwFrameInterval = uvc_try_frame_interval(frame, interval);
182
183
184
185
186
187
188
189
190
191
192
193
194 if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS)
195 probe->dwMaxVideoFrameSize =
196 stream->ctrl.dwMaxVideoFrameSize;
197
198
199 ret = uvc_probe_video(stream, probe);
200 if (ret < 0)
201 goto done;
202
203 fmt->fmt.pix.width = frame->wWidth;
204 fmt->fmt.pix.height = frame->wHeight;
205 fmt->fmt.pix.field = V4L2_FIELD_NONE;
206 fmt->fmt.pix.bytesperline = format->bpp * frame->wWidth / 8;
207 fmt->fmt.pix.sizeimage = probe->dwMaxVideoFrameSize;
208 fmt->fmt.pix.colorspace = format->colorspace;
209 fmt->fmt.pix.priv = 0;
210
211 if (uvc_format != NULL)
212 *uvc_format = format;
213 if (uvc_frame != NULL)
214 *uvc_frame = frame;
215
216done:
217 return ret;
218}
219
220static int uvc_v4l2_get_format(struct uvc_streaming *stream,
221 struct v4l2_format *fmt)
222{
223 struct uvc_format *format = stream->cur_format;
224 struct uvc_frame *frame = stream->cur_frame;
225
226 if (fmt->type != stream->type)
227 return -EINVAL;
228
229 if (format == NULL || frame == NULL)
230 return -EINVAL;
231
232 fmt->fmt.pix.pixelformat = format->fcc;
233 fmt->fmt.pix.width = frame->wWidth;
234 fmt->fmt.pix.height = frame->wHeight;
235 fmt->fmt.pix.field = V4L2_FIELD_NONE;
236 fmt->fmt.pix.bytesperline = format->bpp * frame->wWidth / 8;
237 fmt->fmt.pix.sizeimage = stream->ctrl.dwMaxVideoFrameSize;
238 fmt->fmt.pix.colorspace = format->colorspace;
239 fmt->fmt.pix.priv = 0;
240
241 return 0;
242}
243
244static int uvc_v4l2_set_format(struct uvc_streaming *stream,
245 struct v4l2_format *fmt)
246{
247 struct uvc_streaming_control probe;
248 struct uvc_format *format;
249 struct uvc_frame *frame;
250 int ret;
251
252 if (fmt->type != stream->type)
253 return -EINVAL;
254
255 if (uvc_queue_allocated(&stream->queue))
256 return -EBUSY;
257
258 ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame);
259 if (ret < 0)
260 return ret;
261
262 memcpy(&stream->ctrl, &probe, sizeof probe);
263 stream->cur_format = format;
264 stream->cur_frame = frame;
265
266 return 0;
267}
268
269static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream,
270 struct v4l2_streamparm *parm)
271{
272 uint32_t numerator, denominator;
273
274 if (parm->type != stream->type)
275 return -EINVAL;
276
277 numerator = stream->ctrl.dwFrameInterval;
278 denominator = 10000000;
279 uvc_simplify_fraction(&numerator, &denominator, 8, 333);
280
281 memset(parm, 0, sizeof *parm);
282 parm->type = stream->type;
283
284 if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
285 parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
286 parm->parm.capture.capturemode = 0;
287 parm->parm.capture.timeperframe.numerator = numerator;
288 parm->parm.capture.timeperframe.denominator = denominator;
289 parm->parm.capture.extendedmode = 0;
290 parm->parm.capture.readbuffers = 0;
291 } else {
292 parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
293 parm->parm.output.outputmode = 0;
294 parm->parm.output.timeperframe.numerator = numerator;
295 parm->parm.output.timeperframe.denominator = denominator;
296 }
297
298 return 0;
299}
300
301static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream,
302 struct v4l2_streamparm *parm)
303{
304 struct uvc_frame *frame = stream->cur_frame;
305 struct uvc_streaming_control probe;
306 struct v4l2_fract timeperframe;
307 uint32_t interval;
308 int ret;
309
310 if (parm->type != stream->type)
311 return -EINVAL;
312
313 if (uvc_queue_streaming(&stream->queue))
314 return -EBUSY;
315
316 if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
317 timeperframe = parm->parm.capture.timeperframe;
318 else
319 timeperframe = parm->parm.output.timeperframe;
320
321 memcpy(&probe, &stream->ctrl, sizeof probe);
322 interval = uvc_fraction_to_interval(timeperframe.numerator,
323 timeperframe.denominator);
324
325 uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n",
326 timeperframe.numerator, timeperframe.denominator, interval);
327 probe.dwFrameInterval = uvc_try_frame_interval(frame, interval);
328
329
330 ret = uvc_probe_video(stream, &probe);
331 if (ret < 0)
332 return ret;
333
334 memcpy(&stream->ctrl, &probe, sizeof probe);
335
336
337 timeperframe.numerator = probe.dwFrameInterval;
338 timeperframe.denominator = 10000000;
339 uvc_simplify_fraction(&timeperframe.numerator,
340 &timeperframe.denominator, 8, 333);
341
342 if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
343 parm->parm.capture.timeperframe = timeperframe;
344 else
345 parm->parm.output.timeperframe = timeperframe;
346
347 return 0;
348}
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377static int uvc_acquire_privileges(struct uvc_fh *handle)
378{
379 int ret = 0;
380
381
382 if (handle->state == UVC_HANDLE_ACTIVE)
383 return 0;
384
385
386 mutex_lock(&uvc_driver.open_mutex);
387 if (atomic_inc_return(&handle->stream->active) != 1) {
388 atomic_dec(&handle->stream->active);
389 ret = -EBUSY;
390 goto done;
391 }
392
393 handle->state = UVC_HANDLE_ACTIVE;
394
395done:
396 mutex_unlock(&uvc_driver.open_mutex);
397 return ret;
398}
399
400static void uvc_dismiss_privileges(struct uvc_fh *handle)
401{
402 if (handle->state == UVC_HANDLE_ACTIVE)
403 atomic_dec(&handle->stream->active);
404
405 handle->state = UVC_HANDLE_PASSIVE;
406}
407
408static int uvc_has_privileges(struct uvc_fh *handle)
409{
410 return handle->state == UVC_HANDLE_ACTIVE;
411}
412
413
414
415
416
417static int uvc_v4l2_open(struct file *file)
418{
419 struct uvc_streaming *stream;
420 struct uvc_fh *handle;
421 int ret = 0;
422
423 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n");
424 mutex_lock(&uvc_driver.open_mutex);
425 stream = video_drvdata(file);
426
427 if (stream->dev->state & UVC_DEV_DISCONNECTED) {
428 ret = -ENODEV;
429 goto done;
430 }
431
432 ret = usb_autopm_get_interface(stream->dev->intf);
433 if (ret < 0)
434 goto done;
435
436
437 handle = kzalloc(sizeof *handle, GFP_KERNEL);
438 if (handle == NULL) {
439 usb_autopm_put_interface(stream->dev->intf);
440 ret = -ENOMEM;
441 goto done;
442 }
443
444 if (atomic_inc_return(&stream->dev->users) == 1) {
445 ret = uvc_status_start(stream->dev);
446 if (ret < 0) {
447 usb_autopm_put_interface(stream->dev->intf);
448 atomic_dec(&stream->dev->users);
449 kfree(handle);
450 goto done;
451 }
452 }
453
454 handle->chain = stream->chain;
455 handle->stream = stream;
456 handle->state = UVC_HANDLE_PASSIVE;
457 file->private_data = handle;
458
459 kref_get(&stream->dev->kref);
460
461done:
462 mutex_unlock(&uvc_driver.open_mutex);
463 return ret;
464}
465
466static int uvc_v4l2_release(struct file *file)
467{
468 struct uvc_fh *handle = (struct uvc_fh *)file->private_data;
469 struct uvc_streaming *stream = handle->stream;
470
471 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_release\n");
472
473
474 if (uvc_has_privileges(handle)) {
475 uvc_video_enable(stream, 0);
476
477 mutex_lock(&stream->queue.mutex);
478 if (uvc_free_buffers(&stream->queue) < 0)
479 uvc_printk(KERN_ERR, "uvc_v4l2_release: Unable to "
480 "free buffers.\n");
481 mutex_unlock(&stream->queue.mutex);
482 }
483
484
485 uvc_dismiss_privileges(handle);
486 kfree(handle);
487 file->private_data = NULL;
488
489 if (atomic_dec_return(&stream->dev->users) == 0)
490 uvc_status_stop(stream->dev);
491
492 usb_autopm_put_interface(stream->dev->intf);
493 kref_put(&stream->dev->kref, uvc_delete);
494 return 0;
495}
496
497static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
498{
499 struct video_device *vdev = video_devdata(file);
500 struct uvc_fh *handle = (struct uvc_fh *)file->private_data;
501 struct uvc_video_chain *chain = handle->chain;
502 struct uvc_streaming *stream = handle->stream;
503 long ret = 0;
504
505 switch (cmd) {
506
507 case VIDIOC_QUERYCAP:
508 {
509 struct v4l2_capability *cap = arg;
510
511 memset(cap, 0, sizeof *cap);
512 strlcpy(cap->driver, "uvcvideo", sizeof cap->driver);
513 strlcpy(cap->card, vdev->name, sizeof cap->card);
514 usb_make_path(stream->dev->udev,
515 cap->bus_info, sizeof(cap->bus_info));
516 cap->version = DRIVER_VERSION_NUMBER;
517 if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
518 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE
519 | V4L2_CAP_STREAMING;
520 else
521 cap->capabilities = V4L2_CAP_VIDEO_OUTPUT
522 | V4L2_CAP_STREAMING;
523 break;
524 }
525
526
527 case VIDIOC_QUERYCTRL:
528 return uvc_query_v4l2_ctrl(chain, arg);
529
530 case VIDIOC_G_CTRL:
531 {
532 struct v4l2_control *ctrl = arg;
533 struct v4l2_ext_control xctrl;
534
535 memset(&xctrl, 0, sizeof xctrl);
536 xctrl.id = ctrl->id;
537
538 ret = uvc_ctrl_begin(chain);
539 if (ret < 0)
540 return ret;
541
542 ret = uvc_ctrl_get(chain, &xctrl);
543 uvc_ctrl_rollback(chain);
544 if (ret >= 0)
545 ctrl->value = xctrl.value;
546 break;
547 }
548
549 case VIDIOC_S_CTRL:
550 {
551 struct v4l2_control *ctrl = arg;
552 struct v4l2_ext_control xctrl;
553
554 memset(&xctrl, 0, sizeof xctrl);
555 xctrl.id = ctrl->id;
556 xctrl.value = ctrl->value;
557
558 uvc_ctrl_begin(chain);
559 if (ret < 0)
560 return ret;
561
562 ret = uvc_ctrl_set(chain, &xctrl);
563 if (ret < 0) {
564 uvc_ctrl_rollback(chain);
565 return ret;
566 }
567 ret = uvc_ctrl_commit(chain);
568 break;
569 }
570
571 case VIDIOC_QUERYMENU:
572 return uvc_v4l2_query_menu(chain, arg);
573
574 case VIDIOC_G_EXT_CTRLS:
575 {
576 struct v4l2_ext_controls *ctrls = arg;
577 struct v4l2_ext_control *ctrl = ctrls->controls;
578 unsigned int i;
579
580 ret = uvc_ctrl_begin(chain);
581 if (ret < 0)
582 return ret;
583
584 for (i = 0; i < ctrls->count; ++ctrl, ++i) {
585 ret = uvc_ctrl_get(chain, ctrl);
586 if (ret < 0) {
587 uvc_ctrl_rollback(chain);
588 ctrls->error_idx = i;
589 return ret;
590 }
591 }
592 ctrls->error_idx = 0;
593 ret = uvc_ctrl_rollback(chain);
594 break;
595 }
596
597 case VIDIOC_S_EXT_CTRLS:
598 case VIDIOC_TRY_EXT_CTRLS:
599 {
600 struct v4l2_ext_controls *ctrls = arg;
601 struct v4l2_ext_control *ctrl = ctrls->controls;
602 unsigned int i;
603
604 ret = uvc_ctrl_begin(chain);
605 if (ret < 0)
606 return ret;
607
608 for (i = 0; i < ctrls->count; ++ctrl, ++i) {
609 ret = uvc_ctrl_set(chain, ctrl);
610 if (ret < 0) {
611 uvc_ctrl_rollback(chain);
612 ctrls->error_idx = i;
613 return ret;
614 }
615 }
616
617 ctrls->error_idx = 0;
618
619 if (cmd == VIDIOC_S_EXT_CTRLS)
620 ret = uvc_ctrl_commit(chain);
621 else
622 ret = uvc_ctrl_rollback(chain);
623 break;
624 }
625
626
627 case VIDIOC_ENUMINPUT:
628 {
629 const struct uvc_entity *selector = chain->selector;
630 struct v4l2_input *input = arg;
631 struct uvc_entity *iterm = NULL;
632 u32 index = input->index;
633 int pin = 0;
634
635 if (selector == NULL ||
636 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
637 if (index != 0)
638 return -EINVAL;
639 iterm = list_first_entry(&chain->iterms,
640 struct uvc_entity, chain);
641 pin = iterm->id;
642 } else if (pin < selector->selector.bNrInPins) {
643 pin = selector->selector.baSourceID[index];
644 list_for_each_entry(iterm, chain->iterms.next, chain) {
645 if (iterm->id == pin)
646 break;
647 }
648 }
649
650 if (iterm == NULL || iterm->id != pin)
651 return -EINVAL;
652
653 memset(input, 0, sizeof *input);
654 input->index = index;
655 strlcpy(input->name, iterm->name, sizeof input->name);
656 if (UVC_ENTITY_TYPE(iterm) == UVC_ITT_CAMERA)
657 input->type = V4L2_INPUT_TYPE_CAMERA;
658 break;
659 }
660
661 case VIDIOC_G_INPUT:
662 {
663 u8 input;
664
665 if (chain->selector == NULL ||
666 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
667 *(int *)arg = 0;
668 break;
669 }
670
671 ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
672 chain->selector->id, chain->dev->intfnum,
673 UVC_SU_INPUT_SELECT_CONTROL, &input, 1);
674 if (ret < 0)
675 return ret;
676
677 *(int *)arg = input - 1;
678 break;
679 }
680
681 case VIDIOC_S_INPUT:
682 {
683 u32 input = *(u32 *)arg + 1;
684
685 if ((ret = uvc_acquire_privileges(handle)) < 0)
686 return ret;
687
688 if (chain->selector == NULL ||
689 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
690 if (input != 1)
691 return -EINVAL;
692 break;
693 }
694
695 if (input == 0 || input > chain->selector->selector.bNrInPins)
696 return -EINVAL;
697
698 return uvc_query_ctrl(chain->dev, UVC_SET_CUR,
699 chain->selector->id, chain->dev->intfnum,
700 UVC_SU_INPUT_SELECT_CONTROL, &input, 1);
701 }
702
703
704 case VIDIOC_ENUM_FMT:
705 {
706 struct v4l2_fmtdesc *fmt = arg;
707 struct uvc_format *format;
708 enum v4l2_buf_type type = fmt->type;
709 __u32 index = fmt->index;
710
711 if (fmt->type != stream->type ||
712 fmt->index >= stream->nformats)
713 return -EINVAL;
714
715 memset(fmt, 0, sizeof(*fmt));
716 fmt->index = index;
717 fmt->type = type;
718
719 format = &stream->format[fmt->index];
720 fmt->flags = 0;
721 if (format->flags & UVC_FMT_FLAG_COMPRESSED)
722 fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
723 strlcpy(fmt->description, format->name,
724 sizeof fmt->description);
725 fmt->description[sizeof fmt->description - 1] = 0;
726 fmt->pixelformat = format->fcc;
727 break;
728 }
729
730 case VIDIOC_TRY_FMT:
731 {
732 struct uvc_streaming_control probe;
733
734 if ((ret = uvc_acquire_privileges(handle)) < 0)
735 return ret;
736
737 return uvc_v4l2_try_format(stream, arg, &probe, NULL, NULL);
738 }
739
740 case VIDIOC_S_FMT:
741 if ((ret = uvc_acquire_privileges(handle)) < 0)
742 return ret;
743
744 return uvc_v4l2_set_format(stream, arg);
745
746 case VIDIOC_G_FMT:
747 return uvc_v4l2_get_format(stream, arg);
748
749
750 case VIDIOC_ENUM_FRAMESIZES:
751 {
752 struct v4l2_frmsizeenum *fsize = arg;
753 struct uvc_format *format = NULL;
754 struct uvc_frame *frame;
755 int i;
756
757
758 for (i = 0; i < stream->nformats; i++) {
759 if (stream->format[i].fcc ==
760 fsize->pixel_format) {
761 format = &stream->format[i];
762 break;
763 }
764 }
765 if (format == NULL)
766 return -EINVAL;
767
768 if (fsize->index >= format->nframes)
769 return -EINVAL;
770
771 frame = &format->frame[fsize->index];
772 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
773 fsize->discrete.width = frame->wWidth;
774 fsize->discrete.height = frame->wHeight;
775 break;
776 }
777
778
779 case VIDIOC_ENUM_FRAMEINTERVALS:
780 {
781 struct v4l2_frmivalenum *fival = arg;
782 struct uvc_format *format = NULL;
783 struct uvc_frame *frame = NULL;
784 int i;
785
786
787 for (i = 0; i < stream->nformats; i++) {
788 if (stream->format[i].fcc ==
789 fival->pixel_format) {
790 format = &stream->format[i];
791 break;
792 }
793 }
794 if (format == NULL)
795 return -EINVAL;
796
797 for (i = 0; i < format->nframes; i++) {
798 if (format->frame[i].wWidth == fival->width &&
799 format->frame[i].wHeight == fival->height) {
800 frame = &format->frame[i];
801 break;
802 }
803 }
804 if (frame == NULL)
805 return -EINVAL;
806
807 if (frame->bFrameIntervalType) {
808 if (fival->index >= frame->bFrameIntervalType)
809 return -EINVAL;
810
811 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
812 fival->discrete.numerator =
813 frame->dwFrameInterval[fival->index];
814 fival->discrete.denominator = 10000000;
815 uvc_simplify_fraction(&fival->discrete.numerator,
816 &fival->discrete.denominator, 8, 333);
817 } else {
818 fival->type = V4L2_FRMIVAL_TYPE_STEPWISE;
819 fival->stepwise.min.numerator =
820 frame->dwFrameInterval[0];
821 fival->stepwise.min.denominator = 10000000;
822 fival->stepwise.max.numerator =
823 frame->dwFrameInterval[1];
824 fival->stepwise.max.denominator = 10000000;
825 fival->stepwise.step.numerator =
826 frame->dwFrameInterval[2];
827 fival->stepwise.step.denominator = 10000000;
828 uvc_simplify_fraction(&fival->stepwise.min.numerator,
829 &fival->stepwise.min.denominator, 8, 333);
830 uvc_simplify_fraction(&fival->stepwise.max.numerator,
831 &fival->stepwise.max.denominator, 8, 333);
832 uvc_simplify_fraction(&fival->stepwise.step.numerator,
833 &fival->stepwise.step.denominator, 8, 333);
834 }
835 break;
836 }
837
838
839 case VIDIOC_G_PARM:
840 return uvc_v4l2_get_streamparm(stream, arg);
841
842 case VIDIOC_S_PARM:
843 if ((ret = uvc_acquire_privileges(handle)) < 0)
844 return ret;
845
846 return uvc_v4l2_set_streamparm(stream, arg);
847
848
849 case VIDIOC_CROPCAP:
850 {
851 struct v4l2_cropcap *ccap = arg;
852 struct uvc_frame *frame = stream->cur_frame;
853
854 if (ccap->type != stream->type)
855 return -EINVAL;
856
857 ccap->bounds.left = 0;
858 ccap->bounds.top = 0;
859 ccap->bounds.width = frame->wWidth;
860 ccap->bounds.height = frame->wHeight;
861
862 ccap->defrect = ccap->bounds;
863
864 ccap->pixelaspect.numerator = 1;
865 ccap->pixelaspect.denominator = 1;
866 break;
867 }
868
869 case VIDIOC_G_CROP:
870 case VIDIOC_S_CROP:
871 return -EINVAL;
872
873
874 case VIDIOC_REQBUFS:
875 {
876 struct v4l2_requestbuffers *rb = arg;
877 unsigned int bufsize =
878 stream->ctrl.dwMaxVideoFrameSize;
879
880 if (rb->type != stream->type ||
881 rb->memory != V4L2_MEMORY_MMAP)
882 return -EINVAL;
883
884 if ((ret = uvc_acquire_privileges(handle)) < 0)
885 return ret;
886
887 ret = uvc_alloc_buffers(&stream->queue, rb->count, bufsize);
888 if (ret < 0)
889 return ret;
890
891 rb->count = ret;
892 ret = 0;
893 break;
894 }
895
896 case VIDIOC_QUERYBUF:
897 {
898 struct v4l2_buffer *buf = arg;
899
900 if (buf->type != stream->type)
901 return -EINVAL;
902
903 if (!uvc_has_privileges(handle))
904 return -EBUSY;
905
906 return uvc_query_buffer(&stream->queue, buf);
907 }
908
909 case VIDIOC_QBUF:
910 if (!uvc_has_privileges(handle))
911 return -EBUSY;
912
913 return uvc_queue_buffer(&stream->queue, arg);
914
915 case VIDIOC_DQBUF:
916 if (!uvc_has_privileges(handle))
917 return -EBUSY;
918
919 return uvc_dequeue_buffer(&stream->queue, arg,
920 file->f_flags & O_NONBLOCK);
921
922 case VIDIOC_STREAMON:
923 {
924 int *type = arg;
925
926 if (*type != stream->type)
927 return -EINVAL;
928
929 if (!uvc_has_privileges(handle))
930 return -EBUSY;
931
932 ret = uvc_video_enable(stream, 1);
933 if (ret < 0)
934 return ret;
935 break;
936 }
937
938 case VIDIOC_STREAMOFF:
939 {
940 int *type = arg;
941
942 if (*type != stream->type)
943 return -EINVAL;
944
945 if (!uvc_has_privileges(handle))
946 return -EBUSY;
947
948 return uvc_video_enable(stream, 0);
949 }
950
951
952 case VIDIOC_ENUMSTD:
953 case VIDIOC_QUERYSTD:
954 case VIDIOC_G_STD:
955 case VIDIOC_S_STD:
956
957 case VIDIOC_OVERLAY:
958
959 case VIDIOC_ENUMAUDIO:
960 case VIDIOC_ENUMAUDOUT:
961
962 case VIDIOC_ENUMOUTPUT:
963 uvc_trace(UVC_TRACE_IOCTL, "Unsupported ioctl 0x%08x\n", cmd);
964 return -EINVAL;
965
966
967 case UVCIOC_CTRL_ADD:
968 {
969 struct uvc_xu_control_info *xinfo = arg;
970 struct uvc_control_info *info;
971
972 if (!capable(CAP_SYS_ADMIN))
973 return -EPERM;
974
975 info = kzalloc(sizeof *info, GFP_KERNEL);
976 if (info == NULL)
977 return -ENOMEM;
978
979 memcpy(info->entity, xinfo->entity, sizeof info->entity);
980 info->index = xinfo->index;
981 info->selector = xinfo->selector;
982 info->size = xinfo->size;
983 info->flags = xinfo->flags;
984
985 info->flags |= UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX |
986 UVC_CONTROL_GET_RES | UVC_CONTROL_GET_DEF;
987
988 ret = uvc_ctrl_add_info(info);
989 if (ret < 0)
990 kfree(info);
991 break;
992 }
993
994 case UVCIOC_CTRL_MAP:
995 {
996 struct uvc_xu_control_mapping *xmap = arg;
997 struct uvc_control_mapping *map;
998
999 if (!capable(CAP_SYS_ADMIN))
1000 return -EPERM;
1001
1002 map = kzalloc(sizeof *map, GFP_KERNEL);
1003 if (map == NULL)
1004 return -ENOMEM;
1005
1006 map->id = xmap->id;
1007 memcpy(map->name, xmap->name, sizeof map->name);
1008 memcpy(map->entity, xmap->entity, sizeof map->entity);
1009 map->selector = xmap->selector;
1010 map->size = xmap->size;
1011 map->offset = xmap->offset;
1012 map->v4l2_type = xmap->v4l2_type;
1013 map->data_type = xmap->data_type;
1014
1015 ret = uvc_ctrl_add_mapping(map);
1016 if (ret < 0)
1017 kfree(map);
1018 break;
1019 }
1020
1021 case UVCIOC_CTRL_GET:
1022 return uvc_xu_ctrl_query(chain, arg, 0);
1023
1024 case UVCIOC_CTRL_SET:
1025 return uvc_xu_ctrl_query(chain, arg, 1);
1026
1027 default:
1028 if ((ret = v4l_compat_translate_ioctl(file, cmd, arg,
1029 uvc_v4l2_do_ioctl)) == -ENOIOCTLCMD)
1030 uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n",
1031 cmd);
1032 return ret;
1033 }
1034
1035 return ret;
1036}
1037
1038static long uvc_v4l2_ioctl(struct file *file,
1039 unsigned int cmd, unsigned long arg)
1040{
1041 if (uvc_trace_param & UVC_TRACE_IOCTL) {
1042 uvc_printk(KERN_DEBUG, "uvc_v4l2_ioctl(");
1043 v4l_printk_ioctl(cmd);
1044 printk(")\n");
1045 }
1046
1047 return video_usercopy(file, cmd, arg, uvc_v4l2_do_ioctl);
1048}
1049
1050static ssize_t uvc_v4l2_read(struct file *file, char __user *data,
1051 size_t count, loff_t *ppos)
1052{
1053 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_read: not implemented.\n");
1054 return -ENODEV;
1055}
1056
1057
1058
1059
1060static void uvc_vm_open(struct vm_area_struct *vma)
1061{
1062 struct uvc_buffer *buffer = vma->vm_private_data;
1063 buffer->vma_use_count++;
1064}
1065
1066static void uvc_vm_close(struct vm_area_struct *vma)
1067{
1068 struct uvc_buffer *buffer = vma->vm_private_data;
1069 buffer->vma_use_count--;
1070}
1071
1072static const struct vm_operations_struct uvc_vm_ops = {
1073 .open = uvc_vm_open,
1074 .close = uvc_vm_close,
1075};
1076
1077static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
1078{
1079 struct uvc_fh *handle = (struct uvc_fh *)file->private_data;
1080 struct uvc_streaming *stream = handle->stream;
1081 struct uvc_video_queue *queue = &stream->queue;
1082 struct uvc_buffer *uninitialized_var(buffer);
1083 struct page *page;
1084 unsigned long addr, start, size;
1085 unsigned int i;
1086 int ret = 0;
1087
1088 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_mmap\n");
1089
1090 start = vma->vm_start;
1091 size = vma->vm_end - vma->vm_start;
1092
1093 mutex_lock(&queue->mutex);
1094
1095 for (i = 0; i < queue->count; ++i) {
1096 buffer = &queue->buffer[i];
1097 if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
1098 break;
1099 }
1100
1101 if (i == queue->count || size != queue->buf_size) {
1102 ret = -EINVAL;
1103 goto done;
1104 }
1105
1106
1107
1108
1109
1110 vma->vm_flags |= VM_IO;
1111
1112 addr = (unsigned long)queue->mem + buffer->buf.m.offset;
1113 while (size > 0) {
1114 page = vmalloc_to_page((void *)addr);
1115 if ((ret = vm_insert_page(vma, start, page)) < 0)
1116 goto done;
1117
1118 start += PAGE_SIZE;
1119 addr += PAGE_SIZE;
1120 size -= PAGE_SIZE;
1121 }
1122
1123 vma->vm_ops = &uvc_vm_ops;
1124 vma->vm_private_data = buffer;
1125 uvc_vm_open(vma);
1126
1127done:
1128 mutex_unlock(&queue->mutex);
1129 return ret;
1130}
1131
1132static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait)
1133{
1134 struct uvc_fh *handle = (struct uvc_fh *)file->private_data;
1135 struct uvc_streaming *stream = handle->stream;
1136
1137 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_poll\n");
1138
1139 return uvc_queue_poll(&stream->queue, file, wait);
1140}
1141
1142const struct v4l2_file_operations uvc_fops = {
1143 .owner = THIS_MODULE,
1144 .open = uvc_v4l2_open,
1145 .release = uvc_v4l2_release,
1146 .ioctl = uvc_v4l2_ioctl,
1147 .read = uvc_v4l2_read,
1148 .mmap = uvc_v4l2_mmap,
1149 .poll = uvc_v4l2_poll,
1150};
1151
1152