Commit e0fadfd3 authored by Aidan Thornton's avatar Aidan Thornton Committed by Mauro Carvalho Chehab

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: default avatarAidan Thornton <makosoft@googlemail.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent e74153d4
...@@ -135,14 +135,6 @@ static inline void buffer_filled(struct em28xx *dev, ...@@ -135,14 +135,6 @@ static inline void buffer_filled(struct em28xx *dev,
{ {
mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); 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 */ /* Advice that buffer was filled */
em28xx_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i); em28xx_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i);
buf->vb.state = VIDEOBUF_DONE; buf->vb.state = VIDEOBUF_DONE;
...@@ -202,7 +194,8 @@ static void em28xx_copy_video(struct em28xx *dev, ...@@ -202,7 +194,8 @@ static void em28xx_copy_video(struct em28xx *dev,
((char *)outp + buf->vb.size)); ((char *)outp + buf->vb.size));
lencopy = remain = (char *)outp + buf->vb.size - (char *)startwrite; lencopy = remain = (char *)outp + buf->vb.size - (char *)startwrite;
} }
BUG_ON(lencopy <= 0); if (lencopy <= 0)
return;
memcpy(startwrite, startread, lencopy); memcpy(startwrite, startread, lencopy);
remain -= lencopy; remain -= lencopy;
...@@ -356,11 +349,13 @@ static inline int em28xx_isoc_copy(struct urb *urb) ...@@ -356,11 +349,13 @@ static inline int em28xx_isoc_copy(struct urb *urb)
if (p[0] == 0x22 && p[1] == 0x5a) { if (p[0] == 0x22 && p[1] == 0x5a) {
/* FIXME - are the fields the right way around? */ /* FIXME - are the fields the right way around? */
em28xx_isocdbg("Video frame, length=%i, %s\n", len, 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," em28xx_isocdbg("Current buffer is: outp = 0x%p,"
" len = %i\n", outp, (int)buf->vb.size); " len = %i\n", outp, (int)buf->vb.size);
if (p[2] & 1) { if (p[2] & 1)
buf->top_field = 0;
else {
if (buf->receiving) { if (buf->receiving) {
buffer_filled(dev, dma_q, buf); buffer_filled(dev, dma_q, buf);
rc = get_next_buf(dma_q, &buf); rc = get_next_buf(dma_q, &buf);
...@@ -371,8 +366,7 @@ static inline int em28xx_isoc_copy(struct urb *urb) ...@@ -371,8 +366,7 @@ static inline int em28xx_isoc_copy(struct urb *urb)
} }
buf->top_field = 1; buf->top_field = 1;
} else }
buf->top_field = 0;
buf->receiving = 1; buf->receiving = 1;
dma_q->pos = 0; dma_q->pos = 0;
} else if (p[0] == 0x33 && p[1] == 0x95 && p[2] == 0x00) { } else if (p[0] == 0x33 && p[1] == 0x95 && p[2] == 0x00) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment