Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 9 Feb 2009 16:59:39 GMT
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 157443 for review
Message-ID:  <200902091659.n19GxdP6033610@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=157443

Change 157443 by hselasky@hselasky_laptop001 on 2009/02/09 16:59:35

	
	USB WLAN patches:
	 - Fix issues with freed memory accessed.
	 - Some other minor nits.
	 - USB WLAN adapters have been tested and
	   found to work in device mode.

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb2/wlan/if_rum2.c#29 edit
.. //depot/projects/usb/src/sys/dev/usb2/wlan/if_rumvar.h#6 edit
.. //depot/projects/usb/src/sys/dev/usb2/wlan/if_ural2.c#29 edit
.. //depot/projects/usb/src/sys/dev/usb2/wlan/if_uralvar.h#6 edit
.. //depot/projects/usb/src/sys/dev/usb2/wlan/if_zyd2.c#31 edit
.. //depot/projects/usb/src/sys/dev/usb2/wlan/if_zydreg.h#5 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_rum2.c#29 (text+ko) ====

@@ -133,8 +133,8 @@
 			    const uint8_t mac[IEEE80211_ADDR_LEN]);
 static void		rum_vap_delete(struct ieee80211vap *);
 static void		rum_tx_free(struct rum_tx_data *, int);
-static int		rum_alloc_tx_list(struct rum_softc *);
-static void		rum_free_tx_list(struct rum_softc *);
+static void		rum_setup_tx_list(struct rum_softc *);
+static void		rum_unsetup_tx_list(struct rum_softc *);
 static int		rum_newstate(struct ieee80211vap *,
 			    enum ieee80211_state, int);
 static void		rum_setup_tx_desc(struct rum_softc *,
@@ -552,19 +552,21 @@
 	/* wait for any post attach or other command to complete */
 	usb2_proc_drain(&sc->sc_tq);
 
-	/* stop all USB transfers first */
+	/* stop all USB transfers */
 	usb2_transfer_unsetup(sc->sc_xfer, RUM_N_TRANSFER);
 	usb2_proc_free(&sc->sc_tq);
 
+	/* free TX list, if any */
+	RUM_LOCK(sc);
+	rum_unsetup_tx_list(sc);
+	RUM_UNLOCK(sc);
+
 	if (ifp) {
 		bpfdetach(ifp);
 		ieee80211_ifdetach(ic);
 		if_free(ifp);
 	}
 
-	/* free TX list, if any */
-	rum_free_tx_list(sc);
-
 	mtx_destroy(&sc->sc_mtx);
 
 	return (0);
@@ -612,11 +614,8 @@
 rum_vap_delete(struct ieee80211vap *vap)
 {
 	struct rum_vap *rvp = RUM_VAP(vap);
-	struct rum_softc *sc = rvp->sc;
 
-	RUM_LOCK(sc);
-	usb2_callout_stop(&rvp->amrr_ch);
-	RUM_UNLOCK(sc);
+	usb2_callout_drain(&rvp->amrr_ch);
 	ieee80211_amrr_cleanup(&rvp->amrr);
 	ieee80211_vap_detach(vap);
 	free(rvp, M_80211_VAP);
@@ -641,17 +640,12 @@
 	sc->tx_nfree++;
 }
 
-static int
-rum_alloc_tx_list(struct rum_softc *sc)
+static void
+rum_setup_tx_list(struct rum_softc *sc)
 {
 	struct rum_tx_data *data;
 	int i;
 
-	sc->tx_data = malloc(sizeof(struct rum_tx_data) * RUM_TX_LIST_COUNT,
-	    M_USB, M_NOWAIT|M_ZERO);
-	if (sc->tx_data == NULL)
-		return (ENOMEM);
-
 	sc->tx_nfree = 0;
 	STAILQ_INIT(&sc->tx_q);
 	STAILQ_INIT(&sc->tx_free);
@@ -663,18 +657,20 @@
 		STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
 		sc->tx_nfree++;
 	}
-	return 0;
 }
 
 static void
-rum_free_tx_list(struct rum_softc *sc)
+rum_unsetup_tx_list(struct rum_softc *sc)
 {
 	struct rum_tx_data *data;
 	int i;
 
-	if (sc->tx_data == NULL)
-		return;
+	/* make sure any subsequent use of the queues will fail */
+	sc->tx_nfree = 0;
+	STAILQ_INIT(&sc->tx_q);
+	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];
 
@@ -687,8 +683,6 @@
 			data->ni = NULL;
 		}
 	}
-	free(sc->tx_data, M_USB);
-	sc->tx_data = NULL;
 }
 
 static void
@@ -724,7 +718,8 @@
 			rum_enable_mrr(sc);
 			rum_set_txpreamble(sc);
 			rum_set_basicrates(sc);
-			rum_set_bssid(sc, ni->ni_bssid);
+			IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid);
+			rum_set_bssid(sc, sc->sc_bssid);
 		}
 
 		if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
@@ -1998,11 +1993,7 @@
 	/*
 	 * Allocate Tx and Rx xfer queues.
 	 */
-	error = rum_alloc_tx_list(sc);
-	if (error != 0) {
-		device_printf(sc->sc_dev, "could not allocate Tx list\n");
-		goto fail;
-	}
+	rum_setup_tx_list(sc);
 
 	/* update Rx filter */
 	tmp = rum_read(sc, RT2573_TXRX_CSR0) & 0xffff;
@@ -2056,13 +2047,17 @@
 
 	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
 
+	RUM_UNLOCK(sc);
+
 	/*
-	 * stop all the transfers, if not already stopped:
+	 * Drain the USB transfers, if not already drained:
 	 */
-	usb2_transfer_stop(sc->sc_xfer[RUM_BULK_WR]);
-	usb2_transfer_stop(sc->sc_xfer[RUM_BULK_RD]);
+	usb2_transfer_drain(sc->sc_xfer[RUM_BULK_WR]);
+	usb2_transfer_drain(sc->sc_xfer[RUM_BULK_RD]);
+
+	RUM_LOCK(sc);
 
-	rum_free_tx_list(sc);
+	rum_unsetup_tx_list(sc);
 
 	/* disable Rx */
 	tmp = rum_read(sc, RT2573_TXRX_CSR0);
@@ -2298,7 +2293,6 @@
 	struct rum_softc *sc = task->sc;
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
-	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
 	uint32_t tmp;
 
 	RUM_LOCK_ASSERT(sc, MA_OWNED);
@@ -2311,19 +2305,13 @@
 		rum_set_bssid(sc, ifp->if_broadcastaddr);
 		break;
 
-	case RUM_SCAN_END:
-		rum_enable_tsf_sync(sc);
-		/* XXX keep local copy */
-		rum_set_bssid(sc, vap->iv_bss->ni_bssid);
-		break;
-
 	case RUM_SET_CHANNEL:
 		rum_set_chan(sc, ic->ic_curchan);
 		break;
 
-	default:
-		panic("unknown scan action %d\n", sc->sc_scan_action);
-		/* NEVER REACHED */
+	default: /* RUM_SCAN_END */
+		rum_enable_tsf_sync(sc);
+		rum_set_bssid(sc, sc->sc_bssid);
 		break;
 	}
 }

==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_rumvar.h#6 (text+ko) ====

@@ -116,7 +116,7 @@
 #define RUM_SCAN_END	1
 #define RUM_SET_CHANNEL	2
 
-	struct rum_tx_data		*tx_data;
+	struct rum_tx_data		tx_data[RUM_TX_LIST_COUNT];
 	rum_txdhead			tx_q;
 	rum_txdhead			tx_free;
 	int				tx_nfree;

==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_ural2.c#29 (text+ko) ====

@@ -112,8 +112,8 @@
 			    const uint8_t mac[IEEE80211_ADDR_LEN]);
 static void		ural_vap_delete(struct ieee80211vap *);
 static void		ural_tx_free(struct ural_tx_data *, int);
-static int		ural_alloc_tx_list(struct ural_softc *);
-static void		ural_free_tx_list(struct ural_softc *);
+static void		ural_setup_tx_list(struct ural_softc *);
+static void		ural_unsetup_tx_list(struct ural_softc *);
 static int		ural_newstate(struct ieee80211vap *,
 			    enum ieee80211_state, int);
 static void		ural_setup_tx_desc(struct ural_softc *,
@@ -538,19 +538,21 @@
 	/* wait for any post attach or other command to complete */
 	usb2_proc_drain(&sc->sc_tq);
 
-	/* stop all USB transfers first */
+	/* stop all USB transfers */
 	usb2_transfer_unsetup(sc->sc_xfer, URAL_N_TRANSFER);
 	usb2_proc_free(&sc->sc_tq);
 
+	/* free TX list, if any */
+	RAL_LOCK(sc);
+	ural_unsetup_tx_list(sc);
+	RAL_UNLOCK(sc);
+
 	if (ifp) {
 		bpfdetach(ifp);
 		ieee80211_ifdetach(ic);
 		if_free(ifp);
 	}
 
-	/* free TX list, if any */
-	ural_free_tx_list(sc);
-
 	mtx_destroy(&sc->sc_mtx);
 
 	return (0);
@@ -598,11 +600,8 @@
 ural_vap_delete(struct ieee80211vap *vap)
 {
 	struct ural_vap *uvp = URAL_VAP(vap);
-	struct ural_softc *sc = uvp->sc;
 
-	RAL_LOCK(sc);
-	usb2_callout_stop(&uvp->amrr_ch);
-	RAL_UNLOCK(sc);
+	usb2_callout_drain(&uvp->amrr_ch);
 	ieee80211_amrr_cleanup(&uvp->amrr);
 	ieee80211_vap_detach(vap);
 	free(uvp, M_80211_VAP);
@@ -627,17 +626,12 @@
 	sc->tx_nfree++;
 }
 
-static int
-ural_alloc_tx_list(struct ural_softc *sc)
+static void
+ural_setup_tx_list(struct ural_softc *sc)
 {
 	struct ural_tx_data *data;
 	int i;
 
-	sc->tx_data = malloc(sizeof(struct ural_tx_data) * RAL_TX_LIST_COUNT,
-	    M_USB, M_NOWAIT|M_ZERO);
-	if (sc->tx_data == NULL)
-		return (ENOMEM);
-
 	sc->tx_nfree = 0;
 	STAILQ_INIT(&sc->tx_q);
 	STAILQ_INIT(&sc->tx_free);
@@ -649,18 +643,20 @@
 		STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
 		sc->tx_nfree++;
 	}
-	return 0;
 }
 
 static void
-ural_free_tx_list(struct ural_softc *sc)
+ural_unsetup_tx_list(struct ural_softc *sc)
 {
 	struct ural_tx_data *data;
 	int i;
 
-	if (sc->tx_data == NULL)
-		return;
+	/* make sure any subsequent use of the queues will fail */
+	sc->tx_nfree = 0;
+	STAILQ_INIT(&sc->tx_q);
+	STAILQ_INIT(&sc->tx_free);
 
+	/* free up all node references and mbufs */
 	for (i = 0; i < RAL_TX_LIST_COUNT; i++) {
 		data = &sc->tx_data[i];
 
@@ -673,8 +669,6 @@
 			data->ni = NULL;
 		}
 	}
-	free(sc->tx_data, M_USB);
-	sc->tx_data = NULL;
 }
 
 static void
@@ -711,7 +705,8 @@
 			ural_update_slot(ic->ic_ifp);
 			ural_set_txpreamble(sc);
 			ural_set_basicrates(sc, ic->ic_bsschan);
-			ural_set_bssid(sc, ni->ni_bssid);
+			IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid);
+			ural_set_bssid(sc, sc->sc_bssid);
 		}
 
 		if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
@@ -763,23 +758,27 @@
 	struct ural_softc *sc = task->sc;
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
-	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
 
 	RAL_LOCK_ASSERT(sc, MA_OWNED);
 
-	if (sc->sc_scan_action == URAL_SCAN_START) {
+	switch (sc->sc_scan_action) {
+	case URAL_SCAN_START:
 		/* abort TSF synchronization */
 		DPRINTF("starting scan\n");
 		ural_write(sc, RAL_TXRX_CSR19, 0);
 		ural_set_bssid(sc, ifp->if_broadcastaddr);
-	} else if (sc->sc_scan_action == URAL_SET_CHANNEL) {
+		break;
+
+	case URAL_SET_CHANNEL:
 		ural_set_chan(sc, ic->ic_curchan);
-	} else {
+		break;
+
+	default: /* URAL_SCAN_END */
 		DPRINTF("stopping scan\n");
 		ural_enable_tsf_sync(sc);
-		/* XXX keep local copy */
-		ural_set_bssid(sc, vap->iv_bss->ni_bssid);
-	} 
+		ural_set_bssid(sc, sc->sc_bssid);
+		break;
+	}
 }
 
 static int
@@ -2092,7 +2091,6 @@
 	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211com *ic = ifp->if_l2com;
 	uint16_t tmp;
-	usb2_error_t error;
 	int i, ntries;
 
 	RAL_LOCK_ASSERT(sc, MA_OWNED);
@@ -2143,11 +2141,7 @@
 	/*
 	 * Allocate Tx and Rx xfer queues.
 	 */
-	error = ural_alloc_tx_list(sc);
-	if (error != 0) {
-		device_printf(sc->sc_dev, "could not allocate Tx list\n");
-		goto fail;
-	}
+	ural_setup_tx_list(sc);
 
 	/* kick Rx */
 	tmp = RAL_DROP_PHY | RAL_DROP_CRC;
@@ -2198,12 +2192,14 @@
 	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
 
 	/*
-	 * stop all the transfers, if not already stopped:
+	 * Drain all the transfers, if not already drained:
 	 */
-	usb2_transfer_stop(sc->sc_xfer[URAL_BULK_WR]);
-	usb2_transfer_stop(sc->sc_xfer[URAL_BULK_RD]);
+	RAL_UNLOCK(sc);
+	usb2_transfer_drain(sc->sc_xfer[URAL_BULK_WR]);
+	usb2_transfer_drain(sc->sc_xfer[URAL_BULK_RD]);
+	RAL_LOCK(sc);
 
-	ural_free_tx_list(sc);
+	ural_unsetup_tx_list(sc);
 
 	/* disable Rx */
 	ural_write(sc, RAL_TXRX_CSR2, RAL_DISABLE_RX);

==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_uralvar.h#6 (text+ko) ====

@@ -119,7 +119,7 @@
 	struct ural_task		sc_promisctask[2];
 	struct ural_task		sc_scantask[2];
 
-	struct ural_tx_data		*tx_data;
+	struct ural_tx_data		tx_data[RAL_TX_LIST_COUNT];
 	ural_txdhead			tx_q;
 	ural_txdhead			tx_free;
 	int				tx_nfree;

==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_zyd2.c#31 (text+ko) ====

@@ -64,7 +64,7 @@
 	ZYD_DEBUG_ANY		= 0xffffffff
 };
 #define	DPRINTF(sc, m, fmt, ...) do {				\
-	if (sc->sc_debug & (m))					\
+	if (zyd_debug & (m))					\
 		printf("%s: " fmt, __func__, ## __VA_ARGS__);	\
 } while (0)
 #else
@@ -98,8 +98,8 @@
 		    const uint8_t mac[IEEE80211_ADDR_LEN]);
 static void	zyd_vap_delete(struct ieee80211vap *);
 static void	zyd_tx_free(struct zyd_tx_data *, int);
-static int	zyd_alloc_tx_list(struct zyd_softc *);
-static void	zyd_free_tx_list(struct zyd_softc *);
+static void	zyd_setup_tx_list(struct zyd_softc *);
+static void	zyd_unsetup_tx_list(struct zyd_softc *);
 static struct ieee80211_node *zyd_node_alloc(struct ieee80211vap *,
 			    const uint8_t mac[IEEE80211_ADDR_LEN]);
 static int	zyd_newstate(struct ieee80211vap *, enum ieee80211_state, int);
@@ -293,7 +293,7 @@
 
 	if (uaa->usb2_mode != USB_MODE_HOST)
 		return (ENXIO);
-	if (uaa->info.bConfigIndex != 0)
+	if (uaa->info.bConfigIndex != ZYD_CONFIG_INDEX)
 		return (ENXIO);
 	if (uaa->info.bIfaceIndex != ZYD_IFACE_INDEX)
 		return (ENXIO);
@@ -306,7 +306,7 @@
 {
 	struct usb2_attach_arg *uaa = device_get_ivars(dev);
 	struct zyd_softc *sc = device_get_softc(dev);
-	int error = ENXIO;
+	int error;
 	uint8_t iface_index;
 
 	if (uaa->info.bcdDevice < 0x4330) {
@@ -320,9 +320,7 @@
 	sc->sc_dev = dev;
 	sc->sc_udev = uaa->device;
 	sc->sc_macrev = USB_GET_DRIVER_INFO(uaa);
-#ifdef USB_DEBUG
-	sc->sc_debug = zyd_debug;
-#endif
+
 	mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev),
 	    MTX_NETWORK_LOCK, MTX_DEF);
 
@@ -447,19 +445,19 @@
 	/* wait for any post attach or other command to complete */
 	usb2_proc_drain(&sc->sc_tq);
 
-	/* stop all USB transfers first */
+	/* stop all USB transfers */
 	usb2_transfer_unsetup(sc->sc_xfer, ZYD_N_TRANSFER);
 	usb2_proc_free(&sc->sc_tq);
 
+	/* free TX list, if any */
+	zyd_unsetup_tx_list(sc);
+
 	if (ifp) {
 		bpfdetach(ifp);
 		ieee80211_ifdetach(ic);
 		if_free(ifp);
 	}
 
-	/* free TX list, if any */
-	zyd_free_tx_list(sc);
-
 	mtx_destroy(&sc->sc_mtx);
 
 	return (0);
@@ -530,17 +528,12 @@
 	sc->tx_nfree++;
 }
 
-static int
-zyd_alloc_tx_list(struct zyd_softc *sc)
+static void
+zyd_setup_tx_list(struct zyd_softc *sc)
 {
 	struct zyd_tx_data *data;
 	int i;
 
-	sc->tx_data = malloc(sizeof(struct zyd_tx_data) * ZYD_TX_LIST_CNT,
-	    M_USB, M_NOWAIT|M_ZERO);
-	if (sc->tx_data == NULL)
-		return (ENOMEM);
-
 	sc->tx_nfree = 0;
 	STAILQ_INIT(&sc->tx_q);
 	STAILQ_INIT(&sc->tx_free);
@@ -552,18 +545,20 @@
 		STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
 		sc->tx_nfree++;
 	}
-	return 0;
 }
 
 static void
-zyd_free_tx_list(struct zyd_softc *sc)
+zyd_unsetup_tx_list(struct zyd_softc *sc)
 {
 	struct zyd_tx_data *data;
 	int i;
 
-	if (sc->tx_data == NULL)
-		return;
+	/* make sure any subsequent use of the queues will fail */
+	sc->tx_nfree = 0;
+	STAILQ_INIT(&sc->tx_q);
+	STAILQ_INIT(&sc->tx_free);
 
+	/* free up all node references and mbufs */
 	for (i = 0; i < ZYD_TX_LIST_CNT; i++) {
 		data = &sc->tx_data[i];
 
@@ -576,8 +571,6 @@
 			data->ni = NULL;
 		}
 	}
-	free(sc->tx_data, M_USB);
-	sc->tx_data = NULL;
 }
 
 /* ARGUSED */
@@ -1923,13 +1916,11 @@
 	USETW(req.wIndex, 0);
 	USETW(req.wLength, IEEE80211_ADDR_LEN);
 
-	ZYD_LOCK(sc);
 	error = zyd_do_request(sc, &req, sc->sc_bssid);
 	if (error != 0) {
 		device_printf(sc->sc_dev, "could not read EEPROM: %s\n",
 		    usb2_errstr(error));
 	}
-	ZYD_UNLOCK(sc);
 
 	return (error);
 }
@@ -2868,10 +2859,7 @@
 	/*
 	 * Allocate Tx and Rx xfer queues.
 	 */
-	if ((error = zyd_alloc_tx_list(sc)) != 0) {
-		device_printf(sc->sc_dev, "could not allocate Tx list\n");
-		goto fail;
-	}
+	zyd_setup_tx_list(sc);
 
 	/* enable interrupts */
 	zyd_write32_m(sc, ZYD_CR_INTERRUPT, ZYD_HWINT_MASK);
@@ -2917,12 +2905,14 @@
 	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
 
 	/*
-	 * stop all the transfers, if not already stopped:
+	 * Drain all the transfers, if not already drained:
 	 */
-	usb2_transfer_stop(sc->sc_xfer[ZYD_BULK_WR]);
-	usb2_transfer_stop(sc->sc_xfer[ZYD_BULK_RD]);
+	ZYD_UNLOCK(sc);
+	usb2_transfer_drain(sc->sc_xfer[ZYD_BULK_WR]);
+	usb2_transfer_drain(sc->sc_xfer[ZYD_BULK_RD]);
+	ZYD_LOCK(sc);
 
-	zyd_free_tx_list(sc);
+	zyd_unsetup_tx_list(sc);
 
 	/* Stop now if the device was never set up */
 	if (!(sc->sc_flags & ZYD_FLAG_INITONCE))
@@ -3063,18 +3053,16 @@
 		/* want broadcast address while scanning */
                 zyd_set_bssid(sc, ifp->if_broadcastaddr);
                 break;
-        case ZYD_SCAN_END:
-		/* restore previous bssid */
-                zyd_set_bssid(sc, sc->sc_bssid);
-                break;
+
         case ZYD_SET_CHANNEL:
                 zyd_set_chan(sc, ic->ic_curchan);
                 break;
-        default:
-                device_printf(sc->sc_dev, "unknown scan action %d\n",
-		    sc->sc_scan_action);
+
+        default: /* ZYD_SCAN_END */
+		/* restore previous bssid */
+                zyd_set_bssid(sc, sc->sc_bssid);
                 break;
-        }
+	}
 }
 
 static void

==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_zydreg.h#5 (text+ko) ====

@@ -1127,7 +1127,7 @@
 	uint16_t		count;
 } __packed;
 
-#define ZYD_CONFIG_NO		1
+#define ZYD_CONFIG_INDEX	0
 #define ZYD_IFACE_INDEX		0
 
 #define ZYD_INTR_TIMEOUT	1000
@@ -1274,7 +1274,6 @@
 #define	ZYD_FLAG_INITONCE		(1 << 1)
 #define	ZYD_FLAG_INITDONE		(1 << 2)
 	int			sc_if_flags;
-	uint32_t		sc_debug;
 
 	struct zyd_task		sc_synctask[2];
 	struct zyd_task		sc_mcasttask[2];
@@ -1317,7 +1316,7 @@
 
 	struct mtx		sc_mtx;
 	struct cv		sc_intr_cv;
-	struct zyd_tx_data	*tx_data;
+	struct zyd_tx_data	tx_data[ZYD_TX_LIST_CNT];
 	zyd_txdhead		tx_q;
 	zyd_txdhead		tx_free;
 	int			tx_nfree;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200902091659.n19GxdP6033610>