USB Ethernet (aue) panics on 4.10 (kern/69319)

Scott Mitchell scott+freebsd at fishballoon.org
Mon Nov 15 12:55:29 PST 2004


On Mon, Nov 15, 2004 at 12:08:15AM +0000, Scott Mitchell wrote:
> 
> The attached patch [...]

If only I had a dollar for every time I've done that :-)

Here's the patch.

-- 
===========================================================================
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
-------------- next part --------------
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 */
 


More information about the freebsd-usb mailing list