summaryrefslogtreecommitdiff
path: root/sys/dev/usb/uvideo.c
diff options
context:
space:
mode:
authorMarcus Glocker <mglocker@cvs.openbsd.org>2008-04-18 13:49:56 +0000
committerMarcus Glocker <mglocker@cvs.openbsd.org>2008-04-18 13:49:56 +0000
commit33e6f290d80464fd0dfe9845bf7e87eaaf9bdc84 (patch)
tree8f7610df45c254d5b2fa840983e86e4192a8012c /sys/dev/usb/uvideo.c
parent74ee0ea50ffd59c07ac9844b29c38c621664643f (diff)
Add a function which can identify an USB descriptor explicitly by it's
size, since the UVC spec uses different USB descriptors with the same bDescriptorSubtype ID.
Diffstat (limited to 'sys/dev/usb/uvideo.c')
-rw-r--r--sys/dev/usb/uvideo.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/sys/dev/usb/uvideo.c b/sys/dev/usb/uvideo.c
index 5242e239632..9f5396971ac 100644
--- a/sys/dev/usb/uvideo.c
+++ b/sys/dev/usb/uvideo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvideo.c,v 1.7 2008/04/16 17:18:42 mglocker Exp $ */
+/* $OpenBSD: uvideo.c,v 1.8 2008/04/18 13:49:55 mglocker Exp $ */
/*
* Copyright (c) 2008 Robert Nagy <robert@openbsd.org>
@@ -114,7 +114,7 @@ void uvideo_dump_desc_frame_mjpeg(struct uvideo_softc *,
void uvideo_dump_desc_format_mjpeg(struct uvideo_softc *,
const usb_descriptor_t *);
-int uvideo_desc_len(int, int, int);
+int uvideo_desc_len(const usb_descriptor_t *, int, int, int);
int uvideo_debug_file_open(struct uvideo_softc *);
void uvideo_debug_file_write_sample(void *);
@@ -355,6 +355,8 @@ uvideo_vc_parse_desc(struct uvideo_softc *sc)
const usb_descriptor_t *desc;
int vc_header_found;
+ DPRINTF(1, "%s: %s\n", DEVNAME(sc), __func__);
+
vc_header_found = 0;
usb_desc_iter_init(sc->sc_udev, &iter);
@@ -367,8 +369,7 @@ uvideo_vc_parse_desc(struct uvideo_softc *sc)
switch (desc->bDescriptorSubtype) {
case UDESCSUB_VC_HEADER:
- /* XXX length can vary, do better calculation */
- if (desc->bLength != 13)
+ if (!uvideo_desc_len(desc, 12, 11, 1))
break;
if (vc_header_found) {
printf("%s: too many VC_HEADERs!\n",
@@ -1105,11 +1106,13 @@ uvideo_dump_desc_all(struct uvideo_softc *sc)
case UDESCSUB_VC_HEADER:
printf("bDescriptorSubtype=0x%02x",
desc->bDescriptorSubtype);
- printf(" (UDESCSUB_VC_HEADER)\n");
- if (desc->bLength == 13) {
+ if (uvideo_desc_len(desc, 12, 11, 1)) {
+ printf(" (UDESCSUB_VC_HEADER)\n");
printf("|\n");
uvideo_dump_desc_vcheader(sc, desc);
+ break;
}
+ printf(" (unknown)\n");
break;
case UDESCSUB_VC_INPUT_TERMINAL:
printf("bDescriptorSubtype=0x%02x",
@@ -1422,24 +1425,28 @@ uvideo_dump_desc_format_mjpeg(struct uvideo_softc *sc,
* descriptors types with the same bDescriptorSubtype which makes
* it necessary to differ between those types by doing descriptor
* size dances :-(
+ *
+ * size_fix: total size of the fixed structure part
+ * off_num_elements: offset which tells the number of following elements
+ * size_element: size of a single element
*/
int
-uvideo_desc_len(int size_total, int size_fix, int size_var_element)
+uvideo_desc_len(const usb_descriptor_t *desc,
+ int size_fix, int off_num_elements, int size_element)
{
- int size_var;
+ uint8_t *buf;
+ int size_elements, size_total;
- if (size_total < size_fix)
+ if (desc->bLength < size_fix)
return (0);
- if (size_total == size_fix)
- return (1);
+ buf = (uint8_t *)desc;
- if (size_total > size_fix) {
- size_var = size_total - size_fix;
+ size_elements = buf[off_num_elements] * size_element;
+ size_total = size_fix + size_elements;
- if (size_var % size_var_element == 0)
- return (1);
- }
+ if (desc->bLength == size_total)
+ return (1);
return (0);
}