diff -r 62c88b326ecd linux/drivers/media/video/uvc/uvc_ctrl.c
--- a/linux/drivers/media/video/uvc/uvc_ctrl.c	Wed Nov 12 15:46:43 2008 +0100
+++ b/linux/drivers/media/video/uvc/uvc_ctrl.c	Mon Nov 17 21:54:56 2008 +0800
@@ -1204,6 +1204,82 @@ static void uvc_ctrl_add_ctrl(struct uvc
 		ctrl->info->selector, dev->udev->devpath, entity->id);
 }
 
+/* Check for auto control units in the device that don't have their
+ * corresponding control units available. This kind of auto controls
+ * are most likely a sign of broken camera firmware and should be
+ * removed to avoid complications with software using the driver. */
+static void uvc_ctrl_fixup_dev(struct uvc_device *dev)
+{
+	struct uvc_entity *entity;
+	struct uvc_control *ctrl;
+	unsigned int i;
+
+	list_for_each_entry(entity, &dev->entities, list) {
+		unsigned int has_hue = 0, has_wb_temp = 0, has_wb_comp = 0;
+
+		if (UVC_ENTITY_TYPE(entity) != VC_PROCESSING_UNIT)
+			continue;
+
+		/* First scan for all known controls that might have
+		 * corresponding auto control incorrectly defined */
+		for (i = 0; i < entity->ncontrols; ++i) {
+			ctrl = &entity->controls[i];
+
+			switch (ctrl->info->selector) {
+			case PU_HUE_CONTROL:
+				has_hue = 1;
+				break;
+			case PU_WHITE_BALANCE_TEMPERATURE_CONTROL:
+				has_wb_temp = 1;
+				break;
+			case PU_WHITE_BALANCE_COMPONENT_CONTROL:
+				has_wb_comp = 1;
+				break;
+			default:
+				break;
+			}
+		}
+
+		/* Make a second scan to find incorrect auto controls */
+		for (i = 0; i < entity->ncontrols; ++i) {
+			unsigned int remove = 0;
+
+			ctrl = &entity->controls[i];
+
+			switch (ctrl->info->selector) {
+			case PU_HUE_AUTO_CONTROL:
+				if (!has_hue)
+					remove = 1;
+				break;
+			case PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL:
+				if (!has_wb_temp)
+					remove = 1;
+				break;
+			case PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL:
+				if (!has_wb_comp)
+					remove = 1;
+				break;
+			default:
+				break;
+			}
+
+			if (!remove)
+				continue;
+
+			uvc_trace(UVC_TRACE_CONTROL, "Auto control "
+				UVC_GUID_FORMAT "/%u doesn't seem to "
+				"have matching control, removing it.\n",
+				UVC_GUID_ARGS(ctrl->info->entity),
+				ctrl->info->selector);
+
+			/* Remove the incorrect control from the list */
+			kfree(ctrl->data);
+			ctrl->info = NULL;
+			ctrl->data = NULL;
+		}
+	}
+}
+
 /*
  * Add an item to the UVC control information list, and instantiate a control
  * structure for each device that supports the control.
@@ -1365,6 +1441,7 @@ int uvc_ctrl_init_device(struct uvc_devi
 	list_for_each_entry(info, &uvc_driver.controls, list)
 		uvc_ctrl_add_ctrl(dev, info);
 
+	uvc_ctrl_fixup_dev(dev);
 	list_add_tail(&dev->list, &uvc_driver.devices);
 	mutex_unlock(&uvc_driver.ctrl_mutex);
 
