aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/if_ndis/if_ndis.c
diff options
context:
space:
mode:
authorBill Paul <wpaul@FreeBSD.org>2004-01-18 22:57:11 +0000
committerBill Paul <wpaul@FreeBSD.org>2004-01-18 22:57:11 +0000
commited880bb60f6d78546773349d70cb513c7207a634 (patch)
tree8f94ac297b35591f95c060a1820c94637d8fd4b8 /sys/dev/if_ndis/if_ndis.c
parent8d71fed0f2f10c08a9a2cd558f3660405c1bc203 (diff)
downloadsrc-ed880bb60f6d78546773349d70cb513c7207a634.tar.gz
src-ed880bb60f6d78546773349d70cb513c7207a634.zip
Convert from using taskqueue_swi to using private kernel threads. The
problem with using taskqueue_swi is that some of the things we defer into threads might block for up to several seconds. This is an unfriendly thing to do to taskqueue_swi, since it is assumed the taskqueue threads will execute fairly quickly once a task is submitted. Reorganized the locking in if_ndis.c in the process. Cleaned up ndis_write_cfg() and ndis_decode_parm() a little.
Notes
Notes: svn path=/head/; revision=124697
Diffstat (limited to 'sys/dev/if_ndis/if_ndis.c')
-rw-r--r--sys/dev/if_ndis/if_ndis.c64
1 files changed, 27 insertions, 37 deletions
diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c
index e4650e08755b..814f4a8acf26 100644
--- a/sys/dev/if_ndis/if_ndis.c
+++ b/sys/dev/if_ndis/if_ndis.c
@@ -44,7 +44,6 @@ __FBSDID("$FreeBSD$");
#include <sys/socket.h>
#include <sys/queue.h>
#include <sys/sysctl.h>
-#include <sys/taskqueue.h>
#include <net/if.h>
#include <net/if_arp.h>
@@ -106,11 +105,11 @@ static __stdcall void ndis_linksts (ndis_handle,
static __stdcall void ndis_linksts_done (ndis_handle);
static void ndis_intr (void *);
-static void ndis_intrtask (void *, int);
+static void ndis_intrtask (void *);
static void ndis_tick (void *);
-static void ndis_ticktask (void *, int);
+static void ndis_ticktask (void *);
static void ndis_start (struct ifnet *);
-static void ndis_starttask (void *, int);
+static void ndis_starttask (void *);
static int ndis_ioctl (struct ifnet *, u_long, caddr_t);
static int ndis_wi_ioctl_get (struct ifnet *, u_long, caddr_t);
static int ndis_wi_ioctl_set (struct ifnet *, u_long, caddr_t);
@@ -239,10 +238,6 @@ ndis_attach(dev)
sc->ndis_mtx = mtx_pool_alloc(ndis_mtxpool);
sc->ndis_intrmtx = mtx_pool_alloc(ndis_mtxpool);
- TASK_INIT(&sc->ndis_intrtask, 0, ndis_intrtask, sc);
- TASK_INIT(&sc->ndis_ticktask, 0, ndis_ticktask, sc);
- TASK_INIT(&sc->ndis_starttask, 0, ndis_starttask, sc);
-
/*
* Map control/status registers.
@@ -825,20 +820,25 @@ ndis_txeof(adapter, packet, status)
m = packet->np_m0;
idx = packet->np_txidx;
- ifp->if_opackets++;
if (sc->ndis_sc)
bus_dmamap_unload(sc->ndis_ttag, sc->ndis_tmaps[idx]);
ndis_free_packet(packet);
+ m_freem(m);
+
+ NDIS_LOCK(sc);
sc->ndis_txarray[idx] = NULL;
sc->ndis_txpending++;
+ if (status == NDIS_STATUS_SUCCESS)
+ ifp->if_opackets++;
+ else
+ ifp->if_oerrors++;
ifp->if_timer = 0;
ifp->if_flags &= ~IFF_OACTIVE;
+ NDIS_UNLOCK(sc);
- m_freem(m);
-
- taskqueue_enqueue(taskqueue_swi, &sc->ndis_starttask);
+ ndis_sched(ndis_starttask, ifp, NDIS_TASKQUEUE);
return;
}
@@ -875,13 +875,13 @@ ndis_linksts_done(adapter)
switch (block->nmb_getstat) {
case NDIS_STATUS_MEDIA_CONNECT:
- taskqueue_enqueue(taskqueue_swi, &sc->ndis_ticktask);
- taskqueue_enqueue(taskqueue_swi, &sc->ndis_starttask);
+ ndis_sched(ndis_ticktask, sc, NDIS_TASKQUEUE);
+ ndis_sched(ndis_starttask, ifp, NDIS_TASKQUEUE);
break;
case NDIS_STATUS_MEDIA_DISCONNECT:
if (sc->ndis_80211)
ndis_getstate_80211(sc);
- taskqueue_enqueue(taskqueue_swi, &sc->ndis_ticktask);
+ ndis_sched(ndis_ticktask, sc, NDIS_TASKQUEUE);
break;
default:
break;
@@ -891,9 +891,8 @@ ndis_linksts_done(adapter)
}
static void
-ndis_intrtask(arg, pending)
+ndis_intrtask(arg)
void *arg;
- int pending;
{
struct ndis_softc *sc;
struct ifnet *ifp;
@@ -901,16 +900,11 @@ ndis_intrtask(arg, pending)
sc = arg;
ifp = &sc->arpcom.ac_if;
- NDIS_LOCK(sc);
ndis_intrhand(sc);
- NDIS_UNLOCK(sc);
mtx_lock(sc->ndis_intrmtx);
ndis_enable_intr(sc);
mtx_unlock(sc->ndis_intrmtx);
- if (ifp->if_snd.ifq_head != NULL)
- ndis_start(ifp);
-
return;
}
@@ -940,7 +934,7 @@ ndis_intr(arg)
mtx_unlock(sc->ndis_intrmtx);
if ((is_our_intr || call_isr) && (ifp->if_flags & IFF_UP))
- taskqueue_enqueue(taskqueue_swi, &sc->ndis_intrtask);
+ ndis_sched(ndis_intrtask, ifp, NDIS_SWI);
return;
}
@@ -951,16 +945,16 @@ ndis_tick(xsc)
{
struct ndis_softc *sc;
sc = xsc;
- taskqueue_enqueue(taskqueue_swi, &sc->ndis_ticktask);
+
+ ndis_sched(ndis_ticktask, sc, NDIS_TASKQUEUE);
sc->ndis_stat_ch = timeout(ndis_tick, sc, hz *
sc->ndis_block.nmb_checkforhangsecs);
}
static void
-ndis_ticktask(xsc, pending)
+ndis_ticktask(xsc)
void *xsc;
- int pending;
{
struct ndis_softc *sc;
__stdcall ndis_checkforhang_handler hangfunc;
@@ -1029,9 +1023,8 @@ ndis_map_sclist(arg, segs, nseg, mapsize, error)
}
static void
-ndis_starttask(arg, pending)
+ndis_starttask(arg)
void *arg;
- int pending;
{
struct ifnet *ifp;
@@ -1875,12 +1868,10 @@ ndis_watchdog(ifp)
NDIS_LOCK(sc);
ifp->if_oerrors++;
device_printf(sc->ndis_dev, "watchdog timeout\n");
+ NDIS_UNLOCK(sc);
ndis_reset(sc);
-
- taskqueue_enqueue(taskqueue_swi, &sc->ndis_starttask);
-
- NDIS_UNLOCK(sc);
+ ndis_sched(ndis_starttask, ifp, NDIS_TASKQUEUE);
return;
}
@@ -1895,17 +1886,16 @@ ndis_stop(sc)
{
struct ifnet *ifp;
-/* NDIS_LOCK(sc);*/
ifp = &sc->arpcom.ac_if;
- ifp->if_timer = 0;
-
- sc->ndis_link = 0;
untimeout(ndis_tick, sc, sc->ndis_stat_ch);
ndis_halt_nic(sc);
+ NDIS_LOCK(sc);
+ ifp->if_timer = 0;
+ sc->ndis_link = 0;
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
- /*NDIS_UNLOCK(sc);*/
+ NDIS_UNLOCK(sc);
return;
}