aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAidan Thornton <makosoft@googlemail.com>2008-04-13 13:56:02 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-04-24 13:08:47 -0400
commite0fadfd34dda2205b296b8826acfaaf4df2e022f (patch)
tree2c061c373e64f4c0ee3209f7b70a6db9ca5df3be /drivers
parente74153d44a57d9445fb1dfad7c3accbec6d4a873 (diff)
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 <makosoft@googlemail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c20
1 files changed, 7 insertions, 13 deletions
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 033ecb45256b..e2d04cf4ba9d 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,
135{ 135{
136 mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT); 136 mod_timer(&dma_q->timeout, jiffies+BUFFER_TIMEOUT);
137 137
138 /* Nobody is waiting something to be done, just return */
139 if (!waitqueue_active(&buf->vb.done)) {
140 printk(KERN_ERR "em28xx: buffer underrun at %ld\n",
141 jiffies);
142
143 return;
144 }
145
146 /* Advice that buffer was filled */ 138 /* Advice that buffer was filled */
147 em28xx_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i); 139 em28xx_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i);
148 buf->vb.state = VIDEOBUF_DONE; 140 buf->vb.state = VIDEOBUF_DONE;
@@ -202,7 +194,8 @@ static void em28xx_copy_video(struct em28xx *dev,
202 ((char *)outp + buf->vb.size)); 194 ((char *)outp + buf->vb.size));
203 lencopy = remain = (char *)outp + buf->vb.size - (char *)startwrite; 195 lencopy = remain = (char *)outp + buf->vb.size - (char *)startwrite;
204 } 196 }
205 BUG_ON(lencopy <= 0); 197 if (lencopy <= 0)
198 return;
206 memcpy(startwrite, startread, lencopy); 199 memcpy(startwrite, startread, lencopy);
207 200
208 remain -= lencopy; 201 remain -= lencopy;
@@ -356,11 +349,13 @@ static inline int em28xx_isoc_copy(struct urb *urb)
356 if (p[0] == 0x22 && p[1] == 0x5a) { 349 if (p[0] == 0x22 && p[1] == 0x5a) {
357 /* FIXME - are the fields the right way around? */ 350 /* FIXME - are the fields the right way around? */
358 em28xx_isocdbg("Video frame, length=%i, %s\n", len, 351 em28xx_isocdbg("Video frame, length=%i, %s\n", len,
359 (p[2] & 1)? "top" : "bottom"); 352 (p[2] & 1)? "odd" : "even");
360 em28xx_isocdbg("Current buffer is: outp = 0x%p," 353 em28xx_isocdbg("Current buffer is: outp = 0x%p,"
361 " len = %i\n", outp, (int)buf->vb.size); 354 " len = %i\n", outp, (int)buf->vb.size);
362 355
363 if (p[2] & 1) { 356 if (p[2] & 1)
357 buf->top_field = 0;
358 else {
364 if (buf->receiving) { 359 if (buf->receiving) {
365 buffer_filled(dev, dma_q, buf); 360 buffer_filled(dev, dma_q, buf);
366 rc = get_next_buf(dma_q, &buf); 361 rc = get_next_buf(dma_q, &buf);
@@ -371,8 +366,7 @@ static inline int em28xx_isoc_copy(struct urb *urb)
371 } 366 }
372 367
373 buf->top_field = 1; 368 buf->top_field = 1;
374 } else 369 }
375 buf->top_field = 0;
376 buf->receiving = 1; 370 buf->receiving = 1;
377 dma_q->pos = 0; 371 dma_q->pos = 0;
378 } else if (p[0] == 0x33 && p[1] == 0x95 && p[2] == 0x00) { 372 } else if (p[0] == 0x33 && p[1] == 0x95 && p[2] == 0x00) {