summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>2000-06-01 23:16:42 +0000
committerwpaul <wpaul@FreeBSD.org>2000-06-01 23:16:42 +0000
commit5e4b4dc43d2f189e04122d52fd724f264373e7be (patch)
tree65bbe5451d1fc2f38502e810d247f625a6a3757c /sys
parentcd07a5410ebdb7b6ba2a119cb348ff5c105e1d53 (diff)
downloadFreeBSD-src-5e4b4dc43d2f189e04122d52fd724f264373e7be.zip
FreeBSD-src-5e4b4dc43d2f189e04122d52fd724f264373e7be.tar.gz
Handle watchdog timeouts better. We can't really call the foo_init()
routines from foo_watchdog() because foo_watchdog() is called at interrupt context, and that's a no-no due to the way the USB stack is currently set up. What we do now is call the TX end of frame handler manually to clear the completed transmission, then check the send queue and send off any frames that are pending. Also turned off the interrupt pipe stuff in if_aue, since it appears to tickle a bug in the USB stack that I haven't found yet.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/usb/if_cue.c14
-rw-r--r--sys/dev/usb/if_kue.c14
2 files changed, 20 insertions, 8 deletions
diff --git a/sys/dev/usb/if_cue.c b/sys/dev/usb/if_cue.c
index 28593d3..6681517 100644
--- a/sys/dev/usb/if_cue.c
+++ b/sys/dev/usb/if_cue.c
@@ -812,9 +812,11 @@ Static void cue_txeof(xfer, priv, status)
ifp->if_flags &= ~IFF_OACTIVE;
usbd_get_xfer_status(c->cue_xfer, NULL, NULL, NULL, &err);
- c->cue_mbuf->m_pkthdr.rcvif = ifp;
- usb_tx_done(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;
+ }
if (err)
ifp->if_oerrors++;
@@ -1094,13 +1096,17 @@ Static void cue_watchdog(ifp)
struct ifnet *ifp;
{
struct cue_softc *sc;
+ struct cue_chain *c;
+ usbd_status stat;
sc = ifp->if_softc;
ifp->if_oerrors++;
printf("cue%d: watchdog timeout\n", sc->cue_unit);
- cue_init(sc);
+ c = &sc->cue_cdata.cue_tx_chain[0];
+ usbd_get_xfer_status(c->cue_xfer, NULL, NULL, NULL, &stat);
+ cue_txeof(c->cue_xfer, c, stat);
if (ifp->if_snd.ifq_head != NULL)
cue_start(ifp);
diff --git a/sys/dev/usb/if_kue.c b/sys/dev/usb/if_kue.c
index 540f517..cb6a03c 100644
--- a/sys/dev/usb/if_kue.c
+++ b/sys/dev/usb/if_kue.c
@@ -763,9 +763,11 @@ Static void kue_txeof(xfer, priv, status)
usbd_get_xfer_status(c->kue_xfer, NULL, NULL, NULL, &err);
- c->kue_mbuf->m_pkthdr.rcvif = ifp;
- usb_tx_done(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;
+ }
if (err)
ifp->if_oerrors++;
@@ -1002,13 +1004,17 @@ Static void kue_watchdog(ifp)
struct ifnet *ifp;
{
struct kue_softc *sc;
+ struct kue_chain *c;
+ usbd_status stat;
sc = ifp->if_softc;
ifp->if_oerrors++;
printf("kue%d: watchdog timeout\n", sc->kue_unit);
- kue_init(sc);
+ c = &sc->kue_cdata.kue_tx_chain[0];
+ usbd_get_xfer_status(c->kue_xfer, NULL, NULL, NULL, &stat);
+ kue_txeof(c->kue_xfer, c, stat);
if (ifp->if_snd.ifq_head != NULL)
kue_start(ifp);
OpenPOWER on IntegriCloud