summaryrefslogtreecommitdiffstats
path: root/sys/compat/ndis/subr_ntoskrnl.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/compat/ndis/subr_ntoskrnl.c')
-rw-r--r--sys/compat/ndis/subr_ntoskrnl.c141
1 files changed, 66 insertions, 75 deletions
diff --git a/sys/compat/ndis/subr_ntoskrnl.c b/sys/compat/ndis/subr_ntoskrnl.c
index 8c9646c..7162d59 100644
--- a/sys/compat/ndis/subr_ntoskrnl.c
+++ b/sys/compat/ndis/subr_ntoskrnl.c
@@ -121,8 +121,6 @@ __stdcall static slist_entry *ntoskrnl_push_slist_ex(/*slist_header *,
slist_entry *,*/ kspin_lock *);
__stdcall static slist_entry *ntoskrnl_pop_slist_ex(/*slist_header *,
kspin_lock * */void);
-__stdcall static void ntoskrnl_lock_dpc(/*kspin_lock * */ void);
-__stdcall static void ntoskrnl_unlock_dpc(/*kspin_lock * */ void);
__stdcall static uint32_t
ntoskrnl_interlock_inc(/*volatile uint32_t * */ void);
__stdcall static uint32_t
@@ -167,17 +165,17 @@ static uint32_t ntoskrnl_dbgprint(char *, ...);
__stdcall static void ntoskrnl_debugger(void);
__stdcall static void dummy(void);
-static struct mtx *ntoskrnl_interlock;
-struct mtx *ntoskrnl_dispatchlock;
-extern struct mtx_pool *ndis_mtxpool;
+static struct mtx ntoskrnl_dispatchlock;
+static kspin_lock ntoskrnl_global;
static int ntoskrnl_kth = 0;
static struct nt_objref_head ntoskrnl_reflist;
int
ntoskrnl_libinit()
{
- ntoskrnl_interlock = mtx_pool_alloc(ndis_mtxpool);
- ntoskrnl_dispatchlock = mtx_pool_alloc(ndis_mtxpool);
+ mtx_init(&ntoskrnl_dispatchlock,
+ "ntoskrnl dispatch lock", MTX_NDIS_LOCK, MTX_DEF);
+ ntoskrnl_init_lock(&ntoskrnl_global);
TAILQ_INIT(&ntoskrnl_reflist);
return(0);
}
@@ -185,6 +183,7 @@ ntoskrnl_libinit()
int
ntoskrnl_libfini()
{
+ mtx_destroy(&ntoskrnl_dispatchlock);
return(0);
}
@@ -324,16 +323,13 @@ ntoskrnl_wakeup(arg)
obj = arg;
- mtx_pool_lock(ndis_mtxpool, ntoskrnl_dispatchlock);
+ mtx_lock(&ntoskrnl_dispatchlock);
obj->dh_sigstate = TRUE;
e = obj->dh_waitlisthead.nle_flink;
while (e != &obj->dh_waitlisthead) {
w = (wait_block *)e;
td = w->wb_kthread;
- if (td->td_proc->p_flag & P_KTHREAD)
- kthread_resume(td->td_proc);
- else
- wakeup(td);
+ ndis_thresume(td->td_proc);
/*
* For synchronization objects, only wake up
* the first waiter.
@@ -342,7 +338,7 @@ ntoskrnl_wakeup(arg)
break;
e = e->nle_flink;
}
- mtx_pool_unlock(ndis_mtxpool, ntoskrnl_dispatchlock);
+ mtx_unlock(&ntoskrnl_dispatchlock);
return;
}
@@ -436,7 +432,7 @@ ntoskrnl_waitforobj(obj, reason, mode, alertable, duetime)
if (obj == NULL)
return(STATUS_INVALID_PARAMETER);
- mtx_pool_lock(ndis_mtxpool, ntoskrnl_dispatchlock);
+ mtx_lock(&ntoskrnl_dispatchlock);
/*
* See if the object is a mutex. If so, and we already own
@@ -455,13 +451,13 @@ ntoskrnl_waitforobj(obj, reason, mode, alertable, duetime)
obj->dh_sigstate = FALSE;
km->km_acquirecnt++;
km->km_ownerthread = curthread->td_proc;
- mtx_pool_unlock(ndis_mtxpool, ntoskrnl_dispatchlock);
+ mtx_unlock(&ntoskrnl_dispatchlock);
return (STATUS_SUCCESS);
}
} else if (obj->dh_sigstate == TRUE) {
if (obj->dh_type == EVENT_TYPE_SYNC)
obj->dh_sigstate = FALSE;
- mtx_pool_unlock(ndis_mtxpool, ntoskrnl_dispatchlock);
+ mtx_unlock(&ntoskrnl_dispatchlock);
return (STATUS_SUCCESS);
}
@@ -496,22 +492,18 @@ ntoskrnl_waitforobj(obj, reason, mode, alertable, duetime)
}
}
- mtx_pool_unlock(ndis_mtxpool, ntoskrnl_dispatchlock);
+ mtx_unlock(&ntoskrnl_dispatchlock);
- if (td->td_proc->p_flag & P_KTHREAD)
- error = kthread_suspend(td->td_proc,
- duetime == NULL ? 0 : tvtohz(&tv));
- else
- error = tsleep(td, PPAUSE|PDROP, "ndisws",
- duetime == NULL ? 0 : tvtohz(&tv));
+ error = ndis_thsuspend(td->td_proc,
+ duetime == NULL ? 0 : tvtohz(&tv));
- mtx_pool_lock(ndis_mtxpool, ntoskrnl_dispatchlock);
+ mtx_lock(&ntoskrnl_dispatchlock);
/* We timed out. Leave the object alone and return status. */
if (error == EWOULDBLOCK) {
REMOVE_LIST_ENTRY((&w.wb_waitlist));
- mtx_pool_unlock(ndis_mtxpool, ntoskrnl_dispatchlock);
+ mtx_unlock(&ntoskrnl_dispatchlock);
return(STATUS_TIMEOUT);
}
@@ -534,7 +526,7 @@ ntoskrnl_waitforobj(obj, reason, mode, alertable, duetime)
obj->dh_sigstate = FALSE;
REMOVE_LIST_ENTRY((&w.wb_waitlist));
- mtx_pool_unlock(ndis_mtxpool, ntoskrnl_dispatchlock);
+ mtx_unlock(&ntoskrnl_dispatchlock);
return(STATUS_SUCCESS);
}
@@ -565,7 +557,7 @@ ntoskrnl_waitforobjs(cnt, obj, wtype, reason, mode,
if (cnt > THREAD_WAIT_OBJECTS && wb_array == NULL)
return(STATUS_INVALID_PARAMETER);
- mtx_pool_lock(ndis_mtxpool, ntoskrnl_dispatchlock);
+ mtx_lock(&ntoskrnl_dispatchlock);
if (wb_array == NULL)
w = &_wb_array[0];
@@ -583,8 +575,7 @@ ntoskrnl_waitforobjs(cnt, obj, wtype, reason, mode,
km->km_acquirecnt++;
km->km_ownerthread = curthread->td_proc;
if (wtype == WAITTYPE_ANY) {
- mtx_pool_unlock(ndis_mtxpool,
- ntoskrnl_dispatchlock);
+ mtx_unlock(&ntoskrnl_dispatchlock);
return (STATUS_WAIT_0 + i);
}
}
@@ -592,8 +583,7 @@ ntoskrnl_waitforobjs(cnt, obj, wtype, reason, mode,
if (obj[i]->dh_type == EVENT_TYPE_SYNC)
obj[i]->dh_sigstate = FALSE;
if (wtype == WAITTYPE_ANY) {
- mtx_pool_unlock(ndis_mtxpool,
- ntoskrnl_dispatchlock);
+ mtx_unlock(&ntoskrnl_dispatchlock);
return (STATUS_WAIT_0 + i);
}
}
@@ -633,16 +623,12 @@ ntoskrnl_waitforobjs(cnt, obj, wtype, reason, mode,
while (wcnt) {
nanotime(&t1);
- mtx_pool_unlock(ndis_mtxpool, ntoskrnl_dispatchlock);
+ mtx_unlock(&ntoskrnl_dispatchlock);
- if (td->td_proc->p_flag & P_KTHREAD)
- error = kthread_suspend(td->td_proc,
- duetime == NULL ? 0 : tvtohz(&tv));
- else
- error = tsleep(td, PPAUSE|PDROP, "ndisws",
- duetime == NULL ? 0 : tvtohz(&tv));
+ error = ndis_thsuspend(td->td_proc,
+ duetime == NULL ? 0 : tvtohz(&tv));
- mtx_pool_lock(ndis_mtxpool, ntoskrnl_dispatchlock);
+ mtx_lock(&ntoskrnl_dispatchlock);
nanotime(&t2);
for (i = 0; i < cnt; i++) {
@@ -678,16 +664,16 @@ ntoskrnl_waitforobjs(cnt, obj, wtype, reason, mode,
}
if (error == EWOULDBLOCK) {
- mtx_pool_unlock(ndis_mtxpool, ntoskrnl_dispatchlock);
+ mtx_unlock(&ntoskrnl_dispatchlock);
return(STATUS_TIMEOUT);
}
if (wtype == WAITTYPE_ANY && wcnt) {
- mtx_pool_unlock(ndis_mtxpool, ntoskrnl_dispatchlock);
+ mtx_unlock(&ntoskrnl_dispatchlock);
return(STATUS_WAIT_0 + widx);
}
- mtx_pool_unlock(ndis_mtxpool, ntoskrnl_dispatchlock);
+ mtx_unlock(&ntoskrnl_dispatchlock);
return(STATUS_SUCCESS);
}
@@ -880,9 +866,12 @@ ntoskrnl_init_lookaside(lookaside, allocfunc, freefunc,
uint32_t tag;
uint16_t depth;
{
- struct mtx *mtx;
+ bzero((char *)lookaside, sizeof(paged_lookaside_list));
- lookaside->nll_l.gl_size = size;
+ if (size < sizeof(slist_entry))
+ lookaside->nll_l.gl_size = sizeof(slist_entry);
+ else
+ lookaside->nll_l.gl_size = size;
lookaside->nll_l.gl_tag = tag;
if (allocfunc == NULL)
lookaside->nll_l.gl_allocfunc = ntoskrnl_allocfunc;
@@ -894,8 +883,7 @@ ntoskrnl_init_lookaside(lookaside, allocfunc, freefunc,
else
lookaside->nll_l.gl_freefunc = freefunc;
- mtx = mtx_pool_alloc(ndis_mtxpool);
- lookaside->nll_obsoletelock = (kspin_lock)mtx;
+ ntoskrnl_init_lock(&lookaside->nll_obsoletelock);
lookaside->nll_l.gl_depth = LOOKASIDE_DEPTH;
lookaside->nll_l.gl_maxdepth = LOOKASIDE_DEPTH;
@@ -928,8 +916,6 @@ ntoskrnl_init_nplookaside(lookaside, allocfunc, freefunc,
uint32_t tag;
uint16_t depth;
{
- struct mtx *mtx;
-
bzero((char *)lookaside, sizeof(npaged_lookaside_list));
if (size < sizeof(slist_entry))
@@ -947,8 +933,7 @@ ntoskrnl_init_nplookaside(lookaside, allocfunc, freefunc,
else
lookaside->nll_l.gl_freefunc = freefunc;
- mtx = mtx_pool_alloc(ndis_mtxpool);
- lookaside->nll_obsoletelock = (kspin_lock)mtx;
+ ntoskrnl_init_lock(&lookaside->nll_obsoletelock);
lookaside->nll_l.gl_depth = LOOKASIDE_DEPTH;
lookaside->nll_l.gl_maxdepth = LOOKASIDE_DEPTH;
@@ -987,9 +972,8 @@ ntoskrnl_push_slist(/*head, entry*/ void)
__asm__ __volatile__ ("" : "=c" (head), "=d" (entry));
- mtx_pool_lock(ndis_mtxpool, ntoskrnl_interlock);
- oldhead = ntoskrnl_pushsl(head, entry);
- mtx_pool_unlock(ndis_mtxpool, ntoskrnl_interlock);
+ oldhead = (slist_entry *)FASTCALL3(ntoskrnl_push_slist_ex,
+ head, entry, &ntoskrnl_global);
return(oldhead);
}
@@ -1002,9 +986,8 @@ ntoskrnl_pop_slist(/*head*/ void)
__asm__ __volatile__ ("" : "=c" (head));
- mtx_pool_lock(ndis_mtxpool, ntoskrnl_interlock);
- first = ntoskrnl_popsl(head);
- mtx_pool_unlock(ndis_mtxpool, ntoskrnl_interlock);
+ first = (slist_entry *)FASTCALL2(ntoskrnl_pop_slist_ex,
+ head, &ntoskrnl_global);
return(first);
}
@@ -1016,12 +999,13 @@ ntoskrnl_push_slist_ex(/*head, entry,*/ lock)
slist_header *head;
slist_entry *entry;
slist_entry *oldhead;
+ uint8_t irql;
__asm__ __volatile__ ("" : "=c" (head), "=d" (entry));
- mtx_pool_lock(ndis_mtxpool, (struct mtx *)*lock);
+ irql = FASTCALL2(hal_lock, lock, DISPATCH_LEVEL);
oldhead = ntoskrnl_pushsl(head, entry);
- mtx_pool_unlock(ndis_mtxpool, (struct mtx *)*lock);
+ FASTCALL2(hal_unlock, lock, irql);
return(oldhead);
}
@@ -1032,36 +1016,38 @@ ntoskrnl_pop_slist_ex(/*head, lock*/ void)
slist_header *head;
kspin_lock *lock;
slist_entry *first;
+ uint8_t irql;
__asm__ __volatile__ ("" : "=c" (head), "=d" (lock));
- mtx_pool_lock(ndis_mtxpool, (struct mtx *)*lock);
+ irql = FASTCALL2(hal_lock, lock, DISPATCH_LEVEL);
first = ntoskrnl_popsl(head);
- mtx_pool_unlock(ndis_mtxpool, (struct mtx *)*lock);
+ FASTCALL2(hal_unlock, lock, irql);
return(first);
}
-__stdcall static void
+__stdcall void
ntoskrnl_lock_dpc(/*lock*/ void)
{
kspin_lock *lock;
__asm__ __volatile__ ("" : "=c" (lock));
- mtx_pool_lock(ndis_mtxpool, (struct mtx *)*lock);
+ while (atomic_cmpset_int((volatile u_int *)lock, 0, 1) == 0)
+ /* do noting */;
return;
}
-__stdcall static void
+__stdcall void
ntoskrnl_unlock_dpc(/*lock*/ void)
{
kspin_lock *lock;
__asm__ __volatile__ ("" : "=c" (lock));
- mtx_pool_unlock(ndis_mtxpool, (struct mtx *)*lock);
+ atomic_cmpset_int((volatile u_int *)lock, 1, 0);
return;
}
@@ -1093,12 +1079,13 @@ ntoskrnl_interlock_addstat(/*addend, inc*/)
{
uint64_t *addend;
uint32_t inc;
+ uint8_t irql;
__asm__ __volatile__ ("" : "=c" (addend), "=d" (inc));
- mtx_pool_lock(ndis_mtxpool, ntoskrnl_interlock);
+ irql = FASTCALL2(hal_lock, &ntoskrnl_global, DISPATCH_LEVEL);
*addend += inc;
- mtx_pool_unlock(ndis_mtxpool, ntoskrnl_interlock);
+ FASTCALL2(hal_unlock, &ntoskrnl_global, irql);
return;
};
@@ -1196,7 +1183,7 @@ __stdcall static void
ntoskrnl_init_lock(lock)
kspin_lock *lock;
{
- *lock = (kspin_lock)mtx_pool_alloc(ndis_mtxpool);
+ *lock = 0;
return;
}
@@ -1423,18 +1410,18 @@ ntoskrnl_release_mutex(kmutex, kwait)
kmutant *kmutex;
uint8_t kwait;
{
- mtx_pool_lock(ndis_mtxpool, ntoskrnl_dispatchlock);
+ mtx_lock(&ntoskrnl_dispatchlock);
if (kmutex->km_ownerthread != curthread->td_proc) {
- mtx_pool_unlock(ndis_mtxpool, ntoskrnl_dispatchlock);
+ mtx_unlock(&ntoskrnl_dispatchlock);
return(STATUS_MUTANT_NOT_OWNED);
}
kmutex->km_acquirecnt--;
if (kmutex->km_acquirecnt == 0) {
kmutex->km_ownerthread = NULL;
- mtx_pool_unlock(ndis_mtxpool, ntoskrnl_dispatchlock);
+ mtx_unlock(&ntoskrnl_dispatchlock);
ntoskrnl_wakeup(&kmutex->km_header);
} else
- mtx_pool_unlock(ndis_mtxpool, ntoskrnl_dispatchlock);
+ mtx_unlock(&ntoskrnl_dispatchlock);
return(kmutex->km_acquirecnt);
}
@@ -1465,10 +1452,10 @@ ntoskrnl_reset_event(kevent)
{
uint32_t prevstate;
- mtx_pool_lock(ndis_mtxpool, ntoskrnl_dispatchlock);
+ mtx_lock(&ntoskrnl_dispatchlock);
prevstate = kevent->k_header.dh_sigstate;
kevent->k_header.dh_sigstate = FALSE;
- mtx_pool_unlock(ndis_mtxpool, ntoskrnl_dispatchlock);
+ mtx_unlock(&ntoskrnl_dispatchlock);
return(prevstate);
}
@@ -1628,7 +1615,7 @@ ntoskrnl_thread_exit(status)
ntoskrnl_kth--;
- kthread_exit(0);
+ kthread_exit(0);
return(0); /* notreached */
}
@@ -1721,7 +1708,8 @@ ntoskrnl_init_timer_ex(timer, type)
/*
* This is a wrapper for Windows deferred procedure calls that
* have been placed on an NDIS thread work queue. We need it
- * since the DPC could be a _stdcall function.
+ * since the DPC could be a _stdcall function. Also, as far as
+ * I can tell, defered procedure calls must run at DISPATCH_LEVEL.
*/
static void
ntoskrnl_run_dpc(arg)
@@ -1729,10 +1717,13 @@ ntoskrnl_run_dpc(arg)
{
__stdcall kdpc_func dpcfunc;
kdpc *dpc;
+ uint8_t irql;
dpc = arg;
dpcfunc = (kdpc_func)dpc->k_deferedfunc;
+ irql = FASTCALL1(hal_raise_irql, DISPATCH_LEVEL);
dpcfunc(dpc, dpc->k_deferredctx, dpc->k_sysarg1, dpc->k_sysarg2);
+ FASTCALL1(hal_lower_irql, irql);
return;
}
OpenPOWER on IntegriCloud