summaryrefslogtreecommitdiff
path: root/sys/dev/usb
diff options
context:
space:
mode:
authorMarcus Glocker <mglocker@cvs.openbsd.org>2008-04-20 09:14:06 +0000
committerMarcus Glocker <mglocker@cvs.openbsd.org>2008-04-20 09:14:06 +0000
commit8c4b8a2c650d53e62db834d2550357e91a8c51d0 (patch)
treeb62672c29844b70f1fba7300fac03b31f9e6f7c2 /sys/dev/usb
parentc0fb0775f102deefbb672e0e3504e9767cf74f20 (diff)
Parse VS_INPUT_HEADER descriptor.
Diffstat (limited to 'sys/dev/usb')
-rw-r--r--sys/dev/usb/uvideo.c52
-rw-r--r--sys/dev/usb/uvideo.h8
2 files changed, 55 insertions, 5 deletions
diff --git a/sys/dev/usb/uvideo.c b/sys/dev/usb/uvideo.c
index 3a5a4854b4a..c6987988e40 100644
--- a/sys/dev/usb/uvideo.c
+++ b/sys/dev/usb/uvideo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvideo.c,v 1.10 2008/04/19 11:24:23 mglocker Exp $ */
+/* $OpenBSD: uvideo.c,v 1.11 2008/04/20 09:14:05 mglocker Exp $ */
/*
* Copyright (c) 2008 Robert Nagy <robert@openbsd.org>
@@ -68,6 +68,8 @@ int uvideo_vc_parse_desc_header(struct uvideo_softc *,
int uvideo_vs_parse_desc(struct uvideo_softc *,
struct usb_attach_arg *, usb_config_descriptor_t *);
+int uvideo_vs_parse_desc_input_header(struct uvideo_softc *,
+ const usb_descriptor_t *);
int uvideo_vs_parse_desc_format(struct uvideo_softc *);
int uvideo_vs_parse_desc_format_mjpeg(struct uvideo_softc *,
const usb_descriptor_t *);
@@ -365,7 +367,7 @@ uvideo_vc_parse_desc(struct uvideo_softc *sc)
vc_header_found = 1;
break;
- /* TODO which VC descriptors do we need else? */
+ /* TODO: which VC descriptors do we need else? */
}
desc = usb_desc_iter_next(&iter);
@@ -403,6 +405,8 @@ int
uvideo_vs_parse_desc(struct uvideo_softc *sc, struct usb_attach_arg *uaa,
usb_config_descriptor_t *cdesc)
{
+ usbd_desc_iter_t iter;
+ const usb_descriptor_t *desc;
usb_interface_descriptor_t *id;
int i, iface, numalts;
usbd_status error;
@@ -412,7 +416,27 @@ uvideo_vs_parse_desc(struct uvideo_softc *sc, struct usb_attach_arg *uaa,
DPRINTF(1, "%s: number of VS interfaces=%d\n",
DEVNAME(sc), sc->sc_desc_vc_header.fix->bInCollection);
- /* TODO: loop through general VS descriptors */
+ usb_desc_iter_init(sc->sc_udev, &iter);
+ desc = usb_desc_iter_next(&iter);
+ while (desc) {
+ if (desc->bDescriptorType != UDESC_CS_INTERFACE) {
+ desc = usb_desc_iter_next(&iter);
+ continue;
+ }
+
+ switch (desc->bDescriptorSubtype) {
+ case UDESCSUB_VS_INPUT_HEADER:
+ if (!uvideo_desc_len(desc, 13, 3, 0, 12))
+ break;
+ if (uvideo_vs_parse_desc_input_header(sc, desc) != 0)
+ return (-1);
+ break;
+
+ /* TODO: which VS descriptors do we need else? */
+ }
+
+ desc = usb_desc_iter_next(&iter);
+ }
/* parse video stream format descriptors */
error = uvideo_vs_parse_desc_format(sc);
@@ -451,6 +475,26 @@ uvideo_vs_parse_desc(struct uvideo_softc *sc, struct usb_attach_arg *uaa,
}
int
+uvideo_vs_parse_desc_input_header(struct uvideo_softc *sc,
+ const usb_descriptor_t *desc)
+{
+ struct usb_video_input_header_desc *d;
+
+ d = (struct usb_video_input_header_desc *)(uint8_t *)desc;
+
+ /* on some devices bNumFormats is larger than the truth */
+ if (d->bNumFormats == 0) {
+ printf("%s: no INPUT FORMAT descriptors found!\n", DEVNAME(sc));
+ return (-1);
+ }
+
+ sc->sc_desc_vs_input_header.fix = d;
+ sc->sc_desc_vs_input_header.bmaControls = (uByte *)(d + 1);
+
+ return (0);
+}
+
+int
uvideo_vs_parse_desc_format(struct uvideo_softc *sc)
{
usbd_desc_iter_t iter;
@@ -676,7 +720,7 @@ uvideo_desc_len(const usb_descriptor_t *desc,
size_elements = buf[off_num_elements] * size_element;
size_total = size_fix + size_elements;
- if (desc->bLength == size_total)
+ if (desc->bLength == size_total && size_elements != 0)
return (1);
return (0);
diff --git a/sys/dev/usb/uvideo.h b/sys/dev/usb/uvideo.h
index eb6a5f161a5..8bc8fc006e8 100644
--- a/sys/dev/usb/uvideo.h
+++ b/sys/dev/usb/uvideo.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvideo.h,v 1.6 2008/04/18 21:19:15 mglocker Exp $ */
+/* $OpenBSD: uvideo.h,v 1.7 2008/04/20 09:14:05 mglocker Exp $ */
/*
* Copyright (c) 2007 Robert Nagy <robert@openbsd.org>
@@ -231,6 +231,11 @@ struct usb_video_input_header_desc {
uByte bControlSize;
};
+struct usb_video_input_header_desc_all {
+ struct usb_video_input_header_desc *fix;
+ uByte *bmaControls;
+};
+
/* Table 3-18: Color Matching Descriptor */
struct usb_video_color_matching_descr {
uByte bLength;
@@ -381,6 +386,7 @@ struct uvideo_softc {
int sc_nframes;
struct usb_video_probe_commit sc_desc_probe;
struct usb_video_header_desc_all sc_desc_vc_header;
+ struct usb_video_input_header_desc_all sc_desc_vs_input_header;
struct usb_video_format_mjpeg_desc *sc_desc_format_mjpeg;
struct usb_video_frame_mjpeg_desc *sc_desc_frame_mjpeg;