1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include <linux/module.h>
20#include <linux/types.h>
21#include <linux/kernel.h>
22#include <linux/mm.h>
23#include <linux/string.h>
24#include <linux/errno.h>
25#include <linux/init.h>
26#include <linux/kmod.h>
27#include <linux/slab.h>
28#include <asm/uaccess.h>
29#include <asm/system.h>
30
31#include <media/v4l2-common.h>
32#include <media/v4l2-device.h>
33#include <media/v4l2-ioctl.h>
34
35#define VIDEO_NUM_DEVICES 256
36#define VIDEO_NAME "video4linux"
37
38
39
40
41
42static ssize_t show_index(struct device *cd,
43 struct device_attribute *attr, char *buf)
44{
45 struct video_device *vdev = to_video_device(cd);
46
47 return sprintf(buf, "%i\n", vdev->index);
48}
49
50static ssize_t show_name(struct device *cd,
51 struct device_attribute *attr, char *buf)
52{
53 struct video_device *vdev = to_video_device(cd);
54
55 return sprintf(buf, "%.*s\n", (int)sizeof(vdev->name), vdev->name);
56}
57
58static struct device_attribute video_device_attrs[] = {
59 __ATTR(name, S_IRUGO, show_name, NULL),
60 __ATTR(index, S_IRUGO, show_index, NULL),
61 __ATTR_NULL
62};
63
64
65
66
67static struct video_device *video_device[VIDEO_NUM_DEVICES];
68static DEFINE_MUTEX(videodev_lock);
69static DECLARE_BITMAP(devnode_nums[VFL_TYPE_MAX], VIDEO_NUM_DEVICES);
70
71
72
73
74
75
76#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
77
78static inline unsigned long *devnode_bits(int vfl_type)
79{
80
81
82
83 int idx = (vfl_type > VFL_TYPE_RADIO) ? VFL_TYPE_MAX - 1 : vfl_type;
84
85 return devnode_nums[idx];
86}
87#else
88
89static inline unsigned long *devnode_bits(int vfl_type)
90{
91 return devnode_nums[vfl_type];
92}
93#endif
94
95
96static inline void devnode_set(struct video_device *vdev)
97{
98 set_bit(vdev->num, devnode_bits(vdev->vfl_type));
99}
100
101
102static inline void devnode_clear(struct video_device *vdev)
103{
104 clear_bit(vdev->num, devnode_bits(vdev->vfl_type));
105}
106
107
108static inline int devnode_find(struct video_device *vdev, int from, int to)
109{
110 return find_next_zero_bit(devnode_bits(vdev->vfl_type), to, from);
111}
112
113struct video_device *video_device_alloc(void)
114{
115 return kzalloc(sizeof(struct video_device), GFP_KERNEL);
116}
117EXPORT_SYMBOL(video_device_alloc);
118
119void video_device_release(struct video_device *vdev)
120{
121 kfree(vdev);
122}
123EXPORT_SYMBOL(video_device_release);
124
125void video_device_release_empty(struct video_device *vdev)
126{
127
128
129}
130EXPORT_SYMBOL(video_device_release_empty);
131
132static inline void video_get(struct video_device *vdev)
133{
134 get_device(&vdev->dev);
135}
136
137static inline void video_put(struct video_device *vdev)
138{
139 put_device(&vdev->dev);
140}
141
142
143static void v4l2_device_release(struct device *cd)
144{
145 struct video_device *vdev = to_video_device(cd);
146
147 mutex_lock(&videodev_lock);
148 if (video_device[vdev->minor] != vdev) {
149 mutex_unlock(&videodev_lock);
150
151 WARN_ON(1);
152 return;
153 }
154
155
156 video_device[vdev->minor] = NULL;
157
158
159 cdev_del(vdev->cdev);
160
161
162 vdev->cdev = NULL;
163
164
165 devnode_clear(vdev);
166
167 mutex_unlock(&videodev_lock);
168
169
170
171 vdev->release(vdev);
172}
173
174static struct class video_class = {
175 .name = VIDEO_NAME,
176 .dev_attrs = video_device_attrs,
177};
178
179struct video_device *video_devdata(struct file *file)
180{
181 return video_device[iminor(file->f_path.dentry->d_inode)];
182}
183EXPORT_SYMBOL(video_devdata);
184
185static ssize_t v4l2_read(struct file *filp, char __user *buf,
186 size_t sz, loff_t *off)
187{
188 struct video_device *vdev = video_devdata(filp);
189 int ret = -ENODEV;
190
191 if (!vdev->fops->read)
192 return -EINVAL;
193 if (vdev->lock && mutex_lock_interruptible(vdev->lock))
194 return -ERESTARTSYS;
195 if (video_is_registered(vdev))
196 ret = vdev->fops->read(filp, buf, sz, off);
197 if (vdev->lock)
198 mutex_unlock(vdev->lock);
199 return ret;
200}
201
202static ssize_t v4l2_write(struct file *filp, const char __user *buf,
203 size_t sz, loff_t *off)
204{
205 struct video_device *vdev = video_devdata(filp);
206 int ret = -ENODEV;
207
208 if (!vdev->fops->write)
209 return -EINVAL;
210 if (vdev->lock && mutex_lock_interruptible(vdev->lock))
211 return -ERESTARTSYS;
212 if (video_is_registered(vdev))
213 ret = vdev->fops->write(filp, buf, sz, off);
214 if (vdev->lock)
215 mutex_unlock(vdev->lock);
216 return ret;
217}
218
219static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll)
220{
221 struct video_device *vdev = video_devdata(filp);
222 int ret = POLLERR | POLLHUP;
223
224 if (!vdev->fops->poll)
225 return DEFAULT_POLLMASK;
226 if (vdev->lock)
227 mutex_lock(vdev->lock);
228 if (video_is_registered(vdev))
229 ret = vdev->fops->poll(filp, poll);
230 if (vdev->lock)
231 mutex_unlock(vdev->lock);
232 return ret;
233}
234
235static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
236{
237 struct video_device *vdev = video_devdata(filp);
238 int ret = -ENODEV;
239
240 if (vdev->fops->unlocked_ioctl) {
241 if (vdev->lock && mutex_lock_interruptible(vdev->lock))
242 return -ERESTARTSYS;
243 if (video_is_registered(vdev))
244 ret = vdev->fops->unlocked_ioctl(filp, cmd, arg);
245 if (vdev->lock)
246 mutex_unlock(vdev->lock);
247 } else if (vdev->fops->ioctl) {
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270 static DEFINE_MUTEX(v4l2_ioctl_mutex);
271 struct mutex *m = vdev->v4l2_dev ?
272 &vdev->v4l2_dev->ioctl_lock : &v4l2_ioctl_mutex;
273
274 if (cmd != VIDIOC_DQBUF && mutex_lock_interruptible(m))
275 return -ERESTARTSYS;
276 if (video_is_registered(vdev))
277 ret = vdev->fops->ioctl(filp, cmd, arg);
278 if (cmd != VIDIOC_DQBUF)
279 mutex_unlock(m);
280 } else
281 ret = -ENOTTY;
282
283 return ret;
284}
285
286static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
287{
288 struct video_device *vdev = video_devdata(filp);
289 int ret = -ENODEV;
290
291 if (!vdev->fops->mmap)
292 return ret;
293 if (vdev->lock && mutex_lock_interruptible(vdev->lock))
294 return -ERESTARTSYS;
295 if (video_is_registered(vdev))
296 ret = vdev->fops->mmap(filp, vm);
297 if (vdev->lock)
298 mutex_unlock(vdev->lock);
299 return ret;
300}
301
302
303static int v4l2_open(struct inode *inode, struct file *filp)
304{
305 struct video_device *vdev;
306 int ret = 0;
307
308
309 mutex_lock(&videodev_lock);
310 vdev = video_devdata(filp);
311
312 if (vdev == NULL || !video_is_registered(vdev)) {
313 mutex_unlock(&videodev_lock);
314 return -ENODEV;
315 }
316
317 video_get(vdev);
318 mutex_unlock(&videodev_lock);
319 if (vdev->fops->open) {
320 if (vdev->lock && mutex_lock_interruptible(vdev->lock)) {
321 ret = -ERESTARTSYS;
322 goto err;
323 }
324 if (video_is_registered(vdev))
325 ret = vdev->fops->open(filp);
326 else
327 ret = -ENODEV;
328 if (vdev->lock)
329 mutex_unlock(vdev->lock);
330 }
331
332err:
333
334 if (ret)
335 video_put(vdev);
336 return ret;
337}
338
339
340static int v4l2_release(struct inode *inode, struct file *filp)
341{
342 struct video_device *vdev = video_devdata(filp);
343 int ret = 0;
344
345 if (vdev->fops->release) {
346 if (vdev->lock)
347 mutex_lock(vdev->lock);
348 vdev->fops->release(filp);
349 if (vdev->lock)
350 mutex_unlock(vdev->lock);
351 }
352
353
354
355 video_put(vdev);
356 return ret;
357}
358
359static const struct file_operations v4l2_fops = {
360 .owner = THIS_MODULE,
361 .read = v4l2_read,
362 .write = v4l2_write,
363 .open = v4l2_open,
364 .mmap = v4l2_mmap,
365 .unlocked_ioctl = v4l2_ioctl,
366#ifdef CONFIG_COMPAT
367 .compat_ioctl = v4l2_compat_ioctl32,
368#endif
369 .release = v4l2_release,
370 .poll = v4l2_poll,
371 .llseek = no_llseek,
372};
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387static int get_index(struct video_device *vdev)
388{
389
390
391 static DECLARE_BITMAP(used, VIDEO_NUM_DEVICES);
392 int i;
393
394
395 if (vdev->parent == NULL)
396 return 0;
397
398 bitmap_zero(used, VIDEO_NUM_DEVICES);
399
400 for (i = 0; i < VIDEO_NUM_DEVICES; i++) {
401 if (video_device[i] != NULL &&
402 video_device[i]->parent == vdev->parent) {
403 set_bit(video_device[i]->index, used);
404 }
405 }
406
407 return find_first_zero_bit(used, VIDEO_NUM_DEVICES);
408}
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439static int __video_register_device(struct video_device *vdev, int type, int nr,
440 int warn_if_nr_in_use)
441{
442 int i = 0;
443 int ret;
444 int minor_offset = 0;
445 int minor_cnt = VIDEO_NUM_DEVICES;
446 const char *name_base;
447
448
449
450 vdev->minor = -1;
451
452
453 WARN_ON(!vdev->release);
454 if (!vdev->release)
455 return -EINVAL;
456
457
458 spin_lock_init(&vdev->fh_lock);
459 INIT_LIST_HEAD(&vdev->fh_list);
460
461
462 switch (type) {
463 case VFL_TYPE_GRABBER:
464 name_base = "video";
465 break;
466 case VFL_TYPE_VBI:
467 name_base = "vbi";
468 break;
469 case VFL_TYPE_RADIO:
470 name_base = "radio";
471 break;
472 default:
473 printk(KERN_ERR "%s called with unknown type: %d\n",
474 __func__, type);
475 return -EINVAL;
476 }
477
478 vdev->vfl_type = type;
479 vdev->cdev = NULL;
480 if (vdev->v4l2_dev) {
481 if (vdev->v4l2_dev->dev)
482 vdev->parent = vdev->v4l2_dev->dev;
483 if (vdev->ctrl_handler == NULL)
484 vdev->ctrl_handler = vdev->v4l2_dev->ctrl_handler;
485 }
486
487
488#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
489
490
491
492
493
494 switch (type) {
495 case VFL_TYPE_GRABBER:
496 minor_offset = 0;
497 minor_cnt = 64;
498 break;
499 case VFL_TYPE_RADIO:
500 minor_offset = 64;
501 minor_cnt = 64;
502 break;
503 case VFL_TYPE_VBI:
504 minor_offset = 224;
505 minor_cnt = 32;
506 break;
507 default:
508 minor_offset = 128;
509 minor_cnt = 64;
510 break;
511 }
512#endif
513
514
515 mutex_lock(&videodev_lock);
516 nr = devnode_find(vdev, nr == -1 ? 0 : nr, minor_cnt);
517 if (nr == minor_cnt)
518 nr = devnode_find(vdev, 0, minor_cnt);
519 if (nr == minor_cnt) {
520 printk(KERN_ERR "could not get a free device node number\n");
521 mutex_unlock(&videodev_lock);
522 return -ENFILE;
523 }
524#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
525
526 i = nr;
527#else
528
529
530 for (i = 0; i < VIDEO_NUM_DEVICES; i++)
531 if (video_device[i] == NULL)
532 break;
533 if (i == VIDEO_NUM_DEVICES) {
534 mutex_unlock(&videodev_lock);
535 printk(KERN_ERR "could not get a free minor\n");
536 return -ENFILE;
537 }
538#endif
539 vdev->minor = i + minor_offset;
540 vdev->num = nr;
541 devnode_set(vdev);
542
543
544 WARN_ON(video_device[vdev->minor] != NULL);
545 vdev->index = get_index(vdev);
546 mutex_unlock(&videodev_lock);
547
548
549 vdev->cdev = cdev_alloc();
550 if (vdev->cdev == NULL) {
551 ret = -ENOMEM;
552 goto cleanup;
553 }
554 vdev->cdev->ops = &v4l2_fops;
555 vdev->cdev->owner = vdev->fops->owner;
556 ret = cdev_add(vdev->cdev, MKDEV(VIDEO_MAJOR, vdev->minor), 1);
557 if (ret < 0) {
558 printk(KERN_ERR "%s: cdev_add failed\n", __func__);
559 kfree(vdev->cdev);
560 vdev->cdev = NULL;
561 goto cleanup;
562 }
563
564
565 vdev->dev.class = &video_class;
566 vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor);
567 if (vdev->parent)
568 vdev->dev.parent = vdev->parent;
569 dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num);
570 ret = device_register(&vdev->dev);
571 if (ret < 0) {
572 printk(KERN_ERR "%s: device_register failed\n", __func__);
573 goto cleanup;
574 }
575
576
577 vdev->dev.release = v4l2_device_release;
578
579 if (nr != -1 && nr != vdev->num && warn_if_nr_in_use)
580 printk(KERN_WARNING "%s: requested %s%d, got %s\n", __func__,
581 name_base, nr, video_device_node_name(vdev));
582
583
584 set_bit(V4L2_FL_REGISTERED, &vdev->flags);
585 mutex_lock(&videodev_lock);
586 video_device[vdev->minor] = vdev;
587 mutex_unlock(&videodev_lock);
588 return 0;
589
590cleanup:
591 mutex_lock(&videodev_lock);
592 if (vdev->cdev)
593 cdev_del(vdev->cdev);
594 devnode_clear(vdev);
595 mutex_unlock(&videodev_lock);
596
597 vdev->minor = -1;
598 return ret;
599}
600
601int video_register_device(struct video_device *vdev, int type, int nr)
602{
603 return __video_register_device(vdev, type, nr, 1);
604}
605EXPORT_SYMBOL(video_register_device);
606
607int video_register_device_no_warn(struct video_device *vdev, int type, int nr)
608{
609 return __video_register_device(vdev, type, nr, 0);
610}
611EXPORT_SYMBOL(video_register_device_no_warn);
612
613
614
615
616
617
618
619
620void video_unregister_device(struct video_device *vdev)
621{
622
623 if (!vdev || !video_is_registered(vdev))
624 return;
625
626 mutex_lock(&videodev_lock);
627
628
629
630 clear_bit(V4L2_FL_REGISTERED, &vdev->flags);
631 mutex_unlock(&videodev_lock);
632 device_unregister(&vdev->dev);
633}
634EXPORT_SYMBOL(video_unregister_device);
635
636
637
638
639static int __init videodev_init(void)
640{
641 dev_t dev = MKDEV(VIDEO_MAJOR, 0);
642 int ret;
643
644 printk(KERN_INFO "Linux video capture interface: v2.00\n");
645 ret = register_chrdev_region(dev, VIDEO_NUM_DEVICES, VIDEO_NAME);
646 if (ret < 0) {
647 printk(KERN_WARNING "videodev: unable to get major %d\n",
648 VIDEO_MAJOR);
649 return ret;
650 }
651
652 ret = class_register(&video_class);
653 if (ret < 0) {
654 unregister_chrdev_region(dev, VIDEO_NUM_DEVICES);
655 printk(KERN_WARNING "video_dev: class_register failed\n");
656 return -EIO;
657 }
658
659 return 0;
660}
661
662static void __exit videodev_exit(void)
663{
664 dev_t dev = MKDEV(VIDEO_MAJOR, 0);
665
666 class_unregister(&video_class);
667 unregister_chrdev_region(dev, VIDEO_NUM_DEVICES);
668}
669
670module_init(videodev_init)
671module_exit(videodev_exit)
672
673MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
674MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
675MODULE_LICENSE("GPL");
676MODULE_ALIAS_CHARDEV_MAJOR(VIDEO_MAJOR);
677
678
679
680
681
682
683
684