summaryrefslogtreecommitdiff
path: root/sys/dev/usb/uvideo.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/usb/uvideo.c')
-rw-r--r--sys/dev/usb/uvideo.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/sys/dev/usb/uvideo.c b/sys/dev/usb/uvideo.c
index 72a28548294..f0f85b5aba8 100644
--- a/sys/dev/usb/uvideo.c
+++ b/sys/dev/usb/uvideo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvideo.c,v 1.147 2010/11/24 19:53:07 jakemsr Exp $ */
+/* $OpenBSD: uvideo.c,v 1.148 2011/01/16 22:35:29 jakemsr Exp $ */
/*
* Copyright (c) 2008 Robert Nagy <robert@openbsd.org>
@@ -468,13 +468,24 @@ uvideo_attach(struct device *parent, struct device *self, void *aux)
{
struct uvideo_softc *sc = (struct uvideo_softc *)self;
struct usb_attach_arg *uaa = aux;
+ usb_interface_descriptor_t *id;
+ int i;
sc->sc_udev = uaa->device;
sc->sc_nifaces = uaa->nifaces;
- sc->sc_ifaces = malloc(uaa->nifaces * sizeof(usbd_interface_handle),
- M_USB, M_WAITOK);
- bcopy(uaa->ifaces, sc->sc_ifaces,
- uaa->nifaces * sizeof(usbd_interface_handle));
+ /*
+ * Claim all video interfaces. Interfaces must be claimed during
+ * attach, during attach hooks is too late.
+ */
+ for (i = 0; i < sc->sc_nifaces; i++) {
+ if (usbd_iface_claimed(sc->sc_udev, i))
+ continue;
+ id = usbd_get_interface_descriptor(&sc->sc_udev->ifaces[i]);
+ if (id == NULL)
+ continue;
+ if (id->bInterfaceClass == UICLASS_VIDEO)
+ usbd_claim_iface(sc->sc_udev, i);
+ }
/* maybe the device has quirks */
sc->sc_quirk = uvideo_lookup(uaa->vendor, uaa->product);
@@ -557,8 +568,6 @@ uvideo_detach(struct device *self, int flags)
struct uvideo_softc *sc = (struct uvideo_softc *)self;
int rv = 0;
- free(sc->sc_ifaces, M_USB);
-
/* Wait for outstanding requests to complete */
usbd_delay_ms(sc->sc_udev, UVIDEO_NFRAMES_MAX);
@@ -837,12 +846,13 @@ uvideo_vs_parse_desc(struct uvideo_softc *sc, usb_config_descriptor_t *cdesc)
for (i = 0; i < sc->sc_desc_vc_header.fix->bInCollection; i++) {
iface = sc->sc_desc_vc_header.baInterfaceNr[i];
- id = usbd_get_interface_descriptor(sc->sc_ifaces[iface]);
+ id = usbd_get_interface_descriptor(&sc->sc_udev->ifaces[iface]);
if (id == NULL) {
printf("%s: can't get VS interface %d!\n",
DEVNAME(sc), iface);
return (USBD_INVAL);
}
+ usbd_claim_iface(sc->sc_udev, iface);
numalts = usbd_get_no_alts(cdesc, id->bInterfaceNumber);
@@ -1197,7 +1207,7 @@ uvideo_vs_parse_desc_alt(struct uvideo_softc *sc, int vs_nr, int iface, int numa
/* save endpoint with largest bandwidth */
if (UGETW(ed->wMaxPacketSize) > vs->psize) {
- vs->ifaceh = sc->sc_ifaces[iface];
+ vs->ifaceh = &sc->sc_udev->ifaces[iface];
vs->endpoint = ed->bEndpointAddress;
vs->numalts = numalts;
vs->curalt = id->bAlternateSetting;