aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorIan Armstrong <ian@iarmst.demon.co.uk>2008-10-09 11:04:23 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-10-13 07:08:30 -0400
commit2bd7ac55c31cb4f42e331d69dde9fc034a68944f (patch)
treec2547fc93abd5e35a33ed6876faa3b3d724f4c23 /drivers/media
parentec9faa1cfac1dd64a2a865dc7c577f3d483656bd (diff)
V4L/DVB (9166): ivtv - Fix potential race condition in yuv handler
Modified yuv register update handling to remove a potential race condition which could occur with the first video frame. Also removed a forced yuv position update, since changing the source video dimensions or interlace settings doesn't affect the frame already being displayed. Signed-off-by: Ian Armstrong <ian@iarmst.demon.co.uk> Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h2
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-irq.c9
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.c1
4 files changed, 9 insertions, 5 deletions
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index be2d779dba12..bc29436e8a3c 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -506,6 +506,8 @@ struct yuv_playback_info
506 struct v4l2_rect main_rect; 506 struct v4l2_rect main_rect;
507 u32 v4l2_src_w; 507 u32 v4l2_src_w;
508 u32 v4l2_src_h; 508 u32 v4l2_src_h;
509
510 u8 running; /* Have any frames been displayed */
509}; 511};
510 512
511#define IVTV_VBI_FRAMES 32 513#define IVTV_VBI_FRAMES 32
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 3c2628a63015..8696527ab134 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -644,8 +644,6 @@ static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *f
644 itv->dma_data_req_size = 644 itv->dma_data_req_size =
645 1080 * ((yi->v4l2_src_h + 31) & ~31); 645 1080 * ((yi->v4l2_src_h + 31) & ~31);
646 646
647 /* Force update of yuv registers */
648 yi->yuv_forced_update = 1;
649 return 0; 647 return 0;
650} 648}
651 649
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c
index 34f3ab827858..f5d00ec5da73 100644
--- a/drivers/media/video/ivtv/ivtv-irq.c
+++ b/drivers/media/video/ivtv/ivtv-irq.c
@@ -753,7 +753,7 @@ static void ivtv_irq_vsync(struct ivtv *itv)
753 */ 753 */
754 unsigned int frame = read_reg(0x28c0) & 1; 754 unsigned int frame = read_reg(0x28c0) & 1;
755 struct yuv_playback_info *yi = &itv->yuv_info; 755 struct yuv_playback_info *yi = &itv->yuv_info;
756 int last_dma_frame = atomic_read(&itv->yuv_info.next_dma_frame); 756 int last_dma_frame = atomic_read(&yi->next_dma_frame);
757 struct yuv_frame_info *f = &yi->new_frame_info[last_dma_frame]; 757 struct yuv_frame_info *f = &yi->new_frame_info[last_dma_frame];
758 758
759 if (0) IVTV_DEBUG_IRQ("DEC VSYNC\n"); 759 if (0) IVTV_DEBUG_IRQ("DEC VSYNC\n");
@@ -772,6 +772,7 @@ static void ivtv_irq_vsync(struct ivtv *itv)
772 next_dma_frame = (next_dma_frame + 1) % IVTV_YUV_BUFFERS; 772 next_dma_frame = (next_dma_frame + 1) % IVTV_YUV_BUFFERS;
773 atomic_set(&yi->next_dma_frame, next_dma_frame); 773 atomic_set(&yi->next_dma_frame, next_dma_frame);
774 yi->fields_lapsed = -1; 774 yi->fields_lapsed = -1;
775 yi->running = 1;
775 } 776 }
776 } 777 }
777 } 778 }
@@ -804,9 +805,11 @@ static void ivtv_irq_vsync(struct ivtv *itv)
804 } 805 }
805 806
806 /* Check if we need to update the yuv registers */ 807 /* Check if we need to update the yuv registers */
807 if ((yi->yuv_forced_update || f->update) && last_dma_frame != -1) { 808 if (yi->running && (yi->yuv_forced_update || f->update)) {
808 if (!f->update) { 809 if (!f->update) {
809 last_dma_frame = (u8)(last_dma_frame - 1) % IVTV_YUV_BUFFERS; 810 last_dma_frame =
811 (u8)(atomic_read(&yi->next_dma_frame) -
812 1) % IVTV_YUV_BUFFERS;
810 f = &yi->new_frame_info[last_dma_frame]; 813 f = &yi->new_frame_info[last_dma_frame];
811 } 814 }
812 815
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
index 3092ff1d00a0..ee91107376c7 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.c
+++ b/drivers/media/video/ivtv/ivtv-yuv.c
@@ -1147,6 +1147,7 @@ void ivtv_yuv_close(struct ivtv *itv)
1147 IVTV_DEBUG_YUV("ivtv_yuv_close\n"); 1147 IVTV_DEBUG_YUV("ivtv_yuv_close\n");
1148 ivtv_waitq(&itv->vsync_waitq); 1148 ivtv_waitq(&itv->vsync_waitq);
1149 1149
1150 yi->running = 0;
1150 atomic_set(&yi->next_dma_frame, -1); 1151 atomic_set(&yi->next_dma_frame, -1);
1151 atomic_set(&yi->next_fill_frame, 0); 1152 atomic_set(&yi->next_fill_frame, 0);
1152 1153