V4L/DVB (7548): Various fixes for the em28xx videobuf code
authorAidan Thornton <makosoft@googlemail.com>
Sun, 13 Apr 2008 17:56:02 +0000 (14:56 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Thu, 24 Apr 2008 17:08:47 +0000 (14:08 -0300)
- 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 <makosoft@googlemail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
drivers/media/video/em28xx/em28xx-video.c

index 033ecb45256b9a24d162d2bfa9ef440a58dcb37c..e2d04cf4ba9d8e6b5be7c2a1b84a8b380808c46d 100644 (file)
@@ -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) {