summaryrefslogtreecommitdiff
path: root/sys/dev/usb/uvideo.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2009-02-19 21:17:36 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2009-02-19 21:17:36 +0000
commit41ff3e4af344f1bb0731d24d2df8752d6621ebd1 (patch)
tree4290cfd3ca2e0d01a44449d9f7e7284682088110 /sys/dev/usb/uvideo.c
parent748c385494ee5d641b7e648df28568538e41467c (diff)
the uaa structure (and things it points, for instance ifaces) is only
alive during match and attach. do not attempt to reuse this pointer or ifaces during a deferred attach routine, since it will contain junk, but instead make copies. tested on all 3 kinds of uvideo's (ricoh fw load, apple fw load, and the rest) ok robert mglocker
Diffstat (limited to 'sys/dev/usb/uvideo.c')
-rw-r--r--sys/dev/usb/uvideo.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/sys/dev/usb/uvideo.c b/sys/dev/usb/uvideo.c
index 634b9c4a8cf..f653170165e 100644
--- a/sys/dev/usb/uvideo.c
+++ b/sys/dev/usb/uvideo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvideo.c,v 1.115 2009/02/06 14:24:44 mglocker Exp $ */
+/* $OpenBSD: uvideo.c,v 1.116 2009/02/19 21:17:34 deraadt Exp $ */
/*
* Copyright (c) 2008 Robert Nagy <robert@openbsd.org>
@@ -80,7 +80,7 @@ usbd_status uvideo_vc_set_ctrl(struct uvideo_softc *, uint8_t *, uint8_t,
int uvideo_find_ctrl(struct uvideo_softc *, int);
usbd_status uvideo_vs_parse_desc(struct uvideo_softc *,
- struct usb_attach_arg *, usb_config_descriptor_t *);
+ usb_config_descriptor_t *);
usbd_status uvideo_vs_parse_desc_input_header(struct uvideo_softc *,
const usb_descriptor_t *);
usbd_status uvideo_vs_parse_desc_format(struct uvideo_softc *);
@@ -93,8 +93,7 @@ usbd_status uvideo_vs_parse_desc_frame_mjpeg(struct uvideo_softc *,
const usb_descriptor_t *);
usbd_status uvideo_vs_parse_desc_frame_uncompressed(struct uvideo_softc *,
const usb_descriptor_t *);
-usbd_status uvideo_vs_parse_desc_alt(struct uvideo_softc *,
- struct usb_attach_arg *uaa, int, int, int);
+usbd_status uvideo_vs_parse_desc_alt(struct uvideo_softc *, int, int, int);
usbd_status uvideo_vs_set_alt(struct uvideo_softc *, usbd_interface_handle,
int);
int uvideo_desc_len(const usb_descriptor_t *, int, int, int, int);
@@ -394,8 +393,12 @@ uvideo_attach(struct device *parent, struct device *self, void *aux)
struct uvideo_softc *sc = (struct uvideo_softc *)self;
struct usb_attach_arg *uaa = aux;
- sc->sc_uaa = uaa;
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));
/* maybe the device has quirks */
sc->sc_quirk = uvideo_lookup(uaa->vendor, uaa->product);
@@ -447,7 +450,7 @@ uvideo_attach_hook(void *arg)
return;
/* parse video stream descriptors */
- error = uvideo_vs_parse_desc(sc, sc->sc_uaa, cdesc);
+ error = uvideo_vs_parse_desc(sc, cdesc);
if (error != USBD_NORMAL_COMPLETION)
return;
@@ -478,6 +481,8 @@ 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);
@@ -703,8 +708,7 @@ uvideo_find_ctrl(struct uvideo_softc *sc, int id)
}
usbd_status
-uvideo_vs_parse_desc(struct uvideo_softc *sc, struct usb_attach_arg *uaa,
- usb_config_descriptor_t *cdesc)
+uvideo_vs_parse_desc(struct uvideo_softc *sc, usb_config_descriptor_t *cdesc)
{
usbd_desc_iter_t iter;
const usb_descriptor_t *desc;
@@ -713,7 +717,7 @@ uvideo_vs_parse_desc(struct uvideo_softc *sc, struct usb_attach_arg *uaa,
usbd_status error;
DPRINTF(1, "%s: number of total interfaces=%d\n",
- DEVNAME(sc), uaa->nifaces);
+ DEVNAME(sc), sc->sc_nifaces);
DPRINTF(1, "%s: number of VS interfaces=%d\n",
DEVNAME(sc), sc->sc_desc_vc_header.fix->bInCollection);
@@ -754,7 +758,7 @@ uvideo_vs_parse_desc(struct uvideo_softc *sc, struct usb_attach_arg *uaa,
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(uaa->ifaces[iface]);
+ id = usbd_get_interface_descriptor(sc->sc_ifaces[iface]);
if (id == NULL) {
printf("%s: can't get VS interface %d!\n",
DEVNAME(sc), iface);
@@ -767,7 +771,7 @@ uvideo_vs_parse_desc(struct uvideo_softc *sc, struct usb_attach_arg *uaa,
DPRINTF(1, "bInterfaceNumber=0x%02x, numalts=%d\n",
id->bInterfaceNumber, numalts);
- error = uvideo_vs_parse_desc_alt(sc, uaa, i, iface, numalts);
+ error = uvideo_vs_parse_desc_alt(sc, i, iface, numalts);
if (error != USBD_NORMAL_COMPLETION)
return (error);
}
@@ -1049,8 +1053,7 @@ uvideo_vs_parse_desc_frame_uncompressed(struct uvideo_softc *sc,
}
usbd_status
-uvideo_vs_parse_desc_alt(struct uvideo_softc *sc, struct usb_attach_arg *uaa,
- int vs_nr, int iface, int numalts)
+uvideo_vs_parse_desc_alt(struct uvideo_softc *sc, int vs_nr, int iface, int numalts)
{
struct uvideo_vs_iface *vs;
usbd_desc_iter_t iter;
@@ -1098,7 +1101,7 @@ uvideo_vs_parse_desc_alt(struct uvideo_softc *sc, struct usb_attach_arg *uaa,
/* save endpoint with largest bandwidth */
if (UGETW(ed->wMaxPacketSize) > vs->psize) {
- vs->ifaceh = uaa->ifaces[iface];
+ vs->ifaceh = sc->sc_ifaces[iface];
vs->endpoint = ed->bEndpointAddress;
vs->numalts = numalts;
vs->curalt = id->bAlternateSetting;