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.
This commit is contained in:
parent
8d71fed0f2
commit
ed880bb60f
@ -34,20 +34,22 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/callout.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/taskqueue.h>
|
||||
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/kthread.h>
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/bus.h>
|
||||
@ -85,7 +87,30 @@ __stdcall static void ndis_getdone_func(ndis_handle, ndis_status);
|
||||
__stdcall static void ndis_resetdone_func(ndis_handle, ndis_status, uint8_t);
|
||||
__stdcall static void ndis_sendrsrcavail_func(ndis_handle);
|
||||
|
||||
static int ndis_create_kthreads(void);
|
||||
static void ndis_destroy_kthreads(void);
|
||||
static void ndis_stop_thread(int);
|
||||
static int ndis_enlarge_thrqueue(int);
|
||||
static int ndis_shrink_thrqueue(int);
|
||||
static void ndis_runq(void *);
|
||||
static void ndis_intq(void *);
|
||||
|
||||
extern struct mtx_pool *ndis_mtxpool;
|
||||
static uma_zone_t ndis_packet_zone, ndis_buffer_zone;
|
||||
struct mtx *ndis_thr_mtx;
|
||||
static STAILQ_HEAD(ndisqhead, ndis_req) ndis_ttodo;
|
||||
struct ndisqhead ndis_itodo;
|
||||
struct ndisqhead ndis_free;
|
||||
static int ndis_jobs = 32;
|
||||
static struct proc *ndis_tproc;
|
||||
static struct proc *ndis_iproc;
|
||||
|
||||
struct ndis_req {
|
||||
void (*ndis_func)(void *);
|
||||
void *ndis_arg;
|
||||
int ndis_exit;
|
||||
STAILQ_ENTRY(ndis_req) link;
|
||||
};
|
||||
|
||||
/*
|
||||
* This allows us to export our symbols to other modules.
|
||||
@ -111,9 +136,15 @@ ndis_modevent(module_t mod, int cmd, void *arg)
|
||||
ndis_buffer_zone = uma_zcreate("NDIS buffer",
|
||||
sizeof(ndis_buffer), NULL, NULL, NULL,
|
||||
NULL, UMA_ALIGN_PTR, 0);
|
||||
|
||||
ndis_create_kthreads();
|
||||
|
||||
break;
|
||||
case MOD_UNLOAD:
|
||||
case MOD_SHUTDOWN:
|
||||
/* stop kthreads */
|
||||
ndis_destroy_kthreads();
|
||||
|
||||
/* Shut down subsystems */
|
||||
ndis_libfini();
|
||||
ntoskrnl_libfini();
|
||||
@ -132,6 +163,303 @@ ndis_modevent(module_t mod, int cmd, void *arg)
|
||||
DEV_MODULE(ndisapi, ndis_modevent, NULL);
|
||||
MODULE_VERSION(ndisapi, 1);
|
||||
|
||||
/*
|
||||
* We create two kthreads for the NDIS subsystem. One of them is a task
|
||||
* queue for performing various odd jobs. The other is an swi thread
|
||||
* reserved exclusively for running interrupt handlers. The reason we
|
||||
* have our own task queue is that there are some cases where we may
|
||||
* need to sleep for a significant amount of time, and if we were to
|
||||
* use one of the taskqueue threads, we might delay the processing
|
||||
* of other pending tasks which might need to run right away. We have
|
||||
* a separate swi thread because we don't want our interrupt handling
|
||||
* to be delayed either.
|
||||
*
|
||||
* By default there are 32 jobs available to start, and another 8
|
||||
* are added to the free list each time a new device is created.
|
||||
*/
|
||||
|
||||
static void
|
||||
ndis_runq(dummy)
|
||||
void *dummy;
|
||||
{
|
||||
struct ndis_req *r = NULL, *die = NULL;
|
||||
|
||||
while (1) {
|
||||
kthread_suspend(ndis_tproc, 0);
|
||||
|
||||
/* Look for any jobs on the work queue. */
|
||||
|
||||
mtx_pool_lock(ndis_mtxpool, ndis_thr_mtx);
|
||||
while(STAILQ_FIRST(&ndis_ttodo) != NULL) {
|
||||
r = STAILQ_FIRST(&ndis_ttodo);
|
||||
STAILQ_REMOVE_HEAD(&ndis_ttodo, link);
|
||||
mtx_pool_unlock(ndis_mtxpool, ndis_thr_mtx);
|
||||
|
||||
/* Do the work. */
|
||||
|
||||
if (r->ndis_func != NULL)
|
||||
(*r->ndis_func)(r->ndis_arg);
|
||||
|
||||
mtx_pool_lock(ndis_mtxpool, ndis_thr_mtx);
|
||||
STAILQ_INSERT_HEAD(&ndis_free, r, link);
|
||||
|
||||
/* Check for a shutdown request */
|
||||
|
||||
if (r->ndis_exit == TRUE)
|
||||
die = r;
|
||||
}
|
||||
mtx_pool_unlock(ndis_mtxpool, ndis_thr_mtx);
|
||||
|
||||
/* Bail if we were told to shut down. */
|
||||
|
||||
if (die != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
wakeup(die);
|
||||
mtx_lock(&Giant);
|
||||
kthread_exit(0);
|
||||
}
|
||||
|
||||
static void
|
||||
ndis_intq(dummy)
|
||||
void *dummy;
|
||||
{
|
||||
struct ndis_req *r = NULL, *die = NULL;
|
||||
|
||||
while (1) {
|
||||
kthread_suspend(ndis_iproc, 0);
|
||||
|
||||
/* Look for any jobs on the work queue. */
|
||||
|
||||
mtx_pool_lock(ndis_mtxpool, ndis_thr_mtx);
|
||||
while(STAILQ_FIRST(&ndis_itodo) != NULL) {
|
||||
r = STAILQ_FIRST(&ndis_itodo);
|
||||
STAILQ_REMOVE_HEAD(&ndis_itodo, link);
|
||||
mtx_pool_unlock(ndis_mtxpool, ndis_thr_mtx);
|
||||
|
||||
/* Do the work. */
|
||||
|
||||
if (r->ndis_func != NULL)
|
||||
(*r->ndis_func)(r->ndis_arg);
|
||||
|
||||
mtx_pool_lock(ndis_mtxpool, ndis_thr_mtx);
|
||||
STAILQ_INSERT_HEAD(&ndis_free, r, link);
|
||||
|
||||
/* Check for a shutdown request */
|
||||
|
||||
if (r->ndis_exit == TRUE)
|
||||
die = r;
|
||||
}
|
||||
mtx_pool_unlock(ndis_mtxpool, ndis_thr_mtx);
|
||||
|
||||
/* Bail if this is an exit request. */
|
||||
|
||||
if (die != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
wakeup(die);
|
||||
mtx_lock(&Giant);
|
||||
kthread_exit(0);
|
||||
}
|
||||
|
||||
static int
|
||||
ndis_create_kthreads()
|
||||
{
|
||||
struct ndis_req *r;
|
||||
int i, error = 0;
|
||||
|
||||
ndis_thr_mtx = mtx_pool_alloc(ndis_mtxpool);
|
||||
STAILQ_INIT(&ndis_ttodo);
|
||||
STAILQ_INIT(&ndis_itodo);
|
||||
STAILQ_INIT(&ndis_free);
|
||||
|
||||
for (i = 0; i < ndis_jobs; i++) {
|
||||
r = malloc(sizeof(struct ndis_req), M_DEVBUF, M_WAITOK);
|
||||
if (r == NULL) {
|
||||
error = ENOMEM;
|
||||
break;
|
||||
}
|
||||
STAILQ_INSERT_HEAD(&ndis_free, r, link);
|
||||
}
|
||||
|
||||
if (error == 0)
|
||||
error = kthread_create(ndis_runq, NULL,
|
||||
&ndis_tproc, RFHIGHPID, 0, "ndis taskqueue");
|
||||
|
||||
if (error == 0)
|
||||
error = kthread_create(ndis_intq, NULL,
|
||||
&ndis_iproc, RFHIGHPID, 0, "ndis swi");
|
||||
|
||||
if (error) {
|
||||
while ((r = STAILQ_FIRST(&ndis_free)) != NULL) {
|
||||
STAILQ_REMOVE_HEAD(&ndis_free, link);
|
||||
free(r, M_DEVBUF);
|
||||
}
|
||||
return(error);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void
|
||||
ndis_destroy_kthreads()
|
||||
{
|
||||
struct ndis_req *r;
|
||||
|
||||
/* Stop the threads. */
|
||||
|
||||
ndis_stop_thread(NDIS_TASKQUEUE);
|
||||
ndis_stop_thread(NDIS_SWI);
|
||||
|
||||
/* Destroy request structures. */
|
||||
|
||||
while ((r = STAILQ_FIRST(&ndis_free)) != NULL) {
|
||||
STAILQ_REMOVE_HEAD(&ndis_free, link);
|
||||
free(r, M_DEVBUF);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
ndis_stop_thread(t)
|
||||
int t;
|
||||
{
|
||||
struct ndis_req *r;
|
||||
struct timeval tv;
|
||||
struct ndisqhead *q;
|
||||
struct proc *p;
|
||||
|
||||
if (t == NDIS_TASKQUEUE) {
|
||||
q = &ndis_ttodo;
|
||||
p = ndis_tproc;
|
||||
} else {
|
||||
q = &ndis_itodo;
|
||||
p = ndis_iproc;
|
||||
}
|
||||
|
||||
/* Create and post a special 'exit' job. */
|
||||
|
||||
mtx_pool_lock(ndis_mtxpool, ndis_thr_mtx);
|
||||
r = STAILQ_FIRST(&ndis_free);
|
||||
STAILQ_REMOVE_HEAD(&ndis_free, link);
|
||||
r->ndis_func = NULL;
|
||||
r->ndis_arg = NULL;
|
||||
r->ndis_exit = TRUE;
|
||||
STAILQ_INSERT_TAIL(q, r, link);
|
||||
mtx_pool_unlock(ndis_mtxpool, ndis_thr_mtx);
|
||||
|
||||
kthread_resume(p);
|
||||
|
||||
/* wait for thread exit */
|
||||
|
||||
tv.tv_sec = 60;
|
||||
tv.tv_usec = 0;
|
||||
tsleep(r, PPAUSE|PCATCH, "ndisthrexit", tvtohz(&tv));
|
||||
|
||||
/* Now empty the job list. */
|
||||
|
||||
mtx_pool_lock(ndis_mtxpool, ndis_thr_mtx);
|
||||
while ((r = STAILQ_FIRST(q)) != NULL) {
|
||||
STAILQ_REMOVE_HEAD(q, link);
|
||||
STAILQ_INSERT_HEAD(&ndis_free, r, link);
|
||||
}
|
||||
mtx_pool_unlock(ndis_mtxpool, ndis_thr_mtx);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
ndis_enlarge_thrqueue(cnt)
|
||||
int cnt;
|
||||
{
|
||||
struct ndis_req *r;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
r = malloc(sizeof(struct ndis_req), M_DEVBUF, M_WAITOK);
|
||||
if (r == NULL)
|
||||
return(ENOMEM);
|
||||
mtx_pool_lock(ndis_mtxpool, ndis_thr_mtx);
|
||||
STAILQ_INSERT_HEAD(&ndis_free, r, link);
|
||||
ndis_jobs++;
|
||||
mtx_pool_unlock(ndis_mtxpool, ndis_thr_mtx);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
ndis_shrink_thrqueue(cnt)
|
||||
int cnt;
|
||||
{
|
||||
struct ndis_req *r;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
mtx_pool_lock(ndis_mtxpool, ndis_thr_mtx);
|
||||
r = STAILQ_FIRST(&ndis_free);
|
||||
if (r == NULL) {
|
||||
mtx_pool_unlock(ndis_mtxpool, ndis_thr_mtx);
|
||||
return(ENOMEM);
|
||||
}
|
||||
STAILQ_REMOVE_HEAD(&ndis_free, link);
|
||||
ndis_jobs--;
|
||||
mtx_pool_unlock(ndis_mtxpool, ndis_thr_mtx);
|
||||
free(r, M_DEVBUF);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
ndis_sched(func, arg, t)
|
||||
void (*func)(void *);
|
||||
void *arg;
|
||||
int t;
|
||||
{
|
||||
struct ndis_req *r;
|
||||
struct ndisqhead *q;
|
||||
struct proc *p;
|
||||
|
||||
if (t == NDIS_TASKQUEUE) {
|
||||
q = &ndis_ttodo;
|
||||
p = ndis_tproc;
|
||||
} else {
|
||||
q = &ndis_itodo;
|
||||
p = ndis_iproc;
|
||||
}
|
||||
|
||||
mtx_pool_lock(ndis_mtxpool, ndis_thr_mtx);
|
||||
/*
|
||||
* Check to see if an instance of this job is already
|
||||
* pending. If so, don't bother queuing it again.
|
||||
*/
|
||||
STAILQ_FOREACH(r, q, link) {
|
||||
if (r->ndis_func == func && r->ndis_arg == arg) {
|
||||
mtx_pool_unlock(ndis_mtxpool, ndis_thr_mtx);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
r = STAILQ_FIRST(&ndis_free);
|
||||
if (r == NULL) {
|
||||
mtx_pool_unlock(ndis_mtxpool, ndis_thr_mtx);
|
||||
return(EAGAIN);
|
||||
}
|
||||
STAILQ_REMOVE_HEAD(&ndis_free, link);
|
||||
r->ndis_func = func;
|
||||
r->ndis_arg = arg;
|
||||
r->ndis_exit = FALSE;
|
||||
STAILQ_INSERT_TAIL(q, r, link);
|
||||
mtx_pool_unlock(ndis_mtxpool, ndis_thr_mtx);
|
||||
|
||||
/* Post the job. */
|
||||
kthread_resume(p);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
__stdcall static void
|
||||
ndis_sendrsrcavail_func(adapter)
|
||||
@ -1080,6 +1408,8 @@ ndis_unload_driver(arg)
|
||||
|
||||
ndis_flush_sysctls(sc);
|
||||
|
||||
ndis_shrink_thrqueue(8);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@ -1186,5 +1516,7 @@ ndis_load_driver(img, arg)
|
||||
block->nmb_dev = sc->ndis_dev;
|
||||
block->nmb_img = img;
|
||||
|
||||
ndis_enlarge_thrqueue(8);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
@ -1321,6 +1321,9 @@ typedef ndis_status (*driver_entry)(void *, ndis_unicode_string *);
|
||||
|
||||
extern image_patch_table ndis_functbl[];
|
||||
|
||||
#define NDIS_TASKQUEUE 1
|
||||
#define NDIS_SWI 2
|
||||
|
||||
__BEGIN_DECLS
|
||||
extern int ndis_libinit(void);
|
||||
extern int ndis_libfini(void);
|
||||
@ -1353,6 +1356,7 @@ extern int ndis_destroy_dma(void *);
|
||||
extern int ndis_create_sysctls(void *);
|
||||
extern int ndis_add_sysctl(void *, char *, char *, char *, int);
|
||||
extern int ndis_flush_sysctls(void *);
|
||||
extern int ndis_sched(void (*)(void *), void *, int);
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _NDIS_VAR_H_ */
|
||||
|
@ -64,7 +64,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/timespec.h>
|
||||
#include <sys/smp.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/taskqueue.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/fcntl.h>
|
||||
@ -261,7 +260,7 @@ __stdcall static u_int8_t ndis_cpu_cnt(void);
|
||||
__stdcall static void ndis_ind_statusdone(ndis_handle);
|
||||
__stdcall static void ndis_ind_status(ndis_handle, ndis_status,
|
||||
void *, uint32_t);
|
||||
static void ndis_workfunc(void *, int);
|
||||
static void ndis_workfunc(void *);
|
||||
__stdcall static ndis_status ndis_sched_workitem(ndis_work_item *);
|
||||
__stdcall static void ndis_pkt_to_pkt(ndis_packet *, uint32_t, uint32_t,
|
||||
ndis_packet *, uint32_t, uint32_t *);
|
||||
@ -601,18 +600,18 @@ ndis_decode_parm(block, parm, val)
|
||||
ndis_config_parm *parm;
|
||||
char *val;
|
||||
{
|
||||
uint16_t *unicode;
|
||||
ndis_unicode_string *ustr;
|
||||
|
||||
unicode = (uint16_t *)&block->nmb_dummybuf;
|
||||
char *astr = NULL;
|
||||
|
||||
switch(parm->ncp_type) {
|
||||
case ndis_parm_string:
|
||||
ustr = &parm->ncp_parmdata.ncp_stringdata;
|
||||
ndis_unicode_to_ascii(ustr->nus_buf, ustr->nus_len, &val);
|
||||
ndis_unicode_to_ascii(ustr->nus_buf, ustr->nus_len, &astr);
|
||||
bcopy(astr, val, 254);
|
||||
free(astr, M_DEVBUF);
|
||||
break;
|
||||
case ndis_parm_int:
|
||||
sprintf(val, "%ul", parm->ncp_parmdata.ncp_intdata);
|
||||
sprintf(val, "%d", parm->ncp_parmdata.ncp_intdata);
|
||||
break;
|
||||
case ndis_parm_hexint:
|
||||
sprintf(val, "%xu", parm->ncp_parmdata.ncp_intdata);
|
||||
@ -644,6 +643,7 @@ ndis_write_cfg(status, cfg, key, parm)
|
||||
ndis_unicode_to_ascii(key->nus_buf, key->nus_len, &keystr);
|
||||
|
||||
/* Decode the parameter into a string. */
|
||||
bzero(val, sizeof(val));
|
||||
*status = ndis_decode_parm(block, parm, val);
|
||||
if (*status != NDIS_STATUS_SUCCESS) {
|
||||
free(keystr, M_DEVBUF);
|
||||
@ -2484,9 +2484,8 @@ ndis_ind_status(adapter, status, sbuf, slen)
|
||||
}
|
||||
|
||||
static void
|
||||
ndis_workfunc(ctx, pending)
|
||||
ndis_workfunc(ctx)
|
||||
void *ctx;
|
||||
int pending;
|
||||
{
|
||||
ndis_work_item *work;
|
||||
__stdcall ndis_proc workfunc;
|
||||
@ -2501,11 +2500,7 @@ __stdcall static ndis_status
|
||||
ndis_sched_workitem(work)
|
||||
ndis_work_item *work;
|
||||
{
|
||||
struct task *t;
|
||||
|
||||
t = (struct task *)&work->nwi_wraprsvd;
|
||||
TASK_INIT(t, 0, ndis_workfunc, work);
|
||||
taskqueue_enqueue(taskqueue_swi, t);
|
||||
ndis_sched(ndis_workfunc, work, NDIS_TASKQUEUE);
|
||||
return(NDIS_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -92,9 +92,6 @@ struct ndis_softc {
|
||||
int ndis_rescnt;
|
||||
struct mtx *ndis_mtx;
|
||||
struct mtx *ndis_intrmtx;
|
||||
struct task ndis_intrtask;
|
||||
struct task ndis_ticktask;
|
||||
struct task ndis_starttask;
|
||||
device_t ndis_dev;
|
||||
int ndis_unit;
|
||||
ndis_miniport_block ndis_block;
|
||||
|
Loading…
Reference in New Issue
Block a user