Martin wrote: > panic() > destroy_dev() > ugen_destroy_devnodes() > ugen_set_config() Could you try the attached patch, to see if it fixes the panic on the second run of your program? -- Cheers, Jay http://www.evilrealms.net/ - Systems Administrator & Developer http://www.imperial.ac.uk/ - 3rd year CS student Index: sys/dev/usb/ugen.c =================================================================== RCS file: /home/ncvs/src/sys/dev/usb/ugen.c,v retrieving revision 1.81 diff -u -3 -p -r1.81 ugen.c --- sys/dev/usb/ugen.c 9 Nov 2003 09:17:22 -0000 1.81 +++ sys/dev/usb/ugen.c 27 Nov 2003 14:06:25 -0000 _at__at_ -1014,8 +1014,8 _at__at_ ugen_set_interface(struct ugen_softc *sc usbd_interface_handle iface; usb_endpoint_descriptor_t *ed; usbd_status err; - struct ugen_endpoint *sce; - u_int8_t niface, nendpt, endptno, endpt; + struct ugen_endpoint *sce, **sce_cache; + u_int8_t niface, nendpt, nendpt_cache, endptno, endpt; int dir; DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno)); _at__at_ -1033,30 +1033,47 _at__at_ ugen_set_interface(struct ugen_softc *sc if (err) return (err); -#if defined(__FreeBSD__) - /* destroy the existing devices, we remake the new ones in a moment */ - ugen_destroy_devnodes(sc); -#endif + /* store an array of endpoint descriptors to destroy if the interface + * change succeeds - these aren't available afterwards */ + sce_cache = malloc(sizeof(struct ugen_endpoint *) * nendpt, M_TEMP, + M_WAITOK); + nendpt_cache = nendpt; - /* XXX should only do this after setting new altno has succeeded */ for (endptno = 0; endptno < nendpt; endptno++) { ed = usbd_interface2endpoint_descriptor(iface,endptno); endpt = ed->bEndpointAddress; dir = UE_GET_DIR(endpt) == UE_DIR_IN ? IN : OUT; - sce = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; - sce->sc = 0; - sce->edesc = 0; - sce->iface = 0; + sce_cache[endptno] = &sc->sc_endpoints[UE_GET_ADDR(endpt)][dir]; } /* change setting */ err = usbd_set_interface(iface, altno); - if (err) + if (err) { + free(sce_cache, M_TEMP); return (err); + } err = usbd_endpoint_count(iface, &nendpt); - if (err) + if (err) { + free(sce_cache, M_TEMP); return (err); + } + +#if defined(__FreeBSD__) + /* destroy the existing devices, we remake the new ones in a moment */ + ugen_destroy_devnodes(sc); +#endif + + /* now we can clear the old interface's ugen_endpoints */ + for (endptno = 0; endptno < nendpt_cache; endptno++) { + sce = sce_cache[endptno]; + sce->sc = 0; + sce->edesc = 0; + sce->iface = 0; + } + free(sce_cache, M_TEMP); + + /* set the new interface's ugen_endpoints */ for (endptno = 0; endptno < nendpt; endptno++) { ed = usbd_interface2endpoint_descriptor(iface,endptno); endpt = ed->bEndpointAddress;Received on Thu Nov 27 2003 - 05:24:57 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:37:31 UTC