summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>2004-03-04 23:04:02 +0000
committerwpaul <wpaul@FreeBSD.org>2004-03-04 23:04:02 +0000
commitf7976fadc05b3d03706b33163ca71bf8f902a35b (patch)
tree71cd8814b9377c6db5c3b2cd2e0c62bba05852c3
parent578e7d07f00758939fc49f7a8a56d73cd208df95 (diff)
downloadFreeBSD-src-f7976fadc05b3d03706b33163ca71bf8f902a35b.zip
FreeBSD-src-f7976fadc05b3d03706b33163ca71bf8f902a35b.tar.gz
- Some older Atheros drivers want KeInitializeTimer(), so implement it,
along with KeInitializeTimerEx(), KeSetTimer(), KeSetTimerEx(), KeCancelTimer(), KeReadStateTimer() and KeInitializeDpc(). I don't know for certain that these will make the Atheros driver happy since I don't have the card/driver combo needed to test it, but these are fairly independent so they shouldn't break anything else. - Debugger() is present even in kernels without options DDB, so no conditional compilation is necessary (pointed out by bde). - Remove the extra km_acquirecnt member that I added to struct kmutant and embed it within an unused portion of the structure instead, so that we don't make the structure larger than it's defined to be in Windows. I don't know what crack I was smoking when I decided it was ok to do this, but it's worn off now.
-rw-r--r--sys/compat/ndis/ntoskrnl_var.h34
-rw-r--r--sys/compat/ndis/subr_ntoskrnl.c200
-rw-r--r--sys/modules/ndis/Makefile1
3 files changed, 215 insertions, 20 deletions
diff --git a/sys/compat/ndis/ntoskrnl_var.h b/sys/compat/ndis/ntoskrnl_var.h
index 3ff4a73..56970c0 100644
--- a/sys/compat/ndis/ntoskrnl_var.h
+++ b/sys/compat/ndis/ntoskrnl_var.h
@@ -212,14 +212,35 @@ typedef struct nt_objref nt_objref;
#define EVENT_TYPE_NOTIFY 0
#define EVENT_TYPE_SYNC 1
+/*
+ * We need to use the timeout()/untimeout() API for ktimers
+ * since timers can be initialized, but not destroyed (so
+ * malloc()ing our own callout structures would mean a leak,
+ * since there'd be no way to free() them). This means we
+ * need to use struct callout_handle, which is really just a
+ * pointer. To make it easier to deal with, we use a union
+ * to overlay the callout_handle over the k_timerlistentry.
+ * The latter is a list_entry, which is two pointers, so
+ * there's enough space available to hide a callout_handle
+ * there.
+ */
+
struct ktimer {
nt_dispatch_header k_header;
uint64_t k_duetime;
- list_entry k_timerlistentry;
+ union {
+ list_entry k_timerlistentry;
+ struct callout_handle k_handle;
+ } u;
void *k_dpc;
uint32_t k_period;
};
+#define k_timerlistentry u.k_timerlistentry
+#define k_handle u.k_handle
+
+typedef struct ktimer ktimer;
+
struct nt_kevent {
nt_dispatch_header k_header;
};
@@ -243,6 +264,8 @@ struct kdpc {
uint32_t *k_lock;
};
+typedef struct kdpc kdpc;
+
/*
* Note: the acquisition count is BSD-specific. The Microsoft
* documentation says that mutexes can be acquired recursively
@@ -256,13 +279,18 @@ struct kdpc {
*/
struct kmutant {
nt_dispatch_header km_header;
- list_entry km_listentry;
+ union {
+ list_entry km_listentry;
+ uint32_t km_acquirecnt;
+ } u;
void *km_ownerthread;
uint8_t km_abandoned;
uint8_t km_apcdisable;
- uint32_t km_acquirecnt;
};
+#define km_listentry u.km_listentry
+#define km_acquirecnt u.km_acquirecnt
+
typedef struct kmutant kmutant;
#define LOOKASIDE_DEPTH 256
diff --git a/sys/compat/ndis/subr_ntoskrnl.c b/sys/compat/ndis/subr_ntoskrnl.c
index f6d0df8..556de35 100644
--- a/sys/compat/ndis/subr_ntoskrnl.c
+++ b/sys/compat/ndis/subr_ntoskrnl.c
@@ -64,8 +64,6 @@ __FBSDID("$FreeBSD$");
#include <compat/ndis/ntoskrnl_var.h>
#include <compat/ndis/ndis_var.h>
-#include "opt_ddb.h"
-
#define __regparm __attribute__((regparm(3)))
#define FUNC void(*)(void)
@@ -92,6 +90,15 @@ __stdcall static void ntoskrnl_clear_event(nt_kevent *);
__stdcall static uint32_t ntoskrnl_read_event(nt_kevent *);
__stdcall static uint32_t ntoskrnl_set_event(nt_kevent *, uint32_t, uint8_t);
__stdcall static uint32_t ntoskrnl_reset_event(nt_kevent *);
+static void ntoskrnl_timercall(void *);
+__stdcall static void ntoskrnl_init_dpc(kdpc *, void *, void *);
+__stdcall static void ntoskrnl_init_timer(ktimer *);
+__stdcall static void ntoskrnl_init_timer_ex(ktimer *, uint32_t);
+__stdcall static uint8_t ntoskrnl_set_timer(ktimer *, int64_t, kdpc *);
+__stdcall static uint8_t ntoskrnl_set_timer_ex(ktimer *, int64_t,
+ uint32_t, kdpc *);
+__stdcall static uint8_t ntoskrnl_cancel_timer(ktimer *);
+__stdcall static uint8_t ntoskrnl_read_timer(ktimer *);
__stdcall static void ntoskrnl_writereg_ushort(uint16_t *, uint16_t);
__stdcall static uint16_t ntoskrnl_readreg_ushort(uint16_t *);
__stdcall static void ntoskrnl_writereg_ulong(uint32_t *, uint32_t);
@@ -1636,14 +1643,177 @@ ntoskrnl_dbgprint(char *fmt, ...)
__stdcall static void
ntoskrnl_debugger(void)
{
-#ifdef DDB
- Debugger("debug from winkernel module");
-#else
- printf("ntoskrnl_debugger(): DDB not present\n");
-#endif
+ Debugger("ntoskrnl_debugger(): breakpoint");
+ return;
+}
+
+static void
+ntoskrnl_timercall(arg)
+ void *arg;
+{
+ ktimer *timer;
+ __stdcall kdpc_func timerfunc;
+ kdpc *dpc;
+ struct timeval tv;
+
+ timer = arg;
+ dpc = timer->k_dpc;
+ timerfunc = (kdpc_func)dpc->k_deferedfunc;
+ timerfunc(dpc, dpc->k_deferredctx, dpc->k_sysarg1, dpc->k_sysarg2);
+
+ ntoskrnl_wakeup(&timer->k_header);
+
+ /*
+ * If this is a periodic timer, re-arm it
+ * so it will fire again.
+ */
+
+ if (timer->k_period) {
+ tv.tv_sec = 0;
+ tv.tv_usec = timer->k_period * 1000;
+ timer->k_handle =
+ timeout(ntoskrnl_timercall, timer, tvtohz(&tv));
+ }
+
+ return;
+}
+
+__stdcall static void
+ntoskrnl_init_timer(timer)
+ ktimer *timer;
+{
+ if (timer == NULL)
+ return;
+
+ INIT_LIST_HEAD((&timer->k_header.dh_waitlisthead));
+ timer->k_header.dh_sigstate = FALSE;
+ timer->k_header.dh_type = EVENT_TYPE_NOTIFY;
+ timer->k_header.dh_size = OTYPE_TIMER;
+ callout_handle_init(&timer->k_handle);
+
+ return;
+}
+
+__stdcall static void
+ntoskrnl_init_timer_ex(timer, type)
+ ktimer *timer;
+ uint32_t type;
+{
+ if (timer == NULL)
+ return;
+
+ INIT_LIST_HEAD((&timer->k_header.dh_waitlisthead));
+ timer->k_header.dh_sigstate = FALSE;
+ timer->k_header.dh_type = type;
+ timer->k_header.dh_size = OTYPE_TIMER;
+ callout_handle_init(&timer->k_handle);
+
+ return;
+}
+
+__stdcall static void
+ntoskrnl_init_dpc(dpc, dpcfunc, dpcctx)
+ kdpc *dpc;
+ void *dpcfunc;
+ void *dpcctx;
+{
+ if (dpc == NULL)
+ return;
+
+ dpc->k_deferedfunc = dpcfunc;
+ dpc->k_deferredctx = dpcctx;
+
return;
}
+__stdcall static uint8_t
+ntoskrnl_set_timer_ex(timer, duetime, period, dpc)
+ ktimer *timer;
+ int64_t duetime;
+ uint32_t period;
+ kdpc *dpc;
+{
+ struct timeval tv;
+ uint64_t curtime;
+ uint8_t pending;
+
+ if (timer == NULL)
+ return(FALSE);
+
+ if (timer->k_handle.callout != NULL &&
+ callout_pending(timer->k_handle.callout))
+ pending = TRUE;
+ else
+ pending = FALSE;
+
+ timer->k_duetime = duetime;
+ timer->k_period = period;
+ timer->k_header.dh_sigstate = FALSE;
+ timer->k_dpc = dpc;
+
+ if (duetime < 0) {
+ tv.tv_sec = - (duetime) / 10000000 ;
+ tv.tv_usec = (- (duetime) / 10) -
+ (tv.tv_sec * 1000000);
+ } else {
+ ntoskrnl_time(&curtime);
+ tv.tv_sec = ((duetime) - curtime) / 10000000 ;
+ tv.tv_usec = ((duetime) - curtime) / 10 -
+ (tv.tv_sec * 1000000);
+ }
+
+ timer->k_handle = timeout(ntoskrnl_timercall, timer, tvtohz(&tv));
+
+ return(pending);
+}
+
+__stdcall static uint8_t
+ntoskrnl_set_timer(timer, duetime, dpc)
+ ktimer *timer;
+ int64_t duetime;
+ kdpc *dpc;
+{
+ return (ntoskrnl_set_timer_ex(timer, duetime, 0, dpc));
+}
+
+__stdcall static uint8_t
+ntoskrnl_cancel_timer(timer)
+ ktimer *timer;
+{
+ uint8_t pending;
+
+ if (timer == NULL)
+ return(FALSE);
+
+ if (timer->k_handle.callout != NULL &&
+ callout_pending(timer->k_handle.callout))
+ pending = TRUE;
+ else
+ pending = FALSE;
+
+ untimeout(ntoskrnl_timercall, timer, timer->k_handle);
+
+ return(pending);
+}
+
+__stdcall static uint8_t
+ntoskrnl_read_timer(timer)
+ ktimer *timer;
+{
+ uint8_t pending;
+
+ if (timer == NULL)
+ return(FALSE);
+
+ if (timer->k_handle.callout != NULL &&
+ callout_pending(timer->k_handle.callout))
+ pending = TRUE;
+ else
+ pending = FALSE;
+
+ return(pending);
+}
+
__stdcall static void
dummy()
{
@@ -1730,15 +1900,13 @@ image_patch_table ntoskrnl_functbl[] = {
{ "KeResetEvent", (FUNC)ntoskrnl_reset_event },
{ "KeClearEvent", (FUNC)ntoskrnl_clear_event },
{ "KeReadStateEvent", (FUNC)ntoskrnl_read_event },
-#ifdef notyet
- { "KeInitializeTimer",
- { "KeInitializeTimerEx",
- { "KeCancelTimer",
- { "KeSetTimer",
- { "KeSetTimerEx",
- { "KeReadStateTimer",
- { "KeInitializeDpc",
-#endif
+ { "KeInitializeTimer", (FUNC)ntoskrnl_init_timer },
+ { "KeInitializeTimerEx", (FUNC)ntoskrnl_init_timer_ex },
+ { "KeInitializeDpc", (FUNC)ntoskrnl_init_dpc },
+ { "KeSetTimer", (FUNC)ntoskrnl_set_timer },
+ { "KeSetTimerEx", (FUNC)ntoskrnl_set_timer_ex },
+ { "KeCancelTimer", (FUNC)ntoskrnl_cancel_timer },
+ { "KeReadStateTimer", (FUNC)ntoskrnl_read_timer },
{ "ObReferenceObjectByHandle", (FUNC)ntoskrnl_objref },
{ "ObfDereferenceObject", (FUNC)ntoskrnl_objderef },
{ "ZwClose", (FUNC)ntoskrnl_zwclose },
diff --git a/sys/modules/ndis/Makefile b/sys/modules/ndis/Makefile
index 135f296..fe9d308 100644
--- a/sys/modules/ndis/Makefile
+++ b/sys/modules/ndis/Makefile
@@ -5,6 +5,5 @@
KMOD= ndis
SRCS= subr_pe.c subr_ndis.c subr_hal.c subr_ntoskrnl.c kern_ndis.c
SRCS+= opt_bdg.h device_if.h bus_if.h pci_if.h card_if.h vnode_if.h
-SRCS+= opt_ddb.h
.include <bsd.kmod.mk>
OpenPOWER on IntegriCloud