kern/69319: [aue] panic: aue startup panic

Scott Mitchell scott+freebsd at fishballoon.org
Tue Nov 16 13:50:33 PST 2004


The following reply was made to PR kern/69319; it has been noted by GNATS.

From: Scott Mitchell <scott+freebsd at fishballoon.org>
To: "Alexander S. Efimov" <alexe at lenta.ru>
Cc: freebsd-gnats-submit at FreeBSD.org
Subject: Re: kern/69319: [aue] panic: aue startup panic
Date: Tue, 16 Nov 2004 21:45:36 +0000

 Might as well have the patch here as well.  As I said on freebsd-usb this:
 
 - Restores the USBD_NO_TSLEEP hack (this seems to cure the panics)
 - Fixes an mbuf leak when the if_start function was called again before
   the previous mbuf had been freed.
 - Fixes ioctl handling to return EINVAL for commands that don't make sense
   for this device.  Otherwise ifconfig(8) prints a lot of irrelevant data,
   such as wireless settings.
 
 Both of my aue(4) adapters run fine with these changes.
 
 	Scott
 
 ----- cut here -----
 Index: sys/dev/usb/if_aue.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/dev/usb/if_aue.c,v
 retrieving revision 1.19.2.21
 diff -u -r1.19.2.21 if_aue.c
 --- sys/dev/usb/if_aue.c	16 Apr 2004 18:12:57 -0000	1.19.2.21
 +++ sys/dev/usb/if_aue.c	8 Aug 2004 16:26:31 -0000
 @@ -270,7 +270,8 @@
  	USETW(req.wIndex, reg);
  	USETW(req.wLength, 1);
  
 -	err = usbd_do_request(sc->aue_udev, &req, &val);
 +	err = usbd_do_request_flags(sc->aue_udev, &req,
 +	    &val, USBD_NO_TSLEEP, NULL, USBD_DEFAULT_TIMEOUT);
  
  	AUE_UNLOCK(sc);
  
 @@ -299,7 +300,8 @@
  	USETW(req.wIndex, reg);
  	USETW(req.wLength, 2);
  
 -	err = usbd_do_request(sc->aue_udev, &req, &val);
 +	err = usbd_do_request_flags(sc->aue_udev, &req,
 +	    &val, USBD_NO_TSLEEP, NULL, USBD_DEFAULT_TIMEOUT);
  
  	AUE_UNLOCK(sc);
  
 @@ -327,7 +329,8 @@
  	USETW(req.wIndex, reg);
  	USETW(req.wLength, 1);
  
 -	err = usbd_do_request(sc->aue_udev, &req, &val);
 +	err = usbd_do_request_flags(sc->aue_udev, &req,
 +	    &val, USBD_NO_TSLEEP, NULL, USBD_DEFAULT_TIMEOUT);
  
  	AUE_UNLOCK(sc);
  
 @@ -355,7 +358,8 @@
  	USETW(req.wIndex, reg);
  	USETW(req.wLength, 2);
  
 -	err = usbd_do_request(sc->aue_udev, &req, &val);
 +	err = usbd_do_request_flags(sc->aue_udev, &req,
 +	    &val, USBD_NO_TSLEEP, NULL, USBD_DEFAULT_TIMEOUT);
  
  	AUE_UNLOCK(sc);
  
 @@ -1071,6 +1075,7 @@
  	struct aue_chain	*c = priv;
  	struct aue_softc	*sc = c->aue_sc;
  	struct ifnet		*ifp;
 +	struct mbuf		*m;
  	usbd_status		err;
  
  	AUE_LOCK(sc);
 @@ -1090,13 +1095,16 @@
  	}
  
  	ifp->if_timer = 0;
 -	ifp->if_flags &= ~IFF_OACTIVE;
 +
  	usbd_get_xfer_status(c->aue_xfer, NULL, NULL, NULL, &err);
 +	m = c->aue_mbuf;
 +	c->aue_mbuf = NULL;
  
 -	if (c->aue_mbuf != NULL) {
 -		c->aue_mbuf->m_pkthdr.rcvif = ifp;
 -		usb_tx_done(c->aue_mbuf);
 -		c->aue_mbuf = NULL;
 + 	ifp->if_flags &= ~IFF_OACTIVE;
 +
 +	if (m != NULL) {
 +		m->m_pkthdr.rcvif = ifp;
 +		usb_tx_done(m);
  	}
  
  	if (err)
 @@ -1129,11 +1137,14 @@
  	}
  
  	mii_tick(mii);
 -	if (!sc->aue_link && mii->mii_media_status & IFM_ACTIVE &&
 -	    IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
 -		sc->aue_link++;
 -		if (ifp->if_snd.ifq_head != NULL)
 -			aue_start(ifp);
 +	if (!sc->aue_link) {
 +		mii_pollstat(mii);
 +		if (mii->mii_media_status & IFM_ACTIVE &&
 +		    IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
 +			sc->aue_link++;
 +			if (ifp->if_snd.ifq_head != NULL)
 +				aue_start(ifp);
 +		}
  	}
  
  	sc->aue_stat_ch = timeout(aue_tick, sc, hz);
 @@ -1391,6 +1402,11 @@
  	AUE_LOCK(sc);
  
  	switch(command) {
 +	case SIOCSIFADDR:
 +	case SIOCGIFADDR:
 +	case SIOCSIFMTU:
 +		error = ether_ioctl(ifp, command, data);
 +		break;
  	case SIOCSIFFLAGS:
  		if (ifp->if_flags & IFF_UP) {
  			if (ifp->if_flags & IFF_RUNNING &&
 @@ -1421,7 +1437,7 @@
  		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
  		break;
  	default:
 -		error = ether_ioctl(ifp, command, data);
 +		error = EINVAL;
  		break;
  	}
  
 Index: sys/dev/usb/if_cue.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/dev/usb/if_cue.c,v
 retrieving revision 1.7.2.8
 diff -u -r1.7.2.8 if_cue.c
 --- sys/dev/usb/if_cue.c	16 Apr 2004 18:12:57 -0000	1.7.2.8
 +++ sys/dev/usb/if_cue.c	8 Aug 2004 17:03:13 -0000
 @@ -174,7 +174,8 @@
  	USETW(req.wIndex, reg);
  	USETW(req.wLength, 1);
  
 -	err = usbd_do_request(sc->cue_udev, &req, &val);
 +	err = usbd_do_request_flags(sc->cue_udev, &req, &val,
 +	    USBD_NO_TSLEEP, NULL, USBD_DEFAULT_TIMEOUT);
  
  	CUE_UNLOCK(sc);
  
 @@ -202,7 +203,8 @@
  	USETW(req.wIndex, reg);
  	USETW(req.wLength, 2);
  
 -	err = usbd_do_request(sc->cue_udev, &req, &val);
 +	err = usbd_do_request_flags(sc->cue_udev, &req, &val,
 +	    USBD_NO_TSLEEP, NULL, USBD_DEFAULT_TIMEOUT);
  
  	CUE_UNLOCK(sc);
  
 @@ -229,7 +231,8 @@
  	USETW(req.wIndex, reg);
  	USETW(req.wLength, 0);
  
 -	err = usbd_do_request(sc->cue_udev, &req, NULL);
 +	err = usbd_do_request_flags(sc->cue_udev, &req, &val,
 +	    USBD_NO_TSLEEP, NULL, USBD_DEFAULT_TIMEOUT);
  
  	CUE_UNLOCK(sc);
  
 @@ -257,7 +260,8 @@
  	USETW(req.wIndex, reg);
  	USETW(req.wLength, 0);
  
 -	err = usbd_do_request(sc->cue_udev, &req, NULL);
 +	err = usbd_do_request_flags(sc->cue_udev,
 +	    &req, &val, USBD_NO_TSLEEP, NULL);
  
  	CUE_UNLOCK(sc);
  
 @@ -288,7 +292,8 @@
  	USETW(req.wIndex, addr);
  	USETW(req.wLength, len);
  
 -	err = usbd_do_request(sc->cue_udev, &req, buf);
 +	err = usbd_do_request_flags(sc->cue_udev, &req, &buf,
 +	    USBD_NO_TSLEEP, NULL, USBD_DEFAULT_TIMEOUT);
  
  	CUE_UNLOCK(sc);
  
 @@ -315,7 +320,8 @@
  	USETW(req.wIndex, 0);
  	USETW(req.wLength, ETHER_ADDR_LEN);
  
 -	err = usbd_do_request(sc->cue_udev, &req, buf);
 +	err = usbd_do_request_flags(sc->cue_udev, &req, buf,
 +	    USBD_NO_TSLEEP, NULL, USBD_DEFAULT_TIMEOUT);
  
  	CUE_UNLOCK(sc);
  
 @@ -415,7 +421,9 @@
  	USETW(req.wValue, 0);
  	USETW(req.wIndex, 0);
  	USETW(req.wLength, 0);
 -	err = usbd_do_request(sc->cue_udev, &req, NULL);
 +	err = usbd_do_request_flags(sc->cue_udev, &req, NULL,
 +	    USBD_NO_TSLEEP, NULL, USBD_DEFAULT_TIMEOUT);
 +
  	if (err)
  		printf("cue%d: reset failed\n", sc->cue_unit);
  
 @@ -780,6 +788,7 @@
  	struct cue_softc	*sc;
  	struct cue_chain	*c;
  	struct ifnet		*ifp;
 +	struct mbuf		*m;
  	usbd_status		err;
  
  	c = priv;
 @@ -801,13 +810,16 @@
  	}
  
  	ifp->if_timer = 0;
 -	ifp->if_flags &= ~IFF_OACTIVE;
 +
  	usbd_get_xfer_status(c->cue_xfer, NULL, NULL, NULL, &err);
 +	m = c->cue_mbuf;
 +	c->cue_mbuf = NULL;
  
 -	if (c->cue_mbuf != NULL) {
 -		c->cue_mbuf->m_pkthdr.rcvif = ifp;
 -		usb_tx_done(c->cue_mbuf);
 -		c->cue_mbuf = NULL;
 +	ifp->if_flags &= ~IFF_OACTIVE;
 +
 +	if (m != NULL) {
 +		m->m_pkthdr.rcvif = ifp;
 +		usb_tx_done(m);
  	}
  
  	if (err)
 @@ -1042,6 +1054,11 @@
  	CUE_LOCK(sc);
  
  	switch(command) {
 +	case SIOCSIFADDR:
 +	case SIOCGIFADDR:
 +	case SIOCSIFMTU:
 +		error = ether_ioctl(ifp, command, data);
 +		break;
  	case SIOCSIFFLAGS:
  		if (ifp->if_flags & IFF_UP) {
  			if (ifp->if_flags & IFF_RUNNING &&
 @@ -1069,7 +1086,7 @@
  		error = 0;
  		break;
  	default:
 -		error = ether_ioctl(ifp, command, data);
 +		error = EINVAL;
  		break;
  	}
  
 Index: sys/dev/usb/if_kue.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/dev/usb/if_kue.c,v
 retrieving revision 1.17.2.10
 diff -u -r1.17.2.10 if_kue.c
 --- sys/dev/usb/if_kue.c	1 Mar 2004 00:07:21 -0000	1.17.2.10
 +++ sys/dev/usb/if_kue.c	8 Aug 2004 16:29:53 -0000
 @@ -192,7 +192,7 @@
  
  	xfer = usbd_alloc_xfer(dev);
  	usbd_setup_default_xfer(xfer, dev, 0, 500000, req,
 -	    data, UGETW(req->wLength), USBD_SHORT_XFER_OK, 0);
 +	    data, UGETW(req->wLength), USBD_SHORT_XFER_OK|USBD_NO_TSLEEP, 0);
  	err = usbd_sync_transfer(xfer);
  	usbd_free_xfer(xfer);
  	return(err);
 @@ -753,6 +753,7 @@
  	struct kue_softc	*sc;
  	struct kue_chain	*c;
  	struct ifnet		*ifp;
 +	struct mbuf		*m;
  	usbd_status		err;
  
  	c = priv;
 @@ -760,8 +761,6 @@
  	KUE_LOCK(sc);
  
  	ifp = &sc->arpcom.ac_if;
 -	ifp->if_timer = 0;
 -	ifp->if_flags &= ~IFF_OACTIVE;
  
  	if (status != USBD_NORMAL_COMPLETION) {
  		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
 @@ -776,12 +775,17 @@
  		return;
  	}
  
 +	ifp->if_timer = 0;
 +
  	usbd_get_xfer_status(c->kue_xfer, NULL, NULL, NULL, &err);
 +	m = c->kue_mbuf;
 +	c->kue_mbuf = NULL;
  
 -	if (c->kue_mbuf != NULL) {
 -		c->kue_mbuf->m_pkthdr.rcvif = ifp;
 -		usb_tx_done(c->kue_mbuf);
 -		c->kue_mbuf = NULL;
 +	ifp->if_flags &= ~IFF_OACTIVE;
 +
 +	if (m != NULL) {
 +		m->m_pkthdr.rcvif = ifp;
 +		usb_tx_done(m);
  	}
  
  	if (err)
 @@ -976,6 +980,11 @@
  	KUE_LOCK(sc);
  
  	switch(command) {
 +	case SIOCSIFADDR:
 +	case SIOCGIFADDR:
 +	case SIOCSIFMTU:
 +		error = ether_ioctl(ifp, command, data);
 +		break;
  	case SIOCSIFFLAGS:
  		if (ifp->if_flags & IFF_UP) {
  			if (ifp->if_flags & IFF_RUNNING &&
 @@ -1005,7 +1014,7 @@
  		error = 0;
  		break;
  	default:
 -		error = ether_ioctl(ifp, command, data);
 +		error = EINVAL;
  		break;
  	}
  
 Index: sys/dev/usb/if_rue.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/dev/usb/if_rue.c,v
 retrieving revision 1.2.2.3
 diff -u -r1.2.2.3 if_rue.c
 --- sys/dev/usb/if_rue.c	16 Apr 2004 18:12:57 -0000	1.2.2.3
 +++ sys/dev/usb/if_rue.c	8 Aug 2004 16:29:04 -0000
 @@ -231,7 +231,8 @@
  	USETW(req.wIndex, 0);
  	USETW(req.wLength, len);
  
 -	err = usbd_do_request(sc->rue_udev, &req, buf);
 +	err = usbd_do_request_flags(sc->rue_udev, &req, buf,
 +	    USBD_NO_TSLEEP, NULL, USBD_DEFAULT_TIMEOUT);
  
  	RUE_UNLOCK(sc);
  
 @@ -261,7 +262,8 @@
  	USETW(req.wIndex, 0);
  	USETW(req.wLength, len);
  
 -	err = usbd_do_request(sc->rue_udev, &req, buf);
 +	err = usbd_do_request_flags(sc->rue_udev, &req, buf,
 +	    USBD_NO_TSLEEP, NULL, USBD_DEFAULT_TIMEOUT);
  
  	RUE_UNLOCK(sc);
  
 @@ -1008,6 +1010,7 @@
  	struct rue_chain	*c = priv;
  	struct rue_softc	*sc = c->rue_sc;
  	struct ifnet		*ifp;
 +	struct mbuf		*m;
  	usbd_status		err;
  
  	RUE_LOCK(sc);
 @@ -1028,13 +1031,16 @@
  	}
  
  	ifp->if_timer = 0;
 -	ifp->if_flags &= ~IFF_OACTIVE;
 +
  	usbd_get_xfer_status(c->rue_xfer, NULL, NULL, NULL, &err);
 +	m = c->rue_mbuf;
 +	c->rue_mbuf = NULL;
  
 -	if (c->rue_mbuf != NULL) {
 -		c->rue_mbuf->m_pkthdr.rcvif = ifp;
 -		usb_tx_done(c->rue_mbuf);
 -		c->rue_mbuf = NULL;
 +	ifp->if_flags &= ~IFF_OACTIVE;
 +
 +	if (m != NULL) {
 +		m->m_pkthdr.rcvif = ifp;
 +		usb_tx_done(m);
  	}
  
  	if (err)
 @@ -1065,11 +1071,14 @@
  	}
  
  	mii_tick(mii);
 -	if (!sc->rue_link && mii->mii_media_status & IFM_ACTIVE &&
 -	    IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
 -		sc->rue_link++;
 -		if (ifp->if_snd.ifq_head != NULL)
 -			rue_start(ifp);
 +	if (!sc->rue_link) {
 +		mii_pollstat(mii);
 +		if (mii->mii_media_status & IFM_ACTIVE &&
 +		    IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
 +			sc->rue_link++;
 +			if (ifp->if_snd.ifq_head != NULL)
 +				rue_start(ifp);
 +		}
  	}
  
  	sc->rue_stat_ch = timeout(rue_tick, sc, hz);
 @@ -1334,6 +1343,11 @@
  	RUE_LOCK(sc);
  
  	switch (command) {
 +	case SIOCSIFADDR:
 +	case SIOCGIFADDR:
 +	case SIOCSIFMTU:
 +		error = ether_ioctl(ifp, command, data);
 +		break;
  	case SIOCSIFFLAGS:
  		if (ifp->if_flags & IFF_UP) {
  			if (ifp->if_flags & IFF_RUNNING &&
 @@ -1368,7 +1382,7 @@
  		error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
  		break;
  	default:
 -		error = ether_ioctl(ifp, command, data);
 +		error = EINVAL;
  		break;
  	}
  
 Index: sys/dev/usb/usbdi.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/dev/usb/usbdi.c,v
 retrieving revision 1.34.2.10
 diff -u -r1.34.2.10 usbdi.c
 --- sys/dev/usb/usbdi.c	16 Apr 2004 18:12:58 -0000	1.34.2.10
 +++ sys/dev/usb/usbdi.c	20 Jul 2004 20:19:44 -0000
 @@ -338,8 +338,29 @@
  	s = splusb();
  	if (!xfer->done) {
  		if (pipe->device->bus->use_polling)
 -			panic("usbd_transfer: not done");
 -		tsleep(xfer, PRIBIO, "usbsyn", 0);
 +			panic("usbd_transfer: not done\n");
 +		/* XXX Temporary hack XXX */
 +		if (xfer->flags & USBD_NO_TSLEEP) {
 +			int i;
 +			usbd_bus_handle bus = pipe->device->bus;
 +			int to = xfer->timeout * 1000;
 +			DPRINTFN(2,("usbd_transfer: polling\n"));
 +			for (i = 0; i < to; i += 10) {
 +				delay(10);
 +				bus->methods->do_poll(bus);
 +				if (xfer->done)
 +					break;
 +			}
 +			DPRINTFN(2,("usbd_transfer: polling done =\n",
 +			    xfer->done));
 +			/* XXX Is this right, what about the HC timeout? */
 +			if (!xfer->done) {
 +				pipe->methods->abort(xfer);
 +				xfer->status = USBD_TIMEOUT;
 +			}
 +		} else
 +		/* XXX End hack XXX */
 +			tsleep(xfer, PRIBIO, "usbsyn", 0);
  	}
  	splx(s);
  	return (xfer->status);
 Index: sys/dev/usb/usbdi.h
 ===================================================================
 RCS file: /home/ncvs/src/sys/dev/usb/usbdi.h,v
 retrieving revision 1.21.2.4
 diff -u -r1.21.2.4 usbdi.h
 --- sys/dev/usb/usbdi.h	1 Mar 2004 00:07:23 -0000	1.21.2.4
 +++ sys/dev/usb/usbdi.h	20 Jul 2004 20:20:59 -0000
 @@ -85,6 +85,9 @@
  /* in usb.h #define USBD_SHORT_XFER_OK	0x04*/	/* allow short reads */
  #define USBD_FORCE_SHORT_XFER	0x08	/* force last short packet on write */
  
 +/* XXX Temporary hack XXX */
 +#define USBD_NO_TSLEEP		0x80	/* XXX use busy wait */
 +
  #define USBD_NO_TIMEOUT 0
  #define USBD_DEFAULT_TIMEOUT 5000 /* ms = 5 s */
 ----- cut here ----- 
 
 -- 
 ===========================================================================
 Scott Mitchell           | PGP Key ID | "Eagles may soar, but weasels
 Cambridge, England       | 0x54B171B9 |  don't get sucked into jet engines"
 scott at fishballoon.org | 0xAA775B8B |      -- Anon


More information about the freebsd-bugs mailing list