summaryrefslogtreecommitdiffstats
path: root/drivers/media/video/vivi.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2007-12-10 04:07:03 -0300
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-01-25 19:03:21 -0200
commitf905c442e5b19f75fe4e8ce96f2acffa565f2392 (patch)
tree204196dd55470f3be766a55500027c6b3d691d00 /drivers/media/video/vivi.c
parentd2761f227162f610d35b9d68564f5c64774be581 (diff)
V4L/DVB (6753): Fix vivi to support non-zero minor node
There were a trouble at vivi driver when using non-zero inodes. This where due to not properly preserving the minor inode after calling video_register. Since this driver is a reference for newer drivers, and it is possible to have more than one video device inside the machine, this patch makes vivi to dynamically allocate video_device struct. Thanks to Gregor Jasny <jasny@vidsoft.de> for pointing the issue. Also, this patch removes a very anoying (but useless) message of not having a proper release call. CC: Gregor Jasny <jasny@vidsoft.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/vivi.c')
-rw-r--r--drivers/media/video/vivi.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index fe9784a0cc2..5ddaaa370cb 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -170,7 +170,7 @@ struct vivi_dev {
int users;
/* various device info */
- struct video_device vfd;
+ struct video_device *vfd;
struct vivi_dmaqueue vidq;
@@ -986,7 +986,7 @@ static int vivi_open(struct inode *inode, struct file *file)
printk(KERN_DEBUG "vivi: open called (minor=%d)\n",minor);
list_for_each_entry(dev, &vivi_devlist, vivi_devlist)
- if (dev->vfd.minor == minor)
+ if (dev->vfd->minor == minor)
goto found;
return -ENODEV;
found:
@@ -1067,7 +1067,7 @@ vivi_poll(struct file *file, struct poll_table_struct *wait)
return videobuf_poll_stream(file, q, wait);
}
-static int vivi_release(struct inode *inode, struct file *file)
+static int vivi_close(struct inode *inode, struct file *file)
{
struct vivi_fh *fh = file->private_data;
struct vivi_dev *dev = fh->dev;
@@ -1088,6 +1088,18 @@ static int vivi_release(struct inode *inode, struct file *file)
return 0;
}
+static int vivi_release(struct vivi_dev *dev)
+{
+ if (-1 != dev->vfd->minor)
+ video_unregister_device(dev->vfd);
+ else
+ video_device_release(dev->vfd);
+
+ dev->vfd = NULL;
+
+ return 0;
+}
+
static int
vivi_mmap(struct file *file, struct vm_area_struct * vma)
{
@@ -1109,7 +1121,7 @@ vivi_mmap(struct file *file, struct vm_area_struct * vma)
static const struct file_operations vivi_fops = {
.owner = THIS_MODULE,
.open = vivi_open,
- .release = vivi_release,
+ .release = vivi_close,
.read = vivi_read,
.poll = vivi_poll,
.ioctl = video_ioctl2, /* V4L2 ioctl handler */
@@ -1117,12 +1129,12 @@ static const struct file_operations vivi_fops = {
.llseek = no_llseek,
};
-static struct video_device vivi = {
+static struct video_device vivi_template = {
.name = "vivi",
.type = VID_TYPE_CAPTURE,
.fops = &vivi_fops,
.minor = -1,
-// .release = video_device_release,
+ .release = video_device_release,
.vidioc_querycap = vidioc_querycap,
.vidioc_enum_fmt_cap = vidioc_enum_fmt_cap,
@@ -1156,6 +1168,7 @@ static int __init vivi_init(void)
{
int ret;
struct vivi_dev *dev;
+ struct video_device *vfd;
dev = kzalloc(sizeof(*dev),GFP_KERNEL);
if (NULL == dev)
@@ -1174,7 +1187,18 @@ static int __init vivi_init(void)
dev->vidq.timeout.data = (unsigned long)dev;
init_timer(&dev->vidq.timeout);
- ret = video_register_device(&vivi, VFL_TYPE_GRABBER, video_nr);
+ vfd = video_device_alloc();
+ if (NULL == vfd)
+ return -ENOMEM;
+
+ *vfd = vivi_template;
+
+ ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
+ snprintf(vfd->name, sizeof(vfd->name), "%s (%i)",
+ vivi_template.name, vfd->minor);
+
+ dev->vfd = vfd;
+
printk(KERN_INFO "Video Technology Magazine Virtual Video Capture Board (Load status: %d)\n", ret);
return ret;
}
@@ -1188,9 +1212,9 @@ static void __exit vivi_exit(void)
list = vivi_devlist.next;
list_del(list);
h = list_entry(list, struct vivi_dev, vivi_devlist);
+ vivi_release(h);
kfree (h);
}
- video_unregister_device(&vivi);
}
module_init(vivi_init);