diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-12-10 02:38:11 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-01-25 16:03:21 -0500 |
commit | 55712ff7e06b721fbeebd36499bad4a11b7d8327 (patch) | |
tree | 05d943d39d9b87eab483df65b625dbd621ded2ae /drivers/media/video/vivi.c | |
parent | f905c442e5b19f75fe4e8ce96f2acffa565f2392 (diff) |
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: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/vivi.c')
-rw-r--r-- | drivers/media/video/vivi.c | 106 |
1 files changed, 62 insertions, 44 deletions
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 5ddaaa370cbc..fda01f49efdf 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c | |||
@@ -59,6 +59,7 @@ | |||
59 | static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ | 59 | static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ |
60 | static struct video_device vivi; /* Video device */ | 60 | static struct video_device vivi; /* Video device */ |
61 | static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ | 61 | static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ |
62 | static int n_devs = 1; /* Number of virtual devices */ | ||
62 | 63 | ||
63 | /* supported controls */ | 64 | /* supported controls */ |
64 | static struct v4l2_queryctrl vivi_qctrl[] = { | 65 | static struct v4l2_queryctrl vivi_qctrl[] = { |
@@ -1079,7 +1080,7 @@ static int vivi_close(struct inode *inode, struct file *file) | |||
1079 | videobuf_stop(&fh->vb_vidq); | 1080 | videobuf_stop(&fh->vb_vidq); |
1080 | videobuf_mmap_free(&fh->vb_vidq); | 1081 | videobuf_mmap_free(&fh->vb_vidq); |
1081 | 1082 | ||
1082 | kfree (fh); | 1083 | kfree(fh); |
1083 | 1084 | ||
1084 | dev->users--; | 1085 | dev->users--; |
1085 | 1086 | ||
@@ -1088,14 +1089,23 @@ static int vivi_close(struct inode *inode, struct file *file) | |||
1088 | return 0; | 1089 | return 0; |
1089 | } | 1090 | } |
1090 | 1091 | ||
1091 | static int vivi_release(struct vivi_dev *dev) | 1092 | static int vivi_release(void) |
1092 | { | 1093 | { |
1093 | if (-1 != dev->vfd->minor) | 1094 | struct vivi_dev *dev; |
1094 | video_unregister_device(dev->vfd); | 1095 | struct list_head *list; |
1095 | else | 1096 | |
1096 | video_device_release(dev->vfd); | 1097 | while (!list_empty(&vivi_devlist)) { |
1098 | list = vivi_devlist.next; | ||
1099 | list_del(list); | ||
1100 | dev = list_entry(list, struct vivi_dev, vivi_devlist); | ||
1097 | 1101 | ||
1098 | dev->vfd = NULL; | 1102 | if (-1 != dev->vfd->minor) |
1103 | video_unregister_device(dev->vfd); | ||
1104 | else | ||
1105 | video_device_release(dev->vfd); | ||
1106 | |||
1107 | kfree(dev); | ||
1108 | } | ||
1099 | 1109 | ||
1100 | return 0; | 1110 | return 0; |
1101 | } | 1111 | } |
@@ -1166,55 +1176,60 @@ static struct video_device vivi_template = { | |||
1166 | 1176 | ||
1167 | static int __init vivi_init(void) | 1177 | static int __init vivi_init(void) |
1168 | { | 1178 | { |
1169 | int ret; | 1179 | int ret = -ENOMEM, i; |
1170 | struct vivi_dev *dev; | 1180 | struct vivi_dev *dev; |
1171 | struct video_device *vfd; | 1181 | struct video_device *vfd; |
1172 | 1182 | ||
1173 | dev = kzalloc(sizeof(*dev),GFP_KERNEL); | 1183 | for (i = 0; i < n_devs; i++) { |
1174 | if (NULL == dev) | 1184 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
1175 | return -ENOMEM; | 1185 | if (NULL == dev) |
1176 | list_add_tail(&dev->vivi_devlist,&vivi_devlist); | 1186 | break; |
1177 | 1187 | ||
1178 | /* init video dma queues */ | 1188 | list_add_tail(&dev->vivi_devlist, &vivi_devlist); |
1179 | INIT_LIST_HEAD(&dev->vidq.active); | ||
1180 | INIT_LIST_HEAD(&dev->vidq.queued); | ||
1181 | init_waitqueue_head(&dev->vidq.wq); | ||
1182 | 1189 | ||
1183 | /* initialize locks */ | 1190 | /* init video dma queues */ |
1184 | mutex_init(&dev->lock); | 1191 | INIT_LIST_HEAD(&dev->vidq.active); |
1192 | INIT_LIST_HEAD(&dev->vidq.queued); | ||
1193 | init_waitqueue_head(&dev->vidq.wq); | ||
1185 | 1194 | ||
1186 | dev->vidq.timeout.function = vivi_vid_timeout; | 1195 | /* initialize locks */ |
1187 | dev->vidq.timeout.data = (unsigned long)dev; | 1196 | mutex_init(&dev->lock); |
1188 | init_timer(&dev->vidq.timeout); | ||
1189 | 1197 | ||
1190 | vfd = video_device_alloc(); | 1198 | dev->vidq.timeout.function = vivi_vid_timeout; |
1191 | if (NULL == vfd) | 1199 | dev->vidq.timeout.data = (unsigned long)dev; |
1192 | return -ENOMEM; | 1200 | init_timer(&dev->vidq.timeout); |
1193 | 1201 | ||
1194 | *vfd = vivi_template; | 1202 | vfd = video_device_alloc(); |
1203 | if (NULL == vfd) | ||
1204 | break; | ||
1205 | |||
1206 | *vfd = vivi_template; | ||
1207 | |||
1208 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); | ||
1209 | if (ret < 0) | ||
1210 | break; | ||
1211 | |||
1212 | snprintf(vfd->name, sizeof(vfd->name), "%s (%i)", | ||
1213 | vivi_template.name, vfd->minor); | ||
1195 | 1214 | ||
1196 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); | 1215 | if (video_nr >= 0) |
1197 | snprintf(vfd->name, sizeof(vfd->name), "%s (%i)", | 1216 | video_nr++; |
1198 | vivi_template.name, vfd->minor); | ||
1199 | 1217 | ||
1200 | dev->vfd = vfd; | 1218 | dev->vfd = vfd; |
1219 | } | ||
1201 | 1220 | ||
1202 | printk(KERN_INFO "Video Technology Magazine Virtual Video Capture Board (Load status: %d)\n", ret); | 1221 | if (ret < 0) { |
1222 | vivi_release(); | ||
1223 | printk(KERN_INFO "Error %d while loading vivi driver\n", ret); | ||
1224 | } else | ||
1225 | printk(KERN_INFO "Video Technology Magazine Virtual Video " | ||
1226 | "Capture Board successfully loaded.\n"); | ||
1203 | return ret; | 1227 | return ret; |
1204 | } | 1228 | } |
1205 | 1229 | ||
1206 | static void __exit vivi_exit(void) | 1230 | static void __exit vivi_exit(void) |
1207 | { | 1231 | { |
1208 | struct vivi_dev *h; | 1232 | vivi_release(); |
1209 | struct list_head *list; | ||
1210 | |||
1211 | while (!list_empty(&vivi_devlist)) { | ||
1212 | list = vivi_devlist.next; | ||
1213 | list_del(list); | ||
1214 | h = list_entry(list, struct vivi_dev, vivi_devlist); | ||
1215 | vivi_release(h); | ||
1216 | kfree (h); | ||
1217 | } | ||
1218 | } | 1233 | } |
1219 | 1234 | ||
1220 | module_init(vivi_init); | 1235 | module_init(vivi_init); |
@@ -1225,10 +1240,13 @@ MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol"); | |||
1225 | MODULE_LICENSE("Dual BSD/GPL"); | 1240 | MODULE_LICENSE("Dual BSD/GPL"); |
1226 | 1241 | ||
1227 | module_param(video_nr, int, 0); | 1242 | module_param(video_nr, int, 0); |
1243 | MODULE_PARM_DESC(video_nr, "video iminor start number"); | ||
1228 | 1244 | ||
1229 | module_param_named(debug,vivi.debug, int, 0644); | 1245 | module_param(n_devs, int, 0); |
1230 | MODULE_PARM_DESC(debug,"activates debug info"); | 1246 | MODULE_PARM_DESC(n_devs, "number of video devices to create"); |
1231 | 1247 | ||
1232 | module_param(vid_limit,int,0644); | 1248 | module_param_named(debug, vivi.debug, int, 0644); |
1233 | MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes"); | 1249 | MODULE_PARM_DESC(debug, "activates debug info"); |
1234 | 1250 | ||
1251 | module_param(vid_limit, int, 0644); | ||
1252 | MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); | ||