summaryrefslogtreecommitdiffstats
path: root/sys/compat/ndis/kern_ndis.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/compat/ndis/kern_ndis.c')
-rw-r--r--sys/compat/ndis/kern_ndis.c113
1 files changed, 79 insertions, 34 deletions
diff --git a/sys/compat/ndis/kern_ndis.c b/sys/compat/ndis/kern_ndis.c
index cd928dc..733e0d3 100644
--- a/sys/compat/ndis/kern_ndis.c
+++ b/sys/compat/ndis/kern_ndis.c
@@ -106,9 +106,8 @@ static int ndis_enlarge_thrqueue(int);
static int ndis_shrink_thrqueue(int);
static void ndis_runq(void *);
-extern struct mtx_pool *ndis_mtxpool;
static uma_zone_t ndis_packet_zone, ndis_buffer_zone;
-struct mtx *ndis_thr_mtx;
+struct mtx ndis_thr_mtx;
static STAILQ_HEAD(ndisqhead, ndis_req) ndis_ttodo;
struct ndisqhead ndis_itodo;
struct ndisqhead ndis_free;
@@ -207,23 +206,25 @@ ndis_runq(arg)
p = arg;
while (1) {
- kthread_suspend(p->np_p, 0);
+
+ /* Sleep, but preserve our original priority. */
+ ndis_thsuspend(p->np_p, 0);
/* Look for any jobs on the work queue. */
- mtx_pool_lock(ndis_mtxpool, ndis_thr_mtx);
+ mtx_lock(&ndis_thr_mtx);
p->np_state = NDIS_PSTATE_RUNNING;
while(STAILQ_FIRST(p->np_q) != NULL) {
r = STAILQ_FIRST(p->np_q);
STAILQ_REMOVE_HEAD(p->np_q, link);
- mtx_pool_unlock(ndis_mtxpool, ndis_thr_mtx);
+ mtx_unlock(&ndis_thr_mtx);
/* Do the work. */
if (r->nr_func != NULL)
(*r->nr_func)(r->nr_arg);
- mtx_pool_lock(ndis_mtxpool, ndis_thr_mtx);
+ mtx_lock(&ndis_thr_mtx);
STAILQ_INSERT_HEAD(&ndis_free, r, link);
/* Check for a shutdown request */
@@ -232,7 +233,7 @@ ndis_runq(arg)
die = r;
}
p->np_state = NDIS_PSTATE_SLEEPING;
- mtx_pool_unlock(ndis_mtxpool, ndis_thr_mtx);
+ mtx_unlock(&ndis_thr_mtx);
/* Bail if we were told to shut down. */
@@ -242,6 +243,7 @@ ndis_runq(arg)
wakeup(die);
kthread_exit(0);
+ return; /* notreached */
}
static int
@@ -250,7 +252,9 @@ ndis_create_kthreads()
struct ndis_req *r;
int i, error = 0;
- ndis_thr_mtx = mtx_pool_alloc(ndis_mtxpool);
+ mtx_init(&ndis_thr_mtx, "NDIS thread lock",
+ MTX_NDIS_LOCK, MTX_DEF);
+
STAILQ_INIT(&ndis_ttodo);
STAILQ_INIT(&ndis_itodo);
STAILQ_INIT(&ndis_free);
@@ -308,6 +312,8 @@ ndis_destroy_kthreads()
free(r, M_DEVBUF);
}
+ mtx_destroy(&ndis_thr_mtx);
+
return;
}
@@ -329,16 +335,16 @@ ndis_stop_thread(t)
/* Create and post a special 'exit' job. */
- mtx_pool_lock(ndis_mtxpool, ndis_thr_mtx);
+ mtx_lock(&ndis_thr_mtx);
r = STAILQ_FIRST(&ndis_free);
STAILQ_REMOVE_HEAD(&ndis_free, link);
r->nr_func = NULL;
r->nr_arg = NULL;
r->nr_exit = TRUE;
STAILQ_INSERT_TAIL(q, r, link);
- mtx_pool_unlock(ndis_mtxpool, ndis_thr_mtx);
+ mtx_unlock(&ndis_thr_mtx);
- kthread_resume(p);
+ ndis_thresume(p);
/* wait for thread exit */
@@ -346,12 +352,12 @@ ndis_stop_thread(t)
/* Now empty the job list. */
- mtx_pool_lock(ndis_mtxpool, ndis_thr_mtx);
+ mtx_lock(&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);
+ mtx_unlock(&ndis_thr_mtx);
return;
}
@@ -367,10 +373,10 @@ ndis_enlarge_thrqueue(cnt)
r = malloc(sizeof(struct ndis_req), M_DEVBUF, M_WAITOK);
if (r == NULL)
return(ENOMEM);
- mtx_pool_lock(ndis_mtxpool, ndis_thr_mtx);
+ mtx_lock(&ndis_thr_mtx);
STAILQ_INSERT_HEAD(&ndis_free, r, link);
ndis_jobs++;
- mtx_pool_unlock(ndis_mtxpool, ndis_thr_mtx);
+ mtx_unlock(&ndis_thr_mtx);
}
return(0);
@@ -384,15 +390,15 @@ ndis_shrink_thrqueue(cnt)
int i;
for (i = 0; i < cnt; i++) {
- mtx_pool_lock(ndis_mtxpool, ndis_thr_mtx);
+ mtx_lock(&ndis_thr_mtx);
r = STAILQ_FIRST(&ndis_free);
if (r == NULL) {
- mtx_pool_unlock(ndis_mtxpool, ndis_thr_mtx);
+ mtx_unlock(&ndis_thr_mtx);
return(ENOMEM);
}
STAILQ_REMOVE_HEAD(&ndis_free, link);
ndis_jobs--;
- mtx_pool_unlock(ndis_mtxpool, ndis_thr_mtx);
+ mtx_unlock(&ndis_thr_mtx);
free(r, M_DEVBUF);
}
@@ -417,17 +423,17 @@ ndis_unsched(func, arg, t)
p = ndis_iproc.np_p;
}
- mtx_pool_lock(ndis_mtxpool, ndis_thr_mtx);
+ mtx_lock(&ndis_thr_mtx);
STAILQ_FOREACH(r, q, link) {
if (r->nr_func == func && r->nr_arg == arg) {
STAILQ_REMOVE(q, r, ndis_req, link);
STAILQ_INSERT_HEAD(&ndis_free, r, link);
- mtx_pool_unlock(ndis_mtxpool, ndis_thr_mtx);
+ mtx_unlock(&ndis_thr_mtx);
return(0);
}
}
- mtx_pool_unlock(ndis_mtxpool, ndis_thr_mtx);
+ mtx_unlock(&ndis_thr_mtx);
return(ENOENT);
}
@@ -451,20 +457,20 @@ ndis_sched(func, arg, t)
p = ndis_iproc.np_p;
}
- mtx_pool_lock(ndis_mtxpool, ndis_thr_mtx);
+ mtx_lock(&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->nr_func == func && r->nr_arg == arg) {
- mtx_pool_unlock(ndis_mtxpool, ndis_thr_mtx);
+ mtx_unlock(&ndis_thr_mtx);
return(0);
}
}
r = STAILQ_FIRST(&ndis_free);
if (r == NULL) {
- mtx_pool_unlock(ndis_mtxpool, ndis_thr_mtx);
+ mtx_unlock(&ndis_thr_mtx);
return(EAGAIN);
}
STAILQ_REMOVE_HEAD(&ndis_free, link);
@@ -476,7 +482,7 @@ ndis_sched(func, arg, t)
s = ndis_tproc.np_state;
else
s = ndis_iproc.np_state;
- mtx_pool_unlock(ndis_mtxpool, ndis_thr_mtx);
+ mtx_unlock(&ndis_thr_mtx);
/*
* Post the job, but only if the thread is actually blocked
@@ -486,11 +492,32 @@ ndis_sched(func, arg, t)
* it up until KeWaitForObject() gets woken up on its own.
*/
if (s == NDIS_PSTATE_SLEEPING)
- kthread_resume(p);
+ ndis_thresume(p);
return(0);
}
+int
+ndis_thsuspend(p, timo)
+ struct proc *p;
+ int timo;
+{
+ int error;
+
+ PROC_LOCK(p);
+ error = msleep(&p->p_siglist, &p->p_mtx,
+ curthread->td_priority|PDROP, "ndissp", timo);
+ return(error);
+}
+
+void
+ndis_thresume(p)
+ struct proc *p;
+{
+ wakeup(&p->p_siglist);
+ return;
+}
+
__stdcall static void
ndis_sendrsrcavail_func(adapter)
ndis_handle adapter;
@@ -706,6 +733,7 @@ ndis_return_packet(buf, arg)
ndis_handle adapter;
ndis_packet *p;
__stdcall ndis_return_handler returnfunc;
+ uint8_t irql;
if (arg == NULL)
return;
@@ -722,8 +750,11 @@ ndis_return_packet(buf, arg)
sc = p->np_softc;
returnfunc = sc->ndis_chars.nmc_return_packet_func;
adapter = sc->ndis_block.nmb_miniportadapterctx;
- if (adapter != NULL)
+ if (adapter != NULL) {
+ irql = FASTCALL1(hal_raise_irql, DISPATCH_LEVEL);
returnfunc(adapter, p);
+ FASTCALL1(hal_lower_irql, irql);
+ }
return;
}
@@ -1035,6 +1066,7 @@ ndis_set_info(arg, oid, buf, buflen)
__stdcall ndis_setinfo_handler setfunc;
uint32_t byteswritten = 0, bytesneeded = 0;
int error;
+ uint8_t irql;
sc = arg;
NDIS_LOCK(sc);
@@ -1045,13 +1077,16 @@ ndis_set_info(arg, oid, buf, buflen)
if (adapter == NULL || setfunc == NULL)
return(ENXIO);
+ irql = FASTCALL1(hal_raise_irql, DISPATCH_LEVEL);
rval = setfunc(adapter, oid, buf, *buflen,
&byteswritten, &bytesneeded);
+ FASTCALL1(hal_lower_irql, irql);
if (rval == NDIS_STATUS_PENDING) {
PROC_LOCK(curthread->td_proc);
error = msleep(&sc->ndis_block.nmb_wkupdpctimer,
- &curthread->td_proc->p_mtx, PPAUSE|PDROP,
+ &curthread->td_proc->p_mtx,
+ curthread->td_priority|PDROP,
"ndisset", 5 * hz);
rval = sc->ndis_block.nmb_setstat;
}
@@ -1091,6 +1126,7 @@ ndis_send_packets(arg, packets, cnt)
__stdcall ndis_senddone_func senddonefunc;
int i;
ndis_packet *p;
+ uint8_t irql;
sc = arg;
adapter = sc->ndis_block.nmb_miniportadapterctx;
@@ -1098,7 +1134,9 @@ ndis_send_packets(arg, packets, cnt)
return(ENXIO);
sendfunc = sc->ndis_chars.nmc_sendmulti_func;
senddonefunc = sc->ndis_block.nmb_senddone_func;
+ irql = FASTCALL1(hal_raise_irql, DISPATCH_LEVEL);
sendfunc(adapter, packets, cnt);
+ FASTCALL1(hal_lower_irql, irql);
for (i = 0; i < cnt; i++) {
p = packets[i];
@@ -1126,6 +1164,7 @@ ndis_send_packet(arg, packet)
ndis_status status;
__stdcall ndis_sendsingle_handler sendfunc;
__stdcall ndis_senddone_func senddonefunc;
+ uint8_t irql;
sc = arg;
adapter = sc->ndis_block.nmb_miniportadapterctx;
@@ -1134,7 +1173,9 @@ ndis_send_packet(arg, packet)
sendfunc = sc->ndis_chars.nmc_sendsingle_func;
senddonefunc = sc->ndis_block.nmb_senddone_func;
+ irql = FASTCALL1(hal_raise_irql, DISPATCH_LEVEL);
status = sendfunc(adapter, packet, packet->np_private.npp_flags);
+ FASTCALL1(hal_lower_irql, irql);
if (status == NDIS_STATUS_PENDING)
return(0);
@@ -1210,6 +1251,7 @@ ndis_reset_nic(arg)
uint8_t addressing_reset;
struct ifnet *ifp;
int rval;
+ uint8_t irql;
sc = arg;
ifp = &sc->arpcom.ac_if;
@@ -1220,11 +1262,14 @@ ndis_reset_nic(arg)
if (adapter == NULL || resetfunc == NULL)
return(EIO);
+ irql = FASTCALL1(hal_raise_irql, DISPATCH_LEVEL);
rval = resetfunc(&addressing_reset, adapter);
+ FASTCALL1(hal_lower_irql, irql);
+
if (rval == NDIS_STATUS_PENDING) {
PROC_LOCK(curthread->td_proc);
msleep(sc, &curthread->td_proc->p_mtx,
- PPAUSE|PDROP, "ndisrst", 0);
+ curthread->td_priority|PDROP, "ndisrst", 0);
}
return(0);
@@ -1346,10 +1391,8 @@ ndis_enable_intr(arg)
__stdcall ndis_enable_interrupts_handler intrenbfunc;
sc = arg;
- NDIS_LOCK(sc);
adapter = sc->ndis_block.nmb_miniportadapterctx;
intrenbfunc = sc->ndis_chars.nmc_enable_interrupts_func;
- NDIS_UNLOCK(sc);
if (adapter == NULL || intrenbfunc == NULL)
return;
intrenbfunc(adapter);
@@ -1392,10 +1435,8 @@ ndis_isr(arg, ourintr, callhandler)
return(EINVAL);
sc = arg;
- NDIS_LOCK(sc);
adapter = sc->ndis_block.nmb_miniportadapterctx;
isrfunc = sc->ndis_chars.nmc_isr_func;
- NDIS_UNLOCK(sc);
if (adapter == NULL || isrfunc == NULL)
return(ENXIO);
@@ -1443,6 +1484,7 @@ ndis_get_info(arg, oid, buf, buflen)
__stdcall ndis_queryinfo_handler queryfunc;
uint32_t byteswritten = 0, bytesneeded = 0;
int error;
+ uint8_t irql;
sc = arg;
NDIS_LOCK(sc);
@@ -1453,15 +1495,18 @@ ndis_get_info(arg, oid, buf, buflen)
if (adapter == NULL || queryfunc == NULL)
return(ENXIO);
+ irql = FASTCALL1(hal_raise_irql, DISPATCH_LEVEL);
rval = queryfunc(adapter, oid, buf, *buflen,
&byteswritten, &bytesneeded);
+ FASTCALL1(hal_lower_irql, irql);
/* Wait for requests that block. */
if (rval == NDIS_STATUS_PENDING) {
PROC_LOCK(curthread->td_proc);
error = msleep(&sc->ndis_block.nmb_wkupdpctimer,
- &curthread->td_proc->p_mtx, PPAUSE|PDROP,
+ &curthread->td_proc->p_mtx,
+ curthread->td_priority|PDROP,
"ndisget", 5 * hz);
rval = sc->ndis_block.nmb_getstat;
}
OpenPOWER on IntegriCloud