summaryrefslogtreecommitdiff
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
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
-rw-r--r--sys/dev/usb/uvideo.c31
-rw-r--r--sys/dev/usb/uvideo.h5
2 files changed, 20 insertions, 16 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;
diff --git a/sys/dev/usb/uvideo.h b/sys/dev/usb/uvideo.h
index 27569cc23c1..b31c4c455cd 100644
--- a/sys/dev/usb/uvideo.h
+++ b/sys/dev/usb/uvideo.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvideo.h,v 1.44 2009/02/12 14:48:00 mglocker Exp $ */
+/* $OpenBSD: uvideo.h,v 1.45 2009/02/19 21:17:35 deraadt Exp $ */
/*
* Copyright (c) 2007 Robert Nagy <robert@openbsd.org>
@@ -554,8 +554,9 @@ struct uvideo_controls {
struct uvideo_softc {
struct device sc_dev;
- struct usb_attach_arg *sc_uaa;
usbd_device_handle sc_udev;
+ int sc_nifaces;
+ usbd_interface_handle *sc_ifaces;
struct device *sc_videodev;