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