summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>2004-01-12 21:00:48 +0000
committerwpaul <wpaul@FreeBSD.org>2004-01-12 21:00:48 +0000
commit377a4756cda494302db31c4722b9306848499b34 (patch)
tree4f7ea1efb8a1bf52cf9ba6675a44201418610216
parentee6a0c1737a80a14501637f982468a667622dde7 (diff)
downloadFreeBSD-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.c40
-rw-r--r--sys/compat/ndis/subr_ntoskrnl.c70
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 },
OpenPOWER on IntegriCloud