From 6daa19f5d466032385dc530f2c224d4c762e04f9 Mon Sep 17 00:00:00 2001 From: wpaul Date: Sun, 6 Nov 2005 19:38:34 +0000 Subject: The latest version of the Intel 2200BG/2915ABG driver (9.0.0.3-9) from Intel's web site requires some minor tweaks to get it to work: - The driver seems to have been released with full WMI tracing enabled, and makes references to some WMI APIs, namely IoWMIRegistrationControl(), WmiQueryTraceInformation() and WmiTraceMessage(). Only the first one is ever called (during intialization). These have been implemented as do-nothing stubs for now. Also added a definition for STATUS_NOT_FOUND to ntoskrnl_var.h, which is used as a return code for one of the WMI routines. - The driver references KeRaiseIrqlToDpcLevel() and KeLowerIrql() (the latter as a function, which is unusual because normally KeLowerIrql() is a macro in the Windows DDK that calls KfLowewIrql()). I'm not sure why these are being called since they're not really part of WDM. Presumeably they're being used for backwards compatibility with old versions of Windows. These have been implemented in subr_hal.c. (Note that they're _stdcall routines instead of _fastcall.) - When querying the OID_802_11_BSSID_LIST OID to get a BSSID list, you don't know ahead of time how many networks the NIC has found during scanning, so you're allowed to pass 0 as the list length. This should cause the driver to return an 'insufficient resources' error and set the length to indicate how many bytes are actually needed. However for some reason, the Intel driver does not honor this convention: if you give it a length of 0, it returns some other error and doesn't tell you how much space is really needed. To get around this, if using a length of 0 yields anything besides the expected error case, we arbitrarily assume a length of 64K. This is similar to the hack that wpa_supplicant uses when doing a BSSID list query. --- sys/compat/ndis/ntoskrnl_var.h | 1 + sys/compat/ndis/subr_hal.c | 31 ++++++++++++++++++++++++++----- sys/compat/ndis/subr_ntoskrnl.c | 33 +++++++++++++++++++++++++++++++++ sys/dev/if_ndis/if_ndis.c | 13 ++++++------- 4 files changed, 66 insertions(+), 12 deletions(-) diff --git a/sys/compat/ndis/ntoskrnl_var.h b/sys/compat/ndis/ntoskrnl_var.h index b01b90e..01caaed 100644 --- a/sys/compat/ndis/ntoskrnl_var.h +++ b/sys/compat/ndis/ntoskrnl_var.h @@ -1196,6 +1196,7 @@ typedef struct driver_object driver_object; #define STATUS_MUTANT_NOT_OWNED 0xC0000046 #define STATUS_INVALID_PARAMETER_2 0xC00000F0 #define STATUS_INSUFFICIENT_RESOURCES 0xC000009A +#define STATUS_NOT_FOUND 0xC0000225 #define STATUS_WAIT_0 0x00000000 diff --git a/sys/compat/ndis/subr_hal.c b/sys/compat/ndis/subr_hal.c index 73e574a..e428280 100644 --- a/sys/compat/ndis/subr_hal.c +++ b/sys/compat/ndis/subr_hal.c @@ -78,6 +78,8 @@ static void READ_PORT_BUFFER_USHORT(uint16_t *, static void READ_PORT_BUFFER_UCHAR(uint8_t *, uint8_t *, uint32_t); static uint64_t KeQueryPerformanceCounter(uint64_t *); +static void _KeLowerIrql(uint8_t); +static uint8_t KeRaiseIrqlToDpcLevel(void); static void dummy (void); #define NDIS_MAXCPUS 64 @@ -370,10 +372,6 @@ KfAcquireSpinLock(lock) { uint8_t oldirql; - /* I am so going to hell for this. */ - if (KeGetCurrentIrql() > DISPATCH_LEVEL) - panic("IRQL_NOT_LESS_THAN_OR_EQUAL"); - KeRaiseIrql(DISPATCH_LEVEL, &oldirql); KeAcquireSpinLockAtDpcLevel(lock); @@ -416,13 +414,16 @@ KfRaiseIrql(irql) uint8_t oldirql; oldirql = KeGetCurrentIrql(); - if (irql < oldirql) + + /* I am so going to hell for this. */ + if (oldirql > irql) panic("IRQL_NOT_LESS_THAN"); if (oldirql != DISPATCH_LEVEL) { sched_pin(); mtx_lock(&disp_lock[curthread->td_oncpu]); } +/*printf("RAISE IRQL: %d %d\n", irql, oldirql);*/ return(oldirql); } @@ -443,6 +444,23 @@ KfLowerIrql(oldirql) return; } +static uint8_t +KeRaiseIrqlToDpcLevel(void) +{ + uint8_t irql; + + KeRaiseIrql(DISPATCH_LEVEL, &irql); + return(irql); +} + +static void +_KeLowerIrql(oldirql) + uint8_t oldirql; +{ + KeLowerIrql(oldirql); + return; +} + static void dummy() { printf ("hal dummy called...\n"); @@ -469,6 +487,9 @@ image_patch_table hal_functbl[] = { IMPORT_SFUNC(KeQueryPerformanceCounter, 1), IMPORT_FFUNC(KfLowerIrql, 1), IMPORT_FFUNC(KfRaiseIrql, 1), + IMPORT_SFUNC(KeRaiseIrqlToDpcLevel, 0), +#undef KeLowerIrql + IMPORT_SFUNC_MAP(KeLowerIrql, _KeLowerIrql, 1), /* * This last entry is a catch-all for any function we haven't diff --git a/sys/compat/ndis/subr_ntoskrnl.c b/sys/compat/ndis/subr_ntoskrnl.c index d3500b9..f221f7f 100644 --- a/sys/compat/ndis/subr_ntoskrnl.c +++ b/sys/compat/ndis/subr_ntoskrnl.c @@ -227,6 +227,10 @@ static ndis_status ObReferenceObjectByHandle(ndis_handle, uint32_t, void *, uint8_t, void **, void **); static void ObfDereferenceObject(void *); static uint32_t ZwClose(ndis_handle); +static uint32_t WmiQueryTraceInformation(uint32_t, void *, uint32_t, + uint32_t, void *); +static uint32_t WmiTraceMessage(uint64_t, uint32_t, void *, uint16_t, ...); +static uint32_t IoWMIRegistrationControl(device_object *, uint32_t); static void *ntoskrnl_memset(void *, int, size_t); static char *ntoskrnl_strstr(char *, char *); static int ntoskrnl_toupper(int); @@ -3336,6 +3340,32 @@ ZwClose(handle) return(STATUS_SUCCESS); } +static uint32_t +WmiQueryTraceInformation(traceclass, traceinfo, infolen, reqlen, buf) + uint32_t traceclass; + void *traceinfo; + uint32_t infolen; + uint32_t reqlen; + void *buf; +{ + return(STATUS_NOT_FOUND); +} + +static uint32_t +WmiTraceMessage(uint64_t loghandle, uint32_t messageflags, + void *guid, uint16_t messagenum, ...) +{ + return(STATUS_SUCCESS); +} + +static uint32_t +IoWMIRegistrationControl(dobj, action) + device_object *dobj; + uint32_t action; +{ + return(STATUS_SUCCESS); +} + /* * This is here just in case the thread returns without calling * PsTerminateSystemThread(). @@ -4215,6 +4245,9 @@ image_patch_table ntoskrnl_functbl[] = { IMPORT_SFUNC(ZwClose, 1), IMPORT_SFUNC(PsCreateSystemThread, 7), IMPORT_SFUNC(PsTerminateSystemThread, 1), + IMPORT_SFUNC(IoWMIRegistrationControl, 2), + IMPORT_SFUNC(WmiQueryTraceInformation, 5), + IMPORT_CFUNC(WmiTraceMessage, 0), /* * This last entry is a catch-all for any function we haven't diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c index 938ff4e..00c5216 100644 --- a/sys/dev/if_ndis/if_ndis.c +++ b/sys/dev/if_ndis/if_ndis.c @@ -2506,12 +2506,11 @@ ndis_get_assoc(sc, assoc) device_printf(sc->ndis_dev, "failed to get bssid\n"); return(ENOENT); } - len = 0; + + len = 4; error = ndis_get_info(sc, OID_802_11_BSSID_LIST, NULL, &len); - if (error != ENOSPC) { - device_printf(sc->ndis_dev, "bssid_list failed\n"); - return (error); - } + if (error != ENOSPC) + len = 65536; bl = malloc(len, M_TEMP, M_NOWAIT|M_ZERO); error = ndis_get_info(sc, OID_802_11_BSSID_LIST, bl, &len); @@ -2978,7 +2977,7 @@ ndis_wi_ioctl_get(ifp, command, data) len = 0; error = ndis_get_info(sc, OID_802_11_BSSID_LIST, NULL, &len); if (error != ENOSPC) - break; + len = 65536; bl = malloc(len, M_DEVBUF, M_NOWAIT|M_ZERO); error = ndis_get_info(sc, OID_802_11_BSSID_LIST, bl, &len); if (error) { @@ -3097,7 +3096,7 @@ ndis_80211_ioctl_get(struct ifnet *ifp, u_long command, caddr_t data) len = 0; error = ndis_get_info(sc, OID_802_11_BSSID_LIST, NULL, &len); if (error != ENOSPC) - break; + len = 65536; bl = malloc(len, M_DEVBUF, M_NOWAIT | M_ZERO); error = ndis_get_info(sc, OID_802_11_BSSID_LIST, bl, &len); if (error) { -- cgit v1.1