V4L/DVB (6754): Allow vivi to open multiple video devices
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>
This commit is contained in:
parent
f905c442e5
commit
55712ff7e0
1 changed files with 62 additions and 44 deletions
|
@ -59,6 +59,7 @@
|
||||||
static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
|
static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
|
||||||
static struct video_device vivi; /* Video device */
|
static struct video_device vivi; /* Video device */
|
||||||
static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
|
static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
|
||||||
|
static int n_devs = 1; /* Number of virtual devices */
|
||||||
|
|
||||||
/* supported controls */
|
/* supported controls */
|
||||||
static struct v4l2_queryctrl vivi_qctrl[] = {
|
static struct v4l2_queryctrl vivi_qctrl[] = {
|
||||||
|
@ -1079,7 +1080,7 @@ static int vivi_close(struct inode *inode, struct file *file)
|
||||||
videobuf_stop(&fh->vb_vidq);
|
videobuf_stop(&fh->vb_vidq);
|
||||||
videobuf_mmap_free(&fh->vb_vidq);
|
videobuf_mmap_free(&fh->vb_vidq);
|
||||||
|
|
||||||
kfree (fh);
|
kfree(fh);
|
||||||
|
|
||||||
dev->users--;
|
dev->users--;
|
||||||
|
|
||||||
|
@ -1088,14 +1089,23 @@ static int vivi_close(struct inode *inode, struct file *file)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vivi_release(struct vivi_dev *dev)
|
static int vivi_release(void)
|
||||||
{
|
{
|
||||||
if (-1 != dev->vfd->minor)
|
struct vivi_dev *dev;
|
||||||
video_unregister_device(dev->vfd);
|
struct list_head *list;
|
||||||
else
|
|
||||||
video_device_release(dev->vfd);
|
|
||||||
|
|
||||||
dev->vfd = NULL;
|
while (!list_empty(&vivi_devlist)) {
|
||||||
|
list = vivi_devlist.next;
|
||||||
|
list_del(list);
|
||||||
|
dev = list_entry(list, struct vivi_dev, vivi_devlist);
|
||||||
|
|
||||||
|
if (-1 != dev->vfd->minor)
|
||||||
|
video_unregister_device(dev->vfd);
|
||||||
|
else
|
||||||
|
video_device_release(dev->vfd);
|
||||||
|
|
||||||
|
kfree(dev);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1166,55 +1176,60 @@ static struct video_device vivi_template = {
|
||||||
|
|
||||||
static int __init vivi_init(void)
|
static int __init vivi_init(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = -ENOMEM, i;
|
||||||
struct vivi_dev *dev;
|
struct vivi_dev *dev;
|
||||||
struct video_device *vfd;
|
struct video_device *vfd;
|
||||||
|
|
||||||
dev = kzalloc(sizeof(*dev),GFP_KERNEL);
|
for (i = 0; i < n_devs; i++) {
|
||||||
if (NULL == dev)
|
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||||
return -ENOMEM;
|
if (NULL == dev)
|
||||||
list_add_tail(&dev->vivi_devlist,&vivi_devlist);
|
break;
|
||||||
|
|
||||||
/* init video dma queues */
|
list_add_tail(&dev->vivi_devlist, &vivi_devlist);
|
||||||
INIT_LIST_HEAD(&dev->vidq.active);
|
|
||||||
INIT_LIST_HEAD(&dev->vidq.queued);
|
|
||||||
init_waitqueue_head(&dev->vidq.wq);
|
|
||||||
|
|
||||||
/* initialize locks */
|
/* init video dma queues */
|
||||||
mutex_init(&dev->lock);
|
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;
|
/* initialize locks */
|
||||||
dev->vidq.timeout.data = (unsigned long)dev;
|
mutex_init(&dev->lock);
|
||||||
init_timer(&dev->vidq.timeout);
|
|
||||||
|
|
||||||
vfd = video_device_alloc();
|
dev->vidq.timeout.function = vivi_vid_timeout;
|
||||||
if (NULL == vfd)
|
dev->vidq.timeout.data = (unsigned long)dev;
|
||||||
return -ENOMEM;
|
init_timer(&dev->vidq.timeout);
|
||||||
|
|
||||||
*vfd = vivi_template;
|
vfd = video_device_alloc();
|
||||||
|
if (NULL == vfd)
|
||||||
|
break;
|
||||||
|
|
||||||
ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
|
*vfd = vivi_template;
|
||||||
snprintf(vfd->name, sizeof(vfd->name), "%s (%i)",
|
|
||||||
vivi_template.name, vfd->minor);
|
|
||||||
|
|
||||||
dev->vfd = vfd;
|
ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
|
||||||
|
if (ret < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
printk(KERN_INFO "Video Technology Magazine Virtual Video Capture Board (Load status: %d)\n", ret);
|
snprintf(vfd->name, sizeof(vfd->name), "%s (%i)",
|
||||||
|
vivi_template.name, vfd->minor);
|
||||||
|
|
||||||
|
if (video_nr >= 0)
|
||||||
|
video_nr++;
|
||||||
|
|
||||||
|
dev->vfd = vfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit vivi_exit(void)
|
static void __exit vivi_exit(void)
|
||||||
{
|
{
|
||||||
struct vivi_dev *h;
|
vivi_release();
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(vivi_init);
|
module_init(vivi_init);
|
||||||
|
@ -1225,10 +1240,13 @@ MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol");
|
||||||
MODULE_LICENSE("Dual BSD/GPL");
|
MODULE_LICENSE("Dual BSD/GPL");
|
||||||
|
|
||||||
module_param(video_nr, int, 0);
|
module_param(video_nr, int, 0);
|
||||||
|
MODULE_PARM_DESC(video_nr, "video iminor start number");
|
||||||
|
|
||||||
module_param_named(debug,vivi.debug, int, 0644);
|
module_param(n_devs, int, 0);
|
||||||
MODULE_PARM_DESC(debug,"activates debug info");
|
MODULE_PARM_DESC(n_devs, "number of video devices to create");
|
||||||
|
|
||||||
module_param(vid_limit,int,0644);
|
module_param_named(debug, vivi.debug, int, 0644);
|
||||||
MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes");
|
MODULE_PARM_DESC(debug, "activates debug info");
|
||||||
|
|
||||||
|
module_param(vid_limit, int, 0644);
|
||||||
|
MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
|
||||||
|
|
Loading…
Reference in a new issue