summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2023-05-05 14:45:24 +0300
committerMauro Carvalho Chehab <mchehab@kernel.org>2023-06-09 16:11:54 +0300
commit7691d900b9291417dc6a88262f43176a63536c31 (patch)
tree4a4b277bc4069a7cad2de559f79e7782eb739d84 /drivers
parentc9d597b9b7ef9ffcb54051f04798b608edc6850c (diff)
downloadlinux-7691d900b9291417dc6a88262f43176a63536c31.tar.xz
media: uvcvideo: Increment intervals pointer at end of parsing
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/usb/uvc/uvc_driver.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index ef9066dcf535..adfb0b08d129 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -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];
}