PERFORCE change 157443 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Mon Feb 9 08:59:43 PST 2009
http://perforce.freebsd.org/chv.cgi?CH=157443
Change 157443 by hselasky at 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;
More information about the p4-projects
mailing list