On 05/21/14 16:23, Idwer Vollering wrote:
2014-05-21 8:26 GMT+02:00 Hans Petter Selasky <h...@selasky.org>:
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
=== ./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;
_______________________________________________
freebsd-wireless@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-wireless
To unsubscribe, send any mail to "freebsd-wireless-unsubscr...@freebsd.org"