diff options
author | Kevin Lo <kevlo@cvs.openbsd.org> | 2019-07-06 13:37:10 +0000 |
---|---|---|
committer | Kevin Lo <kevlo@cvs.openbsd.org> | 2019-07-06 13:37:10 +0000 |
commit | e782b9ec4fd0db7566b41c31ef62fc54fa42c22b (patch) | |
tree | 4a5f091765690a313e131c5cddee92ed1d176db6 /sys | |
parent | 3b7c82cbf5a1f54daae7f4a3e544e347b6695e02 (diff) |
Ensure Rx/Tx resources are freed during interface stop.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/usb/if_mue.c | 59 |
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; } |