diff options
author | wpaul <wpaul@FreeBSD.org> | 2004-03-04 23:04:02 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 2004-03-04 23:04:02 +0000 |
commit | f7976fadc05b3d03706b33163ca71bf8f902a35b (patch) | |
tree | 71cd8814b9377c6db5c3b2cd2e0c62bba05852c3 | |
parent | 578e7d07f00758939fc49f7a8a56d73cd208df95 (diff) | |
download | FreeBSD-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.h | 34 | ||||
-rw-r--r-- | sys/compat/ndis/subr_ntoskrnl.c | 200 | ||||
-rw-r--r-- | sys/modules/ndis/Makefile | 1 |
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> |