summaryrefslogtreecommitdiffstats
path: root/sys/compat/ndis/subr_hal.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/compat/ndis/subr_hal.c')
-rw-r--r--sys/compat/ndis/subr_hal.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/sys/compat/ndis/subr_hal.c b/sys/compat/ndis/subr_hal.c
index 81dcade..b72613c 100644
--- a/sys/compat/ndis/subr_hal.c
+++ b/sys/compat/ndis/subr_hal.c
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/sched.h>
+#include <sys/module.h>
#include <sys/systm.h>
#include <machine/clock.h>
@@ -223,13 +224,19 @@ READ_PORT_BUFFER_UCHAR(port, val, cnt)
* until the current thread lowers the IRQL to something less than
* DISPATCH_LEVEL.
*
- * In FreeBSD, ISRs run in interrupt threads, so to duplicate the
- * Windows notion of IRQLs, we use the following rules:
+ * There's another commonly used IRQL in Windows, which is APC_LEVEL.
+ * An APC is an Asynchronous Procedure Call, which differs from a DPC
+ * (Defered Procedure Call) in that a DPC is queued up to run in
+ * another thread, while an APC runs in the thread that scheduled
+ * it (similar to a signal handler in a UNIX process). We don't
+ * actually support the notion of APCs in FreeBSD, so for now, the
+ * only IRQLs we're interested in are DISPATCH_LEVEL and PASSIVE_LEVEL.
*
- * PASSIVE_LEVEL == normal kernel thread priority
- * DISPATCH_LEVEL == lowest interrupt thread priotity (PI_SOFT)
- * DEVICE_LEVEL == highest interrupt thread priority (PI_REALTIME)
- * HIGH_LEVEL == interrupts disabled (critical_enter())
+ * To simulate DISPATCH_LEVEL, we raise the current thread's priority
+ * to PI_REALTIME, which is the highest we can give it. This should,
+ * if I understand things correctly, prevent anything except for an
+ * interrupt thread from preempting us. PASSIVE_LEVEL is basically
+ * everything else.
*
* Be aware that, at least on the x86 arch, the Windows spinlock
* functions are divided up in peculiar ways. The actual spinlock
@@ -306,6 +313,9 @@ KfRaiseIrql(REGARGS1(uint8_t irql))
mtx_lock_spin(&sched_lock);
oldirql = curthread->td_base_pri;
sched_prio(curthread, PI_REALTIME);
+#if __FreeBSD_version < 600000
+ curthread->td_base_pri = PI_REALTIME;
+#endif
mtx_unlock_spin(&sched_lock);
return(oldirql);
@@ -321,6 +331,9 @@ KfLowerIrql(REGARGS1(uint8_t oldirql))
panic("IRQL_NOT_GREATER_THAN");
mtx_lock_spin(&sched_lock);
+#if __FreeBSD_version < 600000
+ curthread->td_base_pri = oldirql;
+#endif
sched_prio(curthread, oldirql);
mtx_unlock_spin(&sched_lock);
OpenPOWER on IntegriCloud