rpms/kernel/F-10 linux-2.6-uvc-hg.patch, NONE, 1.1 linux-2.6-uvc-spca525.patch, NONE, 1.1 kernel.spec, 1.1156, 1.1157

Hans de Goede jwrdegoede at fedoraproject.org
Wed Nov 19 20:29:59 UTC 2008


Author: jwrdegoede

Update of /cvs/extras/rpms/kernel/F-10
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv8161

Modified Files:
	kernel.spec 
Added Files:
	linux-2.6-uvc-hg.patch linux-2.6-uvc-spca525.patch 
Log Message:
* Wed Nov 19 2008 Hans de Goede <hdegoede at redhat.com> 2.6.27.5-121
- Update uvcvideo to latest git
- Patch uvcvideo to not make older logitech cams crash (bz 472217)


linux-2.6-uvc-hg.patch:

--- NEW FILE linux-2.6-uvc-hg.patch ---
diff -up linux-2.6.27.noarch/drivers/media/video/uvc/uvc_ctrl.c.uvc linux-2.6.27.noarch/drivers/media/video/uvc/uvc_ctrl.c
--- linux-2.6.27.noarch/drivers/media/video/uvc/uvc_ctrl.c.uvc	2008-10-10 00:13:53.000000000 +0200
+++ linux-2.6.27.noarch/drivers/media/video/uvc/uvc_ctrl.c	2008-11-19 11:18:58.000000000 +0100
@@ -83,6 +83,22 @@ static struct uvc_control_info uvc_ctrls
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
+		.selector	= PU_WHITE_BALANCE_TEMPERATURE_CONTROL,
+		.index		= 6,
+		.size		= 2,
+		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
+				| UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
+	},
+	{
+		.entity		= UVC_GUID_UVC_PROCESSING,
+		.selector	= PU_WHITE_BALANCE_COMPONENT_CONTROL,
+		.index		= 7,
+		.size		= 4,
+		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
+				| UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
+	},
+	{
+		.entity		= UVC_GUID_UVC_PROCESSING,
 		.selector	= PU_BACKLIGHT_COMPENSATION_CONTROL,
 		.index		= 8,
 		.size		= 2,
@@ -114,6 +130,60 @@ static struct uvc_control_info uvc_ctrls
 				| UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE,
 	},
 	{
+		.entity		= UVC_GUID_UVC_PROCESSING,
+		.selector	= PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,
+		.index		= 12,
+		.size		= 1,
+		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
+				| UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE,
+	},
+	{
+		.entity		= UVC_GUID_UVC_PROCESSING,
+		.selector	= PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL,
+		.index		= 13,
+		.size		= 1,
+		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
+				| UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE,
+	},
+	{
+		.entity		= UVC_GUID_UVC_PROCESSING,
+		.selector	= PU_DIGITAL_MULTIPLIER_CONTROL,
+		.index		= 14,
+		.size		= 2,
+		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
+				| UVC_CONTROL_RESTORE,
+	},
+	{
+		.entity		= UVC_GUID_UVC_PROCESSING,
+		.selector	= PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL,
+		.index		= 15,
+		.size		= 2,
+		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
+				| UVC_CONTROL_RESTORE,
+	},
+	{
+		.entity		= UVC_GUID_UVC_PROCESSING,
+		.selector	= PU_ANALOG_VIDEO_STANDARD_CONTROL,
+		.index		= 16,
+		.size		= 1,
+		.flags		= UVC_CONTROL_GET_CUR,
+	},
+	{
+		.entity		= UVC_GUID_UVC_PROCESSING,
+		.selector	= PU_ANALOG_LOCK_STATUS_CONTROL,
+		.index		= 17,
+		.size		= 1,
+		.flags		= UVC_CONTROL_GET_CUR,
+	},
+	{
+		.entity		= UVC_GUID_UVC_CAMERA,
+		.selector	= CT_SCANNING_MODE_CONTROL,
+		.index		= 0,
+		.size		= 1,
+		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
+				| UVC_CONTROL_RESTORE,
+	},
+	{
 		.entity		= UVC_GUID_UVC_CAMERA,
 		.selector	= CT_AE_MODE_CONTROL,
 		.index		= 1,
@@ -140,6 +210,14 @@ static struct uvc_control_info uvc_ctrls
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
+		.selector	= CT_EXPOSURE_TIME_RELATIVE_CONTROL,
+		.index		= 4,
+		.size		= 1,
+		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
+				| UVC_CONTROL_RESTORE,
+	},
+	{
+		.entity		= UVC_GUID_UVC_CAMERA,
 		.selector	= CT_FOCUS_ABSOLUTE_CONTROL,
 		.index		= 5,
 		.size		= 2,
@@ -148,42 +226,90 @@ static struct uvc_control_info uvc_ctrls
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
-		.selector	= CT_FOCUS_AUTO_CONTROL,
-		.index		= 17,
-		.size		= 1,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
-				| UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE,
+		.selector	= CT_FOCUS_RELATIVE_CONTROL,
+		.index		= 6,
+		.size		= 2,
+		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
+				| UVC_CONTROL_AUTO_UPDATE,
 	},
 	{
-		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,
-		.index		= 12,
+		.entity		= UVC_GUID_UVC_CAMERA,
+		.selector	= CT_IRIS_ABSOLUTE_CONTROL,
+		.index		= 7,
+		.size		= 2,
+		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
+				| UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
+	},
+	{
+		.entity		= UVC_GUID_UVC_CAMERA,
+		.selector	= CT_IRIS_RELATIVE_CONTROL,
+		.index		= 8,
 		.size		= 1,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
-				| UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE,
+				| UVC_CONTROL_AUTO_UPDATE,
 	},
 	{
-		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_WHITE_BALANCE_TEMPERATURE_CONTROL,
-		.index		= 6,
+		.entity		= UVC_GUID_UVC_CAMERA,
+		.selector	= CT_ZOOM_ABSOLUTE_CONTROL,
+		.index		= 9,
 		.size		= 2,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
 				| UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
 	},
 	{
-		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL,
+		.entity		= UVC_GUID_UVC_CAMERA,
+		.selector	= CT_ZOOM_RELATIVE_CONTROL,
+		.index		= 10,
+		.size		= 3,
+		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
+				| UVC_CONTROL_AUTO_UPDATE,
+	},
+	{
+		.entity		= UVC_GUID_UVC_CAMERA,
+		.selector	= CT_PANTILT_ABSOLUTE_CONTROL,
+		.index		= 11,
+		.size		= 8,
+		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
+				| UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
+	},
+	{
+		.entity		= UVC_GUID_UVC_CAMERA,
+		.selector	= CT_PANTILT_RELATIVE_CONTROL,
+		.index		= 12,
+		.size		= 4,
+		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
+				| UVC_CONTROL_AUTO_UPDATE,
+	},
+	{
+		.entity		= UVC_GUID_UVC_CAMERA,
+		.selector	= CT_ROLL_ABSOLUTE_CONTROL,
 		.index		= 13,
+		.size		= 2,
+		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
+				| UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
+	},
+	{
+		.entity		= UVC_GUID_UVC_CAMERA,
+		.selector	= CT_ROLL_RELATIVE_CONTROL,
+		.index		= 14,
+		.size		= 2,
+		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
+				| UVC_CONTROL_AUTO_UPDATE,
+	},
+	{
+		.entity		= UVC_GUID_UVC_CAMERA,
+		.selector	= CT_FOCUS_AUTO_CONTROL,
+		.index		= 17,
 		.size		= 1,
 		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
 				| UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE,
 	},
 	{
-		.entity		= UVC_GUID_UVC_PROCESSING,
-		.selector	= PU_WHITE_BALANCE_COMPONENT_CONTROL,
-		.index		= 7,
-		.size		= 4,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
+		.entity		= UVC_GUID_UVC_CAMERA,
+		.selector	= CT_PRIVACY_CONTROL,
+		.index		= 18,
+		.size		= 1,
+		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
 				| UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
 	},
 };
@@ -711,7 +837,17 @@ static int uvc_ctrl_commit_entity(struct
 
 	for (i = 0; i < entity->ncontrols; ++i) {
 		ctrl = &entity->controls[i];
-		if (ctrl->info == NULL || !ctrl->dirty)
+		if (ctrl->info == NULL)
+			continue;
+
+		/* Reset the loaded flag for auto-update controls that were
+		 * marked as loaded in uvc_ctrl_get/uvc_ctrl_set to prevent
+		 * uvc_ctrl_get from using the cached value.
+		 */
+		if (ctrl->info->flags & UVC_CONTROL_AUTO_UPDATE)
+			ctrl->loaded = 0;
+
+		if (!ctrl->dirty)
 			continue;
 
 		if (!rollback)
@@ -727,9 +863,6 @@ static int uvc_ctrl_commit_entity(struct
 			       uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
 			       ctrl->info->size);
 
-		if ((ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0)
-			ctrl->loaded = 0;
-
 		ctrl->dirty = 0;
 
 		if (ret < 0)
@@ -787,8 +920,7 @@ int uvc_ctrl_get(struct uvc_video_device
 		if (ret < 0)
 			return ret;
 
-		if ((ctrl->info->flags & UVC_CONTROL_AUTO_UPDATE) == 0)
-			ctrl->loaded = 1;
+		ctrl->loaded = 1;
 	}
 
 	xctrl->value = uvc_get_le_value(
@@ -839,8 +971,7 @@ int uvc_ctrl_set(struct uvc_video_device
 				return ret;
 		}
 
-		if ((ctrl->info->flags & UVC_CONTROL_AUTO_UPDATE) == 0)
-			ctrl->loaded = 1;
+		ctrl->loaded = 1;
 	}
 
 	if (!ctrl->dirty) {
diff -up linux-2.6.27.noarch/drivers/media/video/uvc/uvc_driver.c.uvc linux-2.6.27.noarch/drivers/media/video/uvc/uvc_driver.c
--- linux-2.6.27.noarch/drivers/media/video/uvc/uvc_driver.c.uvc	2008-10-10 00:13:53.000000000 +0200
+++ linux-2.6.27.noarch/drivers/media/video/uvc/uvc_driver.c	2008-11-19 11:24:07.000000000 +0100
@@ -32,6 +32,7 @@
 #include <linux/vmalloc.h>
 #include <linux/wait.h>
 #include <asm/atomic.h>
+#include <asm/unaligned.h>
 
 #include <media/v4l2-common.h>
 
@@ -288,8 +289,10 @@ static int uvc_parse_format(struct uvc_d
 	struct uvc_format_desc *fmtdesc;
 	struct uvc_frame *frame;
 	const unsigned char *start = buffer;
+	unsigned char *_buffer;
 	unsigned int interval;
 	unsigned int i, n;
+	int _buflen;
 	__u8 ftype;
 
 	format->type = buffer[2];
@@ -410,12 +413,20 @@ static int uvc_parse_format(struct uvc_d
 	buflen -= buffer[0];
 	buffer += buffer[0];
 
+	/* Count the number of frame descriptors to test the bFrameIndex
+	 * field when parsing the descriptors. We can't rely on the
+	 * bNumFrameDescriptors field as some cameras don't initialize it
+	 * properly.
+	 */
+	for (_buflen = buflen, _buffer = buffer;
+	     _buflen > 2 && _buffer[2] == ftype;
+	     _buflen -= _buffer[0], _buffer += _buffer[0])
+		format->nframes++;
+
 	/* Parse the frame descriptors. Only uncompressed, MJPEG and frame
 	 * based formats have frame descriptors.
 	 */
 	while (buflen > 2 && buffer[2] == ftype) {
-		frame = &format->frame[format->nframes];
-
 		if (ftype != VS_FRAME_FRAME_BASED)
 			n = buflen > 25 ? buffer[25] : 0;
 		else
@@ -430,22 +441,32 @@ static int uvc_parse_format(struct uvc_d
 			return -EINVAL;
 		}
 
+		if (buffer[3] - 1 >= format->nframes) {
+			uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
+			       "interface %d frame index %u out of range\n",
+			       dev->udev->devnum, alts->desc.bInterfaceNumber,
+			       buffer[3]);
+			return -EINVAL;
+		}
+
+		frame = &format->frame[buffer[3] - 1];
+
 		frame->bFrameIndex = buffer[3];
 		frame->bmCapabilities = buffer[4];
-		frame->wWidth = le16_to_cpup((__le16 *)&buffer[5]);
-		frame->wHeight = le16_to_cpup((__le16 *)&buffer[7]);
-		frame->dwMinBitRate = le32_to_cpup((__le32 *)&buffer[9]);
-		frame->dwMaxBitRate = le32_to_cpup((__le32 *)&buffer[13]);
+		frame->wWidth = get_unaligned_le16(&buffer[5]);
+		frame->wHeight = get_unaligned_le16(&buffer[7]);
+		frame->dwMinBitRate = get_unaligned_le32(&buffer[9]);
+		frame->dwMaxBitRate = get_unaligned_le32(&buffer[13]);
 		if (ftype != VS_FRAME_FRAME_BASED) {
 			frame->dwMaxVideoFrameBufferSize =
-				le32_to_cpup((__le32 *)&buffer[17]);
+				get_unaligned_le32(&buffer[17]);
 			frame->dwDefaultFrameInterval =
-				le32_to_cpup((__le32 *)&buffer[21]);
+				get_unaligned_le32(&buffer[21]);
 			frame->bFrameIntervalType = buffer[25];
 		} else {
 			frame->dwMaxVideoFrameBufferSize = 0;
 			frame->dwDefaultFrameInterval =
-				le32_to_cpup((__le32 *)&buffer[17]);
+				get_unaligned_le32(&buffer[17]);
 			frame->bFrameIntervalType = buffer[21];
 		}
 		frame->dwFrameInterval = *intervals;
@@ -468,7 +489,7 @@ static int uvc_parse_format(struct uvc_d
 		 * some other divisions by zero which could happen.
 		 */
 		for (i = 0; i < n; ++i) {
-			interval = le32_to_cpup((__le32 *)&buffer[26+4*i]);
+			interval = get_unaligned_le32(&buffer[26+4*i]);
 			*(*intervals)++ = interval ? interval : 1;
 		}
 
@@ -486,7 +507,6 @@ static int uvc_parse_format(struct uvc_d
 			10000000/frame->dwDefaultFrameInterval,
 			(100000000/frame->dwDefaultFrameInterval)%10);
 
-		format->nframes++;
 		buflen -= buffer[0];
 		buffer += buffer[0];
 	}
@@ -813,8 +833,7 @@ static int uvc_parse_vendor_control(stru
 		unit->type = VC_EXTENSION_UNIT;
 		memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
 		unit->extension.bNumControls = buffer[20];
-		unit->extension.bNrInPins =
-			le16_to_cpup((__le16 *)&buffer[21]);
+		unit->extension.bNrInPins = get_unaligned_le16(&buffer[21]);
 		unit->extension.baSourceID = (__u8 *)unit + sizeof *unit;
 		memcpy(unit->extension.baSourceID, &buffer[22], p);
 		unit->extension.bControlSize = buffer[22+p];
@@ -858,8 +877,8 @@ static int uvc_parse_standard_control(st
 			return -EINVAL;
 		}
 
-		dev->uvc_version = le16_to_cpup((__le16 *)&buffer[3]);
-		dev->clock_frequency = le32_to_cpup((__le32 *)&buffer[7]);
+		dev->uvc_version = get_unaligned_le16(&buffer[3]);
+		dev->clock_frequency = get_unaligned_le32(&buffer[7]);
 
 		/* Parse all USB Video Streaming interfaces. */
 		for (i = 0; i < n; ++i) {
@@ -886,7 +905,7 @@ static int uvc_parse_standard_control(st
 		/* Make sure the terminal type MSB is not null, otherwise it
 		 * could be confused with a unit.
 		 */
-		type = le16_to_cpup((__le16 *)&buffer[4]);
+		type = get_unaligned_le16(&buffer[4]);
 		if ((type & 0xff00) == 0) {
 			uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
 				"interface %d INPUT_TERMINAL %d has invalid "
@@ -928,11 +947,11 @@ static int uvc_parse_standard_control(st
 			term->camera.bControlSize = n;
 			term->camera.bmControls = (__u8 *)term + sizeof *term;
 			term->camera.wObjectiveFocalLengthMin =
-				le16_to_cpup((__le16 *)&buffer[8]);
+				get_unaligned_le16(&buffer[8]);
 			term->camera.wObjectiveFocalLengthMax =
-				le16_to_cpup((__le16 *)&buffer[10]);
+				get_unaligned_le16(&buffer[10]);
 			term->camera.wOcularFocalLength =
-				le16_to_cpup((__le16 *)&buffer[12]);
+				get_unaligned_le16(&buffer[12]);
 			memcpy(term->camera.bmControls, &buffer[15], n);
 		} else if (UVC_ENTITY_TYPE(term) == ITT_MEDIA_TRANSPORT_INPUT) {
 			term->media.bControlSize = n;
@@ -968,7 +987,7 @@ static int uvc_parse_standard_control(st
 		/* Make sure the terminal type MSB is not null, otherwise it
 		 * could be confused with a unit.
 		 */
-		type = le16_to_cpup((__le16 *)&buffer[4]);
+		type = get_unaligned_le16(&buffer[4]);
 		if ((type & 0xff00) == 0) {
 			uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
 				"interface %d OUTPUT_TERMINAL %d has invalid "
@@ -1042,7 +1061,7 @@ static int uvc_parse_standard_control(st
 		unit->type = buffer[2];
 		unit->processing.bSourceID = buffer[4];
 		unit->processing.wMaxMultiplier =
-			le16_to_cpup((__le16 *)&buffer[5]);
+			get_unaligned_le16(&buffer[5]);
 		unit->processing.bControlSize = buffer[7];
 		unit->processing.bmControls = (__u8 *)unit + sizeof *unit;
 		memcpy(unit->processing.bmControls, &buffer[8], n);
@@ -1077,8 +1096,7 @@ static int uvc_parse_standard_control(st
 		unit->type = buffer[2];
 		memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
 		unit->extension.bNumControls = buffer[20];
-		unit->extension.bNrInPins =
-			le16_to_cpup((__le16 *)&buffer[21]);
+		unit->extension.bNrInPins = get_unaligned_le16(&buffer[21]);
 		unit->extension.baSourceID = (__u8 *)unit + sizeof *unit;
 		memcpy(unit->extension.baSourceID, &buffer[22], p);
 		unit->extension.bControlSize = buffer[22+p];
@@ -1663,7 +1681,7 @@ static int uvc_suspend(struct usb_interf
 	return uvc_video_suspend(&dev->video);
 }
 
-static int uvc_resume(struct usb_interface *intf)
+static int __uvc_resume(struct usb_interface *intf, int reset)
 {
 	struct uvc_device *dev = usb_get_intfdata(intf);
 	int ret;
@@ -1672,7 +1690,7 @@ static int uvc_resume(struct usb_interfa
 		intf->cur_altsetting->desc.bInterfaceNumber);
 
 	if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOCONTROL) {
-		if ((ret = uvc_ctrl_resume_device(dev)) < 0)
+		if (reset && (ret = uvc_ctrl_resume_device(dev)) < 0)
 			return ret;
 
 		return uvc_status_resume(dev);
@@ -1687,6 +1705,16 @@ static int uvc_resume(struct usb_interfa
 	return uvc_video_resume(&dev->video);
 }
 
+static int uvc_resume(struct usb_interface *intf)
+{
+	return __uvc_resume(intf, 0);
+}
+
+static int uvc_reset_resume(struct usb_interface *intf)
+{
+	return __uvc_resume(intf, 1);
+}
+
 /* ------------------------------------------------------------------------
  * Driver initialization and cleanup
  */
@@ -1697,24 +1725,6 @@ static int uvc_resume(struct usb_interfa
  * though they are compliant.
  */
 static struct usb_device_id uvc_ids[] = {
-	/* ALi M5606 (Clevo M540SR) */
-	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
-				| USB_DEVICE_ID_MATCH_INT_INFO,
-	  .idVendor		= 0x0402,
-	  .idProduct		= 0x5606,
-	  .bInterfaceClass	= USB_CLASS_VIDEO,
-	  .bInterfaceSubClass	= 1,
-	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
-	/* Creative Live! Optia */
-	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
-				| USB_DEVICE_ID_MATCH_INT_INFO,
-	  .idVendor		= 0x041e,
-	  .idProduct		= 0x4057,
-	  .bInterfaceClass	= USB_CLASS_VIDEO,
-	  .bInterfaceSubClass	= 1,
-	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
 	/* Microsoft Lifecam NX-6000 */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1800,15 +1810,6 @@ static struct usb_device_id uvc_ids[] = 
 	  .bInterfaceSubClass   = 1,
 	  .bInterfaceProtocol   = 0,
 	  .driver_info          = UVC_QUIRK_STREAM_NO_FID },
-	/* Silicon Motion SM371 */
-	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
-				| USB_DEVICE_ID_MATCH_INT_INFO,
-	  .idVendor		= 0x090c,
-	  .idProduct		= 0xb371,
-	  .bInterfaceClass	= USB_CLASS_VIDEO,
-	  .bInterfaceSubClass	= 1,
-	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
 	/* MT6227 */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1827,6 +1828,15 @@ static struct usb_device_id uvc_ids[] = 
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
 	  .driver_info		= UVC_QUIRK_STREAM_NO_FID },
+	/* Syntek (Samsung Q310) */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x174f,
+	  .idProduct		= 0x5931,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_STREAM_NO_FID },
 	/* Asus F9SG */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1845,6 +1855,15 @@ static struct usb_device_id uvc_ids[] = 
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
 	  .driver_info		= UVC_QUIRK_STREAM_NO_FID },
+	/* Lenovo Thinkpad SL500 */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x17ef,
+	  .idProduct		= 0x480b,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_STREAM_NO_FID },
 	/* Ecamm Pico iMage */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1875,69 +1894,6 @@ static struct usb_device_id uvc_ids[] = 
 	  .bInterfaceProtocol	= 0,
 	  .driver_info		= UVC_QUIRK_PROBE_MINMAX
 				| UVC_QUIRK_IGNORE_SELECTOR_UNIT},
-	/* Acer OEM Webcam - Unknown vendor */
-	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
-				| USB_DEVICE_ID_MATCH_INT_INFO,
-	  .idVendor		= 0x5986,
-	  .idProduct		= 0x0100,
-	  .bInterfaceClass	= USB_CLASS_VIDEO,
-	  .bInterfaceSubClass	= 1,
-	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
-	/* Packard Bell OEM Webcam - Bison Electronics */
-	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
-				| USB_DEVICE_ID_MATCH_INT_INFO,
-	  .idVendor		= 0x5986,
-	  .idProduct		= 0x0101,
-	  .bInterfaceClass	= USB_CLASS_VIDEO,
-	  .bInterfaceSubClass	= 1,
-	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
-	/* Acer Crystal Eye webcam - Bison Electronics */
-	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
-				| USB_DEVICE_ID_MATCH_INT_INFO,
-	  .idVendor		= 0x5986,
-	  .idProduct		= 0x0102,
-	  .bInterfaceClass	= USB_CLASS_VIDEO,
-	  .bInterfaceSubClass	= 1,
-	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
-	/* Medion Akoya Mini E1210 - Bison Electronics */
-	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
-				| USB_DEVICE_ID_MATCH_INT_INFO,
-	  .idVendor		= 0x5986,
-	  .idProduct		= 0x0141,
-	  .bInterfaceClass	= USB_CLASS_VIDEO,
-	  .bInterfaceSubClass	= 1,
-	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
-	/* Acer OrbiCam - Bison Electronics */
-	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
-				| USB_DEVICE_ID_MATCH_INT_INFO,
-	  .idVendor		= 0x5986,
-	  .idProduct		= 0x0200,
-	  .bInterfaceClass	= USB_CLASS_VIDEO,
-	  .bInterfaceSubClass	= 1,
-	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
-	/* Bison Electronics */
-	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
-				| USB_DEVICE_ID_MATCH_INT_INFO,
-	  .idVendor		= 0x5986,
-	  .idProduct		= 0x0300,
-	  .bInterfaceClass	= USB_CLASS_VIDEO,
-	  .bInterfaceSubClass	= 1,
-	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
-	/* Clevo M570TU - Bison Electronics */
-	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
-				| USB_DEVICE_ID_MATCH_INT_INFO,
-	  .idVendor		= 0x5986,
-	  .idProduct		= 0x0303,
-	  .bInterfaceClass	= USB_CLASS_VIDEO,
-	  .bInterfaceSubClass	= 1,
-	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
 	/* Generic USB Video Class */
 	{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },
 	{}
@@ -1952,6 +1908,7 @@ struct uvc_driver uvc_driver = {
 		.disconnect	= uvc_disconnect,
 		.suspend	= uvc_suspend,
 		.resume		= uvc_resume,
+		.reset_resume	= uvc_reset_resume,
 		.id_table	= uvc_ids,
 		.supports_autosuspend = 1,
 	},
diff -up linux-2.6.27.noarch/drivers/media/video/uvc/uvc_status.c.uvc linux-2.6.27.noarch/drivers/media/video/uvc/uvc_status.c
--- linux-2.6.27.noarch/drivers/media/video/uvc/uvc_status.c.uvc	2008-10-10 00:13:53.000000000 +0200
+++ linux-2.6.27.noarch/drivers/media/video/uvc/uvc_status.c	2008-11-19 11:18:58.000000000 +0100
@@ -177,9 +177,15 @@ int uvc_status_init(struct uvc_device *d
 
 	uvc_input_init(dev);
 
+	dev->status = kzalloc(UVC_MAX_STATUS_SIZE, GFP_KERNEL);
+	if (dev->status == NULL)
+		return -ENOMEM;
+
 	dev->int_urb = usb_alloc_urb(0, GFP_KERNEL);
-	if (dev->int_urb == NULL)
+	if (dev->int_urb == NULL) {
+		kfree(dev->status);
 		return -ENOMEM;
+	}
 
 	pipe = usb_rcvintpipe(dev->udev, ep->desc.bEndpointAddress);
 
@@ -192,7 +198,7 @@ int uvc_status_init(struct uvc_device *d
 		interval = fls(interval) - 1;
 
 	usb_fill_int_urb(dev->int_urb, dev->udev, pipe,
-		dev->status, sizeof dev->status, uvc_status_complete,
+		dev->status, UVC_MAX_STATUS_SIZE, uvc_status_complete,
 		dev, interval);
 
 	return usb_submit_urb(dev->int_urb, GFP_KERNEL);
@@ -202,6 +208,7 @@ void uvc_status_cleanup(struct uvc_devic
 {
 	usb_kill_urb(dev->int_urb);
 	usb_free_urb(dev->int_urb);
+	kfree(dev->status);
 	uvc_input_cleanup(dev);
 }
 
diff -up linux-2.6.27.noarch/drivers/media/video/uvc/uvc_v4l2.c.uvc linux-2.6.27.noarch/drivers/media/video/uvc/uvc_v4l2.c
--- linux-2.6.27.noarch/drivers/media/video/uvc/uvc_v4l2.c.uvc	2008-10-10 00:13:53.000000000 +0200
+++ linux-2.6.27.noarch/drivers/media/video/uvc/uvc_v4l2.c	2008-11-19 11:19:44.000000000 +0100
@@ -252,9 +252,6 @@ static int uvc_v4l2_set_format(struct uv
 	if (ret < 0)
 		return ret;
 
-	if ((ret = uvc_set_video_ctrl(video, &probe, 0)) < 0)
-		return ret;
-
 	memcpy(&video->streaming->ctrl, &probe, sizeof probe);
 	video->streaming->cur_format = format;
 	video->streaming->cur_frame = frame;
@@ -315,10 +312,6 @@ static int uvc_v4l2_set_streamparm(struc
 	if ((ret = uvc_probe_video(video, &probe)) < 0)
 		return ret;
 
-	/* Commit the new settings. */
-	if ((ret = uvc_set_video_ctrl(video, &probe, 0)) < 0)
-		return ret;
-
 	memcpy(&video->streaming->ctrl, &probe, sizeof probe);
 
 	/* Return the actual frame period. */
@@ -845,10 +834,6 @@ static int uvc_v4l2_do_ioctl(struct inod
 		if (ret < 0)
 			return ret;
 
-		if (!(video->streaming->cur_format->flags &
-		    UVC_FMT_FLAG_COMPRESSED))
-			video->queue.flags |= UVC_QUEUE_DROP_INCOMPLETE;
-
 		rb->count = ret;
 		ret = 0;
 		break;
diff -up linux-2.6.27.noarch/drivers/media/video/uvc/uvc_video.c.uvc linux-2.6.27.noarch/drivers/media/video/uvc/uvc_video.c
--- linux-2.6.27.noarch/drivers/media/video/uvc/uvc_video.c.uvc	2008-10-10 00:13:53.000000000 +0200
+++ linux-2.6.27.noarch/drivers/media/video/uvc/uvc_video.c	2008-11-19 11:24:07.000000000 +0100
@@ -36,15 +36,22 @@ static int __uvc_query_ctrl(struct uvc_d
 {
 	__u8 type = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
 	unsigned int pipe;
-	int ret;
 
 	pipe = (query & 0x80) ? usb_rcvctrlpipe(dev->udev, 0)
 			      : usb_sndctrlpipe(dev->udev, 0);
 	type |= (query & 0x80) ? USB_DIR_IN : USB_DIR_OUT;
 
-	ret = usb_control_msg(dev->udev, pipe, query, type, cs << 8,
+	return usb_control_msg(dev->udev, pipe, query, type, cs << 8,
 			unit << 8 | intfnum, data, size, timeout);
+}
+
+int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
+			__u8 intfnum, __u8 cs, void *data, __u16 size)
+{
+	int ret;
 
+	ret = __uvc_query_ctrl(dev, query, unit, intfnum, cs, data, size,
+				UVC_CTRL_CONTROL_TIMEOUT);
 	if (ret != size) {
 		uvc_printk(KERN_ERR, "Failed to query (%u) UVC control %u "
 			"(unit %u) : %d (exp. %u).\n", query, cs, unit, ret,
@@ -55,13 +62,6 @@ static int __uvc_query_ctrl(struct uvc_d
 	return 0;
 }
 
-int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
-			__u8 intfnum, __u8 cs, void *data, __u16 size)
-{
-	return __uvc_query_ctrl(dev, query, unit, intfnum, cs, data, size,
-				UVC_CTRL_CONTROL_TIMEOUT);
-}
-
 static void uvc_fixup_buffer_size(struct uvc_video_device *video,
 	struct uvc_streaming_control *ctrl)
 {
@@ -102,8 +102,36 @@ static int uvc_get_video_ctrl(struct uvc
 	ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum,
 		probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size,
 		UVC_CTRL_STREAMING_TIMEOUT);
-	if (ret < 0)
+
+	if ((query == GET_MIN || query == GET_MAX) && ret == 2) {
+		/* Some cameras, mostly based on Bison Electronics chipsets,
+		 * answer a GET_MIN or GET_MAX request with the wCompQuality
+		 * field only.
+		 */
+		uvc_warn_once(video->dev, UVC_WARN_MINMAX, "UVC non "
+			"compliance - GET_MIN/MAX(PROBE) incorrectly "
+			"supported. Enabling workaround.\n");
+		memset(ctrl, 0, sizeof ctrl);
+		ctrl->wCompQuality = le16_to_cpup((__le16 *)data);
+		ret = 0;
+		goto out;
+	} else if (query == GET_DEF && probe == 1) {
+		/* Many cameras don't support the GET_DEF request on their
+		 * video probe control. Warn once and return, the caller will
+		 * fall back to GET_CUR.
+		 */
+		uvc_warn_once(video->dev, UVC_WARN_PROBE_DEF, "UVC non "
+			"compliance - GET_DEF(PROBE) not supported. "
+			"Enabling workaround.\n");
+		ret = -EIO;
 		goto out;
+	} else if (ret != size) {
+		uvc_printk(KERN_ERR, "Failed to query (%u) UVC %s control : "
+			"%d (exp. %u).\n", query, probe ? "probe" : "commit",
+			ret, size);
+		ret = -EIO;
+		goto out;
+	}
 
 	ctrl->bmHint = le16_to_cpup((__le16 *)&data[0]);
 	ctrl->bFormatIndex = data[2];
@@ -114,14 +142,11 @@ static int uvc_get_video_ctrl(struct uvc
 	ctrl->wCompQuality = le16_to_cpup((__le16 *)&data[12]);
 	ctrl->wCompWindowSize = le16_to_cpup((__le16 *)&data[14]);
 	ctrl->wDelay = le16_to_cpup((__le16 *)&data[16]);
-	ctrl->dwMaxVideoFrameSize =
-		le32_to_cpu(get_unaligned((__le32 *)&data[18]));
-	ctrl->dwMaxPayloadTransferSize =
-		le32_to_cpu(get_unaligned((__le32 *)&data[22]));
+	ctrl->dwMaxVideoFrameSize = get_unaligned_le32(&data[18]);
+	ctrl->dwMaxPayloadTransferSize = get_unaligned_le32(&data[22]);
 
 	if (size == 34) {
-		ctrl->dwClockFrequency =
-			le32_to_cpu(get_unaligned((__le32 *)&data[26]));
+		ctrl->dwClockFrequency = get_unaligned_le32(&data[26]);
 		ctrl->bmFramingInfo = data[30];
 		ctrl->bPreferedVersion = data[31];
 		ctrl->bMinVersion = data[32];
@@ -138,13 +163,14 @@ static int uvc_get_video_ctrl(struct uvc
 	 * Try to get the value from the format and frame descriptor.
 	 */
 	uvc_fixup_buffer_size(video, ctrl);
+	ret = 0;
 
 out:
 	kfree(data);
 	return ret;
 }
 
-int uvc_set_video_ctrl(struct uvc_video_device *video,
+static int uvc_set_video_ctrl(struct uvc_video_device *video,
 	struct uvc_streaming_control *ctrl, int probe)
 {
 	__u8 *data;
@@ -168,14 +194,11 @@ int uvc_set_video_ctrl(struct uvc_video_
 	/* Note: Some of the fields below are not required for IN devices (see
 	 * UVC spec, 4.3.1.1), but we still copy them in case support for OUT
 	 * devices is added in the future. */
-	put_unaligned(cpu_to_le32(ctrl->dwMaxVideoFrameSize),
-		(__le32 *)&data[18]);
-	put_unaligned(cpu_to_le32(ctrl->dwMaxPayloadTransferSize),
-		(__le32 *)&data[22]);
+	put_unaligned_le32(ctrl->dwMaxVideoFrameSize, &data[18]);
+	put_unaligned_le32(ctrl->dwMaxPayloadTransferSize, &data[22]);
 
 	if (size == 34) {
-		put_unaligned(cpu_to_le32(ctrl->dwClockFrequency),
-			(__le32 *)&data[26]);
+		put_unaligned_le32(ctrl->dwClockFrequency, &data[26]);
 		data[30] = ctrl->bmFramingInfo;
 		data[31] = ctrl->bPreferedVersion;
 		data[32] = ctrl->bMinVersion;
@@ -186,6 +209,12 @@ int uvc_set_video_ctrl(struct uvc_video_
 		video->streaming->intfnum,
 		probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size,
 		UVC_CTRL_STREAMING_TIMEOUT);
+	if (ret != size) {
+		uvc_printk(KERN_ERR, "Failed to set UVC %s control : "
+			"%d (exp. %u).\n", probe ? "probe" : "commit",
+			ret, size);
+		ret = -EIO;
+	}
 
 	kfree(data);
 	return ret;
@@ -252,6 +281,12 @@ done:
 	return ret;
 }
 
+int uvc_commit_video(struct uvc_video_device *video,
+	struct uvc_streaming_control *probe)
+{
+	return uvc_set_video_ctrl(video, probe, 0);
+}
+
 /* ------------------------------------------------------------------------
  * Video codecs
  */
@@ -455,7 +490,8 @@ static void uvc_video_decode_isoc(struct
 			urb->iso_frame_desc[i].actual_length - ret);
 
 		/* Process the header again. */
-		uvc_video_decode_end(video, buf, mem, ret);
+		uvc_video_decode_end(video, buf, mem,
+			urb->iso_frame_desc[i].actual_length);
 
 		if (buf->state == UVC_BUF_STATE_DONE ||
 		    buf->state == UVC_BUF_STATE_ERROR)
@@ -512,7 +548,7 @@ static void uvc_video_decode_bulk(struct
 	    video->bulk.payload_size >= video->bulk.max_payload_size) {
 		if (!video->bulk.skip_payload && buf != NULL) {
 			uvc_video_decode_end(video, buf, video->bulk.header,
-				video->bulk.header_size);
+				video->bulk.payload_size);
 			if (buf->state == UVC_BUF_STATE_DONE ||
 			    buf->state == UVC_BUF_STATE_ERROR)
 				buf = uvc_queue_next_buffer(&video->queue, buf);
@@ -655,7 +691,7 @@ static int uvc_init_video_isoc(struct uv
 	if (size > UVC_MAX_FRAME_SIZE)
 		return -EINVAL;
 
-	npackets = (size + psize - 1) / psize;
+	npackets = DIV_ROUND_UP(size, psize);
 	if (npackets > UVC_MAX_ISO_PACKETS)
 		npackets = UVC_MAX_ISO_PACKETS;
 
@@ -853,7 +889,7 @@ int uvc_video_resume(struct uvc_video_de
 
 	video->frozen = 0;
 
-	if ((ret = uvc_set_video_ctrl(video, &video->streaming->ctrl, 0)) < 0) {
+	if ((ret = uvc_commit_video(video, &video->streaming->ctrl)) < 0) {
 		uvc_queue_enable(&video->queue, 0);
 		return ret;
 	}
@@ -934,11 +970,8 @@ int uvc_video_init(struct uvc_video_devi
 			break;
 	}
 
-	/* Commit the default settings. */
 	probe->bFormatIndex = format->index;
 	probe->bFrameIndex = frame->bFrameIndex;
-	if ((ret = uvc_set_video_ctrl(video, probe, 0)) < 0)
-		return ret;
 
 	video->streaming->cur_format = format;
 	video->streaming->cur_frame = frame;
@@ -970,9 +1003,18 @@ int uvc_video_enable(struct uvc_video_de
 		return 0;
 	}
 
+	if (video->streaming->cur_format->flags & UVC_FMT_FLAG_COMPRESSED)
+		video->queue.flags &= ~UVC_QUEUE_DROP_INCOMPLETE;
+	else
+		video->queue.flags |= UVC_QUEUE_DROP_INCOMPLETE;
+
 	if ((ret = uvc_queue_enable(&video->queue, 1)) < 0)
 		return ret;
 
+	/* Commit the streaming parameters. */
+	if ((ret = uvc_commit_video(video, &video->streaming->ctrl)) < 0)
+		return ret;
+
 	return uvc_init_video(video, GFP_KERNEL);
 }
 
diff -up linux-2.6.27.noarch/drivers/media/video/uvc/uvcvideo.h.uvc linux-2.6.27.noarch/drivers/media/video/uvc/uvcvideo.h
--- linux-2.6.27.noarch/drivers/media/video/uvc/uvcvideo.h.uvc	2008-10-10 00:13:53.000000000 +0200
+++ linux-2.6.27.noarch/drivers/media/video/uvc/uvcvideo.h	2008-11-19 11:24:07.000000000 +0100
@@ -303,6 +303,8 @@ struct uvc_xu_control {
 #define UVC_MAX_FRAME_SIZE	(16*1024*1024)
 /* Maximum number of video buffers. */
 #define UVC_MAX_VIDEO_BUFFERS	32
+/* Maximum status buffer size in bytes of interrupt URB. */
+#define UVC_MAX_STATUS_SIZE	16
 
 #define UVC_CTRL_CONTROL_TIMEOUT	300
 #define UVC_CTRL_STREAMING_TIMEOUT	1000
@@ -615,6 +617,7 @@ enum uvc_device_state {
 struct uvc_device {
 	struct usb_device *udev;
 	struct usb_interface *intf;
+	unsigned long warnings;
 	__u32 quirks;
 	int intfnum;
 	char name[32];
@@ -634,7 +637,7 @@ struct uvc_device {
 	/* Status Interrupt Endpoint */
 	struct usb_host_endpoint *int_ep;
 	struct urb *int_urb;
-	__u8 status[16];
+	__u8 *status;
 	struct input_dev *input;
 
 	/* Video Streaming interfaces */
@@ -677,6 +680,9 @@ struct uvc_driver {
 #define UVC_TRACE_SUSPEND	(1 << 8)
 #define UVC_TRACE_STATUS	(1 << 9)
 
+#define UVC_WARN_MINMAX		0
+#define UVC_WARN_PROBE_DEF	1
+
 extern unsigned int uvc_trace_param;
 
 #define uvc_trace(flag, msg...) \
@@ -685,6 +691,12 @@ extern unsigned int uvc_trace_param;
 			printk(KERN_DEBUG "uvcvideo: " msg); \
 	} while (0)
 
+#define uvc_warn_once(dev, warn, msg...) \
+	do { \
+		if (!test_and_set_bit(warn, &dev->warnings)) \
+			printk(KERN_INFO "uvcvideo: " msg); \
+	} while (0)
+
 #define uvc_printk(level, msg...) \
 	printk(level "uvcvideo: " msg)
 
@@ -738,10 +750,10 @@ extern int uvc_video_resume(struct uvc_v
 extern int uvc_video_enable(struct uvc_video_device *video, int enable);
 extern int uvc_probe_video(struct uvc_video_device *video,
 		struct uvc_streaming_control *probe);
+extern int uvc_commit_video(struct uvc_video_device *video,
+		struct uvc_streaming_control *ctrl);
 extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
 		__u8 intfnum, __u8 cs, void *data, __u16 size);
-extern int uvc_set_video_ctrl(struct uvc_video_device *video,
-		struct uvc_streaming_control *ctrl, int probe);
 
 /* Status */
 extern int uvc_status_init(struct uvc_device *dev);

linux-2.6-uvc-spca525.patch:

--- NEW FILE linux-2.6-uvc-spca525.patch ---
diff -r 283b73ee3b3a linux/drivers/media/video/uvc/uvc_driver.c
--- linux/drivers/media/video/uvc/uvc_driver.c	Mon Nov 17 22:32:11 2008 +0100
+++ linux/drivers/media/video/uvc/uvc_driver.c	Wed Nov 19 00:02:56 2008 +0100
@@ -1722,7 +1722,7 @@
  */
 
 /*
- * The Logitech cameras listed below have their interface class set to
+ * Some Logitech cameras listed below have their interface class set to
  * VENDOR_SPEC because they don't announce themselves as UVC devices, even
  * though they are compliant.
  */
@@ -1745,6 +1745,15 @@
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
 	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
+	/* Logitech Quickcam OEM Dell Notebook */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x046d,
+	  .idProduct		= 0x08c0,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_DELAY_QUERY_CTRLS },
 	/* Logitech Quickcam Fusion */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1752,7 +1761,8 @@
 	  .idProduct		= 0x08c1,
 	  .bInterfaceClass	= USB_CLASS_VENDOR_SPEC,
 	  .bInterfaceSubClass	= 1,
-	  .bInterfaceProtocol	= 0 },
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_DELAY_QUERY_CTRLS },
 	/* Logitech Quickcam Orbit MP */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1760,7 +1770,8 @@
 	  .idProduct		= 0x08c2,
 	  .bInterfaceClass	= USB_CLASS_VENDOR_SPEC,
 	  .bInterfaceSubClass	= 1,
-	  .bInterfaceProtocol	= 0 },
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_DELAY_QUERY_CTRLS },
 	/* Logitech Quickcam Pro for Notebook */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1768,7 +1779,8 @@
 	  .idProduct		= 0x08c3,
 	  .bInterfaceClass	= USB_CLASS_VENDOR_SPEC,
 	  .bInterfaceSubClass	= 1,
-	  .bInterfaceProtocol	= 0 },
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_DELAY_QUERY_CTRLS },
 	/* Logitech Quickcam Pro 5000 */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1776,7 +1788,8 @@
 	  .idProduct		= 0x08c5,
 	  .bInterfaceClass	= USB_CLASS_VENDOR_SPEC,
 	  .bInterfaceSubClass	= 1,
-	  .bInterfaceProtocol	= 0 },
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_DELAY_QUERY_CTRLS },
 	/* Logitech Quickcam OEM Dell Notebook */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1784,7 +1797,8 @@
 	  .idProduct		= 0x08c6,
 	  .bInterfaceClass	= USB_CLASS_VENDOR_SPEC,
 	  .bInterfaceSubClass	= 1,
-	  .bInterfaceProtocol	= 0 },
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_DELAY_QUERY_CTRLS },
 	/* Logitech Quickcam OEM Cisco VT Camera II */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1792,7 +1806,62 @@
 	  .idProduct		= 0x08c7,
 	  .bInterfaceClass	= USB_CLASS_VENDOR_SPEC,
 	  .bInterfaceSubClass	= 1,
-	  .bInterfaceProtocol	= 0 },
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_DELAY_QUERY_CTRLS },
+	/* Logitech Quickcam Ultra Vision */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x046d,
+	  .idProduct		= 0x08c9,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_DELAY_QUERY_CTRLS },
+	/* Logitech Quickcam Fusion (2006 model) */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x046d,
+	  .idProduct		= 0x08ca,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_DELAY_QUERY_CTRLS },
+	/* Logitech Quickcam for Notebooks Pro (2006 model) */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x046d,
+	  .idProduct		= 0x08cb,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_DELAY_QUERY_CTRLS },
+	/* Logitech Quickcam Orbit/Sphere MP (2006 model) */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x046d,
+	  .idProduct		= 0x08cc,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_DELAY_QUERY_CTRLS },
+	/* Logitech Quickcam Pro 5000 (2006 model) */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x046d,
+	  .idProduct		= 0x08ce,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_DELAY_QUERY_CTRLS },
+	/* Logitech Quickcam Deluxe for Notebooks */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x046d,
+	  .idProduct		= 0x09c1,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_DELAY_QUERY_CTRLS },
 	/* Apple Built-In iSight */
 	{ .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
diff -r 283b73ee3b3a linux/drivers/media/video/uvc/uvc_video.c
--- linux/drivers/media/video/uvc/uvc_video.c	Mon Nov 17 22:32:11 2008 +0100
+++ linux/drivers/media/video/uvc/uvc_video.c	Wed Nov 19 00:02:56 2008 +0100
@@ -40,6 +40,9 @@
 	pipe = (query & 0x80) ? usb_rcvctrlpipe(dev->udev, 0)
 			      : usb_sndctrlpipe(dev->udev, 0);
 	type |= (query & 0x80) ? USB_DIR_IN : USB_DIR_OUT;
+
+	if (dev->quirks & UVC_QUIRK_DELAY_QUERY_CTRLS)
+		msleep(2);
 
 	return usb_control_msg(dev->udev, pipe, query, type, cs << 8,
 			unit << 8 | intfnum, data, size, timeout);
diff -r 283b73ee3b3a linux/drivers/media/video/uvc/uvcvideo.h
--- linux/drivers/media/video/uvc/uvcvideo.h	Mon Nov 17 22:32:11 2008 +0100
+++ linux/drivers/media/video/uvc/uvcvideo.h	Wed Nov 19 00:02:56 2008 +0100
@@ -317,6 +317,7 @@
 #define UVC_QUIRK_BUILTIN_ISIGHT	0x00000008
 #define UVC_QUIRK_STREAM_NO_FID		0x00000010
 #define UVC_QUIRK_IGNORE_SELECTOR_UNIT	0x00000020
+#define UVC_QUIRK_DELAY_QUERY_CTRLS	0x00000040
 
 /* Format flags */
 #define UVC_FMT_FLAG_COMPRESSED		0x00000001


Index: kernel.spec
===================================================================
RCS file: /cvs/extras/rpms/kernel/F-10/kernel.spec,v
retrieving revision 1.1156
retrieving revision 1.1157
diff -u -r1.1156 -r1.1157
--- kernel.spec	18 Nov 2008 23:17:49 -0000	1.1156
+++ kernel.spec	19 Nov 2008 20:29:29 -0000	1.1157
@@ -649,6 +649,9 @@
 Patch801: linux-2.6-alsa-ac97-whitelist-AD1981B.patch
 Patch802: linux-2.6-alsa-revo51-headphone.patch
 
+Patch900: linux-2.6-uvc-hg.patch
+Patch901: linux-2.6-uvc-spca525.patch
+
 Patch1101: linux-2.6-default-mmf_dump_elf_headers.patch
 Patch1515: linux-2.6.27-lirc.patch
 Patch1520: linux-2.6-hdpvr.patch
@@ -1272,6 +1275,9 @@
 
 ApplyPatch linux-2.6-alsa-revo51-headphone.patch
 
+ApplyPatch linux-2.6-uvc-hg.patch
+ApplyPatch linux-2.6-uvc-spca525.patch
+
 # build id related enhancements
 ApplyPatch linux-2.6-default-mmf_dump_elf_headers.patch
 
@@ -1929,6 +1935,10 @@
 %kernel_variant_files -k vmlinux %{with_kdump} kdump
 
 %changelog
+* Wed Nov 19 2008 Hans de Goede <hdegoede at redhat.com> 2.6.27.5-121
+- Update uvcvideo to latest git
+- Patch uvcvideo to not make older logitech cams crash (bz 472217)
+
 * Tue Nov 18 2008 Dave Jones <davej at redhat.com> 2.6.27.5-120
 - Only build the x86-64 optimised versions of aes/salsa/Twofish on 64bit.
 




More information about the fedora-extras-commits mailing list