summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Lo <kevlo@cvs.openbsd.org>2019-07-06 13:37:10 +0000
committerKevin Lo <kevlo@cvs.openbsd.org>2019-07-06 13:37:10 +0000
commite782b9ec4fd0db7566b41c31ef62fc54fa42c22b (patch)
tree4a5f091765690a313e131c5cddee92ed1d176db6
parent3b7c82cbf5a1f54daae7f4a3e544e347b6695e02 (diff)
Ensure Rx/Tx resources are freed during interface stop.
-rw-r--r--sys/dev/usb/if_mue.c59
1 files changed, 58 insertions, 1 deletions
diff --git a/sys/dev/usb/if_mue.c b/sys/dev/usb/if_mue.c
index 2f9e3777f6e..75e6efa2d91 100644
--- a/sys/dev/usb/if_mue.c
+++ b/sys/dev/usb/if_mue.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_mue.c,v 1.5 2018/09/19 07:47:54 mestre Exp $ */
+/* $OpenBSD: if_mue.c,v 1.6 2019/07/06 13:37:09 kevlo Exp $ */
/*
* Copyright (c) 2018 Kevin Lo <kevlo@openbsd.org>
@@ -1339,6 +1339,8 @@ void
mue_stop(struct mue_softc *sc)
{
struct ifnet *ifp;
+ usbd_status err;
+ int i;
ifp = GET_IFP(sc);
ifp->if_timer = 0;
@@ -1347,6 +1349,61 @@ mue_stop(struct mue_softc *sc)
timeout_del(&sc->mue_stat_ch);
+ /* Stop transfers. */
+ if (sc->mue_ep[MUE_ENDPT_RX] != NULL) {
+ usbd_abort_pipe(sc->mue_ep[MUE_ENDPT_RX]);
+ err = usbd_close_pipe(sc->mue_ep[MUE_ENDPT_RX]);
+ if (err) {
+ printf("%s: close rx pipe failed: %s\n",
+ sc->mue_dev.dv_xname, usbd_errstr(err));
+ }
+ sc->mue_ep[MUE_ENDPT_RX] = NULL;
+ }
+
+ if (sc->mue_ep[MUE_ENDPT_TX] != NULL) {
+ usbd_abort_pipe(sc->mue_ep[MUE_ENDPT_TX]);
+ err = usbd_close_pipe(sc->mue_ep[MUE_ENDPT_TX]);
+ if (err) {
+ printf("%s: close tx pipe failed: %s\n",
+ sc->mue_dev.dv_xname, usbd_errstr(err));
+ }
+ sc->mue_ep[MUE_ENDPT_TX] = NULL;
+ }
+
+ if (sc->mue_ep[MUE_ENDPT_INTR] != NULL) {
+ usbd_abort_pipe(sc->mue_ep[MUE_ENDPT_INTR]);
+ err = usbd_close_pipe(sc->mue_ep[MUE_ENDPT_INTR]);
+ if (err) {
+ printf("%s: close intr pipe failed: %s\n",
+ sc->mue_dev.dv_xname, usbd_errstr(err));
+ }
+ sc->mue_ep[MUE_ENDPT_INTR] = NULL;
+ }
+
+ /* Free RX resources. */
+ for (i = 0; i < MUE_RX_LIST_CNT; i++) {
+ if (sc->mue_cdata.mue_rx_chain[i].mue_mbuf != NULL) {
+ m_freem(sc->mue_cdata.mue_rx_chain[i].mue_mbuf);
+ sc->mue_cdata.mue_rx_chain[i].mue_mbuf = NULL;
+ }
+ if (sc->mue_cdata.mue_rx_chain[i].mue_xfer != NULL) {
+ usbd_free_xfer(sc->mue_cdata.mue_rx_chain[i].mue_xfer);
+ sc->mue_cdata.mue_rx_chain[i].mue_xfer = NULL;
+ }
+ }
+
+ /* Free TX resources. */
+ for (i = 0; i < MUE_TX_LIST_CNT; i++) {
+ if (sc->mue_cdata.mue_tx_chain[i].mue_mbuf != NULL) {
+ m_freem(sc->mue_cdata.mue_tx_chain[i].mue_mbuf);
+ sc->mue_cdata.mue_tx_chain[i].mue_mbuf = NULL;
+ }
+ if (sc->mue_cdata.mue_tx_chain[i].mue_xfer != NULL) {
+ usbd_free_xfer(sc->mue_cdata.mue_tx_chain[i].mue_xfer);
+ sc->mue_cdata.mue_tx_chain[i].mue_xfer = NULL;
+ }
+ }
+
sc->mue_link = 0;
}