Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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);
+13 −10
Original line number Diff line number Diff line
@@ -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;
		   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;
}
+1 −1
Original line number Diff line number Diff line
@@ -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);