diff options
author | wpaul <wpaul@FreeBSD.org> | 2004-01-12 21:00:48 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 2004-01-12 21:00:48 +0000 |
commit | 377a4756cda494302db31c4722b9306848499b34 (patch) | |
tree | 4f7ea1efb8a1bf52cf9ba6675a44201418610216 | |
parent | ee6a0c1737a80a14501637f982468a667622dde7 (diff) | |
download | FreeBSD-src-377a4756cda494302db31c4722b9306848499b34.zip FreeBSD-src-377a4756cda494302db31c4722b9306848499b34.tar.gz |
In if_ndis.c:ndis_intr(), be a bit more intelligent about squelching
unexpected interrupts. If an interrupt is triggered and we're not
finished initializing yet, bail. If we have finished initializing,
but IFF_UP isn't set yet, drain the interrupt with ndis_intr() or
ndis_disable_intr() as appropriate, then return _without_ scheduling
ndis_intrtask().
In kern_ndis.c:ndis_load_driver() only relocate/dynalink a given driver
image once. Trying to relocate an image that's already been relocated
will trash the image. We poison a part of the image header that we
don't otherwise need with a magic value to indicate it's already been
fixed up. This fixes the case where there are multiple units of the
same kind of device.
-rw-r--r-- | sys/compat/ndis/kern_ndis.c | 40 | ||||
-rw-r--r-- | sys/compat/ndis/subr_ntoskrnl.c | 70 |
2 files changed, 96 insertions, 14 deletions
diff --git a/sys/compat/ndis/kern_ndis.c b/sys/compat/ndis/kern_ndis.c index 39a8be4..50b9e8f 100644 --- a/sys/compat/ndis/kern_ndis.c +++ b/sys/compat/ndis/kern_ndis.c @@ -477,12 +477,14 @@ ndis_convert_res(arg) if (brl != NULL) { SLIST_FOREACH(brle, brl, link) { switch (brle->type) { +#ifdef notdef case SYS_RES_IOPORT: prd->cprd_type = CmResourceTypePort; prd->u.cprd_port.cprd_start.np_quad = brle->start; prd->u.cprd_port.cprd_len = brle->count; break; +#endif case SYS_RES_MEMORY: prd->cprd_type = CmResourceTypeMemory; prd->u.cprd_port.cprd_start.np_quad = @@ -1084,6 +1086,8 @@ ndis_unload_driver(arg) return(0); } +#define NDIS_LOADED 0x42534F44 + int ndis_load_driver(img, arg) vm_offset_t img; @@ -1102,22 +1106,34 @@ ndis_load_driver(img, arg) sc = arg; - /* Perform text relocation */ - if (pe_relocate(img)) - return(ENOEXEC); + /* + * Only perform the relocation/linking phase once + * since the binary image may be shared among multiple + * device instances. + */ - /* Dynamically link the NDIS.SYS routines -- required. */ - if (pe_patch_imports(img, "NDIS", ndis_functbl)) - return(ENOEXEC); + ptr = (uint32_t *)(img + 8); + if (*ptr != NDIS_LOADED) { + /* Perform text relocation */ + if (pe_relocate(img)) + return(ENOEXEC); - /* Dynamically link the HAL.dll routines -- also required. */ - if (pe_patch_imports(img, "HAL", hal_functbl)) - return(ENOEXEC); + /* Dynamically link the NDIS.SYS routines -- required. */ + if (pe_patch_imports(img, "NDIS", ndis_functbl)) + return(ENOEXEC); - /* Dynamically link ntoskrnl.exe -- optional. */ - if (pe_get_import_descriptor(img, &imp_desc, "ntoskrnl") == 0) { - if (pe_patch_imports(img, "ntoskrnl", ntoskrnl_functbl)) + /* Dynamically link the HAL.dll routines -- also required. */ + if (pe_patch_imports(img, "HAL", hal_functbl)) return(ENOEXEC); + + /* Dynamically link ntoskrnl.exe -- optional. */ + if (pe_get_import_descriptor(img, + &imp_desc, "ntoskrnl") == 0) { + if (pe_patch_imports(img, + "ntoskrnl", ntoskrnl_functbl)) + return(ENOEXEC); + } + *ptr = NDIS_LOADED; } /* Locate the driver entry point */ diff --git a/sys/compat/ndis/subr_ntoskrnl.c b/sys/compat/ndis/subr_ntoskrnl.c index 14a446b..5376008 100644 --- a/sys/compat/ndis/subr_ntoskrnl.c +++ b/sys/compat/ndis/subr_ntoskrnl.c @@ -119,8 +119,12 @@ __stdcall static uint32_t __stdcall static void ntoskrnl_freemdl(ndis_buffer *); __stdcall static void *ntoskrnl_mmaplockedpages(ndis_buffer *, uint8_t); __stdcall static void ntoskrnl_init_lock(kspin_lock *); -__stdcall static void dummy(void); __stdcall static size_t ntoskrnl_memcmp(const void *, const void *, size_t); +__stdcall static void ntoskrnl_init_ansi_string(ndis_ansi_string *, char *); +__stdcall static void ntoskrnl_init_unicode_string(ndis_unicode_string *, + uint16_t *); +__stdcall static void ntoskrnl_free_unicode_string(ndis_unicode_string *); +__stdcall static void dummy(void); static struct mtx *ntoskrnl_interlock; extern struct mtx_pool *ndis_mtxpool; @@ -185,8 +189,12 @@ ntoskrnl_unicode_to_ansi(dest, src, allocate) { char *astr = NULL; + if (dest == NULL || src == NULL) + return(NDIS_STATUS_FAILURE); + if (allocate) { - ndis_unicode_to_ascii(src->nus_buf, src->nus_len, &astr); + if (ndis_unicode_to_ascii(src->nus_buf, src->nus_len, &astr)) + return(NDIS_STATUS_FAILURE); dest->nas_buf = astr; dest->nas_len = dest->nas_maxlen = strlen(astr); } else { @@ -647,6 +655,60 @@ ntoskrnl_memcmp(s1, s2, len) } __stdcall static void +ntoskrnl_init_ansi_string(dst, src) + ndis_ansi_string *dst; + char *src; +{ + ndis_ansi_string *a; + + a = dst; + if (a == NULL) + return; + if (src == NULL) { + a->nas_len = a->nas_maxlen = 0; + a->nas_buf = NULL; + } else { + a->nas_buf = src; + a->nas_len = a->nas_maxlen = strlen(src); + } + + return; +} + +__stdcall static void +ntoskrnl_init_unicode_string(dst, src) + ndis_unicode_string *dst; + uint16_t *src; +{ + ndis_unicode_string *u; + int i; + + u = dst; + if (u == NULL) + return; + if (src == NULL) { + u->nus_len = u->nus_maxlen = 0; + u->nus_buf = NULL; + } else { + i = 0; + while(src[i] != 0) + i++; + u->nus_buf = src; + u->nus_len = u->nus_maxlen = i * 2; + } + + return; +} + +__stdcall static void +ntoskrnl_free_unicode_string(ustr) + ndis_unicode_string *ustr; +{ + free(ustr->nus_buf, M_DEVBUF); + return; +} + +__stdcall static void dummy() { printf ("ntoskrnl dummy called...\n"); @@ -659,6 +721,10 @@ image_patch_table ntoskrnl_functbl[] = { { "RtlEqualUnicodeString", (FUNC)ntoskrnl_unicode_equal }, { "RtlCopyUnicodeString", (FUNC)ntoskrnl_unicode_copy }, { "RtlUnicodeStringToAnsiString", (FUNC)ntoskrnl_unicode_to_ansi }, + { "RtlAnsiStringToUnicodeString", (FUNC)ntoskrnl_ansi_to_unicode }, + { "RtlInitAnsiString", (FUNC)ntoskrnl_init_ansi_string }, + { "RtlInitUnicodeString", (FUNC)ntoskrnl_init_unicode_string }, + { "RtlFreeUnicodeString", (FUNC)ndoskrnl_free_unicode_string }, { "sprintf", (FUNC)sprintf }, { "DbgPrint", (FUNC)printf }, { "strncmp", (FUNC)strncmp }, |