diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-12-13 14:13:37 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-01-25 16:03:39 -0500 |
commit | 55862ac9b2e656c35ab1e25d9b162e5bda81281f (patch) | |
tree | a527adfecb5dd3825b5d407a331e55f12270daff /drivers/media/video | |
parent | 6c2f990105acd360e83b95b41c60ed8bf25e67fe (diff) |
V4L/DVB (6816): Add proper locking for buffer filling
Avoids de-alocating buffers before finishing to fill a buffer
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video')
-rw-r--r-- | drivers/media/video/vivi.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 0346d1af3e62..004209d54498 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c | |||
@@ -163,6 +163,7 @@ struct vivi_dev { | |||
163 | struct list_head vivi_devlist; | 163 | struct list_head vivi_devlist; |
164 | 164 | ||
165 | struct mutex lock; | 165 | struct mutex lock; |
166 | spinlock_t slock; | ||
166 | 167 | ||
167 | int users; | 168 | int users; |
168 | 169 | ||
@@ -388,6 +389,7 @@ static void vivi_thread_tick(struct vivi_dmaqueue *dma_q) | |||
388 | 389 | ||
389 | int bc; | 390 | int bc; |
390 | 391 | ||
392 | spin_lock(&dev->slock); | ||
391 | /* Announces videobuf that all went ok */ | 393 | /* Announces videobuf that all went ok */ |
392 | for (bc = 0;; bc++) { | 394 | for (bc = 0;; bc++) { |
393 | if (list_empty(&dma_q->active)) { | 395 | if (list_empty(&dma_q->active)) { |
@@ -401,6 +403,7 @@ static void vivi_thread_tick(struct vivi_dmaqueue *dma_q) | |||
401 | /* Nobody is waiting something to be done, just return */ | 403 | /* Nobody is waiting something to be done, just return */ |
402 | if (!waitqueue_active(&buf->vb.done)) { | 404 | if (!waitqueue_active(&buf->vb.done)) { |
403 | mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); | 405 | mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); |
406 | spin_unlock(&dev->slock); | ||
404 | return; | 407 | return; |
405 | } | 408 | } |
406 | 409 | ||
@@ -419,6 +422,7 @@ static void vivi_thread_tick(struct vivi_dmaqueue *dma_q) | |||
419 | if (bc != 1) | 422 | if (bc != 1) |
420 | dprintk(dev, 1, "%s: %d buffers handled (should be 1)\n", | 423 | dprintk(dev, 1, "%s: %d buffers handled (should be 1)\n", |
421 | __FUNCTION__, bc); | 424 | __FUNCTION__, bc); |
425 | spin_unlock(&dev->slock); | ||
422 | } | 426 | } |
423 | 427 | ||
424 | static void vivi_sleep(struct vivi_dmaqueue *dma_q) | 428 | static void vivi_sleep(struct vivi_dmaqueue *dma_q) |
@@ -591,6 +595,8 @@ static void vivi_vid_timeout(unsigned long data) | |||
591 | struct vivi_dmaqueue *vidq = &dev->vidq; | 595 | struct vivi_dmaqueue *vidq = &dev->vidq; |
592 | struct vivi_buffer *buf; | 596 | struct vivi_buffer *buf; |
593 | 597 | ||
598 | spin_lock(&dev->slock); | ||
599 | |||
594 | while (!list_empty(&vidq->active)) { | 600 | while (!list_empty(&vidq->active)) { |
595 | buf = list_entry(vidq->active.next, | 601 | buf = list_entry(vidq->active.next, |
596 | struct vivi_buffer, vb.queue); | 602 | struct vivi_buffer, vb.queue); |
@@ -599,8 +605,9 @@ static void vivi_vid_timeout(unsigned long data) | |||
599 | wake_up(&buf->vb.done); | 605 | wake_up(&buf->vb.done); |
600 | printk(KERN_INFO "vivi/0: [%p/%d] timeout\n", buf, buf->vb.i); | 606 | printk(KERN_INFO "vivi/0: [%p/%d] timeout\n", buf, buf->vb.i); |
601 | } | 607 | } |
602 | |||
603 | restart_video_queue(vidq); | 608 | restart_video_queue(vidq); |
609 | |||
610 | spin_unlock(&dev->slock); | ||
604 | } | 611 | } |
605 | 612 | ||
606 | /* ------------------------------------------------------------------ | 613 | /* ------------------------------------------------------------------ |
@@ -1064,7 +1071,7 @@ found: | |||
1064 | dev->h, dev->m, dev->s, (dev->us + 500) / 1000); | 1071 | dev->h, dev->m, dev->s, (dev->us + 500) / 1000); |
1065 | 1072 | ||
1066 | videobuf_queue_vmalloc_init(&fh->vb_vidq, &vivi_video_qops, | 1073 | videobuf_queue_vmalloc_init(&fh->vb_vidq, &vivi_video_qops, |
1067 | NULL, NULL, fh->type, V4L2_FIELD_INTERLACED, | 1074 | NULL, &dev->slock, fh->type, V4L2_FIELD_INTERLACED, |
1068 | sizeof(struct vivi_buffer), fh); | 1075 | sizeof(struct vivi_buffer), fh); |
1069 | 1076 | ||
1070 | return 0; | 1077 | return 0; |
@@ -1224,6 +1231,7 @@ static int __init vivi_init(void) | |||
1224 | 1231 | ||
1225 | /* initialize locks */ | 1232 | /* initialize locks */ |
1226 | mutex_init(&dev->lock); | 1233 | mutex_init(&dev->lock); |
1234 | spin_lock_init(&dev->slock); | ||
1227 | 1235 | ||
1228 | dev->vidq.timeout.function = vivi_vid_timeout; | 1236 | dev->vidq.timeout.function = vivi_vid_timeout; |
1229 | dev->vidq.timeout.data = (unsigned long)dev; | 1237 | dev->vidq.timeout.data = (unsigned long)dev; |