Date: Sat, 6 Jun 2009 04:34:11 GMT From: Andrew Thompson <thompsa@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 163629 for review Message-ID: <200906060434.n564YBwc028662@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=163629 Change 163629 by thompsa@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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906060434.n564YBwc028662>