summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/usb/usb_quirks.c6
-rw-r--r--sys/dev/usb/uvideo.c20
2 files changed, 24 insertions, 2 deletions
diff --git a/sys/dev/usb/usb_quirks.c b/sys/dev/usb/usb_quirks.c
index f2c4a248cae..39c2068ab53 100644
--- a/sys/dev/usb/usb_quirks.c
+++ b/sys/dev/usb/usb_quirks.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: usb_quirks.c,v 1.43 2008/06/29 10:04:15 yuo Exp $ */
+/* $OpenBSD: usb_quirks.c,v 1.44 2008/07/22 16:24:40 mglocker Exp $ */
/* $NetBSD: usb_quirks.c,v 1.45 2003/05/10 17:47:14 hamajima Exp $ */
/* $FreeBSD: src/sys/dev/usb/usb_quirks.c,v 1.30 2003/01/02 04:15:55 imp Exp $ */
@@ -148,6 +148,10 @@ const struct usbd_quirk_entry {
{ USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_SISPM_OLD, ANY, { UQ_BAD_HID }},
{ USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_SISPM, ANY, { UQ_BAD_HID }},
{ USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_SISPM_FLASH, ANY, { UQ_BAD_HID }},
+
+/* devices which are UVC compatible (uvideo) but don't set UDCLASS_VIDEO */
+{ USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMOEM_1,
+ ANY, { UQ_EHCI_NEEDTO_DISOWN }},
{ 0, 0, 0, { 0 } }
};
diff --git a/sys/dev/usb/uvideo.c b/sys/dev/usb/uvideo.c
index 4eb441fdbb9..9c55488efbf 100644
--- a/sys/dev/usb/uvideo.c
+++ b/sys/dev/usb/uvideo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvideo.c,v 1.58 2008/07/22 11:02:17 mglocker Exp $ */
+/* $OpenBSD: uvideo.c,v 1.59 2008/07/22 16:24:40 mglocker Exp $ */
/*
* Copyright (c) 2008 Robert Nagy <robert@openbsd.org>
@@ -287,6 +287,19 @@ uvideo_close(void *addr)
return (0);
}
+/*
+ * Some devices do not report themselfs as UVC compatible although
+ * they are. They report UICLASS_VENDOR in the bInterfaceClass
+ * instead of UICLASS_VIDEO. Give those devices a chance to attach
+ * by looking up their USB ID.
+ *
+ * If the device also doesn't set UDCLASS_VIDEO you need to add an
+ * entry in usb_quirks.c, too, so the ehci disown works.
+ */
+static const struct usb_devno uvideo_quirk_devs [] = {
+ { USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_QUICKCAMOEM_1 }
+};
+
int
uvideo_match(struct device *parent, void *match, void *aux)
{
@@ -304,6 +317,11 @@ uvideo_match(struct device *parent, void *match, void *aux)
id->bInterfaceSubClass == UISUBCLASS_VIDEOCONTROL)
return (UMATCH_VENDOR_PRODUCT_CONF_IFACE);
+ if (usb_lookup(uvideo_quirk_devs, uaa->vendor, uaa->product) != NULL &&
+ id->bInterfaceClass == UICLASS_VENDOR &&
+ id->bInterfaceSubClass == UISUBCLASS_VIDEOCONTROL)
+ return (UMATCH_VENDOR_PRODUCT_CONF_IFACE);
+
return (UMATCH_NONE);
}