2 * Video capture interface for Linux version 2
4 * A generic video device interface for the LINUX operating system
5 * using a set of device structures/vectors for low level operations.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
12 * Authors: Alan Cox, <alan@redhat.com> (version 1)
13 * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
15 * Fixes: 20000516 Claudio Matsuoka <claudio@conectiva.com>
16 * - Added procfs support
19 #define dbgarg(cmd, fmt, arg...) \
20 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \
21 printk (KERN_DEBUG "%s: ", vfd->name); \
22 v4l_printk_ioctl(cmd); \
23 printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg); \
26 #define dbgarg2(fmt, arg...) \
27 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \
28 printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg);
30 #include <linux/module.h>
31 #include <linux/types.h>
32 #include <linux/kernel.h>
34 #include <linux/string.h>
35 #include <linux/errno.h>
36 #include <linux/init.h>
37 #include <linux/kmod.h>
38 #include <linux/slab.h>
39 #include <asm/uaccess.h>
40 #include <asm/system.h>
42 #define __OLD_VIDIOC_ /* To allow fixing old calls*/
43 #include <linux/videodev2.h>
45 #ifdef CONFIG_VIDEO_V4L1
46 #include <linux/videodev.h>
48 #include <media/v4l2-common.h>
50 #define VIDEO_NUM_DEVICES 256
51 #define VIDEO_NAME "video4linux"
57 static ssize_t show_name(struct device *cd,
58 struct device_attribute *attr, char *buf)
60 struct video_device *vfd = container_of(cd, struct video_device,
62 return sprintf(buf, "%.*s\n", (int)sizeof(vfd->name), vfd->name);
65 struct video_device *video_device_alloc(void)
67 struct video_device *vfd;
69 vfd = kzalloc(sizeof(*vfd),GFP_KERNEL);
73 void video_device_release(struct video_device *vfd)
78 static void video_release(struct device *cd)
80 struct video_device *vfd = container_of(cd, struct video_device,
84 /* needed until all drivers are fixed */
91 static struct device_attribute video_device_attrs[] = {
92 __ATTR(name, S_IRUGO, show_name, NULL),
96 static struct class video_class = {
98 .dev_attrs = video_device_attrs,
99 .dev_release = video_release,
106 static struct video_device *video_device[VIDEO_NUM_DEVICES];
107 static DEFINE_MUTEX(videodev_lock);
109 struct video_device* video_devdata(struct file *file)
111 return video_device[iminor(file->f_path.dentry->d_inode)];
115 * Open a video device - FIXME: Obsoleted
117 static int video_open(struct inode *inode, struct file *file)
119 unsigned int minor = iminor(inode);
121 struct video_device *vfl;
122 const struct file_operations *old_fops;
124 if(minor>=VIDEO_NUM_DEVICES)
126 mutex_lock(&videodev_lock);
127 vfl=video_device[minor];
129 mutex_unlock(&videodev_lock);
130 request_module("char-major-%d-%d", VIDEO_MAJOR, minor);
131 mutex_lock(&videodev_lock);
132 vfl=video_device[minor];
134 mutex_unlock(&videodev_lock);
138 old_fops = file->f_op;
139 file->f_op = fops_get(vfl->fops);
141 err = file->f_op->open(inode,file);
143 fops_put(file->f_op);
144 file->f_op = fops_get(old_fops);
147 mutex_unlock(&videodev_lock);
152 * helper function -- handles userspace copying for ioctl arguments
157 video_fix_command(unsigned int cmd)
160 case VIDIOC_OVERLAY_OLD:
161 cmd = VIDIOC_OVERLAY;
163 case VIDIOC_S_PARM_OLD:
166 case VIDIOC_S_CTRL_OLD:
169 case VIDIOC_G_AUDIO_OLD:
170 cmd = VIDIOC_G_AUDIO;
172 case VIDIOC_G_AUDOUT_OLD:
173 cmd = VIDIOC_G_AUDOUT;
175 case VIDIOC_CROPCAP_OLD:
176 cmd = VIDIOC_CROPCAP;
184 * Obsolete usercopy function - Should be removed soon
187 video_usercopy(struct inode *inode, struct file *file,
188 unsigned int cmd, unsigned long arg,
189 int (*func)(struct inode *inode, struct file *file,
190 unsigned int cmd, void *arg))
197 size_t ctrls_size = 0;
198 void __user *user_ptr = NULL;
201 cmd = video_fix_command(cmd);
203 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
204 cmd == VIDIOC_TRY_EXT_CTRLS);
206 /* Copy arguments into temp kernel buffer */
207 switch (_IOC_DIR(cmd)) {
213 case (_IOC_WRITE | _IOC_READ):
214 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
217 /* too big to allocate from stack */
218 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
225 if (_IOC_DIR(cmd) & _IOC_WRITE)
226 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
231 struct v4l2_ext_controls *p = parg;
233 /* In case of an error, tell the caller that it wasn't
234 a specific control that caused it. */
235 p->error_idx = p->count;
236 user_ptr = (void __user *)p->controls;
238 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
239 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
240 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
245 if (copy_from_user(mbuf, user_ptr, ctrls_size))
252 err = func(inode, file, cmd, parg);
253 if (err == -ENOIOCTLCMD)
256 struct v4l2_ext_controls *p = parg;
258 p->controls = (void *)user_ptr;
259 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
267 /* Copy results into user buffer */
268 switch (_IOC_DIR(cmd))
271 case (_IOC_WRITE | _IOC_READ):
272 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
283 * open/release helper functions -- handle exclusive opens
284 * Should be removed soon
286 int video_exclusive_open(struct inode *inode, struct file *file)
288 struct video_device *vfl = video_devdata(file);
291 mutex_lock(&vfl->lock);
297 mutex_unlock(&vfl->lock);
301 int video_exclusive_release(struct inode *inode, struct file *file)
303 struct video_device *vfl = video_devdata(file);
309 static char *v4l2_memory_names[] = {
310 [V4L2_MEMORY_MMAP] = "mmap",
311 [V4L2_MEMORY_USERPTR] = "userptr",
312 [V4L2_MEMORY_OVERLAY] = "overlay",
316 /* FIXME: Those stuff are replicated also on v4l2-common.c */
317 static char *v4l2_type_names_FIXME[] = {
318 [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap",
319 [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over",
320 [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out",
321 [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
322 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
323 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
324 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-capture",
325 [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over",
326 [V4L2_BUF_TYPE_PRIVATE] = "private",
329 static char *v4l2_field_names_FIXME[] = {
330 [V4L2_FIELD_ANY] = "any",
331 [V4L2_FIELD_NONE] = "none",
332 [V4L2_FIELD_TOP] = "top",
333 [V4L2_FIELD_BOTTOM] = "bottom",
334 [V4L2_FIELD_INTERLACED] = "interlaced",
335 [V4L2_FIELD_SEQ_TB] = "seq-tb",
336 [V4L2_FIELD_SEQ_BT] = "seq-bt",
337 [V4L2_FIELD_ALTERNATE] = "alternate",
338 [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb",
339 [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt",
342 #define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
344 static void dbgbuf(unsigned int cmd, struct video_device *vfd,
345 struct v4l2_buffer *p)
347 struct v4l2_timecode *tc=&p->timecode;
349 dbgarg (cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
350 "bytesused=%d, flags=0x%08d, "
351 "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n",
352 (p->timestamp.tv_sec/3600),
353 (int)(p->timestamp.tv_sec/60)%60,
354 (int)(p->timestamp.tv_sec%60),
355 p->timestamp.tv_usec,
357 prt_names(p->type,v4l2_type_names_FIXME),
358 p->bytesused,p->flags,
359 p->field,p->sequence,
360 prt_names(p->memory,v4l2_memory_names),
361 p->m.userptr, p->length);
362 dbgarg2 ("timecode= %02d:%02d:%02d type=%d, "
363 "flags=0x%08d, frames=%d, userbits=0x%08x\n",
364 tc->hours,tc->minutes,tc->seconds,
365 tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits);
368 static inline void dbgrect(struct video_device *vfd, char *s,
371 dbgarg2 ("%sRect start at %dx%d, size= %dx%d\n", s, r->left, r->top,
372 r->width, r->height);
375 static inline void v4l_print_pix_fmt (struct video_device *vfd,
376 struct v4l2_pix_format *fmt)
378 dbgarg2 ("width=%d, height=%d, format=%c%c%c%c, field=%s, "
379 "bytesperline=%d sizeimage=%d, colorspace=%d\n",
380 fmt->width,fmt->height,
381 (fmt->pixelformat & 0xff),
382 (fmt->pixelformat >> 8) & 0xff,
383 (fmt->pixelformat >> 16) & 0xff,
384 (fmt->pixelformat >> 24) & 0xff,
385 prt_names(fmt->field,v4l2_field_names_FIXME),
386 fmt->bytesperline,fmt->sizeimage,fmt->colorspace);
390 static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type)
393 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
394 if (vfd->vidioc_try_fmt_cap)
397 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
398 if (vfd->vidioc_try_fmt_overlay)
401 case V4L2_BUF_TYPE_VBI_CAPTURE:
402 if (vfd->vidioc_try_fmt_vbi)
405 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
406 if (vfd->vidioc_try_fmt_vbi_output)
409 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
410 if (vfd->vidioc_try_fmt_vbi_capture)
413 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
414 if (vfd->vidioc_try_fmt_video_output)
417 case V4L2_BUF_TYPE_VBI_OUTPUT:
418 if (vfd->vidioc_try_fmt_vbi_output)
421 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
422 if (vfd->vidioc_try_fmt_output_overlay)
425 case V4L2_BUF_TYPE_PRIVATE:
426 if (vfd->vidioc_try_fmt_type_private)
433 static int __video_do_ioctl(struct inode *inode, struct file *file,
434 unsigned int cmd, void *arg)
436 struct video_device *vfd = video_devdata(file);
437 void *fh = file->private_data;
440 if ( (vfd->debug & V4L2_DEBUG_IOCTL) &&
441 !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) {
442 v4l_print_ioctl(vfd->name, cmd);
445 #ifdef CONFIG_VIDEO_V4L1_COMPAT
446 /***********************************************************
447 Handles calls to the obsoleted V4L1 API
448 Due to the nature of VIDIOCGMBUF, each driver that supports
449 V4L1 should implement its own handler for this ioctl.
450 ***********************************************************/
452 /* --- streaming capture ------------------------------------- */
453 if (cmd == VIDIOCGMBUF) {
454 struct video_mbuf *p=arg;
456 memset(p, 0, sizeof(*p));
458 if (!vfd->vidiocgmbuf)
460 ret=vfd->vidiocgmbuf(file, fh, p);
462 dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
464 (unsigned long)p->offsets);
468 /********************************************************
469 All other V4L1 calls are handled by v4l1_compat module.
470 Those calls will be translated into V4L2 calls, and
471 __video_do_ioctl will be called again, with one or more
473 ********************************************************/
474 if (_IOC_TYPE(cmd)=='v')
475 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
480 /* --- capabilities ------------------------------------------ */
481 case VIDIOC_QUERYCAP:
483 struct v4l2_capability *cap = (struct v4l2_capability*)arg;
484 memset(cap, 0, sizeof(*cap));
486 if (!vfd->vidioc_querycap)
489 ret=vfd->vidioc_querycap(file, fh, cap);
491 dbgarg (cmd, "driver=%s, card=%s, bus=%s, "
493 "capabilities=0x%08x\n",
494 cap->driver,cap->card,cap->bus_info,
500 /* --- priority ------------------------------------------ */
501 case VIDIOC_G_PRIORITY:
503 enum v4l2_priority *p=arg;
505 if (!vfd->vidioc_g_priority)
507 ret=vfd->vidioc_g_priority(file, fh, p);
509 dbgarg(cmd, "priority is %d\n", *p);
512 case VIDIOC_S_PRIORITY:
514 enum v4l2_priority *p=arg;
516 if (!vfd->vidioc_s_priority)
518 dbgarg(cmd, "setting priority to %d\n", *p);
519 ret=vfd->vidioc_s_priority(file, fh, *p);
523 /* --- capture ioctls ---------------------------------------- */
524 case VIDIOC_ENUM_FMT:
526 struct v4l2_fmtdesc *f = arg;
527 enum v4l2_buf_type type;
532 memset(f,0,sizeof(*f));
537 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
538 if (vfd->vidioc_enum_fmt_cap)
539 ret=vfd->vidioc_enum_fmt_cap(file, fh, f);
541 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
542 if (vfd->vidioc_enum_fmt_overlay)
543 ret=vfd->vidioc_enum_fmt_overlay(file, fh, f);
545 case V4L2_BUF_TYPE_VBI_CAPTURE:
546 if (vfd->vidioc_enum_fmt_vbi)
547 ret=vfd->vidioc_enum_fmt_vbi(file, fh, f);
549 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
550 if (vfd->vidioc_enum_fmt_vbi_output)
551 ret=vfd->vidioc_enum_fmt_vbi_output(file,
554 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
555 if (vfd->vidioc_enum_fmt_vbi_capture)
556 ret=vfd->vidioc_enum_fmt_vbi_capture(file,
559 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
560 if (vfd->vidioc_enum_fmt_video_output)
561 ret=vfd->vidioc_enum_fmt_video_output(file,
564 case V4L2_BUF_TYPE_VBI_OUTPUT:
565 if (vfd->vidioc_enum_fmt_vbi_output)
566 ret=vfd->vidioc_enum_fmt_vbi_output(file,
569 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
570 if (vfd->vidioc_enum_fmt_output_overlay)
571 ret=vfd->vidioc_enum_fmt_output_overlay(file, fh, f);
573 case V4L2_BUF_TYPE_PRIVATE:
574 if (vfd->vidioc_enum_fmt_type_private)
575 ret=vfd->vidioc_enum_fmt_type_private(file,
580 dbgarg (cmd, "index=%d, type=%d, flags=%d, "
581 "pixelformat=%c%c%c%c, description='%s'\n",
582 f->index, f->type, f->flags,
583 (f->pixelformat & 0xff),
584 (f->pixelformat >> 8) & 0xff,
585 (f->pixelformat >> 16) & 0xff,
586 (f->pixelformat >> 24) & 0xff,
592 struct v4l2_format *f = (struct v4l2_format *)arg;
593 enum v4l2_buf_type type=f->type;
595 memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
598 /* FIXME: Should be one dump per type */
599 dbgarg (cmd, "type=%s\n", prt_names(type,
600 v4l2_type_names_FIXME));
603 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
604 if (vfd->vidioc_g_fmt_cap)
605 ret=vfd->vidioc_g_fmt_cap(file, fh, f);
607 v4l_print_pix_fmt(vfd,&f->fmt.pix);
609 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
610 if (vfd->vidioc_g_fmt_overlay)
611 ret=vfd->vidioc_g_fmt_overlay(file, fh, f);
613 case V4L2_BUF_TYPE_VBI_CAPTURE:
614 if (vfd->vidioc_g_fmt_vbi)
615 ret=vfd->vidioc_g_fmt_vbi(file, fh, f);
617 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
618 if (vfd->vidioc_g_fmt_vbi_output)
619 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
621 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
622 if (vfd->vidioc_g_fmt_vbi_capture)
623 ret=vfd->vidioc_g_fmt_vbi_capture(file, fh, f);
625 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
626 if (vfd->vidioc_g_fmt_video_output)
627 ret=vfd->vidioc_g_fmt_video_output(file,
630 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
631 if (vfd->vidioc_g_fmt_output_overlay)
632 ret=vfd->vidioc_g_fmt_output_overlay(file, fh, f);
634 case V4L2_BUF_TYPE_VBI_OUTPUT:
635 if (vfd->vidioc_g_fmt_vbi_output)
636 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
638 case V4L2_BUF_TYPE_PRIVATE:
639 if (vfd->vidioc_g_fmt_type_private)
640 ret=vfd->vidioc_g_fmt_type_private(file,
649 struct v4l2_format *f = (struct v4l2_format *)arg;
651 /* FIXME: Should be one dump per type */
652 dbgarg (cmd, "type=%s\n", prt_names(f->type,
653 v4l2_type_names_FIXME));
656 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
657 v4l_print_pix_fmt(vfd,&f->fmt.pix);
658 if (vfd->vidioc_s_fmt_cap)
659 ret=vfd->vidioc_s_fmt_cap(file, fh, f);
661 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
662 if (vfd->vidioc_s_fmt_overlay)
663 ret=vfd->vidioc_s_fmt_overlay(file, fh, f);
665 case V4L2_BUF_TYPE_VBI_CAPTURE:
666 if (vfd->vidioc_s_fmt_vbi)
667 ret=vfd->vidioc_s_fmt_vbi(file, fh, f);
669 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
670 if (vfd->vidioc_s_fmt_vbi_output)
671 ret=vfd->vidioc_s_fmt_vbi_output(file, fh, f);
673 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
674 if (vfd->vidioc_s_fmt_vbi_capture)
675 ret=vfd->vidioc_s_fmt_vbi_capture(file, fh, f);
677 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
678 if (vfd->vidioc_s_fmt_video_output)
679 ret=vfd->vidioc_s_fmt_video_output(file,
682 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
683 if (vfd->vidioc_s_fmt_output_overlay)
684 ret=vfd->vidioc_s_fmt_output_overlay(file, fh, f);
686 case V4L2_BUF_TYPE_VBI_OUTPUT:
687 if (vfd->vidioc_s_fmt_vbi_output)
688 ret=vfd->vidioc_s_fmt_vbi_output(file,
691 case V4L2_BUF_TYPE_PRIVATE:
692 if (vfd->vidioc_s_fmt_type_private)
693 ret=vfd->vidioc_s_fmt_type_private(file,
701 struct v4l2_format *f = (struct v4l2_format *)arg;
703 /* FIXME: Should be one dump per type */
704 dbgarg (cmd, "type=%s\n", prt_names(f->type,
705 v4l2_type_names_FIXME));
707 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
708 if (vfd->vidioc_try_fmt_cap)
709 ret=vfd->vidioc_try_fmt_cap(file, fh, f);
711 v4l_print_pix_fmt(vfd,&f->fmt.pix);
713 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
714 if (vfd->vidioc_try_fmt_overlay)
715 ret=vfd->vidioc_try_fmt_overlay(file, fh, f);
717 case V4L2_BUF_TYPE_VBI_CAPTURE:
718 if (vfd->vidioc_try_fmt_vbi)
719 ret=vfd->vidioc_try_fmt_vbi(file, fh, f);
721 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
722 if (vfd->vidioc_try_fmt_vbi_output)
723 ret=vfd->vidioc_try_fmt_vbi_output(file,
726 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
727 if (vfd->vidioc_try_fmt_vbi_capture)
728 ret=vfd->vidioc_try_fmt_vbi_capture(file,
731 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
732 if (vfd->vidioc_try_fmt_video_output)
733 ret=vfd->vidioc_try_fmt_video_output(file,
736 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
737 if (vfd->vidioc_try_fmt_output_overlay)
738 ret=vfd->vidioc_try_fmt_output_overlay(file, fh, f);
740 case V4L2_BUF_TYPE_VBI_OUTPUT:
741 if (vfd->vidioc_try_fmt_vbi_output)
742 ret=vfd->vidioc_try_fmt_vbi_output(file,
745 case V4L2_BUF_TYPE_PRIVATE:
746 if (vfd->vidioc_try_fmt_type_private)
747 ret=vfd->vidioc_try_fmt_type_private(file,
754 /* FIXME: Those buf reqs could be handled here,
755 with some changes on videobuf to allow its header to be included at
756 videodev2.h or being merged at videodev2.
760 struct v4l2_requestbuffers *p=arg;
762 if (!vfd->vidioc_reqbufs)
764 ret = check_fmt (vfd, p->type);
768 ret=vfd->vidioc_reqbufs(file, fh, p);
769 dbgarg (cmd, "count=%d, type=%s, memory=%s\n",
771 prt_names(p->type,v4l2_type_names_FIXME),
772 prt_names(p->memory,v4l2_memory_names));
775 case VIDIOC_QUERYBUF:
777 struct v4l2_buffer *p=arg;
779 if (!vfd->vidioc_querybuf)
781 ret = check_fmt (vfd, p->type);
785 ret=vfd->vidioc_querybuf(file, fh, p);
792 struct v4l2_buffer *p=arg;
794 if (!vfd->vidioc_qbuf)
796 ret = check_fmt (vfd, p->type);
800 ret=vfd->vidioc_qbuf(file, fh, p);
807 struct v4l2_buffer *p=arg;
808 if (!vfd->vidioc_dqbuf)
810 ret = check_fmt (vfd, p->type);
814 ret=vfd->vidioc_dqbuf(file, fh, p);
823 if (!vfd->vidioc_overlay)
825 dbgarg (cmd, "value=%d\n",*i);
826 ret=vfd->vidioc_overlay(file, fh, *i);
831 struct v4l2_framebuffer *p=arg;
832 if (!vfd->vidioc_g_fbuf)
834 ret=vfd->vidioc_g_fbuf(file, fh, arg);
836 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
837 p->capability,p->flags,
838 (unsigned long)p->base);
839 v4l_print_pix_fmt (vfd, &p->fmt);
845 struct v4l2_framebuffer *p=arg;
846 if (!vfd->vidioc_s_fbuf)
849 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
850 p->capability,p->flags,(unsigned long)p->base);
851 v4l_print_pix_fmt (vfd, &p->fmt);
852 ret=vfd->vidioc_s_fbuf(file, fh, arg);
856 case VIDIOC_STREAMON:
858 enum v4l2_buf_type i = *(int *)arg;
859 if (!vfd->vidioc_streamon)
861 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
862 ret=vfd->vidioc_streamon(file, fh,i);
865 case VIDIOC_STREAMOFF:
867 enum v4l2_buf_type i = *(int *)arg;
869 if (!vfd->vidioc_streamoff)
871 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
872 ret=vfd->vidioc_streamoff(file, fh, i);
875 /* ---------- tv norms ---------- */
878 struct v4l2_standard *p = arg;
879 v4l2_std_id id = vfd->tvnorms,curr_id=0;
880 unsigned int index = p->index,i;
887 /* Return norm array on a canonical way */
888 for (i=0;i<= index && id; i++) {
889 if ( (id & V4L2_STD_PAL) == V4L2_STD_PAL) {
890 curr_id = V4L2_STD_PAL;
891 } else if ( (id & V4L2_STD_PAL_BG) == V4L2_STD_PAL_BG) {
892 curr_id = V4L2_STD_PAL_BG;
893 } else if ( (id & V4L2_STD_PAL_DK) == V4L2_STD_PAL_DK) {
894 curr_id = V4L2_STD_PAL_DK;
895 } else if ( (id & V4L2_STD_PAL_B) == V4L2_STD_PAL_B) {
896 curr_id = V4L2_STD_PAL_B;
897 } else if ( (id & V4L2_STD_PAL_B1) == V4L2_STD_PAL_B1) {
898 curr_id = V4L2_STD_PAL_B1;
899 } else if ( (id & V4L2_STD_PAL_G) == V4L2_STD_PAL_G) {
900 curr_id = V4L2_STD_PAL_G;
901 } else if ( (id & V4L2_STD_PAL_H) == V4L2_STD_PAL_H) {
902 curr_id = V4L2_STD_PAL_H;
903 } else if ( (id & V4L2_STD_PAL_I) == V4L2_STD_PAL_I) {
904 curr_id = V4L2_STD_PAL_I;
905 } else if ( (id & V4L2_STD_PAL_D) == V4L2_STD_PAL_D) {
906 curr_id = V4L2_STD_PAL_D;
907 } else if ( (id & V4L2_STD_PAL_D1) == V4L2_STD_PAL_D1) {
908 curr_id = V4L2_STD_PAL_D1;
909 } else if ( (id & V4L2_STD_PAL_K) == V4L2_STD_PAL_K) {
910 curr_id = V4L2_STD_PAL_K;
911 } else if ( (id & V4L2_STD_PAL_M) == V4L2_STD_PAL_M) {
912 curr_id = V4L2_STD_PAL_M;
913 } else if ( (id & V4L2_STD_PAL_N) == V4L2_STD_PAL_N) {
914 curr_id = V4L2_STD_PAL_N;
915 } else if ( (id & V4L2_STD_PAL_Nc) == V4L2_STD_PAL_Nc) {
916 curr_id = V4L2_STD_PAL_Nc;
917 } else if ( (id & V4L2_STD_PAL_60) == V4L2_STD_PAL_60) {
918 curr_id = V4L2_STD_PAL_60;
919 } else if ( (id & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
920 curr_id = V4L2_STD_NTSC;
921 } else if ( (id & V4L2_STD_NTSC_M) == V4L2_STD_NTSC_M) {
922 curr_id = V4L2_STD_NTSC_M;
923 } else if ( (id & V4L2_STD_NTSC_M_JP) == V4L2_STD_NTSC_M_JP) {
924 curr_id = V4L2_STD_NTSC_M_JP;
925 } else if ( (id & V4L2_STD_NTSC_443) == V4L2_STD_NTSC_443) {
926 curr_id = V4L2_STD_NTSC_443;
927 } else if ( (id & V4L2_STD_NTSC_M_KR) == V4L2_STD_NTSC_M_KR) {
928 curr_id = V4L2_STD_NTSC_M_KR;
929 } else if ( (id & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
930 curr_id = V4L2_STD_SECAM;
931 } else if ( (id & V4L2_STD_SECAM_DK) == V4L2_STD_SECAM_DK) {
932 curr_id = V4L2_STD_SECAM_DK;
933 } else if ( (id & V4L2_STD_SECAM_B) == V4L2_STD_SECAM_B) {
934 curr_id = V4L2_STD_SECAM_B;
935 } else if ( (id & V4L2_STD_SECAM_D) == V4L2_STD_SECAM_D) {
936 curr_id = V4L2_STD_SECAM_D;
937 } else if ( (id & V4L2_STD_SECAM_G) == V4L2_STD_SECAM_G) {
938 curr_id = V4L2_STD_SECAM_G;
939 } else if ( (id & V4L2_STD_SECAM_H) == V4L2_STD_SECAM_H) {
940 curr_id = V4L2_STD_SECAM_H;
941 } else if ( (id & V4L2_STD_SECAM_K) == V4L2_STD_SECAM_K) {
942 curr_id = V4L2_STD_SECAM_K;
943 } else if ( (id & V4L2_STD_SECAM_K1) == V4L2_STD_SECAM_K1) {
944 curr_id = V4L2_STD_SECAM_K1;
945 } else if ( (id & V4L2_STD_SECAM_L) == V4L2_STD_SECAM_L) {
946 curr_id = V4L2_STD_SECAM_L;
947 } else if ( (id & V4L2_STD_SECAM_LC) == V4L2_STD_SECAM_LC) {
948 curr_id = V4L2_STD_SECAM_LC;
957 v4l2_video_std_construct(p, curr_id,v4l2_norm_to_name(curr_id));
960 dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, "
961 "framelines=%d\n", p->index,
962 (unsigned long long)p->id, p->name,
963 p->frameperiod.numerator,
964 p->frameperiod.denominator,
972 v4l2_std_id *id = arg;
974 *id = vfd->current_norm;
976 dbgarg (cmd, "value=%08Lx\n", (long long unsigned) *id);
983 v4l2_std_id *id = arg,norm;
985 dbgarg (cmd, "value=%08Lx\n", (long long unsigned) *id);
987 norm = (*id) & vfd->tvnorms;
988 if ( vfd->tvnorms && !norm) /* Check if std is supported */
991 /* Calls the specific handler */
992 if (vfd->vidioc_s_std)
993 ret=vfd->vidioc_s_std(file, fh, &norm);
997 /* Updates standard information */
999 vfd->current_norm=norm;
1003 case VIDIOC_QUERYSTD:
1007 if (!vfd->vidioc_querystd)
1009 ret=vfd->vidioc_querystd(file, fh, arg);
1011 dbgarg (cmd, "detected std=%08Lx\n",
1012 (unsigned long long)*p);
1015 /* ------ input switching ---------- */
1016 /* FIXME: Inputs can be handled inside videodev2 */
1017 case VIDIOC_ENUMINPUT:
1019 struct v4l2_input *p=arg;
1022 if (!vfd->vidioc_enum_input)
1024 memset(p, 0, sizeof(*p));
1027 ret=vfd->vidioc_enum_input(file, fh, p);
1029 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1031 "tuner=%d, std=%08Lx, status=%d\n",
1032 p->index,p->name,p->type,p->audioset,
1034 (unsigned long long)p->std,
1038 case VIDIOC_G_INPUT:
1040 unsigned int *i = arg;
1042 if (!vfd->vidioc_g_input)
1044 ret=vfd->vidioc_g_input(file, fh, i);
1046 dbgarg (cmd, "value=%d\n",*i);
1049 case VIDIOC_S_INPUT:
1051 unsigned int *i = arg;
1053 if (!vfd->vidioc_s_input)
1055 dbgarg (cmd, "value=%d\n",*i);
1056 ret=vfd->vidioc_s_input(file, fh, *i);
1060 /* ------ output switching ---------- */
1061 case VIDIOC_G_OUTPUT:
1063 unsigned int *i = arg;
1065 if (!vfd->vidioc_g_output)
1067 ret=vfd->vidioc_g_output(file, fh, i);
1069 dbgarg (cmd, "value=%d\n",*i);
1072 case VIDIOC_S_OUTPUT:
1074 unsigned int *i = arg;
1076 if (!vfd->vidioc_s_output)
1078 dbgarg (cmd, "value=%d\n",*i);
1079 ret=vfd->vidioc_s_output(file, fh, *i);
1083 /* --- controls ---------------------------------------------- */
1084 case VIDIOC_QUERYCTRL:
1086 struct v4l2_queryctrl *p=arg;
1088 if (!vfd->vidioc_queryctrl)
1090 ret=vfd->vidioc_queryctrl(file, fh, p);
1093 dbgarg (cmd, "id=%d, type=%d, name=%s, "
1095 " step=%d, default=%d, flags=0x%08x\n",
1096 p->id,p->type,p->name,p->minimum,
1097 p->maximum,p->step,p->default_value,
1103 struct v4l2_control *p = arg;
1105 if (!vfd->vidioc_g_ctrl)
1107 dbgarg(cmd, "Enum for index=%d\n", p->id);
1109 ret=vfd->vidioc_g_ctrl(file, fh, p);
1111 dbgarg2 ( "id=%d, value=%d\n", p->id, p->value);
1116 struct v4l2_control *p = arg;
1118 if (!vfd->vidioc_s_ctrl)
1120 dbgarg (cmd, "id=%d, value=%d\n", p->id, p->value);
1122 ret=vfd->vidioc_s_ctrl(file, fh, p);
1125 case VIDIOC_G_EXT_CTRLS:
1127 struct v4l2_ext_controls *p = arg;
1129 if (vfd->vidioc_g_ext_ctrls) {
1130 dbgarg(cmd, "count=%d\n", p->count);
1132 ret=vfd->vidioc_g_ext_ctrls(file, fh, p);
1136 case VIDIOC_S_EXT_CTRLS:
1138 struct v4l2_ext_controls *p = arg;
1140 if (vfd->vidioc_s_ext_ctrls) {
1141 dbgarg(cmd, "count=%d\n", p->count);
1143 ret=vfd->vidioc_s_ext_ctrls(file, fh, p);
1147 case VIDIOC_TRY_EXT_CTRLS:
1149 struct v4l2_ext_controls *p = arg;
1151 if (vfd->vidioc_try_ext_ctrls) {
1152 dbgarg(cmd, "count=%d\n", p->count);
1154 ret=vfd->vidioc_try_ext_ctrls(file, fh, p);
1158 case VIDIOC_QUERYMENU:
1160 struct v4l2_querymenu *p=arg;
1161 if (!vfd->vidioc_querymenu)
1163 ret=vfd->vidioc_querymenu(file, fh, p);
1165 dbgarg (cmd, "id=%d, index=%d, name=%s\n",
1166 p->id,p->index,p->name);
1169 /* --- audio ---------------------------------------------- */
1170 case VIDIOC_ENUMAUDIO:
1172 struct v4l2_audio *p=arg;
1174 if (!vfd->vidioc_enumaudio)
1176 dbgarg(cmd, "Enum for index=%d\n", p->index);
1177 ret=vfd->vidioc_enumaudio(file, fh, p);
1179 dbgarg2("index=%d, name=%s, capability=%d, "
1180 "mode=%d\n",p->index,p->name,
1181 p->capability, p->mode);
1184 case VIDIOC_G_AUDIO:
1186 struct v4l2_audio *p=arg;
1187 __u32 index=p->index;
1189 if (!vfd->vidioc_g_audio)
1192 memset(p,0,sizeof(*p));
1194 dbgarg(cmd, "Get for index=%d\n", p->index);
1195 ret=vfd->vidioc_g_audio(file, fh, p);
1197 dbgarg2("index=%d, name=%s, capability=%d, "
1198 "mode=%d\n",p->index,
1199 p->name,p->capability, p->mode);
1202 case VIDIOC_S_AUDIO:
1204 struct v4l2_audio *p=arg;
1206 if (!vfd->vidioc_s_audio)
1208 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1209 "mode=%d\n", p->index, p->name,
1210 p->capability, p->mode);
1211 ret=vfd->vidioc_s_audio(file, fh, p);
1214 case VIDIOC_ENUMAUDOUT:
1216 struct v4l2_audioout *p=arg;
1218 if (!vfd->vidioc_enumaudout)
1220 dbgarg(cmd, "Enum for index=%d\n", p->index);
1221 ret=vfd->vidioc_enumaudout(file, fh, p);
1223 dbgarg2("index=%d, name=%s, capability=%d, "
1224 "mode=%d\n", p->index, p->name,
1225 p->capability,p->mode);
1228 case VIDIOC_G_AUDOUT:
1230 struct v4l2_audioout *p=arg;
1232 if (!vfd->vidioc_g_audout)
1234 dbgarg(cmd, "Enum for index=%d\n", p->index);
1235 ret=vfd->vidioc_g_audout(file, fh, p);
1237 dbgarg2("index=%d, name=%s, capability=%d, "
1238 "mode=%d\n", p->index, p->name,
1239 p->capability,p->mode);
1242 case VIDIOC_S_AUDOUT:
1244 struct v4l2_audioout *p=arg;
1246 if (!vfd->vidioc_s_audout)
1248 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1249 "mode=%d\n", p->index, p->name,
1250 p->capability,p->mode);
1252 ret=vfd->vidioc_s_audout(file, fh, p);
1255 case VIDIOC_G_MODULATOR:
1257 struct v4l2_modulator *p=arg;
1258 if (!vfd->vidioc_g_modulator)
1260 ret=vfd->vidioc_g_modulator(file, fh, p);
1262 dbgarg(cmd, "index=%d, name=%s, "
1263 "capability=%d, rangelow=%d,"
1264 " rangehigh=%d, txsubchans=%d\n",
1265 p->index, p->name,p->capability,
1266 p->rangelow, p->rangehigh,
1270 case VIDIOC_S_MODULATOR:
1272 struct v4l2_modulator *p=arg;
1273 if (!vfd->vidioc_s_modulator)
1275 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1276 "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
1277 p->index, p->name,p->capability,p->rangelow,
1278 p->rangehigh,p->txsubchans);
1279 ret=vfd->vidioc_s_modulator(file, fh, p);
1284 struct v4l2_crop *p=arg;
1285 if (!vfd->vidioc_g_crop)
1287 ret=vfd->vidioc_g_crop(file, fh, p);
1289 dbgarg(cmd, "type=%d\n", p->type);
1290 dbgrect(vfd, "", &p->c);
1296 struct v4l2_crop *p=arg;
1297 if (!vfd->vidioc_s_crop)
1299 dbgarg(cmd, "type=%d\n", p->type);
1300 dbgrect(vfd, "", &p->c);
1301 ret=vfd->vidioc_s_crop(file, fh, p);
1304 case VIDIOC_CROPCAP:
1306 struct v4l2_cropcap *p=arg;
1307 /*FIXME: Should also show v4l2_fract pixelaspect */
1308 if (!vfd->vidioc_cropcap)
1310 dbgarg(cmd, "type=%d\n", p->type);
1311 dbgrect(vfd, "bounds ", &p->bounds);
1312 dbgrect(vfd, "defrect ", &p->defrect);
1313 ret=vfd->vidioc_cropcap(file, fh, p);
1316 case VIDIOC_G_JPEGCOMP:
1318 struct v4l2_jpegcompression *p=arg;
1319 if (!vfd->vidioc_g_jpegcomp)
1321 ret=vfd->vidioc_g_jpegcomp(file, fh, p);
1323 dbgarg (cmd, "quality=%d, APPn=%d, "
1324 "APP_len=%d, COM_len=%d, "
1325 "jpeg_markers=%d\n",
1326 p->quality,p->APPn,p->APP_len,
1327 p->COM_len,p->jpeg_markers);
1330 case VIDIOC_S_JPEGCOMP:
1332 struct v4l2_jpegcompression *p=arg;
1333 if (!vfd->vidioc_g_jpegcomp)
1335 dbgarg (cmd, "quality=%d, APPn=%d, APP_len=%d, "
1336 "COM_len=%d, jpeg_markers=%d\n",
1337 p->quality,p->APPn,p->APP_len,
1338 p->COM_len,p->jpeg_markers);
1339 ret=vfd->vidioc_s_jpegcomp(file, fh, p);
1342 case VIDIOC_G_ENC_INDEX:
1344 struct v4l2_enc_idx *p=arg;
1346 if (!vfd->vidioc_g_enc_index)
1348 ret=vfd->vidioc_g_enc_index(file, fh, p);
1350 dbgarg (cmd, "entries=%d, entries_cap=%d\n",
1351 p->entries,p->entries_cap);
1354 case VIDIOC_ENCODER_CMD:
1356 struct v4l2_encoder_cmd *p=arg;
1358 if (!vfd->vidioc_encoder_cmd)
1360 ret=vfd->vidioc_encoder_cmd(file, fh, p);
1362 dbgarg (cmd, "cmd=%d, flags=%d\n",
1366 case VIDIOC_TRY_ENCODER_CMD:
1368 struct v4l2_encoder_cmd *p=arg;
1370 if (!vfd->vidioc_try_encoder_cmd)
1372 ret=vfd->vidioc_try_encoder_cmd(file, fh, p);
1374 dbgarg (cmd, "cmd=%d, flags=%d\n",
1380 struct v4l2_streamparm *p=arg;
1383 memset(p,0,sizeof(*p));
1386 if (vfd->vidioc_g_parm) {
1387 ret=vfd->vidioc_g_parm(file, fh, p);
1389 struct v4l2_standard s;
1391 if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1394 v4l2_video_std_construct(&s, vfd->current_norm,
1395 v4l2_norm_to_name(vfd->current_norm));
1397 p->parm.capture.timeperframe = s.frameperiod;
1401 dbgarg (cmd, "type=%d\n", p->type);
1406 struct v4l2_streamparm *p=arg;
1407 if (!vfd->vidioc_s_parm)
1409 dbgarg (cmd, "type=%d\n", p->type);
1410 ret=vfd->vidioc_s_parm(file, fh, p);
1413 case VIDIOC_G_TUNER:
1415 struct v4l2_tuner *p=arg;
1416 __u32 index=p->index;
1418 if (!vfd->vidioc_g_tuner)
1421 memset(p,0,sizeof(*p));
1424 ret=vfd->vidioc_g_tuner(file, fh, p);
1426 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1427 "capability=%d, rangelow=%d, "
1428 "rangehigh=%d, signal=%d, afc=%d, "
1429 "rxsubchans=%d, audmode=%d\n",
1430 p->index, p->name, p->type,
1431 p->capability, p->rangelow,
1432 p->rangehigh, p->rxsubchans,
1433 p->audmode, p->signal, p->afc);
1436 case VIDIOC_S_TUNER:
1438 struct v4l2_tuner *p=arg;
1439 if (!vfd->vidioc_s_tuner)
1441 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1442 "capability=%d, rangelow=%d, rangehigh=%d, "
1443 "signal=%d, afc=%d, rxsubchans=%d, "
1444 "audmode=%d\n",p->index, p->name, p->type,
1445 p->capability, p->rangelow,p->rangehigh,
1446 p->rxsubchans, p->audmode, p->signal,
1448 ret=vfd->vidioc_s_tuner(file, fh, p);
1451 case VIDIOC_G_FREQUENCY:
1453 struct v4l2_frequency *p=arg;
1454 if (!vfd->vidioc_g_frequency)
1457 memset(p,0,sizeof(*p));
1459 ret=vfd->vidioc_g_frequency(file, fh, p);
1461 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1462 p->tuner,p->type,p->frequency);
1465 case VIDIOC_S_FREQUENCY:
1467 struct v4l2_frequency *p=arg;
1468 if (!vfd->vidioc_s_frequency)
1470 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1471 p->tuner,p->type,p->frequency);
1472 ret=vfd->vidioc_s_frequency(file, fh, p);
1475 case VIDIOC_G_SLICED_VBI_CAP:
1477 struct v4l2_sliced_vbi_cap *p=arg;
1478 if (!vfd->vidioc_g_sliced_vbi_cap)
1480 ret=vfd->vidioc_g_sliced_vbi_cap(file, fh, p);
1482 dbgarg (cmd, "service_set=%d\n", p->service_set);
1485 case VIDIOC_LOG_STATUS:
1487 if (!vfd->vidioc_log_status)
1489 ret=vfd->vidioc_log_status(file, fh);
1492 #ifdef CONFIG_VIDEO_ADV_DEBUG
1493 case VIDIOC_DBG_G_REGISTER:
1495 struct v4l2_register *p=arg;
1496 if (!capable(CAP_SYS_ADMIN))
1498 else if (vfd->vidioc_g_register)
1499 ret=vfd->vidioc_g_register(file, fh, p);
1502 case VIDIOC_DBG_S_REGISTER:
1504 struct v4l2_register *p=arg;
1505 if (!capable(CAP_SYS_ADMIN))
1507 else if (vfd->vidioc_s_register)
1508 ret=vfd->vidioc_s_register(file, fh, p);
1512 case VIDIOC_G_CHIP_IDENT:
1514 struct v4l2_chip_ident *p=arg;
1515 if (!vfd->vidioc_g_chip_ident)
1517 ret=vfd->vidioc_g_chip_ident(file, fh, p);
1519 dbgarg (cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
1524 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1526 printk ("%s: err:\n", vfd->name);
1527 v4l_print_ioctl(vfd->name, cmd);
1534 int video_ioctl2 (struct inode *inode, struct file *file,
1535 unsigned int cmd, unsigned long arg)
1542 size_t ctrls_size = 0;
1543 void __user *user_ptr = NULL;
1545 #ifdef __OLD_VIDIOC_
1546 cmd = video_fix_command(cmd);
1548 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
1549 cmd == VIDIOC_TRY_EXT_CTRLS);
1551 /* Copy arguments into temp kernel buffer */
1552 switch (_IOC_DIR(cmd)) {
1558 case (_IOC_WRITE | _IOC_READ):
1559 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
1562 /* too big to allocate from stack */
1563 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
1570 if (_IOC_DIR(cmd) & _IOC_WRITE)
1571 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
1577 struct v4l2_ext_controls *p = parg;
1579 /* In case of an error, tell the caller that it wasn't
1580 a specific control that caused it. */
1581 p->error_idx = p->count;
1582 user_ptr = (void __user *)p->controls;
1584 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
1585 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
1586 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
1591 if (copy_from_user(mbuf, user_ptr, ctrls_size))
1598 err = __video_do_ioctl(inode, file, cmd, parg);
1599 if (err == -ENOIOCTLCMD)
1602 struct v4l2_ext_controls *p = parg;
1604 p->controls = (void *)user_ptr;
1605 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
1613 /* Copy results into user buffer */
1614 switch (_IOC_DIR(cmd))
1617 case (_IOC_WRITE | _IOC_READ):
1618 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
1629 static const struct file_operations video_fops;
1632 * video_register_device - register video4linux devices
1633 * @vfd: video device structure we want to register
1634 * @type: type of device to register
1635 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
1638 * The registration code assigns minor numbers based on the type
1639 * requested. -ENFILE is returned in all the device slots for this
1640 * category are full. If not then the minor field is set and the
1641 * driver initialize function is called (if non %NULL).
1643 * Zero is returned on success.
1647 * %VFL_TYPE_GRABBER - A frame grabber
1649 * %VFL_TYPE_VTX - A teletext device
1651 * %VFL_TYPE_VBI - Vertical blank data (undecoded)
1653 * %VFL_TYPE_RADIO - A radio card
1656 int video_register_device(struct video_device *vfd, int type, int nr)
1666 case VFL_TYPE_GRABBER:
1667 base=MINOR_VFL_TYPE_GRABBER_MIN;
1668 end=MINOR_VFL_TYPE_GRABBER_MAX+1;
1669 name_base = "video";
1672 base=MINOR_VFL_TYPE_VTX_MIN;
1673 end=MINOR_VFL_TYPE_VTX_MAX+1;
1677 base=MINOR_VFL_TYPE_VBI_MIN;
1678 end=MINOR_VFL_TYPE_VBI_MAX+1;
1681 case VFL_TYPE_RADIO:
1682 base=MINOR_VFL_TYPE_RADIO_MIN;
1683 end=MINOR_VFL_TYPE_RADIO_MAX+1;
1684 name_base = "radio";
1687 printk(KERN_ERR "%s called with unknown type: %d\n",
1688 __FUNCTION__, type);
1692 /* pick a minor number */
1693 mutex_lock(&videodev_lock);
1694 if (nr >= 0 && nr < end-base) {
1695 /* use the one the driver asked for */
1697 if (NULL != video_device[i]) {
1698 mutex_unlock(&videodev_lock);
1702 /* use first free */
1703 for(i=base;i<end;i++)
1704 if (NULL == video_device[i])
1707 mutex_unlock(&videodev_lock);
1711 video_device[i]=vfd;
1713 mutex_unlock(&videodev_lock);
1714 mutex_init(&vfd->lock);
1717 memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
1719 vfd->class_dev.parent = vfd->dev;
1720 vfd->class_dev.class = &video_class;
1721 vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor);
1722 sprintf(vfd->class_dev.bus_id, "%s%d", name_base, i - base);
1723 ret = device_register(&vfd->class_dev);
1725 printk(KERN_ERR "%s: device_register failed\n",
1731 /* needed until all drivers are fixed */
1733 printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
1734 "Please fix your driver for proper sysfs support, see "
1735 "http://lwn.net/Articles/36850/\n", vfd->name);
1740 mutex_lock(&videodev_lock);
1741 video_device[vfd->minor] = NULL;
1743 mutex_unlock(&videodev_lock);
1748 * video_unregister_device - unregister a video4linux device
1749 * @vfd: the device to unregister
1751 * This unregisters the passed device and deassigns the minor
1752 * number. Future open calls will be met with errors.
1755 void video_unregister_device(struct video_device *vfd)
1757 mutex_lock(&videodev_lock);
1758 if(video_device[vfd->minor]!=vfd)
1759 panic("videodev: bad unregister");
1761 video_device[vfd->minor]=NULL;
1762 device_unregister(&vfd->class_dev);
1763 mutex_unlock(&videodev_lock);
1767 * Video fs operations
1769 static const struct file_operations video_fops=
1771 .owner = THIS_MODULE,
1772 .llseek = no_llseek,
1777 * Initialise video for linux
1780 static int __init videodev_init(void)
1784 printk(KERN_INFO "Linux video capture interface: v2.00\n");
1785 if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
1786 printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
1790 ret = class_register(&video_class);
1792 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1793 printk(KERN_WARNING "video_dev: class_register failed\n");
1800 static void __exit videodev_exit(void)
1802 class_unregister(&video_class);
1803 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1806 module_init(videodev_init)
1807 module_exit(videodev_exit)
1809 EXPORT_SYMBOL(video_register_device);
1810 EXPORT_SYMBOL(video_unregister_device);
1811 EXPORT_SYMBOL(video_devdata);
1812 EXPORT_SYMBOL(video_usercopy);
1813 EXPORT_SYMBOL(video_exclusive_open);
1814 EXPORT_SYMBOL(video_exclusive_release);
1815 EXPORT_SYMBOL(video_ioctl2);
1816 EXPORT_SYMBOL(video_device_alloc);
1817 EXPORT_SYMBOL(video_device_release);
1819 MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
1820 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
1821 MODULE_LICENSE("GPL");