mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-24 12:09:35 +07:00
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>
This commit is contained in:
parent
d2761f2271
commit
f905c442e5
@ -170,7 +170,7 @@ struct vivi_dev {
|
|||||||
int users;
|
int users;
|
||||||
|
|
||||||
/* various device info */
|
/* various device info */
|
||||||
struct video_device vfd;
|
struct video_device *vfd;
|
||||||
|
|
||||||
struct vivi_dmaqueue vidq;
|
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);
|
printk(KERN_DEBUG "vivi: open called (minor=%d)\n",minor);
|
||||||
|
|
||||||
list_for_each_entry(dev, &vivi_devlist, vivi_devlist)
|
list_for_each_entry(dev, &vivi_devlist, vivi_devlist)
|
||||||
if (dev->vfd.minor == minor)
|
if (dev->vfd->minor == minor)
|
||||||
goto found;
|
goto found;
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
found:
|
found:
|
||||||
@ -1067,7 +1067,7 @@ vivi_poll(struct file *file, struct poll_table_struct *wait)
|
|||||||
return videobuf_poll_stream(file, q, 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_fh *fh = file->private_data;
|
||||||
struct vivi_dev *dev = fh->dev;
|
struct vivi_dev *dev = fh->dev;
|
||||||
@ -1088,6 +1088,18 @@ static int vivi_release(struct inode *inode, struct file *file)
|
|||||||
return 0;
|
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
|
static int
|
||||||
vivi_mmap(struct file *file, struct vm_area_struct * vma)
|
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 = {
|
static const struct file_operations vivi_fops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.open = vivi_open,
|
.open = vivi_open,
|
||||||
.release = vivi_release,
|
.release = vivi_close,
|
||||||
.read = vivi_read,
|
.read = vivi_read,
|
||||||
.poll = vivi_poll,
|
.poll = vivi_poll,
|
||||||
.ioctl = video_ioctl2, /* V4L2 ioctl handler */
|
.ioctl = video_ioctl2, /* V4L2 ioctl handler */
|
||||||
@ -1117,12 +1129,12 @@ static const struct file_operations vivi_fops = {
|
|||||||
.llseek = no_llseek,
|
.llseek = no_llseek,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct video_device vivi = {
|
static struct video_device vivi_template = {
|
||||||
.name = "vivi",
|
.name = "vivi",
|
||||||
.type = VID_TYPE_CAPTURE,
|
.type = VID_TYPE_CAPTURE,
|
||||||
.fops = &vivi_fops,
|
.fops = &vivi_fops,
|
||||||
.minor = -1,
|
.minor = -1,
|
||||||
// .release = video_device_release,
|
.release = video_device_release,
|
||||||
|
|
||||||
.vidioc_querycap = vidioc_querycap,
|
.vidioc_querycap = vidioc_querycap,
|
||||||
.vidioc_enum_fmt_cap = vidioc_enum_fmt_cap,
|
.vidioc_enum_fmt_cap = vidioc_enum_fmt_cap,
|
||||||
@ -1156,6 +1168,7 @@ static int __init vivi_init(void)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct vivi_dev *dev;
|
struct vivi_dev *dev;
|
||||||
|
struct video_device *vfd;
|
||||||
|
|
||||||
dev = kzalloc(sizeof(*dev),GFP_KERNEL);
|
dev = kzalloc(sizeof(*dev),GFP_KERNEL);
|
||||||
if (NULL == dev)
|
if (NULL == dev)
|
||||||
@ -1174,7 +1187,18 @@ static int __init vivi_init(void)
|
|||||||
dev->vidq.timeout.data = (unsigned long)dev;
|
dev->vidq.timeout.data = (unsigned long)dev;
|
||||||
init_timer(&dev->vidq.timeout);
|
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);
|
printk(KERN_INFO "Video Technology Magazine Virtual Video Capture Board (Load status: %d)\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1188,9 +1212,9 @@ static void __exit vivi_exit(void)
|
|||||||
list = vivi_devlist.next;
|
list = vivi_devlist.next;
|
||||||
list_del(list);
|
list_del(list);
|
||||||
h = list_entry(list, struct vivi_dev, vivi_devlist);
|
h = list_entry(list, struct vivi_dev, vivi_devlist);
|
||||||
|
vivi_release(h);
|
||||||
kfree (h);
|
kfree (h);
|
||||||
}
|
}
|
||||||
video_unregister_device(&vivi);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(vivi_init);
|
module_init(vivi_init);
|
||||||
|
Loading…
Reference in New Issue
Block a user