From owner-freebsd-current@FreeBSD.ORG Fri Nov 28 05:42:49 2003 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2666516A4CE for ; Fri, 28 Nov 2003 05:42:49 -0800 (PST) Received: from duck.doc.ic.ac.uk (duck.doc.ic.ac.uk [146.169.1.46]) by mx1.FreeBSD.org (Postfix) with ESMTP id 74ED943FAF for ; Fri, 28 Nov 2003 05:42:47 -0800 (PST) (envelope-from jay@evilrealms.net) Received: from wavelan2.dynip.doc.ic.ac.uk ([146.169.25.27] helo=evilrealms.net) by duck.doc.ic.ac.uk with esmtp (Exim 3.16 #7) id 1APitS-0002ci-00; Fri, 28 Nov 2003 13:42:46 +0000 Message-ID: <3FC7510A.8070906@evilrealms.net> Date: Fri, 28 Nov 2003 13:43:38 +0000 From: Jay Cornwall User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.5) Gecko/20031014 Thunderbird/0.3 X-Accept-Language: en-us, en MIME-Version: 1.0 To: Martin References: <1069874342.704.18.camel@klotz.local> <1069888991.2521.7.camel@klotz.local> <3FC60935.3050604@evilrealms.net> <1069958220.817.6.camel@klotz.local> In-Reply-To: <1069958220.817.6.camel@klotz.local> Content-Type: multipart/mixed; boundary="------------070301080009050508000506" cc: freebsd-current@freebsd.org Subject: Re: Panic with ugen X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 28 Nov 2003 13:42:49 -0000 This is a multi-part message in MIME format. --------------070301080009050508000506 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Martin wrote: >>Could you try the attached patch, to see if it fixes the panic on the second >>run of your program? > No success. Still same panic. Oops, my bad. I misread your backtrace, and fixed a similar bug in ugen_set_interface rather than ugen_set_config. Could you try the attached patch (rm -f sys/dev/usb/ugen.c, cvs up sys/dev/usb/ugen.c, patch ...) to see if it alleviates the panic? It should at least give a more specific panic, if it doesn't fix the problem. -- Cheers, Jay http://www.imperial.ac.uk/ - 3rd year CS student --------------070301080009050508000506 Content-Type: text/plain; name="ugen-panic.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ugen-panic.patch" 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 28 Nov 2003 13:36:27 -0000 @@ -322,10 +322,6 @@ ugen_set_config(struct ugen_softc *sc, i DPRINTFN(1,("ugen_set_config: %s to configno %d, sc=%p\n", USBDEVNAME(sc->sc_dev), configno, sc)); -#if defined(__FreeBSD__) - ugen_destroy_devnodes(sc); -#endif - /* We start at 1, not 0, because we don't care whether the * control endpoint is open or not. It is always present. */ @@ -347,15 +343,22 @@ ugen_set_config(struct ugen_softc *sc, i err = usbd_interface_count(dev, &niface); if (err) return (err); + +#if defined(__FreeBSD__) + ugen_destroy_devnodes(sc); +#endif + memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints); for (ifaceno = 0; ifaceno < niface; ifaceno++) { DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno)); err = usbd_device2interface_handle(dev, ifaceno, &iface); - if (err) - return (err); + if (err) { + panic("ugen_set_config: can't obtain interface handle"); + } err = usbd_endpoint_count(iface, &nendpt); - if (err) - return (err); + if (err) { + panic("ugen_set_config: endpoint count failed"); + } for (endptno = 0; endptno < nendpt; endptno++) { ed = usbd_interface2endpoint_descriptor(iface,endptno); endpt = ed->bEndpointAddress; @@ -1014,8 +1017,8 @@ 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)); @@ -1033,30 +1036,46 @@ 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) - return (err); + if (err) { + panic("ugen_set_interface: endpoint count failed"); + } + +#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; --------------070301080009050508000506--