V4L/DVB (10101): uvcvideo: Fix bulk URB processing when the header is erroneous
authorLaurent Pinchart <laurent.pinchart@skynet.be>
Tue, 16 Dec 2008 13:41:57 +0000 (10:41 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 30 Dec 2008 11:40:31 +0000 (09:40 -0200)
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>
drivers/media/video/uvc/uvc_video.c

index b7160b15e78046b5944e318437e33373c67c906f..6d0ac3be8191adc8ec3fe417f9c2cae03beb02d3 100644 (file)
@@ -368,7 +368,7 @@ static int uvc_video_decode_start(struct uvc_video_device *video,
 
        /* Synchronize to the input stream by waiting for the FID bit to be
         * toggled when the the buffer state is not UVC_BUF_STATE_ACTIVE.
-        * queue->last_fid is initialized to -1, so the first isochronous
+        * video->last_fid is initialized to -1, so the first isochronous
         * frame will always be in sync.
         *
         * 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,
         * last payload can be lost anyway). We thus must check if the FID has
         * been toggled.
         *
-        * queue->last_fid is initialized to -1, so the first isochronous
+        * video->last_fid is initialized to -1, so the first isochronous
         * frame will never trigger an end of frame detection.
         *
         * Empty buffers (bytesused == 0) don't trigger end of frame detection
@@ -512,7 +512,7 @@ static void uvc_video_decode_bulk(struct urb *urb,
        /* If the URB is the first of its payload, decode and save the
         * header.
         */
-       if (video->bulk.header_size == 0) {
+       if (video->bulk.header_size == 0 && !video->bulk.skip_payload) {
                do {
                        ret = uvc_video_decode_start(video, buf, mem, len);
                        if (ret == -EAGAIN)
@@ -522,14 +522,13 @@ static void uvc_video_decode_bulk(struct urb *urb,
                /* If an error occured skip the rest of the payload. */
                if (ret < 0 || buf == NULL) {
                        video->bulk.skip_payload = 1;
-                       return;
-               }
+               } else {
+                       memcpy(video->bulk.header, mem, ret);
+                       video->bulk.header_size = ret;
 
-               video->bulk.header_size = ret;
-               memcpy(video->bulk.header, mem, video->bulk.header_size);
-
-               mem += ret;
-               len -= ret;
+                       mem += ret;
+                       len -= ret;
+               }
        }
 
        /* The buffer queue might have been cancelled while a bulk transfer