1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-29 12:03:03 +00:00

urtwn(4): fix mbuf leak in the TX path

Reviewed by:	kevlo
Approved by:	adrian (mentor)
Differential Revision:	https://reviews.freebsd.org/D3988
This commit is contained in:
Andriy Voskoboinyk 2015-10-24 19:59:15 +00:00
parent 5b355b1259
commit a0226b9f2d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=289891

View File

@ -183,7 +183,8 @@ static struct mbuf * urtwn_rx_frame(struct urtwn_softc *, uint8_t *, int,
int *); int *);
static struct mbuf * urtwn_rxeof(struct usb_xfer *, struct urtwn_data *, static struct mbuf * urtwn_rxeof(struct usb_xfer *, struct urtwn_data *,
int *, int8_t *); int *, int8_t *);
static void urtwn_txeof(struct usb_xfer *, struct urtwn_data *); static void urtwn_txeof(struct urtwn_softc *, struct urtwn_data *,
int);
static int urtwn_alloc_list(struct urtwn_softc *, static int urtwn_alloc_list(struct urtwn_softc *,
struct urtwn_data[], int, int); struct urtwn_data[], int, int);
static int urtwn_alloc_rx_list(struct urtwn_softc *); static int urtwn_alloc_rx_list(struct urtwn_softc *);
@ -815,16 +816,19 @@ urtwn_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error)
} }
static void static void
urtwn_txeof(struct usb_xfer *xfer, struct urtwn_data *data) urtwn_txeof(struct urtwn_softc *sc, struct urtwn_data *data, int status)
{ {
struct urtwn_softc *sc = usbd_xfer_softc(xfer);
URTWN_ASSERT_LOCKED(sc); URTWN_ASSERT_LOCKED(sc);
/* XXX status? */
ieee80211_tx_complete(data->ni, data->m, 0); ieee80211_tx_complete(data->ni, data->m, status);
data->ni = NULL; data->ni = NULL;
data->m = NULL; data->m = NULL;
sc->sc_txtimer = 0; sc->sc_txtimer = 0;
STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next);
} }
static int static int
@ -937,8 +941,7 @@ urtwn_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
if (data == NULL) if (data == NULL)
goto tr_setup; goto tr_setup;
STAILQ_REMOVE_HEAD(&sc->sc_tx_active, next); STAILQ_REMOVE_HEAD(&sc->sc_tx_active, next);
urtwn_txeof(xfer, data); urtwn_txeof(sc, data, 0);
STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next);
/* FALLTHROUGH */ /* FALLTHROUGH */
case USB_ST_SETUP: case USB_ST_SETUP:
tr_setup: tr_setup:
@ -956,12 +959,8 @@ urtwn_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error)
data = STAILQ_FIRST(&sc->sc_tx_active); data = STAILQ_FIRST(&sc->sc_tx_active);
if (data == NULL) if (data == NULL)
goto tr_setup; goto tr_setup;
if (data->ni != NULL) { STAILQ_REMOVE_HEAD(&sc->sc_tx_active, next);
if_inc_counter(data->ni->ni_vap->iv_ifp, urtwn_txeof(sc, data, 1);
IFCOUNTER_OERRORS, 1);
ieee80211_free_node(data->ni);
data->ni = NULL;
}
if (error != USB_ERR_CANCELLED) { if (error != USB_ERR_CANCELLED) {
usbd_xfer_set_stall(xfer); usbd_xfer_set_stall(xfer);
goto tr_setup; goto tr_setup;