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:
Родитель
f905c442e5
Коммит
55712ff7e0
|
@ -59,6 +59,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[] = {
|
||||
|
@ -1079,7 +1080,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--;
|
||||
|
||||
|
@ -1088,14 +1089,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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -1166,55 +1176,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;
|
||||
|
||||
ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
|
||||
snprintf(vfd->name, sizeof(vfd->name), "%s (%i)",
|
||||
vivi_template.name, vfd->minor);
|
||||
*vfd = vivi_template;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -1225,10 +1240,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");
|
||||
|
|
Загрузка…
Ссылка в новой задаче