diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-12-10 05:38:11 -0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-12-10 05:38:11 -0200 |
commit | 1022b8e7b9eec01adec0cf40ed43487611f9022e (patch) | |
tree | d37bae87720eb19251abc49b6d0d280ab45fa97f /linux | |
parent | 162148c8ef07fc2d523af872e7b4bc2956d13fac (diff) | |
download | mediapointer-dvb-s2-1022b8e7b9eec01adec0cf40ed43487611f9022e.tar.gz mediapointer-dvb-s2-1022b8e7b9eec01adec0cf40ed43487611f9022e.tar.bz2 |
Allow vivi to open multiple video devices
From: Mauro Carvalho Chehab <mchehab@infradead.org>
Now, it is possible to open multiple vivi devices, by using n_devs parameter.
This makes vivi driver closer to a real one.
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'linux')
-rw-r--r-- | linux/drivers/media/video/vivi.c | 106 |
1 files changed, 62 insertions, 44 deletions
diff --git a/linux/drivers/media/video/vivi.c b/linux/drivers/media/video/vivi.c index 7c6939ca3..64fc5ee8b 100644 --- a/linux/drivers/media/video/vivi.c +++ b/linux/drivers/media/video/vivi.c @@ -68,6 +68,7 @@ static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ static struct video_device vivi; /* Video device */ static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ +static int n_devs = 1; /* Number of virtual devices */ /* supported controls */ static struct v4l2_queryctrl vivi_qctrl[] = { @@ -1177,7 +1178,7 @@ static int vivi_close(struct inode *inode, struct file *file) videobuf_stop(&fh->vb_vidq); videobuf_mmap_free(&fh->vb_vidq); - kfree (fh); + kfree(fh); dev->users--; @@ -1186,14 +1187,23 @@ static int vivi_close(struct inode *inode, struct file *file) return 0; } -static int vivi_release(struct vivi_dev *dev) +static int vivi_release(void) { - if (-1 != dev->vfd->minor) - video_unregister_device(dev->vfd); - else - video_device_release(dev->vfd); + struct vivi_dev *dev; + struct list_head *list; + + while (!list_empty(&vivi_devlist)) { + list = vivi_devlist.next; + list_del(list); + dev = list_entry(list, struct vivi_dev, vivi_devlist); - dev->vfd = NULL; + if (-1 != dev->vfd->minor) + video_unregister_device(dev->vfd); + else + video_device_release(dev->vfd); + + kfree(dev); + } return 0; } @@ -1264,55 +1274,60 @@ static struct video_device vivi_template = { static int __init vivi_init(void) { - int ret; + int ret = -ENOMEM, i; struct vivi_dev *dev; struct video_device *vfd; - dev = kzalloc(sizeof(*dev),GFP_KERNEL); - if (NULL == dev) - return -ENOMEM; - list_add_tail(&dev->vivi_devlist,&vivi_devlist); + for (i = 0; i < n_devs; i++) { + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (NULL == dev) + break; - /* init video dma queues */ - INIT_LIST_HEAD(&dev->vidq.active); - INIT_LIST_HEAD(&dev->vidq.queued); - init_waitqueue_head(&dev->vidq.wq); + list_add_tail(&dev->vivi_devlist, &vivi_devlist); - /* initialize locks */ - mutex_init(&dev->lock); + /* init video dma queues */ + INIT_LIST_HEAD(&dev->vidq.active); + INIT_LIST_HEAD(&dev->vidq.queued); + init_waitqueue_head(&dev->vidq.wq); - dev->vidq.timeout.function = vivi_vid_timeout; - dev->vidq.timeout.data = (unsigned long)dev; - init_timer(&dev->vidq.timeout); + /* initialize locks */ + mutex_init(&dev->lock); - vfd = video_device_alloc(); - if (NULL == vfd) - return -ENOMEM; + dev->vidq.timeout.function = vivi_vid_timeout; + dev->vidq.timeout.data = (unsigned long)dev; + init_timer(&dev->vidq.timeout); - *vfd = vivi_template; + vfd = video_device_alloc(); + if (NULL == vfd) + break; + + *vfd = vivi_template; + + ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); + if (ret < 0) + break; + + snprintf(vfd->name, sizeof(vfd->name), "%s (%i)", + vivi_template.name, vfd->minor); - ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); - snprintf(vfd->name, sizeof(vfd->name), "%s (%i)", - vivi_template.name, vfd->minor); + if (video_nr >= 0) + video_nr++; - dev->vfd = vfd; + dev->vfd = vfd; + } - printk(KERN_INFO "Video Technology Magazine Virtual Video Capture Board (Load status: %d)\n", ret); + if (ret < 0) { + vivi_release(); + printk(KERN_INFO "Error %d while loading vivi driver\n", ret); + } else + printk(KERN_INFO "Video Technology Magazine Virtual Video " + "Capture Board successfully loaded.\n"); return ret; } static void __exit vivi_exit(void) { - struct vivi_dev *h; - struct list_head *list; - - while (!list_empty(&vivi_devlist)) { - list = vivi_devlist.next; - list_del(list); - h = list_entry(list, struct vivi_dev, vivi_devlist); - vivi_release(h); - kfree (h); - } + vivi_release(); } module_init(vivi_init); @@ -1323,10 +1338,13 @@ MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol"); MODULE_LICENSE("Dual BSD/GPL"); module_param(video_nr, int, 0); +MODULE_PARM_DESC(video_nr, "video iminor start number"); -module_param_named(debug,vivi.debug, int, 0644); -MODULE_PARM_DESC(debug,"activates debug info"); +module_param(n_devs, int, 0); +MODULE_PARM_DESC(n_devs, "number of video devices to create"); -module_param(vid_limit,int,0644); -MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes"); +module_param_named(debug, vivi.debug, int, 0644); +MODULE_PARM_DESC(debug, "activates debug info"); +module_param(vid_limit, int, 0644); +MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); |