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