diff options
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-fileops.c')
-rw-r--r-- | drivers/media/video/ivtv/ivtv-fileops.c | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index 170bef61aa62..5b5d6666fa16 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c | |||
@@ -258,19 +258,19 @@ static struct ivtv_buffer *ivtv_get_buffer(struct ivtv_stream *s, int non_block, | |||
258 | } | 258 | } |
259 | return buf; | 259 | return buf; |
260 | } | 260 | } |
261 | /* return if file was opened with O_NONBLOCK */ | ||
262 | if (non_block) { | ||
263 | *err = -EAGAIN; | ||
264 | return NULL; | ||
265 | } | ||
266 | 261 | ||
267 | /* return if end of stream */ | 262 | /* return if end of stream */ |
268 | if (s->type != IVTV_DEC_STREAM_TYPE_VBI && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { | 263 | if (s->type != IVTV_DEC_STREAM_TYPE_VBI && !test_bit(IVTV_F_S_STREAMING, &s->s_flags)) { |
269 | clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags); | ||
270 | IVTV_DEBUG_INFO("EOS %s\n", s->name); | 264 | IVTV_DEBUG_INFO("EOS %s\n", s->name); |
271 | return NULL; | 265 | return NULL; |
272 | } | 266 | } |
273 | 267 | ||
268 | /* return if file was opened with O_NONBLOCK */ | ||
269 | if (non_block) { | ||
270 | *err = -EAGAIN; | ||
271 | return NULL; | ||
272 | } | ||
273 | |||
274 | /* wait for more data to arrive */ | 274 | /* wait for more data to arrive */ |
275 | prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE); | 275 | prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE); |
276 | /* New buffers might have become available before we were added to the waitqueue */ | 276 | /* New buffers might have become available before we were added to the waitqueue */ |
@@ -378,10 +378,20 @@ static ssize_t ivtv_read(struct ivtv_stream *s, char __user *ubuf, size_t tot_co | |||
378 | int rc; | 378 | int rc; |
379 | 379 | ||
380 | buf = ivtv_get_buffer(s, non_block, &rc); | 380 | buf = ivtv_get_buffer(s, non_block, &rc); |
381 | if (buf == NULL && rc == -EAGAIN && tot_written) | 381 | /* if there is no data available... */ |
382 | break; | 382 | if (buf == NULL) { |
383 | if (buf == NULL) | 383 | /* if we got data, then return that regardless */ |
384 | if (tot_written) | ||
385 | break; | ||
386 | /* EOS condition */ | ||
387 | if (rc == 0) { | ||
388 | clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags); | ||
389 | clear_bit(IVTV_F_S_APPL_IO, &s->s_flags); | ||
390 | ivtv_release_stream(s); | ||
391 | } | ||
392 | /* set errno */ | ||
384 | return rc; | 393 | return rc; |
394 | } | ||
385 | rc = ivtv_copy_buf_to_user(s, buf, ubuf + tot_written, tot_count - tot_written); | 395 | rc = ivtv_copy_buf_to_user(s, buf, ubuf + tot_written, tot_count - tot_written); |
386 | if (buf != &itv->vbi.sliced_mpeg_buf) { | 396 | if (buf != &itv->vbi.sliced_mpeg_buf) { |
387 | ivtv_enqueue(s, buf, (buf->readpos == buf->bytesused) ? &s->q_free : &s->q_io); | 397 | ivtv_enqueue(s, buf, (buf->readpos == buf->bytesused) ? &s->q_free : &s->q_io); |
@@ -738,10 +748,11 @@ void ivtv_stop_capture(struct ivtv_open_id *id, int gop_end) | |||
738 | ivtv_stop_v4l2_encode_stream(s, gop_end); | 748 | ivtv_stop_v4l2_encode_stream(s, gop_end); |
739 | } | 749 | } |
740 | } | 750 | } |
741 | clear_bit(IVTV_F_S_APPL_IO, &s->s_flags); | 751 | if (!gop_end) { |
742 | clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags); | 752 | clear_bit(IVTV_F_S_APPL_IO, &s->s_flags); |
743 | 753 | clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags); | |
744 | ivtv_release_stream(s); | 754 | ivtv_release_stream(s); |
755 | } | ||
745 | } | 756 | } |
746 | 757 | ||
747 | static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts) | 758 | static void ivtv_stop_decoding(struct ivtv_open_id *id, int flags, u64 pts) |