PERFORCE change 163629 for review
Andrew Thompson
thompsa at FreeBSD.org
Sat Jun 6 04:34:13 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=163629
Change 163629 by thompsa at thompsa_burger on 2009/06/06 04:33:41
- Use multiple urbs for tx and rx
- Use urb list functions
Affected files ...
.. //depot/projects/usb_buf/src/sys/dev/usb/wlan/if_rum.c#9 edit
.. //depot/projects/usb_buf/src/sys/dev/usb/wlan/if_rumvar.h#5 edit
Differences ...
==== //depot/projects/usb_buf/src/sys/dev/usb/wlan/if_rum.c#9 (text+ko) ====
@@ -387,6 +387,7 @@
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_OUT,
.bufsize = (MCLBYTES + RT2573_TX_DESC_SIZE + 8),
+ .urb_count = RUM_TX_LIST_COUNT,
.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
.callback = rum_bulk_write_callback,
.timeout = 5000, /* ms */
@@ -396,6 +397,7 @@
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
.bufsize = (MCLBYTES + RT2573_RX_DESC_SIZE),
+ .urb_count = RUM_RX_LIST_COUNT,
.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
.callback = rum_bulk_read_callback,
},
@@ -541,6 +543,10 @@
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic;
+ RUM_LOCK(sc);
+ rum_stop(sc);
+ RUM_UNLOCK(sc);
+
/* stop all USB transfers */
usb_pipe_close(sc->sc_xfer, RUM_N_TRANSFER);
@@ -647,8 +653,7 @@
data->ni = NULL;
}
usb_init_urb(data->urb); /* reset state */
- STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
- sc->tx_nfree++;
+ urb_list_insert(&sc->tx_free, data->urb);
}
static void
@@ -657,8 +662,7 @@
struct rum_tx_data *data;
int i;
- sc->tx_nfree = 0;
- STAILQ_INIT(&sc->tx_free);
+ urb_list_init(&sc->tx_free);
for (i = 0; i < RUM_TX_LIST_COUNT; i++) {
data = &sc->tx_data[i];
@@ -666,8 +670,8 @@
data->sc = sc;
data->urb = usb_get_urb(sc->sc_xfer[RUM_BULK_WR], 0);
KASSERT(data->urb != NULL, ("usb_get_urb failed"));
- urb_set_priv(data->urb, &data);
- STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
+ urb_set_priv(data->urb, data);
+ urb_list_insert(&sc->tx_free, data->urb);
sc->tx_nfree++;
}
}
@@ -678,10 +682,6 @@
struct rum_tx_data *data;
int i;
- /* make sure any subsequent use of the queues will fail */
- sc->tx_nfree = 0;
- STAILQ_INIT(&sc->tx_free);
-
/* free up all node references and mbufs */
for (i = 0; i < RUM_TX_LIST_COUNT; i++) {
data = &sc->tx_data[i];
@@ -695,10 +695,13 @@
data->ni = NULL;
}
if (data->urb != NULL) {
+ urb_list_remove(&sc->tx_free, data->urb);
usb_free_urb(data->urb);
data->urb = NULL;
}
}
+ if (sc->tx_free.count != 0)
+ printf("leaked %d urbs\n", sc->tx_free.count);
}
static int
@@ -772,15 +775,14 @@
struct rum_tx_data *data;
int len;
- printf("rum_bulk_write_callback(%p, %d)\n", urb, error);
-
urb_get_status(urb, NULL, NULL, &len, NULL);
DPRINTFN(11, "transfer complete, %d bytes\n", len);
/* free resources */
data = urb_get_priv(urb);
+ RUM_LOCK(sc);
rum_tx_free(data, 0);
- usb_free_urb(urb);
+ RUM_UNLOCK(sc);
if (error) {
if (error == USB_ERR_CANCELLED)
@@ -815,7 +817,7 @@
}
urb_get_status(urb, (void **)&desc, NULL, &actlen, NULL);
- DPRINTFN(0, "rx done, actlen=%d\n", actlen);
+ DPRINTFN(5, "rx done, urb=%p actlen=%d\n", urb, actlen);
if (actlen < RT2573_RX_DESC_SIZE + IEEE80211_MIN_LEN) {
DPRINTF("%s: xfer too short %d\n",
@@ -950,6 +952,7 @@
const struct ieee80211_frame *wh;
struct rum_tx_data *data;
struct rum_tx_desc *desc;
+ struct usb_urb *urb;
struct mbuf *mprot;
int protrate, ackrate, pktlen, flags, isshort, xferlen;
uint16_t dur;
@@ -980,13 +983,12 @@
/* XXX stat + msg */
return (ENOBUFS);
}
- data = STAILQ_FIRST(&sc->tx_free);
- STAILQ_REMOVE_HEAD(&sc->tx_free, next);
- sc->tx_nfree--;
+ urb = urb_list_dequeue(&sc->tx_free);
+ data = urb_get_priv(urb);
- urb_get_status(data->urb, (void **)&data->buf, &xferlen, NULL, NULL);
+ urb_get_status(urb, (void **)&data->buf, &xferlen, NULL, NULL);
if (xferlen < m->m_pkthdr.len + RT2573_TX_DESC_SIZE) {
- //m_freem(m); /* XXX data leak */
+ urb_list_insert(&sc->tx_free, urb);
return EINVAL;
}
@@ -994,7 +996,7 @@
data->m = mprot;
data->ni = ieee80211_ref_node(ni);
- vap = data->ni->ni_vap;
+ vap = ni->ni_vap;
if (ieee80211_radiotap_active_vap(vap)) {
struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
@@ -1013,8 +1015,8 @@
m->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, rate);
/* NB: no roundup necessary */
- urb_set_framelen(data->urb, 0, RT2573_TX_DESC_SIZE + mprot->m_pkthdr.len);
- usb_submit_urb(data->urb);
+ urb_set_framelen(urb, 0, RT2573_TX_DESC_SIZE + mprot->m_pkthdr.len);
+ usb_submit_urb(urb);
return 0;
}
@@ -1027,6 +1029,7 @@
struct ieee80211com *ic = ifp->if_l2com;
struct rum_tx_data *data;
struct rum_tx_desc *desc;
+ struct usb_urb *urb;
struct ieee80211_frame *wh;
const struct ieee80211_txparam *tp;
struct ieee80211_key *k;
@@ -1036,9 +1039,8 @@
RUM_LOCK_ASSERT(sc, MA_OWNED);
- data = STAILQ_FIRST(&sc->tx_free);
- STAILQ_REMOVE_HEAD(&sc->tx_free, next);
- sc->tx_nfree--;
+ urb = urb_list_dequeue(&sc->tx_free);
+ data = urb_get_priv(urb);
wh = mtod(m0, struct ieee80211_frame *);
if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
@@ -1066,9 +1068,10 @@
flags |= RT2573_TX_TIMESTAMP;
}
- urb_get_status(data->urb, (void **)&data->buf, &xferlen, NULL, NULL);
+ urb_get_status(urb, (void **)&data->buf, &xferlen, NULL, NULL);
if (xferlen < m0->m_pkthdr.len + RT2573_TX_DESC_SIZE) {
- m_freem(m0); /* XXX data leak */
+ urb_list_insert(&sc->tx_free, urb);
+ m_freem(m0);
return EINVAL;
}
@@ -1076,7 +1079,6 @@
data->m = m0;
data->ni = ni;
- vap = data->ni->ni_vap;
if (ieee80211_radiotap_active_vap(vap)) {
struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
@@ -1103,8 +1105,8 @@
DPRINTFN(10, "sending mgt frame len=%d rate=%d xfer len=%d\n",
m0->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, tp->mgmtrate, xferlen);
- urb_set_framelen(data->urb, 0, xferlen);
- usb_submit_urb(data->urb);
+ urb_set_framelen(urb, 0, xferlen);
+ usb_submit_urb(urb);
return (0);
}
@@ -1117,6 +1119,7 @@
struct ieee80211vap *vap;
struct rum_tx_data *data;
struct rum_tx_desc *desc;
+ struct usb_urb *urb;
uint32_t flags;
int rate, error, xferlen;
@@ -1136,24 +1139,24 @@
params->ibp_flags & IEEE80211_BPF_RTS ?
IEEE80211_PROT_RTSCTS : IEEE80211_PROT_CTSONLY,
rate);
- if (error || sc->tx_nfree == 0) {
+ if (error || sc->tx_free.count == 0) {
m_freem(m0);
return ENOBUFS;
}
flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS;
}
- data = STAILQ_FIRST(&sc->tx_free);
- STAILQ_REMOVE_HEAD(&sc->tx_free, next);
- sc->tx_nfree--;
+ urb = urb_list_dequeue(&sc->tx_free);
+ data = urb_get_priv(urb);
- urb_get_status(data->urb, (void **)&data->buf, &xferlen, NULL, NULL);
+ urb_get_status(urb, (void **)&data->buf, &xferlen, NULL, NULL);
if (xferlen < m0->m_pkthdr.len + RT2573_TX_DESC_SIZE) {
- m_freem(m0); /* XXX data leak */
+ urb_list_insert(&sc->tx_free, urb);
+ m_freem(m0);
return EINVAL;
}
- vap = data->ni->ni_vap;
+ vap = ni->ni_vap;
if (ieee80211_radiotap_active_vap(vap)) {
struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
@@ -1185,8 +1188,8 @@
DPRINTFN(10, "sending raw frame len=%u rate=%u xfer len=%u\n",
m0->m_pkthdr.len, rate, xferlen);
- urb_set_framelen(data->urb, 0, xferlen);
- usb_submit_urb(data->urb);
+ urb_set_framelen(urb, 0, xferlen);
+ usb_submit_urb(urb);
return 0;
}
@@ -1199,6 +1202,7 @@
struct ieee80211com *ic = ifp->if_l2com;
struct rum_tx_data *data;
struct rum_tx_desc *desc;
+ struct usb_urb *urb;
struct ieee80211_frame *wh;
const struct ieee80211_txparam *tp;
struct ieee80211_key *k;
@@ -1238,7 +1242,7 @@
prot = ic->ic_protmode;
if (prot != IEEE80211_PROT_NONE) {
error = rum_sendprot(sc, m0, ni, prot, rate);
- if (error || sc->tx_nfree == 0) {
+ if (error || sc->tx_free.count == 0) {
m_freem(m0);
return ENOBUFS;
}
@@ -1246,13 +1250,13 @@
}
}
- data = STAILQ_FIRST(&sc->tx_free);
- STAILQ_REMOVE_HEAD(&sc->tx_free, next);
- sc->tx_nfree--;
+ urb = urb_list_dequeue(&sc->tx_free);
+ data = urb_get_priv(urb);
- urb_get_status(data->urb, (void **)&data->buf, &xferlen, NULL, NULL);
+ urb_get_status(urb, (void **)&data->buf, &xferlen, NULL, NULL);
if (xferlen < m0->m_pkthdr.len + RT2573_TX_DESC_SIZE) {
- m_freem(m0); /* XXX data leak */
+ urb_list_insert(&sc->tx_free, urb);
+ m_freem(m0);
return EINVAL;
}
@@ -1269,7 +1273,6 @@
*(uint16_t *)wh->i_dur = htole16(dur);
}
- vap = data->ni->ni_vap;
if (ieee80211_radiotap_active_vap(vap)) {
struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
@@ -1290,8 +1293,8 @@
DPRINTFN(10, "sending frame len=%d rate=%d xfer len=%d\n",
m0->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, rate, xferlen);
- urb_set_framelen(data->urb, 0, xferlen);
- usb_submit_urb(data->urb);
+ urb_set_framelen(urb, 0, xferlen);
+ usb_submit_urb(urb);
return 0;
}
@@ -1312,7 +1315,7 @@
IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
if (m == NULL)
break;
- if (sc->tx_nfree < RUM_TX_MINFREE) {
+ if (sc->tx_free.count < RUM_TX_MINFREE) {
IFQ_DRV_PREPEND(&ifp->if_snd, m);
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
break;
@@ -2042,8 +2045,9 @@
/*
* Start up the receive pipe.
*/
- urb = usb_get_urb(sc->sc_xfer[RUM_BULK_RD], 0);
- usb_submit_urb(urb);
+ while ((urb = usb_get_urb(sc->sc_xfer[RUM_BULK_RD], 0)) != NULL) {
+ usb_submit_urb(urb);
+ }
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
ifp->if_drv_flags |= IFF_DRV_RUNNING;
@@ -2175,7 +2179,7 @@
ieee80211_free_node(ni);
return ENETDOWN;
}
- if (sc->tx_nfree < RUM_TX_MINFREE) {
+ if (sc->tx_free.count < RUM_TX_MINFREE) {
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
RUM_UNLOCK(sc);
m_freem(m);
==== //depot/projects/usb_buf/src/sys/dev/usb/wlan/if_rumvar.h#5 (text+ko) ====
@@ -17,8 +17,9 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define RUM_TX_LIST_COUNT 1
-#define RUM_TX_MINFREE 0
+#define RUM_RX_LIST_COUNT 2
+#define RUM_TX_LIST_COUNT 4
+#define RUM_TX_MINFREE 2
struct rum_rx_radiotap_header {
struct ieee80211_radiotap_header wr_ihdr;
@@ -103,7 +104,8 @@
uint8_t rffreq;
struct rum_tx_data tx_data[RUM_TX_LIST_COUNT];
- rum_txdhead tx_free;
+ usb_urb_list tx_free;
+ usb_urb_list rx_free;
int tx_nfree;
struct rum_rx_desc sc_rx_desc;
More information about the p4-projects
mailing list