diff options
author | Andy Walls <awalls@radix.net> | 2008-09-03 15:47:50 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-09-03 17:36:43 -0400 |
commit | 0058717a1ef0c87deeccbe0a3b17def173fee9a9 (patch) | |
tree | 54f6ec97deb79e8beba8098d64c52fbe9dfe7c2d /drivers/media/video | |
parent | 46f2c21cfdb1a829a9a23e23562ffa66b007dc48 (diff) |
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>
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/cx18/cx18-irq.c | 2 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-queue.c | 23 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-queue.h | 2 |
3 files changed, 15 insertions, 12 deletions
diff --git a/drivers/media/video/cx18/cx18-irq.c b/drivers/media/video/cx18/cx18-irq.c index 25114a5cbd57..ab218315c84b 100644 --- a/drivers/media/video/cx18/cx18-irq.c +++ b/drivers/media/video/cx18/cx18-irq.c | |||
@@ -61,7 +61,7 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb) | |||
61 | CX18_WARN("Ack struct = %d for %s\n", | 61 | CX18_WARN("Ack struct = %d for %s\n", |
62 | mb->args[2], s->name); | 62 | mb->args[2], s->name); |
63 | id = read_enc(off); | 63 | id = read_enc(off); |
64 | buf = cx18_queue_find_buf(s, id, read_enc(off + 4)); | 64 | buf = cx18_queue_get_buf_irq(s, id, read_enc(off + 4)); |
65 | CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id); | 65 | CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id); |
66 | if (buf) { | 66 | if (buf) { |
67 | cx18_buf_sync_for_cpu(s, buf); | 67 | cx18_buf_sync_for_cpu(s, buf); |
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c index 6990b77c6200..8a4dd821fd91 100644 --- a/drivers/media/video/cx18/cx18-queue.c +++ b/drivers/media/video/cx18/cx18-queue.c | |||
@@ -78,12 +78,13 @@ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q) | |||
78 | return buf; | 78 | return buf; |
79 | } | 79 | } |
80 | 80 | ||
81 | struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id, | 81 | struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id, |
82 | u32 bytesused) | 82 | u32 bytesused) |
83 | { | 83 | { |
84 | struct cx18 *cx = s->cx; | 84 | struct cx18 *cx = s->cx; |
85 | struct list_head *p; | 85 | struct list_head *p; |
86 | 86 | ||
87 | spin_lock(&s->qlock); | ||
87 | list_for_each(p, &s->q_free.list) { | 88 | list_for_each(p, &s->q_free.list) { |
88 | struct cx18_buffer *buf = | 89 | struct cx18_buffer *buf = |
89 | list_entry(p, struct cx18_buffer, list); | 90 | list_entry(p, struct cx18_buffer, list); |
@@ -92,17 +93,19 @@ struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id, | |||
92 | continue; | 93 | continue; |
93 | buf->bytesused = bytesused; | 94 | buf->bytesused = bytesused; |
94 | /* the transport buffers are handled differently, | 95 | /* the transport buffers are handled differently, |
95 | so there is no need to move them to the full queue */ | 96 | they are not moved to the full queue */ |
96 | if (s->type == CX18_ENC_STREAM_TYPE_TS) | 97 | if (s->type != CX18_ENC_STREAM_TYPE_TS) { |
97 | return buf; | 98 | s->q_free.buffers--; |
98 | s->q_free.buffers--; | 99 | s->q_free.length -= s->buf_size; |
99 | s->q_free.length -= s->buf_size; | 100 | s->q_full.buffers++; |
100 | s->q_full.buffers++; | 101 | s->q_full.length += s->buf_size; |
101 | s->q_full.length += s->buf_size; | 102 | s->q_full.bytesused += buf->bytesused; |
102 | s->q_full.bytesused += buf->bytesused; | 103 | list_move_tail(&buf->list, &s->q_full.list); |
103 | list_move_tail(&buf->list, &s->q_full.list); | 104 | } |
105 | spin_unlock(&s->qlock); | ||
104 | return buf; | 106 | return buf; |
105 | } | 107 | } |
108 | spin_unlock(&s->qlock); | ||
106 | CX18_ERR("Cannot find buffer %d for stream %s\n", id, s->name); | 109 | CX18_ERR("Cannot find buffer %d for stream %s\n", id, s->name); |
107 | return NULL; | 110 | return NULL; |
108 | } | 111 | } |
diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h index 91423b9863a4..7f93bb13c09f 100644 --- a/drivers/media/video/cx18/cx18-queue.h +++ b/drivers/media/video/cx18/cx18-queue.h | |||
@@ -46,7 +46,7 @@ void cx18_queue_init(struct cx18_queue *q); | |||
46 | void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, | 46 | void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, |
47 | struct cx18_queue *q); | 47 | struct cx18_queue *q); |
48 | struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q); | 48 | struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q); |
49 | struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id, | 49 | struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id, |
50 | u32 bytesused); | 50 | u32 bytesused); |
51 | void cx18_flush_queues(struct cx18_stream *s); | 51 | void cx18_flush_queues(struct cx18_stream *s); |
52 | 52 | ||