media: uvcvideo: Increment intervals pointer at end of parsing
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Fri, 5 May 2023 11:45:24 +0000 (14:45 +0300)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Fri, 9 Jun 2023 13:11:54 +0000 (14:11 +0100)
The intervals pointer is incremented for each interval when parsing the
format descriptor. This doesn't cause any issue as such, but gets in the
way of constifying some pointers. Modify the parsing code to index the
intervals pointer as an array and increment it in one go at end of
parsing.

Careful readers will notice that the maxIntervalIndex variable is set to
1 instead of n - 2 when bFrameIntervalType has a zero value. This is
functionally equivalent, as n is equal to 3 in that case.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
drivers/media/usb/uvc/uvc_driver.c

index ef9066dcf53587e0470b7f8a08ccf30decaaa1e6..adfb0b08d1298956e7ed4fd374deb5ceeb7594e8 100644 (file)
@@ -370,6 +370,8 @@ static int uvc_parse_format(struct uvc_device *dev,
         */
        while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
               buffer[2] == ftype) {
+               unsigned int maxIntervalIndex;
+
                frame = &format->frames[format->nframes];
                if (ftype != UVC_VS_FRAME_FRAME_BASED)
                        n = buflen > 25 ? buffer[25] : 0;
@@ -418,7 +420,7 @@ static int uvc_parse_format(struct uvc_device *dev,
 
                for (i = 0; i < n; ++i) {
                        interval = get_unaligned_le32(&buffer[26+4*i]);
-                       *(*intervals)++ = interval ? interval : 1;
+                       (*intervals)[i] = interval ? interval : 1;
                }
 
                /*
@@ -439,12 +441,17 @@ static int uvc_parse_format(struct uvc_device *dev,
                        frame->dwMaxVideoFrameBufferSize = format->bpp
                                * frame->wWidth * frame->wHeight / 8;
 
-               /* Clamp the default frame interval to the boundaries. */
-               n -= frame->bFrameIntervalType ? 1 : 2;
+               /*
+                * Clamp the default frame interval to the boundaries. A zero
+                * bFrameIntervalType value indicates a continuous frame
+                * interval range, with dwFrameInterval[0] storing the minimum
+                * value and dwFrameInterval[1] storing the maximum value.
+                */
+               maxIntervalIndex = frame->bFrameIntervalType ? n - 1 : 1;
                frame->dwDefaultFrameInterval =
                        clamp(frame->dwDefaultFrameInterval,
                              frame->dwFrameInterval[0],
-                             frame->dwFrameInterval[n]);
+                             frame->dwFrameInterval[maxIntervalIndex]);
 
                /*
                 * Some devices report frame intervals that are not functional.
@@ -463,6 +470,8 @@ static int uvc_parse_format(struct uvc_device *dev,
                        (100000000 / frame->dwDefaultFrameInterval) % 10);
 
                format->nframes++;
+               *intervals += n;
+
                buflen -= buffer[0];
                buffer += buffer[0];
        }