kern/171550: patch: "no match for InterlockedCompareExchange" and
then kernel panic upon kldload ndisgen module for RTL8188/8192CU
Chris Radek
chris at timeguy.com
Tue Sep 11 16:40:08 UTC 2012
>Number: 171550
>Category: kern
>Synopsis: patch: "no match for InterlockedCompareExchange" and then kernel panic upon kldload ndisgen module for RTL8188/8192CU
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Tue Sep 11 16:40:07 UTC 2012
>Closed-Date:
>Last-Modified:
>Originator: Chris Radek
>Release: 9.0-RELEASE-p4
>Organization:
>Environment:
FreeBSD tiny.timeguy.com 9.0-RELEASE-p4 FreeBSD 9.0-RELEASE-p4 #1: Fri Aug 24 17:13:08 CDT 2012 root at tiny.timeguy.com:/usr/obj/usr/src/sys/TINY i386
>Description:
One of the things I tried to get my Airlink101 AWLL5099 (usb wifi) working was wrapping various related drivers with ndisgen. This patch fixes a kernel panic upon loading the resulting .ko file, and eliminates the warning "no match for InterlockedCompareExchange".
The driver still didn't work, and I have moved on, but google searches tell me that other drivers may also need this call so I figure the patch might be helpful.
In my case, the remaining failure is "no match for PoRequestPowerIrp" and I don't understand that one well enough to fix it.
>How-To-Repeat:
Use ndisgen to wrap a windows driver that uses InterlockedCompareExchange. For example, the one found at: http://www.airlink101.com/support/index.php?cmd=files&id=202
Or apparently others:
http://lists.freebsd.org/pipermail/freebsd-current/2006-January/059723.html
>Fix:
Attached patch
Patch attached with submission follows:
diff --recursive -u usrsrc9.orig/sys/compat/ndis/ntoskrnl_var.h usrsrc9/sys/compat/ndis/ntoskrnl_var.h
--- usrsrc9.orig/sys/compat/ndis/ntoskrnl_var.h 2012-09-08 17:30:39.673644663 -0500
+++ usrsrc9/sys/compat/ndis/ntoskrnl_var.h 2012-09-08 17:31:21.248566542 -0500
@@ -1460,6 +1460,8 @@
extern uint8_t KeSynchronizeExecution(kinterrupt *, void *, void *);
extern uintptr_t InterlockedExchange(volatile uint32_t *,
uintptr_t);
+extern uintptr_t InterlockedCompareExchange(volatile uint32_t *,
+ uintptr_t, uintptr_t);
extern void *ExAllocatePoolWithTag(uint32_t, size_t, uint32_t);
extern void ExFreePool(void *);
extern uint32_t IoConnectInterrupt(kinterrupt **, void *, void *,
diff --recursive -u usrsrc9.orig/sys/compat/ndis/subr_ntoskrnl.c usrsrc9/sys/compat/ndis/subr_ntoskrnl.c
--- usrsrc9.orig/sys/compat/ndis/subr_ntoskrnl.c 2012-09-08 17:30:27.011560031 -0500
+++ usrsrc9/sys/compat/ndis/subr_ntoskrnl.c 2012-09-08 17:31:21.249568664 -0500
@@ -2361,6 +2361,22 @@
return (r);
}
+uintptr_t
+InterlockedCompareExchange(dst, exc, com)
+ volatile uint32_t *dst;
+ uintptr_t exc;
+ uintptr_t com;
+{
+ uintptr_t r;
+
+ mtx_lock_spin(&ntoskrnl_interlock);
+ r = *dst;
+ if(*dst == com) *dst = exc;
+ mtx_unlock_spin(&ntoskrnl_interlock);
+
+ return (r);
+}
+
static uint32_t
InterlockedIncrement(addend)
volatile uint32_t *addend;
@@ -4381,6 +4397,7 @@
IMPORT_FFUNC(InterlockedIncrement, 1),
IMPORT_FFUNC(InterlockedDecrement, 1),
IMPORT_FFUNC(InterlockedExchange, 2),
+ IMPORT_FFUNC(InterlockedCompareExchange, 3),
IMPORT_FFUNC(ExInterlockedAddLargeStatistic, 2),
IMPORT_SFUNC(IoAllocateMdl, 5),
IMPORT_SFUNC(IoFreeMdl, 1),
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list