aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2010-09-26 08:01:26 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-10-20 23:06:14 -0400
commit0e0809a58869e3e422985f868ad5e0da1fc0ba85 (patch)
treee4895d60a050e15d6c4b21aa7dbc4090199efdf3 /drivers/media/video
parent08bff03ed697a583612b62a6ac566bd5bce98012 (diff)
V4L/DVB: videobuf: add queue argument to videobuf_waiton()
videobuf_waiton() must unlock and relock ext_lock if it has to wait. For that to happen it needs the videobuf_queue pointer. Don't attempt to unlock/relock q->ext_lock unless it was locked in the first place. vb->state has to be protected by a spinlock to be safe. This patch is based on code from Mauro Carvalho Chehab <mchehab@redhat.com>. [mchehab@redhat.com: add extra argument to a few missing places] Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/bt8xx/bttv-risc.c2
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c2
-rw-r--r--drivers/media/video/cx88/cx88-core.c2
-rw-r--r--drivers/media/video/fsl-viu.c2
-rw-r--r--drivers/media/video/mem2mem_testdev.c2
-rw-r--r--drivers/media/video/mx1_camera.c2
-rw-r--r--drivers/media/video/mx2_camera.c2
-rw-r--r--drivers/media/video/mx3_camera.c2
-rw-r--r--drivers/media/video/omap24xxcam.c2
-rw-r--r--drivers/media/video/pxa_camera.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c2
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c2
-rw-r--r--drivers/media/video/sh_vou.c2
-rw-r--r--drivers/media/video/tlg2300/pd-video.c4
-rw-r--r--drivers/media/video/videobuf-core.c47
-rw-r--r--drivers/media/video/videobuf-dvb.c2
16 files changed, 50 insertions, 29 deletions
diff --git a/drivers/media/video/bt8xx/bttv-risc.c b/drivers/media/video/bt8xx/bttv-risc.c
index 0fa9f39f37a3..9b57d091da48 100644
--- a/drivers/media/video/bt8xx/bttv-risc.c
+++ b/drivers/media/video/bt8xx/bttv-risc.c
@@ -582,7 +582,7 @@ bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf
582 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); 582 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
583 583
584 BUG_ON(in_interrupt()); 584 BUG_ON(in_interrupt());
585 videobuf_waiton(&buf->vb,0,0); 585 videobuf_waiton(q, &buf->vb, 0, 0);
586 videobuf_dma_unmap(q->dev, dma); 586 videobuf_dma_unmap(q->dev, dma);
587 videobuf_dma_free(dma); 587 videobuf_dma_free(dma);
588 btcx_riscmem_free(btv->c.pci,&buf->bottom); 588 btcx_riscmem_free(btv->c.pci,&buf->bottom);
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index f6b62e7398af..2a34e955dad2 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -1221,7 +1221,7 @@ void cx23885_free_buffer(struct videobuf_queue *q, struct cx23885_buffer *buf)
1221 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); 1221 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
1222 1222
1223 BUG_ON(in_interrupt()); 1223 BUG_ON(in_interrupt());
1224 videobuf_waiton(&buf->vb, 0, 0); 1224 videobuf_waiton(q, &buf->vb, 0, 0);
1225 videobuf_dma_unmap(q->dev, dma); 1225 videobuf_dma_unmap(q->dev, dma);
1226 videobuf_dma_free(dma); 1226 videobuf_dma_free(dma);
1227 btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc); 1227 btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc);
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index e46dd7ed63ce..2e145f0a5fd9 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -217,7 +217,7 @@ cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf)
217 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); 217 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
218 218
219 BUG_ON(in_interrupt()); 219 BUG_ON(in_interrupt());
220 videobuf_waiton(&buf->vb,0,0); 220 videobuf_waiton(q, &buf->vb, 0, 0);
221 videobuf_dma_unmap(q->dev, dma); 221 videobuf_dma_unmap(q->dev, dma);
222 videobuf_dma_free(dma); 222 videobuf_dma_free(dma);
223 btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc); 223 btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc);
diff --git a/drivers/media/video/fsl-viu.c b/drivers/media/video/fsl-viu.c
index 0b318bed4d52..211e83963a46 100644
--- a/drivers/media/video/fsl-viu.c
+++ b/drivers/media/video/fsl-viu.c
@@ -426,7 +426,7 @@ static void free_buffer(struct videobuf_queue *vq, struct viu_buf *buf)
426 426
427 BUG_ON(in_interrupt()); 427 BUG_ON(in_interrupt());
428 428
429 videobuf_waiton(&buf->vb, 0, 0); 429 videobuf_waiton(vq, &buf->vb, 0, 0);
430 430
431 if (vq->int_ops && vq->int_ops->vaddr) 431 if (vq->int_ops && vq->int_ops->vaddr)
432 vaddr = vq->int_ops->vaddr(vb); 432 vaddr = vq->int_ops->vaddr(vb);
diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c
index a7210d981388..3b19f5b25a72 100644
--- a/drivers/media/video/mem2mem_testdev.c
+++ b/drivers/media/video/mem2mem_testdev.c
@@ -848,7 +848,7 @@ static void queue_init(void *priv, struct videobuf_queue *vq,
848 848
849 videobuf_queue_vmalloc_init(vq, &m2mtest_qops, ctx->dev->v4l2_dev.dev, 849 videobuf_queue_vmalloc_init(vq, &m2mtest_qops, ctx->dev->v4l2_dev.dev,
850 &ctx->dev->irqlock, type, V4L2_FIELD_NONE, 850 &ctx->dev->irqlock, type, V4L2_FIELD_NONE,
851 sizeof(struct m2mtest_buffer), priv); 851 sizeof(struct m2mtest_buffer), priv, NULL);
852} 852}
853 853
854 854
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c
index 5c17f9ec3d7c..e8a5ffcb6f06 100644
--- a/drivers/media/video/mx1_camera.c
+++ b/drivers/media/video/mx1_camera.c
@@ -161,7 +161,7 @@ static void free_buffer(struct videobuf_queue *vq, struct mx1_buffer *buf)
161 * This waits until this buffer is out of danger, i.e., until it is no 161 * This waits until this buffer is out of danger, i.e., until it is no
162 * longer in STATE_QUEUED or STATE_ACTIVE 162 * longer in STATE_QUEUED or STATE_ACTIVE
163 */ 163 */
164 videobuf_waiton(vb, 0, 0); 164 videobuf_waiton(vq, vb, 0, 0);
165 videobuf_dma_contig_free(vq, vb); 165 videobuf_dma_contig_free(vq, vb);
166 166
167 vb->state = VIDEOBUF_NEEDS_INIT; 167 vb->state = VIDEOBUF_NEEDS_INIT;
diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c
index b6ea67221d1d..38d09474da13 100644
--- a/drivers/media/video/mx2_camera.c
+++ b/drivers/media/video/mx2_camera.c
@@ -463,7 +463,7 @@ static void free_buffer(struct videobuf_queue *vq, struct mx2_buffer *buf)
463 * This waits until this buffer is out of danger, i.e., until it is no 463 * This waits until this buffer is out of danger, i.e., until it is no
464 * longer in STATE_QUEUED or STATE_ACTIVE 464 * longer in STATE_QUEUED or STATE_ACTIVE
465 */ 465 */
466 videobuf_waiton(vb, 0, 0); 466 videobuf_waiton(vq, vb, 0, 0);
467 467
468 videobuf_dma_contig_free(vq, vb); 468 videobuf_dma_contig_free(vq, vb);
469 dev_dbg(&icd->dev, "%s freed\n", __func__); 469 dev_dbg(&icd->dev, "%s freed\n", __func__);
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index a9be14c23912..a13076969e5a 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -185,7 +185,7 @@ static void free_buffer(struct videobuf_queue *vq, struct mx3_camera_buffer *buf
185 * This waits until this buffer is out of danger, i.e., until it is no 185 * This waits until this buffer is out of danger, i.e., until it is no
186 * longer in STATE_QUEUED or STATE_ACTIVE 186 * longer in STATE_QUEUED or STATE_ACTIVE
187 */ 187 */
188 videobuf_waiton(vb, 0, 0); 188 videobuf_waiton(vq, vb, 0, 0);
189 if (txd) { 189 if (txd) {
190 ichan = to_idmac_chan(txd->chan); 190 ichan = to_idmac_chan(txd->chan);
191 async_tx_ack(txd); 191 async_tx_ack(txd);
diff --git a/drivers/media/video/omap24xxcam.c b/drivers/media/video/omap24xxcam.c
index 926a5aa6f7f8..13c09f5fa875 100644
--- a/drivers/media/video/omap24xxcam.c
+++ b/drivers/media/video/omap24xxcam.c
@@ -420,7 +420,7 @@ static void omap24xxcam_vbq_release(struct videobuf_queue *vbq,
420 struct videobuf_dmabuf *dma = videobuf_to_dma(vb); 420 struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
421 421
422 /* wait for buffer, especially to get out of the sgdma queue */ 422 /* wait for buffer, especially to get out of the sgdma queue */
423 videobuf_waiton(vb, 0, 0); 423 videobuf_waiton(vbq, vb, 0, 0);
424 if (vb->memory == V4L2_MEMORY_MMAP) { 424 if (vb->memory == V4L2_MEMORY_MMAP) {
425 dma_unmap_sg(vbq->dev, dma->sglist, dma->sglen, 425 dma_unmap_sg(vbq->dev, dma->sglist, dma->sglen,
426 dma->direction); 426 dma->direction);
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index 9de7d59916bd..109ba99ae121 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -275,7 +275,7 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
275 * This waits until this buffer is out of danger, i.e., until it is no 275 * This waits until this buffer is out of danger, i.e., until it is no
276 * longer in STATE_QUEUED or STATE_ACTIVE 276 * longer in STATE_QUEUED or STATE_ACTIVE
277 */ 277 */
278 videobuf_waiton(&buf->vb, 0, 0); 278 videobuf_waiton(vq, &buf->vb, 0, 0);
279 videobuf_dma_unmap(vq->dev, dma); 279 videobuf_dma_unmap(vq->dev, dma);
280 videobuf_dma_free(dma); 280 videobuf_dma_free(dma);
281 281
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 40bc635e8a3f..c424c4574d49 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -255,7 +255,7 @@ void saa7134_dma_free(struct videobuf_queue *q,struct saa7134_buf *buf)
255 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); 255 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
256 BUG_ON(in_interrupt()); 256 BUG_ON(in_interrupt());
257 257
258 videobuf_waiton(&buf->vb,0,0); 258 videobuf_waiton(q, &buf->vb, 0, 0);
259 videobuf_dma_unmap(q->dev, dma); 259 videobuf_dma_unmap(q->dev, dma);
260 videobuf_dma_free(dma); 260 videobuf_dma_free(dma);
261 buf->vb.state = VIDEOBUF_NEEDS_INIT; 261 buf->vb.state = VIDEOBUF_NEEDS_INIT;
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 2b24bd0de3ad..39211628d427 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -245,7 +245,7 @@ static void free_buffer(struct videobuf_queue *vq,
245 if (in_interrupt()) 245 if (in_interrupt())
246 BUG(); 246 BUG();
247 247
248 videobuf_waiton(&buf->vb, 0, 0); 248 videobuf_waiton(vq, &buf->vb, 0, 0);
249 videobuf_dma_contig_free(vq, &buf->vb); 249 videobuf_dma_contig_free(vq, &buf->vb);
250 dev_dbg(dev, "%s freed\n", __func__); 250 dev_dbg(dev, "%s freed\n", __func__);
251 buf->vb.state = VIDEOBUF_NEEDS_INIT; 251 buf->vb.state = VIDEOBUF_NEEDS_INIT;
diff --git a/drivers/media/video/sh_vou.c b/drivers/media/video/sh_vou.c
index d394187eb701..d3acd02a1632 100644
--- a/drivers/media/video/sh_vou.c
+++ b/drivers/media/video/sh_vou.c
@@ -230,7 +230,7 @@ static void free_buffer(struct videobuf_queue *vq, struct videobuf_buffer *vb)
230 BUG_ON(in_interrupt()); 230 BUG_ON(in_interrupt());
231 231
232 /* Wait until this buffer is no longer in STATE_QUEUED or STATE_ACTIVE */ 232 /* Wait until this buffer is no longer in STATE_QUEUED or STATE_ACTIVE */
233 videobuf_waiton(vb, 0, 0); 233 videobuf_waiton(vq, vb, 0, 0);
234 videobuf_dma_contig_free(vq, vb); 234 videobuf_dma_contig_free(vq, vb);
235 vb->state = VIDEOBUF_NEEDS_INIT; 235 vb->state = VIDEOBUF_NEEDS_INIT;
236} 236}
diff --git a/drivers/media/video/tlg2300/pd-video.c b/drivers/media/video/tlg2300/pd-video.c
index d0cc012f7ae6..a1ffe18640fe 100644
--- a/drivers/media/video/tlg2300/pd-video.c
+++ b/drivers/media/video/tlg2300/pd-video.c
@@ -1434,7 +1434,7 @@ static int pd_video_open(struct file *file)
1434 V4L2_BUF_TYPE_VIDEO_CAPTURE, 1434 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1435 V4L2_FIELD_INTERLACED,/* video is interlacd */ 1435 V4L2_FIELD_INTERLACED,/* video is interlacd */
1436 sizeof(struct videobuf_buffer),/*it's enough*/ 1436 sizeof(struct videobuf_buffer),/*it's enough*/
1437 front); 1437 front, NULL);
1438 } else if (vfd->vfl_type == VFL_TYPE_VBI 1438 } else if (vfd->vfl_type == VFL_TYPE_VBI
1439 && !(pd->state & POSEIDON_STATE_VBI)) { 1439 && !(pd->state & POSEIDON_STATE_VBI)) {
1440 front = kzalloc(sizeof(struct front_face), GFP_KERNEL); 1440 front = kzalloc(sizeof(struct front_face), GFP_KERNEL);
@@ -1451,7 +1451,7 @@ static int pd_video_open(struct file *file)
1451 V4L2_BUF_TYPE_VBI_CAPTURE, 1451 V4L2_BUF_TYPE_VBI_CAPTURE,
1452 V4L2_FIELD_NONE, /* vbi is NONE mode */ 1452 V4L2_FIELD_NONE, /* vbi is NONE mode */
1453 sizeof(struct videobuf_buffer), 1453 sizeof(struct videobuf_buffer),
1454 front); 1454 front, NULL);
1455 } else { 1455 } else {
1456 /* maybe add FM support here */ 1456 /* maybe add FM support here */
1457 log("other "); 1457 log("other ");
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c
index a32ef8eafc01..8979f91fa8e5 100644
--- a/drivers/media/video/videobuf-core.c
+++ b/drivers/media/video/videobuf-core.c
@@ -73,25 +73,46 @@ struct videobuf_buffer *videobuf_alloc_vb(struct videobuf_queue *q)
73} 73}
74EXPORT_SYMBOL_GPL(videobuf_alloc_vb); 74EXPORT_SYMBOL_GPL(videobuf_alloc_vb);
75 75
76#define WAITON_CONDITION (vb->state != VIDEOBUF_ACTIVE &&\ 76static int is_state_active_or_queued(struct videobuf_queue *q, struct videobuf_buffer *vb)
77 vb->state != VIDEOBUF_QUEUED)
78int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr)
79{ 77{
78 unsigned long flags;
79 bool rc;
80
81 spin_lock_irqsave(q->irqlock, flags);
82 rc = vb->state != VIDEOBUF_ACTIVE && vb->state != VIDEOBUF_QUEUED;
83 spin_unlock_irqrestore(q->irqlock, flags);
84 return rc;
85};
86
87int videobuf_waiton(struct videobuf_queue *q, struct videobuf_buffer *vb,
88 int non_blocking, int intr)
89{
90 bool is_ext_locked;
91 int ret = 0;
92
80 MAGIC_CHECK(vb->magic, MAGIC_BUFFER); 93 MAGIC_CHECK(vb->magic, MAGIC_BUFFER);
81 94
82 if (non_blocking) { 95 if (non_blocking) {
83 if (WAITON_CONDITION) 96 if (is_state_active_or_queued(q, vb))
84 return 0; 97 return 0;
85 else 98 return -EAGAIN;
86 return -EAGAIN;
87 } 99 }
88 100
101 is_ext_locked = q->ext_lock && mutex_is_locked(q->ext_lock);
102
103 /* Release vdev lock to prevent this wait from blocking outside access to
104 the device. */
105 if (is_ext_locked)
106 mutex_unlock(q->ext_lock);
89 if (intr) 107 if (intr)
90 return wait_event_interruptible(vb->done, WAITON_CONDITION); 108 ret = wait_event_interruptible(vb->done, is_state_active_or_queued(q, vb));
91 else 109 else
92 wait_event(vb->done, WAITON_CONDITION); 110 wait_event(vb->done, is_state_active_or_queued(q, vb));
111 /* Relock */
112 if (is_ext_locked)
113 mutex_lock(q->ext_lock);
93 114
94 return 0; 115 return ret;
95} 116}
96EXPORT_SYMBOL_GPL(videobuf_waiton); 117EXPORT_SYMBOL_GPL(videobuf_waiton);
97 118
@@ -671,7 +692,7 @@ static int stream_next_buffer(struct videobuf_queue *q,
671 goto done; 692 goto done;
672 693
673 buf = list_entry(q->stream.next, struct videobuf_buffer, stream); 694 buf = list_entry(q->stream.next, struct videobuf_buffer, stream);
674 retval = videobuf_waiton(buf, nonblocking, 1); 695 retval = videobuf_waiton(q, buf, nonblocking, 1);
675 if (retval < 0) 696 if (retval < 0)
676 goto done; 697 goto done;
677 698
@@ -799,7 +820,7 @@ static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q,
799 spin_lock_irqsave(q->irqlock, flags); 820 spin_lock_irqsave(q->irqlock, flags);
800 q->ops->buf_queue(q, q->read_buf); 821 q->ops->buf_queue(q, q->read_buf);
801 spin_unlock_irqrestore(q->irqlock, flags); 822 spin_unlock_irqrestore(q->irqlock, flags);
802 retval = videobuf_waiton(q->read_buf, 0, 0); 823 retval = videobuf_waiton(q, q->read_buf, 0, 0);
803 if (0 == retval) { 824 if (0 == retval) {
804 CALL(q, sync, q, q->read_buf); 825 CALL(q, sync, q, q->read_buf);
805 if (VIDEOBUF_ERROR == q->read_buf->state) 826 if (VIDEOBUF_ERROR == q->read_buf->state)
@@ -911,7 +932,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
911 } 932 }
912 933
913 /* wait until capture is done */ 934 /* wait until capture is done */
914 retval = videobuf_waiton(q->read_buf, nonblocking, 1); 935 retval = videobuf_waiton(q, q->read_buf, nonblocking, 1);
915 if (0 != retval) 936 if (0 != retval)
916 goto done; 937 goto done;
917 938
@@ -1061,7 +1082,7 @@ ssize_t videobuf_read_stream(struct videobuf_queue *q,
1061 list_del(&q->read_buf->stream); 1082 list_del(&q->read_buf->stream);
1062 q->read_off = 0; 1083 q->read_off = 0;
1063 } 1084 }
1064 rc = videobuf_waiton(q->read_buf, nonblocking, 1); 1085 rc = videobuf_waiton(q, q->read_buf, nonblocking, 1);
1065 if (rc < 0) { 1086 if (rc < 0) {
1066 if (0 == retval) 1087 if (0 == retval)
1067 retval = rc; 1088 retval = rc;
diff --git a/drivers/media/video/videobuf-dvb.c b/drivers/media/video/videobuf-dvb.c
index 3f76398968b8..3de7c7e4402d 100644
--- a/drivers/media/video/videobuf-dvb.c
+++ b/drivers/media/video/videobuf-dvb.c
@@ -57,7 +57,7 @@ static int videobuf_dvb_thread(void *data)
57 buf = list_entry(dvb->dvbq.stream.next, 57 buf = list_entry(dvb->dvbq.stream.next,
58 struct videobuf_buffer, stream); 58 struct videobuf_buffer, stream);
59 list_del(&buf->stream); 59 list_del(&buf->stream);
60 err = videobuf_waiton(buf,0,1); 60 err = videobuf_waiton(&dvb->dvbq, buf, 0, 1);
61 61
62 /* no more feeds left or stop_feed() asked us to quit */ 62 /* no more feeds left or stop_feed() asked us to quit */
63 if (0 == dvb->nfeeds) 63 if (0 == dvb->nfeeds)