diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2012-06-24 06:26:10 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-09 18:42:08 -0400 |
commit | 85397ef62a27c434136d039cc60043650a379c0d (patch) | |
tree | 21555046766f5165634d8636c798cdad1bf187be | |
parent | c3707357c6c651652a87a044445eabd7582f90a4 (diff) |
[media] ivtv: remove V4L2_FL_LOCK_ALL_FOPS
Add proper locking to the file operations, allowing for the removal
of the V4L2_FL_LOCK_ALL_FOPS flag.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/ivtv/ivtv-fileops.c | 52 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-streams.c | 4 |
2 files changed, 42 insertions, 14 deletions
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index 9ff69b5a87e2..88bce907cdef 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c | |||
@@ -505,14 +505,17 @@ ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_ | |||
505 | struct ivtv_open_id *id = fh2id(filp->private_data); | 505 | struct ivtv_open_id *id = fh2id(filp->private_data); |
506 | struct ivtv *itv = id->itv; | 506 | struct ivtv *itv = id->itv; |
507 | struct ivtv_stream *s = &itv->streams[id->type]; | 507 | struct ivtv_stream *s = &itv->streams[id->type]; |
508 | int rc; | 508 | ssize_t rc; |
509 | 509 | ||
510 | IVTV_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name); | 510 | IVTV_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name); |
511 | 511 | ||
512 | if (mutex_lock_interruptible(&itv->serialize_lock)) | ||
513 | return -ERESTARTSYS; | ||
512 | rc = ivtv_start_capture(id); | 514 | rc = ivtv_start_capture(id); |
513 | if (rc) | 515 | if (!rc) |
514 | return rc; | 516 | rc = ivtv_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK); |
515 | return ivtv_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK); | 517 | mutex_unlock(&itv->serialize_lock); |
518 | return rc; | ||
516 | } | 519 | } |
517 | 520 | ||
518 | int ivtv_start_decoding(struct ivtv_open_id *id, int speed) | 521 | int ivtv_start_decoding(struct ivtv_open_id *id, int speed) |
@@ -540,7 +543,7 @@ int ivtv_start_decoding(struct ivtv_open_id *id, int speed) | |||
540 | return 0; | 543 | return 0; |
541 | } | 544 | } |
542 | 545 | ||
543 | ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos) | 546 | static ssize_t ivtv_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos) |
544 | { | 547 | { |
545 | struct ivtv_open_id *id = fh2id(filp->private_data); | 548 | struct ivtv_open_id *id = fh2id(filp->private_data); |
546 | struct ivtv *itv = id->itv; | 549 | struct ivtv *itv = id->itv; |
@@ -712,6 +715,19 @@ retry: | |||
712 | return bytes_written; | 715 | return bytes_written; |
713 | } | 716 | } |
714 | 717 | ||
718 | ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos) | ||
719 | { | ||
720 | struct ivtv_open_id *id = fh2id(filp->private_data); | ||
721 | struct ivtv *itv = id->itv; | ||
722 | ssize_t res; | ||
723 | |||
724 | if (mutex_lock_interruptible(&itv->serialize_lock)) | ||
725 | return -ERESTARTSYS; | ||
726 | res = ivtv_write(filp, user_buf, count, pos); | ||
727 | mutex_unlock(&itv->serialize_lock); | ||
728 | return res; | ||
729 | } | ||
730 | |||
715 | unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait) | 731 | unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait) |
716 | { | 732 | { |
717 | struct ivtv_open_id *id = fh2id(filp->private_data); | 733 | struct ivtv_open_id *id = fh2id(filp->private_data); |
@@ -760,7 +776,9 @@ unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table *wait) | |||
760 | (req_events & (POLLIN | POLLRDNORM))) { | 776 | (req_events & (POLLIN | POLLRDNORM))) { |
761 | int rc; | 777 | int rc; |
762 | 778 | ||
779 | mutex_lock(&itv->serialize_lock); | ||
763 | rc = ivtv_start_capture(id); | 780 | rc = ivtv_start_capture(id); |
781 | mutex_unlock(&itv->serialize_lock); | ||
764 | if (rc) { | 782 | if (rc) { |
765 | IVTV_DEBUG_INFO("Could not start capture for %s (%d)\n", | 783 | IVTV_DEBUG_INFO("Could not start capture for %s (%d)\n", |
766 | s->name, rc); | 784 | s->name, rc); |
@@ -863,6 +881,8 @@ int ivtv_v4l2_close(struct file *filp) | |||
863 | 881 | ||
864 | IVTV_DEBUG_FILE("close %s\n", s->name); | 882 | IVTV_DEBUG_FILE("close %s\n", s->name); |
865 | 883 | ||
884 | mutex_lock(&itv->serialize_lock); | ||
885 | |||
866 | /* Stop radio */ | 886 | /* Stop radio */ |
867 | if (id->type == IVTV_ENC_STREAM_TYPE_RAD && | 887 | if (id->type == IVTV_ENC_STREAM_TYPE_RAD && |
868 | v4l2_fh_is_singular_file(filp)) { | 888 | v4l2_fh_is_singular_file(filp)) { |
@@ -892,10 +912,8 @@ int ivtv_v4l2_close(struct file *filp) | |||
892 | v4l2_fh_exit(fh); | 912 | v4l2_fh_exit(fh); |
893 | 913 | ||
894 | /* Easy case first: this stream was never claimed by us */ | 914 | /* Easy case first: this stream was never claimed by us */ |
895 | if (s->fh != &id->fh) { | 915 | if (s->fh != &id->fh) |
896 | kfree(id); | 916 | goto close_done; |
897 | return 0; | ||
898 | } | ||
899 | 917 | ||
900 | /* 'Unclaim' this stream */ | 918 | /* 'Unclaim' this stream */ |
901 | 919 | ||
@@ -913,11 +931,13 @@ int ivtv_v4l2_close(struct file *filp) | |||
913 | } else { | 931 | } else { |
914 | ivtv_stop_capture(id, 0); | 932 | ivtv_stop_capture(id, 0); |
915 | } | 933 | } |
934 | close_done: | ||
916 | kfree(id); | 935 | kfree(id); |
936 | mutex_unlock(&itv->serialize_lock); | ||
917 | return 0; | 937 | return 0; |
918 | } | 938 | } |
919 | 939 | ||
920 | int ivtv_v4l2_open(struct file *filp) | 940 | static int ivtv_open(struct file *filp) |
921 | { | 941 | { |
922 | struct video_device *vdev = video_devdata(filp); | 942 | struct video_device *vdev = video_devdata(filp); |
923 | struct ivtv_stream *s = video_get_drvdata(vdev); | 943 | struct ivtv_stream *s = video_get_drvdata(vdev); |
@@ -1020,6 +1040,18 @@ int ivtv_v4l2_open(struct file *filp) | |||
1020 | return 0; | 1040 | return 0; |
1021 | } | 1041 | } |
1022 | 1042 | ||
1043 | int ivtv_v4l2_open(struct file *filp) | ||
1044 | { | ||
1045 | struct video_device *vdev = video_devdata(filp); | ||
1046 | int res; | ||
1047 | |||
1048 | if (mutex_lock_interruptible(vdev->lock)) | ||
1049 | return -ERESTARTSYS; | ||
1050 | res = ivtv_open(filp); | ||
1051 | mutex_unlock(vdev->lock); | ||
1052 | return res; | ||
1053 | } | ||
1054 | |||
1023 | void ivtv_mute(struct ivtv *itv) | 1055 | void ivtv_mute(struct ivtv *itv) |
1024 | { | 1056 | { |
1025 | if (atomic_read(&itv->capturing)) | 1057 | if (atomic_read(&itv->capturing)) |
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index 87990c5f0910..f08ec17cc3dc 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c | |||
@@ -228,10 +228,6 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) | |||
228 | s->vdev->release = video_device_release; | 228 | s->vdev->release = video_device_release; |
229 | s->vdev->tvnorms = V4L2_STD_ALL; | 229 | s->vdev->tvnorms = V4L2_STD_ALL; |
230 | s->vdev->lock = &itv->serialize_lock; | 230 | s->vdev->lock = &itv->serialize_lock; |
231 | /* Locking in file operations other than ioctl should be done | ||
232 | by the driver, not the V4L2 core. | ||
233 | This driver needs auditing so that this flag can be removed. */ | ||
234 | set_bit(V4L2_FL_LOCK_ALL_FOPS, &s->vdev->flags); | ||
235 | set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev->flags); | 231 | set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev->flags); |
236 | ivtv_set_funcs(s->vdev); | 232 | ivtv_set_funcs(s->vdev); |
237 | return 0; | 233 | return 0; |