aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2012-06-24 06:26:10 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-08-09 18:42:08 -0400
commit85397ef62a27c434136d039cc60043650a379c0d (patch)
tree21555046766f5165634d8636c798cdad1bf187be
parentc3707357c6c651652a87a044445eabd7582f90a4 (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.c52
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c4
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
518int ivtv_start_decoding(struct ivtv_open_id *id, int speed) 521int 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
543ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *pos) 546static 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
718ssize_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
715unsigned int ivtv_v4l2_dec_poll(struct file *filp, poll_table *wait) 731unsigned 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 }
934close_done:
916 kfree(id); 935 kfree(id);
936 mutex_unlock(&itv->serialize_lock);
917 return 0; 937 return 0;
918} 938}
919 939
920int ivtv_v4l2_open(struct file *filp) 940static 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
1043int 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
1023void ivtv_mute(struct ivtv *itv) 1055void 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;