forked from Minki/linux
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: Andy Walls <awalls@radix.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
46f2c21cfd
commit
0058717a1e
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user