Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *      uvc_v4l2.c  --  USB Video Class driver - V4L2 API
0004  *
0005  *      Copyright (C) 2005-2010
0006  *          Laurent Pinchart (laurent.pinchart@ideasonboard.com)
0007  */
0008 
0009 #include <linux/compat.h>
0010 #include <linux/kernel.h>
0011 #include <linux/list.h>
0012 #include <linux/module.h>
0013 #include <linux/slab.h>
0014 #include <linux/usb.h>
0015 #include <linux/videodev2.h>
0016 #include <linux/vmalloc.h>
0017 #include <linux/mm.h>
0018 #include <linux/wait.h>
0019 #include <linux/atomic.h>
0020 
0021 #include <media/v4l2-common.h>
0022 #include <media/v4l2-ctrls.h>
0023 #include <media/v4l2-event.h>
0024 #include <media/v4l2-ioctl.h>
0025 
0026 #include "uvcvideo.h"
0027 
0028 /* ------------------------------------------------------------------------
0029  * UVC ioctls
0030  */
0031 static int uvc_ioctl_ctrl_map(struct uvc_video_chain *chain,
0032     struct uvc_xu_control_mapping *xmap)
0033 {
0034     struct uvc_control_mapping *map;
0035     unsigned int size;
0036     int ret;
0037 
0038     map = kzalloc(sizeof(*map), GFP_KERNEL);
0039     if (map == NULL)
0040         return -ENOMEM;
0041 
0042     map->id = xmap->id;
0043     /* Non standard control id. */
0044     if (v4l2_ctrl_get_name(map->id) == NULL) {
0045         if (xmap->name[0] == '\0') {
0046             ret = -EINVAL;
0047             goto free_map;
0048         }
0049         xmap->name[sizeof(xmap->name) - 1] = '\0';
0050         map->name = xmap->name;
0051     }
0052     memcpy(map->entity, xmap->entity, sizeof(map->entity));
0053     map->selector = xmap->selector;
0054     map->size = xmap->size;
0055     map->offset = xmap->offset;
0056     map->v4l2_type = xmap->v4l2_type;
0057     map->data_type = xmap->data_type;
0058 
0059     switch (xmap->v4l2_type) {
0060     case V4L2_CTRL_TYPE_INTEGER:
0061     case V4L2_CTRL_TYPE_BOOLEAN:
0062     case V4L2_CTRL_TYPE_BUTTON:
0063         break;
0064 
0065     case V4L2_CTRL_TYPE_MENU:
0066         /*
0067          * Prevent excessive memory consumption, as well as integer
0068          * overflows.
0069          */
0070         if (xmap->menu_count == 0 ||
0071             xmap->menu_count > UVC_MAX_CONTROL_MENU_ENTRIES) {
0072             ret = -EINVAL;
0073             goto free_map;
0074         }
0075 
0076         size = xmap->menu_count * sizeof(*map->menu_info);
0077         map->menu_info = memdup_user(xmap->menu_info, size);
0078         if (IS_ERR(map->menu_info)) {
0079             ret = PTR_ERR(map->menu_info);
0080             goto free_map;
0081         }
0082 
0083         map->menu_count = xmap->menu_count;
0084         break;
0085 
0086     default:
0087         uvc_dbg(chain->dev, CONTROL,
0088             "Unsupported V4L2 control type %u\n", xmap->v4l2_type);
0089         ret = -ENOTTY;
0090         goto free_map;
0091     }
0092 
0093     ret = uvc_ctrl_add_mapping(chain, map);
0094 
0095     kfree(map->menu_info);
0096 free_map:
0097     kfree(map);
0098 
0099     return ret;
0100 }
0101 
0102 /* ------------------------------------------------------------------------
0103  * V4L2 interface
0104  */
0105 
0106 /*
0107  * Find the frame interval closest to the requested frame interval for the
0108  * given frame format and size. This should be done by the device as part of
0109  * the Video Probe and Commit negotiation, but some hardware don't implement
0110  * that feature.
0111  */
0112 static u32 uvc_try_frame_interval(struct uvc_frame *frame, u32 interval)
0113 {
0114     unsigned int i;
0115 
0116     if (frame->bFrameIntervalType) {
0117         u32 best = -1, dist;
0118 
0119         for (i = 0; i < frame->bFrameIntervalType; ++i) {
0120             dist = interval > frame->dwFrameInterval[i]
0121                  ? interval - frame->dwFrameInterval[i]
0122                  : frame->dwFrameInterval[i] - interval;
0123 
0124             if (dist > best)
0125                 break;
0126 
0127             best = dist;
0128         }
0129 
0130         interval = frame->dwFrameInterval[i-1];
0131     } else {
0132         const u32 min = frame->dwFrameInterval[0];
0133         const u32 max = frame->dwFrameInterval[1];
0134         const u32 step = frame->dwFrameInterval[2];
0135 
0136         interval = min + (interval - min + step/2) / step * step;
0137         if (interval > max)
0138             interval = max;
0139     }
0140 
0141     return interval;
0142 }
0143 
0144 static u32 uvc_v4l2_get_bytesperline(const struct uvc_format *format,
0145     const struct uvc_frame *frame)
0146 {
0147     switch (format->fcc) {
0148     case V4L2_PIX_FMT_NV12:
0149     case V4L2_PIX_FMT_YVU420:
0150     case V4L2_PIX_FMT_YUV420:
0151     case V4L2_PIX_FMT_M420:
0152         return frame->wWidth;
0153 
0154     default:
0155         return format->bpp * frame->wWidth / 8;
0156     }
0157 }
0158 
0159 static int uvc_v4l2_try_format(struct uvc_streaming *stream,
0160     struct v4l2_format *fmt, struct uvc_streaming_control *probe,
0161     struct uvc_format **uvc_format, struct uvc_frame **uvc_frame)
0162 {
0163     struct uvc_format *format = NULL;
0164     struct uvc_frame *frame = NULL;
0165     u16 rw, rh;
0166     unsigned int d, maxd;
0167     unsigned int i;
0168     u32 interval;
0169     int ret = 0;
0170     u8 *fcc;
0171 
0172     if (fmt->type != stream->type)
0173         return -EINVAL;
0174 
0175     fcc = (u8 *)&fmt->fmt.pix.pixelformat;
0176     uvc_dbg(stream->dev, FORMAT, "Trying format 0x%08x (%c%c%c%c): %ux%u\n",
0177         fmt->fmt.pix.pixelformat,
0178         fcc[0], fcc[1], fcc[2], fcc[3],
0179         fmt->fmt.pix.width, fmt->fmt.pix.height);
0180 
0181     /*
0182      * Check if the hardware supports the requested format, use the default
0183      * format otherwise.
0184      */
0185     for (i = 0; i < stream->nformats; ++i) {
0186         format = &stream->format[i];
0187         if (format->fcc == fmt->fmt.pix.pixelformat)
0188             break;
0189     }
0190 
0191     if (i == stream->nformats) {
0192         format = stream->def_format;
0193         fmt->fmt.pix.pixelformat = format->fcc;
0194     }
0195 
0196     /*
0197      * Find the closest image size. The distance between image sizes is
0198      * the size in pixels of the non-overlapping regions between the
0199      * requested size and the frame-specified size.
0200      */
0201     rw = fmt->fmt.pix.width;
0202     rh = fmt->fmt.pix.height;
0203     maxd = (unsigned int)-1;
0204 
0205     for (i = 0; i < format->nframes; ++i) {
0206         u16 w = format->frame[i].wWidth;
0207         u16 h = format->frame[i].wHeight;
0208 
0209         d = min(w, rw) * min(h, rh);
0210         d = w*h + rw*rh - 2*d;
0211         if (d < maxd) {
0212             maxd = d;
0213             frame = &format->frame[i];
0214         }
0215 
0216         if (maxd == 0)
0217             break;
0218     }
0219 
0220     if (frame == NULL) {
0221         uvc_dbg(stream->dev, FORMAT, "Unsupported size %ux%u\n",
0222             fmt->fmt.pix.width, fmt->fmt.pix.height);
0223         return -EINVAL;
0224     }
0225 
0226     /* Use the default frame interval. */
0227     interval = frame->dwDefaultFrameInterval;
0228     uvc_dbg(stream->dev, FORMAT,
0229         "Using default frame interval %u.%u us (%u.%u fps)\n",
0230         interval / 10, interval % 10, 10000000 / interval,
0231         (100000000 / interval) % 10);
0232 
0233     /* Set the format index, frame index and frame interval. */
0234     memset(probe, 0, sizeof(*probe));
0235     probe->bmHint = 1;  /* dwFrameInterval */
0236     probe->bFormatIndex = format->index;
0237     probe->bFrameIndex = frame->bFrameIndex;
0238     probe->dwFrameInterval = uvc_try_frame_interval(frame, interval);
0239     /*
0240      * Some webcams stall the probe control set request when the
0241      * dwMaxVideoFrameSize field is set to zero. The UVC specification
0242      * clearly states that the field is read-only from the host, so this
0243      * is a webcam bug. Set dwMaxVideoFrameSize to the value reported by
0244      * the webcam to work around the problem.
0245      *
0246      * The workaround could probably be enabled for all webcams, so the
0247      * quirk can be removed if needed. It's currently useful to detect
0248      * webcam bugs and fix them before they hit the market (providing
0249      * developers test their webcams with the Linux driver as well as with
0250      * the Windows driver).
0251      */
0252     mutex_lock(&stream->mutex);
0253     if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS)
0254         probe->dwMaxVideoFrameSize =
0255             stream->ctrl.dwMaxVideoFrameSize;
0256 
0257     /* Probe the device. */
0258     ret = uvc_probe_video(stream, probe);
0259     mutex_unlock(&stream->mutex);
0260     if (ret < 0)
0261         return ret;
0262 
0263     /*
0264      * After the probe, update fmt with the values returned from
0265      * negotiation with the device. Some devices return invalid bFormatIndex
0266      * and bFrameIndex values, in which case we can only assume they have
0267      * accepted the requested format as-is.
0268      */
0269     for (i = 0; i < stream->nformats; ++i) {
0270         if (probe->bFormatIndex == stream->format[i].index) {
0271             format = &stream->format[i];
0272             break;
0273         }
0274     }
0275 
0276     if (i == stream->nformats)
0277         uvc_dbg(stream->dev, FORMAT,
0278             "Unknown bFormatIndex %u, using default\n",
0279             probe->bFormatIndex);
0280 
0281     for (i = 0; i < format->nframes; ++i) {
0282         if (probe->bFrameIndex == format->frame[i].bFrameIndex) {
0283             frame = &format->frame[i];
0284             break;
0285         }
0286     }
0287 
0288     if (i == format->nframes)
0289         uvc_dbg(stream->dev, FORMAT,
0290             "Unknown bFrameIndex %u, using default\n",
0291             probe->bFrameIndex);
0292 
0293     fmt->fmt.pix.width = frame->wWidth;
0294     fmt->fmt.pix.height = frame->wHeight;
0295     fmt->fmt.pix.field = V4L2_FIELD_NONE;
0296     fmt->fmt.pix.bytesperline = uvc_v4l2_get_bytesperline(format, frame);
0297     fmt->fmt.pix.sizeimage = probe->dwMaxVideoFrameSize;
0298     fmt->fmt.pix.pixelformat = format->fcc;
0299     fmt->fmt.pix.colorspace = format->colorspace;
0300     fmt->fmt.pix.xfer_func = format->xfer_func;
0301     fmt->fmt.pix.ycbcr_enc = format->ycbcr_enc;
0302 
0303     if (uvc_format != NULL)
0304         *uvc_format = format;
0305     if (uvc_frame != NULL)
0306         *uvc_frame = frame;
0307 
0308     return ret;
0309 }
0310 
0311 static int uvc_v4l2_get_format(struct uvc_streaming *stream,
0312     struct v4l2_format *fmt)
0313 {
0314     struct uvc_format *format;
0315     struct uvc_frame *frame;
0316     int ret = 0;
0317 
0318     if (fmt->type != stream->type)
0319         return -EINVAL;
0320 
0321     mutex_lock(&stream->mutex);
0322     format = stream->cur_format;
0323     frame = stream->cur_frame;
0324 
0325     if (format == NULL || frame == NULL) {
0326         ret = -EINVAL;
0327         goto done;
0328     }
0329 
0330     fmt->fmt.pix.pixelformat = format->fcc;
0331     fmt->fmt.pix.width = frame->wWidth;
0332     fmt->fmt.pix.height = frame->wHeight;
0333     fmt->fmt.pix.field = V4L2_FIELD_NONE;
0334     fmt->fmt.pix.bytesperline = uvc_v4l2_get_bytesperline(format, frame);
0335     fmt->fmt.pix.sizeimage = stream->ctrl.dwMaxVideoFrameSize;
0336     fmt->fmt.pix.colorspace = format->colorspace;
0337     fmt->fmt.pix.xfer_func = format->xfer_func;
0338     fmt->fmt.pix.ycbcr_enc = format->ycbcr_enc;
0339 
0340 done:
0341     mutex_unlock(&stream->mutex);
0342     return ret;
0343 }
0344 
0345 static int uvc_v4l2_set_format(struct uvc_streaming *stream,
0346     struct v4l2_format *fmt)
0347 {
0348     struct uvc_streaming_control probe;
0349     struct uvc_format *format;
0350     struct uvc_frame *frame;
0351     int ret;
0352 
0353     if (fmt->type != stream->type)
0354         return -EINVAL;
0355 
0356     ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame);
0357     if (ret < 0)
0358         return ret;
0359 
0360     mutex_lock(&stream->mutex);
0361 
0362     if (uvc_queue_allocated(&stream->queue)) {
0363         ret = -EBUSY;
0364         goto done;
0365     }
0366 
0367     stream->ctrl = probe;
0368     stream->cur_format = format;
0369     stream->cur_frame = frame;
0370 
0371 done:
0372     mutex_unlock(&stream->mutex);
0373     return ret;
0374 }
0375 
0376 static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream,
0377         struct v4l2_streamparm *parm)
0378 {
0379     u32 numerator, denominator;
0380 
0381     if (parm->type != stream->type)
0382         return -EINVAL;
0383 
0384     mutex_lock(&stream->mutex);
0385     numerator = stream->ctrl.dwFrameInterval;
0386     mutex_unlock(&stream->mutex);
0387 
0388     denominator = 10000000;
0389     uvc_simplify_fraction(&numerator, &denominator, 8, 333);
0390 
0391     memset(parm, 0, sizeof(*parm));
0392     parm->type = stream->type;
0393 
0394     if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
0395         parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
0396         parm->parm.capture.capturemode = 0;
0397         parm->parm.capture.timeperframe.numerator = numerator;
0398         parm->parm.capture.timeperframe.denominator = denominator;
0399         parm->parm.capture.extendedmode = 0;
0400         parm->parm.capture.readbuffers = 0;
0401     } else {
0402         parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
0403         parm->parm.output.outputmode = 0;
0404         parm->parm.output.timeperframe.numerator = numerator;
0405         parm->parm.output.timeperframe.denominator = denominator;
0406     }
0407 
0408     return 0;
0409 }
0410 
0411 static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream,
0412         struct v4l2_streamparm *parm)
0413 {
0414     struct uvc_streaming_control probe;
0415     struct v4l2_fract timeperframe;
0416     struct uvc_format *format;
0417     struct uvc_frame *frame;
0418     u32 interval, maxd;
0419     unsigned int i;
0420     int ret;
0421 
0422     if (parm->type != stream->type)
0423         return -EINVAL;
0424 
0425     if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
0426         timeperframe = parm->parm.capture.timeperframe;
0427     else
0428         timeperframe = parm->parm.output.timeperframe;
0429 
0430     interval = uvc_fraction_to_interval(timeperframe.numerator,
0431         timeperframe.denominator);
0432     uvc_dbg(stream->dev, FORMAT, "Setting frame interval to %u/%u (%u)\n",
0433         timeperframe.numerator, timeperframe.denominator, interval);
0434 
0435     mutex_lock(&stream->mutex);
0436 
0437     if (uvc_queue_streaming(&stream->queue)) {
0438         mutex_unlock(&stream->mutex);
0439         return -EBUSY;
0440     }
0441 
0442     format = stream->cur_format;
0443     frame = stream->cur_frame;
0444     probe = stream->ctrl;
0445     probe.dwFrameInterval = uvc_try_frame_interval(frame, interval);
0446     maxd = abs((s32)probe.dwFrameInterval - interval);
0447 
0448     /* Try frames with matching size to find the best frame interval. */
0449     for (i = 0; i < format->nframes && maxd != 0; i++) {
0450         u32 d, ival;
0451 
0452         if (&format->frame[i] == stream->cur_frame)
0453             continue;
0454 
0455         if (format->frame[i].wWidth != stream->cur_frame->wWidth ||
0456             format->frame[i].wHeight != stream->cur_frame->wHeight)
0457             continue;
0458 
0459         ival = uvc_try_frame_interval(&format->frame[i], interval);
0460         d = abs((s32)ival - interval);
0461         if (d >= maxd)
0462             continue;
0463 
0464         frame = &format->frame[i];
0465         probe.bFrameIndex = frame->bFrameIndex;
0466         probe.dwFrameInterval = ival;
0467         maxd = d;
0468     }
0469 
0470     /* Probe the device with the new settings. */
0471     ret = uvc_probe_video(stream, &probe);
0472     if (ret < 0) {
0473         mutex_unlock(&stream->mutex);
0474         return ret;
0475     }
0476 
0477     stream->ctrl = probe;
0478     stream->cur_frame = frame;
0479     mutex_unlock(&stream->mutex);
0480 
0481     /* Return the actual frame period. */
0482     timeperframe.numerator = probe.dwFrameInterval;
0483     timeperframe.denominator = 10000000;
0484     uvc_simplify_fraction(&timeperframe.numerator,
0485         &timeperframe.denominator, 8, 333);
0486 
0487     if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
0488         parm->parm.capture.timeperframe = timeperframe;
0489         parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
0490     } else {
0491         parm->parm.output.timeperframe = timeperframe;
0492         parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
0493     }
0494 
0495     return 0;
0496 }
0497 
0498 /* ------------------------------------------------------------------------
0499  * Privilege management
0500  */
0501 
0502 /*
0503  * Privilege management is the multiple-open implementation basis. The current
0504  * implementation is completely transparent for the end-user and doesn't
0505  * require explicit use of the VIDIOC_G_PRIORITY and VIDIOC_S_PRIORITY ioctls.
0506  * Those ioctls enable finer control on the device (by making possible for a
0507  * user to request exclusive access to a device), but are not mature yet.
0508  * Switching to the V4L2 priority mechanism might be considered in the future
0509  * if this situation changes.
0510  *
0511  * Each open instance of a UVC device can either be in a privileged or
0512  * unprivileged state. Only a single instance can be in a privileged state at
0513  * a given time. Trying to perform an operation that requires privileges will
0514  * automatically acquire the required privileges if possible, or return -EBUSY
0515  * otherwise. Privileges are dismissed when closing the instance or when
0516  * freeing the video buffers using VIDIOC_REQBUFS.
0517  *
0518  * Operations that require privileges are:
0519  *
0520  * - VIDIOC_S_INPUT
0521  * - VIDIOC_S_PARM
0522  * - VIDIOC_S_FMT
0523  * - VIDIOC_REQBUFS
0524  */
0525 static int uvc_acquire_privileges(struct uvc_fh *handle)
0526 {
0527     /* Always succeed if the handle is already privileged. */
0528     if (handle->state == UVC_HANDLE_ACTIVE)
0529         return 0;
0530 
0531     /* Check if the device already has a privileged handle. */
0532     if (atomic_inc_return(&handle->stream->active) != 1) {
0533         atomic_dec(&handle->stream->active);
0534         return -EBUSY;
0535     }
0536 
0537     handle->state = UVC_HANDLE_ACTIVE;
0538     return 0;
0539 }
0540 
0541 static void uvc_dismiss_privileges(struct uvc_fh *handle)
0542 {
0543     if (handle->state == UVC_HANDLE_ACTIVE)
0544         atomic_dec(&handle->stream->active);
0545 
0546     handle->state = UVC_HANDLE_PASSIVE;
0547 }
0548 
0549 static int uvc_has_privileges(struct uvc_fh *handle)
0550 {
0551     return handle->state == UVC_HANDLE_ACTIVE;
0552 }
0553 
0554 /* ------------------------------------------------------------------------
0555  * V4L2 file operations
0556  */
0557 
0558 static int uvc_v4l2_open(struct file *file)
0559 {
0560     struct uvc_streaming *stream;
0561     struct uvc_fh *handle;
0562     int ret = 0;
0563 
0564     stream = video_drvdata(file);
0565     uvc_dbg(stream->dev, CALLS, "%s\n", __func__);
0566 
0567     ret = usb_autopm_get_interface(stream->dev->intf);
0568     if (ret < 0)
0569         return ret;
0570 
0571     /* Create the device handle. */
0572     handle = kzalloc(sizeof(*handle), GFP_KERNEL);
0573     if (handle == NULL) {
0574         usb_autopm_put_interface(stream->dev->intf);
0575         return -ENOMEM;
0576     }
0577 
0578     mutex_lock(&stream->dev->lock);
0579     if (stream->dev->users == 0) {
0580         ret = uvc_status_start(stream->dev, GFP_KERNEL);
0581         if (ret < 0) {
0582             mutex_unlock(&stream->dev->lock);
0583             usb_autopm_put_interface(stream->dev->intf);
0584             kfree(handle);
0585             return ret;
0586         }
0587     }
0588 
0589     stream->dev->users++;
0590     mutex_unlock(&stream->dev->lock);
0591 
0592     v4l2_fh_init(&handle->vfh, &stream->vdev);
0593     v4l2_fh_add(&handle->vfh);
0594     handle->chain = stream->chain;
0595     handle->stream = stream;
0596     handle->state = UVC_HANDLE_PASSIVE;
0597     file->private_data = handle;
0598 
0599     return 0;
0600 }
0601 
0602 static int uvc_v4l2_release(struct file *file)
0603 {
0604     struct uvc_fh *handle = file->private_data;
0605     struct uvc_streaming *stream = handle->stream;
0606 
0607     uvc_dbg(stream->dev, CALLS, "%s\n", __func__);
0608 
0609     /* Only free resources if this is a privileged handle. */
0610     if (uvc_has_privileges(handle))
0611         uvc_queue_release(&stream->queue);
0612 
0613     /* Release the file handle. */
0614     uvc_dismiss_privileges(handle);
0615     v4l2_fh_del(&handle->vfh);
0616     v4l2_fh_exit(&handle->vfh);
0617     kfree(handle);
0618     file->private_data = NULL;
0619 
0620     mutex_lock(&stream->dev->lock);
0621     if (--stream->dev->users == 0)
0622         uvc_status_stop(stream->dev);
0623     mutex_unlock(&stream->dev->lock);
0624 
0625     usb_autopm_put_interface(stream->dev->intf);
0626     return 0;
0627 }
0628 
0629 static int uvc_ioctl_querycap(struct file *file, void *fh,
0630                   struct v4l2_capability *cap)
0631 {
0632     struct uvc_fh *handle = file->private_data;
0633     struct uvc_video_chain *chain = handle->chain;
0634     struct uvc_streaming *stream = handle->stream;
0635 
0636     strscpy(cap->driver, "uvcvideo", sizeof(cap->driver));
0637     strscpy(cap->card, handle->stream->dev->name, sizeof(cap->card));
0638     usb_make_path(stream->dev->udev, cap->bus_info, sizeof(cap->bus_info));
0639     cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING
0640               | chain->caps;
0641 
0642     return 0;
0643 }
0644 
0645 static int uvc_ioctl_enum_fmt(struct uvc_streaming *stream,
0646                   struct v4l2_fmtdesc *fmt)
0647 {
0648     struct uvc_format *format;
0649     enum v4l2_buf_type type = fmt->type;
0650     u32 index = fmt->index;
0651 
0652     if (fmt->type != stream->type || fmt->index >= stream->nformats)
0653         return -EINVAL;
0654 
0655     memset(fmt, 0, sizeof(*fmt));
0656     fmt->index = index;
0657     fmt->type = type;
0658 
0659     format = &stream->format[fmt->index];
0660     fmt->flags = 0;
0661     if (format->flags & UVC_FMT_FLAG_COMPRESSED)
0662         fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
0663     strscpy(fmt->description, format->name, sizeof(fmt->description));
0664     fmt->description[sizeof(fmt->description) - 1] = 0;
0665     fmt->pixelformat = format->fcc;
0666     return 0;
0667 }
0668 
0669 static int uvc_ioctl_enum_fmt_vid_cap(struct file *file, void *fh,
0670                       struct v4l2_fmtdesc *fmt)
0671 {
0672     struct uvc_fh *handle = fh;
0673     struct uvc_streaming *stream = handle->stream;
0674 
0675     return uvc_ioctl_enum_fmt(stream, fmt);
0676 }
0677 
0678 static int uvc_ioctl_enum_fmt_vid_out(struct file *file, void *fh,
0679                       struct v4l2_fmtdesc *fmt)
0680 {
0681     struct uvc_fh *handle = fh;
0682     struct uvc_streaming *stream = handle->stream;
0683 
0684     return uvc_ioctl_enum_fmt(stream, fmt);
0685 }
0686 
0687 static int uvc_ioctl_g_fmt_vid_cap(struct file *file, void *fh,
0688                    struct v4l2_format *fmt)
0689 {
0690     struct uvc_fh *handle = fh;
0691     struct uvc_streaming *stream = handle->stream;
0692 
0693     return uvc_v4l2_get_format(stream, fmt);
0694 }
0695 
0696 static int uvc_ioctl_g_fmt_vid_out(struct file *file, void *fh,
0697                    struct v4l2_format *fmt)
0698 {
0699     struct uvc_fh *handle = fh;
0700     struct uvc_streaming *stream = handle->stream;
0701 
0702     return uvc_v4l2_get_format(stream, fmt);
0703 }
0704 
0705 static int uvc_ioctl_s_fmt_vid_cap(struct file *file, void *fh,
0706                    struct v4l2_format *fmt)
0707 {
0708     struct uvc_fh *handle = fh;
0709     struct uvc_streaming *stream = handle->stream;
0710     int ret;
0711 
0712     ret = uvc_acquire_privileges(handle);
0713     if (ret < 0)
0714         return ret;
0715 
0716     return uvc_v4l2_set_format(stream, fmt);
0717 }
0718 
0719 static int uvc_ioctl_s_fmt_vid_out(struct file *file, void *fh,
0720                    struct v4l2_format *fmt)
0721 {
0722     struct uvc_fh *handle = fh;
0723     struct uvc_streaming *stream = handle->stream;
0724     int ret;
0725 
0726     ret = uvc_acquire_privileges(handle);
0727     if (ret < 0)
0728         return ret;
0729 
0730     return uvc_v4l2_set_format(stream, fmt);
0731 }
0732 
0733 static int uvc_ioctl_try_fmt_vid_cap(struct file *file, void *fh,
0734                      struct v4l2_format *fmt)
0735 {
0736     struct uvc_fh *handle = fh;
0737     struct uvc_streaming *stream = handle->stream;
0738     struct uvc_streaming_control probe;
0739 
0740     return uvc_v4l2_try_format(stream, fmt, &probe, NULL, NULL);
0741 }
0742 
0743 static int uvc_ioctl_try_fmt_vid_out(struct file *file, void *fh,
0744                      struct v4l2_format *fmt)
0745 {
0746     struct uvc_fh *handle = fh;
0747     struct uvc_streaming *stream = handle->stream;
0748     struct uvc_streaming_control probe;
0749 
0750     return uvc_v4l2_try_format(stream, fmt, &probe, NULL, NULL);
0751 }
0752 
0753 static int uvc_ioctl_reqbufs(struct file *file, void *fh,
0754                  struct v4l2_requestbuffers *rb)
0755 {
0756     struct uvc_fh *handle = fh;
0757     struct uvc_streaming *stream = handle->stream;
0758     int ret;
0759 
0760     ret = uvc_acquire_privileges(handle);
0761     if (ret < 0)
0762         return ret;
0763 
0764     mutex_lock(&stream->mutex);
0765     ret = uvc_request_buffers(&stream->queue, rb);
0766     mutex_unlock(&stream->mutex);
0767     if (ret < 0)
0768         return ret;
0769 
0770     if (ret == 0)
0771         uvc_dismiss_privileges(handle);
0772 
0773     return 0;
0774 }
0775 
0776 static int uvc_ioctl_querybuf(struct file *file, void *fh,
0777                   struct v4l2_buffer *buf)
0778 {
0779     struct uvc_fh *handle = fh;
0780     struct uvc_streaming *stream = handle->stream;
0781 
0782     if (!uvc_has_privileges(handle))
0783         return -EBUSY;
0784 
0785     return uvc_query_buffer(&stream->queue, buf);
0786 }
0787 
0788 static int uvc_ioctl_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
0789 {
0790     struct uvc_fh *handle = fh;
0791     struct uvc_streaming *stream = handle->stream;
0792 
0793     if (!uvc_has_privileges(handle))
0794         return -EBUSY;
0795 
0796     return uvc_queue_buffer(&stream->queue,
0797                 stream->vdev.v4l2_dev->mdev, buf);
0798 }
0799 
0800 static int uvc_ioctl_expbuf(struct file *file, void *fh,
0801                 struct v4l2_exportbuffer *exp)
0802 {
0803     struct uvc_fh *handle = fh;
0804     struct uvc_streaming *stream = handle->stream;
0805 
0806     if (!uvc_has_privileges(handle))
0807         return -EBUSY;
0808 
0809     return uvc_export_buffer(&stream->queue, exp);
0810 }
0811 
0812 static int uvc_ioctl_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
0813 {
0814     struct uvc_fh *handle = fh;
0815     struct uvc_streaming *stream = handle->stream;
0816 
0817     if (!uvc_has_privileges(handle))
0818         return -EBUSY;
0819 
0820     return uvc_dequeue_buffer(&stream->queue, buf,
0821                   file->f_flags & O_NONBLOCK);
0822 }
0823 
0824 static int uvc_ioctl_create_bufs(struct file *file, void *fh,
0825                   struct v4l2_create_buffers *cb)
0826 {
0827     struct uvc_fh *handle = fh;
0828     struct uvc_streaming *stream = handle->stream;
0829     int ret;
0830 
0831     ret = uvc_acquire_privileges(handle);
0832     if (ret < 0)
0833         return ret;
0834 
0835     return uvc_create_buffers(&stream->queue, cb);
0836 }
0837 
0838 static int uvc_ioctl_streamon(struct file *file, void *fh,
0839                   enum v4l2_buf_type type)
0840 {
0841     struct uvc_fh *handle = fh;
0842     struct uvc_streaming *stream = handle->stream;
0843     int ret;
0844 
0845     if (!uvc_has_privileges(handle))
0846         return -EBUSY;
0847 
0848     mutex_lock(&stream->mutex);
0849     ret = uvc_queue_streamon(&stream->queue, type);
0850     mutex_unlock(&stream->mutex);
0851 
0852     return ret;
0853 }
0854 
0855 static int uvc_ioctl_streamoff(struct file *file, void *fh,
0856                    enum v4l2_buf_type type)
0857 {
0858     struct uvc_fh *handle = fh;
0859     struct uvc_streaming *stream = handle->stream;
0860 
0861     if (!uvc_has_privileges(handle))
0862         return -EBUSY;
0863 
0864     mutex_lock(&stream->mutex);
0865     uvc_queue_streamoff(&stream->queue, type);
0866     mutex_unlock(&stream->mutex);
0867 
0868     return 0;
0869 }
0870 
0871 static int uvc_ioctl_enum_input(struct file *file, void *fh,
0872                 struct v4l2_input *input)
0873 {
0874     struct uvc_fh *handle = fh;
0875     struct uvc_video_chain *chain = handle->chain;
0876     const struct uvc_entity *selector = chain->selector;
0877     struct uvc_entity *iterm = NULL;
0878     struct uvc_entity *it;
0879     u32 index = input->index;
0880 
0881     if (selector == NULL ||
0882         (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
0883         if (index != 0)
0884             return -EINVAL;
0885         list_for_each_entry(it, &chain->entities, chain) {
0886             if (UVC_ENTITY_IS_ITERM(it)) {
0887                 iterm = it;
0888                 break;
0889             }
0890         }
0891     } else if (index < selector->bNrInPins) {
0892         list_for_each_entry(it, &chain->entities, chain) {
0893             if (!UVC_ENTITY_IS_ITERM(it))
0894                 continue;
0895             if (it->id == selector->baSourceID[index]) {
0896                 iterm = it;
0897                 break;
0898             }
0899         }
0900     }
0901 
0902     if (iterm == NULL)
0903         return -EINVAL;
0904 
0905     memset(input, 0, sizeof(*input));
0906     input->index = index;
0907     strscpy(input->name, iterm->name, sizeof(input->name));
0908     if (UVC_ENTITY_TYPE(iterm) == UVC_ITT_CAMERA)
0909         input->type = V4L2_INPUT_TYPE_CAMERA;
0910 
0911     return 0;
0912 }
0913 
0914 static int uvc_ioctl_g_input(struct file *file, void *fh, unsigned int *input)
0915 {
0916     struct uvc_fh *handle = fh;
0917     struct uvc_video_chain *chain = handle->chain;
0918     u8 *buf;
0919     int ret;
0920 
0921     if (chain->selector == NULL ||
0922         (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
0923         *input = 0;
0924         return 0;
0925     }
0926 
0927     buf = kmalloc(1, GFP_KERNEL);
0928     if (!buf)
0929         return -ENOMEM;
0930 
0931     ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, chain->selector->id,
0932                  chain->dev->intfnum,  UVC_SU_INPUT_SELECT_CONTROL,
0933                  buf, 1);
0934     if (!ret)
0935         *input = *buf - 1;
0936 
0937     kfree(buf);
0938 
0939     return ret;
0940 }
0941 
0942 static int uvc_ioctl_s_input(struct file *file, void *fh, unsigned int input)
0943 {
0944     struct uvc_fh *handle = fh;
0945     struct uvc_video_chain *chain = handle->chain;
0946     u8 *buf;
0947     int ret;
0948 
0949     ret = uvc_acquire_privileges(handle);
0950     if (ret < 0)
0951         return ret;
0952 
0953     if (chain->selector == NULL ||
0954         (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
0955         if (input)
0956             return -EINVAL;
0957         return 0;
0958     }
0959 
0960     if (input >= chain->selector->bNrInPins)
0961         return -EINVAL;
0962 
0963     buf = kmalloc(1, GFP_KERNEL);
0964     if (!buf)
0965         return -ENOMEM;
0966 
0967     *buf = input + 1;
0968     ret = uvc_query_ctrl(chain->dev, UVC_SET_CUR, chain->selector->id,
0969                  chain->dev->intfnum, UVC_SU_INPUT_SELECT_CONTROL,
0970                  buf, 1);
0971     kfree(buf);
0972 
0973     return ret;
0974 }
0975 
0976 static int uvc_ioctl_queryctrl(struct file *file, void *fh,
0977                    struct v4l2_queryctrl *qc)
0978 {
0979     struct uvc_fh *handle = fh;
0980     struct uvc_video_chain *chain = handle->chain;
0981 
0982     return uvc_query_v4l2_ctrl(chain, qc);
0983 }
0984 
0985 static int uvc_ioctl_query_ext_ctrl(struct file *file, void *fh,
0986                     struct v4l2_query_ext_ctrl *qec)
0987 {
0988     struct uvc_fh *handle = fh;
0989     struct uvc_video_chain *chain = handle->chain;
0990     struct v4l2_queryctrl qc = { qec->id };
0991     int ret;
0992 
0993     ret = uvc_query_v4l2_ctrl(chain, &qc);
0994     if (ret)
0995         return ret;
0996 
0997     qec->id = qc.id;
0998     qec->type = qc.type;
0999     strscpy(qec->name, qc.name, sizeof(qec->name));
1000     qec->minimum = qc.minimum;
1001     qec->maximum = qc.maximum;
1002     qec->step = qc.step;
1003     qec->default_value = qc.default_value;
1004     qec->flags = qc.flags;
1005     qec->elem_size = 4;
1006     qec->elems = 1;
1007     qec->nr_of_dims = 0;
1008     memset(qec->dims, 0, sizeof(qec->dims));
1009     memset(qec->reserved, 0, sizeof(qec->reserved));
1010 
1011     return 0;
1012 }
1013 
1014 static int uvc_ctrl_check_access(struct uvc_video_chain *chain,
1015                  struct v4l2_ext_controls *ctrls,
1016                  unsigned long ioctl)
1017 {
1018     struct v4l2_ext_control *ctrl = ctrls->controls;
1019     unsigned int i;
1020     int ret = 0;
1021 
1022     for (i = 0; i < ctrls->count; ++ctrl, ++i) {
1023         ret = uvc_ctrl_is_accessible(chain, ctrl->id,
1024                         ioctl == VIDIOC_G_EXT_CTRLS);
1025         if (ret)
1026             break;
1027     }
1028 
1029     ctrls->error_idx = ioctl == VIDIOC_TRY_EXT_CTRLS ? i : ctrls->count;
1030 
1031     return ret;
1032 }
1033 
1034 static int uvc_ioctl_g_ext_ctrls(struct file *file, void *fh,
1035                  struct v4l2_ext_controls *ctrls)
1036 {
1037     struct uvc_fh *handle = fh;
1038     struct uvc_video_chain *chain = handle->chain;
1039     struct v4l2_ext_control *ctrl = ctrls->controls;
1040     unsigned int i;
1041     int ret;
1042 
1043     ret = uvc_ctrl_check_access(chain, ctrls, VIDIOC_G_EXT_CTRLS);
1044     if (ret < 0)
1045         return ret;
1046 
1047     if (ctrls->which == V4L2_CTRL_WHICH_DEF_VAL) {
1048         for (i = 0; i < ctrls->count; ++ctrl, ++i) {
1049             struct v4l2_queryctrl qc = { .id = ctrl->id };
1050 
1051             ret = uvc_query_v4l2_ctrl(chain, &qc);
1052             if (ret < 0) {
1053                 ctrls->error_idx = i;
1054                 return ret;
1055             }
1056 
1057             ctrl->value = qc.default_value;
1058         }
1059 
1060         return 0;
1061     }
1062 
1063     ret = uvc_ctrl_begin(chain);
1064     if (ret < 0)
1065         return ret;
1066 
1067     for (i = 0; i < ctrls->count; ++ctrl, ++i) {
1068         ret = uvc_ctrl_get(chain, ctrl);
1069         if (ret < 0) {
1070             uvc_ctrl_rollback(handle);
1071             ctrls->error_idx = i;
1072             return ret;
1073         }
1074     }
1075 
1076     ctrls->error_idx = 0;
1077 
1078     return uvc_ctrl_rollback(handle);
1079 }
1080 
1081 static int uvc_ioctl_s_try_ext_ctrls(struct uvc_fh *handle,
1082                      struct v4l2_ext_controls *ctrls,
1083                      unsigned long ioctl)
1084 {
1085     struct v4l2_ext_control *ctrl = ctrls->controls;
1086     struct uvc_video_chain *chain = handle->chain;
1087     unsigned int i;
1088     int ret;
1089 
1090     ret = uvc_ctrl_check_access(chain, ctrls, ioctl);
1091     if (ret < 0)
1092         return ret;
1093 
1094     ret = uvc_ctrl_begin(chain);
1095     if (ret < 0)
1096         return ret;
1097 
1098     for (i = 0; i < ctrls->count; ++ctrl, ++i) {
1099         ret = uvc_ctrl_set(handle, ctrl);
1100         if (ret < 0) {
1101             uvc_ctrl_rollback(handle);
1102             ctrls->error_idx = ioctl == VIDIOC_S_EXT_CTRLS ?
1103                             ctrls->count : i;
1104             return ret;
1105         }
1106     }
1107 
1108     ctrls->error_idx = 0;
1109 
1110     if (ioctl == VIDIOC_S_EXT_CTRLS)
1111         return uvc_ctrl_commit(handle, ctrls);
1112     else
1113         return uvc_ctrl_rollback(handle);
1114 }
1115 
1116 static int uvc_ioctl_s_ext_ctrls(struct file *file, void *fh,
1117                  struct v4l2_ext_controls *ctrls)
1118 {
1119     struct uvc_fh *handle = fh;
1120 
1121     return uvc_ioctl_s_try_ext_ctrls(handle, ctrls, VIDIOC_S_EXT_CTRLS);
1122 }
1123 
1124 static int uvc_ioctl_try_ext_ctrls(struct file *file, void *fh,
1125                    struct v4l2_ext_controls *ctrls)
1126 {
1127     struct uvc_fh *handle = fh;
1128 
1129     return uvc_ioctl_s_try_ext_ctrls(handle, ctrls, VIDIOC_TRY_EXT_CTRLS);
1130 }
1131 
1132 static int uvc_ioctl_querymenu(struct file *file, void *fh,
1133                    struct v4l2_querymenu *qm)
1134 {
1135     struct uvc_fh *handle = fh;
1136     struct uvc_video_chain *chain = handle->chain;
1137 
1138     return uvc_query_v4l2_menu(chain, qm);
1139 }
1140 
1141 static int uvc_ioctl_g_selection(struct file *file, void *fh,
1142                  struct v4l2_selection *sel)
1143 {
1144     struct uvc_fh *handle = fh;
1145     struct uvc_streaming *stream = handle->stream;
1146 
1147     if (sel->type != stream->type)
1148         return -EINVAL;
1149 
1150     switch (sel->target) {
1151     case V4L2_SEL_TGT_CROP_DEFAULT:
1152     case V4L2_SEL_TGT_CROP_BOUNDS:
1153         if (stream->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1154             return -EINVAL;
1155         break;
1156     case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1157     case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1158         if (stream->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1159             return -EINVAL;
1160         break;
1161     default:
1162         return -EINVAL;
1163     }
1164 
1165     sel->r.left = 0;
1166     sel->r.top = 0;
1167     mutex_lock(&stream->mutex);
1168     sel->r.width = stream->cur_frame->wWidth;
1169     sel->r.height = stream->cur_frame->wHeight;
1170     mutex_unlock(&stream->mutex);
1171 
1172     return 0;
1173 }
1174 
1175 static int uvc_ioctl_g_parm(struct file *file, void *fh,
1176                 struct v4l2_streamparm *parm)
1177 {
1178     struct uvc_fh *handle = fh;
1179     struct uvc_streaming *stream = handle->stream;
1180 
1181     return uvc_v4l2_get_streamparm(stream, parm);
1182 }
1183 
1184 static int uvc_ioctl_s_parm(struct file *file, void *fh,
1185                 struct v4l2_streamparm *parm)
1186 {
1187     struct uvc_fh *handle = fh;
1188     struct uvc_streaming *stream = handle->stream;
1189     int ret;
1190 
1191     ret = uvc_acquire_privileges(handle);
1192     if (ret < 0)
1193         return ret;
1194 
1195     return uvc_v4l2_set_streamparm(stream, parm);
1196 }
1197 
1198 static int uvc_ioctl_enum_framesizes(struct file *file, void *fh,
1199                      struct v4l2_frmsizeenum *fsize)
1200 {
1201     struct uvc_fh *handle = fh;
1202     struct uvc_streaming *stream = handle->stream;
1203     struct uvc_format *format = NULL;
1204     struct uvc_frame *frame = NULL;
1205     unsigned int index;
1206     unsigned int i;
1207 
1208     /* Look for the given pixel format */
1209     for (i = 0; i < stream->nformats; i++) {
1210         if (stream->format[i].fcc == fsize->pixel_format) {
1211             format = &stream->format[i];
1212             break;
1213         }
1214     }
1215     if (format == NULL)
1216         return -EINVAL;
1217 
1218     /* Skip duplicate frame sizes */
1219     for (i = 0, index = 0; i < format->nframes; i++) {
1220         if (frame && frame->wWidth == format->frame[i].wWidth &&
1221             frame->wHeight == format->frame[i].wHeight)
1222             continue;
1223         frame = &format->frame[i];
1224         if (index == fsize->index)
1225             break;
1226         index++;
1227     }
1228 
1229     if (i == format->nframes)
1230         return -EINVAL;
1231 
1232     fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1233     fsize->discrete.width = frame->wWidth;
1234     fsize->discrete.height = frame->wHeight;
1235     return 0;
1236 }
1237 
1238 static int uvc_ioctl_enum_frameintervals(struct file *file, void *fh,
1239                      struct v4l2_frmivalenum *fival)
1240 {
1241     struct uvc_fh *handle = fh;
1242     struct uvc_streaming *stream = handle->stream;
1243     struct uvc_format *format = NULL;
1244     struct uvc_frame *frame = NULL;
1245     unsigned int nintervals;
1246     unsigned int index;
1247     unsigned int i;
1248 
1249     /* Look for the given pixel format and frame size */
1250     for (i = 0; i < stream->nformats; i++) {
1251         if (stream->format[i].fcc == fival->pixel_format) {
1252             format = &stream->format[i];
1253             break;
1254         }
1255     }
1256     if (format == NULL)
1257         return -EINVAL;
1258 
1259     index = fival->index;
1260     for (i = 0; i < format->nframes; i++) {
1261         if (format->frame[i].wWidth == fival->width &&
1262             format->frame[i].wHeight == fival->height) {
1263             frame = &format->frame[i];
1264             nintervals = frame->bFrameIntervalType ?: 1;
1265             if (index < nintervals)
1266                 break;
1267             index -= nintervals;
1268         }
1269     }
1270     if (i == format->nframes)
1271         return -EINVAL;
1272 
1273     if (frame->bFrameIntervalType) {
1274         fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1275         fival->discrete.numerator =
1276             frame->dwFrameInterval[index];
1277         fival->discrete.denominator = 10000000;
1278         uvc_simplify_fraction(&fival->discrete.numerator,
1279             &fival->discrete.denominator, 8, 333);
1280     } else {
1281         fival->type = V4L2_FRMIVAL_TYPE_STEPWISE;
1282         fival->stepwise.min.numerator = frame->dwFrameInterval[0];
1283         fival->stepwise.min.denominator = 10000000;
1284         fival->stepwise.max.numerator = frame->dwFrameInterval[1];
1285         fival->stepwise.max.denominator = 10000000;
1286         fival->stepwise.step.numerator = frame->dwFrameInterval[2];
1287         fival->stepwise.step.denominator = 10000000;
1288         uvc_simplify_fraction(&fival->stepwise.min.numerator,
1289             &fival->stepwise.min.denominator, 8, 333);
1290         uvc_simplify_fraction(&fival->stepwise.max.numerator,
1291             &fival->stepwise.max.denominator, 8, 333);
1292         uvc_simplify_fraction(&fival->stepwise.step.numerator,
1293             &fival->stepwise.step.denominator, 8, 333);
1294     }
1295 
1296     return 0;
1297 }
1298 
1299 static int uvc_ioctl_subscribe_event(struct v4l2_fh *fh,
1300                      const struct v4l2_event_subscription *sub)
1301 {
1302     switch (sub->type) {
1303     case V4L2_EVENT_CTRL:
1304         return v4l2_event_subscribe(fh, sub, 0, &uvc_ctrl_sub_ev_ops);
1305     default:
1306         return -EINVAL;
1307     }
1308 }
1309 
1310 static long uvc_ioctl_default(struct file *file, void *fh, bool valid_prio,
1311                   unsigned int cmd, void *arg)
1312 {
1313     struct uvc_fh *handle = fh;
1314     struct uvc_video_chain *chain = handle->chain;
1315 
1316     switch (cmd) {
1317     /* Dynamic controls. */
1318     case UVCIOC_CTRL_MAP:
1319         return uvc_ioctl_ctrl_map(chain, arg);
1320 
1321     case UVCIOC_CTRL_QUERY:
1322         return uvc_xu_ctrl_query(chain, arg);
1323 
1324     default:
1325         return -ENOTTY;
1326     }
1327 }
1328 
1329 #ifdef CONFIG_COMPAT
1330 struct uvc_xu_control_mapping32 {
1331     u32 id;
1332     u8 name[32];
1333     u8 entity[16];
1334     u8 selector;
1335 
1336     u8 size;
1337     u8 offset;
1338     u32 v4l2_type;
1339     u32 data_type;
1340 
1341     compat_caddr_t menu_info;
1342     u32 menu_count;
1343 
1344     u32 reserved[4];
1345 };
1346 
1347 static int uvc_v4l2_get_xu_mapping(struct uvc_xu_control_mapping *kp,
1348             const struct uvc_xu_control_mapping32 __user *up)
1349 {
1350     struct uvc_xu_control_mapping32 *p = (void *)kp;
1351     compat_caddr_t info;
1352     u32 count;
1353 
1354     if (copy_from_user(p, up, sizeof(*p)))
1355         return -EFAULT;
1356 
1357     count = p->menu_count;
1358     info = p->menu_info;
1359 
1360     memset(kp->reserved, 0, sizeof(kp->reserved));
1361     kp->menu_info = count ? compat_ptr(info) : NULL;
1362     kp->menu_count = count;
1363     return 0;
1364 }
1365 
1366 static int uvc_v4l2_put_xu_mapping(const struct uvc_xu_control_mapping *kp,
1367             struct uvc_xu_control_mapping32 __user *up)
1368 {
1369     if (copy_to_user(up, kp, offsetof(typeof(*up), menu_info)) ||
1370         put_user(kp->menu_count, &up->menu_count))
1371         return -EFAULT;
1372 
1373     if (clear_user(up->reserved, sizeof(up->reserved)))
1374         return -EFAULT;
1375 
1376     return 0;
1377 }
1378 
1379 struct uvc_xu_control_query32 {
1380     u8 unit;
1381     u8 selector;
1382     u8 query;
1383     u16 size;
1384     compat_caddr_t data;
1385 };
1386 
1387 static int uvc_v4l2_get_xu_query(struct uvc_xu_control_query *kp,
1388             const struct uvc_xu_control_query32 __user *up)
1389 {
1390     struct uvc_xu_control_query32 v;
1391 
1392     if (copy_from_user(&v, up, sizeof(v)))
1393         return -EFAULT;
1394 
1395     *kp = (struct uvc_xu_control_query){
1396         .unit = v.unit,
1397         .selector = v.selector,
1398         .query = v.query,
1399         .size = v.size,
1400         .data = v.size ? compat_ptr(v.data) : NULL
1401     };
1402     return 0;
1403 }
1404 
1405 static int uvc_v4l2_put_xu_query(const struct uvc_xu_control_query *kp,
1406             struct uvc_xu_control_query32 __user *up)
1407 {
1408     if (copy_to_user(up, kp, offsetof(typeof(*up), data)))
1409         return -EFAULT;
1410     return 0;
1411 }
1412 
1413 #define UVCIOC_CTRL_MAP32   _IOWR('u', 0x20, struct uvc_xu_control_mapping32)
1414 #define UVCIOC_CTRL_QUERY32 _IOWR('u', 0x21, struct uvc_xu_control_query32)
1415 
1416 static long uvc_v4l2_compat_ioctl32(struct file *file,
1417              unsigned int cmd, unsigned long arg)
1418 {
1419     struct uvc_fh *handle = file->private_data;
1420     union {
1421         struct uvc_xu_control_mapping xmap;
1422         struct uvc_xu_control_query xqry;
1423     } karg;
1424     void __user *up = compat_ptr(arg);
1425     long ret;
1426 
1427     switch (cmd) {
1428     case UVCIOC_CTRL_MAP32:
1429         ret = uvc_v4l2_get_xu_mapping(&karg.xmap, up);
1430         if (ret)
1431             return ret;
1432         ret = uvc_ioctl_ctrl_map(handle->chain, &karg.xmap);
1433         if (ret)
1434             return ret;
1435         ret = uvc_v4l2_put_xu_mapping(&karg.xmap, up);
1436         if (ret)
1437             return ret;
1438 
1439         break;
1440 
1441     case UVCIOC_CTRL_QUERY32:
1442         ret = uvc_v4l2_get_xu_query(&karg.xqry, up);
1443         if (ret)
1444             return ret;
1445         ret = uvc_xu_ctrl_query(handle->chain, &karg.xqry);
1446         if (ret)
1447             return ret;
1448         ret = uvc_v4l2_put_xu_query(&karg.xqry, up);
1449         if (ret)
1450             return ret;
1451         break;
1452 
1453     default:
1454         return -ENOIOCTLCMD;
1455     }
1456 
1457     return ret;
1458 }
1459 #endif
1460 
1461 static ssize_t uvc_v4l2_read(struct file *file, char __user *data,
1462             size_t count, loff_t *ppos)
1463 {
1464     struct uvc_fh *handle = file->private_data;
1465     struct uvc_streaming *stream = handle->stream;
1466 
1467     uvc_dbg(stream->dev, CALLS, "%s: not implemented\n", __func__);
1468     return -EINVAL;
1469 }
1470 
1471 static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
1472 {
1473     struct uvc_fh *handle = file->private_data;
1474     struct uvc_streaming *stream = handle->stream;
1475 
1476     uvc_dbg(stream->dev, CALLS, "%s\n", __func__);
1477 
1478     return uvc_queue_mmap(&stream->queue, vma);
1479 }
1480 
1481 static __poll_t uvc_v4l2_poll(struct file *file, poll_table *wait)
1482 {
1483     struct uvc_fh *handle = file->private_data;
1484     struct uvc_streaming *stream = handle->stream;
1485 
1486     uvc_dbg(stream->dev, CALLS, "%s\n", __func__);
1487 
1488     return uvc_queue_poll(&stream->queue, file, wait);
1489 }
1490 
1491 #ifndef CONFIG_MMU
1492 static unsigned long uvc_v4l2_get_unmapped_area(struct file *file,
1493         unsigned long addr, unsigned long len, unsigned long pgoff,
1494         unsigned long flags)
1495 {
1496     struct uvc_fh *handle = file->private_data;
1497     struct uvc_streaming *stream = handle->stream;
1498 
1499     uvc_dbg(stream->dev, CALLS, "%s\n", __func__);
1500 
1501     return uvc_queue_get_unmapped_area(&stream->queue, pgoff);
1502 }
1503 #endif
1504 
1505 const struct v4l2_ioctl_ops uvc_ioctl_ops = {
1506     .vidioc_querycap = uvc_ioctl_querycap,
1507     .vidioc_enum_fmt_vid_cap = uvc_ioctl_enum_fmt_vid_cap,
1508     .vidioc_enum_fmt_vid_out = uvc_ioctl_enum_fmt_vid_out,
1509     .vidioc_g_fmt_vid_cap = uvc_ioctl_g_fmt_vid_cap,
1510     .vidioc_g_fmt_vid_out = uvc_ioctl_g_fmt_vid_out,
1511     .vidioc_s_fmt_vid_cap = uvc_ioctl_s_fmt_vid_cap,
1512     .vidioc_s_fmt_vid_out = uvc_ioctl_s_fmt_vid_out,
1513     .vidioc_try_fmt_vid_cap = uvc_ioctl_try_fmt_vid_cap,
1514     .vidioc_try_fmt_vid_out = uvc_ioctl_try_fmt_vid_out,
1515     .vidioc_reqbufs = uvc_ioctl_reqbufs,
1516     .vidioc_querybuf = uvc_ioctl_querybuf,
1517     .vidioc_qbuf = uvc_ioctl_qbuf,
1518     .vidioc_expbuf = uvc_ioctl_expbuf,
1519     .vidioc_dqbuf = uvc_ioctl_dqbuf,
1520     .vidioc_create_bufs = uvc_ioctl_create_bufs,
1521     .vidioc_streamon = uvc_ioctl_streamon,
1522     .vidioc_streamoff = uvc_ioctl_streamoff,
1523     .vidioc_enum_input = uvc_ioctl_enum_input,
1524     .vidioc_g_input = uvc_ioctl_g_input,
1525     .vidioc_s_input = uvc_ioctl_s_input,
1526     .vidioc_queryctrl = uvc_ioctl_queryctrl,
1527     .vidioc_query_ext_ctrl = uvc_ioctl_query_ext_ctrl,
1528     .vidioc_g_ext_ctrls = uvc_ioctl_g_ext_ctrls,
1529     .vidioc_s_ext_ctrls = uvc_ioctl_s_ext_ctrls,
1530     .vidioc_try_ext_ctrls = uvc_ioctl_try_ext_ctrls,
1531     .vidioc_querymenu = uvc_ioctl_querymenu,
1532     .vidioc_g_selection = uvc_ioctl_g_selection,
1533     .vidioc_g_parm = uvc_ioctl_g_parm,
1534     .vidioc_s_parm = uvc_ioctl_s_parm,
1535     .vidioc_enum_framesizes = uvc_ioctl_enum_framesizes,
1536     .vidioc_enum_frameintervals = uvc_ioctl_enum_frameintervals,
1537     .vidioc_subscribe_event = uvc_ioctl_subscribe_event,
1538     .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1539     .vidioc_default = uvc_ioctl_default,
1540 };
1541 
1542 const struct v4l2_file_operations uvc_fops = {
1543     .owner      = THIS_MODULE,
1544     .open       = uvc_v4l2_open,
1545     .release    = uvc_v4l2_release,
1546     .unlocked_ioctl = video_ioctl2,
1547 #ifdef CONFIG_COMPAT
1548     .compat_ioctl32 = uvc_v4l2_compat_ioctl32,
1549 #endif
1550     .read       = uvc_v4l2_read,
1551     .mmap       = uvc_v4l2_mmap,
1552     .poll       = uvc_v4l2_poll,
1553 #ifndef CONFIG_MMU
1554     .get_unmapped_area = uvc_v4l2_get_unmapped_area,
1555 #endif
1556 };
1557