[media] uvcvideo: Return -ENOTTY for unsupported ioctls
[linux-2.6-block.git] / drivers / media / usb / uvc / uvc_v4l2.c
CommitLineData
c0efd232
LP
1/*
2 * uvc_v4l2.c -- USB Video Class driver - V4L2 API
3 *
11fc5baf
LP
4 * Copyright (C) 2005-2010
5 * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
c0efd232
LP
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 */
13
1a5e4c86 14#include <linux/compat.h>
c0efd232
LP
15#include <linux/kernel.h>
16#include <linux/version.h>
17#include <linux/list.h>
18#include <linux/module.h>
5a0e3ad6 19#include <linux/slab.h>
c0efd232
LP
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>
60063497 25#include <linux/atomic.h>
c0efd232
LP
26
27#include <media/v4l2-common.h>
b4012002
HG
28#include <media/v4l2-ctrls.h>
29#include <media/v4l2-event.h>
35ea11ff 30#include <media/v4l2-ioctl.h>
c0efd232
LP
31
32#include "uvcvideo.h"
33
561474c2
LP
34/* ------------------------------------------------------------------------
35 * UVC ioctls
36 */
ba2fa996 37static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain,
227bd5b3 38 struct uvc_xu_control_mapping *xmap)
561474c2
LP
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:
806e23e9
HC
64 /* Prevent excessive memory consumption, as well as integer
65 * overflows.
66 */
67 if (xmap->menu_count == 0 ||
68 xmap->menu_count > UVC_MAX_CONTROL_MENU_ENTRIES) {
69 ret = -EINVAL;
70 goto done;
71 }
72
561474c2
LP
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:
ba2fa996
LP
89 uvc_trace(UVC_TRACE_CONTROL, "Unsupported V4L2 control type "
90 "%u.\n", xmap->v4l2_type);
7a286cc1 91 ret = -ENOTTY;
561474c2
LP
92 goto done;
93 }
94
ba2fa996 95 ret = uvc_ctrl_add_mapping(chain, map);
561474c2
LP
96
97done:
ba2fa996
LP
98 kfree(map->menu_info);
99 kfree(map);
561474c2
LP
100
101 return ret;
102}
103
c0efd232
LP
104/* ------------------------------------------------------------------------
105 * V4L2 interface
106 */
107
c0efd232
LP
108/*
109 * Find the frame interval closest to the requested frame interval for the
110 * given frame format and size. This should be done by the device as part of
111 * the Video Probe and Commit negotiation, but some hardware don't implement
112 * that feature.
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
35f02a68 146static int uvc_v4l2_try_format(struct uvc_streaming *stream,
c0efd232
LP
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
35f02a68 159 if (fmt->type != stream->type)
c0efd232
LP
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
815adc46
LP
168 /* Check if the hardware supports the requested format, use the default
169 * format otherwise.
170 */
35f02a68
LP
171 for (i = 0; i < stream->nformats; ++i) {
172 format = &stream->format[i];
c0efd232
LP
173 if (format->fcc == fmt->fmt.pix.pixelformat)
174 break;
175 }
176
815adc46
LP
177 if (i == stream->nformats) {
178 format = stream->def_format;
179 fmt->fmt.pix.pixelformat = format->fcc;
c0efd232
LP
180 }
181
182 /* Find the closest image size. The distance between image sizes is
183 * the size in pixels of the non-overlapping regions between the
184 * requested size and the frame-specified size.
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 /* Use the default frame interval. */
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 /* Set the format index, frame index and frame interval. */
218 memset(probe, 0, sizeof *probe);
219 probe->bmHint = 1; /* dwFrameInterval */
220 probe->bFormatIndex = format->index;
221 probe->bFrameIndex = frame->bFrameIndex;
222 probe->dwFrameInterval = uvc_try_frame_interval(frame, interval);
223 /* Some webcams stall the probe control set request when the
224 * dwMaxVideoFrameSize field is set to zero. The UVC specification
225 * clearly states that the field is read-only from the host, so this
226 * is a webcam bug. Set dwMaxVideoFrameSize to the value reported by
227 * the webcam to work around the problem.
228 *
229 * The workaround could probably be enabled for all webcams, so the
230 * quirk can be removed if needed. It's currently useful to detect
231 * webcam bugs and fix them before they hit the market (providing
232 * developers test their webcams with the Linux driver as well as with
233 * the Windows driver).
234 */
6947756d 235 mutex_lock(&stream->mutex);
35f02a68 236 if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS)
c0efd232 237 probe->dwMaxVideoFrameSize =
35f02a68 238 stream->ctrl.dwMaxVideoFrameSize;
c0efd232 239
2c2d264b 240 /* Probe the device. */
35f02a68 241 ret = uvc_probe_video(stream, probe);
6947756d 242 mutex_unlock(&stream->mutex);
35f02a68 243 if (ret < 0)
c0efd232
LP
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
35f02a68 263static int uvc_v4l2_get_format(struct uvc_streaming *stream,
c0efd232
LP
264 struct v4l2_format *fmt)
265{
6947756d
LP
266 struct uvc_format *format;
267 struct uvc_frame *frame;
268 int ret = 0;
c0efd232 269
35f02a68 270 if (fmt->type != stream->type)
c0efd232
LP
271 return -EINVAL;
272
6947756d
LP
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 }
c0efd232
LP
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;
35f02a68 287 fmt->fmt.pix.sizeimage = stream->ctrl.dwMaxVideoFrameSize;
c0efd232
LP
288 fmt->fmt.pix.colorspace = format->colorspace;
289 fmt->fmt.pix.priv = 0;
290
6947756d
LP
291done:
292 mutex_unlock(&stream->mutex);
293 return ret;
c0efd232
LP
294}
295
35f02a68 296static int uvc_v4l2_set_format(struct uvc_streaming *stream,
c0efd232
LP
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
35f02a68 304 if (fmt->type != stream->type)
c0efd232
LP
305 return -EINVAL;
306
35f02a68 307 ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame);
c0efd232
LP
308 if (ret < 0)
309 return ret;
310
6947756d
LP
311 mutex_lock(&stream->mutex);
312
313 if (uvc_queue_allocated(&stream->queue)) {
314 ret = -EBUSY;
315 goto done;
316 }
317
35f02a68
LP
318 memcpy(&stream->ctrl, &probe, sizeof probe);
319 stream->cur_format = format;
320 stream->cur_frame = frame;
c0efd232 321
6947756d
LP
322done:
323 mutex_unlock(&stream->mutex);
324 return ret;
c0efd232
LP
325}
326
35f02a68 327static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream,
c0efd232
LP
328 struct v4l2_streamparm *parm)
329{
330 uint32_t numerator, denominator;
331
35f02a68 332 if (parm->type != stream->type)
c0efd232
LP
333 return -EINVAL;
334
6947756d 335 mutex_lock(&stream->mutex);
35f02a68 336 numerator = stream->ctrl.dwFrameInterval;
6947756d
LP
337 mutex_unlock(&stream->mutex);
338
c0efd232
LP
339 denominator = 10000000;
340 uvc_simplify_fraction(&numerator, &denominator, 8, 333);
341
342 memset(parm, 0, sizeof *parm);
35f02a68 343 parm->type = stream->type;
ff924203 344
35f02a68 345 if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
ff924203
LP
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 }
c0efd232
LP
358
359 return 0;
360}
361
35f02a68 362static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream,
c0efd232
LP
363 struct v4l2_streamparm *parm)
364{
c0efd232 365 struct uvc_streaming_control probe;
ff924203 366 struct v4l2_fract timeperframe;
c0efd232
LP
367 uint32_t interval;
368 int ret;
369
35f02a68 370 if (parm->type != stream->type)
c0efd232
LP
371 return -EINVAL;
372
ff924203
LP
373 if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
374 timeperframe = parm->parm.capture.timeperframe;
375 else
376 timeperframe = parm->parm.output.timeperframe;
377
ff924203
LP
378 interval = uvc_fraction_to_interval(timeperframe.numerator,
379 timeperframe.denominator);
c0efd232 380 uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n",
ff924203 381 timeperframe.numerator, timeperframe.denominator, interval);
6947756d
LP
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 memcpy(&probe, &stream->ctrl, sizeof probe);
391 probe.dwFrameInterval =
392 uvc_try_frame_interval(stream->cur_frame, interval);
c0efd232
LP
393
394 /* Probe the device with the new settings. */
35f02a68 395 ret = uvc_probe_video(stream, &probe);
6947756d
LP
396 if (ret < 0) {
397 mutex_unlock(&stream->mutex);
c0efd232 398 return ret;
6947756d 399 }
c0efd232 400
35f02a68 401 memcpy(&stream->ctrl, &probe, sizeof probe);
6947756d 402 mutex_unlock(&stream->mutex);
c0efd232
LP
403
404 /* Return the actual frame period. */
ff924203
LP
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;
c0efd232
LP
414
415 return 0;
416}
417
418/* ------------------------------------------------------------------------
419 * Privilege management
420 */
421
422/*
423 * Privilege management is the multiple-open implementation basis. The current
424 * implementation is completely transparent for the end-user and doesn't
425 * require explicit use of the VIDIOC_G_PRIORITY and VIDIOC_S_PRIORITY ioctls.
426 * Those ioctls enable finer control on the device (by making possible for a
427 * user to request exclusive access to a device), but are not mature yet.
428 * Switching to the V4L2 priority mechanism might be considered in the future
429 * if this situation changes.
430 *
431 * Each open instance of a UVC device can either be in a privileged or
432 * unprivileged state. Only a single instance can be in a privileged state at
2c2d264b 433 * a given time. Trying to perform an operation that requires privileges will
c0efd232 434 * automatically acquire the required privileges if possible, or return -EBUSY
1a969d98
LP
435 * otherwise. Privileges are dismissed when closing the instance or when
436 * freeing the video buffers using VIDIOC_REQBUFS.
c0efd232 437 *
2c2d264b 438 * Operations that require privileges are:
c0efd232
LP
439 *
440 * - VIDIOC_S_INPUT
441 * - VIDIOC_S_PARM
442 * - VIDIOC_S_FMT
c0efd232
LP
443 * - VIDIOC_REQBUFS
444 */
445static int uvc_acquire_privileges(struct uvc_fh *handle)
446{
c0efd232
LP
447 /* Always succeed if the handle is already privileged. */
448 if (handle->state == UVC_HANDLE_ACTIVE)
449 return 0;
450
451 /* Check if the device already has a privileged handle. */
35f02a68
LP
452 if (atomic_inc_return(&handle->stream->active) != 1) {
453 atomic_dec(&handle->stream->active);
716fdee1 454 return -EBUSY;
c0efd232
LP
455 }
456
457 handle->state = UVC_HANDLE_ACTIVE;
716fdee1 458 return 0;
c0efd232
LP
459}
460
461static void uvc_dismiss_privileges(struct uvc_fh *handle)
462{
463 if (handle->state == UVC_HANDLE_ACTIVE)
35f02a68 464 atomic_dec(&handle->stream->active);
c0efd232
LP
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 * V4L2 file operations
476 */
477
bec43661 478static int uvc_v4l2_open(struct file *file)
c0efd232 479{
35f02a68 480 struct uvc_streaming *stream;
c0efd232
LP
481 struct uvc_fh *handle;
482 int ret = 0;
483
484 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_open\n");
35f02a68 485 stream = video_drvdata(file);
c0efd232 486
716fdee1
LP
487 if (stream->dev->state & UVC_DEV_DISCONNECTED)
488 return -ENODEV;
c0efd232 489
35f02a68 490 ret = usb_autopm_get_interface(stream->dev->intf);
c0efd232 491 if (ret < 0)
716fdee1 492 return ret;
c0efd232
LP
493
494 /* Create the device handle. */
495 handle = kzalloc(sizeof *handle, GFP_KERNEL);
496 if (handle == NULL) {
35f02a68 497 usb_autopm_put_interface(stream->dev->intf);
716fdee1 498 return -ENOMEM;
c0efd232
LP
499 }
500
35f02a68
LP
501 if (atomic_inc_return(&stream->dev->users) == 1) {
502 ret = uvc_status_start(stream->dev);
503 if (ret < 0) {
504 usb_autopm_put_interface(stream->dev->intf);
505 atomic_dec(&stream->dev->users);
04a37e0f 506 kfree(handle);
716fdee1 507 return ret;
04a37e0f
LP
508 }
509 }
510
b4012002
HG
511 v4l2_fh_init(&handle->vfh, stream->vdev);
512 v4l2_fh_add(&handle->vfh);
8e113595 513 handle->chain = stream->chain;
35f02a68 514 handle->stream = stream;
c0efd232
LP
515 handle->state = UVC_HANDLE_PASSIVE;
516 file->private_data = handle;
517
716fdee1 518 return 0;
c0efd232
LP
519}
520
bec43661 521static int uvc_v4l2_release(struct file *file)
c0efd232 522{
abf84383 523 struct uvc_fh *handle = file->private_data;
35f02a68 524 struct uvc_streaming *stream = handle->stream;
c0efd232
LP
525
526 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_release\n");
527
528 /* Only free resources if this is a privileged handle. */
529 if (uvc_has_privileges(handle)) {
35f02a68 530 uvc_video_enable(stream, 0);
6998b6fb 531 uvc_free_buffers(&stream->queue);
c0efd232
LP
532 }
533
534 /* Release the file handle. */
535 uvc_dismiss_privileges(handle);
b4012002
HG
536 v4l2_fh_del(&handle->vfh);
537 v4l2_fh_exit(&handle->vfh);
c0efd232
LP
538 kfree(handle);
539 file->private_data = NULL;
540
35f02a68
LP
541 if (atomic_dec_return(&stream->dev->users) == 0)
542 uvc_status_stop(stream->dev);
04a37e0f 543
35f02a68 544 usb_autopm_put_interface(stream->dev->intf);
c0efd232
LP
545 return 0;
546}
547
069b7479 548static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
c0efd232
LP
549{
550 struct video_device *vdev = video_devdata(file);
abf84383 551 struct uvc_fh *handle = file->private_data;
8e113595 552 struct uvc_video_chain *chain = handle->chain;
35f02a68 553 struct uvc_streaming *stream = handle->stream;
069b7479 554 long ret = 0;
c0efd232 555
c0efd232
LP
556 switch (cmd) {
557 /* Query capabilities */
558 case VIDIOC_QUERYCAP:
559 {
560 struct v4l2_capability *cap = arg;
561
562 memset(cap, 0, sizeof *cap);
d0ebf307
LP
563 strlcpy(cap->driver, "uvcvideo", sizeof cap->driver);
564 strlcpy(cap->card, vdev->name, sizeof cap->card);
35f02a68 565 usb_make_path(stream->dev->udev,
b12049a2 566 cap->bus_info, sizeof(cap->bus_info));
fd3e5824 567 cap->version = LINUX_VERSION_CODE;
f887e99a
LP
568 cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING
569 | chain->caps;
35f02a68 570 if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
f887e99a
LP
571 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE
572 | V4L2_CAP_STREAMING;
ff924203 573 else
f887e99a
LP
574 cap->device_caps = V4L2_CAP_VIDEO_OUTPUT
575 | V4L2_CAP_STREAMING;
c0efd232
LP
576 break;
577 }
578
579 /* Get, Set & Query control */
580 case VIDIOC_QUERYCTRL:
8e113595 581 return uvc_query_v4l2_ctrl(chain, arg);
c0efd232
LP
582
583 case VIDIOC_G_CTRL:
584 {
585 struct v4l2_control *ctrl = arg;
586 struct v4l2_ext_control xctrl;
587
588 memset(&xctrl, 0, sizeof xctrl);
589 xctrl.id = ctrl->id;
590
8e113595
LP
591 ret = uvc_ctrl_begin(chain);
592 if (ret < 0)
1fcbcc47
RK
593 return ret;
594
8e113595 595 ret = uvc_ctrl_get(chain, &xctrl);
b4012002 596 uvc_ctrl_rollback(handle);
f0ed2ce8
LP
597 if (ret < 0)
598 return ret == -ENOENT ? -EINVAL : ret;
599
600 ctrl->value = xctrl.value;
c0efd232
LP
601 break;
602 }
603
604 case VIDIOC_S_CTRL:
605 {
606 struct v4l2_control *ctrl = arg;
607 struct v4l2_ext_control xctrl;
608
609 memset(&xctrl, 0, sizeof xctrl);
610 xctrl.id = ctrl->id;
611 xctrl.value = ctrl->value;
612
8d556625 613 ret = uvc_ctrl_begin(chain);
8e113595 614 if (ret < 0)
1fcbcc47
RK
615 return ret;
616
8e113595 617 ret = uvc_ctrl_set(chain, &xctrl);
c0efd232 618 if (ret < 0) {
b4012002 619 uvc_ctrl_rollback(handle);
f0ed2ce8 620 return ret == -ENOENT ? -EINVAL : ret;
c0efd232 621 }
b4012002 622 ret = uvc_ctrl_commit(handle, &xctrl, 1);
e54532e5
LP
623 if (ret == 0)
624 ctrl->value = xctrl.value;
c0efd232
LP
625 break;
626 }
627
628 case VIDIOC_QUERYMENU:
23d9f3ef 629 return uvc_query_v4l2_menu(chain, arg);
c0efd232
LP
630
631 case VIDIOC_G_EXT_CTRLS:
632 {
633 struct v4l2_ext_controls *ctrls = arg;
634 struct v4l2_ext_control *ctrl = ctrls->controls;
635 unsigned int i;
636
8e113595
LP
637 ret = uvc_ctrl_begin(chain);
638 if (ret < 0)
1fcbcc47
RK
639 return ret;
640
c0efd232 641 for (i = 0; i < ctrls->count; ++ctrl, ++i) {
8e113595 642 ret = uvc_ctrl_get(chain, ctrl);
c0efd232 643 if (ret < 0) {
b4012002 644 uvc_ctrl_rollback(handle);
f0ed2ce8
LP
645 ctrls->error_idx = ret == -ENOENT
646 ? ctrls->count : i;
647 return ret == -ENOENT ? -EINVAL : ret;
c0efd232
LP
648 }
649 }
650 ctrls->error_idx = 0;
b4012002 651 ret = uvc_ctrl_rollback(handle);
c0efd232
LP
652 break;
653 }
654
655 case VIDIOC_S_EXT_CTRLS:
656 case VIDIOC_TRY_EXT_CTRLS:
657 {
658 struct v4l2_ext_controls *ctrls = arg;
659 struct v4l2_ext_control *ctrl = ctrls->controls;
660 unsigned int i;
661
8e113595 662 ret = uvc_ctrl_begin(chain);
c0efd232
LP
663 if (ret < 0)
664 return ret;
665
666 for (i = 0; i < ctrls->count; ++ctrl, ++i) {
8e113595 667 ret = uvc_ctrl_set(chain, ctrl);
c0efd232 668 if (ret < 0) {
b4012002 669 uvc_ctrl_rollback(handle);
f0ed2ce8
LP
670 ctrls->error_idx = (ret == -ENOENT &&
671 cmd == VIDIOC_S_EXT_CTRLS)
672 ? ctrls->count : i;
673 return ret == -ENOENT ? -EINVAL : ret;
c0efd232
LP
674 }
675 }
676
677 ctrls->error_idx = 0;
678
679 if (cmd == VIDIOC_S_EXT_CTRLS)
b4012002
HG
680 ret = uvc_ctrl_commit(handle,
681 ctrls->controls, ctrls->count);
c0efd232 682 else
b4012002 683 ret = uvc_ctrl_rollback(handle);
c0efd232
LP
684 break;
685 }
686
687 /* Get, Set & Enum input */
688 case VIDIOC_ENUMINPUT:
689 {
8e113595 690 const struct uvc_entity *selector = chain->selector;
c0efd232
LP
691 struct v4l2_input *input = arg;
692 struct uvc_entity *iterm = NULL;
693 u32 index = input->index;
694 int pin = 0;
695
696 if (selector == NULL ||
8e113595 697 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
c0efd232
LP
698 if (index != 0)
699 return -EINVAL;
6241d8ca
LP
700 list_for_each_entry(iterm, &chain->entities, chain) {
701 if (UVC_ENTITY_IS_ITERM(iterm))
702 break;
703 }
c0efd232 704 pin = iterm->id;
31c5f0c5 705 } else if (index < selector->bNrInPins) {
8ca5a639 706 pin = selector->baSourceID[index];
6241d8ca
LP
707 list_for_each_entry(iterm, &chain->entities, chain) {
708 if (!UVC_ENTITY_IS_ITERM(iterm))
709 continue;
c0efd232
LP
710 if (iterm->id == pin)
711 break;
712 }
713 }
714
715 if (iterm == NULL || iterm->id != pin)
716 return -EINVAL;
717
718 memset(input, 0, sizeof *input);
719 input->index = index;
d0ebf307 720 strlcpy(input->name, iterm->name, sizeof input->name);
b482d923 721 if (UVC_ENTITY_TYPE(iterm) == UVC_ITT_CAMERA)
c0efd232
LP
722 input->type = V4L2_INPUT_TYPE_CAMERA;
723 break;
724 }
725
726 case VIDIOC_G_INPUT:
727 {
728 u8 input;
729
8e113595
LP
730 if (chain->selector == NULL ||
731 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
c0efd232
LP
732 *(int *)arg = 0;
733 break;
734 }
735
8e113595
LP
736 ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
737 chain->selector->id, chain->dev->intfnum,
b482d923 738 UVC_SU_INPUT_SELECT_CONTROL, &input, 1);
c0efd232
LP
739 if (ret < 0)
740 return ret;
741
742 *(int *)arg = input - 1;
743 break;
744 }
745
746 case VIDIOC_S_INPUT:
747 {
9086c7b9 748 u32 input = *(u32 *)arg + 1;
c0efd232
LP
749
750 if ((ret = uvc_acquire_privileges(handle)) < 0)
751 return ret;
752
8e113595
LP
753 if (chain->selector == NULL ||
754 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
c0efd232
LP
755 if (input != 1)
756 return -EINVAL;
757 break;
758 }
759
8ca5a639 760 if (input == 0 || input > chain->selector->bNrInPins)
c0efd232
LP
761 return -EINVAL;
762
8e113595
LP
763 return uvc_query_ctrl(chain->dev, UVC_SET_CUR,
764 chain->selector->id, chain->dev->intfnum,
b482d923 765 UVC_SU_INPUT_SELECT_CONTROL, &input, 1);
c0efd232
LP
766 }
767
768 /* Try, Get, Set & Enum format */
769 case VIDIOC_ENUM_FMT:
770 {
771 struct v4l2_fmtdesc *fmt = arg;
772 struct uvc_format *format;
8bbd90ce
MN
773 enum v4l2_buf_type type = fmt->type;
774 __u32 index = fmt->index;
c0efd232 775
35f02a68
LP
776 if (fmt->type != stream->type ||
777 fmt->index >= stream->nformats)
c0efd232
LP
778 return -EINVAL;
779
8bbd90ce
MN
780 memset(fmt, 0, sizeof(*fmt));
781 fmt->index = index;
782 fmt->type = type;
783
35f02a68 784 format = &stream->format[fmt->index];
c0efd232
LP
785 fmt->flags = 0;
786 if (format->flags & UVC_FMT_FLAG_COMPRESSED)
787 fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
d0ebf307 788 strlcpy(fmt->description, format->name,
c0efd232
LP
789 sizeof fmt->description);
790 fmt->description[sizeof fmt->description - 1] = 0;
791 fmt->pixelformat = format->fcc;
792 break;
793 }
794
795 case VIDIOC_TRY_FMT:
796 {
797 struct uvc_streaming_control probe;
798
35f02a68 799 return uvc_v4l2_try_format(stream, arg, &probe, NULL, NULL);
c0efd232
LP
800 }
801
802 case VIDIOC_S_FMT:
803 if ((ret = uvc_acquire_privileges(handle)) < 0)
804 return ret;
805
35f02a68 806 return uvc_v4l2_set_format(stream, arg);
c0efd232
LP
807
808 case VIDIOC_G_FMT:
35f02a68 809 return uvc_v4l2_get_format(stream, arg);
c0efd232
LP
810
811 /* Frame size enumeration */
812 case VIDIOC_ENUM_FRAMESIZES:
813 {
814 struct v4l2_frmsizeenum *fsize = arg;
815 struct uvc_format *format = NULL;
816 struct uvc_frame *frame;
817 int i;
818
819 /* Look for the given pixel format */
35f02a68
LP
820 for (i = 0; i < stream->nformats; i++) {
821 if (stream->format[i].fcc ==
c0efd232 822 fsize->pixel_format) {
35f02a68 823 format = &stream->format[i];
c0efd232
LP
824 break;
825 }
826 }
827 if (format == NULL)
828 return -EINVAL;
829
830 if (fsize->index >= format->nframes)
831 return -EINVAL;
832
833 frame = &format->frame[fsize->index];
834 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
835 fsize->discrete.width = frame->wWidth;
836 fsize->discrete.height = frame->wHeight;
837 break;
838 }
839
840 /* Frame interval enumeration */
841 case VIDIOC_ENUM_FRAMEINTERVALS:
842 {
843 struct v4l2_frmivalenum *fival = arg;
844 struct uvc_format *format = NULL;
845 struct uvc_frame *frame = NULL;
846 int i;
847
848 /* Look for the given pixel format and frame size */
35f02a68
LP
849 for (i = 0; i < stream->nformats; i++) {
850 if (stream->format[i].fcc ==
c0efd232 851 fival->pixel_format) {
35f02a68 852 format = &stream->format[i];
c0efd232
LP
853 break;
854 }
855 }
856 if (format == NULL)
857 return -EINVAL;
858
859 for (i = 0; i < format->nframes; i++) {
860 if (format->frame[i].wWidth == fival->width &&
861 format->frame[i].wHeight == fival->height) {
862 frame = &format->frame[i];
863 break;
864 }
865 }
866 if (frame == NULL)
867 return -EINVAL;
868
869 if (frame->bFrameIntervalType) {
870 if (fival->index >= frame->bFrameIntervalType)
871 return -EINVAL;
872
873 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
874 fival->discrete.numerator =
875 frame->dwFrameInterval[fival->index];
876 fival->discrete.denominator = 10000000;
877 uvc_simplify_fraction(&fival->discrete.numerator,
878 &fival->discrete.denominator, 8, 333);
879 } else {
880 fival->type = V4L2_FRMIVAL_TYPE_STEPWISE;
881 fival->stepwise.min.numerator =
882 frame->dwFrameInterval[0];
883 fival->stepwise.min.denominator = 10000000;
884 fival->stepwise.max.numerator =
885 frame->dwFrameInterval[1];
886 fival->stepwise.max.denominator = 10000000;
887 fival->stepwise.step.numerator =
888 frame->dwFrameInterval[2];
889 fival->stepwise.step.denominator = 10000000;
890 uvc_simplify_fraction(&fival->stepwise.min.numerator,
891 &fival->stepwise.min.denominator, 8, 333);
892 uvc_simplify_fraction(&fival->stepwise.max.numerator,
893 &fival->stepwise.max.denominator, 8, 333);
894 uvc_simplify_fraction(&fival->stepwise.step.numerator,
895 &fival->stepwise.step.denominator, 8, 333);
896 }
897 break;
898 }
899
900 /* Get & Set streaming parameters */
901 case VIDIOC_G_PARM:
35f02a68 902 return uvc_v4l2_get_streamparm(stream, arg);
c0efd232
LP
903
904 case VIDIOC_S_PARM:
905 if ((ret = uvc_acquire_privileges(handle)) < 0)
906 return ret;
907
35f02a68 908 return uvc_v4l2_set_streamparm(stream, arg);
c0efd232
LP
909
910 /* Cropping and scaling */
911 case VIDIOC_CROPCAP:
912 {
913 struct v4l2_cropcap *ccap = arg;
c0efd232 914
35f02a68 915 if (ccap->type != stream->type)
c0efd232
LP
916 return -EINVAL;
917
918 ccap->bounds.left = 0;
919 ccap->bounds.top = 0;
6947756d
LP
920
921 mutex_lock(&stream->mutex);
922 ccap->bounds.width = stream->cur_frame->wWidth;
923 ccap->bounds.height = stream->cur_frame->wHeight;
924 mutex_unlock(&stream->mutex);
c0efd232
LP
925
926 ccap->defrect = ccap->bounds;
927
928 ccap->pixelaspect.numerator = 1;
929 ccap->pixelaspect.denominator = 1;
930 break;
931 }
932
933 case VIDIOC_G_CROP:
934 case VIDIOC_S_CROP:
69d11262 935 return -ENOTTY;
c0efd232
LP
936
937 /* Buffers & streaming */
938 case VIDIOC_REQBUFS:
c0efd232
LP
939 if ((ret = uvc_acquire_privileges(handle)) < 0)
940 return ret;
941
6947756d 942 mutex_lock(&stream->mutex);
6998b6fb 943 ret = uvc_alloc_buffers(&stream->queue, arg);
6947756d 944 mutex_unlock(&stream->mutex);
c0efd232
LP
945 if (ret < 0)
946 return ret;
947
1a969d98
LP
948 if (ret == 0)
949 uvc_dismiss_privileges(handle);
950
c0efd232
LP
951 ret = 0;
952 break;
c0efd232
LP
953
954 case VIDIOC_QUERYBUF:
955 {
956 struct v4l2_buffer *buf = arg;
957
c0efd232
LP
958 if (!uvc_has_privileges(handle))
959 return -EBUSY;
960
35f02a68 961 return uvc_query_buffer(&stream->queue, buf);
c0efd232
LP
962 }
963
964 case VIDIOC_QBUF:
965 if (!uvc_has_privileges(handle))
966 return -EBUSY;
967
35f02a68 968 return uvc_queue_buffer(&stream->queue, arg);
c0efd232
LP
969
970 case VIDIOC_DQBUF:
971 if (!uvc_has_privileges(handle))
972 return -EBUSY;
973
35f02a68 974 return uvc_dequeue_buffer(&stream->queue, arg,
c0efd232
LP
975 file->f_flags & O_NONBLOCK);
976
977 case VIDIOC_STREAMON:
978 {
979 int *type = arg;
980
35f02a68 981 if (*type != stream->type)
c0efd232
LP
982 return -EINVAL;
983
984 if (!uvc_has_privileges(handle))
985 return -EBUSY;
986
6947756d 987 mutex_lock(&stream->mutex);
35f02a68 988 ret = uvc_video_enable(stream, 1);
6947756d 989 mutex_unlock(&stream->mutex);
35f02a68 990 if (ret < 0)
c0efd232
LP
991 return ret;
992 break;
993 }
994
995 case VIDIOC_STREAMOFF:
996 {
997 int *type = arg;
998
35f02a68 999 if (*type != stream->type)
c0efd232
LP
1000 return -EINVAL;
1001
1002 if (!uvc_has_privileges(handle))
1003 return -EBUSY;
1004
35f02a68 1005 return uvc_video_enable(stream, 0);
c0efd232
LP
1006 }
1007
b4012002
HG
1008 case VIDIOC_SUBSCRIBE_EVENT:
1009 {
1010 struct v4l2_event_subscription *sub = arg;
1011
1012 switch (sub->type) {
1013 case V4L2_EVENT_CTRL:
1014 return v4l2_event_subscribe(&handle->vfh, sub, 0,
1015 &uvc_ctrl_sub_ev_ops);
1016 default:
1017 return -EINVAL;
1018 }
1019 }
1020
1021 case VIDIOC_UNSUBSCRIBE_EVENT:
1022 return v4l2_event_unsubscribe(&handle->vfh, arg);
1023
1024 case VIDIOC_DQEVENT:
1025 return v4l2_event_dequeue(&handle->vfh, arg,
1026 file->f_flags & O_NONBLOCK);
1027
c0efd232
LP
1028 /* Analog video standards make no sense for digital cameras. */
1029 case VIDIOC_ENUMSTD:
1030 case VIDIOC_QUERYSTD:
1031 case VIDIOC_G_STD:
1032 case VIDIOC_S_STD:
1033
1034 case VIDIOC_OVERLAY:
1035
1036 case VIDIOC_ENUMAUDIO:
1037 case VIDIOC_ENUMAUDOUT:
1038
1039 case VIDIOC_ENUMOUTPUT:
1040 uvc_trace(UVC_TRACE_IOCTL, "Unsupported ioctl 0x%08x\n", cmd);
69d11262 1041 return -ENOTTY;
c0efd232 1042
c0efd232 1043 case UVCIOC_CTRL_MAP:
227bd5b3 1044 return uvc_ioctl_ctrl_map(chain, arg);
fe78d187
MR
1045
1046 case UVCIOC_CTRL_QUERY:
1047 return uvc_xu_ctrl_query(chain, arg);
c0efd232
LP
1048
1049 default:
08af245d 1050 uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n", cmd);
a3ec69b7 1051 return -ENOTTY;
c0efd232
LP
1052 }
1053
1054 return ret;
1055}
1056
069b7479 1057static long uvc_v4l2_ioctl(struct file *file,
c0efd232
LP
1058 unsigned int cmd, unsigned long arg)
1059{
308bb52c
LP
1060 if (uvc_trace_param & UVC_TRACE_IOCTL) {
1061 uvc_printk(KERN_DEBUG, "uvc_v4l2_ioctl(");
4a085168 1062 v4l_printk_ioctl(NULL, cmd);
308bb52c
LP
1063 printk(")\n");
1064 }
1065
f473bf76 1066 return video_usercopy(file, cmd, arg, uvc_v4l2_do_ioctl);
c0efd232
LP
1067}
1068
1a5e4c86
LP
1069#ifdef CONFIG_COMPAT
1070struct uvc_xu_control_mapping32 {
1071 __u32 id;
1072 __u8 name[32];
1073 __u8 entity[16];
1074 __u8 selector;
1075
1076 __u8 size;
1077 __u8 offset;
1078 __u32 v4l2_type;
1079 __u32 data_type;
1080
1081 compat_caddr_t menu_info;
1082 __u32 menu_count;
1083
1084 __u32 reserved[4];
1085};
1086
1087static int uvc_v4l2_get_xu_mapping(struct uvc_xu_control_mapping *kp,
1088 const struct uvc_xu_control_mapping32 __user *up)
1089{
1090 struct uvc_menu_info __user *umenus;
1091 struct uvc_menu_info __user *kmenus;
1092 compat_caddr_t p;
1093
1094 if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
1095 __copy_from_user(kp, up, offsetof(typeof(*up), menu_info)) ||
1096 __get_user(kp->menu_count, &up->menu_count))
1097 return -EFAULT;
1098
1099 memset(kp->reserved, 0, sizeof(kp->reserved));
1100
1101 if (kp->menu_count == 0) {
1102 kp->menu_info = NULL;
1103 return 0;
1104 }
1105
1106 if (__get_user(p, &up->menu_info))
1107 return -EFAULT;
1108 umenus = compat_ptr(p);
1109 if (!access_ok(VERIFY_READ, umenus, kp->menu_count * sizeof(*umenus)))
1110 return -EFAULT;
1111
1112 kmenus = compat_alloc_user_space(kp->menu_count * sizeof(*kmenus));
1113 if (kmenus == NULL)
1114 return -EFAULT;
1115 kp->menu_info = kmenus;
1116
1117 if (copy_in_user(kmenus, umenus, kp->menu_count * sizeof(*umenus)))
1118 return -EFAULT;
1119
1120 return 0;
1121}
1122
1123static int uvc_v4l2_put_xu_mapping(const struct uvc_xu_control_mapping *kp,
1124 struct uvc_xu_control_mapping32 __user *up)
1125{
1126 struct uvc_menu_info __user *umenus;
1127 struct uvc_menu_info __user *kmenus = kp->menu_info;
1128 compat_caddr_t p;
1129
1130 if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
1131 __copy_to_user(up, kp, offsetof(typeof(*up), menu_info)) ||
1132 __put_user(kp->menu_count, &up->menu_count))
1133 return -EFAULT;
1134
57fb4a48
HG
1135 if (__clear_user(up->reserved, sizeof(up->reserved)))
1136 return -EFAULT;
1a5e4c86
LP
1137
1138 if (kp->menu_count == 0)
1139 return 0;
1140
1141 if (get_user(p, &up->menu_info))
1142 return -EFAULT;
1143 umenus = compat_ptr(p);
1a5e4c86
LP
1144
1145 if (copy_in_user(umenus, kmenus, kp->menu_count * sizeof(*umenus)))
1146 return -EFAULT;
1147
1148 return 0;
1149}
1150
1151struct uvc_xu_control_query32 {
1152 __u8 unit;
1153 __u8 selector;
1154 __u8 query;
1155 __u16 size;
1156 compat_caddr_t data;
1157};
1158
1159static int uvc_v4l2_get_xu_query(struct uvc_xu_control_query *kp,
1160 const struct uvc_xu_control_query32 __user *up)
1161{
1162 u8 __user *udata;
1163 u8 __user *kdata;
1164 compat_caddr_t p;
1165
1166 if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
1167 __copy_from_user(kp, up, offsetof(typeof(*up), data)))
1168 return -EFAULT;
1169
1170 if (kp->size == 0) {
1171 kp->data = NULL;
1172 return 0;
1173 }
1174
1175 if (__get_user(p, &up->data))
1176 return -EFAULT;
1177 udata = compat_ptr(p);
1178 if (!access_ok(VERIFY_READ, udata, kp->size))
1179 return -EFAULT;
1180
1181 kdata = compat_alloc_user_space(kp->size);
1182 if (kdata == NULL)
1183 return -EFAULT;
1184 kp->data = kdata;
1185
1186 if (copy_in_user(kdata, udata, kp->size))
1187 return -EFAULT;
1188
1189 return 0;
1190}
1191
1192static int uvc_v4l2_put_xu_query(const struct uvc_xu_control_query *kp,
1193 struct uvc_xu_control_query32 __user *up)
1194{
1195 u8 __user *udata;
1196 u8 __user *kdata = kp->data;
1197 compat_caddr_t p;
1198
1199 if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
1200 __copy_to_user(up, kp, offsetof(typeof(*up), data)))
1201 return -EFAULT;
1202
1203 if (kp->size == 0)
1204 return 0;
1205
1206 if (get_user(p, &up->data))
1207 return -EFAULT;
1208 udata = compat_ptr(p);
1209 if (!access_ok(VERIFY_READ, udata, kp->size))
1210 return -EFAULT;
1211
1212 if (copy_in_user(udata, kdata, kp->size))
1213 return -EFAULT;
1214
1215 return 0;
1216}
1217
1218#define UVCIOC_CTRL_MAP32 _IOWR('u', 0x20, struct uvc_xu_control_mapping32)
1219#define UVCIOC_CTRL_QUERY32 _IOWR('u', 0x21, struct uvc_xu_control_query32)
1220
1221static long uvc_v4l2_compat_ioctl32(struct file *file,
1222 unsigned int cmd, unsigned long arg)
1223{
1224 union {
1225 struct uvc_xu_control_mapping xmap;
1226 struct uvc_xu_control_query xqry;
1227 } karg;
1228 void __user *up = compat_ptr(arg);
1229 mm_segment_t old_fs;
1230 long ret;
1231
1232 switch (cmd) {
1233 case UVCIOC_CTRL_MAP32:
1234 cmd = UVCIOC_CTRL_MAP;
1235 ret = uvc_v4l2_get_xu_mapping(&karg.xmap, up);
1236 break;
1237
1238 case UVCIOC_CTRL_QUERY32:
1239 cmd = UVCIOC_CTRL_QUERY;
1240 ret = uvc_v4l2_get_xu_query(&karg.xqry, up);
1241 break;
1242
1243 default:
1244 return -ENOIOCTLCMD;
1245 }
1246
1247 old_fs = get_fs();
1248 set_fs(KERNEL_DS);
1249 ret = uvc_v4l2_ioctl(file, cmd, (unsigned long)&karg);
1250 set_fs(old_fs);
1251
1252 if (ret < 0)
1253 return ret;
1254
1255 switch (cmd) {
1256 case UVCIOC_CTRL_MAP:
1257 ret = uvc_v4l2_put_xu_mapping(&karg.xmap, up);
1258 break;
1259
1260 case UVCIOC_CTRL_QUERY:
1261 ret = uvc_v4l2_put_xu_query(&karg.xqry, up);
1262 break;
1263 }
1264
1265 return ret;
1266}
1267#endif
1268
c0efd232
LP
1269static ssize_t uvc_v4l2_read(struct file *file, char __user *data,
1270 size_t count, loff_t *ppos)
1271{
1272 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_read: not implemented.\n");
350d6407 1273 return -EINVAL;
c0efd232
LP
1274}
1275
c0efd232
LP
1276static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
1277{
abf84383 1278 struct uvc_fh *handle = file->private_data;
35f02a68 1279 struct uvc_streaming *stream = handle->stream;
c0efd232
LP
1280
1281 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_mmap\n");
1282
4aa27597 1283 return uvc_queue_mmap(&stream->queue, vma);
c0efd232
LP
1284}
1285
1286static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait)
1287{
abf84383 1288 struct uvc_fh *handle = file->private_data;
35f02a68 1289 struct uvc_streaming *stream = handle->stream;
c0efd232
LP
1290
1291 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_poll\n");
1292
35f02a68 1293 return uvc_queue_poll(&stream->queue, file, wait);
c0efd232
LP
1294}
1295
72969447
BL
1296#ifndef CONFIG_MMU
1297static unsigned long uvc_v4l2_get_unmapped_area(struct file *file,
1298 unsigned long addr, unsigned long len, unsigned long pgoff,
1299 unsigned long flags)
1300{
1301 struct uvc_fh *handle = file->private_data;
1302 struct uvc_streaming *stream = handle->stream;
1303
1304 uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_get_unmapped_area\n");
1305
1306 return uvc_queue_get_unmapped_area(&stream->queue, pgoff);
1307}
1308#endif
1309
bec43661 1310const struct v4l2_file_operations uvc_fops = {
c0efd232
LP
1311 .owner = THIS_MODULE,
1312 .open = uvc_v4l2_open,
1313 .release = uvc_v4l2_release,
673eb9ff 1314 .unlocked_ioctl = uvc_v4l2_ioctl,
1a5e4c86
LP
1315#ifdef CONFIG_COMPAT
1316 .compat_ioctl32 = uvc_v4l2_compat_ioctl32,
1317#endif
c0efd232
LP
1318 .read = uvc_v4l2_read,
1319 .mmap = uvc_v4l2_mmap,
1320 .poll = uvc_v4l2_poll,
72969447
BL
1321#ifndef CONFIG_MMU
1322 .get_unmapped_area = uvc_v4l2_get_unmapped_area,
1323#endif
c0efd232 1324};
f87086e3 1325