From e0fadfd34dda2205b296b8826acfaaf4df2e022f Mon Sep 17 00:00:00 2001 From: Aidan Thornton Date: Sun, 13 Apr 2008 14:56:02 -0300 Subject: [PATCH] V4L/DVB (7548): Various fixes for the em28xx videobuf code - Aborting buffer_filled if no-one's waiting on the waitqueue probably isn't what we want, since just because no-one's waiting for it now doesn't mean they wouldn't dequeue it in time. (vivi gets away with this, possibly because it can fill each buffer much faster.) - The first BUG_ON(lencopy <= 0); really isn't worth causing a kernel panic over, especially since there are some reasons why it could trigger in normal use. - The top and botom frames are actually the wrong way around. Signed-off-by: Aidan Thornton Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-video.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 033ecb45256..e2d04cf4ba9 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -135,14 +135,6 @@ static inline void buffer_filled(struct em28xx *dev, { mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); - /* Nobody is waiting something to be done, just return */ - if (!waitqueue_active(&buf->vb.done)) { - printk(KERN_ERR "em28xx: buffer underrun at %ld\n", - jiffies); - - return; - } - /* Advice that buffer was filled */ em28xx_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i); buf->vb.state = VIDEOBUF_DONE; @@ -202,7 +194,8 @@ static void em28xx_copy_video(struct em28xx *dev, ((char *)outp + buf->vb.size)); lencopy = remain = (char *)outp + buf->vb.size - (char *)startwrite; } - BUG_ON(lencopy <= 0); + if (lencopy <= 0) + return; memcpy(startwrite, startread, lencopy); remain -= lencopy; @@ -356,11 +349,13 @@ static inline int em28xx_isoc_copy(struct urb *urb) if (p[0] == 0x22 && p[1] == 0x5a) { /* FIXME - are the fields the right way around? */ em28xx_isocdbg("Video frame, length=%i, %s\n", len, - (p[2] & 1)? "top" : "bottom"); + (p[2] & 1)? "odd" : "even"); em28xx_isocdbg("Current buffer is: outp = 0x%p," " len = %i\n", outp, (int)buf->vb.size); - if (p[2] & 1) { + if (p[2] & 1) + buf->top_field = 0; + else { if (buf->receiving) { buffer_filled(dev, dma_q, buf); rc = get_next_buf(dma_q, &buf); @@ -371,8 +366,7 @@ static inline int em28xx_isoc_copy(struct urb *urb) } buf->top_field = 1; - } else - buf->top_field = 0; + } buf->receiving = 1; dma_q->pos = 0; } else if (p[0] == 0x33 && p[1] == 0x95 && p[2] == 0x00) { -- 2.39.5