]> Git Repo - J-linux.git/blob - drivers/usb/gadget/function/uvc_v4l2.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / drivers / usb / gadget / function / uvc_v4l2.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  *      uvc_v4l2.c  --  USB Video Class Gadget driver
4  *
5  *      Copyright (C) 2009-2010
6  *          Laurent Pinchart ([email protected])
7  */
8
9 #include <linux/device.h>
10 #include <linux/errno.h>
11 #include <linux/kernel.h>
12 #include <linux/list.h>
13 #include <linux/usb/g_uvc.h>
14 #include <linux/usb/uvc.h>
15 #include <linux/videodev2.h>
16 #include <linux/vmalloc.h>
17 #include <linux/wait.h>
18
19 #include <media/v4l2-dev.h>
20 #include <media/v4l2-event.h>
21 #include <media/v4l2-ioctl.h>
22
23 #include "f_uvc.h"
24 #include "uvc.h"
25 #include "uvc_queue.h"
26 #include "uvc_video.h"
27 #include "uvc_v4l2.h"
28 #include "uvc_configfs.h"
29
30 static const struct uvc_format_desc *to_uvc_format(struct uvcg_format *uformat)
31 {
32         char guid[16] = UVC_GUID_FORMAT_MJPEG;
33         const struct uvc_format_desc *format;
34
35         if (uformat->type == UVCG_UNCOMPRESSED) {
36                 struct uvcg_uncompressed *unc;
37
38                 unc = to_uvcg_uncompressed(&uformat->group.cg_item);
39                 if (!unc)
40                         return ERR_PTR(-EINVAL);
41
42                 memcpy(guid, unc->desc.guidFormat, sizeof(guid));
43         } else if (uformat->type == UVCG_FRAMEBASED) {
44                 struct uvcg_framebased *unc;
45
46                 unc = to_uvcg_framebased(&uformat->group.cg_item);
47                 if (!unc)
48                         return ERR_PTR(-EINVAL);
49
50                 memcpy(guid, unc->desc.guidFormat, sizeof(guid));
51         }
52
53         format = uvc_format_by_guid(guid);
54         if (!format)
55                 return ERR_PTR(-EINVAL);
56
57         return format;
58 }
59
60 static int uvc_v4l2_get_bytesperline(struct uvcg_format *uformat,
61                               struct uvcg_frame *uframe)
62 {
63         struct uvcg_uncompressed *u;
64
65         if (uformat->type == UVCG_UNCOMPRESSED) {
66                 u = to_uvcg_uncompressed(&uformat->group.cg_item);
67                 if (!u)
68                         return 0;
69
70                 return u->desc.bBitsPerPixel * uframe->frame.w_width / 8;
71         }
72
73         return 0;
74 }
75
76 static int uvc_get_frame_size(struct uvcg_format *uformat,
77                        struct uvcg_frame *uframe)
78 {
79         unsigned int bpl = uvc_v4l2_get_bytesperline(uformat, uframe);
80
81         return bpl ? bpl * uframe->frame.w_height :
82                 uframe->frame.dw_max_video_frame_buffer_size;
83 }
84
85 static struct uvcg_format *find_format_by_index(struct uvc_device *uvc, int index)
86 {
87         struct uvcg_format_ptr *format;
88         struct uvcg_format *uformat = NULL;
89         int i = 1;
90
91         list_for_each_entry(format, &uvc->header->formats, entry) {
92                 if (index == i) {
93                         uformat = format->fmt;
94                         break;
95                 }
96                 i++;
97         }
98
99         return uformat;
100 }
101
102 static struct uvcg_frame *find_frame_by_index(struct uvc_device *uvc,
103                                        struct uvcg_format *uformat,
104                                        int index)
105 {
106         struct uvcg_format_ptr *format;
107         struct uvcg_frame_ptr *frame;
108         struct uvcg_frame *uframe = NULL;
109
110         list_for_each_entry(format, &uvc->header->formats, entry) {
111                 if (format->fmt->type != uformat->type)
112                         continue;
113                 list_for_each_entry(frame, &format->fmt->frames, entry) {
114                         if (index == frame->frm->frame.b_frame_index) {
115                                 uframe = frame->frm;
116                                 break;
117                         }
118                 }
119         }
120
121         return uframe;
122 }
123
124 static struct uvcg_format *find_format_by_pix(struct uvc_device *uvc,
125                                               u32 pixelformat)
126 {
127         struct uvcg_format_ptr *format;
128         struct uvcg_format *uformat = NULL;
129
130         list_for_each_entry(format, &uvc->header->formats, entry) {
131                 const struct uvc_format_desc *fmtdesc = to_uvc_format(format->fmt);
132
133                 if (IS_ERR(fmtdesc))
134                         continue;
135
136                 if (fmtdesc->fcc == pixelformat) {
137                         uformat = format->fmt;
138                         break;
139                 }
140         }
141
142         return uformat;
143 }
144
145 static struct uvcg_frame *find_closest_frame_by_size(struct uvc_device *uvc,
146                                            struct uvcg_format *uformat,
147                                            u16 rw, u16 rh)
148 {
149         struct uvc_video *video = &uvc->video;
150         struct uvcg_format_ptr *format;
151         struct uvcg_frame_ptr *frame;
152         struct uvcg_frame *uframe = NULL;
153         unsigned int d, maxd;
154
155         /* Find the closest image size. The distance between image sizes is
156          * the size in pixels of the non-overlapping regions between the
157          * requested size and the frame-specified size.
158          */
159         maxd = (unsigned int)-1;
160
161         list_for_each_entry(format, &uvc->header->formats, entry) {
162                 if (format->fmt->type != uformat->type)
163                         continue;
164
165                 list_for_each_entry(frame, &format->fmt->frames, entry) {
166                         u16 w, h;
167
168                         w = frame->frm->frame.w_width;
169                         h = frame->frm->frame.w_height;
170
171                         d = min(w, rw) * min(h, rh);
172                         d = w*h + rw*rh - 2*d;
173                         if (d < maxd) {
174                                 maxd = d;
175                                 uframe = frame->frm;
176                         }
177
178                         if (maxd == 0)
179                                 break;
180                 }
181         }
182
183         if (!uframe)
184                 uvcg_dbg(&video->uvc->func, "Unsupported size %ux%u\n", rw, rh);
185
186         return uframe;
187 }
188
189 /* --------------------------------------------------------------------------
190  * Requests handling
191  */
192
193 static int
194 uvc_send_response(struct uvc_device *uvc, struct uvc_request_data *data)
195 {
196         struct usb_composite_dev *cdev = uvc->func.config->cdev;
197         struct usb_request *req = uvc->control_req;
198
199         if (data->length < 0)
200                 return usb_ep_set_halt(cdev->gadget->ep0);
201
202         req->length = min_t(unsigned int, uvc->event_length, data->length);
203         req->zero = data->length < uvc->event_length;
204
205         memcpy(req->buf, data->data, req->length);
206
207         return usb_ep_queue(cdev->gadget->ep0, req, GFP_KERNEL);
208 }
209
210 /* --------------------------------------------------------------------------
211  * V4L2 ioctls
212  */
213
214 static int
215 uvc_v4l2_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
216 {
217         struct video_device *vdev = video_devdata(file);
218         struct uvc_device *uvc = video_get_drvdata(vdev);
219         struct usb_composite_dev *cdev = uvc->func.config->cdev;
220
221         strscpy(cap->driver, "g_uvc", sizeof(cap->driver));
222         strscpy(cap->card, cdev->gadget->name, sizeof(cap->card));
223         strscpy(cap->bus_info, dev_name(&cdev->gadget->dev),
224                 sizeof(cap->bus_info));
225         return 0;
226 }
227
228 static int
229 uvc_v4l2_get_format(struct file *file, void *fh, struct v4l2_format *fmt)
230 {
231         struct video_device *vdev = video_devdata(file);
232         struct uvc_device *uvc = video_get_drvdata(vdev);
233         struct uvc_video *video = &uvc->video;
234
235         fmt->fmt.pix.pixelformat = video->fcc;
236         fmt->fmt.pix.width = video->width;
237         fmt->fmt.pix.height = video->height;
238         fmt->fmt.pix.field = V4L2_FIELD_NONE;
239         fmt->fmt.pix.bytesperline = video->bpp * video->width / 8;
240         fmt->fmt.pix.sizeimage = video->imagesize;
241         fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
242         fmt->fmt.pix.priv = 0;
243
244         return 0;
245 }
246
247 static int
248 uvc_v4l2_try_format(struct file *file, void *fh, struct v4l2_format *fmt)
249 {
250         struct video_device *vdev = video_devdata(file);
251         struct uvc_device *uvc = video_get_drvdata(vdev);
252         struct uvc_video *video = &uvc->video;
253         struct uvcg_format *uformat;
254         struct uvcg_frame *uframe;
255         const struct uvc_format_desc *fmtdesc;
256         u8 *fcc;
257
258         if (fmt->type != video->queue.queue.type)
259                 return -EINVAL;
260
261         fcc = (u8 *)&fmt->fmt.pix.pixelformat;
262         uvcg_dbg(&uvc->func, "Trying format 0x%08x (%c%c%c%c): %ux%u\n",
263                 fmt->fmt.pix.pixelformat,
264                 fcc[0], fcc[1], fcc[2], fcc[3],
265                 fmt->fmt.pix.width, fmt->fmt.pix.height);
266
267         uformat = find_format_by_pix(uvc, fmt->fmt.pix.pixelformat);
268         if (!uformat)
269                 return -EINVAL;
270
271         uframe = find_closest_frame_by_size(uvc, uformat,
272                                 fmt->fmt.pix.width, fmt->fmt.pix.height);
273         if (!uframe)
274                 return -EINVAL;
275
276         if (uformat->type == UVCG_UNCOMPRESSED) {
277                 struct uvcg_uncompressed *u =
278                         to_uvcg_uncompressed(&uformat->group.cg_item);
279                 if (!u)
280                         return 0;
281
282                 v4l2_fill_pixfmt(&fmt->fmt.pix, fmt->fmt.pix.pixelformat,
283                                  uframe->frame.w_width, uframe->frame.w_height);
284
285                 if (fmt->fmt.pix.sizeimage != (uvc_v4l2_get_bytesperline(uformat, uframe) *
286                                                 uframe->frame.w_height))
287                         return -EINVAL;
288         } else {
289                 fmt->fmt.pix.width = uframe->frame.w_width;
290                 fmt->fmt.pix.height = uframe->frame.w_height;
291                 fmt->fmt.pix.bytesperline = uvc_v4l2_get_bytesperline(uformat, uframe);
292                 fmt->fmt.pix.sizeimage = uvc_get_frame_size(uformat, uframe);
293                 fmtdesc = to_uvc_format(uformat);
294                 if (IS_ERR(fmtdesc))
295                         return PTR_ERR(fmtdesc);
296                 fmt->fmt.pix.pixelformat = fmtdesc->fcc;
297         }
298         fmt->fmt.pix.field = V4L2_FIELD_NONE;
299         fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
300         fmt->fmt.pix.priv = 0;
301
302         return 0;
303 }
304
305 static int
306 uvc_v4l2_set_format(struct file *file, void *fh, struct v4l2_format *fmt)
307 {
308         struct video_device *vdev = video_devdata(file);
309         struct uvc_device *uvc = video_get_drvdata(vdev);
310         struct uvc_video *video = &uvc->video;
311         int ret;
312
313         ret = uvc_v4l2_try_format(file, fh, fmt);
314         if (ret)
315                 return ret;
316
317         video->fcc = fmt->fmt.pix.pixelformat;
318         video->bpp = fmt->fmt.pix.bytesperline * 8 / video->width;
319         video->width = fmt->fmt.pix.width;
320         video->height = fmt->fmt.pix.height;
321         video->imagesize = fmt->fmt.pix.sizeimage;
322
323         return ret;
324 }
325
326 static int uvc_v4l2_g_parm(struct file *file, void *fh,
327                            struct v4l2_streamparm *parm)
328 {
329         struct video_device *vdev = video_devdata(file);
330         struct uvc_device *uvc = video_get_drvdata(vdev);
331         struct uvc_video *video = &uvc->video;
332         struct v4l2_fract timeperframe;
333
334         if (!V4L2_TYPE_IS_OUTPUT(parm->type))
335                 return -EINVAL;
336
337         /* Return the actual frame period. */
338         timeperframe.numerator = video->interval;
339         timeperframe.denominator = 10000000;
340         v4l2_simplify_fraction(&timeperframe.numerator,
341                                &timeperframe.denominator, 8, 333);
342
343         uvcg_dbg(&uvc->func, "Getting frame interval of %u/%u (%u)\n",
344                  timeperframe.numerator, timeperframe.denominator,
345                  video->interval);
346
347         parm->parm.output.timeperframe = timeperframe;
348         parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
349
350         return 0;
351 }
352
353 static int uvc_v4l2_s_parm(struct file *file, void *fh,
354                            struct v4l2_streamparm *parm)
355 {
356         struct video_device *vdev = video_devdata(file);
357         struct uvc_device *uvc = video_get_drvdata(vdev);
358         struct uvc_video *video = &uvc->video;
359         struct v4l2_fract timeperframe;
360
361         if (!V4L2_TYPE_IS_OUTPUT(parm->type))
362                 return -EINVAL;
363
364         timeperframe = parm->parm.output.timeperframe;
365
366         video->interval = v4l2_fraction_to_interval(timeperframe.numerator,
367                                                     timeperframe.denominator);
368
369         uvcg_dbg(&uvc->func, "Setting frame interval to %u/%u (%u)\n",
370                  timeperframe.numerator, timeperframe.denominator,
371                  video->interval);
372
373         return 0;
374 }
375
376 static int
377 uvc_v4l2_enum_frameintervals(struct file *file, void *fh,
378                 struct v4l2_frmivalenum *fival)
379 {
380         struct video_device *vdev = video_devdata(file);
381         struct uvc_device *uvc = video_get_drvdata(vdev);
382         struct uvcg_format *uformat = NULL;
383         struct uvcg_frame *uframe = NULL;
384         struct uvcg_frame_ptr *frame;
385
386         uformat = find_format_by_pix(uvc, fival->pixel_format);
387         if (!uformat)
388                 return -EINVAL;
389
390         list_for_each_entry(frame, &uformat->frames, entry) {
391                 if (frame->frm->frame.w_width == fival->width &&
392                     frame->frm->frame.w_height == fival->height) {
393                         uframe = frame->frm;
394                         break;
395                 }
396         }
397         if (!uframe)
398                 return -EINVAL;
399
400         if (fival->index >= uframe->frame.b_frame_interval_type)
401                 return -EINVAL;
402
403         fival->discrete.numerator =
404                 uframe->dw_frame_interval[fival->index];
405
406         /* TODO: handle V4L2_FRMIVAL_TYPE_STEPWISE */
407         fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
408         fival->discrete.denominator = 10000000;
409         v4l2_simplify_fraction(&fival->discrete.numerator,
410                 &fival->discrete.denominator, 8, 333);
411
412         return 0;
413 }
414
415 static int
416 uvc_v4l2_enum_framesizes(struct file *file, void *fh,
417                 struct v4l2_frmsizeenum *fsize)
418 {
419         struct video_device *vdev = video_devdata(file);
420         struct uvc_device *uvc = video_get_drvdata(vdev);
421         struct uvcg_format *uformat = NULL;
422         struct uvcg_frame *uframe = NULL;
423
424         uformat = find_format_by_pix(uvc, fsize->pixel_format);
425         if (!uformat)
426                 return -EINVAL;
427
428         if (fsize->index >= uformat->num_frames)
429                 return -EINVAL;
430
431         uframe = find_frame_by_index(uvc, uformat, fsize->index + 1);
432         if (!uframe)
433                 return -EINVAL;
434
435         fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
436         fsize->discrete.width = uframe->frame.w_width;
437         fsize->discrete.height = uframe->frame.w_height;
438
439         return 0;
440 }
441
442 static int
443 uvc_v4l2_enum_format(struct file *file, void *fh, struct v4l2_fmtdesc *f)
444 {
445         struct video_device *vdev = video_devdata(file);
446         struct uvc_device *uvc = video_get_drvdata(vdev);
447         const struct uvc_format_desc *fmtdesc;
448         struct uvcg_format *uformat;
449
450         if (f->index >= uvc->header->num_fmt)
451                 return -EINVAL;
452
453         uformat = find_format_by_index(uvc, f->index + 1);
454         if (!uformat)
455                 return -EINVAL;
456
457         fmtdesc = to_uvc_format(uformat);
458         if (IS_ERR(fmtdesc))
459                 return PTR_ERR(fmtdesc);
460
461         f->pixelformat = fmtdesc->fcc;
462
463         return 0;
464 }
465
466 static int
467 uvc_v4l2_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *b)
468 {
469         struct video_device *vdev = video_devdata(file);
470         struct uvc_device *uvc = video_get_drvdata(vdev);
471         struct uvc_video *video = &uvc->video;
472
473         if (b->type != video->queue.queue.type)
474                 return -EINVAL;
475
476         return uvcg_alloc_buffers(&video->queue, b);
477 }
478
479 static int
480 uvc_v4l2_querybuf(struct file *file, void *fh, struct v4l2_buffer *b)
481 {
482         struct video_device *vdev = video_devdata(file);
483         struct uvc_device *uvc = video_get_drvdata(vdev);
484         struct uvc_video *video = &uvc->video;
485
486         return uvcg_query_buffer(&video->queue, b);
487 }
488
489 static int
490 uvc_v4l2_qbuf(struct file *file, void *fh, struct v4l2_buffer *b)
491 {
492         struct video_device *vdev = video_devdata(file);
493         struct uvc_device *uvc = video_get_drvdata(vdev);
494         struct uvc_video *video = &uvc->video;
495         int ret;
496
497         ret = uvcg_queue_buffer(&video->queue, b);
498         if (ret < 0)
499                 return ret;
500
501         if (uvc->state == UVC_STATE_STREAMING)
502                 queue_work(video->async_wq, &video->pump);
503
504         return ret;
505 }
506
507 static int
508 uvc_v4l2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
509 {
510         struct video_device *vdev = video_devdata(file);
511         struct uvc_device *uvc = video_get_drvdata(vdev);
512         struct uvc_video *video = &uvc->video;
513
514         return uvcg_dequeue_buffer(&video->queue, b, file->f_flags & O_NONBLOCK);
515 }
516
517 static int
518 uvc_v4l2_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
519 {
520         struct video_device *vdev = video_devdata(file);
521         struct uvc_device *uvc = video_get_drvdata(vdev);
522         struct uvc_video *video = &uvc->video;
523         int ret;
524
525         if (type != video->queue.queue.type)
526                 return -EINVAL;
527
528         /* Enable UVC video. */
529         ret = uvcg_video_enable(video);
530         if (ret < 0)
531                 return ret;
532
533         /*
534          * Complete the alternate setting selection setup phase now that
535          * userspace is ready to provide video frames.
536          */
537         uvc_function_setup_continue(uvc, 0);
538         uvc->state = UVC_STATE_STREAMING;
539
540         return 0;
541 }
542
543 static int
544 uvc_v4l2_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
545 {
546         struct video_device *vdev = video_devdata(file);
547         struct uvc_device *uvc = video_get_drvdata(vdev);
548         struct uvc_video *video = &uvc->video;
549         int ret = 0;
550
551         if (type != video->queue.queue.type)
552                 return -EINVAL;
553
554         ret = uvcg_video_disable(video);
555         if (ret < 0)
556                 return ret;
557
558         if (uvc->state != UVC_STATE_STREAMING)
559                 return 0;
560
561         uvc->state = UVC_STATE_CONNECTED;
562         uvc_function_setup_continue(uvc, 1);
563         return 0;
564 }
565
566 static int
567 uvc_v4l2_subscribe_event(struct v4l2_fh *fh,
568                          const struct v4l2_event_subscription *sub)
569 {
570         struct uvc_device *uvc = video_get_drvdata(fh->vdev);
571         struct uvc_file_handle *handle = to_uvc_file_handle(fh);
572         int ret;
573
574         if (sub->type < UVC_EVENT_FIRST || sub->type > UVC_EVENT_LAST)
575                 return -EINVAL;
576
577         if (sub->type == UVC_EVENT_SETUP && uvc->func_connected)
578                 return -EBUSY;
579
580         ret = v4l2_event_subscribe(fh, sub, 2, NULL);
581         if (ret < 0)
582                 return ret;
583
584         if (sub->type == UVC_EVENT_SETUP) {
585                 uvc->func_connected = true;
586                 handle->is_uvc_app_handle = true;
587                 uvc_function_connect(uvc);
588         }
589
590         return 0;
591 }
592
593 static void uvc_v4l2_disable(struct uvc_device *uvc)
594 {
595         uvc_function_disconnect(uvc);
596         uvcg_video_disable(&uvc->video);
597         uvcg_free_buffers(&uvc->video.queue);
598         uvc->func_connected = false;
599         wake_up_interruptible(&uvc->func_connected_queue);
600 }
601
602 static int
603 uvc_v4l2_unsubscribe_event(struct v4l2_fh *fh,
604                            const struct v4l2_event_subscription *sub)
605 {
606         struct uvc_device *uvc = video_get_drvdata(fh->vdev);
607         struct uvc_file_handle *handle = to_uvc_file_handle(fh);
608         int ret;
609
610         ret = v4l2_event_unsubscribe(fh, sub);
611         if (ret < 0)
612                 return ret;
613
614         if (sub->type == UVC_EVENT_SETUP && handle->is_uvc_app_handle) {
615                 uvc_v4l2_disable(uvc);
616                 handle->is_uvc_app_handle = false;
617         }
618
619         return 0;
620 }
621
622 static long
623 uvc_v4l2_ioctl_default(struct file *file, void *fh, bool valid_prio,
624                        unsigned int cmd, void *arg)
625 {
626         struct video_device *vdev = video_devdata(file);
627         struct uvc_device *uvc = video_get_drvdata(vdev);
628
629         switch (cmd) {
630         case UVCIOC_SEND_RESPONSE:
631                 return uvc_send_response(uvc, arg);
632
633         default:
634                 return -ENOIOCTLCMD;
635         }
636 }
637
638 const struct v4l2_ioctl_ops uvc_v4l2_ioctl_ops = {
639         .vidioc_querycap = uvc_v4l2_querycap,
640         .vidioc_try_fmt_vid_out = uvc_v4l2_try_format,
641         .vidioc_g_fmt_vid_out = uvc_v4l2_get_format,
642         .vidioc_s_fmt_vid_out = uvc_v4l2_set_format,
643         .vidioc_enum_frameintervals = uvc_v4l2_enum_frameintervals,
644         .vidioc_enum_framesizes = uvc_v4l2_enum_framesizes,
645         .vidioc_enum_fmt_vid_out = uvc_v4l2_enum_format,
646         .vidioc_reqbufs = uvc_v4l2_reqbufs,
647         .vidioc_querybuf = uvc_v4l2_querybuf,
648         .vidioc_qbuf = uvc_v4l2_qbuf,
649         .vidioc_dqbuf = uvc_v4l2_dqbuf,
650         .vidioc_streamon = uvc_v4l2_streamon,
651         .vidioc_streamoff = uvc_v4l2_streamoff,
652         .vidioc_s_parm = uvc_v4l2_s_parm,
653         .vidioc_g_parm = uvc_v4l2_g_parm,
654         .vidioc_subscribe_event = uvc_v4l2_subscribe_event,
655         .vidioc_unsubscribe_event = uvc_v4l2_unsubscribe_event,
656         .vidioc_default = uvc_v4l2_ioctl_default,
657 };
658
659 /* --------------------------------------------------------------------------
660  * V4L2
661  */
662
663 static int
664 uvc_v4l2_open(struct file *file)
665 {
666         struct video_device *vdev = video_devdata(file);
667         struct uvc_device *uvc = video_get_drvdata(vdev);
668         struct uvc_file_handle *handle;
669
670         handle = kzalloc(sizeof(*handle), GFP_KERNEL);
671         if (handle == NULL)
672                 return -ENOMEM;
673
674         v4l2_fh_init(&handle->vfh, vdev);
675         v4l2_fh_add(&handle->vfh);
676
677         handle->device = &uvc->video;
678         file->private_data = &handle->vfh;
679
680         return 0;
681 }
682
683 static int
684 uvc_v4l2_release(struct file *file)
685 {
686         struct video_device *vdev = video_devdata(file);
687         struct uvc_device *uvc = video_get_drvdata(vdev);
688         struct uvc_file_handle *handle = to_uvc_file_handle(file->private_data);
689         struct uvc_video *video = handle->device;
690
691         mutex_lock(&video->mutex);
692         if (handle->is_uvc_app_handle)
693                 uvc_v4l2_disable(uvc);
694         mutex_unlock(&video->mutex);
695
696         file->private_data = NULL;
697         v4l2_fh_del(&handle->vfh);
698         v4l2_fh_exit(&handle->vfh);
699         kfree(handle);
700
701         return 0;
702 }
703
704 static int
705 uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
706 {
707         struct video_device *vdev = video_devdata(file);
708         struct uvc_device *uvc = video_get_drvdata(vdev);
709
710         return uvcg_queue_mmap(&uvc->video.queue, vma);
711 }
712
713 static __poll_t
714 uvc_v4l2_poll(struct file *file, poll_table *wait)
715 {
716         struct video_device *vdev = video_devdata(file);
717         struct uvc_device *uvc = video_get_drvdata(vdev);
718
719         return uvcg_queue_poll(&uvc->video.queue, file, wait);
720 }
721
722 #ifndef CONFIG_MMU
723 static unsigned long uvcg_v4l2_get_unmapped_area(struct file *file,
724                 unsigned long addr, unsigned long len, unsigned long pgoff,
725                 unsigned long flags)
726 {
727         struct video_device *vdev = video_devdata(file);
728         struct uvc_device *uvc = video_get_drvdata(vdev);
729
730         return uvcg_queue_get_unmapped_area(&uvc->video.queue, pgoff);
731 }
732 #endif
733
734 const struct v4l2_file_operations uvc_v4l2_fops = {
735         .owner          = THIS_MODULE,
736         .open           = uvc_v4l2_open,
737         .release        = uvc_v4l2_release,
738         .unlocked_ioctl = video_ioctl2,
739         .mmap           = uvc_v4l2_mmap,
740         .poll           = uvc_v4l2_poll,
741 #ifndef CONFIG_MMU
742         .get_unmapped_area = uvcg_v4l2_get_unmapped_area,
743 #endif
744 };
This page took 0.067199 seconds and 4 git commands to generate.