summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2009-10-08 19:38:10 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-05 18:40:36 -0200
commitc4ed8c66d79d707d89fe732ff5b97739edf1ba62 (patch)
tree4a316dff13cce8e2b830e955076b5dd3764b2414
parentfd1b6bbb4a54a232ae6a1e5e4a6fbe3507ed5142 (diff)
downloadlinux-c4ed8c66d79d707d89fe732ff5b97739edf1ba62.tar.gz
linux-c4ed8c66d79d707d89fe732ff5b97739edf1ba62.tar.bz2
linux-c4ed8c66d79d707d89fe732ff5b97739edf1ba62.zip
V4L/DVB (13154): uvcvideo: Handle garbage at the end of streaming interface descriptors
At least one 5986:0241 webcam model includes vendor-specific descriptors at the end of its streaming interface descriptors. Print an information UVC_TRACE_DESCR message and try to continue parsing the descriptors rather than bailing out with an error. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/uvc/uvc_driver.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index ebddf006a4f4..307d3a6b7395 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -426,7 +426,8 @@ static int uvc_parse_format(struct uvc_device *dev,
/* Parse the frame descriptors. Only uncompressed, MJPEG and frame
* based formats have frame descriptors.
*/
- while (buflen > 2 && buffer[2] == ftype) {
+ while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
+ buffer[2] == ftype) {
frame = &format->frame[format->nframes];
if (ftype != UVC_VS_FRAME_FRAME_BASED)
n = buflen > 25 ? buffer[25] : 0;
@@ -503,12 +504,14 @@ static int uvc_parse_format(struct uvc_device *dev,
buffer += buffer[0];
}
- if (buflen > 2 && buffer[2] == UVC_VS_STILL_IMAGE_FRAME) {
+ if (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
+ buffer[2] == UVC_VS_STILL_IMAGE_FRAME) {
buflen -= buffer[0];
buffer += buffer[0];
}
- if (buflen > 2 && buffer[2] == UVC_VS_COLORFORMAT) {
+ if (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
+ buffer[2] == UVC_VS_COLORFORMAT) {
if (buflen < 6) {
uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
"interface %d COLORFORMAT error\n",
@@ -749,6 +752,11 @@ static int uvc_parse_streaming(struct uvc_device *dev,
buffer += buffer[0];
}
+ if (buflen)
+ uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming interface "
+ "%d has %u bytes of trailing descriptor garbage.\n",
+ dev->udev->devnum, alts->desc.bInterfaceNumber, buflen);
+
/* Parse the alternate settings to find the maximum bandwidth. */
for (i = 0; i < intf->num_altsetting; ++i) {
struct usb_host_endpoint *ep;