[PATCH] ugen_destroy_devnodes panic

Julian Elischer julian at elischer.org
Tue Jan 4 21:39:32 GMT 2005



Peter Pentchev wrote:

>Hi,
>
>I am getting reproducible panics on RELENG_5 with ugen and my camera,
>Canon PowerShot A80.  The problem seems to be that ugen_set_config()
>calls ugen_destroy_devnodes() twice, and ugen_destroy_devnodes() may get
>to operate on the same sc's and the same devs, thus calling
>destroy_dev() on an already destroyed endpoint device.  My first hunch
>was to comment out the first ugen_destroy_devnodes() call in
>ugen_set_config(), but then I realized that it might be necessary to
>make sure no one else tries to open a ugen endpoint while it is being
>marked for destruction.:
>
how does this achieve that goal?

how about seeing if you can use the version of ugen.c from -current.
this has all been reworked there.


>
>What do you think about the following patch which makes
>ugen_destroy_devnodes() zero out the dev pointer for each destroyed
>device, so that it never attempts to destroy the same device twice?  Am
>I right to think that after this routine is called, no one should use
>the device endpoint that it freed?
>
>G'luck,
>Peter
>
>Index: src/sys/dev/usb/ugen.c
>===================================================================
>RCS file: /home/ncvs/src/sys/dev/usb/ugen.c,v
>retrieving revision 1.88.2.2
>diff -u -r1.88.2.2 ugen.c
>--- src/sys/dev/usb/ugen.c	31 Dec 2004 08:01:48 -0000	1.88.2.2
>+++ src/sys/dev/usb/ugen.c	4 Jan 2005 18:20:39 -0000
>@@ -283,7 +283,7 @@
> ugen_destroy_devnodes(struct ugen_softc *sc)
> {
> 	int endptno;
>-	struct cdev *dev;
>+	struct cdev **pdev;
> 
> 	/* destroy all devices for the other (existing) endpoints as well */
> 	for (endptno = 1; endptno < USB_MAX_ENDPOINTS; endptno++) {
>@@ -298,10 +298,13 @@
> 			 * of the structs is populated.
> 			 */
> 			if (sc->sc_endpoints[endptno][IN].sc != NULL)
>-				dev = sc->sc_endpoints[endptno][IN].dev;
>+				pdev = &sc->sc_endpoints[endptno][IN].dev;
> 			else
>-				dev = sc->sc_endpoints[endptno][OUT].dev;
>-			destroy_dev(dev);
>+				pdev = &sc->sc_endpoints[endptno][OUT].dev;
>+			if (*pdev == NULL)
>+				continue;
>+			destroy_dev(*pdev);
>+			*pdev = NULL;
> 		}
> 	}
> }
>
>  
>



More information about the freebsd-usb mailing list