In case we have a temporary loss of connection in umb(4), the USB xfers
may time-out. umb_txeof() should always check whether there are further
mbufs in the if_snd queue; not only after successful transmits.
Also, aborting the xfer in case the watchdog timer triggers, can help
to resume from hanging transmits.
To test this fix, flood ping via umb(4) and then move somewhere where
there's no reception. Ping will start spitting out "No buffer space
available" errors after some time. Now go back to where there's
reception. Without this fix, the ping errors will continue (because
umb_start() isn't called anymore). With this fix, they'll go away.
Gerhard
Index: if_umb.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_umb.c,v
retrieving revision 1.16
diff -u -p -r1.16 if_umb.c
--- if_umb.c 20 Oct 2017 09:35:09 -0000 1.16
+++ if_umb.c 23 Oct 2017 08:28:21 -0000
@@ -896,7 +896,7 @@ umb_watchdog(struct ifnet *ifp)
ifp->if_oerrors++;
printf("%s: watchdog timeout\n", DEVNAM(sc));
- /* XXX FIXME: re-initialize device */
+ usbd_abort_pipe(sc->sc_tx_pipe);
return;
}
@@ -1845,10 +1845,9 @@ umb_txeof(struct usbd_xfer *xfer, void *
if (status == USBD_STALLED)
usbd_clear_endpoint_stall_async(sc->sc_tx_pipe);
}
- } else {
- if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
- umb_start(ifp);
}
+ if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
+ umb_start(ifp);
splx(s);
}