Commit 464e9f3a authored by Ian Armstrong's avatar Ian Armstrong Committed by Mauro Carvalho Chehab

V4L/DVB (8088): ivtv: yuv decoder lock fix

write() operations to the yuv device may not always 'start' the decoder.
Although yuv output will be correct, some functions which should be disabled
while the decoder is in use remain enabled. This can result in hardware
registers being corrupted, causing problems with the mpeg decoder. This patch
simply moves the existing decoder 'start' sequence to earlier in the write()
handler.
Signed-off-by: default avatarIan Armstrong <ian@iarmst.demon.co.uk>
Signed-off-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 0b5a30e9
...@@ -582,6 +582,19 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c ...@@ -582,6 +582,19 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c
ivtv_queue_init(&q); ivtv_queue_init(&q);
set_bit(IVTV_F_S_APPL_IO, &s->s_flags); set_bit(IVTV_F_S_APPL_IO, &s->s_flags);
/* Start decoder (returns 0 if already started) */
mutex_lock(&itv->serialize_lock);
rc = ivtv_start_decoding(id, itv->speed);
mutex_unlock(&itv->serialize_lock);
if (rc) {
IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name);
/* failure, clean up */
clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
return rc;
}
retry: retry:
/* If possible, just DMA the entire frame - Check the data transfer size /* If possible, just DMA the entire frame - Check the data transfer size
since we may get here before the stream has been fully set-up */ since we may get here before the stream has been fully set-up */
...@@ -664,18 +677,6 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c ...@@ -664,18 +677,6 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c
ivtv_enqueue(s, buf, &s->q_full); ivtv_enqueue(s, buf, &s->q_full);
} }
/* Start decoder (returns 0 if already started) */
mutex_lock(&itv->serialize_lock);
rc = ivtv_start_decoding(id, itv->speed);
mutex_unlock(&itv->serialize_lock);
if (rc) {
IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name);
/* failure, clean up */
clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
clear_bit(IVTV_F_S_APPL_IO, &s->s_flags);
return rc;
}
if (test_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags)) { if (test_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags)) {
if (s->q_full.length >= itv->dma_data_req_size) { if (s->q_full.length >= itv->dma_data_req_size) {
int got_sig; int got_sig;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment