For rum(4) and ural(4):
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 27 May 2007 10:53:29 +0000 (10:53 +0000)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 27 May 2007 10:53:29 +0000 (10:53 +0000)
- Use crit section to protect external interfaces, callouts, USB
  task and USB operation callback functions.
- Avoid holding ifnet.if_serializer across various USB operations,
  since current USB stack does not aware of lwkt serializer.
- In various callout, USB task and USB operation callback functions,
  hold ifnet.if_serializer around ieee80211 functions.

sys/dev/netif/rum/if_rum.c
sys/dev/netif/rum/if_rumvar.h
sys/dev/netif/ural/if_ural.c
sys/dev/netif/ural/if_uralvar.h

index ac992d0..b4765b9 100644 (file)
@@ -1,5 +1,5 @@
 /*     $OpenBSD: if_rum.c,v 1.40 2006/09/18 16:20:20 damien Exp $      */
-/*     $DragonFly: src/sys/dev/netif/rum/if_rum.c,v 1.12 2007/05/02 11:29:27 sephe Exp $       */
+/*     $DragonFly: src/sys/dev/netif/rum/if_rum.c,v 1.13 2007/05/27 10:53:29 sephe Exp $       */
 
 /*-
  * Copyright (c) 2005, 2006 Damien Bergamini <damien.bergamini@free.fr>
@@ -430,15 +430,13 @@ USB_DETACH(rum)
        int i;
 #endif
 
-       lwkt_serialize_enter(ifp->if_serializer);
-
-       sc->sc_flags |= RUM_FLAG_DETACHED;
+       crit_enter();
 
        callout_stop(&sc->scan_ch);
        callout_stop(&sc->stats_ch);
 
+       lwkt_serialize_enter(ifp->if_serializer);
        rum_stop(sc);
-
        lwkt_serialize_exit(ifp->if_serializer);
 
        usb_rem_task(sc->sc_udev, &sc->sc_task);
@@ -446,6 +444,8 @@ USB_DETACH(rum)
        bpfdetach(ifp);
        ieee80211_ifdetach(&sc->sc_ic); /* free all nodes */
 
+       crit_exit();
+
        KKASSERT(sc->stats_xfer == NULL);
        KKASSERT(sc->sc_rx_pipeh == NULL);
        KKASSERT(sc->sc_tx_pipeh == NULL);
@@ -603,17 +603,18 @@ rum_next_scan(void *arg)
        struct ieee80211com *ic = &sc->sc_ic;
        struct ifnet *ifp = &ic->ic_if;
 
-       lwkt_serialize_enter(ifp->if_serializer);
-
-       if (sc->sc_flags & RUM_FLAG_STOPPED) {
-               lwkt_serialize_exit(ifp->if_serializer);
+       if (sc->sc_stopped)
                return;
-       }
 
-       if (ic->ic_state == IEEE80211_S_SCAN)
+       crit_enter();
+
+       if (ic->ic_state == IEEE80211_S_SCAN) {
+               lwkt_serialize_enter(ifp->if_serializer);
                ieee80211_next_scan(ic);
+               lwkt_serialize_exit(ifp->if_serializer);
+       }
 
-       lwkt_serialize_exit(ifp->if_serializer);
+       crit_exit();
 }
 
 Static void
@@ -626,25 +627,17 @@ rum_task(void *xarg)
        struct ieee80211_node *ni;
        int arg;
 
-       crit_enter();
-
-       tsleep_interlock(&sc->sc_flags);
-       if (sc->sc_flags & RUM_FLAG_CONFIG)
-               tsleep(&sc->sc_flags, 0, "rumcfg", 0);
-       sc->sc_flags |= RUM_FLAG_CONFIG;
+       if (sc->sc_stopped)
+               return;
 
-       if (sc->sc_flags & RUM_FLAG_STOPPED)
-               goto back;
+       crit_enter();
 
        nstate = sc->sc_state;
        arg = sc->sc_arg;
 
-       if (nstate != IEEE80211_S_INIT) {
-               rum_set_chan(sc, ic->ic_curchan);
-       } else {
-               /* -> INIT state change is inline executed. */
-               goto back;
-       }
+       KASSERT(nstate != IEEE80211_S_INIT,
+               ("->INIT state transition should not be defered\n"));
+       rum_set_chan(sc, ic->ic_curchan);
 
        switch (nstate) {
        case IEEE80211_S_RUN:
@@ -667,28 +660,22 @@ rum_task(void *xarg)
 
                /* clear statistic registers (STA_CSR0 to STA_CSR5) */
                rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof(sc->sta));
+               callout_reset(&sc->stats_ch, 4 * hz / 5, rum_stats_timeout, sc);
+               break;
 
+       case IEEE80211_S_SCAN:
+               callout_reset(&sc->scan_ch, hz / 5, rum_next_scan, sc);
                break;
+
        default:
                break;
        }
 
        lwkt_serialize_enter(ifp->if_serializer);
-
        ieee80211_ratectl_newstate(ic, nstate);
-
-       if (nstate == IEEE80211_S_SCAN)
-               callout_reset(&sc->scan_ch, hz / 5, rum_next_scan, sc);
-       else if (nstate == IEEE80211_S_RUN)
-               callout_reset(&sc->stats_ch, 4 * hz / 5, rum_stats_timeout, sc);
-
        sc->sc_newstate(ic, nstate, arg);
-
        lwkt_serialize_exit(ifp->if_serializer);
 
-back:
-       sc->sc_flags &= ~RUM_FLAG_CONFIG;
-       wakeup(&sc->sc_flags);
        crit_exit();
 }
 
@@ -696,10 +683,11 @@ Static int
 rum_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
 {
        struct rum_softc *sc = ic->ic_if.if_softc;
+       struct ifnet *ifp = &ic->ic_if;
 
        crit_enter();
 
-       ASSERT_SERIALIZED(ic->ic_if.if_serializer);
+       ASSERT_SERIALIZED(ifp->if_serializer);
 
        callout_stop(&sc->scan_ch);
        callout_stop(&sc->stats_ch);
@@ -708,12 +696,16 @@ rum_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
        sc->sc_state = nstate;
        sc->sc_arg = arg;
 
+       lwkt_serialize_exit(ifp->if_serializer);
        usb_rem_task(sc->sc_udev, &sc->sc_task);
+
        if (nstate == IEEE80211_S_INIT) {
+               lwkt_serialize_enter(ifp->if_serializer);
                ieee80211_ratectl_newstate(ic, nstate);
                sc->sc_newstate(ic, nstate, arg);
        } else {
                usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER);
+               lwkt_serialize_enter(ifp->if_serializer);
        }
 
        crit_exit();
@@ -732,17 +724,16 @@ rum_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
        struct rum_softc *sc = data->sc;
        struct ieee80211com *ic = &sc->sc_ic;
        struct ifnet *ifp = &ic->ic_if;
+       struct ieee80211_node *ni;
 
-       lwkt_serialize_enter(ifp->if_serializer);
-
-       if (sc->sc_flags & RUM_FLAG_STOPPED) {
-               lwkt_serialize_exit(ifp->if_serializer);
+       if (sc->sc_stopped)
                return;
-       }
+
+       crit_enter();
 
        if (status != USBD_NORMAL_COMPLETION) {
                if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
-                       lwkt_serialize_exit(ifp->if_serializer);
+                       crit_exit();
                        return;
                }
 
@@ -753,13 +744,13 @@ rum_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
                        usbd_clear_endpoint_stall_async(sc->sc_tx_pipeh);
 
                ifp->if_oerrors++;
-               lwkt_serialize_exit(ifp->if_serializer);
+               crit_exit();
                return;
        }
 
        m_freem(data->m);
        data->m = NULL;
-       ieee80211_free_node(data->ni);
+       ni = data->ni;
        data->ni = NULL;
 
        bzero(data->buf, sizeof(struct rum_tx_data));
@@ -770,9 +761,13 @@ rum_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
 
        sc->sc_tx_timer = 0;
        ifp->if_flags &= ~IFF_OACTIVE;
-       ifp->if_start(ifp);
 
+       lwkt_serialize_enter(ifp->if_serializer);
+       ieee80211_free_node(ni);
+       ifp->if_start(ifp);
        lwkt_serialize_exit(ifp->if_serializer);
+
+       crit_exit();
 }
 
 Static void
@@ -788,16 +783,14 @@ rum_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
        struct mbuf *mnew, *m;
        int len, rssi;
 
-       lwkt_serialize_enter(ifp->if_serializer);
-
-       if (sc->sc_flags & RUM_FLAG_STOPPED) {
-               lwkt_serialize_exit(ifp->if_serializer);
+       if (sc->sc_stopped)
                return;
-       }
+
+       crit_enter();
 
        if (status != USBD_NORMAL_COMPLETION) {
                if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
-                       lwkt_serialize_exit(ifp->if_serializer);
+                       crit_exit();
                        return;
                }
 
@@ -836,8 +829,10 @@ rum_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
        }
 
        m = data->m;
-       data->m = mnew;
-       data->buf = mtod(data->m, uint8_t *);
+       data->m = NULL;
+       data->buf = NULL;
+
+       lwkt_serialize_enter(ifp->if_serializer);
 
        /* finalize mbuf */
        m->m_pkthdr.rcvif = ifp;
@@ -875,6 +870,11 @@ rum_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
        if ((ifp->if_flags & IFF_OACTIVE) == 0)
                ifp->if_start(ifp);
 
+       lwkt_serialize_exit(ifp->if_serializer);
+
+       data->m = mnew;
+       data->buf = mtod(data->m, uint8_t *);
+
        DPRINTFN(15, ("rx done\n"));
 
 skip:  /* setup a new transfer */
@@ -883,7 +883,7 @@ skip:       /* setup a new transfer */
            USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, rum_rxeof);
        usbd_transfer(xfer);
 
-       lwkt_serialize_exit(ifp->if_serializer);
+       crit_exit();
 }
 
 /*
@@ -995,6 +995,7 @@ Static int
 rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
 {
        struct ieee80211com *ic = &sc->sc_ic;
+       struct ifnet *ifp = &ic->ic_if;
        struct rum_tx_desc *desc;
        struct rum_tx_data *data;
        struct ieee80211_frame *wh;
@@ -1074,6 +1075,8 @@ rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
        DPRINTFN(10, ("sending frame len=%u rate=%u xfer len=%u\n",
            m0->m_pkthdr.len + RT2573_TX_DESC_SIZE, rate, xferlen));
 
+       lwkt_serialize_exit(ifp->if_serializer);
+
        usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, xferlen,
            USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RUM_TX_TIMEOUT, rum_txeof);
 
@@ -1082,12 +1085,13 @@ rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
                m_freem(m0);
                data->m = NULL;
                data->ni = NULL;
-               return error;
+       } else {
+               sc->tx_queued++;
+               error = 0;
        }
 
-       sc->tx_queued++;
-
-       return 0;
+       lwkt_serialize_enter(ifp->if_serializer);
+       return error;
 }
 
 Static void
@@ -1098,9 +1102,16 @@ rum_start(struct ifnet *ifp)
 
        ASSERT_SERIALIZED(ifp->if_serializer);
 
-       if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
+       if (sc->sc_stopped)
                return;
 
+       crit_enter();
+
+       if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) {
+               crit_exit();
+               return;
+       }
+
        for (;;) {
                struct ieee80211_node *ni;
                struct mbuf *m0;
@@ -1172,6 +1183,8 @@ rum_start(struct ifnet *ifp)
                sc->sc_tx_timer = 5;
                ifp->if_timer = 1;
        }
+
+       crit_exit();
 }
 
 Static void
@@ -1181,6 +1194,8 @@ rum_watchdog(struct ifnet *ifp)
 
        ASSERT_SERIALIZED(ifp->if_serializer);
 
+       crit_enter();
+
        ifp->if_timer = 0;
 
        if (sc->sc_tx_timer > 0) {
@@ -1188,12 +1203,16 @@ rum_watchdog(struct ifnet *ifp)
                        kprintf("%s: device timeout\n", USBDEVNAME(sc->sc_dev));
                        /*rum_init(sc); XXX needs a process context! */
                        ifp->if_oerrors++;
+
+                       crit_exit();
                        return;
                }
                ifp->if_timer = 1;
        }
 
        ieee80211_watchdog(&sc->sc_ic);
+
+       crit_exit();
 }
 
 Static int
@@ -1205,13 +1224,18 @@ rum_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr)
 
        ASSERT_SERIALIZED(ifp->if_serializer);
 
+       crit_enter();
+
        switch (cmd) {
        case SIOCSIFFLAGS:
                if (ifp->if_flags & IFF_UP) {
-                       if (ifp->if_flags & IFF_RUNNING)
+                       if (ifp->if_flags & IFF_RUNNING) {
+                               lwkt_serialize_exit(ifp->if_serializer);
                                rum_update_promisc(sc);
-                       else
+                               lwkt_serialize_enter(ifp->if_serializer);
+                       } else {
                                rum_init(sc);
+                       }
                } else {
                        if (ifp->if_flags & IFF_RUNNING)
                                rum_stop(sc);
@@ -1234,13 +1258,17 @@ rum_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr)
                         * explicitly reset the interface to generate a new
                         * beacon frame.
                         */
+                       lwkt_serialize_exit(ifp->if_serializer);
                        rum_set_chan(sc, ic->ic_ibss_chan);
+                       lwkt_serialize_enter(ifp->if_serializer);
                } else if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
                           (IFF_UP | IFF_RUNNING)) {
                        rum_init(sc);
                }
                error = 0;
        }
+
+       crit_exit();
        return error;
 }
 
@@ -1823,18 +1851,14 @@ rum_init(void *xsc)
        usbd_status usb_err;
        int i, ntries, error;
 
-       crit_enter();
-
        ASSERT_SERIALIZED(ifp->if_serializer);
 
-       rum_stop(sc);
+       crit_enter();
 
-       tsleep_interlock(&sc->sc_flags);
-       if (sc->sc_flags & RUM_FLAG_CONFIG)
-               tsleep(&sc->sc_flags, 0, "rumcfg", 0);
-       sc->sc_flags |= RUM_FLAG_CONFIG;
+       rum_stop(sc);
+       sc->sc_stopped = 0;
 
-       sc->sc_flags &= ~RUM_FLAG_STOPPED;
+       lwkt_serialize_exit(ifp->if_serializer);
 
        /* initialize MAC registers to default values */
        for (i = 0; i < N(rum_def_mac); i++)
@@ -1865,14 +1889,10 @@ rum_init(void *xsc)
        /* select default channel */
        sc->sc_curchan = ic->ic_curchan = ic->ic_ibss_chan;
 
-       lwkt_serialize_exit(ifp->if_serializer);
-
        rum_select_band(sc, sc->sc_curchan);
        rum_select_antenna(sc);
        rum_set_chan(sc, sc->sc_curchan);
 
-       lwkt_serialize_enter(ifp->if_serializer);
-
        /* clear STA registers */
        rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta);
 
@@ -1942,8 +1962,6 @@ rum_init(void *xsc)
                usbd_transfer(data->xfer);
        }
 
-       lwkt_serialize_exit(ifp->if_serializer);
-
        /* update Rx filter */
        tmp = rum_read(sc, RT2573_TXRX_CSR0) & 0xffff;
 
@@ -1957,25 +1975,22 @@ rum_init(void *xsc)
                        tmp |= RT2573_DROP_NOT_TO_ME;
        }
        rum_write(sc, RT2573_TXRX_CSR0, tmp);
-
+fail:
        lwkt_serialize_enter(ifp->if_serializer);
 
-       ifp->if_flags &= ~IFF_OACTIVE;
-       ifp->if_flags |= IFF_RUNNING;
-
-       if (ic->ic_opmode != IEEE80211_M_MONITOR) {
-               if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
-                       ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
+       if (error) {
+               rum_stop(sc);
        } else {
-               ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
+               ifp->if_flags &= ~IFF_OACTIVE;
+               ifp->if_flags |= IFF_RUNNING;
+
+               if (ic->ic_opmode != IEEE80211_M_MONITOR) {
+                       if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
+                               ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
+               } else {
+                       ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
+               }
        }
-       error = 0;
-fail:
-       sc->sc_flags &= ~RUM_FLAG_CONFIG;
-       if (error)
-               rum_stop(sc);
-       else
-               wakeup(&sc->sc_flags);
 
        crit_exit();
 #undef N
@@ -1988,13 +2003,12 @@ rum_stop(struct rum_softc *sc)
        struct ifnet *ifp = &ic->ic_if;
        uint32_t tmp;
 
-       crit_enter();
-
        ASSERT_SERIALIZED(ifp->if_serializer);
 
-       /* Don't try transmitting/receiving any packets. */
+       crit_enter();
+
        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
-       sc->sc_flags |= RUM_FLAG_STOPPED;
+       sc->sc_stopped = 1;
 
        ieee80211_new_state(ic, IEEE80211_S_INIT, -1);  /* free all nodes */
 
@@ -2003,11 +2017,6 @@ rum_stop(struct rum_softc *sc)
 
        lwkt_serialize_exit(ifp->if_serializer);
 
-       tsleep_interlock(&sc->sc_flags);
-       if (sc->sc_flags & RUM_FLAG_CONFIG)
-               tsleep(&sc->sc_flags, 0, "rumcfg", 0);
-       sc->sc_flags |= RUM_FLAG_CONFIG;
-
        /* disable Rx */
        tmp = rum_read(sc, RT2573_TXRX_CSR0);
        rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX);
@@ -2038,9 +2047,6 @@ rum_stop(struct rum_softc *sc)
        rum_free_rx_list(sc);
        rum_free_tx_list(sc);
 
-       sc->sc_flags &= ~RUM_FLAG_CONFIG;
-       wakeup(&sc->sc_flags);
-
        crit_exit();
 }
 
@@ -2073,12 +2079,16 @@ Static int
 rum_prepare_beacon(struct rum_softc *sc)
 {
        struct ieee80211com *ic = &sc->sc_ic;
+       struct ifnet *ifp = &ic->ic_if;
        struct ieee80211_beacon_offsets bo;
        struct rum_tx_desc desc;
        struct mbuf *m0;
        int rate;
 
+       lwkt_serialize_enter(ifp->if_serializer);
        m0 = ieee80211_beacon_alloc(ic, ic->ic_bss, &bo);
+       lwkt_serialize_exit(ifp->if_serializer);
+
        if (m0 == NULL) {
                if_printf(&ic->ic_if, "could not allocate beacon frame\n");
                return ENOBUFS;
@@ -2106,15 +2116,12 @@ Static void
 rum_stats_timeout(void *arg)
 {
        struct rum_softc *sc = arg;
-       struct ifnet *ifp = &sc->sc_ic.ic_if;
        usb_device_request_t req;
 
-       lwkt_serialize_enter(ifp->if_serializer);
-
-       if (sc->sc_flags & RUM_FLAG_STOPPED) {
-               lwkt_serialize_exit(ifp->if_serializer);
+       if (sc->sc_stopped)
                return;
-       }
+
+       crit_enter();
 
        /*
         * Asynchronously read statistic registers (cleared by read).
@@ -2131,7 +2138,7 @@ rum_stats_timeout(void *arg)
                                rum_stats_update);
        usbd_transfer(sc->stats_xfer);
 
-       lwkt_serialize_exit(ifp->if_serializer);
+       crit_exit();
 }
 
 Static void
@@ -2148,7 +2155,7 @@ rum_stats_update(usbd_xfer_handle xfer, usbd_private_handle priv,
                return;
        }
 
-       lwkt_serialize_enter(ifp->if_serializer);
+       crit_enter();
 
        /* count TX retry-fail as Tx errors */
        ifp->if_oerrors += RUM_TX_PKT_FAIL(sc);
@@ -2175,7 +2182,7 @@ rum_stats_update(usbd_xfer_handle xfer, usbd_private_handle priv,
 
        callout_reset(&sc->stats_ch, 4 * hz / 5, rum_stats_timeout, sc);
 
-       lwkt_serialize_exit(ifp->if_serializer);
+       crit_exit();
 }
 
 Static void
index f167ffb..18bdf0e 100644 (file)
@@ -1,5 +1,5 @@
 /*     $OpenBSD: if_rumvar.h,v 1.6 2006/08/18 15:11:12 damien Exp $    */
-/*     $DragonFly: src/sys/dev/netif/rum/if_rumvar.h,v 1.3 2007/04/08 09:41:41 sephe Exp $     */
+/*     $DragonFly: src/sys/dev/netif/rum/if_rumvar.h,v 1.4 2007/05/27 10:53:29 sephe Exp $     */
 
 /*-
  * Copyright (c) 2005, 2006 Damien Bergamini <damien.bergamini@free.fr>
@@ -76,11 +76,7 @@ struct rum_softc {
        int                             (*sc_newstate)(struct ieee80211com *,
                                            enum ieee80211_state, int);
 
-       uint32_t                        sc_flags;
-#define RUM_FLAG_SYNCTASK      0x1
-#define RUM_FLAG_STOPPED       0x2
-#define RUM_FLAG_DETACHED      0x4
-#define RUM_FLAG_CONFIG                0x8
+       int                             sc_stopped;
 
        usbd_device_handle              sc_udev;
        usbd_interface_handle           sc_iface;
index af3e2e3..569c0ce 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/dev/usb/if_ural.c,v 1.10.2.8 2006/07/08 07:48:43 maxim Exp $  */
-/*     $DragonFly: src/sys/dev/netif/ural/if_ural.c,v 1.12 2007/05/27 02:45:48 sephe Exp $     */
+/*     $DragonFly: src/sys/dev/netif/ural/if_ural.c,v 1.13 2007/05/27 10:53:29 sephe Exp $     */
 
 /*-
  * Copyright (c) 2005, 2006
@@ -533,14 +533,13 @@ USB_DETACH(ural)
        int i;
 #endif
 
-       lwkt_serialize_enter(ifp->if_serializer);
+       crit_enter();
 
        callout_stop(&sc->scan_ch);
        callout_stop(&sc->stats_ch);
 
-       sc->sc_flags |= URAL_FLAG_SYNCTASK;
+       lwkt_serialize_enter(ifp->if_serializer);
        ural_stop(sc);
-
        lwkt_serialize_exit(ifp->if_serializer);
 
        usb_rem_task(sc->sc_udev, &sc->sc_task);
@@ -548,6 +547,8 @@ USB_DETACH(ural)
        bpfdetach(ifp);
        ieee80211_ifdetach(ic);
 
+       crit_exit();
+
        KKASSERT(sc->stats_xfer == NULL);
        KKASSERT(sc->sc_rx_pipeh == NULL);
        KKASSERT(sc->sc_tx_pipeh == NULL);
@@ -711,12 +712,18 @@ ural_next_scan(void *arg)
        struct ieee80211com *ic = &sc->sc_ic;
        struct ifnet *ifp = &ic->ic_if;
 
-       lwkt_serialize_enter(ifp->if_serializer);
+       if (sc->sc_stopped)
+               return;
+
+       crit_enter();
 
-       if (ic->ic_state == IEEE80211_S_SCAN)
+       if (ic->ic_state == IEEE80211_S_SCAN) {
+               lwkt_serialize_enter(ifp->if_serializer);
                ieee80211_next_scan(ic);
+               lwkt_serialize_exit(ifp->if_serializer);
+       }
 
-       lwkt_serialize_exit(ifp->if_serializer);
+       crit_exit();
 }
 
 Static void
@@ -725,49 +732,27 @@ ural_task(void *xarg)
        struct ural_softc *sc = xarg;
        struct ieee80211com *ic = &sc->sc_ic;
        struct ifnet *ifp = &ic->ic_if;
-       enum ieee80211_state ostate;
+       enum ieee80211_state nstate;
        struct ieee80211_node *ni;
        struct mbuf *m;
        int arg;
 
-       lwkt_serialize_enter(ifp->if_serializer);
-
-       ieee80211_ratectl_newstate(ic, sc->sc_state);
-
-       ostate = ic->ic_state;
-       arg = sc->sc_newstate_arg;
-
-       switch (sc->sc_state) {
-       case IEEE80211_S_INIT:
-               if (ostate == IEEE80211_S_RUN) {
-                       /* abort TSF synchronization */
-                       ural_write(sc, RAL_TXRX_CSR19, 0);
-
-                       /* force tx led to stop blinking */
-                       ural_write(sc, RAL_MAC_CSR20, 0);
-               }
-               break;
+       if (sc->sc_stopped)
+               return;
 
-       case IEEE80211_S_SCAN:
-               ural_set_chan(sc, ic->ic_curchan);
-               callout_reset(&sc->scan_ch, hz / 5, ural_next_scan, sc);
-               break;
+       crit_enter();
 
-       case IEEE80211_S_AUTH:
-               ural_set_chan(sc, ic->ic_curchan);
-               break;
+       nstate = sc->sc_state;
+       arg = sc->sc_arg;
 
-       case IEEE80211_S_ASSOC:
-               ural_set_chan(sc, ic->ic_curchan);
-               break;
+       KASSERT(nstate != IEEE80211_S_INIT,
+               ("->INIT state transition should not be defered\n"));
+       ural_set_chan(sc, ic->ic_curchan);
 
+       switch (sc->sc_state) {
        case IEEE80211_S_RUN:
-               ural_set_chan(sc, ic->ic_curchan);
-
                ni = ic->ic_bss;
 
-               lwkt_serialize_exit(ifp->if_serializer);
-
                if (ic->ic_opmode != IEEE80211_M_MONITOR) {
                        ural_update_slot(&ic->ic_if);
                        ural_set_txpreamble(sc);
@@ -777,16 +762,21 @@ ural_task(void *xarg)
 
                if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
                    ic->ic_opmode == IEEE80211_M_IBSS) {
+                       lwkt_serialize_enter(ifp->if_serializer);
                        m = ieee80211_beacon_alloc(ic, ni, &sc->sc_bo);
+                       lwkt_serialize_exit(ifp->if_serializer);
+
                        if (m == NULL) {
                                kprintf("%s: could not allocate beacon\n",
                                    USBDEVNAME(sc->sc_dev));
+                               crit_exit();
                                return;
                        }
 
                        if (ural_tx_bcn(sc, m, ni) != 0) {
                                kprintf("%s: could not send beacon\n",
                                    USBDEVNAME(sc->sc_dev));
+                               crit_exit();
                                return;
                        }
                }
@@ -800,17 +790,24 @@ ural_task(void *xarg)
                /* clear statistic registers (STA_CSR0 to STA_CSR10) */
                ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof(sc->sta));
 
-               lwkt_serialize_enter(ifp->if_serializer);
-
                callout_reset(&sc->stats_ch, 4 * hz / 5,
                              ural_stats_timeout, sc);
+               break;
 
+       case IEEE80211_S_SCAN:
+               callout_reset(&sc->scan_ch, hz / 5, ural_next_scan, sc);
+               break;
+
+       default:
                break;
        }
 
+       lwkt_serialize_enter(ifp->if_serializer);
+       ieee80211_ratectl_newstate(ic, sc->sc_state);
        sc->sc_newstate(ic, sc->sc_state, arg);
-
        lwkt_serialize_exit(ifp->if_serializer);
+
+       crit_exit();
 }
 
 Static int
@@ -821,24 +818,28 @@ ural_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
 
        ASSERT_SERIALIZED(ifp->if_serializer);
 
+       crit_enter();
+
        callout_stop(&sc->scan_ch);
        callout_stop(&sc->stats_ch);
 
        /* do it in a process context */
        sc->sc_state = nstate;
-       sc->sc_newstate_arg = arg;
+       sc->sc_arg = arg;
 
        lwkt_serialize_exit(ifp->if_serializer);
        usb_rem_task(sc->sc_udev, &sc->sc_task);
 
-       if (sc->sc_flags & URAL_FLAG_SYNCTASK) {
-               usb_do_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER,
-                           USBD_NO_TIMEOUT);
+       if (nstate == IEEE80211_S_INIT) {
+               lwkt_serialize_enter(ifp->if_serializer);
+               ieee80211_ratectl_newstate(ic, nstate);
+               sc->sc_newstate(ic, nstate, arg);
        } else {
                usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER);
+               lwkt_serialize_enter(ifp->if_serializer);
        }
-       lwkt_serialize_enter(ifp->if_serializer);
 
+       crit_exit();
        return 0;
 }
 
@@ -885,11 +886,19 @@ ural_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
 {
        struct ural_tx_data *data = priv;
        struct ural_softc *sc = data->sc;
+       struct ieee80211_node *ni;
        struct ifnet *ifp = &sc->sc_ic.ic_if;
 
+       if (sc->sc_stopped)
+               return;
+
+       crit_enter();
+
        if (status != USBD_NORMAL_COMPLETION) {
-               if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
+               if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
+                       crit_exit();
                        return;
+               }
 
                kprintf("%s: could not transmit buffer: %s\n",
                    USBDEVNAME(sc->sc_dev), usbd_errstr(status));
@@ -898,14 +907,13 @@ ural_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
                        usbd_clear_endpoint_stall_async(sc->sc_rx_pipeh);
 
                ifp->if_oerrors++;
+               crit_exit();
                return;
        }
 
-       lwkt_serialize_enter(ifp->if_serializer);
-
        m_freem(data->m);
        data->m = NULL;
-       ieee80211_free_node(data->ni);
+       ni = data->ni;
        data->ni = NULL;
 
        sc->tx_queued--;
@@ -915,9 +923,13 @@ ural_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
 
        sc->sc_tx_timer = 0;
        ifp->if_flags &= ~IFF_OACTIVE;
-       ural_start(ifp);
 
+       lwkt_serialize_enter(ifp->if_serializer);
+       ieee80211_free_node(ni);
+       ifp->if_start(ifp);
        lwkt_serialize_exit(ifp->if_serializer);
+
+       crit_exit();
 }
 
 Static void
@@ -933,9 +945,16 @@ ural_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
        struct mbuf *mnew, *m;
        int len;
 
+       if (sc->sc_stopped)
+               return;
+
+       crit_enter();
+
        if (status != USBD_NORMAL_COMPLETION) {
-               if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
+               if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
+                       crit_exit();
                        return;
+               }
 
                if (status == USBD_STALLED)
                        usbd_clear_endpoint_stall_async(sc->sc_rx_pipeh);
@@ -972,15 +991,15 @@ ural_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
        }
 
        m = data->m;
-       data->m = mnew;
-       data->buf = mtod(data->m, uint8_t *);
+       data->m = NULL;
+       data->buf = NULL;
+
+       lwkt_serialize_enter(ifp->if_serializer);
 
        /* finalize mbuf */
        m->m_pkthdr.rcvif = ifp;
        m->m_pkthdr.len = m->m_len = (le32toh(desc->flags) >> 16) & 0xfff;
 
-       lwkt_serialize_enter(ifp->if_serializer);
-
        if (sc->sc_drvbpf != NULL) {
                struct ural_rx_radiotap_header *tap = &sc->sc_rxtap;
 
@@ -1006,14 +1025,19 @@ ural_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
        /* node is no longer needed */
        ieee80211_free_node(ni);
 
-       DPRINTFN(15, ("rx done\n"));
-
        lwkt_serialize_exit(ifp->if_serializer);
 
+       data->m = mnew;
+       data->buf = mtod(data->m, uint8_t *);
+
+       DPRINTFN(15, ("rx done\n"));
+
 skip:  /* setup a new transfer */
        usbd_setup_xfer(xfer, sc->sc_rx_pipeh, data, data->buf, MCLBYTES,
            USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, ural_rxeof);
        usbd_transfer(xfer);
+
+       crit_exit();
 }
 
 Static uint8_t
@@ -1143,6 +1167,7 @@ Static int
 ural_tx_mgt(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
 {
        struct ieee80211com *ic = &sc->sc_ic;
+       struct ifnet *ifp = &ic->ic_if;
        struct ural_tx_desc *desc;
        struct ural_tx_data *data;
        struct ieee80211_frame *wh;
@@ -1204,6 +1229,8 @@ ural_tx_mgt(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
        DPRINTFN(10, ("sending mgt frame len=%u rate=%u xfer len=%u\n",
            m0->m_pkthdr.len, rate, xferlen));
 
+       lwkt_serialize_exit(ifp->if_serializer);
+
        usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf,
            xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RAL_TX_TIMEOUT,
            ural_txeof);
@@ -1213,17 +1240,20 @@ ural_tx_mgt(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
                m_freem(m0);
                data->m = NULL;
                data->ni = NULL;
-               return error;
+       } else {
+               sc->tx_queued++;
+               error = 0;
        }
 
-       sc->tx_queued++;
-       return 0;
+       lwkt_serialize_enter(ifp->if_serializer);
+       return error;
 }
 
 Static int
 ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
 {
        struct ieee80211com *ic = &sc->sc_ic;
+       struct ifnet *ifp = &ic->ic_if;
        struct ural_tx_desc *desc;
        struct ural_tx_data *data;
        struct ieee80211_frame *wh;
@@ -1293,6 +1323,8 @@ ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
        DPRINTFN(10, ("sending data frame len=%u rate=%u xfer len=%u\n",
            m0->m_pkthdr.len, rate, xferlen));
 
+       lwkt_serialize_exit(ifp->if_serializer);
+
        usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf,
            xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RAL_TX_TIMEOUT,
            ural_txeof);
@@ -1302,11 +1334,13 @@ ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
                m_freem(m0);
                data->m = NULL;
                data->ni = NULL;
-               return error;
+       } else {
+               sc->tx_queued++;
+               error = 0;
        }
 
-       sc->tx_queued++;
-       return 0;
+       lwkt_serialize_enter(ifp->if_serializer);
+       return error;
 }
 
 Static void
@@ -1317,9 +1351,16 @@ ural_start(struct ifnet *ifp)
 
        ASSERT_SERIALIZED(ifp->if_serializer);
 
-       if ((ifp->if_flags & (IFF_OACTIVE | IFF_RUNNING)) != IFF_RUNNING)
+       if (sc->sc_stopped)
                return;
 
+       crit_enter();
+
+       if ((ifp->if_flags & (IFF_OACTIVE | IFF_RUNNING)) != IFF_RUNNING) {
+               crit_exit();
+               return;
+       }
+
        for (;;) {
                struct ieee80211_node *ni;
                struct mbuf *m0;
@@ -1391,6 +1432,8 @@ ural_start(struct ifnet *ifp)
                sc->sc_tx_timer = 5;
                ifp->if_timer = 1;
        }
+
+       crit_exit();
 }
 
 Static void
@@ -1401,6 +1444,8 @@ ural_watchdog(struct ifnet *ifp)
 
        ASSERT_SERIALIZED(ifp->if_serializer);
 
+       crit_enter();
+
        ifp->if_timer = 0;
 
        if (sc->sc_tx_timer > 0) {
@@ -1408,12 +1453,15 @@ ural_watchdog(struct ifnet *ifp)
                        device_printf(sc->sc_dev, "device timeout\n");
                        /*ural_init(sc); XXX needs a process context! */
                        ifp->if_oerrors++;
+
+                       crit_exit();
                        return;
                }
                ifp->if_timer = 1;
        }
-
        ieee80211_watchdog(ic);
+
+       crit_exit();
 }
 
 /*
@@ -1427,10 +1475,18 @@ ural_reset(struct ifnet *ifp)
        struct ural_softc *sc = ifp->if_softc;
        struct ieee80211com *ic = &sc->sc_ic;
 
+       ASSERT_SERIALIZED(ifp->if_serializer);
+
        if (ic->ic_opmode != IEEE80211_M_MONITOR)
                return ENETRESET;
 
+       crit_enter();
+
+       lwkt_serialize_exit(ifp->if_serializer);
        ural_set_chan(sc, ic->ic_curchan);
+       lwkt_serialize_enter(ifp->if_serializer);
+
+       crit_exit();
 
        return 0;
 }
@@ -1444,13 +1500,18 @@ ural_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr)
 
        ASSERT_SERIALIZED(ifp->if_serializer);
 
+       crit_enter();
+
        switch (cmd) {
        case SIOCSIFFLAGS:
                if (ifp->if_flags & IFF_UP) {
-                       if (ifp->if_flags & IFF_RUNNING)
+                       if (ifp->if_flags & IFF_RUNNING) {
+                               lwkt_serialize_exit(ifp->if_serializer);
                                ural_update_promisc(sc);
-                       else
+                               lwkt_serialize_enter(ifp->if_serializer);
+                       } else {
                                ural_init(sc);
+                       }
                } else {
                        if (ifp->if_flags & IFF_RUNNING)
                                ural_stop(sc);
@@ -1468,6 +1529,8 @@ ural_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr)
                        ural_init(sc);
                error = 0;
        }
+
+       crit_exit();
        return error;
 }
 
@@ -1658,18 +1721,13 @@ Static void
 ural_set_chan(struct ural_softc *sc, struct ieee80211_channel *c)
 {
        struct ieee80211com *ic = &sc->sc_ic;
-       struct ifnet *ifp = &ic->ic_if;
        uint8_t power, tmp;
        u_int i, chan;
 
-       ASSERT_SERIALIZED(ifp->if_serializer);
-
        chan = ieee80211_chan2ieee(ic, c);
        if (chan == 0 || chan == IEEE80211_CHAN_ANY)
                return;
 
-       lwkt_serialize_exit(ifp->if_serializer);
-
        if (IEEE80211_IS_CHAN_2GHZ(c))
                power = min(sc->txpow[chan - 1], 31);
        else
@@ -1762,8 +1820,6 @@ ural_set_chan(struct ural_softc *sc, struct ieee80211_channel *c)
 
        sc->sc_sifs = IEEE80211_IS_CHAN_5GHZ(c) ? IEEE80211_DUR_OFDM_SIFS
                                                : IEEE80211_DUR_SIFS;
-
-       lwkt_serialize_enter(ifp->if_serializer);
 }
 
 /*
@@ -2059,15 +2115,22 @@ ural_init(void *priv)
        struct ifnet *ifp = &ic->ic_if;
        struct ural_rx_data *data;
        uint16_t tmp;
-       usbd_status error;
-       int i, ntries;
+       usbd_status usb_err;
+       int i, ntries, error;
 
        ASSERT_SERIALIZED(ifp->if_serializer);
 
+       crit_enter();
+
+       lwkt_serialize_exit(ifp->if_serializer);
        ural_set_testmode(sc);
        ural_write(sc, 0x308, 0x00f0);  /* XXX magic */
+       lwkt_serialize_enter(ifp->if_serializer);
 
        ural_stop(sc);
+       sc->sc_stopped = 0;
+
+       lwkt_serialize_exit(ifp->if_serializer);
 
        /* initialize MAC registers to default values */
        for (i = 0; i < N(ural_def_mac); i++)
@@ -2084,6 +2147,7 @@ ural_init(void *priv)
        if (ntries == 100) {
                kprintf("%s: timeout waiting for BBP/RF to wakeup\n",
                    USBDEVNAME(sc->sc_dev));
+               error = ETIMEDOUT;
                goto fail;
        }
 
@@ -2093,7 +2157,8 @@ ural_init(void *priv)
        /* set basic rate set (will be updated later) */
        ural_write(sc, RAL_TXRX_CSR11, 0x15f);
 
-       if (ural_bbp_init(sc) != 0)
+       error = ural_bbp_init(sc);
+       if (error)
                goto fail;
 
        /* set default BSS channel */
@@ -2115,25 +2180,28 @@ ural_init(void *priv)
        if (sc->stats_xfer == NULL) {
                kprintf("%s: could not allocate AMRR xfer\n",
                    USBDEVNAME(sc->sc_dev));
+               error = ENOMEM;
                goto fail;
        }
 
        /*
         * Open Tx and Rx USB bulk pipes.
         */
-       error = usbd_open_pipe(sc->sc_iface, sc->sc_tx_no, USBD_EXCLUSIVE_USE,
+       usb_err = usbd_open_pipe(sc->sc_iface, sc->sc_tx_no, USBD_EXCLUSIVE_USE,
            &sc->sc_tx_pipeh);
-       if (error != 0) {
+       if (usb_err != 0) {
                kprintf("%s: could not open Tx pipe: %s\n",
-                   USBDEVNAME(sc->sc_dev), usbd_errstr(error));
+                   USBDEVNAME(sc->sc_dev), usbd_errstr(usb_err));
+               error = ENOMEM;
                goto fail;
        }
 
-       error = usbd_open_pipe(sc->sc_iface, sc->sc_rx_no, USBD_EXCLUSIVE_USE,
+       usb_err = usbd_open_pipe(sc->sc_iface, sc->sc_rx_no, USBD_EXCLUSIVE_USE,
            &sc->sc_rx_pipeh);
-       if (error != 0) {
+       if (usb_err != 0) {
                kprintf("%s: could not open Rx pipe: %s\n",
-                   USBDEVNAME(sc->sc_dev), usbd_errstr(error));
+                   USBDEVNAME(sc->sc_dev), usbd_errstr(usb_err));
+               error = ENOMEM;
                goto fail;
        }
 
@@ -2141,14 +2209,14 @@ ural_init(void *priv)
         * Allocate Tx and Rx xfer queues.
         */
        error = ural_alloc_tx_list(sc);
-       if (error != 0) {
+       if (error) {
                kprintf("%s: could not allocate Tx list\n",
                    USBDEVNAME(sc->sc_dev));
                goto fail;
        }
 
        error = ural_alloc_rx_list(sc);
-       if (error != 0) {
+       if (error) {
                kprintf("%s: could not allocate Rx list\n",
                    USBDEVNAME(sc->sc_dev));
                goto fail;
@@ -2176,21 +2244,25 @@ ural_init(void *priv)
        }
        ural_write(sc, RAL_TXRX_CSR2, tmp);
 
-       ifp->if_flags &= ~IFF_OACTIVE;
-       ifp->if_flags |= IFF_RUNNING;
-
        /* clear statistic registers (STA_CSR0 to STA_CSR10) */
        ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof(sc->sta));
+fail:
+       lwkt_serialize_enter(ifp->if_serializer);
+       if (error) {
+               ural_stop(sc);
+       } else {
+               ifp->if_flags &= ~IFF_OACTIVE;
+               ifp->if_flags |= IFF_RUNNING;
 
-       if (ic->ic_opmode != IEEE80211_M_MONITOR) {
-               if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
-                       ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
-       } else
-               ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
-
-       return;
+               if (ic->ic_opmode != IEEE80211_M_MONITOR) {
+                       if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
+                               ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
+               } else {
+                       ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
+               }
+       }
 
-fail:  ural_stop(sc);
+       crit_exit();
 #undef N
 }
 
@@ -2202,11 +2274,17 @@ ural_stop(struct ural_softc *sc)
 
        ASSERT_SERIALIZED(ifp->if_serializer);
 
+       crit_enter();
+
+       ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
+       sc->sc_stopped = 1;
+
        ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
 
        sc->sc_tx_timer = 0;
        ifp->if_timer = 0;
-       ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
+
+       lwkt_serialize_exit(ifp->if_serializer);
 
        /* disable Rx */
        ural_write(sc, RAL_TXRX_CSR2, RAL_DISABLE_RX);
@@ -2232,18 +2310,24 @@ ural_stop(struct ural_softc *sc)
                sc->sc_tx_pipeh = NULL;
        }
 
+       lwkt_serialize_enter(ifp->if_serializer);
+
        ural_free_rx_list(sc);
        ural_free_tx_list(sc);
+
+       crit_exit();
 }
 
 Static void
 ural_stats_timeout(void *arg)
 {
        struct ural_softc *sc = (struct ural_softc *)arg;
-       struct ifnet *ifp = &sc->sc_ic.ic_if;
        usb_device_request_t req;
 
-       lwkt_serialize_enter(ifp->if_serializer);
+       if (sc->sc_stopped)
+               return;
+
+       crit_enter();
 
        /*
         * Asynchronously read statistic registers (cleared by read).
@@ -2260,7 +2344,7 @@ ural_stats_timeout(void *arg)
                                ural_stats_update);
        usbd_transfer(sc->stats_xfer);
 
-       lwkt_serialize_exit(ifp->if_serializer);
+       crit_exit();
 }
 
 Static void
@@ -2277,7 +2361,7 @@ ural_stats_update(usbd_xfer_handle xfer, usbd_private_handle priv,
                return;
        }
 
-       lwkt_serialize_enter(ifp->if_serializer);
+       crit_enter();
 
        /* count TX retry-fail as Tx errors */
        ifp->if_oerrors += sc->sta[RAL_TX_PKT_FAIL];
@@ -2306,7 +2390,7 @@ ural_stats_update(usbd_xfer_handle xfer, usbd_private_handle priv,
 
        callout_reset(&sc->stats_ch, 4 * hz / 5, ural_stats_timeout, sc);
 
-       lwkt_serialize_exit(ifp->if_serializer);
+       crit_exit();
 }
 
 Static void
index 9ce8531..aebeeb7 100644 (file)
@@ -1,5 +1,5 @@
 /*     $FreeBSD: src/sys/dev/usb/if_uralvar.h,v 1.3.2.3 2006/01/29 14:16:36 damien Exp $       */
-/*     $DragonFly: src/sys/dev/netif/ural/if_uralvar.h,v 1.4 2007/05/26 22:07:18 sephe Exp $   */
+/*     $DragonFly: src/sys/dev/netif/ural/if_uralvar.h,v 1.5 2007/05/27 10:53:29 sephe Exp $   */
 
 /*-
  * Copyright (c) 2005, 2006
@@ -72,8 +72,7 @@ struct ural_rx_data {
 
 struct ural_softc {
        struct ieee80211com             sc_ic;
-       uint32_t                        sc_flags;
-#define URAL_FLAG_SYNCTASK     0x1
+       int                             sc_stopped;
 
        int                             (*sc_newstate)(struct ieee80211com *,
                                            enum ieee80211_state, int);
@@ -93,7 +92,7 @@ struct ural_softc {
        usbd_pipe_handle                sc_tx_pipeh;
 
        enum ieee80211_state            sc_state;
-       int                             sc_newstate_arg;
+       int                             sc_arg;
        int                             sc_sifs;
        struct usb_task                 sc_task;