aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ivtv/ivtv-fileops.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-fileops.c')
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c118
1 files changed, 44 insertions, 74 deletions
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index 38f052257f46..2cd6c89b7d91 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -50,16 +50,16 @@ static int ivtv_claim_stream(struct ivtv_open_id *id, int type)
50 50
51 if (test_and_set_bit(IVTV_F_S_CLAIMED, &s->s_flags)) { 51 if (test_and_set_bit(IVTV_F_S_CLAIMED, &s->s_flags)) {
52 /* someone already claimed this stream */ 52 /* someone already claimed this stream */
53 if (s->id == id->open_id) { 53 if (s->fh == &id->fh) {
54 /* yes, this file descriptor did. So that's OK. */ 54 /* yes, this file descriptor did. So that's OK. */
55 return 0; 55 return 0;
56 } 56 }
57 if (s->id == -1 && (type == IVTV_DEC_STREAM_TYPE_VBI || 57 if (s->fh == NULL && (type == IVTV_DEC_STREAM_TYPE_VBI ||
58 type == IVTV_ENC_STREAM_TYPE_VBI)) { 58 type == IVTV_ENC_STREAM_TYPE_VBI)) {
59 /* VBI is handled already internally, now also assign 59 /* VBI is handled already internally, now also assign
60 the file descriptor to this stream for external 60 the file descriptor to this stream for external
61 reading of the stream. */ 61 reading of the stream. */
62 s->id = id->open_id; 62 s->fh = &id->fh;
63 IVTV_DEBUG_INFO("Start Read VBI\n"); 63 IVTV_DEBUG_INFO("Start Read VBI\n");
64 return 0; 64 return 0;
65 } 65 }
@@ -67,7 +67,7 @@ static int ivtv_claim_stream(struct ivtv_open_id *id, int type)
67 IVTV_DEBUG_INFO("Stream %d is busy\n", type); 67 IVTV_DEBUG_INFO("Stream %d is busy\n", type);
68 return -EBUSY; 68 return -EBUSY;
69 } 69 }
70 s->id = id->open_id; 70 s->fh = &id->fh;
71 if (type == IVTV_DEC_STREAM_TYPE_VBI) { 71 if (type == IVTV_DEC_STREAM_TYPE_VBI) {
72 /* Enable reinsertion interrupt */ 72 /* Enable reinsertion interrupt */
73 ivtv_clear_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT); 73 ivtv_clear_irq_mask(itv, IVTV_IRQ_DEC_VBI_RE_INSERT);
@@ -104,7 +104,7 @@ void ivtv_release_stream(struct ivtv_stream *s)
104 struct ivtv *itv = s->itv; 104 struct ivtv *itv = s->itv;
105 struct ivtv_stream *s_vbi; 105 struct ivtv_stream *s_vbi;
106 106
107 s->id = -1; 107 s->fh = NULL;
108 if ((s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type == IVTV_ENC_STREAM_TYPE_VBI) && 108 if ((s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type == IVTV_ENC_STREAM_TYPE_VBI) &&
109 test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) { 109 test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) {
110 /* this stream is still in use internally */ 110 /* this stream is still in use internally */
@@ -136,7 +136,7 @@ void ivtv_release_stream(struct ivtv_stream *s)
136 /* was already cleared */ 136 /* was already cleared */
137 return; 137 return;
138 } 138 }
139 if (s_vbi->id != -1) { 139 if (s_vbi->fh) {
140 /* VBI stream still claimed by a file descriptor */ 140 /* VBI stream still claimed by a file descriptor */
141 return; 141 return;
142 } 142 }
@@ -268,11 +268,13 @@ static struct ivtv_buffer *ivtv_get_buffer(struct ivtv_stream *s, int non_block,
268 } 268 }
269 269
270 /* wait for more data to arrive */ 270 /* wait for more data to arrive */
271 mutex_unlock(&itv->serialize_lock);
271 prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE); 272 prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
272 /* New buffers might have become available before we were added to the waitqueue */ 273 /* New buffers might have become available before we were added to the waitqueue */
273 if (!s->q_full.buffers) 274 if (!s->q_full.buffers)
274 schedule(); 275 schedule();
275 finish_wait(&s->waitq, &wait); 276 finish_wait(&s->waitq, &wait);
277 mutex_lock(&itv->serialize_lock);
276 if (signal_pending(current)) { 278 if (signal_pending(current)) {
277 /* return if a signal was received */ 279 /* return if a signal was received */
278 IVTV_DEBUG_INFO("User stopped %s\n", s->name); 280 IVTV_DEBUG_INFO("User stopped %s\n", s->name);
@@ -357,7 +359,7 @@ static ssize_t ivtv_read(struct ivtv_stream *s, char __user *ubuf, size_t tot_co
357 size_t tot_written = 0; 359 size_t tot_written = 0;
358 int single_frame = 0; 360 int single_frame = 0;
359 361
360 if (atomic_read(&itv->capturing) == 0 && s->id == -1) { 362 if (atomic_read(&itv->capturing) == 0 && s->fh == NULL) {
361 /* shouldn't happen */ 363 /* shouldn't happen */
362 IVTV_DEBUG_WARN("Stream %s not initialized before read\n", s->name); 364 IVTV_DEBUG_WARN("Stream %s not initialized before read\n", s->name);
363 return -EIO; 365 return -EIO;
@@ -507,9 +509,7 @@ ssize_t ivtv_v4l2_read(struct file * filp, char __user *buf, size_t count, loff_
507 509
508 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);
509 511
510 mutex_lock(&itv->serialize_lock);
511 rc = ivtv_start_capture(id); 512 rc = ivtv_start_capture(id);
512 mutex_unlock(&itv->serialize_lock);
513 if (rc) 513 if (rc)
514 return rc; 514 return rc;
515 return 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);
@@ -584,9 +584,7 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c
584 set_bit(IVTV_F_S_APPL_IO, &s->s_flags); 584 set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
585 585
586 /* Start decoder (returns 0 if already started) */ 586 /* Start decoder (returns 0 if already started) */
587 mutex_lock(&itv->serialize_lock);
588 rc = ivtv_start_decoding(id, itv->speed); 587 rc = ivtv_start_decoding(id, itv->speed);
589 mutex_unlock(&itv->serialize_lock);
590 if (rc) { 588 if (rc) {
591 IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name); 589 IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name);
592 590
@@ -627,11 +625,13 @@ retry:
627 break; 625 break;
628 if (filp->f_flags & O_NONBLOCK) 626 if (filp->f_flags & O_NONBLOCK)
629 return -EAGAIN; 627 return -EAGAIN;
628 mutex_unlock(&itv->serialize_lock);
630 prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE); 629 prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE);
631 /* New buffers might have become free before we were added to the waitqueue */ 630 /* New buffers might have become free before we were added to the waitqueue */
632 if (!s->q_free.buffers) 631 if (!s->q_free.buffers)
633 schedule(); 632 schedule();
634 finish_wait(&s->waitq, &wait); 633 finish_wait(&s->waitq, &wait);
634 mutex_lock(&itv->serialize_lock);
635 if (signal_pending(current)) { 635 if (signal_pending(current)) {
636 IVTV_DEBUG_INFO("User stopped %s\n", s->name); 636 IVTV_DEBUG_INFO("User stopped %s\n", s->name);
637 return -EINTR; 637 return -EINTR;
@@ -686,12 +686,14 @@ retry:
686 if (mode == OUT_YUV) 686 if (mode == OUT_YUV)
687 ivtv_yuv_setup_stream_frame(itv); 687 ivtv_yuv_setup_stream_frame(itv);
688 688
689 mutex_unlock(&itv->serialize_lock);
689 prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE); 690 prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
690 while (!(got_sig = signal_pending(current)) && 691 while (!(got_sig = signal_pending(current)) &&
691 test_bit(IVTV_F_S_DMA_PENDING, &s->s_flags)) { 692 test_bit(IVTV_F_S_DMA_PENDING, &s->s_flags)) {
692 schedule(); 693 schedule();
693 } 694 }
694 finish_wait(&itv->dma_waitq, &wait); 695 finish_wait(&itv->dma_waitq, &wait);
696 mutex_lock(&itv->serialize_lock);
695 if (got_sig) { 697 if (got_sig) {
696 IVTV_DEBUG_INFO("User interrupted %s\n", s->name); 698 IVTV_DEBUG_INFO("User interrupted %s\n", s->name);
697 return -EINTR; 699 return -EINTR;
@@ -756,9 +758,7 @@ unsigned int ivtv_v4l2_enc_poll(struct file *filp, poll_table * wait)
756 if (!eof && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { 758 if (!eof && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
757 int rc; 759 int rc;
758 760
759 mutex_lock(&itv->serialize_lock);
760 rc = ivtv_start_capture(id); 761 rc = ivtv_start_capture(id);
761 mutex_unlock(&itv->serialize_lock);
762 if (rc) { 762 if (rc) {
763 IVTV_DEBUG_INFO("Could not start capture for %s (%d)\n", 763 IVTV_DEBUG_INFO("Could not start capture for %s (%d)\n",
764 s->name, rc); 764 s->name, rc);
@@ -808,7 +808,7 @@ void ivtv_stop_capture(struct ivtv_open_id *id, int gop_end)
808 id->type == IVTV_ENC_STREAM_TYPE_VBI) && 808 id->type == IVTV_ENC_STREAM_TYPE_VBI) &&
809 test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) { 809 test_bit(IVTV_F_S_INTERNAL_USE, &s->s_flags)) {
810 /* Also used internally, don't stop capturing */ 810 /* Also used internally, don't stop capturing */
811 s->id = -1; 811 s->fh = NULL;
812 } 812 }
813 else { 813 else {
814 ivtv_stop_v4l2_encode_stream(s, gop_end); 814 ivtv_stop_v4l2_encode_stream(s, gop_end);
@@ -861,20 +861,9 @@ int ivtv_v4l2_close(struct file *filp)
861 861
862 IVTV_DEBUG_FILE("close %s\n", s->name); 862 IVTV_DEBUG_FILE("close %s\n", s->name);
863 863
864 v4l2_fh_del(fh);
865 v4l2_fh_exit(fh);
866
867 /* Easy case first: this stream was never claimed by us */
868 if (s->id != id->open_id) {
869 kfree(id);
870 return 0;
871 }
872
873 /* 'Unclaim' this stream */
874
875 /* Stop radio */ 864 /* Stop radio */
876 mutex_lock(&itv->serialize_lock); 865 if (id->type == IVTV_ENC_STREAM_TYPE_RAD &&
877 if (id->type == IVTV_ENC_STREAM_TYPE_RAD) { 866 v4l2_fh_is_singular_file(filp)) {
878 /* Closing radio device, return to TV mode */ 867 /* Closing radio device, return to TV mode */
879 ivtv_mute(itv); 868 ivtv_mute(itv);
880 /* Mark that the radio is no longer in use */ 869 /* Mark that the radio is no longer in use */
@@ -890,13 +879,25 @@ int ivtv_v4l2_close(struct file *filp)
890 if (atomic_read(&itv->capturing) > 0) { 879 if (atomic_read(&itv->capturing) > 0) {
891 /* Undo video mute */ 880 /* Undo video mute */
892 ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1, 881 ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1,
893 v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute) | 882 v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute) |
894 (v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute_yuv) << 8)); 883 (v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute_yuv) << 8));
895 } 884 }
896 /* Done! Unmute and continue. */ 885 /* Done! Unmute and continue. */
897 ivtv_unmute(itv); 886 ivtv_unmute(itv);
898 ivtv_release_stream(s); 887 }
899 } else if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) { 888
889 v4l2_fh_del(fh);
890 v4l2_fh_exit(fh);
891
892 /* Easy case first: this stream was never claimed by us */
893 if (s->fh != &id->fh) {
894 kfree(id);
895 return 0;
896 }
897
898 /* 'Unclaim' this stream */
899
900 if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) {
900 struct ivtv_stream *s_vout = &itv->streams[IVTV_DEC_STREAM_TYPE_VOUT]; 901 struct ivtv_stream *s_vout = &itv->streams[IVTV_DEC_STREAM_TYPE_VOUT];
901 902
902 ivtv_stop_decoding(id, VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0); 903 ivtv_stop_decoding(id, VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0);
@@ -911,21 +912,25 @@ int ivtv_v4l2_close(struct file *filp)
911 ivtv_stop_capture(id, 0); 912 ivtv_stop_capture(id, 0);
912 } 913 }
913 kfree(id); 914 kfree(id);
914 mutex_unlock(&itv->serialize_lock);
915 return 0; 915 return 0;
916} 916}
917 917
918static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp) 918int ivtv_v4l2_open(struct file *filp)
919{ 919{
920#ifdef CONFIG_VIDEO_ADV_DEBUG
921 struct video_device *vdev = video_devdata(filp); 920 struct video_device *vdev = video_devdata(filp);
922#endif 921 struct ivtv_stream *s = video_get_drvdata(vdev);
923 struct ivtv *itv = s->itv; 922 struct ivtv *itv = s->itv;
924 struct ivtv_open_id *item; 923 struct ivtv_open_id *item;
925 int res = 0; 924 int res = 0;
926 925
927 IVTV_DEBUG_FILE("open %s\n", s->name); 926 IVTV_DEBUG_FILE("open %s\n", s->name);
928 927
928 if (ivtv_init_on_first_open(itv)) {
929 IVTV_ERR("Failed to initialize on device %s\n",
930 video_device_node_name(vdev));
931 return -ENXIO;
932 }
933
929#ifdef CONFIG_VIDEO_ADV_DEBUG 934#ifdef CONFIG_VIDEO_ADV_DEBUG
930 /* Unless ivtv_fw_debug is set, error out if firmware dead. */ 935 /* Unless ivtv_fw_debug is set, error out if firmware dead. */
931 if (ivtv_fw_debug) { 936 if (ivtv_fw_debug) {
@@ -966,31 +971,19 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
966 return -ENOMEM; 971 return -ENOMEM;
967 } 972 }
968 v4l2_fh_init(&item->fh, s->vdev); 973 v4l2_fh_init(&item->fh, s->vdev);
969 if (res < 0) {
970 v4l2_fh_exit(&item->fh);
971 kfree(item);
972 return res;
973 }
974 item->itv = itv; 974 item->itv = itv;
975 item->type = s->type; 975 item->type = s->type;
976 976
977 item->open_id = itv->open_id++;
978 filp->private_data = &item->fh; 977 filp->private_data = &item->fh;
978 v4l2_fh_add(&item->fh);
979 979
980 if (item->type == IVTV_ENC_STREAM_TYPE_RAD) { 980 if (item->type == IVTV_ENC_STREAM_TYPE_RAD &&
981 /* Try to claim this stream */ 981 v4l2_fh_is_singular_file(filp)) {
982 if (ivtv_claim_stream(item, item->type)) {
983 /* No, it's already in use */
984 v4l2_fh_exit(&item->fh);
985 kfree(item);
986 return -EBUSY;
987 }
988
989 if (!test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) { 982 if (!test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
990 if (atomic_read(&itv->capturing) > 0) { 983 if (atomic_read(&itv->capturing) > 0) {
991 /* switching to radio while capture is 984 /* switching to radio while capture is
992 in progress is not polite */ 985 in progress is not polite */
993 ivtv_release_stream(s); 986 v4l2_fh_del(&item->fh);
994 v4l2_fh_exit(&item->fh); 987 v4l2_fh_exit(&item->fh);
995 kfree(item); 988 kfree(item);
996 return -EBUSY; 989 return -EBUSY;
@@ -1022,32 +1015,9 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
1022 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31); 1015 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31);
1023 itv->yuv_info.stream_size = 0; 1016 itv->yuv_info.stream_size = 0;
1024 } 1017 }
1025 v4l2_fh_add(&item->fh);
1026 return 0; 1018 return 0;
1027} 1019}
1028 1020
1029int ivtv_v4l2_open(struct file *filp)
1030{
1031 int res;
1032 struct ivtv *itv = NULL;
1033 struct ivtv_stream *s = NULL;
1034 struct video_device *vdev = video_devdata(filp);
1035
1036 s = video_get_drvdata(vdev);
1037 itv = s->itv;
1038
1039 mutex_lock(&itv->serialize_lock);
1040 if (ivtv_init_on_first_open(itv)) {
1041 IVTV_ERR("Failed to initialize on device %s\n",
1042 video_device_node_name(vdev));
1043 mutex_unlock(&itv->serialize_lock);
1044 return -ENXIO;
1045 }
1046 res = ivtv_serialized_open(s, filp);
1047 mutex_unlock(&itv->serialize_lock);
1048 return res;
1049}
1050
1051void ivtv_mute(struct ivtv *itv) 1021void ivtv_mute(struct ivtv *itv)
1052{ 1022{
1053 if (atomic_read(&itv->capturing)) 1023 if (atomic_read(&itv->capturing))