diff options
-rw-r--r-- | drivers/media/video/v4l2-dev.c | 51 | ||||
-rw-r--r-- | drivers/media/video/videobuf2-core.c | 21 | ||||
-rw-r--r-- | include/media/v4l2-dev.h | 3 |
3 files changed, 15 insertions, 60 deletions
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 07aeafca9ea..71237f5f85f 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c | |||
@@ -298,13 +298,8 @@ static ssize_t v4l2_read(struct file *filp, char __user *buf, | |||
298 | 298 | ||
299 | if (!vdev->fops->read) | 299 | if (!vdev->fops->read) |
300 | return -EINVAL; | 300 | return -EINVAL; |
301 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) && | ||
302 | mutex_lock_interruptible(vdev->lock)) | ||
303 | return -ERESTARTSYS; | ||
304 | if (video_is_registered(vdev)) | 301 | if (video_is_registered(vdev)) |
305 | ret = vdev->fops->read(filp, buf, sz, off); | 302 | ret = vdev->fops->read(filp, buf, sz, off); |
306 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) | ||
307 | mutex_unlock(vdev->lock); | ||
308 | if (vdev->debug) | 303 | if (vdev->debug) |
309 | printk(KERN_DEBUG "%s: read: %zd (%d)\n", | 304 | printk(KERN_DEBUG "%s: read: %zd (%d)\n", |
310 | video_device_node_name(vdev), sz, ret); | 305 | video_device_node_name(vdev), sz, ret); |
@@ -319,13 +314,8 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf, | |||
319 | 314 | ||
320 | if (!vdev->fops->write) | 315 | if (!vdev->fops->write) |
321 | return -EINVAL; | 316 | return -EINVAL; |
322 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) && | ||
323 | mutex_lock_interruptible(vdev->lock)) | ||
324 | return -ERESTARTSYS; | ||
325 | if (video_is_registered(vdev)) | 317 | if (video_is_registered(vdev)) |
326 | ret = vdev->fops->write(filp, buf, sz, off); | 318 | ret = vdev->fops->write(filp, buf, sz, off); |
327 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) | ||
328 | mutex_unlock(vdev->lock); | ||
329 | if (vdev->debug) | 319 | if (vdev->debug) |
330 | printk(KERN_DEBUG "%s: write: %zd (%d)\n", | 320 | printk(KERN_DEBUG "%s: write: %zd (%d)\n", |
331 | video_device_node_name(vdev), sz, ret); | 321 | video_device_node_name(vdev), sz, ret); |
@@ -335,20 +325,16 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf, | |||
335 | static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll) | 325 | static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll) |
336 | { | 326 | { |
337 | struct video_device *vdev = video_devdata(filp); | 327 | struct video_device *vdev = video_devdata(filp); |
338 | int ret = POLLERR | POLLHUP; | 328 | unsigned int res = POLLERR | POLLHUP; |
339 | 329 | ||
340 | if (!vdev->fops->poll) | 330 | if (!vdev->fops->poll) |
341 | return DEFAULT_POLLMASK; | 331 | return DEFAULT_POLLMASK; |
342 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) | ||
343 | mutex_lock(vdev->lock); | ||
344 | if (video_is_registered(vdev)) | 332 | if (video_is_registered(vdev)) |
345 | ret = vdev->fops->poll(filp, poll); | 333 | res = vdev->fops->poll(filp, poll); |
346 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) | ||
347 | mutex_unlock(vdev->lock); | ||
348 | if (vdev->debug) | 334 | if (vdev->debug) |
349 | printk(KERN_DEBUG "%s: poll: %08x\n", | 335 | printk(KERN_DEBUG "%s: poll: %08x\n", |
350 | video_device_node_name(vdev), ret); | 336 | video_device_node_name(vdev), res); |
351 | return ret; | 337 | return res; |
352 | } | 338 | } |
353 | 339 | ||
354 | static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 340 | static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
@@ -432,14 +418,9 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm) | |||
432 | int ret = -ENODEV; | 418 | int ret = -ENODEV; |
433 | 419 | ||
434 | if (!vdev->fops->mmap) | 420 | if (!vdev->fops->mmap) |
435 | return ret; | 421 | return -ENODEV; |
436 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) && | ||
437 | mutex_lock_interruptible(vdev->lock)) | ||
438 | return -ERESTARTSYS; | ||
439 | if (video_is_registered(vdev)) | 422 | if (video_is_registered(vdev)) |
440 | ret = vdev->fops->mmap(filp, vm); | 423 | ret = vdev->fops->mmap(filp, vm); |
441 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) | ||
442 | mutex_unlock(vdev->lock); | ||
443 | if (vdev->debug) | 424 | if (vdev->debug) |
444 | printk(KERN_DEBUG "%s: mmap (%d)\n", | 425 | printk(KERN_DEBUG "%s: mmap (%d)\n", |
445 | video_device_node_name(vdev), ret); | 426 | video_device_node_name(vdev), ret); |
@@ -464,20 +445,12 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
464 | video_get(vdev); | 445 | video_get(vdev); |
465 | mutex_unlock(&videodev_lock); | 446 | mutex_unlock(&videodev_lock); |
466 | if (vdev->fops->open) { | 447 | if (vdev->fops->open) { |
467 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) && | ||
468 | mutex_lock_interruptible(vdev->lock)) { | ||
469 | ret = -ERESTARTSYS; | ||
470 | goto err; | ||
471 | } | ||
472 | if (video_is_registered(vdev)) | 448 | if (video_is_registered(vdev)) |
473 | ret = vdev->fops->open(filp); | 449 | ret = vdev->fops->open(filp); |
474 | else | 450 | else |
475 | ret = -ENODEV; | 451 | ret = -ENODEV; |
476 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) | ||
477 | mutex_unlock(vdev->lock); | ||
478 | } | 452 | } |
479 | 453 | ||
480 | err: | ||
481 | if (vdev->debug) | 454 | if (vdev->debug) |
482 | printk(KERN_DEBUG "%s: open (%d)\n", | 455 | printk(KERN_DEBUG "%s: open (%d)\n", |
483 | video_device_node_name(vdev), ret); | 456 | video_device_node_name(vdev), ret); |
@@ -493,16 +466,12 @@ static int v4l2_release(struct inode *inode, struct file *filp) | |||
493 | struct video_device *vdev = video_devdata(filp); | 466 | struct video_device *vdev = video_devdata(filp); |
494 | int ret = 0; | 467 | int ret = 0; |
495 | 468 | ||
496 | if (vdev->fops->release) { | 469 | if (vdev->fops->release) |
497 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) | 470 | ret = vdev->fops->release(filp); |
498 | mutex_lock(vdev->lock); | ||
499 | vdev->fops->release(filp); | ||
500 | if (test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)) | ||
501 | mutex_unlock(vdev->lock); | ||
502 | } | ||
503 | if (vdev->debug) | 471 | if (vdev->debug) |
504 | printk(KERN_DEBUG "%s: release\n", | 472 | printk(KERN_DEBUG "%s: release\n", |
505 | video_device_node_name(vdev)); | 473 | video_device_node_name(vdev)); |
474 | |||
506 | /* decrease the refcount unconditionally since the release() | 475 | /* decrease the refcount unconditionally since the release() |
507 | return value is ignored. */ | 476 | return value is ignored. */ |
508 | video_put(vdev); | 477 | video_put(vdev); |
@@ -882,10 +851,6 @@ int __video_register_device(struct video_device *vdev, int type, int nr, | |||
882 | WARN_ON(video_device[vdev->minor] != NULL); | 851 | WARN_ON(video_device[vdev->minor] != NULL); |
883 | vdev->index = get_index(vdev); | 852 | vdev->index = get_index(vdev); |
884 | mutex_unlock(&videodev_lock); | 853 | mutex_unlock(&videodev_lock); |
885 | /* if no lock was passed, then make sure the LOCK_ALL_FOPS bit is | ||
886 | clear and warn if it wasn't. */ | ||
887 | if (vdev->lock == NULL) | ||
888 | WARN_ON(test_and_clear_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags)); | ||
889 | 854 | ||
890 | if (vdev->ioctl_ops) | 855 | if (vdev->ioctl_ops) |
891 | determine_valid_ioctls(vdev); | 856 | determine_valid_ioctls(vdev); |
diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c index 268c7dd4f82..4da3df61901 100644 --- a/drivers/media/video/videobuf2-core.c +++ b/drivers/media/video/videobuf2-core.c | |||
@@ -2270,10 +2270,9 @@ ssize_t vb2_fop_write(struct file *file, char __user *buf, | |||
2270 | { | 2270 | { |
2271 | struct video_device *vdev = video_devdata(file); | 2271 | struct video_device *vdev = video_devdata(file); |
2272 | struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock; | 2272 | struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock; |
2273 | bool must_lock = !test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) && lock; | ||
2274 | int err = -EBUSY; | 2273 | int err = -EBUSY; |
2275 | 2274 | ||
2276 | if (must_lock && mutex_lock_interruptible(lock)) | 2275 | if (lock && mutex_lock_interruptible(lock)) |
2277 | return -ERESTARTSYS; | 2276 | return -ERESTARTSYS; |
2278 | if (vb2_queue_is_busy(vdev, file)) | 2277 | if (vb2_queue_is_busy(vdev, file)) |
2279 | goto exit; | 2278 | goto exit; |
@@ -2282,7 +2281,7 @@ ssize_t vb2_fop_write(struct file *file, char __user *buf, | |||
2282 | if (err >= 0) | 2281 | if (err >= 0) |
2283 | vdev->queue->owner = file->private_data; | 2282 | vdev->queue->owner = file->private_data; |
2284 | exit: | 2283 | exit: |
2285 | if (must_lock) | 2284 | if (lock) |
2286 | mutex_unlock(lock); | 2285 | mutex_unlock(lock); |
2287 | return err; | 2286 | return err; |
2288 | } | 2287 | } |
@@ -2293,10 +2292,9 @@ ssize_t vb2_fop_read(struct file *file, char __user *buf, | |||
2293 | { | 2292 | { |
2294 | struct video_device *vdev = video_devdata(file); | 2293 | struct video_device *vdev = video_devdata(file); |
2295 | struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock; | 2294 | struct mutex *lock = vdev->queue->lock ? vdev->queue->lock : vdev->lock; |
2296 | bool must_lock = !test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags) && vdev->lock; | ||
2297 | int err = -EBUSY; | 2295 | int err = -EBUSY; |
2298 | 2296 | ||
2299 | if (must_lock && mutex_lock_interruptible(lock)) | 2297 | if (lock && mutex_lock_interruptible(lock)) |
2300 | return -ERESTARTSYS; | 2298 | return -ERESTARTSYS; |
2301 | if (vb2_queue_is_busy(vdev, file)) | 2299 | if (vb2_queue_is_busy(vdev, file)) |
2302 | goto exit; | 2300 | goto exit; |
@@ -2305,7 +2303,7 @@ ssize_t vb2_fop_read(struct file *file, char __user *buf, | |||
2305 | if (err >= 0) | 2303 | if (err >= 0) |
2306 | vdev->queue->owner = file->private_data; | 2304 | vdev->queue->owner = file->private_data; |
2307 | exit: | 2305 | exit: |
2308 | if (must_lock) | 2306 | if (lock) |
2309 | mutex_unlock(lock); | 2307 | mutex_unlock(lock); |
2310 | return err; | 2308 | return err; |
2311 | } | 2309 | } |
@@ -2319,11 +2317,6 @@ unsigned int vb2_fop_poll(struct file *file, poll_table *wait) | |||
2319 | unsigned long req_events = poll_requested_events(wait); | 2317 | unsigned long req_events = poll_requested_events(wait); |
2320 | unsigned res; | 2318 | unsigned res; |
2321 | void *fileio; | 2319 | void *fileio; |
2322 | /* Yuck. We really need to get rid of this flag asap. If it is | ||
2323 | set, then the core took the serialization lock before calling | ||
2324 | poll(). This is being phased out, but for now we have to handle | ||
2325 | this case. */ | ||
2326 | bool locked = test_bit(V4L2_FL_LOCK_ALL_FOPS, &vdev->flags); | ||
2327 | bool must_lock = false; | 2320 | bool must_lock = false; |
2328 | 2321 | ||
2329 | /* Try to be smart: only lock if polling might start fileio, | 2322 | /* Try to be smart: only lock if polling might start fileio, |
@@ -2339,9 +2332,9 @@ unsigned int vb2_fop_poll(struct file *file, poll_table *wait) | |||
2339 | 2332 | ||
2340 | /* If locking is needed, but this helper doesn't know how, then you | 2333 | /* If locking is needed, but this helper doesn't know how, then you |
2341 | shouldn't be using this helper but you should write your own. */ | 2334 | shouldn't be using this helper but you should write your own. */ |
2342 | WARN_ON(must_lock && !locked && !lock); | 2335 | WARN_ON(must_lock && !lock); |
2343 | 2336 | ||
2344 | if (must_lock && !locked && lock && mutex_lock_interruptible(lock)) | 2337 | if (must_lock && lock && mutex_lock_interruptible(lock)) |
2345 | return POLLERR; | 2338 | return POLLERR; |
2346 | 2339 | ||
2347 | fileio = q->fileio; | 2340 | fileio = q->fileio; |
@@ -2351,7 +2344,7 @@ unsigned int vb2_fop_poll(struct file *file, poll_table *wait) | |||
2351 | /* If fileio was started, then we have a new queue owner. */ | 2344 | /* If fileio was started, then we have a new queue owner. */ |
2352 | if (must_lock && !fileio && q->fileio) | 2345 | if (must_lock && !fileio && q->fileio) |
2353 | q->owner = file->private_data; | 2346 | q->owner = file->private_data; |
2354 | if (must_lock && !locked && lock) | 2347 | if (must_lock && lock) |
2355 | mutex_unlock(lock); | 2348 | mutex_unlock(lock); |
2356 | return res; | 2349 | return res; |
2357 | } | 2350 | } |
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 5c416cdc88d..6ee8897c47e 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h | |||
@@ -39,9 +39,6 @@ struct v4l2_ctrl_handler; | |||
39 | #define V4L2_FL_USES_V4L2_FH (1) | 39 | #define V4L2_FL_USES_V4L2_FH (1) |
40 | /* Use the prio field of v4l2_fh for core priority checking */ | 40 | /* Use the prio field of v4l2_fh for core priority checking */ |
41 | #define V4L2_FL_USE_FH_PRIO (2) | 41 | #define V4L2_FL_USE_FH_PRIO (2) |
42 | /* If ioctl core locking is in use, then apply that also to all | ||
43 | file operations. Don't use this flag in new drivers! */ | ||
44 | #define V4L2_FL_LOCK_ALL_FOPS (3) | ||
45 | 42 | ||
46 | /* Priority helper functions */ | 43 | /* Priority helper functions */ |
47 | 44 | ||