提交 55712ff7 编写于 作者: M Mauro Carvalho Chehab

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: NMauro Carvalho Chehab <mchehab@infradead.org>
上级 f905c442
...@@ -59,6 +59,7 @@ ...@@ -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) ...@@ -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) ...@@ -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); 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; return 0;
} }
...@@ -1166,55 +1176,60 @@ static struct video_device vivi_template = { ...@@ -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;
*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); if (video_nr >= 0)
snprintf(vfd->name, sizeof(vfd->name), "%s (%i)", video_nr++;
vivi_template.name, vfd->minor);
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; 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"); ...@@ -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");
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册