summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/wlan/if_zyd.c
diff options
context:
space:
mode:
authorthompsa <thompsa@FreeBSD.org>2009-05-02 15:14:18 +0000
committerthompsa <thompsa@FreeBSD.org>2009-05-02 15:14:18 +0000
commited7c3176b96444dc82c6a07114013192611024f3 (patch)
tree46c2c9933cb1753f24ffd7c0096b2ba9074180d2 /sys/dev/usb/wlan/if_zyd.c
parentb704e6092a4076e74c276c0d531447a8cb3bf6a6 (diff)
downloadFreeBSD-src-ed7c3176b96444dc82c6a07114013192611024f3.zip
FreeBSD-src-ed7c3176b96444dc82c6a07114013192611024f3.tar.gz
Create a taskqueue for each wireless interface which provides a serialised
sleepable context for net80211 driver callbacks. This removes the need for USB and firmware based drivers to roll their own code to defer the chip programming for state changes, scan requests, channel changes and mcast/promisc updates. When a driver callback completes the hardware state is now guaranteed to have been updated and is in sync with net80211 layer. This nukes around 1300 lines of code from the wireless device drivers making them more readable and less race prone. The net80211 layer has been updated as follows - all state/channel changes are serialised on the taskqueue. - ieee80211_new_state() always queues and can now be called from any context - scanning runs from a single taskq function and executes to completion. driver callbacks are synchronous so the channel, phy mode and rx filters are guaranteed to be set in hardware before probe request frames are transmitted. Help and contributions from Sam Leffler. Reviewed by: sam
Diffstat (limited to 'sys/dev/usb/wlan/if_zyd.c')
-rw-r--r--sys/dev/usb/wlan/if_zyd.c361
1 files changed, 92 insertions, 269 deletions
diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c
index 6858d55..c386ea8 100644
--- a/sys/dev/usb/wlan/if_zyd.c
+++ b/sys/dev/usb/wlan/if_zyd.c
@@ -26,20 +26,56 @@ __FBSDID("$FreeBSD$");
* ZyDAS ZD1211/ZD1211B USB WLAN driver.
*/
-#include "usbdevs.h"
+#include <sys/param.h>
+#include <sys/sockio.h>
+#include <sys/sysctl.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/kdb.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
+
+#include <net/bpf.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/ethernet.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_types.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/if_ether.h>
+#include <netinet/ip.h>
+#endif
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_regdomain.h>
+#include <net80211/ieee80211_radiotap.h>
+#include <net80211/ieee80211_amrr.h>
+
#include <dev/usb/usb.h>
-#include <dev/usb/usb_mfunc.h>
#include <dev/usb/usb_error.h>
-
#include <dev/usb/usb_core.h>
#include <dev/usb/usb_lookup.h>
-#include <dev/usb/usb_process.h>
#include <dev/usb/usb_debug.h>
#include <dev/usb/usb_request.h>
#include <dev/usb/usb_busdma.h>
#include <dev/usb/usb_util.h>
+#include "usbdevs.h"
-#include <dev/usb/wlan/usb_wlan.h>
#include <dev/usb/wlan/if_zydreg.h>
#include <dev/usb/wlan/if_zydfw.h>
@@ -74,7 +110,7 @@ enum {
#endif
#define zyd_do_request(sc,req,data) \
- usb2_do_request_proc((sc)->sc_udev, &(sc)->sc_tq, req, data, 0, NULL, 5000)
+ usb2_do_request_flags((sc)->sc_udev, &(sc)->sc_mtx, req, data, 0, NULL, 5000)
static device_probe_t zyd_match;
static device_attach_t zyd_attach;
@@ -85,14 +121,6 @@ static usb2_callback_t zyd_intr_write_callback;
static usb2_callback_t zyd_bulk_read_callback;
static usb2_callback_t zyd_bulk_write_callback;
-static usb2_proc_callback_t zyd_attach_post;
-static usb2_proc_callback_t zyd_task;
-static usb2_proc_callback_t zyd_scantask;
-static usb2_proc_callback_t zyd_multitask;
-static usb2_proc_callback_t zyd_init_task;
-static usb2_proc_callback_t zyd_stop_task;
-static usb2_proc_callback_t zyd_flush_task;
-
static struct ieee80211vap *zyd_vap_create(struct ieee80211com *,
const char name[IFNAMSIZ], int unit, int opmode,
int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
@@ -137,7 +165,9 @@ static void zyd_start(struct ifnet *);
static int zyd_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
static int zyd_ioctl(struct ifnet *, u_long, caddr_t);
+static void zyd_init_locked(struct zyd_softc *);
static void zyd_init(void *);
+static void zyd_stop(struct zyd_softc *);
static int zyd_loadfirmware(struct zyd_softc *);
static void zyd_newassoc(struct ieee80211_node *, int);
static void zyd_scan_start(struct ieee80211com *);
@@ -166,8 +196,6 @@ static int zyd_maxim_set_channel(struct zyd_rf *, uint8_t);
static int zyd_maxim2_init(struct zyd_rf *);
static int zyd_maxim2_switch_radio(struct zyd_rf *, int);
static int zyd_maxim2_set_channel(struct zyd_rf *, uint8_t);
-static void zyd_queue_command(struct zyd_softc *, usb2_proc_callback_t *,
- struct usb2_proc_msg *, struct usb2_proc_msg *);
static const struct zyd_phy_pair zyd_def_phy[] = ZYD_DEF_PHY;
static const struct zyd_phy_pair zyd_def_phyB[] = ZYD_DEF_PHYB;
@@ -307,8 +335,10 @@ zyd_attach(device_t dev)
{
struct usb2_attach_arg *uaa = device_get_ivars(dev);
struct zyd_softc *sc = device_get_softc(dev);
+ struct ifnet *ifp;
+ struct ieee80211com *ic;
+ uint8_t iface_index, bands;
int error;
- uint8_t iface_index;
if (uaa->info.bcdDevice < 0x4330) {
device_printf(dev, "device version mismatch: 0x%X "
@@ -324,7 +354,6 @@ zyd_attach(device_t dev)
mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev),
MTX_NETWORK_LOCK, MTX_DEF);
- cv_init(&sc->sc_cmd_cv, "wtxdone");
STAILQ_INIT(&sc->sc_rqh);
iface_index = ZYD_IFACE_INDEX;
@@ -336,52 +365,19 @@ zyd_attach(device_t dev)
"err=%s\n", usb2_errstr(error));
goto detach;
}
- error = usb2_proc_create(&sc->sc_tq, &sc->sc_mtx,
- device_get_nameunit(dev), USB_PRI_MED);
- if (error) {
- device_printf(dev, "could not setup config thread!\n");
- goto detach;
- }
- /* fork rest of the attach code */
ZYD_LOCK(sc);
- zyd_queue_command(sc, zyd_attach_post,
- &sc->sc_synctask[0].hdr,
- &sc->sc_synctask[1].hdr);
- ZYD_UNLOCK(sc);
- return (0);
-
-detach:
- zyd_detach(dev);
- return (ENXIO); /* failure */
-}
-
-static void
-zyd_attach_post(struct usb2_proc_msg *pm)
-{
- struct zyd_task *task = (struct zyd_task *)pm;
- struct zyd_softc *sc = task->sc;
- struct ifnet *ifp;
- struct ieee80211com *ic;
- int error;
- uint8_t bands;
-
if ((error = zyd_get_macaddr(sc)) != 0) {
device_printf(sc->sc_dev, "could not read EEPROM\n");
- return;
+ ZYD_UNLOCK(sc);
+ goto detach;
}
-
- /* XXX Async attach race */
- if (usb2_proc_is_gone(&sc->sc_tq))
- return;
-
ZYD_UNLOCK(sc);
ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
if (ifp == NULL) {
device_printf(sc->sc_dev, "can not if_alloc()\n");
- ZYD_LOCK(sc);
- return;
+ goto detach;
}
ifp->if_softc = sc;
if_initname(ifp, "zyd", device_get_unit(sc->sc_dev));
@@ -437,7 +433,11 @@ zyd_attach_post(struct usb2_proc_msg *pm)
if (bootverbose)
ieee80211_announce(ic);
- ZYD_LOCK(sc);
+ return (0);
+
+detach:
+ zyd_detach(dev);
+ return (ENXIO); /* failure */
}
static int
@@ -447,12 +447,8 @@ zyd_detach(device_t dev)
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic;
- /* wait for any post attach or other command to complete */
- usb2_proc_drain(&sc->sc_tq);
-
/* 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);
@@ -463,7 +459,6 @@ zyd_detach(device_t dev)
ieee80211_ifdetach(ic);
if_free(ifp);
}
- cv_destroy(&sc->sc_cmd_cv);
mtx_destroy(&sc->sc_mtx);
return (0);
@@ -475,7 +470,6 @@ zyd_vap_create(struct ieee80211com *ic,
const uint8_t bssid[IEEE80211_ADDR_LEN],
const uint8_t mac[IEEE80211_ADDR_LEN])
{
- struct zyd_softc *sc = ic->ic_ifp->if_softc;
struct zyd_vap *zvp;
struct ieee80211vap *vap;
@@ -494,7 +488,6 @@ zyd_vap_create(struct ieee80211com *ic,
zvp->newstate = vap->iv_newstate;
vap->iv_newstate = zyd_newstate;
- zvp->sc = sc;
ieee80211_amrr_init(&zvp->amrr, vap,
IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
@@ -508,23 +501,9 @@ zyd_vap_create(struct ieee80211com *ic,
}
static void
-zyd_flush_task(struct usb2_proc_msg *_pm)
-{
- /* nothing to do */
-}
-
-static void
zyd_vap_delete(struct ieee80211vap *vap)
{
struct zyd_vap *zvp = ZYD_VAP(vap);
- struct zyd_softc *sc = zvp->sc;
-
- ZYD_LOCK(sc);
- /* wait for any pending tasks to complete */
- zyd_queue_command(sc, zyd_flush_task,
- &sc->sc_synctask[0].hdr,
- &sc->sc_synctask[1].hdr);
- ZYD_UNLOCK(sc);
ieee80211_amrr_cleanup(&zvp->amrr);
ieee80211_vap_detach(vap);
@@ -606,34 +585,38 @@ zyd_node_alloc(struct ieee80211vap *vap __unused,
return (zn != NULL) ? (&zn->ni) : (NULL);
}
-static void
-zyd_task(struct usb2_proc_msg *pm)
+static int
+zyd_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
{
- struct zyd_task *task = (struct zyd_task *)pm;
- struct zyd_softc *sc = task->sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
- struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
- struct ieee80211_node *ni = vap->iv_bss;
struct zyd_vap *zvp = ZYD_VAP(vap);
+ struct ieee80211com *ic = vap->iv_ic;
+ struct zyd_softc *sc = ic->ic_ifp->if_softc;
+ struct ieee80211_node *ni;
int error;
- switch (sc->sc_state) {
+ DPRINTF(sc, ZYD_DEBUG_STATE, "%s: %s -> %s\n", __func__,
+ ieee80211_state_name[vap->iv_state],
+ ieee80211_state_name[nstate]);
+
+ IEEE80211_UNLOCK(ic);
+ ZYD_LOCK(sc);
+ switch (nstate) {
case IEEE80211_S_AUTH:
zyd_set_chan(sc, ic->ic_curchan);
break;
case IEEE80211_S_RUN:
+ ni = vap->iv_bss;
if (vap->iv_opmode == IEEE80211_M_MONITOR)
break;
/* turn link LED on */
error = zyd_set_led(sc, ZYD_LED1, 1);
if (error != 0)
- goto fail;
-
+ break;
+
/* make data LED blink upon Tx */
zyd_write32_m(sc, sc->sc_fwbase + ZYD_FW_LINK_STATUS, 1);
-
+
IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid);
zyd_set_bssid(sc, sc->sc_bssid);
break;
@@ -643,40 +626,7 @@ zyd_task(struct usb2_proc_msg *pm)
fail:
ZYD_UNLOCK(sc);
IEEE80211_LOCK(ic);
- zvp->newstate(vap, sc->sc_state, sc->sc_arg);
- if (vap->iv_newstate_cb != NULL)
- vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg);
- IEEE80211_UNLOCK(ic);
- ZYD_LOCK(sc);
-}
-
-static int
-zyd_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
-{
- struct zyd_vap *zvp = ZYD_VAP(vap);
- struct ieee80211com *ic = vap->iv_ic;
- struct zyd_softc *sc = ic->ic_ifp->if_softc;
-
- DPRINTF(sc, ZYD_DEBUG_STATE, "%s: %s -> %s\n", __func__,
- ieee80211_state_name[vap->iv_state],
- ieee80211_state_name[nstate]);
-
- ZYD_LOCK(sc);
- /* do it in a process context */
- sc->sc_state = nstate;
- sc->sc_arg = arg;
- ZYD_UNLOCK(sc);
-
- if (nstate == IEEE80211_S_INIT) {
- zvp->newstate(vap, nstate, arg);
- return (0);
- } else {
- ZYD_LOCK(sc);
- zyd_queue_command(sc, zyd_task, &sc->sc_task[0].hdr,
- &sc->sc_task[1].hdr);
- ZYD_UNLOCK(sc);
- return (EINPROGRESS);
- }
+ return (zvp->newstate(vap, nstate, arg));
}
/*
@@ -845,9 +795,6 @@ zyd_cmd(struct zyd_softc *sc, uint16_t code, const void *idata, int ilen,
if (ilen > sizeof(cmd.data))
return (EINVAL);
- if (usb2_proc_is_gone(&sc->sc_tq))
- return (ENXIO);
-
cmd.code = htole16(code);
bcopy(idata, cmd.data, ilen);
DPRINTF(sc, ZYD_DEBUG_CMD, "sending cmd %p = %*D\n",
@@ -2012,15 +1959,6 @@ fail:
}
static void
-zyd_multitask(struct usb2_proc_msg *pm)
-{
- struct zyd_task *task = (struct zyd_task *)pm;
- struct zyd_softc *sc = task->sc;
-
- zyd_set_multi(sc);
-}
-
-static void
zyd_set_multi(struct zyd_softc *sc)
{
int error;
@@ -2073,8 +2011,7 @@ zyd_update_mcast(struct ifnet *ifp)
return;
ZYD_LOCK(sc);
- zyd_queue_command(sc, zyd_multitask,
- &sc->sc_mcasttask[0].hdr, &sc->sc_mcasttask[1].hdr);
+ zyd_set_multi(sc);
ZYD_UNLOCK(sc);
}
@@ -2502,10 +2439,6 @@ zyd_bulk_write_callback(struct usb2_xfer *xfer)
struct zyd_tx_data *data;
struct mbuf *m;
- /* wakeup any waiting command, if any */
- if (sc->sc_last_task != NULL)
- cv_signal(&sc->sc_cmd_cv);
-
switch (USB_GET_STATE(xfer)) {
case USB_ST_TRANSFERRED:
DPRINTF(sc, ZYD_DEBUG_ANY, "transfer complete, %u bytes\n",
@@ -2522,10 +2455,6 @@ zyd_bulk_write_callback(struct usb2_xfer *xfer)
/* FALLTHROUGH */
case USB_ST_SETUP:
tr_setup:
- /* wait for command to complete, if any */
- if (sc->sc_last_task != NULL)
- break;
-
data = STAILQ_FIRST(&sc->tx_q);
if (data) {
STAILQ_REMOVE_HEAD(&sc->tx_q, next);
@@ -2757,22 +2686,14 @@ zyd_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
case SIOCSIFFLAGS:
ZYD_LOCK(sc);
if (ifp->if_flags & IFF_UP) {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- zyd_queue_command(sc, zyd_multitask,
- &sc->sc_mcasttask[0].hdr,
- &sc->sc_mcasttask[1].hdr);
- } else {
- zyd_queue_command(sc, zyd_init_task,
- &sc->sc_synctask[0].hdr,
- &sc->sc_synctask[1].hdr);
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+ zyd_init_locked(sc);
startall = 1;
- }
+ } else
+ zyd_set_multi(sc);
} else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
- zyd_queue_command(sc, zyd_stop_task,
- &sc->sc_synctask[0].hdr,
- &sc->sc_synctask[1].hdr);
- }
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ zyd_stop(sc);
}
ZYD_UNLOCK(sc);
if (startall)
@@ -2792,10 +2713,8 @@ zyd_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
}
static void
-zyd_init_task(struct usb2_proc_msg *pm)
+zyd_init_locked(struct zyd_softc *sc)
{
- struct zyd_task *task = (struct zyd_task *)pm;
- struct zyd_softc *sc = task->sc;
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
struct usb2_config_descriptor *cd;
@@ -2850,7 +2769,7 @@ zyd_init_task(struct usb2_proc_msg *pm)
}
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
- zyd_stop_task(pm);
+ zyd_stop(sc);
DPRINTF(sc, ZYD_DEBUG_INIT, "setting MAC address to %6D\n",
IF_LLADDR(ifp), ":");
@@ -2898,7 +2817,7 @@ zyd_init_task(struct usb2_proc_msg *pm)
return;
-fail: zyd_stop_task(pm);
+fail: zyd_stop(sc);
return;
}
@@ -2910,9 +2829,7 @@ zyd_init(void *priv)
struct ieee80211com *ic = ifp->if_l2com;
ZYD_LOCK(sc);
- zyd_queue_command(sc, zyd_init_task,
- &sc->sc_synctask[0].hdr,
- &sc->sc_synctask[1].hdr);
+ zyd_init_locked(sc);
ZYD_UNLOCK(sc);
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
@@ -2920,10 +2837,8 @@ zyd_init(void *priv)
}
static void
-zyd_stop_task(struct usb2_proc_msg *pm)
+zyd_stop(struct zyd_softc *sc)
{
- struct zyd_task *task = (struct zyd_task *)pm;
- struct zyd_softc *sc = task->sc;
struct ifnet *ifp = sc->sc_ifp;
int error;
@@ -3029,13 +2944,12 @@ zyd_newassoc(struct ieee80211_node *ni, int isnew)
static void
zyd_scan_start(struct ieee80211com *ic)
{
- struct zyd_softc *sc = ic->ic_ifp->if_softc;
+ struct ifnet *ifp = ic->ic_ifp;
+ struct zyd_softc *sc = ifp->if_softc;
ZYD_LOCK(sc);
- /* do it in a process context */
- sc->sc_scan_action = ZYD_SCAN_START;
- zyd_queue_command(sc, zyd_scantask,
- &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr);
+ /* want broadcast address while scanning */
+ zyd_set_bssid(sc, ifp->if_broadcastaddr);
ZYD_UNLOCK(sc);
}
@@ -3045,10 +2959,8 @@ zyd_scan_end(struct ieee80211com *ic)
struct zyd_softc *sc = ic->ic_ifp->if_softc;
ZYD_LOCK(sc);
- /* do it in a process context */
- sc->sc_scan_action = ZYD_SCAN_END;
- zyd_queue_command(sc, zyd_scantask,
- &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr);
+ /* restore previous bssid */
+ zyd_set_bssid(sc, sc->sc_bssid);
ZYD_UNLOCK(sc);
}
@@ -3058,105 +2970,16 @@ zyd_set_channel(struct ieee80211com *ic)
struct zyd_softc *sc = ic->ic_ifp->if_softc;
ZYD_LOCK(sc);
- /* do it in a process context */
- sc->sc_scan_action = ZYD_SET_CHANNEL;
- zyd_queue_command(sc, zyd_scantask,
- &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr);
+ zyd_set_chan(sc, ic->ic_curchan);
ZYD_UNLOCK(sc);
}
-static void
-zyd_scantask(struct usb2_proc_msg *pm)
-{
- struct zyd_task *task = (struct zyd_task *)pm;
- struct zyd_softc *sc = task->sc;
- struct ifnet *ifp = sc->sc_ifp;
- struct ieee80211com *ic = ifp->if_l2com;
-
- ZYD_LOCK_ASSERT(sc, MA_OWNED);
-
- switch (sc->sc_scan_action) {
- case ZYD_SCAN_START:
- /* want broadcast address while scanning */
- zyd_set_bssid(sc, ifp->if_broadcastaddr);
- break;
-
- case ZYD_SET_CHANNEL:
- zyd_set_chan(sc, ic->ic_curchan);
- break;
-
- default: /* ZYD_SCAN_END */
- /* restore previous bssid */
- zyd_set_bssid(sc, sc->sc_bssid);
- break;
- }
-}
-
-static void
-zyd_command_wrapper(struct usb2_proc_msg *pm)
-{
- struct zyd_task *task = (struct zyd_task *)pm;
- struct zyd_softc *sc = task->sc;
- struct ifnet *ifp;
-
- /* wait for pending transfer, if any */
- while (usb2_transfer_pending(sc->sc_xfer[ZYD_BULK_WR]))
- cv_wait(&sc->sc_cmd_cv, &sc->sc_mtx);
-
- /* make sure any hardware FIFOs are emptied */
- usb2_pause_mtx(&sc->sc_mtx, hz / 1000);
-
- /* execute task */
- task->func(pm);
-
- /* check if this is the last task executed */
- if (sc->sc_last_task == task) {
- sc->sc_last_task = NULL;
- ifp = sc->sc_ifp;
- /* re-start TX, if any */
- if ((ifp != NULL) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
- usb2_transfer_start(sc->sc_xfer[ZYD_BULK_WR]);
- }
-}
-
-static void
-zyd_queue_command(struct zyd_softc *sc, usb2_proc_callback_t *fn,
- struct usb2_proc_msg *t0, struct usb2_proc_msg *t1)
-{
- struct zyd_task *task;
-
- ZYD_LOCK_ASSERT(sc, MA_OWNED);
-
- /*
- * NOTE: The task cannot get executed before we drop the
- * "sc_mtx" mutex. It is safe to update fields in the message
- * structure after that the message got queued.
- */
- task = (struct zyd_task *)
- usb2_proc_msignal(&sc->sc_tq, t0, t1);
-
- /* Setup callback and softc pointers */
- task->hdr.pm_callback = zyd_command_wrapper;
- task->func = fn;
- task->sc = sc;
-
- /* Make sure that any TX operation will stop */
- sc->sc_last_task = task;
-
- /*
- * Init and stop must be synchronous!
- */
- if ((fn == zyd_init_task) || (fn == zyd_stop_task) ||
- (fn == zyd_flush_task))
- usb2_proc_mwait(&sc->sc_tq, t0, t1);
-}
-
static device_method_t zyd_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, zyd_match),
DEVMETHOD(device_attach, zyd_attach),
DEVMETHOD(device_detach, zyd_detach),
-
+
{ 0, 0 }
};
OpenPOWER on IntegriCloud