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	Fri Nov 28 21:58:18 2008 +0800
@@ -545,9 +545,14 @@ static inline __u8 *uvc_ctrl_data(struct
 	return ctrl->data + id * ctrl->info->size;
 }
 
-static inline int uvc_get_bit(const __u8 *data, int bit)
+static inline int uvc_test_bit(const __u8 *data, int bit)
 {
 	return (data[bit >> 3] >> (bit & 7)) & 1;
+}
+
+static inline void uvc_clear_bit(__u8 *data, int bit)
+{
+	data[bit >> 3] &= ~(1 << (bit & 7));
 }
 
 /* Extract the bit string specified by mapping->offset and mapping->size
@@ -1308,6 +1313,51 @@ end:
 }
 
 /*
+ * Prune an entity of its bogus controls. This currently include processing
+ * unit auto controls for which no corresponding manual control is available.
+ * Such auto controls make little sense if any, and are known to crash at
+ * least the SiGma Micro webcam.
+ */
+static void
+uvc_ctrl_prune_entity(struct uvc_entity *entity)
+{
+	static const struct {
+		u8 idx_manual;
+		u8 idx_auto;
+	} blacklist[] = {
+		{ 2, 11 }, /* Hue */
+		{ 6, 12 }, /* White Balance Temperature */
+		{ 7, 13 }, /* White Balance Component */
+	};
+
+	u8 *controls;
+	unsigned int size;
+	unsigned int i;
+
+	if (UVC_ENTITY_TYPE(entity) != VC_PROCESSING_UNIT)
+		return;
+
+	controls = entity->processing.bmControls;
+	size = entity->processing.bControlSize;
+
+	for (i = 0; i < ARRAY_SIZE(blacklist); ++i) {
+		if (blacklist[i].idx_auto >= 8 * size ||
+		    blacklist[i].idx_manual >= 8 * size)
+			continue;
+
+		if (!uvc_test_bit(controls, blacklist[i].idx_auto) ||
+		     uvc_test_bit(controls, blacklist[i].idx_manual))
+			continue;
+
+		uvc_trace(UVC_TRACE_CONTROL, "Auto control %u/%u has no "
+			"matching manual control, removing it.\n", entity->id,
+			blacklist[i].idx_auto);
+
+		uvc_clear_bit(controls, blacklist[i].idx_auto);
+	}
+}
+
+/*
  * Initialize device controls.
  */
 int uvc_ctrl_init_device(struct uvc_device *dev)
@@ -1333,6 +1383,9 @@ int uvc_ctrl_init_device(struct uvc_devi
 			bControlSize = entity->camera.bControlSize;
 		}
 
+		if (dev->quirks & UVC_QUIRK_PRUNE_CONTROLS)
+			uvc_ctrl_prune_entity(entity);
+
 		for (i = 0; i < bControlSize; ++i)
 			ncontrols += hweight8(bmControls[i]);
 
@@ -1347,7 +1400,7 @@ int uvc_ctrl_init_device(struct uvc_devi
 
 		ctrl = entity->controls;
 		for (i = 0; i < bControlSize * 8; ++i) {
-			if (uvc_get_bit(bmControls, i) == 0)
+			if (uvc_test_bit(bmControls, i) == 0)
 				continue;
 
 			ctrl->entity = entity;
diff -r 62c88b326ecd linux/drivers/media/video/uvc/uvc_driver.c
--- a/linux/drivers/media/video/uvc/uvc_driver.c	Wed Nov 12 15:46:43 2008 +0100
+++ b/linux/drivers/media/video/uvc/uvc_driver.c	Fri Nov 28 21:58:19 2008 +0800
@@ -1895,7 +1895,8 @@ static struct usb_device_id uvc_ids[] = 
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
 	  .driver_info		= UVC_QUIRK_PROBE_MINMAX
-				| UVC_QUIRK_IGNORE_SELECTOR_UNIT},
+				| UVC_QUIRK_IGNORE_SELECTOR_UNIT
+				| UVC_QUIRK_PRUNE_CONTROLS },
 	/* Generic USB Video Class */
 	{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },
 	{}
diff -r 62c88b326ecd linux/drivers/media/video/uvc/uvcvideo.h
--- a/linux/drivers/media/video/uvc/uvcvideo.h	Wed Nov 12 15:46:43 2008 +0100
+++ b/linux/drivers/media/video/uvc/uvcvideo.h	Fri Nov 28 21:58:19 2008 +0800
@@ -317,6 +317,7 @@ struct uvc_xu_control {
 #define UVC_QUIRK_BUILTIN_ISIGHT	0x00000008
 #define UVC_QUIRK_STREAM_NO_FID		0x00000010
 #define UVC_QUIRK_IGNORE_SELECTOR_UNIT	0x00000020
+#define UVC_QUIRK_PRUNE_CONTROLS	0x00000040
 
 /* Format flags */
 #define UVC_FMT_FLAG_COMPRESSED		0x00000001
