From 621b33fc5bb319d80e027197635f0846292cd5a4 Mon Sep 17 00:00:00 2001 From: Bill Paul Date: Thu, 31 Mar 2005 16:38:48 +0000 Subject: [PATCH] Fix an amd64 issue I overlooked. When setting up a callout to ndis_timercall() in NdisMInitializeTimer(), we can't use the raw function pointer. This is because ntoskrnl_run_dpc() expects to invoke a function with Microsoft calling conventions. On i386, this works because ndis_timercall() is declared with the __stdcall attribute, but this is a no-op on amd64. To do it correctly, we have to generate a wrapper for ndis_timercall() and us the wrapper instead of of the raw function pointer. Fix this by adding ndis_timercall() to the funcptr table in subr_ndis.c, and create ndis_findwrap() to extract the wrapped function from the table in NdisMInitializeTimer() instead of just passing ndis_timercall() to KeInitializeDpc() directly. --- sys/compat/ndis/subr_ndis.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/sys/compat/ndis/subr_ndis.c b/sys/compat/ndis/subr_ndis.c index 388cd6204bf..6afd419783c 100644 --- a/sys/compat/ndis/subr_ndis.c +++ b/sys/compat/ndis/subr_ndis.c @@ -271,6 +271,7 @@ __stdcall static void NdisMIndicateStatusComplete(ndis_handle); __stdcall static void NdisMIndicateStatus(ndis_handle, ndis_status, void *, uint32_t); static void ndis_workfunc(void *); +static funcptr ndis_findwrap(funcptr); __stdcall static ndis_status NdisScheduleWorkItem(ndis_work_item *); __stdcall static void NdisCopyFromPacketToPacket(ndis_packet *, uint32_t, uint32_t, ndis_packet *, uint32_t, uint32_t *); @@ -327,6 +328,22 @@ ndis_libfini() return(0); } +static funcptr +ndis_findwrap(func) + funcptr func; +{ + image_patch_table *patch; + + patch = ntoskrnl_functbl; + while (patch->ipt_func != NULL) { + if ((funcptr)patch->ipt_func == func) + return((funcptr)patch->ipt_wrap); + patch++; + } + + return(NULL); +} + /* * NDIS deals with strings in unicode format, so we have * do deal with them that way too. For now, we only handle @@ -1188,10 +1205,15 @@ NdisMInitializeTimer(timer, handle, func, ctx) timer->nmt_timerctx = ctx; timer->nmt_block = handle; - /* Set up the timer so it will call our intermediate DPC. */ - + /* + * Set up the timer so it will call our intermediate DPC. + * Be sure to use the wrapped entry point, since + * ntoskrnl_run_dpc() expects to invoke a function with + * Microsoft calling conventions. + */ KeInitializeTimer(&timer->nmt_ktimer); - KeInitializeDpc(&timer->nmt_kdpc, ndis_timercall, timer); + KeInitializeDpc(&timer->nmt_kdpc, + ndis_findwrap((funcptr)ndis_timercall), timer); return; } @@ -3266,6 +3288,7 @@ image_patch_table ndis_functbl[] = { IMPORT_FUNC(NdisMDeregisterDevice), IMPORT_FUNC(NdisMQueryAdapterInstanceName), IMPORT_FUNC(NdisMRegisterUnloadHandler), + IMPORT_FUNC(ndis_timercall), /* * This last entry is a catch-all for any function we haven't