Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 28 Nov 2003 13:43:38 +0000
From:      Jay Cornwall <jay@evilrealms.net>
To:        Martin <nakal@web.de>
Cc:        freebsd-current@freebsd.org
Subject:   Re: Panic with ugen
Message-ID:  <3FC7510A.8070906@evilrealms.net>
In-Reply-To: <1069958220.817.6.camel@klotz.local>
References:  <1069874342.704.18.camel@klotz.local> <1069888991.2521.7.camel@klotz.local>	<3FC60935.3050604@evilrealms.net> <1069958220.817.6.camel@klotz.local>

next in thread | previous in thread | raw e-mail | index | archive | help
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--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3FC7510A.8070906>