aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/v4l2-dev.c356
-rw-r--r--include/media/v4l2-dev.h47
2 files changed, 295 insertions, 108 deletions
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index c5ca51a9020a..4e0db8845e04 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -41,17 +41,17 @@
41static ssize_t show_index(struct device *cd, 41static ssize_t show_index(struct device *cd,
42 struct device_attribute *attr, char *buf) 42 struct device_attribute *attr, char *buf)
43{ 43{
44 struct video_device *vfd = container_of(cd, struct video_device, dev); 44 struct video_device *vdev = to_video_device(cd);
45 45
46 return sprintf(buf, "%i\n", vfd->index); 46 return sprintf(buf, "%i\n", vdev->index);
47} 47}
48 48
49static ssize_t show_name(struct device *cd, 49static ssize_t show_name(struct device *cd,
50 struct device_attribute *attr, char *buf) 50 struct device_attribute *attr, char *buf)
51{ 51{
52 struct video_device *vfd = container_of(cd, struct video_device, dev); 52 struct video_device *vdev = to_video_device(cd);
53 53
54 return sprintf(buf, "%.*s\n", (int)sizeof(vfd->name), vfd->name); 54 return sprintf(buf, "%.*s\n", (int)sizeof(vdev->name), vdev->name);
55} 55}
56 56
57static struct device_attribute video_device_attrs[] = { 57static struct device_attribute video_device_attrs[] = {
@@ -73,64 +73,64 @@ struct video_device *video_device_alloc(void)
73} 73}
74EXPORT_SYMBOL(video_device_alloc); 74EXPORT_SYMBOL(video_device_alloc);
75 75
76void video_device_release(struct video_device *vfd) 76void video_device_release(struct video_device *vdev)
77{ 77{
78 kfree(vfd); 78 kfree(vdev);
79} 79}
80EXPORT_SYMBOL(video_device_release); 80EXPORT_SYMBOL(video_device_release);
81 81
82void video_device_release_empty(struct video_device *vfd) 82void video_device_release_empty(struct video_device *vdev)
83{ 83{
84 /* Do nothing */ 84 /* Do nothing */
85 /* Only valid when the video_device struct is a static. */ 85 /* Only valid when the video_device struct is a static. */
86} 86}
87EXPORT_SYMBOL(video_device_release_empty); 87EXPORT_SYMBOL(video_device_release_empty);
88 88
89/* Called when the last user of the character device is gone. */ 89static inline void video_get(struct video_device *vdev)
90static void v4l2_chardev_release(struct kobject *kobj)
91{ 90{
92 struct video_device *vfd = container_of(kobj, struct video_device, cdev.kobj); 91 get_device(&vdev->dev);
92}
93
94static inline void video_put(struct video_device *vdev)
95{
96 put_device(&vdev->dev);
97}
98
99/* Called when the last user of the video device exits. */
100static void v4l2_device_release(struct device *cd)
101{
102 struct video_device *vdev = to_video_device(cd);
93 103
94 mutex_lock(&videodev_lock); 104 mutex_lock(&videodev_lock);
95 if (video_device[vfd->minor] != vfd) { 105 if (video_device[vdev->minor] != vdev) {
96 mutex_unlock(&videodev_lock); 106 mutex_unlock(&videodev_lock);
97 BUG(); 107 /* should not happen */
108 WARN_ON(1);
98 return; 109 return;
99 } 110 }
100 111
101 /* Free up this device for reuse */ 112 /* Free up this device for reuse */
102 video_device[vfd->minor] = NULL; 113 video_device[vdev->minor] = NULL;
103 clear_bit(vfd->num, video_nums[vfd->vfl_type]);
104 mutex_unlock(&videodev_lock);
105 114
106 /* Release the character device */ 115 /* Delete the cdev on this minor as well */
107 vfd->cdev_release(kobj); 116 cdev_del(vdev->cdev);
108 /* Release video_device and perform other 117 /* Just in case some driver tries to access this from
109 cleanups as needed. */ 118 the release() callback. */
110 if (vfd->release) 119 vdev->cdev = NULL;
111 vfd->release(vfd);
112}
113 120
114/* The new kobj_type for the character device */ 121 /* Mark minor as free */
115static struct kobj_type v4l2_ktype_cdev_default = { 122 clear_bit(vdev->num, video_nums[vdev->vfl_type]);
116 .release = v4l2_chardev_release,
117};
118 123
119static void video_release(struct device *cd) 124 mutex_unlock(&videodev_lock);
120{
121 struct video_device *vfd = container_of(cd, struct video_device, dev);
122 125
123 /* It's now safe to delete the char device. 126 /* Release video_device and perform other
124 This will either trigger the v4l2_chardev_release immediately (if 127 cleanups as needed. */
125 the refcount goes to 0) or later when the last user of the 128 vdev->release(vdev);
126 character device closes it. */
127 cdev_del(&vfd->cdev);
128} 129}
129 130
130static struct class video_class = { 131static struct class video_class = {
131 .name = VIDEO_NAME, 132 .name = VIDEO_NAME,
132 .dev_attrs = video_device_attrs, 133 .dev_attrs = video_device_attrs,
133 .dev_release = video_release,
134}; 134};
135 135
136struct video_device *video_devdata(struct file *file) 136struct video_device *video_devdata(struct file *file)
@@ -139,13 +139,163 @@ struct video_device *video_devdata(struct file *file)
139} 139}
140EXPORT_SYMBOL(video_devdata); 140EXPORT_SYMBOL(video_devdata);
141 141
142static ssize_t v4l2_read(struct file *filp, char __user *buf,
143 size_t sz, loff_t *off)
144{
145 struct video_device *vdev = video_devdata(filp);
146
147 if (!vdev->fops->read)
148 return -EINVAL;
149 if (video_is_unregistered(vdev))
150 return -EIO;
151 return vdev->fops->read(filp, buf, sz, off);
152}
153
154static ssize_t v4l2_write(struct file *filp, const char __user *buf,
155 size_t sz, loff_t *off)
156{
157 struct video_device *vdev = video_devdata(filp);
158
159 if (!vdev->fops->write)
160 return -EINVAL;
161 if (video_is_unregistered(vdev))
162 return -EIO;
163 return vdev->fops->write(filp, buf, sz, off);
164}
165
166static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll)
167{
168 struct video_device *vdev = video_devdata(filp);
169
170 if (!vdev->fops->poll || video_is_unregistered(vdev))
171 return DEFAULT_POLLMASK;
172 return vdev->fops->poll(filp, poll);
173}
174
175static int v4l2_ioctl(struct inode *inode, struct file *filp,
176 unsigned int cmd, unsigned long arg)
177{
178 struct video_device *vdev = video_devdata(filp);
179
180 if (!vdev->fops->ioctl)
181 return -ENOTTY;
182 /* Allow ioctl to continue even if the device was unregistered.
183 Things like dequeueing buffers might still be useful. */
184 return vdev->fops->ioctl(inode, filp, cmd, arg);
185}
186
187static long v4l2_unlocked_ioctl(struct file *filp,
188 unsigned int cmd, unsigned long arg)
189{
190 struct video_device *vdev = video_devdata(filp);
191
192 if (!vdev->fops->unlocked_ioctl)
193 return -ENOTTY;
194 /* Allow ioctl to continue even if the device was unregistered.
195 Things like dequeueing buffers might still be useful. */
196 return vdev->fops->unlocked_ioctl(filp, cmd, arg);
197}
198
199#ifdef CONFIG_COMPAT
200static long v4l2_compat_ioctl(struct file *filp,
201 unsigned int cmd, unsigned long arg)
202{
203 struct video_device *vdev = video_devdata(filp);
204
205 if (!vdev->fops->compat_ioctl)
206 return -ENOIOCTLCMD;
207 /* Allow ioctl to continue even if the device was unregistered.
208 Things like dequeueing buffers might still be useful. */
209 return vdev->fops->compat_ioctl(filp, cmd, arg);
210}
211#endif
212
213static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
214{
215 struct video_device *vdev = video_devdata(filp);
216
217 if (!vdev->fops->mmap ||
218 video_is_unregistered(vdev))
219 return -ENODEV;
220 return vdev->fops->mmap(filp, vm);
221}
222
223/* Override for the open function */
224static int v4l2_open(struct inode *inode, struct file *filp)
225{
226 struct video_device *vdev;
227 int ret;
228
229 /* Check if the video device is available */
230 mutex_lock(&videodev_lock);
231 vdev = video_devdata(filp);
232 /* return ENODEV if the video device has been removed
233 already or if it is not registered anymore. */
234 if (vdev == NULL || video_is_unregistered(vdev)) {
235 mutex_unlock(&videodev_lock);
236 return -ENODEV;
237 }
238 /* and increase the device refcount */
239 video_get(vdev);
240 mutex_unlock(&videodev_lock);
241 ret = vdev->fops->open(inode, filp);
242 /* decrease the refcount in case of an error */
243 if (ret)
244 video_put(vdev);
245 return ret;
246}
247
248/* Override for the release function */
249static int v4l2_release(struct inode *inode, struct file *filp)
250{
251 struct video_device *vdev = video_devdata(filp);
252 int ret = vdev->fops->release(inode, filp);
253
254 /* decrease the refcount unconditionally since the release()
255 return value is ignored. */
256 video_put(vdev);
257 return ret;
258}
259
260static const struct file_operations v4l2_unlocked_fops = {
261 .owner = THIS_MODULE,
262 .read = v4l2_read,
263 .write = v4l2_write,
264 .open = v4l2_open,
265 .mmap = v4l2_mmap,
266 .unlocked_ioctl = v4l2_unlocked_ioctl,
267#ifdef CONFIG_COMPAT
268 .compat_ioctl = v4l2_compat_ioctl,
269#endif
270 .release = v4l2_release,
271 .poll = v4l2_poll,
272 .llseek = no_llseek,
273};
274
275static const struct file_operations v4l2_fops = {
276 .owner = THIS_MODULE,
277 .read = v4l2_read,
278 .write = v4l2_write,
279 .open = v4l2_open,
280 .mmap = v4l2_mmap,
281 .ioctl = v4l2_ioctl,
282#ifdef CONFIG_COMPAT
283 .compat_ioctl = v4l2_compat_ioctl,
284#endif
285 .release = v4l2_release,
286 .poll = v4l2_poll,
287 .llseek = no_llseek,
288};
289
142/** 290/**
143 * get_index - assign stream number based on parent device 291 * get_index - assign stream number based on parent device
144 * @vdev: video_device to assign index number to, vdev->dev should be assigned 292 * @vdev: video_device to assign index number to, vdev->parent should be assigned
145 * @num: -1 if auto assign, requested number otherwise 293 * @num: -1 if auto assign, requested number otherwise
146 * 294 *
295 * Note that when this is called the new device has not yet been registered
296 * in the video_device array.
147 * 297 *
148 * returns -ENFILE if num is already in use, a free index number if 298 * Returns -ENFILE if num is already in use, a free index number if
149 * successful. 299 * successful.
150 */ 300 */
151static int get_index(struct video_device *vdev, int num) 301static int get_index(struct video_device *vdev, int num)
@@ -168,7 +318,6 @@ static int get_index(struct video_device *vdev, int num)
168 318
169 for (i = 0; i < VIDEO_NUM_DEVICES; i++) { 319 for (i = 0; i < VIDEO_NUM_DEVICES; i++) {
170 if (video_device[i] != NULL && 320 if (video_device[i] != NULL &&
171 video_device[i] != vdev &&
172 video_device[i]->parent == vdev->parent) { 321 video_device[i]->parent == vdev->parent) {
173 used |= 1 << video_device[i]->index; 322 used |= 1 << video_device[i]->index;
174 } 323 }
@@ -184,17 +333,15 @@ static int get_index(struct video_device *vdev, int num)
184 return i > max_index ? -ENFILE : i; 333 return i > max_index ? -ENFILE : i;
185} 334}
186 335
187static const struct file_operations video_fops; 336int video_register_device(struct video_device *vdev, int type, int nr)
188
189int video_register_device(struct video_device *vfd, int type, int nr)
190{ 337{
191 return video_register_device_index(vfd, type, nr, -1); 338 return video_register_device_index(vdev, type, nr, -1);
192} 339}
193EXPORT_SYMBOL(video_register_device); 340EXPORT_SYMBOL(video_register_device);
194 341
195/** 342/**
196 * video_register_device_index - register video4linux devices 343 * video_register_device_index - register video4linux devices
197 * @vfd: video device structure we want to register 344 * @vdev: video device structure we want to register
198 * @type: type of device to register 345 * @type: type of device to register
199 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ... 346 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ...
200 * -1 == first free) 347 * -1 == first free)
@@ -218,8 +365,7 @@ EXPORT_SYMBOL(video_register_device);
218 * 365 *
219 * %VFL_TYPE_RADIO - A radio card 366 * %VFL_TYPE_RADIO - A radio card
220 */ 367 */
221 368int video_register_device_index(struct video_device *vdev, int type, int nr,
222int video_register_device_index(struct video_device *vfd, int type, int nr,
223 int index) 369 int index)
224{ 370{
225 int i = 0; 371 int i = 0;
@@ -227,14 +373,19 @@ int video_register_device_index(struct video_device *vfd, int type, int nr,
227 int minor_offset = 0; 373 int minor_offset = 0;
228 int minor_cnt = VIDEO_NUM_DEVICES; 374 int minor_cnt = VIDEO_NUM_DEVICES;
229 const char *name_base; 375 const char *name_base;
230 void *priv = video_get_drvdata(vfd); 376 void *priv = video_get_drvdata(vdev);
231 377
232 /* the release callback MUST be present */ 378 /* A minor value of -1 marks this video device as never
233 BUG_ON(!vfd->release); 379 having been registered */
380 if (vdev)
381 vdev->minor = -1;
234 382
235 if (vfd == NULL) 383 /* the release callback MUST be present */
384 WARN_ON(!vdev || !vdev->release);
385 if (!vdev || !vdev->release)
236 return -EINVAL; 386 return -EINVAL;
237 387
388 /* Part 1: check device type */
238 switch (type) { 389 switch (type) {
239 case VFL_TYPE_GRABBER: 390 case VFL_TYPE_GRABBER:
240 name_base = "video"; 391 name_base = "video";
@@ -254,8 +405,10 @@ int video_register_device_index(struct video_device *vfd, int type, int nr,
254 return -EINVAL; 405 return -EINVAL;
255 } 406 }
256 407
257 vfd->vfl_type = type; 408 vdev->vfl_type = type;
409 vdev->cdev = NULL;
258 410
411 /* Part 2: find a free minor, kernel number and device index. */
259#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES 412#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
260 /* Keep the ranges for the first four types for historical 413 /* Keep the ranges for the first four types for historical
261 * reasons. 414 * reasons.
@@ -286,10 +439,7 @@ int video_register_device_index(struct video_device *vfd, int type, int nr,
286 } 439 }
287#endif 440#endif
288 441
289 /* Initialize the character device */ 442 /* Pick a minor number */
290 cdev_init(&vfd->cdev, vfd->fops);
291 vfd->cdev.owner = vfd->fops->owner;
292 /* pick a minor number */
293 mutex_lock(&videodev_lock); 443 mutex_lock(&videodev_lock);
294 nr = find_next_zero_bit(video_nums[type], minor_cnt, nr == -1 ? 0 : nr); 444 nr = find_next_zero_bit(video_nums[type], minor_cnt, nr == -1 ? 0 : nr);
295 if (nr == minor_cnt) 445 if (nr == minor_cnt)
@@ -313,72 +463,92 @@ int video_register_device_index(struct video_device *vfd, int type, int nr,
313 return -ENFILE; 463 return -ENFILE;
314 } 464 }
315#endif 465#endif
316 vfd->minor = i + minor_offset; 466 vdev->minor = i + minor_offset;
317 vfd->num = nr; 467 vdev->num = nr;
318 set_bit(nr, video_nums[type]); 468 set_bit(nr, video_nums[type]);
319 BUG_ON(video_device[vfd->minor]); 469 /* Should not happen since we thought this minor was free */
320 video_device[vfd->minor] = vfd; 470 WARN_ON(video_device[vdev->minor] != NULL);
321 471 ret = vdev->index = get_index(vdev, index);
322 ret = get_index(vfd, index);
323 vfd->index = ret;
324
325 mutex_unlock(&videodev_lock); 472 mutex_unlock(&videodev_lock);
326 473
327 if (ret < 0) { 474 if (ret < 0) {
328 printk(KERN_ERR "%s: get_index failed\n", __func__); 475 printk(KERN_ERR "%s: get_index failed\n", __func__);
329 goto fail_minor; 476 goto cleanup;
330 } 477 }
331 478
332 ret = cdev_add(&vfd->cdev, MKDEV(VIDEO_MAJOR, vfd->minor), 1); 479 /* Part 3: Initialize the character device */
480 vdev->cdev = cdev_alloc();
481 if (vdev->cdev == NULL) {
482 ret = -ENOMEM;
483 goto cleanup;
484 }
485 if (vdev->fops->unlocked_ioctl)
486 vdev->cdev->ops = &v4l2_unlocked_fops;
487 else
488 vdev->cdev->ops = &v4l2_fops;
489 vdev->cdev->owner = vdev->fops->owner;
490 ret = cdev_add(vdev->cdev, MKDEV(VIDEO_MAJOR, vdev->minor), 1);
333 if (ret < 0) { 491 if (ret < 0) {
334 printk(KERN_ERR "%s: cdev_add failed\n", __func__); 492 printk(KERN_ERR "%s: cdev_add failed\n", __func__);
335 goto fail_minor; 493 kfree(vdev->cdev);
494 vdev->cdev = NULL;
495 goto cleanup;
336 } 496 }
337 /* sysfs class */ 497
338 memset(&vfd->dev, 0, sizeof(vfd->dev)); 498 /* Part 4: register the device with sysfs */
499 memset(&vdev->dev, 0, sizeof(vdev->dev));
339 /* The memset above cleared the device's drvdata, so 500 /* The memset above cleared the device's drvdata, so
340 put back the copy we made earlier. */ 501 put back the copy we made earlier. */
341 video_set_drvdata(vfd, priv); 502 video_set_drvdata(vdev, priv);
342 vfd->dev.class = &video_class; 503 vdev->dev.class = &video_class;
343 vfd->dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor); 504 vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor);
344 if (vfd->parent) 505 if (vdev->parent)
345 vfd->dev.parent = vfd->parent; 506 vdev->dev.parent = vdev->parent;
346 dev_set_name(&vfd->dev, "%s%d", name_base, nr); 507 dev_set_name(&vdev->dev, "%s%d", name_base, nr);
347 ret = device_register(&vfd->dev); 508 ret = device_register(&vdev->dev);
348 if (ret < 0) { 509 if (ret < 0) {
349 printk(KERN_ERR "%s: device_register failed\n", __func__); 510 printk(KERN_ERR "%s: device_register failed\n", __func__);
350 goto del_cdev; 511 goto cleanup;
351 } 512 }
352 /* Remember the cdev's release function */ 513 /* Register the release callback that will be called when the last
353 vfd->cdev_release = vfd->cdev.kobj.ktype->release; 514 reference to the device goes away. */
354 /* Install our own */ 515 vdev->dev.release = v4l2_device_release;
355 vfd->cdev.kobj.ktype = &v4l2_ktype_cdev_default;
356 return 0;
357 516
358del_cdev: 517 /* Part 5: Activate this minor. The char device can now be used. */
359 cdev_del(&vfd->cdev); 518 mutex_lock(&videodev_lock);
519 video_device[vdev->minor] = vdev;
520 mutex_unlock(&videodev_lock);
521 return 0;
360 522
361fail_minor: 523cleanup:
362 mutex_lock(&videodev_lock); 524 mutex_lock(&videodev_lock);
363 video_device[vfd->minor] = NULL; 525 if (vdev->cdev)
364 clear_bit(vfd->num, video_nums[type]); 526 cdev_del(vdev->cdev);
527 clear_bit(vdev->num, video_nums[type]);
365 mutex_unlock(&videodev_lock); 528 mutex_unlock(&videodev_lock);
366 vfd->minor = -1; 529 /* Mark this video device as never having been registered. */
530 vdev->minor = -1;
367 return ret; 531 return ret;
368} 532}
369EXPORT_SYMBOL(video_register_device_index); 533EXPORT_SYMBOL(video_register_device_index);
370 534
371/** 535/**
372 * video_unregister_device - unregister a video4linux device 536 * video_unregister_device - unregister a video4linux device
373 * @vfd: the device to unregister 537 * @vdev: the device to unregister
374 * 538 *
375 * This unregisters the passed device and deassigns the minor 539 * This unregisters the passed device. Future open calls will
376 * number. Future open calls will be met with errors. 540 * be met with errors.
377 */ 541 */
378 542void video_unregister_device(struct video_device *vdev)
379void video_unregister_device(struct video_device *vfd)
380{ 543{
381 device_unregister(&vfd->dev); 544 /* Check if vdev was ever registered at all */
545 if (!vdev || vdev->minor < 0)
546 return;
547
548 mutex_lock(&videodev_lock);
549 set_bit(V4L2_FL_UNREGISTERED, &vdev->flags);
550 mutex_unlock(&videodev_lock);
551 device_unregister(&vdev->dev);
382} 552}
383EXPORT_SYMBOL(video_unregister_device); 553EXPORT_SYMBOL(video_unregister_device);
384 554
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index a0a6b41c5e09..e0d72d2c6f0e 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -26,6 +26,11 @@
26 26
27struct v4l2_ioctl_callbacks; 27struct v4l2_ioctl_callbacks;
28 28
29/* Flag to mark the video_device struct as unregistered.
30 Drivers can set this flag if they want to block all future
31 device access. It is set by video_unregister_device. */
32#define V4L2_FL_UNREGISTERED (0)
33
29/* 34/*
30 * Newer version of video_device, handled by videodev2.c 35 * Newer version of video_device, handled by videodev2.c
31 * This version moves redundant code from video device code to 36 * This version moves redundant code from video device code to
@@ -39,15 +44,17 @@ struct video_device
39 44
40 /* sysfs */ 45 /* sysfs */
41 struct device dev; /* v4l device */ 46 struct device dev; /* v4l device */
42 struct cdev cdev; /* character device */ 47 struct cdev *cdev; /* character device */
43 void (*cdev_release)(struct kobject *kobj);
44 struct device *parent; /* device parent */ 48 struct device *parent; /* device parent */
45 49
46 /* device info */ 50 /* device info */
47 char name[32]; 51 char name[32];
48 int vfl_type; 52 int vfl_type;
53 /* 'minor' is set to -1 if the registration failed */
49 int minor; 54 int minor;
50 u16 num; 55 u16 num;
56 /* use bitops to set/clear/test flags */
57 unsigned long flags;
51 /* attribute to differentiate multiple indices on one physical device */ 58 /* attribute to differentiate multiple indices on one physical device */
52 int index; 59 int index;
53 60
@@ -58,7 +65,7 @@ struct video_device
58 v4l2_std_id current_norm; /* Current tvnorm */ 65 v4l2_std_id current_norm; /* Current tvnorm */
59 66
60 /* callbacks */ 67 /* callbacks */
61 void (*release)(struct video_device *vfd); 68 void (*release)(struct video_device *vdev);
62 69
63 /* ioctl callbacks */ 70 /* ioctl callbacks */
64 const struct v4l2_ioctl_ops *ioctl_ops; 71 const struct v4l2_ioctl_ops *ioctl_ops;
@@ -67,36 +74,41 @@ struct video_device
67/* dev to video-device */ 74/* dev to video-device */
68#define to_video_device(cd) container_of(cd, struct video_device, dev) 75#define to_video_device(cd) container_of(cd, struct video_device, dev)
69 76
70/* Register and unregister devices. Note that if video_register_device fails, 77/* Register video devices. Note that if video_register_device fails,
71 the release() callback of the video_device structure is *not* called, so 78 the release() callback of the video_device structure is *not* called, so
72 the caller is responsible for freeing any data. Usually that means that 79 the caller is responsible for freeing any data. Usually that means that
73 you call video_device_release() on failure. */ 80 you call video_device_release() on failure.
74int __must_check video_register_device(struct video_device *vfd, int type, int nr); 81
75int __must_check video_register_device_index(struct video_device *vfd, 82 Also note that vdev->minor is set to -1 if the registration failed. */
83int __must_check video_register_device(struct video_device *vdev, int type, int nr);
84int __must_check video_register_device_index(struct video_device *vdev,
76 int type, int nr, int index); 85 int type, int nr, int index);
77void video_unregister_device(struct video_device *vfd); 86
87/* Unregister video devices. Will do nothing if vdev == NULL or
88 vdev->minor < 0. */
89void video_unregister_device(struct video_device *vdev);
78 90
79/* helper functions to alloc/release struct video_device, the 91/* helper functions to alloc/release struct video_device, the
80 latter can also be used for video_device->release(). */ 92 latter can also be used for video_device->release(). */
81struct video_device * __must_check video_device_alloc(void); 93struct video_device * __must_check video_device_alloc(void);
82 94
83/* this release function frees the vfd pointer */ 95/* this release function frees the vdev pointer */
84void video_device_release(struct video_device *vfd); 96void video_device_release(struct video_device *vdev);
85 97
86/* this release function does nothing, use when the video_device is a 98/* this release function does nothing, use when the video_device is a
87 static global struct. Note that having a static video_device is 99 static global struct. Note that having a static video_device is
88 a dubious construction at best. */ 100 a dubious construction at best. */
89void video_device_release_empty(struct video_device *vfd); 101void video_device_release_empty(struct video_device *vdev);
90 102
91/* helper functions to access driver private data. */ 103/* helper functions to access driver private data. */
92static inline void *video_get_drvdata(struct video_device *dev) 104static inline void *video_get_drvdata(struct video_device *vdev)
93{ 105{
94 return dev_get_drvdata(&dev->dev); 106 return dev_get_drvdata(&vdev->dev);
95} 107}
96 108
97static inline void video_set_drvdata(struct video_device *dev, void *data) 109static inline void video_set_drvdata(struct video_device *vdev, void *data)
98{ 110{
99 dev_set_drvdata(&dev->dev, data); 111 dev_set_drvdata(&vdev->dev, data);
100} 112}
101 113
102struct video_device *video_devdata(struct file *file); 114struct video_device *video_devdata(struct file *file);
@@ -108,4 +120,9 @@ static inline void *video_drvdata(struct file *file)
108 return video_get_drvdata(video_devdata(file)); 120 return video_get_drvdata(video_devdata(file));
109} 121}
110 122
123static inline int video_is_unregistered(struct video_device *vdev)
124{
125 return test_bit(V4L2_FL_UNREGISTERED, &vdev->flags);
126}
127
111#endif /* _V4L2_DEV_H */ 128#endif /* _V4L2_DEV_H */