From owner-freebsd-wireless@FreeBSD.ORG Wed May 21 15:22:17 2014 Return-Path: Delivered-To: freebsd-wireless@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id DD8D93B8; Wed, 21 May 2014 15:22:16 +0000 (UTC) Received: from mail.turbocat.net (heidi.turbocat.net [88.198.202.214]) (using TLSv1.1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 7EFB3210B; Wed, 21 May 2014 15:22:15 +0000 (UTC) Received: from laptop015.home.selasky.org (cm-176.74.213.204.customer.telag.net [176.74.213.204]) (using TLSv1 with cipher ECDHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by mail.turbocat.net (Postfix) with ESMTPSA id 558331FE026; Wed, 21 May 2014 17:22:08 +0200 (CEST) Message-ID: <537CC4CF.9030509@selasky.org> Date: Wed, 21 May 2014 17:22:55 +0200 From: Hans Petter Selasky User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:24.0) Gecko/20100101 Thunderbird/24.1.0 MIME-Version: 1.0 To: Idwer Vollering Subject: Re: if_rsu hardware causes a kernel panic on removal.. References: <537AEC79.6080406@selasky.org> <537B497E.8070701@selasky.org> <537B6F44.6070905@selasky.org> <537B9D78.3030103@selasky.org> <537C4712.908@selasky.org> In-Reply-To: Content-Type: multipart/mixed; boundary="------------070705010309030008020503" Cc: freebsd-wireless@freebsd.org, freebsd-usb@freebsd.org X-BeenThere: freebsd-wireless@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: "Discussions of 802.11 stack, tools device driver development." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 21 May 2014 15:22:17 -0000 This is a multi-part message in MIME format. --------------070705010309030008020503 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit On 05/21/14 16:23, Idwer Vollering wrote: > 2014-05-21 8:26 GMT+02:00 Hans Petter Selasky : >> Hi, >> >> Can you SVN up to: >> >> http://svnweb.freebsd.org/changeset/base/266484 >> >> at least, and compile a new kernel and modules without any additional >> patches. > > As said earlier, the only local change is 'int rsu_debug=5'. > >> Then send backtrace of any new panics. > > http://ra.openbios.org/~idwer/freebsd/core.txt.0_fbsd-current-r266496-rsu-panic-insertion > >> >> --HPS > Hi, Can you try the attached patch and report back? --HPS --------------070705010309030008020503 Content-Type: text/x-diff; name="if_rsu.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="if_rsu.diff" === ./if_rsu.c ================================================================== --- ./if_rsu.c (revision 266497) +++ ./if_rsu.c (local) @@ -128,7 +128,10 @@ static device_probe_t rsu_match; static device_attach_t rsu_attach; static device_detach_t rsu_detach; -static usb_callback_t rsu_bulk_tx_callback; +static usb_callback_t rsu_bulk_tx_callback_0; +static usb_callback_t rsu_bulk_tx_callback_1; +static usb_callback_t rsu_bulk_tx_callback_2; +static usb_callback_t rsu_bulk_tx_callback_3; static usb_callback_t rsu_bulk_rx_callback; static usb_error_t rsu_do_request(struct rsu_softc *, struct usb_device_request *, void *); @@ -241,7 +244,7 @@ .pipe_bof = 1, .force_short_xfer = 1 }, - .callback = rsu_bulk_tx_callback, + .callback = rsu_bulk_tx_callback_0, .timeout = RSU_TX_TIMEOUT }, [RSU_BULK_TX_BK] = { @@ -254,7 +257,7 @@ .pipe_bof = 1, .force_short_xfer = 1 }, - .callback = rsu_bulk_tx_callback, + .callback = rsu_bulk_tx_callback_1, .timeout = RSU_TX_TIMEOUT }, [RSU_BULK_TX_VI] = { @@ -267,7 +270,7 @@ .pipe_bof = 1, .force_short_xfer = 1 }, - .callback = rsu_bulk_tx_callback, + .callback = rsu_bulk_tx_callback_2, .timeout = RSU_TX_TIMEOUT }, [RSU_BULK_TX_VO] = { @@ -280,7 +283,7 @@ .pipe_bof = 1, .force_short_xfer = 1 }, - .callback = rsu_bulk_tx_callback, + .callback = rsu_bulk_tx_callback_3, .timeout = RSU_TX_TIMEOUT }, }; @@ -598,10 +601,13 @@ if (error != 0) return (error); - STAILQ_INIT(&sc->sc_tx_active); STAILQ_INIT(&sc->sc_tx_inactive); - STAILQ_INIT(&sc->sc_tx_pending); + for (i = 0; i != RSU_MAX_TX_EP; i++) { + STAILQ_INIT(&sc->sc_tx_active[i]); + STAILQ_INIT(&sc->sc_tx_pending[i]); + } + for (i = 0; i < RSU_TX_LIST_COUNT; i++) { STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, &sc->sc_tx[i], next); } @@ -843,10 +849,12 @@ static int rsu_fw_cmd(struct rsu_softc *sc, uint8_t code, void *buf, int len) { + const uint8_t which = RSU_BULK_TX_VO - RSU_BULK_TX_BE; struct rsu_data *data; struct r92s_tx_desc *txd; struct r92s_fw_cmd_hdr *cmd; - int cmdsz, xferlen; + int cmdsz; + int xferlen; data = rsu_getbuf(sc); if (data == NULL) @@ -879,8 +887,8 @@ DPRINTFN(2, "Tx cmd code=0x%x len=0x%x\n", code, cmdsz); data->buflen = xferlen; - STAILQ_INSERT_TAIL(&sc->sc_tx_pending, data, next); - usbd_transfer_start(sc->sc_xfer[RSU_BULK_TX_VO]); + STAILQ_INSERT_TAIL(&sc->sc_tx_pending[which], data, next); + usbd_transfer_start(sc->sc_xfer[which + RSU_BULK_TX_BE]); return (0); } @@ -1580,7 +1588,7 @@ } static void -rsu_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error) +rsu_bulk_tx_callback_sub(struct usb_xfer *xfer, usb_error_t error, uint8_t which) { struct rsu_softc *sc = usbd_xfer_softc(xfer); struct ifnet *ifp = sc->sc_ifp; @@ -1590,23 +1598,23 @@ switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: - data = STAILQ_FIRST(&sc->sc_tx_active); + data = STAILQ_FIRST(&sc->sc_tx_active[which]); if (data == NULL) goto tr_setup; DPRINTF("transfer done %p\n", data); - STAILQ_REMOVE_HEAD(&sc->sc_tx_active, next); + STAILQ_REMOVE_HEAD(&sc->sc_tx_active[which], next); rsu_txeof(xfer, data); STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next); /* FALLTHROUGH */ case USB_ST_SETUP: tr_setup: - data = STAILQ_FIRST(&sc->sc_tx_pending); + data = STAILQ_FIRST(&sc->sc_tx_pending[which]); if (data == NULL) { DPRINTF("empty pending queue sc %p\n", sc); return; } - STAILQ_REMOVE_HEAD(&sc->sc_tx_pending, next); - STAILQ_INSERT_TAIL(&sc->sc_tx_active, data, next); + STAILQ_REMOVE_HEAD(&sc->sc_tx_pending[which], next); + STAILQ_INSERT_TAIL(&sc->sc_tx_active[which], data, next); usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen); DPRINTF("submitting transfer %p\n", data); usbd_transfer_submit(xfer); @@ -1613,14 +1621,21 @@ rsu_start_locked(ifp, xfer); break; default: - data = STAILQ_FIRST(&sc->sc_tx_active); - if (data == NULL) + data = STAILQ_FIRST(&sc->sc_tx_active[which]); + if (data == NULL) { + if (error == USB_ERR_CANCELLED) + break; + + usbd_xfer_set_stall(xfer); goto tr_setup; - if (data->ni != NULL) { - ieee80211_free_node(data->ni); - data->ni = NULL; - ifp->if_oerrors++; } + + STAILQ_REMOVE_HEAD(&sc->sc_tx_active[which], next); + rsu_txeof(xfer, data); + STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next); + + ifp->if_oerrors++; + if (error != USB_ERR_CANCELLED) { usbd_xfer_set_stall(xfer); goto tr_setup; @@ -1629,6 +1644,30 @@ } } +static void +rsu_bulk_tx_callback_0(struct usb_xfer *xfer, usb_error_t error) +{ + rsu_bulk_tx_callback_sub(xfer, error, 0); +} + +static void +rsu_bulk_tx_callback_1(struct usb_xfer *xfer, usb_error_t error) +{ + rsu_bulk_tx_callback_sub(xfer, error, 1); +} + +static void +rsu_bulk_tx_callback_2(struct usb_xfer *xfer, usb_error_t error) +{ + rsu_bulk_tx_callback_sub(xfer, error, 2); +} + +static void +rsu_bulk_tx_callback_3(struct usb_xfer *xfer, usb_error_t error) +{ + rsu_bulk_tx_callback_sub(xfer, error, 3); +} + static int rsu_tx_start(struct rsu_softc *sc, struct ieee80211_node *ni, struct mbuf *m0, struct rsu_data *data, struct usb_xfer *xfer_self) @@ -1639,15 +1678,11 @@ struct ieee80211_frame *wh; struct ieee80211_key *k = NULL; struct r92s_tx_desc *txd; - struct usb_xfer *xfer; - uint8_t type, tid = 0; - int hasqos, xferlen; - struct usb_xfer *rsu_pipes[4] = { - sc->sc_xfer[RSU_BULK_TX_BE], - sc->sc_xfer[RSU_BULK_TX_BK], - sc->sc_xfer[RSU_BULK_TX_VI], - sc->sc_xfer[RSU_BULK_TX_VO] - }; + uint8_t type; + uint8_t tid = 0; + uint8_t which; + int hasqos; + int xferlen; RSU_ASSERT_LOCKED(sc); @@ -1668,12 +1703,12 @@ switch (type) { case IEEE80211_FC0_TYPE_CTL: case IEEE80211_FC0_TYPE_MGT: - xfer = sc->sc_xfer[RSU_BULK_TX_VO]; + which = RSU_BULK_TX_VO - RSU_BULK_TX_BE; break; default: KASSERT(M_WME_GETAC(m0) < 4, ("unsupported WME pipe %d", M_WME_GETAC(m0))); - xfer = rsu_pipes[M_WME_GETAC(m0)]; + which = M_WME_GETAC(m0) + RSU_BULK_TX_BE; break; } hasqos = 0; @@ -1735,10 +1770,10 @@ data->buflen = xferlen; data->ni = ni; data->m = m0; - STAILQ_INSERT_TAIL(&sc->sc_tx_pending, data, next); + STAILQ_INSERT_TAIL(&sc->sc_tx_pending[which], data, next); - if (xfer != xfer_self) - usbd_transfer_start(xfer); + if (sc->sc_xfer[which + RSU_BULK_TX_BE] != xfer_self) + usbd_transfer_start(sc->sc_xfer[which + RSU_BULK_TX_BE]); return (0); } @@ -2073,6 +2108,7 @@ static int rsu_fw_loadsection(struct rsu_softc *sc, const uint8_t *buf, int len) { + const uint8_t which = RSU_BULK_TX_VO - RSU_BULK_TX_BE; struct rsu_data *data; struct r92s_tx_desc *txd; int mlen; @@ -2093,11 +2129,11 @@ memcpy(&txd[1], buf, mlen); data->buflen = sizeof(*txd) + mlen; DPRINTF("starting transfer %p\n", data); - STAILQ_INSERT_TAIL(&sc->sc_tx_pending, data, next); + STAILQ_INSERT_TAIL(&sc->sc_tx_pending[which], data, next); buf += mlen; len -= mlen; } - usbd_transfer_start(sc->sc_xfer[RSU_BULK_TX_VO]); + usbd_transfer_start(sc->sc_xfer[RSU_BULK_TX_BE + which]); return (0); } === ./if_rsureg.h ================================================================== --- ./if_rsureg.h (revision 266497) +++ ./if_rsureg.h (local) @@ -735,6 +735,8 @@ #define RSU_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) #define RSU_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) +#define RSU_MAX_TX_EP 4 + struct rsu_softc { struct ifnet *sc_ifp; device_t sc_dev; @@ -764,9 +766,9 @@ STAILQ_HEAD(, rsu_data) sc_rx_active; STAILQ_HEAD(, rsu_data) sc_rx_inactive; - STAILQ_HEAD(, rsu_data) sc_tx_active; + STAILQ_HEAD(, rsu_data) sc_tx_active[RSU_MAX_TX_EP]; STAILQ_HEAD(, rsu_data) sc_tx_inactive; - STAILQ_HEAD(, rsu_data) sc_tx_pending; + STAILQ_HEAD(, rsu_data) sc_tx_pending[RSU_MAX_TX_EP]; union { struct rsu_rx_radiotap_header th; --------------070705010309030008020503--