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.
This commit is contained in:
Bill Paul 2004-01-12 21:00:48 +00:00
parent 361c31ad14
commit 958e09f637
2 changed files with 98 additions and 16 deletions

View File

@ -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);
/* 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))
ptr = (uint32_t *)(img + 8);
if (*ptr != NDIS_LOADED) {
/* Perform text relocation */
if (pe_relocate(img))
return(ENOEXEC);
/* Dynamically link the NDIS.SYS routines -- required. */
if (pe_patch_imports(img, "NDIS", ndis_functbl))
return(ENOEXEC);
/* 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 */

View File

@ -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 {
@ -646,6 +654,60 @@ ntoskrnl_memcmp(s1, s2, len)
return(total);
}
__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()
{
@ -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 },