Commit 0058717a authored by Andy Walls's avatar Andy Walls Committed by Mauro Carvalho Chehab

V4L/DVB (8701): cx18: Add missing lock for when the irq handler manipulates the queues

cx18: Add missing lock for when the irq handler manipulates the queues.  This
was a potential source of stream queue corruption.  Also changed the name of
cx18_queue_find_buf() to cx18_queue_get_buf_irq().
Signed-off-by: default avatarAndy Walls <awalls@radix.net>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 46f2c21c
......@@ -61,7 +61,7 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb)
CX18_WARN("Ack struct = %d for %s\n",
mb->args[2], s->name);
id = read_enc(off);
buf = cx18_queue_find_buf(s, id, read_enc(off + 4));
buf = cx18_queue_get_buf_irq(s, id, read_enc(off + 4));
CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id);
if (buf) {
cx18_buf_sync_for_cpu(s, buf);
......
......@@ -78,12 +78,13 @@ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q)
return buf;
}
struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id,
struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id,
u32 bytesused)
{
struct cx18 *cx = s->cx;
struct list_head *p;
spin_lock(&s->qlock);
list_for_each(p, &s->q_free.list) {
struct cx18_buffer *buf =
list_entry(p, struct cx18_buffer, list);
......@@ -92,17 +93,19 @@ struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id,
continue;
buf->bytesused = bytesused;
/* the transport buffers are handled differently,
so there is no need to move them to the full queue */
if (s->type == CX18_ENC_STREAM_TYPE_TS)
return buf;
s->q_free.buffers--;
s->q_free.length -= s->buf_size;
s->q_full.buffers++;
s->q_full.length += s->buf_size;
s->q_full.bytesused += buf->bytesused;
list_move_tail(&buf->list, &s->q_full.list);
they are not moved to the full queue */
if (s->type != CX18_ENC_STREAM_TYPE_TS) {
s->q_free.buffers--;
s->q_free.length -= s->buf_size;
s->q_full.buffers++;
s->q_full.length += s->buf_size;
s->q_full.bytesused += buf->bytesused;
list_move_tail(&buf->list, &s->q_full.list);
}
spin_unlock(&s->qlock);
return buf;
}
spin_unlock(&s->qlock);
CX18_ERR("Cannot find buffer %d for stream %s\n", id, s->name);
return NULL;
}
......
......@@ -46,7 +46,7 @@ void cx18_queue_init(struct cx18_queue *q);
void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf,
struct cx18_queue *q);
struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q);
struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id,
struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id,
u32 bytesused);
void cx18_flush_queues(struct cx18_stream *s);
......
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