diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2007-08-19 06:10:55 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-10-09 21:05:43 -0400 |
commit | baa4072d84e7a2e9954121c826d7bb8f1fb66b38 (patch) | |
tree | 0b354b98963f39c3089e9c5729d40b1d3a0d231c /drivers/media/video/ivtv/ivtv-fileops.c | |
parent | 1aa32c2ffd146dddd76babf842e998502f1b993a (diff) |
V4L/DVB (6056): ivtv: move serialization to the fileops level
Serialization is now done on the open/close/ioctl level and also when the
read/write/poll start an encoder/decoder stream.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-fileops.c')
-rw-r--r-- | drivers/media/video/ivtv/ivtv-fileops.c | 95 |
1 files changed, 56 insertions, 39 deletions
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index 846e9bfa41f0..1f3c8d0310f5 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c | |||
@@ -502,7 +502,9 @@ ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_ | |||
502 | 502 | ||
503 | IVTV_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name); | 503 | IVTV_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name); |
504 | 504 | ||
505 | mutex_lock(&itv->serialize_lock); | ||
505 | rc = ivtv_start_capture(id); | 506 | rc = ivtv_start_capture(id); |
507 | mutex_unlock(&itv->serialize_lock); | ||
506 | if (rc) | 508 | if (rc) |
507 | return rc; | 509 | return rc; |
508 | return ivtv_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK); | 510 | return ivtv_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK); |
@@ -613,7 +615,9 @@ retry: | |||
613 | } | 615 | } |
614 | 616 | ||
615 | /* Start decoder (returns 0 if already started) */ | 617 | /* Start decoder (returns 0 if already started) */ |
618 | mutex_lock(&itv->serialize_lock); | ||
616 | rc = ivtv_start_decoding(id, itv->speed); | 619 | rc = ivtv_start_decoding(id, itv->speed); |
620 | mutex_unlock(&itv->serialize_lock); | ||
617 | if (rc) { | 621 | if (rc) { |
618 | IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name); | 622 | IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name); |
619 | 623 | ||
@@ -681,8 +685,11 @@ unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait) | |||
681 | 685 | ||
682 | /* Start a capture if there is none */ | 686 | /* Start a capture if there is none */ |
683 | if (!eof && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { | 687 | if (!eof && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { |
684 | int rc = ivtv_start_capture(id); | 688 | int rc; |
685 | 689 | ||
690 | mutex_lock(&itv->serialize_lock); | ||
691 | rc = ivtv_start_capture(id); | ||
692 | mutex_unlock(&itv->serialize_lock); | ||
686 | if (rc) { | 693 | if (rc) { |
687 | IVTV_DEBUG_INFO("Could not start capture for %s (%d)\n", | 694 | IVTV_DEBUG_INFO("Could not start capture for %s (%d)\n", |
688 | s->name, rc); | 695 | s->name, rc); |
@@ -788,6 +795,7 @@ int ivtv_v4l2_close(struct inode *inode, struct file *filp) | |||
788 | /* 'Unclaim' this stream */ | 795 | /* 'Unclaim' this stream */ |
789 | 796 | ||
790 | /* Stop radio */ | 797 | /* Stop radio */ |
798 | mutex_lock(&itv->serialize_lock); | ||
791 | if (id->type == IVTV_ENC_STREAM_TYPE_RAD) { | 799 | if (id->type == IVTV_ENC_STREAM_TYPE_RAD) { |
792 | /* Closing radio device, return to TV mode */ | 800 | /* Closing radio device, return to TV mode */ |
793 | ivtv_mute(itv); | 801 | ivtv_mute(itv); |
@@ -822,53 +830,26 @@ int ivtv_v4l2_close(struct inode *inode, struct file *filp) | |||
822 | ivtv_stop_capture(id, 0); | 830 | ivtv_stop_capture(id, 0); |
823 | } | 831 | } |
824 | kfree(id); | 832 | kfree(id); |
833 | mutex_unlock(&itv->serialize_lock); | ||
825 | return 0; | 834 | return 0; |
826 | } | 835 | } |
827 | 836 | ||
828 | int ivtv_v4l2_open(struct inode *inode, struct file *filp) | 837 | static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp) |
829 | { | 838 | { |
830 | int x, y = 0; | 839 | struct ivtv *itv = s->itv; |
831 | struct ivtv_open_id *item; | 840 | struct ivtv_open_id *item; |
832 | struct ivtv *itv = NULL; | ||
833 | struct ivtv_stream *s = NULL; | ||
834 | int minor = iminor(inode); | ||
835 | 841 | ||
836 | /* Find which card this open was on */ | ||
837 | spin_lock(&ivtv_cards_lock); | ||
838 | for (x = 0; itv == NULL && x < ivtv_cards_active; x++) { | ||
839 | /* find out which stream this open was on */ | ||
840 | for (y = 0; y < IVTV_MAX_STREAMS; y++) { | ||
841 | s = &ivtv_cards[x]->streams[y]; | ||
842 | if (s->v4l2dev && s->v4l2dev->minor == minor) { | ||
843 | itv = ivtv_cards[x]; | ||
844 | break; | ||
845 | } | ||
846 | } | ||
847 | } | ||
848 | spin_unlock(&ivtv_cards_lock); | ||
849 | |||
850 | if (itv == NULL) { | ||
851 | /* Couldn't find a device registered | ||
852 | on that minor, shouldn't happen! */ | ||
853 | IVTV_WARN("No ivtv device found on minor %d\n", minor); | ||
854 | return -ENXIO; | ||
855 | } | ||
856 | |||
857 | if (ivtv_init_on_first_open(itv)) { | ||
858 | IVTV_ERR("Failed to initialize on minor %d\n", minor); | ||
859 | return -ENXIO; | ||
860 | } | ||
861 | IVTV_DEBUG_FILE("open %s\n", s->name); | 842 | IVTV_DEBUG_FILE("open %s\n", s->name); |
862 | 843 | ||
863 | if (y == IVTV_DEC_STREAM_TYPE_MPG && | 844 | if (s->type == IVTV_DEC_STREAM_TYPE_MPG && |
864 | test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_YUV].s_flags)) | 845 | test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_YUV].s_flags)) |
865 | return -EBUSY; | 846 | return -EBUSY; |
866 | 847 | ||
867 | if (y == IVTV_DEC_STREAM_TYPE_YUV && | 848 | if (s->type == IVTV_DEC_STREAM_TYPE_YUV && |
868 | test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_MPG].s_flags)) | 849 | test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_MPG].s_flags)) |
869 | return -EBUSY; | 850 | return -EBUSY; |
870 | 851 | ||
871 | if (y == IVTV_DEC_STREAM_TYPE_YUV) { | 852 | if (s->type == IVTV_DEC_STREAM_TYPE_YUV) { |
872 | if (read_reg(0x82c) == 0) { | 853 | if (read_reg(0x82c) == 0) { |
873 | IVTV_ERR("Tried to open YUV output device but need to send data to mpeg decoder before it can be used\n"); | 854 | IVTV_ERR("Tried to open YUV output device but need to send data to mpeg decoder before it can be used\n"); |
874 | /* return -ENODEV; */ | 855 | /* return -ENODEV; */ |
@@ -883,7 +864,7 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp) | |||
883 | return -ENOMEM; | 864 | return -ENOMEM; |
884 | } | 865 | } |
885 | item->itv = itv; | 866 | item->itv = itv; |
886 | item->type = y; | 867 | item->type = s->type; |
887 | v4l2_prio_open(&itv->prio, &item->prio); | 868 | v4l2_prio_open(&itv->prio, &item->prio); |
888 | 869 | ||
889 | item->open_id = itv->open_id++; | 870 | item->open_id = itv->open_id++; |
@@ -925,14 +906,50 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp) | |||
925 | } | 906 | } |
926 | 907 | ||
927 | /* YUV or MPG Decoding Mode? */ | 908 | /* YUV or MPG Decoding Mode? */ |
928 | if (y == IVTV_DEC_STREAM_TYPE_MPG) | 909 | if (s->type == IVTV_DEC_STREAM_TYPE_MPG) |
929 | clear_bit(IVTV_F_I_DEC_YUV, &itv->i_flags); | 910 | clear_bit(IVTV_F_I_DEC_YUV, &itv->i_flags); |
930 | else if (y == IVTV_DEC_STREAM_TYPE_YUV) | 911 | else if (s->type == IVTV_DEC_STREAM_TYPE_YUV) |
931 | { | ||
932 | set_bit(IVTV_F_I_DEC_YUV, &itv->i_flags); | 912 | set_bit(IVTV_F_I_DEC_YUV, &itv->i_flags); |
913 | return 0; | ||
914 | } | ||
915 | |||
916 | int ivtv_v4l2_open(struct inode *inode, struct file *filp) | ||
917 | { | ||
918 | int res, x, y = 0; | ||
919 | struct ivtv *itv = NULL; | ||
920 | struct ivtv_stream *s = NULL; | ||
921 | int minor = iminor(inode); | ||
922 | |||
923 | /* Find which card this open was on */ | ||
924 | spin_lock(&ivtv_cards_lock); | ||
925 | for (x = 0; itv == NULL && x < ivtv_cards_active; x++) { | ||
926 | /* find out which stream this open was on */ | ||
927 | for (y = 0; y < IVTV_MAX_STREAMS; y++) { | ||
928 | s = &ivtv_cards[x]->streams[y]; | ||
929 | if (s->v4l2dev && s->v4l2dev->minor == minor) { | ||
930 | itv = ivtv_cards[x]; | ||
931 | break; | ||
932 | } | ||
933 | } | ||
933 | } | 934 | } |
935 | spin_unlock(&ivtv_cards_lock); | ||
934 | 936 | ||
935 | return 0; | 937 | if (itv == NULL) { |
938 | /* Couldn't find a device registered | ||
939 | on that minor, shouldn't happen! */ | ||
940 | IVTV_WARN("No ivtv device found on minor %d\n", minor); | ||
941 | return -ENXIO; | ||
942 | } | ||
943 | |||
944 | mutex_lock(&itv->serialize_lock); | ||
945 | if (ivtv_init_on_first_open(itv)) { | ||
946 | IVTV_ERR("Failed to initialize on minor %d\n", minor); | ||
947 | mutex_unlock(&itv->serialize_lock); | ||
948 | return -ENXIO; | ||
949 | } | ||
950 | res = ivtv_serialized_open(s, filp); | ||
951 | mutex_unlock(&itv->serialize_lock); | ||
952 | return res; | ||
936 | } | 953 | } |
937 | 954 | ||
938 | void ivtv_mute(struct ivtv *itv) | 955 | void ivtv_mute(struct ivtv *itv) |