V4L/DVB (4148): Fix userbits debug prints
[linux-2.6/kvm.git] / drivers / media / video / videodev.c
blob43152297e6d5631fa6a544c67d9fd430c43d7a4d
1 /*
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);
25 #define dbgarg2(fmt, arg...) \
26 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \
27 printk (KERN_DEBUG "%s: " fmt, vfd->name, ## arg);
29 #include <linux/module.h>
30 #include <linux/types.h>
31 #include <linux/kernel.h>
32 #include <linux/sched.h>
33 #include <linux/smp_lock.h>
34 #include <linux/mm.h>
35 #include <linux/string.h>
36 #include <linux/errno.h>
37 #include <linux/init.h>
38 #include <linux/kmod.h>
39 #include <linux/slab.h>
40 #include <linux/devfs_fs_kernel.h>
41 #include <asm/uaccess.h>
42 #include <asm/system.h>
44 #define __OLD_VIDIOC_ /* To allow fixing old calls*/
45 #include <linux/videodev2.h>
47 #ifdef CONFIG_VIDEO_V4L1
48 #include <linux/videodev.h>
49 #endif
50 #include <media/v4l2-common.h>
52 #define VIDEO_NUM_DEVICES 256
53 #define VIDEO_NAME "video4linux"
56 * sysfs stuff
59 static ssize_t show_name(struct class_device *cd, char *buf)
61 struct video_device *vfd = container_of(cd, struct video_device,
62 class_dev);
63 return sprintf(buf,"%.*s\n",(int)sizeof(vfd->name),vfd->name);
66 static CLASS_DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
68 struct video_device *video_device_alloc(void)
70 struct video_device *vfd;
72 vfd = kzalloc(sizeof(*vfd),GFP_KERNEL);
73 return vfd;
76 void video_device_release(struct video_device *vfd)
78 kfree(vfd);
81 static void video_release(struct class_device *cd)
83 struct video_device *vfd = container_of(cd, struct video_device,
84 class_dev);
86 #if 1
87 /* needed until all drivers are fixed */
88 if (!vfd->release)
89 return;
90 #endif
91 vfd->release(vfd);
94 static struct class video_class = {
95 .name = VIDEO_NAME,
96 .release = video_release,
100 * Active devices
103 static struct video_device *video_device[VIDEO_NUM_DEVICES];
104 static DEFINE_MUTEX(videodev_lock);
106 struct video_device* video_devdata(struct file *file)
108 return video_device[iminor(file->f_dentry->d_inode)];
112 * Open a video device - FIXME: Obsoleted
114 static int video_open(struct inode *inode, struct file *file)
116 unsigned int minor = iminor(inode);
117 int err = 0;
118 struct video_device *vfl;
119 const struct file_operations *old_fops;
121 if(minor>=VIDEO_NUM_DEVICES)
122 return -ENODEV;
123 mutex_lock(&videodev_lock);
124 vfl=video_device[minor];
125 if(vfl==NULL) {
126 mutex_unlock(&videodev_lock);
127 request_module("char-major-%d-%d", VIDEO_MAJOR, minor);
128 mutex_lock(&videodev_lock);
129 vfl=video_device[minor];
130 if (vfl==NULL) {
131 mutex_unlock(&videodev_lock);
132 return -ENODEV;
135 old_fops = file->f_op;
136 file->f_op = fops_get(vfl->fops);
137 if(file->f_op->open)
138 err = file->f_op->open(inode,file);
139 if (err) {
140 fops_put(file->f_op);
141 file->f_op = fops_get(old_fops);
143 fops_put(old_fops);
144 mutex_unlock(&videodev_lock);
145 return err;
149 * helper function -- handles userspace copying for ioctl arguments
152 #ifdef __OLD_VIDIOC_
153 static unsigned int
154 video_fix_command(unsigned int cmd)
156 switch (cmd) {
157 case VIDIOC_OVERLAY_OLD:
158 cmd = VIDIOC_OVERLAY;
159 break;
160 case VIDIOC_S_PARM_OLD:
161 cmd = VIDIOC_S_PARM;
162 break;
163 case VIDIOC_S_CTRL_OLD:
164 cmd = VIDIOC_S_CTRL;
165 break;
166 case VIDIOC_G_AUDIO_OLD:
167 cmd = VIDIOC_G_AUDIO;
168 break;
169 case VIDIOC_G_AUDOUT_OLD:
170 cmd = VIDIOC_G_AUDOUT;
171 break;
172 case VIDIOC_CROPCAP_OLD:
173 cmd = VIDIOC_CROPCAP;
174 break;
176 return cmd;
178 #endif
181 * Obsolete usercopy function - Should be removed soon
184 video_usercopy(struct inode *inode, struct file *file,
185 unsigned int cmd, unsigned long arg,
186 int (*func)(struct inode *inode, struct file *file,
187 unsigned int cmd, void *arg))
189 char sbuf[128];
190 void *mbuf = NULL;
191 void *parg = NULL;
192 int err = -EINVAL;
194 #ifdef __OLD_VIDIOC_
195 cmd = video_fix_command(cmd);
196 #endif
198 /* Copy arguments into temp kernel buffer */
199 switch (_IOC_DIR(cmd)) {
200 case _IOC_NONE:
201 parg = NULL;
202 break;
203 case _IOC_READ:
204 case _IOC_WRITE:
205 case (_IOC_WRITE | _IOC_READ):
206 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
207 parg = sbuf;
208 } else {
209 /* too big to allocate from stack */
210 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
211 if (NULL == mbuf)
212 return -ENOMEM;
213 parg = mbuf;
216 err = -EFAULT;
217 if (_IOC_DIR(cmd) & _IOC_WRITE)
218 if (copy_from_user(parg, (void __user *)arg,
219 _IOC_SIZE(cmd)))
220 goto out;
221 break;
224 /* call driver */
225 err = func(inode, file, cmd, parg);
226 if (err == -ENOIOCTLCMD)
227 err = -EINVAL;
228 if (err < 0)
229 goto out;
231 /* Copy results into user buffer */
232 switch (_IOC_DIR(cmd))
234 case _IOC_READ:
235 case (_IOC_WRITE | _IOC_READ):
236 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
237 err = -EFAULT;
238 break;
241 out:
242 kfree(mbuf);
243 return err;
247 * open/release helper functions -- handle exclusive opens
248 * Should be removed soon
250 int video_exclusive_open(struct inode *inode, struct file *file)
252 struct video_device *vfl = video_devdata(file);
253 int retval = 0;
255 mutex_lock(&vfl->lock);
256 if (vfl->users) {
257 retval = -EBUSY;
258 } else {
259 vfl->users++;
261 mutex_unlock(&vfl->lock);
262 return retval;
265 int video_exclusive_release(struct inode *inode, struct file *file)
267 struct video_device *vfl = video_devdata(file);
269 vfl->users--;
270 return 0;
273 static char *v4l2_memory_names[] = {
274 [V4L2_MEMORY_MMAP] = "mmap",
275 [V4L2_MEMORY_USERPTR] = "userptr",
276 [V4L2_MEMORY_OVERLAY] = "overlay",
280 /* FIXME: Those stuff are replicated also on v4l2-common.c */
281 static char *v4l2_type_names_FIXME[] = {
282 [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap",
283 [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over",
284 [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out",
285 [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap",
286 [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out",
287 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
288 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-capture",
289 [V4L2_BUF_TYPE_PRIVATE] = "private",
292 static char *v4l2_field_names_FIXME[] = {
293 [V4L2_FIELD_ANY] = "any",
294 [V4L2_FIELD_NONE] = "none",
295 [V4L2_FIELD_TOP] = "top",
296 [V4L2_FIELD_BOTTOM] = "bottom",
297 [V4L2_FIELD_INTERLACED] = "interlaced",
298 [V4L2_FIELD_SEQ_TB] = "seq-tb",
299 [V4L2_FIELD_SEQ_BT] = "seq-bt",
300 [V4L2_FIELD_ALTERNATE] = "alternate",
303 #define prt_names(a,arr) (((a)>=0)&&((a)<ARRAY_SIZE(arr)))?arr[a]:"unknown"
305 static void dbgbuf(unsigned int cmd, struct video_device *vfd,
306 struct v4l2_buffer *p)
308 struct v4l2_timecode *tc=&p->timecode;
310 dbgarg (cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
311 "bytesused=%d, flags=0x%08d, "
312 "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx\n",
313 (p->timestamp.tv_sec/3600),
314 (int)(p->timestamp.tv_sec/60)%60,
315 (int)(p->timestamp.tv_sec%60),
316 p->timestamp.tv_usec,
317 p->index,
318 prt_names(p->type,v4l2_type_names_FIXME),
319 p->bytesused,p->flags,
320 p->field,p->sequence,
321 prt_names(p->memory,v4l2_memory_names),
322 p->m.userptr);
323 dbgarg2 ("timecode= %02d:%02d:%02d type=%d, "
324 "flags=0x%08d, frames=%d, userbits=0x%08x\n",
325 tc->hours,tc->minutes,tc->seconds,
326 tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits);
329 static inline void dbgrect(struct video_device *vfd, char *s,
330 struct v4l2_rect *r)
332 dbgarg2 ("%sRect start at %dx%d, size= %dx%d\n", s, r->left, r->top,
333 r->width, r->height);
336 static inline void v4l_print_pix_fmt (struct video_device *vfd,
337 struct v4l2_pix_format *fmt)
339 dbgarg2 ("width=%d, height=%d, format=0x%08x, field=%s, "
340 "bytesperline=%d sizeimage=%d, colorspace=%d\n",
341 fmt->width,fmt->height,fmt->pixelformat,
342 prt_names(fmt->field,v4l2_field_names_FIXME),
343 fmt->bytesperline,fmt->sizeimage,fmt->colorspace);
347 static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type)
349 switch (type) {
350 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
351 if (vfd->vidioc_try_fmt_cap)
352 return (0);
353 break;
354 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
355 if (vfd->vidioc_try_fmt_overlay)
356 return (0);
357 break;
358 case V4L2_BUF_TYPE_VBI_CAPTURE:
359 if (vfd->vidioc_try_fmt_vbi)
360 return (0);
361 break;
362 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
363 if (vfd->vidioc_try_fmt_vbi_output)
364 return (0);
365 break;
366 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
367 if (vfd->vidioc_try_fmt_vbi_capture)
368 return (0);
369 break;
370 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
371 if (vfd->vidioc_try_fmt_video_output)
372 return (0);
373 break;
374 case V4L2_BUF_TYPE_VBI_OUTPUT:
375 if (vfd->vidioc_try_fmt_vbi_output)
376 return (0);
377 break;
378 case V4L2_BUF_TYPE_PRIVATE:
379 if (vfd->vidioc_try_fmt_type_private)
380 return (0);
381 break;
383 return (-EINVAL);
386 static int __video_do_ioctl(struct inode *inode, struct file *file,
387 unsigned int cmd, void *arg)
389 struct video_device *vfd = video_devdata(file);
390 void *fh = file->private_data;
391 int ret = -EINVAL;
393 if ( (vfd->debug & V4L2_DEBUG_IOCTL) &&
394 !(vfd->debug | V4L2_DEBUG_IOCTL_ARG)) {
395 v4l_print_ioctl(vfd->name, cmd);
398 switch(cmd) {
399 /* --- capabilities ------------------------------------------ */
400 case VIDIOC_QUERYCAP:
402 struct v4l2_capability *cap = (struct v4l2_capability*)arg;
403 memset(cap, 0, sizeof(*cap));
405 if (!vfd->vidioc_querycap)
406 break;
408 ret=vfd->vidioc_querycap(file, fh, cap);
409 if (!ret)
410 dbgarg (cmd, "driver=%s, card=%s, bus=%s, "
411 "version=0x%08x, "
412 "capabilities=0x%08x\n",
413 cap->driver,cap->card,cap->bus_info,
414 cap->version,
415 cap->capabilities);
416 break;
419 /* --- priority ------------------------------------------ */
420 case VIDIOC_G_PRIORITY:
422 enum v4l2_priority *p=arg;
424 if (!vfd->vidioc_g_priority)
425 break;
426 ret=vfd->vidioc_g_priority(file, fh, p);
427 if (!ret)
428 dbgarg(cmd, "priority is %d\n", *p);
429 break;
431 case VIDIOC_S_PRIORITY:
433 enum v4l2_priority *p=arg;
435 if (!vfd->vidioc_s_priority)
436 break;
437 dbgarg(cmd, "setting priority to %d\n", *p);
438 ret=vfd->vidioc_s_priority(file, fh, *p);
439 break;
442 /* --- capture ioctls ---------------------------------------- */
443 case VIDIOC_ENUM_FMT:
445 struct v4l2_fmtdesc *f = arg;
446 enum v4l2_buf_type type;
447 unsigned int index;
449 index = f->index;
450 type = f->type;
451 memset(f,0,sizeof(*f));
452 f->index = index;
453 f->type = type;
455 switch (type) {
456 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
457 if (vfd->vidioc_enum_fmt_cap)
458 ret=vfd->vidioc_enum_fmt_cap(file, fh, f);
459 break;
460 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
461 if (vfd->vidioc_enum_fmt_overlay)
462 ret=vfd->vidioc_enum_fmt_overlay(file, fh, f);
463 break;
464 case V4L2_BUF_TYPE_VBI_CAPTURE:
465 if (vfd->vidioc_enum_fmt_vbi)
466 ret=vfd->vidioc_enum_fmt_vbi(file, fh, f);
467 break;
468 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
469 if (vfd->vidioc_enum_fmt_vbi_output)
470 ret=vfd->vidioc_enum_fmt_vbi_output(file,
471 fh, f);
472 break;
473 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
474 if (vfd->vidioc_enum_fmt_vbi_capture)
475 ret=vfd->vidioc_enum_fmt_vbi_capture(file,
476 fh, f);
477 break;
478 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
479 if (vfd->vidioc_enum_fmt_video_output)
480 ret=vfd->vidioc_enum_fmt_video_output(file,
481 fh, f);
482 break;
483 case V4L2_BUF_TYPE_VBI_OUTPUT:
484 if (vfd->vidioc_enum_fmt_vbi_output)
485 ret=vfd->vidioc_enum_fmt_vbi_output(file,
486 fh, f);
487 break;
488 case V4L2_BUF_TYPE_PRIVATE:
489 if (vfd->vidioc_enum_fmt_type_private)
490 ret=vfd->vidioc_enum_fmt_type_private(file,
491 fh, f);
492 break;
494 if (!ret)
495 dbgarg (cmd, "index=%d, type=%d, flags=%d, "
496 "description=%s,"
497 " pixelformat=0x%8x\n",
498 f->index, f->type, f->flags,
499 f->description,
500 f->pixelformat);
502 break;
504 case VIDIOC_G_FMT:
506 struct v4l2_format *f = (struct v4l2_format *)arg;
507 enum v4l2_buf_type type=f->type;
509 memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
510 f->type=type;
512 /* FIXME: Should be one dump per type */
513 dbgarg (cmd, "type=%s\n", prt_names(type,
514 v4l2_type_names_FIXME));
516 switch (type) {
517 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
518 if (vfd->vidioc_g_fmt_cap)
519 ret=vfd->vidioc_g_fmt_cap(file, fh, f);
520 if (!ret)
521 v4l_print_pix_fmt(vfd,&f->fmt.pix);
522 break;
523 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
524 if (vfd->vidioc_g_fmt_overlay)
525 ret=vfd->vidioc_g_fmt_overlay(file, fh, f);
526 break;
527 case V4L2_BUF_TYPE_VBI_CAPTURE:
528 if (vfd->vidioc_g_fmt_vbi)
529 ret=vfd->vidioc_g_fmt_vbi(file, fh, f);
530 break;
531 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
532 if (vfd->vidioc_g_fmt_vbi_output)
533 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
534 break;
535 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
536 if (vfd->vidioc_g_fmt_vbi_capture)
537 ret=vfd->vidioc_g_fmt_vbi_capture(file, fh, f);
538 break;
539 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
540 if (vfd->vidioc_g_fmt_video_output)
541 ret=vfd->vidioc_g_fmt_video_output(file,
542 fh, f);
543 break;
544 case V4L2_BUF_TYPE_VBI_OUTPUT:
545 if (vfd->vidioc_g_fmt_vbi_output)
546 ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f);
547 break;
548 case V4L2_BUF_TYPE_PRIVATE:
549 if (vfd->vidioc_g_fmt_type_private)
550 ret=vfd->vidioc_g_fmt_type_private(file,
551 fh, f);
552 break;
555 break;
557 case VIDIOC_S_FMT:
559 struct v4l2_format *f = (struct v4l2_format *)arg;
561 /* FIXME: Should be one dump per type */
562 dbgarg (cmd, "type=%s\n", prt_names(f->type,
563 v4l2_type_names_FIXME));
565 switch (f->type) {
566 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
567 v4l_print_pix_fmt(vfd,&f->fmt.pix);
568 if (vfd->vidioc_s_fmt_cap)
569 ret=vfd->vidioc_s_fmt_cap(file, fh, f);
570 break;
571 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
572 if (vfd->vidioc_s_fmt_overlay)
573 ret=vfd->vidioc_s_fmt_overlay(file, fh, f);
574 break;
575 case V4L2_BUF_TYPE_VBI_CAPTURE:
576 if (vfd->vidioc_s_fmt_vbi)
577 ret=vfd->vidioc_s_fmt_vbi(file, fh, f);
578 break;
579 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
580 if (vfd->vidioc_s_fmt_vbi_output)
581 ret=vfd->vidioc_s_fmt_vbi_output(file, fh, f);
582 break;
583 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
584 if (vfd->vidioc_s_fmt_vbi_capture)
585 ret=vfd->vidioc_s_fmt_vbi_capture(file, fh, f);
586 break;
587 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
588 if (vfd->vidioc_s_fmt_video_output)
589 ret=vfd->vidioc_s_fmt_video_output(file,
590 fh, f);
591 break;
592 case V4L2_BUF_TYPE_VBI_OUTPUT:
593 if (vfd->vidioc_s_fmt_vbi_output)
594 ret=vfd->vidioc_s_fmt_vbi_output(file,
595 fh, f);
596 break;
597 case V4L2_BUF_TYPE_PRIVATE:
598 if (vfd->vidioc_s_fmt_type_private)
599 ret=vfd->vidioc_s_fmt_type_private(file,
600 fh, f);
601 break;
603 break;
605 case VIDIOC_TRY_FMT:
607 struct v4l2_format *f = (struct v4l2_format *)arg;
609 /* FIXME: Should be one dump per type */
610 dbgarg (cmd, "type=%s\n", prt_names(f->type,
611 v4l2_type_names_FIXME));
612 switch (f->type) {
613 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
614 if (vfd->vidioc_try_fmt_cap)
615 ret=vfd->vidioc_try_fmt_cap(file, fh, f);
616 if (!ret)
617 v4l_print_pix_fmt(vfd,&f->fmt.pix);
618 break;
619 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
620 if (vfd->vidioc_try_fmt_overlay)
621 ret=vfd->vidioc_try_fmt_overlay(file, fh, f);
622 break;
623 case V4L2_BUF_TYPE_VBI_CAPTURE:
624 if (vfd->vidioc_try_fmt_vbi)
625 ret=vfd->vidioc_try_fmt_vbi(file, fh, f);
626 break;
627 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
628 if (vfd->vidioc_try_fmt_vbi_output)
629 ret=vfd->vidioc_try_fmt_vbi_output(file,
630 fh, f);
631 break;
632 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
633 if (vfd->vidioc_try_fmt_vbi_capture)
634 ret=vfd->vidioc_try_fmt_vbi_capture(file,
635 fh, f);
636 break;
637 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
638 if (vfd->vidioc_try_fmt_video_output)
639 ret=vfd->vidioc_try_fmt_video_output(file,
640 fh, f);
641 break;
642 case V4L2_BUF_TYPE_VBI_OUTPUT:
643 if (vfd->vidioc_try_fmt_vbi_output)
644 ret=vfd->vidioc_try_fmt_vbi_output(file,
645 fh, f);
646 break;
647 case V4L2_BUF_TYPE_PRIVATE:
648 if (vfd->vidioc_try_fmt_type_private)
649 ret=vfd->vidioc_try_fmt_type_private(file,
650 fh, f);
651 break;
654 break;
656 /* FIXME: Those buf reqs could be handled here,
657 with some changes on videobuf to allow its header to be included at
658 videodev2.h or being merged at videodev2.
660 case VIDIOC_REQBUFS:
662 struct v4l2_requestbuffers *p=arg;
664 if (!vfd->vidioc_reqbufs)
665 break;
666 ret = check_fmt (vfd, p->type);
667 if (ret)
668 break;
670 ret=vfd->vidioc_reqbufs(file, fh, p);
671 dbgarg (cmd, "count=%d, type=%s, memory=%s\n",
672 p->count,
673 prt_names(p->type,v4l2_type_names_FIXME),
674 prt_names(p->memory,v4l2_memory_names));
675 break;
677 case VIDIOC_QUERYBUF:
679 struct v4l2_buffer *p=arg;
681 if (!vfd->vidioc_querybuf)
682 break;
683 ret = check_fmt (vfd, p->type);
684 if (ret)
685 break;
687 ret=vfd->vidioc_querybuf(file, fh, p);
688 if (!ret)
689 dbgbuf(cmd,vfd,p);
690 break;
692 case VIDIOC_QBUF:
694 struct v4l2_buffer *p=arg;
696 if (!vfd->vidioc_qbuf)
697 break;
698 ret = check_fmt (vfd, p->type);
699 if (ret)
700 break;
702 ret=vfd->vidioc_qbuf(file, fh, p);
703 if (!ret)
704 dbgbuf(cmd,vfd,p);
705 break;
707 case VIDIOC_DQBUF:
709 struct v4l2_buffer *p=arg;
710 if (!vfd->vidioc_qbuf)
711 break;
712 ret = check_fmt (vfd, p->type);
713 if (ret)
714 break;
716 ret=vfd->vidioc_qbuf(file, fh, p);
717 if (!ret)
718 dbgbuf(cmd,vfd,p);
719 break;
721 case VIDIOC_OVERLAY:
723 int *i = arg;
725 if (!vfd->vidioc_overlay)
726 break;
727 dbgarg (cmd, "value=%d\n",*i);
728 ret=vfd->vidioc_overlay(file, fh, *i);
729 break;
731 #ifdef HAVE_V4L1
732 /* --- streaming capture ------------------------------------- */
733 case VIDIOCGMBUF:
735 struct video_mbuf *p=arg;
737 memset(p,0,sizeof(p));
739 if (!vfd->vidiocgmbuf)
740 break;
741 ret=vfd->vidiocgmbuf(file, fh, p);
742 if (!ret)
743 dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n",
744 p->size, p->frames,
745 (unsigned long)p->offsets);
746 break;
748 #endif
749 case VIDIOC_G_FBUF:
751 struct v4l2_framebuffer *p=arg;
752 if (!vfd->vidioc_g_fbuf)
753 break;
754 ret=vfd->vidioc_g_fbuf(file, fh, arg);
755 if (!ret) {
756 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
757 p->capability,p->flags,
758 (unsigned long)p->base);
759 v4l_print_pix_fmt (vfd, &p->fmt);
761 break;
763 case VIDIOC_S_FBUF:
765 struct v4l2_framebuffer *p=arg;
766 if (!vfd->vidioc_s_fbuf)
767 break;
769 dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n",
770 p->capability,p->flags,(unsigned long)p->base);
771 v4l_print_pix_fmt (vfd, &p->fmt);
772 ret=vfd->vidioc_s_fbuf(file, fh, arg);
774 break;
776 case VIDIOC_STREAMON:
778 enum v4l2_buf_type i = *(int *)arg;
779 if (!vfd->vidioc_streamon)
780 break;
781 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
782 ret=vfd->vidioc_streamon(file, fh,i);
783 break;
785 case VIDIOC_STREAMOFF:
787 enum v4l2_buf_type i = *(int *)arg;
789 if (!vfd->vidioc_streamoff)
790 break;
791 dbgarg (cmd, "type=%s\n", prt_names(i,v4l2_type_names_FIXME));
792 ret=vfd->vidioc_streamoff(file, fh, i);
793 break;
795 /* ---------- tv norms ---------- */
796 case VIDIOC_ENUMSTD:
798 struct v4l2_standard *p = arg;
799 unsigned int index = p->index;
801 if (!vfd->tvnormsize) {
802 printk (KERN_WARNING "%s: no TV norms defined!\n",
803 vfd->name);
804 break;
807 if (index<=0 || index >= vfd->tvnormsize) {
808 ret=-EINVAL;
809 break;
811 v4l2_video_std_construct(p, vfd->tvnorms[p->index].id,
812 vfd->tvnorms[p->index].name);
813 p->index = index;
815 dbgarg (cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, "
816 "framelines=%d\n", p->index,
817 (unsigned long long)p->id, p->name,
818 p->frameperiod.numerator,
819 p->frameperiod.denominator,
820 p->framelines);
822 ret=0;
823 break;
825 case VIDIOC_G_STD:
827 v4l2_std_id *id = arg;
829 *id = vfd->current_norm;
831 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
833 ret=0;
834 break;
836 case VIDIOC_S_STD:
838 v4l2_std_id *id = arg;
839 unsigned int i;
841 if (!vfd->tvnormsize) {
842 printk (KERN_WARNING "%s: no TV norms defined!\n",
843 vfd->name);
844 break;
847 dbgarg (cmd, "value=%Lu\n", (long long unsigned) *id);
849 /* First search for exact match */
850 for (i = 0; i < vfd->tvnormsize; i++)
851 if (*id == vfd->tvnorms[i].id)
852 break;
853 /* Then for a generic video std that contains desired std */
854 if (i == vfd->tvnormsize)
855 for (i = 0; i < vfd->tvnormsize; i++)
856 if (*id & vfd->tvnorms[i].id)
857 break;
858 if (i == vfd->tvnormsize) {
859 break;
862 /* Calls the specific handler */
863 if (vfd->vidioc_s_std)
864 ret=vfd->vidioc_s_std(file, fh, i);
865 else
866 ret=-EINVAL;
868 /* Updates standard information */
869 if (!ret)
870 vfd->current_norm=*id;
872 break;
874 case VIDIOC_QUERYSTD:
876 v4l2_std_id *p=arg;
878 if (!vfd->vidioc_querystd)
879 break;
880 ret=vfd->vidioc_querystd(file, fh, arg);
881 if (!ret)
882 dbgarg (cmd, "detected std=%Lu\n",
883 (unsigned long long)*p);
884 break;
886 /* ------ input switching ---------- */
887 /* FIXME: Inputs can be handled inside videodev2 */
888 case VIDIOC_ENUMINPUT:
890 struct v4l2_input *p=arg;
891 int i=p->index;
893 if (!vfd->vidioc_enum_input)
894 break;
895 memset(p, 0, sizeof(*p));
896 p->index=i;
898 ret=vfd->vidioc_enum_input(file, fh, p);
899 if (!ret)
900 dbgarg (cmd, "index=%d, name=%s, type=%d, "
901 "audioset=%d, "
902 "tuner=%d, std=%Ld, status=%d\n",
903 p->index,p->name,p->type,p->audioset,
904 p->tuner,
905 (unsigned long long)p->std,
906 p->status);
907 break;
909 case VIDIOC_G_INPUT:
911 unsigned int *i = arg;
913 if (!vfd->vidioc_g_input)
914 break;
915 ret=vfd->vidioc_g_input(file, fh, i);
916 if (!ret)
917 dbgarg (cmd, "value=%d\n",*i);
918 break;
920 case VIDIOC_S_INPUT:
922 unsigned int *i = arg;
924 if (!vfd->vidioc_s_input)
925 break;
926 dbgarg (cmd, "value=%d\n",*i);
927 ret=vfd->vidioc_s_input(file, fh, *i);
928 break;
931 /* ------ output switching ---------- */
932 case VIDIOC_G_OUTPUT:
934 unsigned int *i = arg;
936 if (!vfd->vidioc_g_output)
937 break;
938 ret=vfd->vidioc_g_output(file, fh, i);
939 if (!ret)
940 dbgarg (cmd, "value=%d\n",*i);
941 break;
943 case VIDIOC_S_OUTPUT:
945 unsigned int *i = arg;
947 if (!vfd->vidioc_s_output)
948 break;
949 dbgarg (cmd, "value=%d\n",*i);
950 ret=vfd->vidioc_s_output(file, fh, *i);
951 break;
954 /* --- controls ---------------------------------------------- */
955 case VIDIOC_QUERYCTRL:
957 struct v4l2_queryctrl *p=arg;
959 if (!vfd->vidioc_queryctrl)
960 break;
961 ret=vfd->vidioc_queryctrl(file, fh, p);
963 if (!ret)
964 dbgarg (cmd, "id=%d, type=%d, name=%s, "
965 "min/max=%d/%d,"
966 " step=%d, default=%d, flags=0x%08x\n",
967 p->id,p->type,p->name,p->minimum,
968 p->maximum,p->step,p->default_value,
969 p->flags);
970 break;
972 case VIDIOC_G_CTRL:
974 struct v4l2_control *p = arg;
976 if (!vfd->vidioc_g_ctrl)
977 break;
978 dbgarg(cmd, "Enum for index=%d\n", p->id);
980 ret=vfd->vidioc_g_ctrl(file, fh, p);
981 if (!ret)
982 dbgarg2 ( "id=%d, value=%d\n", p->id, p->value);
983 break;
985 case VIDIOC_S_CTRL:
987 struct v4l2_control *p = arg;
989 if (!vfd->vidioc_s_ctrl)
990 break;
991 dbgarg (cmd, "id=%d, value=%d\n", p->id, p->value);
993 ret=vfd->vidioc_s_ctrl(file, fh, p);
994 break;
996 case VIDIOC_QUERYMENU:
998 struct v4l2_querymenu *p=arg;
999 if (!vfd->vidioc_querymenu)
1000 break;
1001 ret=vfd->vidioc_querymenu(file, fh, p);
1002 if (!ret)
1003 dbgarg (cmd, "id=%d, index=%d, name=%s\n",
1004 p->id,p->index,p->name);
1005 break;
1007 /* --- audio ---------------------------------------------- */
1008 case VIDIOC_ENUMAUDIO:
1010 struct v4l2_audio *p=arg;
1012 if (!vfd->vidioc_enumaudio)
1013 break;
1014 dbgarg(cmd, "Enum for index=%d\n", p->index);
1015 ret=vfd->vidioc_enumaudio(file, fh, p);
1016 if (!ret)
1017 dbgarg2("index=%d, name=%s, capability=%d, "
1018 "mode=%d\n",p->index,p->name,
1019 p->capability, p->mode);
1020 break;
1022 case VIDIOC_G_AUDIO:
1024 struct v4l2_audio *p=arg;
1026 if (!vfd->vidioc_g_audio)
1027 break;
1028 dbgarg(cmd, "Get for index=%d\n", p->index);
1029 ret=vfd->vidioc_g_audio(file, fh, p);
1030 if (!ret)
1031 dbgarg2("index=%d, name=%s, capability=%d, "
1032 "mode=%d\n",p->index,
1033 p->name,p->capability, p->mode);
1034 break;
1036 case VIDIOC_S_AUDIO:
1038 struct v4l2_audio *p=arg;
1040 if (!vfd->vidioc_s_audio)
1041 break;
1042 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1043 "mode=%d\n", p->index, p->name,
1044 p->capability, p->mode);
1045 ret=vfd->vidioc_s_audio(file, fh, p);
1046 break;
1048 case VIDIOC_ENUMAUDOUT:
1050 struct v4l2_audioout *p=arg;
1052 if (!vfd->vidioc_enumaudout)
1053 break;
1054 dbgarg(cmd, "Enum for index=%d\n", p->index);
1055 ret=vfd->vidioc_enumaudout(file, fh, p);
1056 if (!ret)
1057 dbgarg2("index=%d, name=%s, capability=%d, "
1058 "mode=%d\n", p->index, p->name,
1059 p->capability,p->mode);
1060 break;
1062 case VIDIOC_G_AUDOUT:
1064 struct v4l2_audioout *p=arg;
1066 if (!vfd->vidioc_g_audout)
1067 break;
1068 dbgarg(cmd, "Enum for index=%d\n", p->index);
1069 ret=vfd->vidioc_g_audout(file, fh, p);
1070 if (!ret)
1071 dbgarg2("index=%d, name=%s, capability=%d, "
1072 "mode=%d\n", p->index, p->name,
1073 p->capability,p->mode);
1074 break;
1076 case VIDIOC_S_AUDOUT:
1078 struct v4l2_audioout *p=arg;
1080 if (!vfd->vidioc_s_audout)
1081 break;
1082 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1083 "mode=%d\n", p->index, p->name,
1084 p->capability,p->mode);
1086 ret=vfd->vidioc_s_audout(file, fh, p);
1087 break;
1089 case VIDIOC_G_MODULATOR:
1091 struct v4l2_modulator *p=arg;
1092 if (!vfd->vidioc_g_modulator)
1093 break;
1094 ret=vfd->vidioc_g_modulator(file, fh, p);
1095 if (!ret)
1096 dbgarg(cmd, "index=%d, name=%s, "
1097 "capability=%d, rangelow=%d,"
1098 " rangehigh=%d, txsubchans=%d\n",
1099 p->index, p->name,p->capability,
1100 p->rangelow, p->rangehigh,
1101 p->txsubchans);
1102 break;
1104 case VIDIOC_S_MODULATOR:
1106 struct v4l2_modulator *p=arg;
1107 if (!vfd->vidioc_s_modulator)
1108 break;
1109 dbgarg(cmd, "index=%d, name=%s, capability=%d, "
1110 "rangelow=%d, rangehigh=%d, txsubchans=%d\n",
1111 p->index, p->name,p->capability,p->rangelow,
1112 p->rangehigh,p->txsubchans);
1113 ret=vfd->vidioc_s_modulator(file, fh, p);
1114 break;
1116 case VIDIOC_G_CROP:
1118 struct v4l2_crop *p=arg;
1119 if (!vfd->vidioc_g_crop)
1120 break;
1121 ret=vfd->vidioc_g_crop(file, fh, p);
1122 if (!ret) {
1123 dbgarg(cmd, "type=%d\n", p->type);
1124 dbgrect(vfd, "", &p->c);
1126 break;
1128 case VIDIOC_S_CROP:
1130 struct v4l2_crop *p=arg;
1131 if (!vfd->vidioc_s_crop)
1132 break;
1133 dbgarg(cmd, "type=%d\n", p->type);
1134 dbgrect(vfd, "", &p->c);
1135 ret=vfd->vidioc_s_crop(file, fh, p);
1136 break;
1138 case VIDIOC_CROPCAP:
1140 struct v4l2_cropcap *p=arg;
1141 /*FIXME: Should also show v4l2_fract pixelaspect */
1142 if (!vfd->vidioc_cropcap)
1143 break;
1144 dbgarg(cmd, "type=%d\n", p->type);
1145 dbgrect(vfd, "bounds ", &p->bounds);
1146 dbgrect(vfd, "defrect ", &p->defrect);
1147 ret=vfd->vidioc_cropcap(file, fh, p);
1148 break;
1150 case VIDIOC_G_MPEGCOMP:
1152 struct v4l2_mpeg_compression *p=arg;
1153 /*FIXME: Several fields not shown */
1154 if (!vfd->vidioc_g_mpegcomp)
1155 break;
1156 ret=vfd->vidioc_g_mpegcomp(file, fh, p);
1157 if (!ret)
1158 dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d,"
1159 " ts_pid_video=%d, ts_pid_pcr=%d, "
1160 "ps_size=%d, au_sample_rate=%d, "
1161 "au_pesid=%c, vi_frame_rate=%d, "
1162 "vi_frames_per_gop=%d, "
1163 "vi_bframes_count=%d, vi_pesid=%c\n",
1164 p->ts_pid_pmt,p->ts_pid_audio,
1165 p->ts_pid_video,p->ts_pid_pcr,
1166 p->ps_size, p->au_sample_rate,
1167 p->au_pesid, p->vi_frame_rate,
1168 p->vi_frames_per_gop,
1169 p->vi_bframes_count, p->vi_pesid);
1170 break;
1172 case VIDIOC_S_MPEGCOMP:
1174 struct v4l2_mpeg_compression *p=arg;
1175 /*FIXME: Several fields not shown */
1176 if (!vfd->vidioc_s_mpegcomp)
1177 break;
1178 dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d, "
1179 "ts_pid_video=%d, ts_pid_pcr=%d, ps_size=%d, "
1180 "au_sample_rate=%d, au_pesid=%c, "
1181 "vi_frame_rate=%d, vi_frames_per_gop=%d, "
1182 "vi_bframes_count=%d, vi_pesid=%c\n",
1183 p->ts_pid_pmt,p->ts_pid_audio, p->ts_pid_video,
1184 p->ts_pid_pcr, p->ps_size, p->au_sample_rate,
1185 p->au_pesid, p->vi_frame_rate,
1186 p->vi_frames_per_gop, p->vi_bframes_count,
1187 p->vi_pesid);
1188 ret=vfd->vidioc_s_mpegcomp(file, fh, p);
1189 break;
1191 case VIDIOC_G_JPEGCOMP:
1193 struct v4l2_jpegcompression *p=arg;
1194 if (!vfd->vidioc_g_jpegcomp)
1195 break;
1196 ret=vfd->vidioc_g_jpegcomp(file, fh, p);
1197 if (!ret)
1198 dbgarg (cmd, "quality=%d, APPn=%d, "
1199 "APP_len=%d, COM_len=%d, "
1200 "jpeg_markers=%d\n",
1201 p->quality,p->APPn,p->APP_len,
1202 p->COM_len,p->jpeg_markers);
1203 break;
1205 case VIDIOC_S_JPEGCOMP:
1207 struct v4l2_jpegcompression *p=arg;
1208 if (!vfd->vidioc_g_jpegcomp)
1209 break;
1210 dbgarg (cmd, "quality=%d, APPn=%d, APP_len=%d, "
1211 "COM_len=%d, jpeg_markers=%d\n",
1212 p->quality,p->APPn,p->APP_len,
1213 p->COM_len,p->jpeg_markers);
1214 ret=vfd->vidioc_s_jpegcomp(file, fh, p);
1215 break;
1217 case VIDIOC_G_PARM:
1219 struct v4l2_streamparm *p=arg;
1220 if (!vfd->vidioc_g_parm)
1221 break;
1222 ret=vfd->vidioc_g_parm(file, fh, p);
1223 dbgarg (cmd, "type=%d\n", p->type);
1224 break;
1226 case VIDIOC_S_PARM:
1228 struct v4l2_streamparm *p=arg;
1229 if (!vfd->vidioc_s_parm)
1230 break;
1231 dbgarg (cmd, "type=%d\n", p->type);
1232 ret=vfd->vidioc_s_parm(file, fh, p);
1233 break;
1235 case VIDIOC_G_TUNER:
1237 struct v4l2_tuner *p=arg;
1238 if (!vfd->vidioc_g_tuner)
1239 break;
1240 ret=vfd->vidioc_g_tuner(file, fh, p);
1241 if (!ret)
1242 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1243 "capability=%d, rangelow=%d, "
1244 "rangehigh=%d, signal=%d, afc=%d, "
1245 "rxsubchans=%d, audmode=%d\n",
1246 p->index, p->name, p->type,
1247 p->capability, p->rangelow,
1248 p->rangehigh, p->rxsubchans,
1249 p->audmode, p->signal, p->afc);
1250 break;
1252 case VIDIOC_S_TUNER:
1254 struct v4l2_tuner *p=arg;
1255 if (!vfd->vidioc_s_tuner)
1256 break;
1257 dbgarg (cmd, "index=%d, name=%s, type=%d, "
1258 "capability=%d, rangelow=%d, rangehigh=%d, "
1259 "signal=%d, afc=%d, rxsubchans=%d, "
1260 "audmode=%d\n",p->index, p->name, p->type,
1261 p->capability, p->rangelow,p->rangehigh,
1262 p->rxsubchans, p->audmode, p->signal,
1263 p->afc);
1264 ret=vfd->vidioc_s_tuner(file, fh, p);
1265 break;
1267 case VIDIOC_G_FREQUENCY:
1269 struct v4l2_frequency *p=arg;
1270 if (!vfd->vidioc_g_frequency)
1271 break;
1272 ret=vfd->vidioc_g_frequency(file, fh, p);
1273 if (!ret)
1274 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1275 p->tuner,p->type,p->frequency);
1276 break;
1278 case VIDIOC_S_FREQUENCY:
1280 struct v4l2_frequency *p=arg;
1281 if (!vfd->vidioc_s_frequency)
1282 break;
1283 dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n",
1284 p->tuner,p->type,p->frequency);
1285 ret=vfd->vidioc_s_frequency(file, fh, p);
1286 break;
1288 case VIDIOC_G_SLICED_VBI_CAP:
1290 struct v4l2_sliced_vbi_cap *p=arg;
1291 if (!vfd->vidioc_g_sliced_vbi_cap)
1292 break;
1293 ret=vfd->vidioc_g_sliced_vbi_cap(file, fh, p);
1294 if (!ret)
1295 dbgarg (cmd, "service_set=%d\n", p->service_set);
1296 break;
1298 case VIDIOC_LOG_STATUS:
1300 if (!vfd->vidioc_log_status)
1301 break;
1302 ret=vfd->vidioc_log_status(file, fh);
1303 break;
1306 /* --- Others --------------------------------------------- */
1308 default:
1309 ret=v4l_compat_translate_ioctl(inode,file,cmd,arg,__video_do_ioctl);
1312 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1313 if (ret<0) {
1314 printk ("%s: err:\n", vfd->name);
1315 v4l_print_ioctl(vfd->name, cmd);
1319 return ret;
1322 int video_ioctl2 (struct inode *inode, struct file *file,
1323 unsigned int cmd, unsigned long arg)
1325 char sbuf[128];
1326 void *mbuf = NULL;
1327 void *parg = NULL;
1328 int err = -EINVAL;
1330 #ifdef __OLD_VIDIOC_
1331 cmd = video_fix_command(cmd);
1332 #endif
1334 /* Copy arguments into temp kernel buffer */
1335 switch (_IOC_DIR(cmd)) {
1336 case _IOC_NONE:
1337 parg = NULL;
1338 break;
1339 case _IOC_READ:
1340 case _IOC_WRITE:
1341 case (_IOC_WRITE | _IOC_READ):
1342 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
1343 parg = sbuf;
1344 } else {
1345 /* too big to allocate from stack */
1346 mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
1347 if (NULL == mbuf)
1348 return -ENOMEM;
1349 parg = mbuf;
1352 err = -EFAULT;
1353 if (_IOC_DIR(cmd) & _IOC_WRITE)
1354 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
1355 goto out;
1356 break;
1359 /* Handles IOCTL */
1360 err = __video_do_ioctl(inode, file, cmd, parg);
1361 if (err == -ENOIOCTLCMD)
1362 err = -EINVAL;
1363 if (err < 0)
1364 goto out;
1366 /* Copy results into user buffer */
1367 switch (_IOC_DIR(cmd))
1369 case _IOC_READ:
1370 case (_IOC_WRITE | _IOC_READ):
1371 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
1372 err = -EFAULT;
1373 break;
1376 out:
1377 kfree(mbuf);
1378 return err;
1382 static struct file_operations video_fops;
1385 * video_register_device - register video4linux devices
1386 * @vfd: video device structure we want to register
1387 * @type: type of device to register
1388 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
1389 * -1 == first free)
1391 * The registration code assigns minor numbers based on the type
1392 * requested. -ENFILE is returned in all the device slots for this
1393 * category are full. If not then the minor field is set and the
1394 * driver initialize function is called (if non %NULL).
1396 * Zero is returned on success.
1398 * Valid types are
1400 * %VFL_TYPE_GRABBER - A frame grabber
1402 * %VFL_TYPE_VTX - A teletext device
1404 * %VFL_TYPE_VBI - Vertical blank data (undecoded)
1406 * %VFL_TYPE_RADIO - A radio card
1409 int video_register_device(struct video_device *vfd, int type, int nr)
1411 int i=0;
1412 int base;
1413 int end;
1414 char *name_base;
1416 switch(type)
1418 case VFL_TYPE_GRABBER:
1419 base=MINOR_VFL_TYPE_GRABBER_MIN;
1420 end=MINOR_VFL_TYPE_GRABBER_MAX+1;
1421 name_base = "video";
1422 break;
1423 case VFL_TYPE_VTX:
1424 base=MINOR_VFL_TYPE_VTX_MIN;
1425 end=MINOR_VFL_TYPE_VTX_MAX+1;
1426 name_base = "vtx";
1427 break;
1428 case VFL_TYPE_VBI:
1429 base=MINOR_VFL_TYPE_VBI_MIN;
1430 end=MINOR_VFL_TYPE_VBI_MAX+1;
1431 name_base = "vbi";
1432 break;
1433 case VFL_TYPE_RADIO:
1434 base=MINOR_VFL_TYPE_RADIO_MIN;
1435 end=MINOR_VFL_TYPE_RADIO_MAX+1;
1436 name_base = "radio";
1437 break;
1438 default:
1439 return -1;
1442 /* pick a minor number */
1443 mutex_lock(&videodev_lock);
1444 if (nr >= 0 && nr < end-base) {
1445 /* use the one the driver asked for */
1446 i = base+nr;
1447 if (NULL != video_device[i]) {
1448 mutex_unlock(&videodev_lock);
1449 return -ENFILE;
1451 } else {
1452 /* use first free */
1453 for(i=base;i<end;i++)
1454 if (NULL == video_device[i])
1455 break;
1456 if (i == end) {
1457 mutex_unlock(&videodev_lock);
1458 return -ENFILE;
1461 video_device[i]=vfd;
1462 vfd->minor=i;
1463 mutex_unlock(&videodev_lock);
1465 sprintf(vfd->devfs_name, "v4l/%s%d", name_base, i - base);
1466 devfs_mk_cdev(MKDEV(VIDEO_MAJOR, vfd->minor),
1467 S_IFCHR | S_IRUSR | S_IWUSR, vfd->devfs_name);
1468 mutex_init(&vfd->lock);
1470 /* sysfs class */
1471 memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev));
1472 if (vfd->dev)
1473 vfd->class_dev.dev = vfd->dev;
1474 vfd->class_dev.class = &video_class;
1475 vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor);
1476 strlcpy(vfd->class_dev.class_id, vfd->devfs_name + 4, BUS_ID_SIZE);
1477 class_device_register(&vfd->class_dev);
1478 class_device_create_file(&vfd->class_dev,
1479 &class_device_attr_name);
1481 #if 1
1482 /* needed until all drivers are fixed */
1483 if (!vfd->release)
1484 printk(KERN_WARNING "videodev: \"%s\" has no release callback. "
1485 "Please fix your driver for proper sysfs support, see "
1486 "http://lwn.net/Articles/36850/\n", vfd->name);
1487 #endif
1488 return 0;
1492 * video_unregister_device - unregister a video4linux device
1493 * @vfd: the device to unregister
1495 * This unregisters the passed device and deassigns the minor
1496 * number. Future open calls will be met with errors.
1499 void video_unregister_device(struct video_device *vfd)
1501 mutex_lock(&videodev_lock);
1502 if(video_device[vfd->minor]!=vfd)
1503 panic("videodev: bad unregister");
1505 devfs_remove(vfd->devfs_name);
1506 video_device[vfd->minor]=NULL;
1507 class_device_unregister(&vfd->class_dev);
1508 mutex_unlock(&videodev_lock);
1512 * Video fs operations
1514 static struct file_operations video_fops=
1516 .owner = THIS_MODULE,
1517 .llseek = no_llseek,
1518 .open = video_open,
1522 * Initialise video for linux
1525 static int __init videodev_init(void)
1527 int ret;
1529 printk(KERN_INFO "Linux video capture interface: v2.00\n");
1530 if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) {
1531 printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR);
1532 return -EIO;
1535 ret = class_register(&video_class);
1536 if (ret < 0) {
1537 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1538 printk(KERN_WARNING "video_dev: class_register failed\n");
1539 return -EIO;
1542 return 0;
1545 static void __exit videodev_exit(void)
1547 class_unregister(&video_class);
1548 unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME);
1551 module_init(videodev_init)
1552 module_exit(videodev_exit)
1554 EXPORT_SYMBOL(video_register_device);
1555 EXPORT_SYMBOL(video_unregister_device);
1556 EXPORT_SYMBOL(video_devdata);
1557 EXPORT_SYMBOL(video_usercopy);
1558 EXPORT_SYMBOL(video_exclusive_open);
1559 EXPORT_SYMBOL(video_exclusive_release);
1560 EXPORT_SYMBOL(video_ioctl2);
1561 EXPORT_SYMBOL(video_device_alloc);
1562 EXPORT_SYMBOL(video_device_release);
1564 MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
1565 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
1566 MODULE_LICENSE("GPL");
1570 * Local variables:
1571 * c-basic-offset: 8
1572 * End: