diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-12-10 02:07:03 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-01-25 16:03:21 -0500 |
commit | f905c442e5b19f75fe4e8ce96f2acffa565f2392 (patch) | |
tree | 204196dd55470f3be766a55500027c6b3d691d00 /drivers/media/video/vivi.c | |
parent | d2761f227162f610d35b9d68564f5c64774be581 (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.c | 40 |
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; |
992 | found: | 992 | found: |
@@ -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 | ||
1070 | static int vivi_release(struct inode *inode, struct file *file) | 1070 | static 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 | ||
1091 | static 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 | |||
1091 | static int | 1103 | static int |
1092 | vivi_mmap(struct file *file, struct vm_area_struct * vma) | 1104 | vivi_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) | |||
1109 | static const struct file_operations vivi_fops = { | 1121 | static 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 | ||
1120 | static struct video_device vivi = { | 1132 | static 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 | ||
1196 | module_init(vivi_init); | 1220 | module_init(vivi_init); |