aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/vivi.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2007-12-10 02:07:03 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-01-25 16:03:21 -0500
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 fe9784a0cc21..5ddaaa370cbc 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -170,7 +170,7 @@ struct vivi_dev {
170 int users; 170 int users;
171 171
172 /* various device info */ 172 /* various device info */
173 struct video_device vfd; 173 struct video_device *vfd;
174 174
175 struct vivi_dmaqueue vidq; 175 struct vivi_dmaqueue vidq;
176 176
@@ -986,7 +986,7 @@ static int vivi_open(struct inode *inode, struct file *file)
986 printk(KERN_DEBUG "vivi: open called (minor=%d)\n",minor); 986 printk(KERN_DEBUG "vivi: open called (minor=%d)\n",minor);
987 987
988 list_for_each_entry(dev, &vivi_devlist, vivi_devlist) 988 list_for_each_entry(dev, &vivi_devlist, vivi_devlist)
989 if (dev->vfd.minor == minor) 989 if (dev->vfd->minor == minor)
990 goto found; 990 goto found;
991 return -ENODEV; 991 return -ENODEV;
992found: 992found:
@@ -1067,7 +1067,7 @@ vivi_poll(struct file *file, struct poll_table_struct *wait)
1067 return videobuf_poll_stream(file, q, wait); 1067 return videobuf_poll_stream(file, q, wait);
1068} 1068}
1069 1069
1070static int vivi_release(struct inode *inode, struct file *file) 1070static int vivi_close(struct inode *inode, struct file *file)
1071{ 1071{
1072 struct vivi_fh *fh = file->private_data; 1072 struct vivi_fh *fh = file->private_data;
1073 struct vivi_dev *dev = fh->dev; 1073 struct vivi_dev *dev = fh->dev;
@@ -1088,6 +1088,18 @@ static int vivi_release(struct inode *inode, struct file *file)
1088 return 0; 1088 return 0;
1089} 1089}
1090 1090
1091static int vivi_release(struct vivi_dev *dev)
1092{
1093 if (-1 != dev->vfd->minor)
1094 video_unregister_device(dev->vfd);
1095 else
1096 video_device_release(dev->vfd);
1097
1098 dev->vfd = NULL;
1099
1100 return 0;
1101}
1102
1091static int 1103static int
1092vivi_mmap(struct file *file, struct vm_area_struct * vma) 1104vivi_mmap(struct file *file, struct vm_area_struct * vma)
1093{ 1105{
@@ -1109,7 +1121,7 @@ vivi_mmap(struct file *file, struct vm_area_struct * vma)
1109static const struct file_operations vivi_fops = { 1121static const struct file_operations vivi_fops = {
1110 .owner = THIS_MODULE, 1122 .owner = THIS_MODULE,
1111 .open = vivi_open, 1123 .open = vivi_open,
1112 .release = vivi_release, 1124 .release = vivi_close,
1113 .read = vivi_read, 1125 .read = vivi_read,
1114 .poll = vivi_poll, 1126 .poll = vivi_poll,
1115 .ioctl = video_ioctl2, /* V4L2 ioctl handler */ 1127 .ioctl = video_ioctl2, /* V4L2 ioctl handler */
@@ -1117,12 +1129,12 @@ static const struct file_operations vivi_fops = {
1117 .llseek = no_llseek, 1129 .llseek = no_llseek,
1118}; 1130};
1119 1131
1120static struct video_device vivi = { 1132static struct video_device vivi_template = {
1121 .name = "vivi", 1133 .name = "vivi",
1122 .type = VID_TYPE_CAPTURE, 1134 .type = VID_TYPE_CAPTURE,
1123 .fops = &vivi_fops, 1135 .fops = &vivi_fops,
1124 .minor = -1, 1136 .minor = -1,
1125// .release = video_device_release, 1137 .release = video_device_release,
1126 1138
1127 .vidioc_querycap = vidioc_querycap, 1139 .vidioc_querycap = vidioc_querycap,
1128 .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap, 1140 .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap,
@@ -1156,6 +1168,7 @@ static int __init vivi_init(void)
1156{ 1168{
1157 int ret; 1169 int ret;
1158 struct vivi_dev *dev; 1170 struct vivi_dev *dev;
1171 struct video_device *vfd;
1159 1172
1160 dev = kzalloc(sizeof(*dev),GFP_KERNEL); 1173 dev = kzalloc(sizeof(*dev),GFP_KERNEL);
1161 if (NULL == dev) 1174 if (NULL == dev)
@@ -1174,7 +1187,18 @@ static int __init vivi_init(void)
1174 dev->vidq.timeout.data = (unsigned long)dev; 1187 dev->vidq.timeout.data = (unsigned long)dev;
1175 init_timer(&dev->vidq.timeout); 1188 init_timer(&dev->vidq.timeout);
1176 1189
1177 ret = video_register_device(&vivi, VFL_TYPE_GRABBER, video_nr); 1190 vfd = video_device_alloc();
1191 if (NULL == vfd)
1192 return -ENOMEM;
1193
1194 *vfd = vivi_template;
1195
1196 ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
1197 snprintf(vfd->name, sizeof(vfd->name), "%s (%i)",
1198 vivi_template.name, vfd->minor);
1199
1200 dev->vfd = vfd;
1201
1178 printk(KERN_INFO "Video Technology Magazine Virtual Video Capture Board (Load status: %d)\n", ret); 1202 printk(KERN_INFO "Video Technology Magazine Virtual Video Capture Board (Load status: %d)\n", ret);
1179 return ret; 1203 return ret;
1180} 1204}
@@ -1188,9 +1212,9 @@ static void __exit vivi_exit(void)
1188 list = vivi_devlist.next; 1212 list = vivi_devlist.next;
1189 list_del(list); 1213 list_del(list);
1190 h = list_entry(list, struct vivi_dev, vivi_devlist); 1214 h = list_entry(list, struct vivi_dev, vivi_devlist);
1215 vivi_release(h);
1191 kfree (h); 1216 kfree (h);
1192 } 1217 }
1193 video_unregister_device(&vivi);
1194} 1218}
1195 1219
1196module_init(vivi_init); 1220module_init(vivi_init);