aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/uvc
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@skynet.be>2008-12-16 08:41:57 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-30 06:40:31 -0500
commitf8dd4af6d44b4b738f125f6a21afa885f3b1d13b (patch)
tree67e3e53a108f741a1f1feda01b25f20370680a3d /drivers/media/video/uvc
parent4e96fd088cf6fb95ba4b212e5e72bac1e6d34e79 (diff)
V4L/DVB (10101): uvcvideo: Fix bulk URB processing when the header is erroneous
When the first bulk URB of a video payload contains an erroneous header, or when no V4L2 buffer is available, the whole payload must be dropped. Change the skip logic to drop all bulk URBs until the end of the payload instead of the first one only. Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/uvc')
-rw-r--r--drivers/media/video/uvc/uvc_video.c19
1 files changed, 9 insertions, 10 deletions
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index b7160b15e780..6d0ac3be8191 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -368,7 +368,7 @@ static int uvc_video_decode_start(struct uvc_video_device *video,
368 368
369 /* Synchronize to the input stream by waiting for the FID bit to be 369 /* Synchronize to the input stream by waiting for the FID bit to be
370 * toggled when the the buffer state is not UVC_BUF_STATE_ACTIVE. 370 * toggled when the the buffer state is not UVC_BUF_STATE_ACTIVE.
371 * queue->last_fid is initialized to -1, so the first isochronous 371 * video->last_fid is initialized to -1, so the first isochronous
372 * frame will always be in sync. 372 * frame will always be in sync.
373 * 373 *
374 * If the device doesn't toggle the FID bit, invert video->last_fid 374 * If the device doesn't toggle the FID bit, invert video->last_fid
@@ -395,7 +395,7 @@ static int uvc_video_decode_start(struct uvc_video_device *video,
395 * last payload can be lost anyway). We thus must check if the FID has 395 * last payload can be lost anyway). We thus must check if the FID has
396 * been toggled. 396 * been toggled.
397 * 397 *
398 * queue->last_fid is initialized to -1, so the first isochronous 398 * video->last_fid is initialized to -1, so the first isochronous
399 * frame will never trigger an end of frame detection. 399 * frame will never trigger an end of frame detection.
400 * 400 *
401 * Empty buffers (bytesused == 0) don't trigger end of frame detection 401 * Empty buffers (bytesused == 0) don't trigger end of frame detection
@@ -512,7 +512,7 @@ static void uvc_video_decode_bulk(struct urb *urb,
512 /* If the URB is the first of its payload, decode and save the 512 /* If the URB is the first of its payload, decode and save the
513 * header. 513 * header.
514 */ 514 */
515 if (video->bulk.header_size == 0) { 515 if (video->bulk.header_size == 0 && !video->bulk.skip_payload) {
516 do { 516 do {
517 ret = uvc_video_decode_start(video, buf, mem, len); 517 ret = uvc_video_decode_start(video, buf, mem, len);
518 if (ret == -EAGAIN) 518 if (ret == -EAGAIN)
@@ -522,14 +522,13 @@ static void uvc_video_decode_bulk(struct urb *urb,
522 /* If an error occured skip the rest of the payload. */ 522 /* If an error occured skip the rest of the payload. */
523 if (ret < 0 || buf == NULL) { 523 if (ret < 0 || buf == NULL) {
524 video->bulk.skip_payload = 1; 524 video->bulk.skip_payload = 1;
525 return; 525 } else {
526 } 526 memcpy(video->bulk.header, mem, ret);
527 video->bulk.header_size = ret;
527 528
528 video->bulk.header_size = ret; 529 mem += ret;
529 memcpy(video->bulk.header, mem, video->bulk.header_size); 530 len -= ret;
530 531 }
531 mem += ret;
532 len -= ret;
533 } 532 }
534 533
535 /* The buffer queue might have been cancelled while a bulk transfer 534 /* The buffer queue might have been cancelled while a bulk transfer