# CONFIG_NCPFS_SMALLDOS is not set
CONFIG_NCPFS_STRONG=y
CONFIG_NCP_FS=m
-CONFIG_NDISWRAPPER=m
CONFIG_NE2000=m
CONFIG_NE2K_PCI=m
CONFIG_NE2_MCA=m
##
##
##
-source "ubuntu/ndiswrapper/Kconfig"
-##
-##
-##
source "ubuntu/rfkill/Kconfig"
##
##
##
##
##
-#obj-$(CONFIG_NDISWRAPPER) += ndiswrapper/
-##
-##
-##
#obj-m += rfkill/
##
##
+++ /dev/null
-Downloaded from: http://sourceforge.net/project/showfiles.php?group_id=93482
-Current Version: 1.56
+++ /dev/null
-config NDISWRAPPER
- tristate "Wrapper for Windows NDIS network drivers"
- depends on NET && X86
- default m
+++ /dev/null
-ndiswrapper-objs := crt.o hal.o iw_ndis.o loader.o ndis.o ntoskernel.o ntoskernel_io.o \
- pe_linker.o pnp.o proc.o rtl.o wrapmem.o wrapndis.o wrapper.o usb.o
-
-EXPORTS = crt_exports.h hal_exports.h ndis_exports.h ntoskernel_exports.h \
- ntoskernel_io_exports.h rtl_exports.h usb_exports.h
-
-STUB_SRCS = crt.c hal.c ndis.c ntoskernel.c ntoskernel_io.c \
- pnp.c rtl.c wrapndis.c usb.c
-
-
-EXTRA_CFLAGS += -DENABLE_USB -I$(obj)
-EXTRA_AFLAGS += -I$(obj)
-
-# generate exports symbol table from C files
-quiet_cmd_mkexport = MKEXPORT $@
-cmd_mkexport = $(SHELL) $(srctree)/$(src)/mkexport.sh $< $@
-
-%_exports.h: %.c $(srctree)/$(src)/mkexport.sh FORCE
- $(call if_changed,mkexport)
-
-$(addprefix $(obj)/,$(EXPORTS:_exports.h=.o)): %.o: %_exports.h
-extra-y += $(EXPORTS)
-
-ifeq ($(CONFIG_X86_64),y)
-quiet_cmd_mkstubs = MKSTUBS $@
-cmd_mkstubs = $(SHELL) $(srctree)/$(src)/mkstubs.sh $(addprefix $(srctree)/$(src)/,$(STUB_SRCS)) >$@
-
-$(obj)/win2lin_stubs.h: $(addprefix $(srctree)/$(src)/,$(STUB_SRCS)) FORCE
- $(call if_changed,mkstubs)
-
-$(obj)/win2lin_stubs.o: $(obj)/win2lin_stubs.h
-extra-y += win2lin_stubs.h
-ndiswrapper-objs += win2lin_stubs.o
-else
-ndiswrapper-objs += divdi3.o
-endif
-
-obj-$(CONFIG_NDISWRAPPER) := ndiswrapper.o
+++ /dev/null
-/*
- * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include "ntoskernel.h"
-#include "crt_exports.h"
-
-#ifdef CONFIG_X86_64
-/* Windows long is 32-bit, so strip single 'l' in integer formats */
-static void strip_l_modifier(char *str)
-{
- char *ptr = str;
- int in_format = 0;
- char *lptr = NULL;
- char last = 0;
- char *end_ptr;
- char *wptr;
-
- /* Replace single 'l' inside integer formats with '\0' */
- for (ptr = str; *ptr; ptr++) {
- if (!in_format) {
- if (*ptr == '%')
- in_format = 1;
- last = *ptr;
- continue;
- }
- switch (*ptr) {
- case 'd':
- case 'i':
- case 'o':
- case 'u':
- case 'x':
- case 'X':
- case 'p':
- case 'n':
- case 'm':
- if (lptr) {
- *lptr = '\0';
- lptr = NULL;
- }
- in_format = 0;
- break;
- case 'c':
- case 'C':
- case 's':
- case 'S':
- case 'f':
- case 'e':
- case 'E':
- case 'g':
- case 'G':
- case 'a':
- case 'A':
- lptr = NULL;
- in_format = 0;
- break;
- case '%':
- lptr = NULL;
- if (last == '%')
- in_format = 0;
- else
- in_format = 1; /* ignore previous junk */
- break;
- case 'l':
- if (last == 'l')
- lptr = NULL;
- else
- lptr = ptr;
- break;
- default:
- break;
- }
- last = *ptr;
- }
-
- /* Purge zeroes from the resulting string */
- end_ptr = ptr;
- wptr = str;
- for (ptr = str; ptr < end_ptr; ptr++)
- if (*ptr != 0)
- *(wptr++) = *ptr;
- *wptr = 0;
-}
-
-/*
- * va_list on x86_64 Linux is designed to allow passing arguments in registers
- * even to variadic functions. va_list is a structure holding pointers to the
- * register save area, which holds the arguments passed in registers, and to
- * the stack, which may have the arguments that did not fit the registers.
- * va_list also holds offsets in the register save area for the next general
- * purpose and floating point registers that the next va_arg() would fetch.
- *
- * Unlike Linux, the Windows va_list is just a pointer to the stack. No
- * arguments are passed in the registers. That's why we construct the Linux
- * va_list so that the register save area is never used. For that goal, we set
- * the offsets to the maximal allowed values, meaning that the arguments passed
- * in the registers have been exhausted. The values are 48 for general purpose
- * registers (6 registers, 8 bytes each) and 304 for floating point registers
- * (16 registers, 16 bytes each, on top of general purpose register).
- */
-
-struct x86_64_va_list {
- int gp_offset;
- int fp_offset;
- void *overflow_arg_area;
- void *reg_save_area;
-};
-
-#define VA_LIST_DECL(_args) \
- va_list _args##new; \
- struct x86_64_va_list *_args##x;
-#define VA_LIST_PREP(_args) \
-do { \
- _args##x = (struct x86_64_va_list *)&_args##new; \
- _args##x->gp_offset = 6 * 8; /* GP registers exhausted */ \
- _args##x->fp_offset = 6 * 8 + 16 * 16; /* FP registers exhausted */ \
- _args##x->overflow_arg_area = (void *)_args; \
- _args##x->reg_save_area = NULL; \
-} while (0)
-#define VA_LIST_CONV(_args) (_args##new)
-#define VA_LIST_FREE(_args)
-#define FMT_DECL(_fmt) \
- char *_fmt##copy; \
- int _fmt##len;
-#define FMT_PREP(_fmt) \
-do { \
- _fmt##len = strlen(format) + 1; \
- _fmt##copy = kmalloc(_fmt##len, GFP_KERNEL); \
- if (_fmt##copy) { \
- memcpy(_fmt##copy, format, _fmt##len); \
- strip_l_modifier(_fmt##copy); \
- } \
-} while (0)
-#define FMT_CONV(_fmt) (_fmt##copy ? _fmt##copy : format)
-#define FMT_FREE(_fmt) kfree(_fmt##copy)
-
-#else /* !CONFIG_X86_64 */
-
-#define VA_LIST_DECL(_args)
-#define VA_LIST_PREP(_args)
-#define VA_LIST_CONV(_args) (_args)
-#define VA_LIST_FREE(_args)
-#define FMT_DECL(_fmt)
-#define FMT_PREP(_fmt)
-#define FMT_CONV(_fmt) (format)
-#define FMT_FREE(_fmt)
-
-#endif /* !CONFIG_X86_64 */
-
-noregparm INT WIN_FUNC(_win_sprintf,12)
- (char *buf, const char *format, ...)
-{
- va_list args;
- int res;
- FMT_DECL(format)
-
- FMT_PREP(format);
- va_start(args, format);
- res = vsprintf(buf, FMT_CONV(format), args);
- va_end(args);
- FMT_FREE(format);
-
- TRACE2("buf: %p: %s", buf, buf);
- return res;
-}
-
-noregparm INT WIN_FUNC(swprintf,12)
- (wchar_t *buf, const wchar_t *format, ...)
-{
- TODO();
- EXIT2(return 0);
-}
-
-noregparm INT WIN_FUNC(_win_vsprintf,3)
- (char *str, const char *format, va_list ap)
-{
- INT i;
- VA_LIST_DECL(ap)
- FMT_DECL(format)
-
- VA_LIST_PREP(ap);
- FMT_PREP(format);
-
- i = vsprintf(str, FMT_CONV(format), VA_LIST_CONV(ap));
- TRACE2("str: %p: %s", str, str);
-
- FMT_FREE(format);
- VA_LIST_FREE(ap);
- EXIT2(return i);
-}
-
-noregparm INT WIN_FUNC(_win_snprintf,12)
- (char *buf, SIZE_T count, const char *format, ...)
-{
- va_list args;
- int res;
- FMT_DECL(format)
-
- FMT_PREP(format);
- va_start(args, format);
- res = vsnprintf(buf, count, FMT_CONV(format), args);
- va_end(args);
- TRACE2("buf: %p: %s", buf, buf);
-
- FMT_FREE(format);
- return res;
-}
-
-noregparm INT WIN_FUNC(_win__snprintf,12)
- (char *buf, SIZE_T count, const char *format, ...)
-{
- va_list args;
- int res;
- FMT_DECL(format)
-
- FMT_PREP(format);
- va_start(args, format);
- res = vsnprintf(buf, count, FMT_CONV(format), args);
- va_end(args);
- TRACE2("buf: %p: %s", buf, buf);
-
- FMT_FREE(format);
- return res;
-}
-
-noregparm INT WIN_FUNC(_win_vsnprintf,4)
- (char *str, SIZE_T size, const char *format, va_list ap)
-{
- INT i;
- VA_LIST_DECL(ap)
- FMT_DECL(format)
-
- VA_LIST_PREP(ap);
- FMT_PREP(format);
-
- i = vsnprintf(str, size, FMT_CONV(format), VA_LIST_CONV(ap));
- TRACE2("str: %p: %s", str, str);
-
- FMT_FREE(format);
- VA_LIST_FREE(ap);
- EXIT2(return i);
-}
-
-noregparm INT WIN_FUNC(_win__vsnprintf,4)
- (char *str, SIZE_T size, const char *format, va_list ap)
-{
- INT i;
- VA_LIST_DECL(ap)
- FMT_DECL(format)
-
- VA_LIST_PREP(ap);
- FMT_PREP(format);
-
- i = vsnprintf(str, size, FMT_CONV(format), VA_LIST_CONV(ap));
- TRACE2("str: %p: %s", str, str);
-
- FMT_FREE(format);
- VA_LIST_FREE(ap);
- EXIT2(return i);
-}
-
-noregparm char *WIN_FUNC(_win_strncpy,3)
- (char *dst, char *src, SIZE_T n)
-{
- return strncpy(dst, src, n);
-}
-
-noregparm SIZE_T WIN_FUNC(_win_strlen,1)
- (const char *s)
-{
- return strlen(s);
-}
-
-noregparm INT WIN_FUNC(_win_strncmp,3)
- (const char *s1, const char *s2, SIZE_T n)
-{
- return strncmp(s1, s2, n);
-}
-
-noregparm INT WIN_FUNC(_win_strcmp,2)
- (const char *s1, const char *s2)
-{
- return strcmp(s1, s2);
-}
-
-noregparm INT WIN_FUNC(_win_stricmp,2)
- (const char *s1, const char *s2)
-{
- return stricmp(s1, s2);
-}
-
-noregparm char *WIN_FUNC(_win_strncat,3)
- (char *dest, const char *src, SIZE_T n)
-{
- return strncat(dest, src, n);
-}
-
-noregparm INT WIN_FUNC(_win_wcscmp,2)
- (const wchar_t *s1, const wchar_t *s2)
-{
- while (*s1 && *s1 == *s2) {
- s1++;
- s2++;
- }
- return *s1 - *s2;
-}
-
-noregparm INT WIN_FUNC(_win_wcsicmp,2)
- (const wchar_t *s1, const wchar_t *s2)
-{
- while (*s1 && tolower((char)*s1) == tolower((char)*s2)) {
- s1++;
- s2++;
- }
- return tolower((char)*s1) - tolower((char)*s2);
-}
-
-noregparm SIZE_T WIN_FUNC(_win_wcslen,1)
- (const wchar_t *s)
-{
- const wchar_t *t = s;
- while (*t)
- t++;
- return t - s;
-}
-
-noregparm wchar_t *WIN_FUNC(_win_wcsncpy,3)
- (wchar_t *dest, const wchar_t *src, SIZE_T n)
-{
- const wchar_t *s;
- wchar_t *d;
- s = src + n;
- d = dest;
- while (src < s && (*d++ = *src++))
- ;
- if (s > src)
- memset(d, 0, (s - src) * sizeof(wchar_t));
- return dest;
-}
-
-noregparm wchar_t *WIN_FUNC(_win_wcscpy,2)
- (wchar_t *dest, const wchar_t *src)
-{
- wchar_t *d = dest;
- while ((*d++ = *src++))
- ;
- return dest;
-}
-
-noregparm wchar_t *WIN_FUNC(_win_wcscat,2)
- (wchar_t *dest, const wchar_t *src)
-{
- wchar_t *d;
- d = dest;
- while (*d)
- d++;
- while ((*d++ = *src++))
- ;
- return dest;
-}
-
-noregparm INT WIN_FUNC(_win_towupper,1)
- (wchar_t c)
-{
- return toupper(c);
-}
-
-noregparm INT WIN_FUNC(_win_towlower,1)
- (wchar_t c)
-{
- return tolower(c);
-}
-
-noregparm INT WIN_FUNC(_win_tolower,1)
- (INT c)
-{
- return tolower(c);
-}
-
-noregparm INT WIN_FUNC(_win_toupper,1)
- (INT c)
-{
- return toupper(c);
-}
-
-noregparm void *WIN_FUNC(_win_strcpy,2)
- (void *to, const void *from)
-{
- return strcpy(to, from);
-}
-
-noregparm char *WIN_FUNC(_win_strstr,2)
- (const char *s1, const char *s2)
-{
- return strstr(s1, s2);
-}
-
-noregparm char *WIN_FUNC(_win_strchr,2)
- (const char *s, int c)
-{
- return strchr(s, c);
-}
-
-noregparm char *WIN_FUNC(_win_strrchr,2)
- (const char *s, int c)
-{
- return strrchr(s, c);
-}
-
-noregparm void *WIN_FUNC(_win_memmove,3)
- (void *to, void *from, SIZE_T count)
-{
- return memmove(to, from, count);
-}
-
-noregparm void *WIN_FUNC(_win_memchr,3)
- (const void *s, INT c, SIZE_T n)
-{
- return memchr(s, c, n);
-}
-
-noregparm void *WIN_FUNC(_win_memcpy,3)
- (void *to, const void *from, SIZE_T n)
-{
- return memcpy(to, from, n);
-}
-
-noregparm void *WIN_FUNC(_win_memset,3)
- (void *s, char c, SIZE_T count)
-{
- return memset(s, c, count);
-}
-
-noregparm int WIN_FUNC(_win_memcmp,3)
- (void *s1, void *s2, SIZE_T n)
-{
- return memcmp(s1, s2, n);
-}
-
-noregparm void WIN_FUNC(_win_srand,1)
- (UINT seed)
-{
- net_srandom(seed);
-}
-
-noregparm int WIN_FUNC(rand,0)
- (void)
-{
- char buf[6];
- int i, n;
-
- get_random_bytes(buf, sizeof(buf));
- for (n = i = 0; i < sizeof(buf) ; i++)
- n += buf[i];
- return n;
-}
-
-noregparm int WIN_FUNC(_win_atoi,1)
- (const char *ptr)
-{
- int i = simple_strtol(ptr, NULL, 10);
- return i;
-}
-
-noregparm int WIN_FUNC(_win_isprint,1)
- (int c)
-{
- return isprint(c);
-}
-
-wstdcall s64 WIN_FUNC(_alldiv,2)
- (s64 a, s64 b)
-{
- return a / b;
-}
-
-wstdcall u64 WIN_FUNC(_aulldiv,2)
- (u64 a, u64 b)
-{
- return a / b;
-}
-
-wstdcall s64 WIN_FUNC(_allmul,2)
- (s64 a, s64 b)
-{
- return a * b;
-}
-
-wstdcall u64 WIN_FUNC(_aullmul,2)
- (u64 a, u64 b)
-{
- return a * b;
-}
-
-wstdcall s64 WIN_FUNC(_allrem,2)
- (s64 a, s64 b)
-{
- return a % b;
-}
-
-wstdcall u64 WIN_FUNC(_aullrem,2)
- (u64 a, u64 b)
-{
- return a % b;
-}
-
-__attribute__((regparm(3))) s64 WIN_FUNC(_allshl,2)
- (s64 a, u8 b)
-{
- return a << b;
-}
-
-__attribute__((regparm(3))) u64 WIN_FUNC(_aullshl,2)
- (u64 a, u8 b)
-{
- return a << b;
-}
-
-__attribute__((regparm(3))) s64 WIN_FUNC(_allshr,2)
- (s64 a, u8 b)
-{
- return a >> b;
-}
-
-__attribute__((regparm(3))) u64 WIN_FUNC(_aullshr,2)
- (u64 a, u8 b)
-{
- return a >> b;
-}
-
-int stricmp(const char *s1, const char *s2)
-{
- while (*s1 && tolower(*s1) == tolower(*s2)) {
- s1++;
- s2++;
- }
- return *s1 - *s2;
-}
-
-void dump_bytes(const char *ctx, const u8 *from, int len)
-{
- int i, j;
- u8 *buf;
-
- buf = kmalloc(len * 3 + 1, irql_gfp());
- if (!buf) {
- ERROR("couldn't allocate memory");
- return;
- }
- for (i = j = 0; i < len; i++, j += 3) {
- sprintf(&buf[j], "%02x ", from[i]);
- }
- buf[j] = 0;
- printk(KERN_DEBUG "%s: %p: %s\n", ctx, from, buf);
- kfree(buf);
-}
-
-int crt_init(void)
-{
- return 0;
-}
-
-/* called when module is being removed */
-void crt_exit(void)
-{
- EXIT4(return);
-}
+++ /dev/null
-/* 64-bit multiplication and division
- Copyright (C) 1989, 1992-1999, 2000, 2001, 2002, 2003
- Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-
-#if BITS_PER_LONG != 32
-#error This is for 32-bit targets only
-#endif
-
-typedef unsigned int UQItype __attribute__ ((mode (QI)));
-typedef int SItype __attribute__ ((mode (SI)));
-typedef unsigned int USItype __attribute__ ((mode (SI)));
-typedef int DItype __attribute__ ((mode (DI)));
-typedef unsigned int UDItype __attribute__ ((mode (DI)));
-#define Wtype SItype
-#define HWtype SItype
-#define DWtype DItype
-#define UWtype USItype
-#define UHWtype USItype
-#define UDWtype UDItype
-#define W_TYPE_SIZE 32
-
-#include "longlong.h"
-
-#if defined(__BIG_ENDIAN)
-struct DWstruct { Wtype high, low;};
-#elif defined(__LITTLE_ENDIAN)
-struct DWstruct { Wtype low, high;};
-#else
-#error Unhandled endianity
-#endif
-typedef union { struct DWstruct s; DWtype ll; } DWunion;
-
-/* Prototypes of exported functions. */
-extern DWtype __divdi3 (DWtype u, DWtype v);
-extern DWtype __moddi3 (DWtype u, DWtype v);
-extern UDWtype __udivdi3 (UDWtype u, UDWtype v);
-extern UDWtype __umoddi3 (UDWtype u, UDWtype v);
-
-static UDWtype
-__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
-{
- DWunion ww;
- DWunion nn, dd;
- DWunion rr;
- UWtype d0, d1, n0, n1, n2;
- UWtype q0, q1;
- UWtype b, bm;
-
- nn.ll = n;
- dd.ll = d;
-
- d0 = dd.s.low;
- d1 = dd.s.high;
- n0 = nn.s.low;
- n1 = nn.s.high;
-
-#if !UDIV_NEEDS_NORMALIZATION
- if (d1 == 0)
- {
- if (d0 > n1)
- {
- /* 0q = nn / 0D */
-
- udiv_qrnnd (q0, n0, n1, n0, d0);
- q1 = 0;
-
- /* Remainder in n0. */
- }
- else
- {
- /* qq = NN / 0d */
-
- if (d0 == 0)
- d0 = 1 / d0; /* Divide intentionally by zero. */
-
- udiv_qrnnd (q1, n1, 0, n1, d0);
- udiv_qrnnd (q0, n0, n1, n0, d0);
-
- /* Remainder in n0. */
- }
-
- if (rp != 0)
- {
- rr.s.low = n0;
- rr.s.high = 0;
- *rp = rr.ll;
- }
- }
-
-#else /* UDIV_NEEDS_NORMALIZATION */
-
- if (d1 == 0)
- {
- if (d0 > n1)
- {
- /* 0q = nn / 0D */
-
- count_leading_zeros (bm, d0);
-
- if (bm != 0)
- {
- /* Normalize, i.e. make the most significant bit of the
- denominator set. */
-
- d0 = d0 << bm;
- n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm));
- n0 = n0 << bm;
- }
-
- udiv_qrnnd (q0, n0, n1, n0, d0);
- q1 = 0;
-
- /* Remainder in n0 >> bm. */
- }
- else
- {
- /* qq = NN / 0d */
-
- if (d0 == 0)
- d0 = 1 / d0; /* Divide intentionally by zero. */
-
- count_leading_zeros (bm, d0);
-
- if (bm == 0)
- {
- /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
- conclude (the most significant bit of n1 is set) /\ (the
- leading quotient digit q1 = 1).
-
- This special case is necessary, not an optimization.
- (Shifts counts of W_TYPE_SIZE are undefined.) */
-
- n1 -= d0;
- q1 = 1;
- }
- else
- {
- /* Normalize. */
-
- b = W_TYPE_SIZE - bm;
-
- d0 = d0 << bm;
- n2 = n1 >> b;
- n1 = (n1 << bm) | (n0 >> b);
- n0 = n0 << bm;
-
- udiv_qrnnd (q1, n1, n2, n1, d0);
- }
-
- /* n1 != d0... */
-
- udiv_qrnnd (q0, n0, n1, n0, d0);
-
- /* Remainder in n0 >> bm. */
- }
-
- if (rp != 0)
- {
- rr.s.low = n0 >> bm;
- rr.s.high = 0;
- *rp = rr.ll;
- }
- }
-#endif /* UDIV_NEEDS_NORMALIZATION */
-
- else
- {
- if (d1 > n1)
- {
- /* 00 = nn / DD */
-
- q0 = 0;
- q1 = 0;
-
- /* Remainder in n1n0. */
- if (rp != 0)
- {
- rr.s.low = n0;
- rr.s.high = n1;
- *rp = rr.ll;
- }
- }
- else
- {
- /* 0q = NN / dd */
-
- count_leading_zeros (bm, d1);
- if (bm == 0)
- {
- /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
- conclude (the most significant bit of n1 is set) /\ (the
- quotient digit q0 = 0 or 1).
-
- This special case is necessary, not an optimization. */
-
- /* The condition on the next line takes advantage of that
- n1 >= d1 (true due to program flow). */
- if (n1 > d1 || n0 >= d0)
- {
- q0 = 1;
- sub_ddmmss (n1, n0, n1, n0, d1, d0);
- }
- else
- q0 = 0;
-
- q1 = 0;
-
- if (rp != 0)
- {
- rr.s.low = n0;
- rr.s.high = n1;
- *rp = rr.ll;
- }
- }
- else
- {
- UWtype m1, m0;
- /* Normalize. */
-
- b = W_TYPE_SIZE - bm;
-
- d1 = (d1 << bm) | (d0 >> b);
- d0 = d0 << bm;
- n2 = n1 >> b;
- n1 = (n1 << bm) | (n0 >> b);
- n0 = n0 << bm;
-
- udiv_qrnnd (q0, n1, n2, n1, d1);
- umul_ppmm (m1, m0, q0, d0);
-
- if (m1 > n1 || (m1 == n1 && m0 > n0))
- {
- q0--;
- sub_ddmmss (m1, m0, m1, m0, d1, d0);
- }
-
- q1 = 0;
-
- /* Remainder in (n1n0 - m1m0) >> bm. */
- if (rp != 0)
- {
- sub_ddmmss (n1, n0, n1, n0, m1, m0);
- rr.s.low = (n1 << b) | (n0 >> bm);
- rr.s.high = n1 >> bm;
- *rp = rr.ll;
- }
- }
- }
- }
-
- ww.s.low = q0;
- ww.s.high = q1;
- return ww.ll;
-}
-
-DWtype
-__divdi3 (DWtype u, DWtype v)
-{
- Wtype c = 0;
- DWtype w;
-
- if (u < 0)
- {
- c = ~c;
- u = -u;
- }
- if (v < 0)
- {
- c = ~c;
- v = -v;
- }
- w = __udivmoddi4 (u, v, NULL);
- if (c)
- w = -w;
- return w;
-}
-
-DWtype
-__moddi3 (DWtype u, DWtype v)
-{
- Wtype c = 0;
- DWtype w;
-
- if (u < 0)
- {
- c = ~c;
- u = -u;
- }
- if (v < 0)
- v = -v;
- __udivmoddi4 (u, v, &w);
- if (c)
- w = -w;
- return w;
-}
-
-UDWtype
-__udivdi3 (UDWtype u, UDWtype v)
-{
- return __udivmoddi4 (u, v, NULL);
-}
-
-UDWtype
-__umoddi3 (UDWtype u, UDWtype v)
-{
- UDWtype w;
-
- __udivmoddi4 (u, v, &w);
- return w;
-}
+++ /dev/null
-/*
- * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include "ntoskernel.h"
-#include "hal_exports.h"
-
-wstdcall void WIN_FUNC(WRITE_PORT_ULONG,2)
- (ULONG_PTR port, ULONG value)
-{
- outl(value, port);
-}
-
-wstdcall ULONG WIN_FUNC(READ_PORT_ULONG,1)
- (ULONG_PTR port)
-{
- return inl(port);
-}
-
-wstdcall void WIN_FUNC(WRITE_PORT_USHORT,2)
- (ULONG_PTR port, USHORT value)
-{
- outw(value, port);
-}
-
-wstdcall USHORT WIN_FUNC(READ_PORT_USHORT,1)
- (ULONG_PTR port)
-{
- return inw(port);
-}
-
-wstdcall void WIN_FUNC(WRITE_PORT_UCHAR,2)
- (ULONG_PTR port, UCHAR value)
-{
- outb(value, port);
-}
-
-wstdcall UCHAR WIN_FUNC(READ_PORT_UCHAR,1)
- (ULONG_PTR port)
-{
- return inb(port);
-}
-
-wstdcall void WIN_FUNC(WRITE_PORT_BUFFER_USHORT,3)
- (ULONG_PTR port, USHORT *buf, ULONG count)
-{
- outsw(port, buf, count);
-}
-
-wstdcall void WIN_FUNC(READ_PORT_BUFFER_USHORT,3)
- (ULONG_PTR port, USHORT *buf, ULONG count)
-{
- insw(port, buf, count);
-}
-
-wstdcall void WIN_FUNC(WRITE_PORT_BUFFER_ULONG,3)
- (ULONG_PTR port, ULONG *buf, ULONG count)
-{
- outsl(port, buf, count);
-}
-
-wstdcall void WIN_FUNC(READ_PORT_BUFFER_ULONG,3)
- (ULONG_PTR port, ULONG *buf, ULONG count)
-{
- insl(port, buf, count);
-}
-
-wstdcall USHORT WIN_FUNC(READ_REGISTER_USHORT,1)
- (void __iomem *reg)
-{
- return readw(reg);
-}
-
-wstdcall void WIN_FUNC(WRITE_REGISTER_ULONG,2)
- (void __iomem *reg, UINT val)
-{
- writel(val, reg);
-}
-
-wstdcall void WIN_FUNC(WRITE_REGISTER_USHORT,2)
- (void __iomem *reg, USHORT val)
-{
- writew(val, reg);
-}
-
-wstdcall void WIN_FUNC(WRITE_REGISTER_UCHAR,2)
- (void __iomem *reg, UCHAR val)
-{
- writeb(val, reg);
-}
-
-wstdcall void WIN_FUNC(KeStallExecutionProcessor,1)
- (ULONG usecs)
-{
- udelay(usecs);
-}
-
-wstdcall KIRQL WIN_FUNC(KeGetCurrentIrql,0)
- (void)
-{
- return current_irql();
-}
-
-wfastcall KIRQL WIN_FUNC(KfRaiseIrql,1)
- (KIRQL newirql)
-{
- return raise_irql(newirql);
-}
-
-wfastcall void WIN_FUNC(KfLowerIrql,1)
- (KIRQL oldirql)
-{
- lower_irql(oldirql);
-}
-
-wfastcall KIRQL WIN_FUNC(KfAcquireSpinLock,1)
- (NT_SPIN_LOCK *lock)
-{
- return nt_spin_lock_irql(lock, DISPATCH_LEVEL);
-}
-
-wfastcall void WIN_FUNC(KfReleaseSpinLock,2)
- (NT_SPIN_LOCK *lock, KIRQL oldirql)
-{
- nt_spin_unlock_irql(lock, oldirql);
-}
-
-wfastcall void WIN_FUNC(KefAcquireSpinLockAtDpcLevel,1)
- (NT_SPIN_LOCK *lock)
-{
-#ifdef DEBUG_IRQL
- if (current_irql() != DISPATCH_LEVEL)
- ERROR("irql != DISPATCH_LEVEL");
-#endif
- nt_spin_lock(lock);
-}
-
-wfastcall void WIN_FUNC(KefReleaseSpinLockFromDpcLevel,1)
- (NT_SPIN_LOCK *lock)
-{
-#ifdef DEBUG_IRQL
- if (current_irql() != DISPATCH_LEVEL)
- ERROR("irql != DISPATCH_LEVEL");
-#endif
- nt_spin_unlock(lock);
-}
+++ /dev/null
- /*
- * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/version.h>
-#include <linux/wireless.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
-#include <linux/if_arp.h>
-#include <linux/usb.h>
-#include <linux/random.h>
-
-#include <net/iw_handler.h>
-#include <linux/rtnetlink.h>
-#include <asm/uaccess.h>
-
-#include "iw_ndis.h"
-#include "wrapndis.h"
-
-static int freq_chan[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
- 2447, 2452, 2457, 2462, 2467, 2472, 2484 };
-
-static const char *network_names[] = {"IEEE 802.11FH", "IEEE 802.11b",
- "IEEE 802.11a", "IEEE 802.11g", "Auto"};
-
-int set_essid(struct ndis_device *wnd, const char *ssid, int ssid_len)
-{
- NDIS_STATUS res;
- struct ndis_essid req;
-
- if (ssid_len > NDIS_ESSID_MAX_SIZE)
- return -EINVAL;
-
- memset(&req, 0, sizeof(req));
- req.length = ssid_len;
- if (ssid_len)
- memcpy(&req.essid, ssid, ssid_len);
-
- res = mp_set(wnd, OID_802_11_SSID, &req, sizeof(req));
- if (res) {
- WARNING("setting essid failed (%08X)", res);
- EXIT2(return -EINVAL);
- }
- memcpy(&wnd->essid, &req, sizeof(req));
- EXIT2(return 0);
-}
-
-static int set_assoc_params(struct ndis_device *wnd)
-{
- TRACE2("wpa_version=0x%x auth_alg=0x%x key_mgmt=0x%x "
- "cipher_pairwise=0x%x cipher_group=0x%x",
- wnd->iw_auth_wpa_version, wnd->iw_auth_80211_alg,
- wnd->iw_auth_key_mgmt, wnd->iw_auth_cipher_pairwise,
- wnd->iw_auth_cipher_group);
- set_auth_mode(wnd);
- set_priv_filter(wnd);
- set_encr_mode(wnd);
- return 0;
-}
-
-static int iw_set_essid(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- char ssid[NDIS_ESSID_MAX_SIZE];
- int length;
-
- ENTER2("");
- memset(ssid, 0, sizeof(ssid));
- /* there is no way to turn off essid other than to set to
- * random bytes; instead, we use off to mean any */
- if (wrqu->essid.flags) {
- /* wireless-tools prior to version 20 add extra 1, and
- * later than 20 don't! Deal with that mess */
- length = wrqu->essid.length - 1;
- if (length > 0)
- length--;
- while (length < wrqu->essid.length && extra[length])
- length++;
- TRACE2("%d", length);
- if (length <= 0 || length > NDIS_ESSID_MAX_SIZE)
- EXIT2(return -EINVAL);
- } else
- length = 0;
-
- set_assoc_params(wnd);
-
- memcpy(ssid, extra, length);
- if (set_essid(wnd, ssid, length))
- EXIT2(return -EINVAL);
-
- EXIT2(return 0);
-}
-
-static int iw_get_essid(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- NDIS_STATUS res;
- struct ndis_essid req;
-
- ENTER2("");
- memset(&req, 0, sizeof(req));
- res = mp_query(wnd, OID_802_11_SSID, &req, sizeof(req));
- if (res) {
- WARNING("getting essid failed (%08X)", res);
- EXIT2(return -EOPNOTSUPP);
- }
- memcpy(extra, req.essid, req.length);
- if (req.length > 0)
- wrqu->essid.flags = 1;
- else
- wrqu->essid.flags = 0;
- wrqu->essid.length = req.length;
- EXIT2(return 0);
-}
-
-int set_infra_mode(struct ndis_device *wnd,
- enum ndis_infrastructure_mode mode)
-{
- NDIS_STATUS res;
- unsigned int i;
-
- ENTER2("%d", mode);
- res = mp_query_int(wnd, OID_802_11_INFRASTRUCTURE_MODE,
- &wnd->infrastructure_mode);
- if (res != NDIS_STATUS_SUCCESS) {
- WARNING("getting operating mode to failed (%08X)", res);
- EXIT2(return -EINVAL);
- }
- if (wnd->infrastructure_mode == mode)
- EXIT2(return 0);
- res = mp_set_int(wnd, OID_802_11_INFRASTRUCTURE_MODE, mode);
- if (res) {
- WARNING("setting operating mode to %d failed (%08X)",
- mode, res);
- EXIT2(return -EINVAL);
- }
- /* NDIS drivers clear keys when infrastructure mode is
- * changed. But Linux tools assume otherwise. So set the
- * keys */
- if (wnd->iw_auth_key_mgmt == 0 ||
- wnd->iw_auth_key_mgmt == IW_AUTH_KEY_MGMT_802_1X) {
- for (i = 0; i < MAX_ENCR_KEYS; i++) {
- if (wnd->encr_info.keys[i].length > 0)
- add_wep_key(wnd, wnd->encr_info.keys[i].key,
- wnd->encr_info.keys[i].length, i);
- }
- }
- wnd->infrastructure_mode = mode;
- EXIT2(return 0);
-}
-
-static int iw_set_infra_mode(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- enum ndis_infrastructure_mode ndis_mode;
-
- ENTER2("%d", wrqu->mode);
- switch (wrqu->mode) {
- case IW_MODE_ADHOC:
- ndis_mode = Ndis802_11IBSS;
- break;
- case IW_MODE_INFRA:
- ndis_mode = Ndis802_11Infrastructure;
- break;
- case IW_MODE_AUTO:
- ndis_mode = Ndis802_11AutoUnknown;
- break;
- default:
- EXIT2(return -EINVAL);
- }
-
- if (set_infra_mode(wnd, ndis_mode))
- EXIT2(return -EINVAL);
-
- EXIT2(return 0);
-}
-
-static int iw_get_infra_mode(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- int ndis_mode, iw_mode;
- NDIS_STATUS res;
-
- ENTER2("");
- res = mp_query_int(wnd, OID_802_11_INFRASTRUCTURE_MODE, &ndis_mode);
- if (res) {
- WARNING("getting operating mode failed (%08X)", res);
- EXIT2(return -EOPNOTSUPP);
- }
-
- switch(ndis_mode) {
- case Ndis802_11IBSS:
- iw_mode = IW_MODE_ADHOC;
- break;
- case Ndis802_11Infrastructure:
- iw_mode = IW_MODE_INFRA;
- break;
- case Ndis802_11AutoUnknown:
- iw_mode = IW_MODE_AUTO;
- break;
- default:
- ERROR("invalid operating mode (%u)", ndis_mode);
- EXIT2(return -EINVAL);
- }
- wrqu->mode = iw_mode;
- EXIT2(return 0);
-}
-
-static const char *network_type_to_name(int net_type)
-{
- if (net_type >= 0 &&
- net_type < (sizeof(network_names)/sizeof(network_names[0])))
- return network_names[net_type];
- else
- return network_names[sizeof(network_names) /
- sizeof(network_names[0]) - 1];
-}
-
-static int iw_get_network_type(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- unsigned int network_type;
- NDIS_STATUS res;
-
- ENTER2("");
- res = mp_query_int(wnd, OID_802_11_NETWORK_TYPE_IN_USE,
- &network_type);
- if (res) {
- WARNING("getting network type failed: %08X", res);
- network_type = -1;
- }
- strncpy(wrqu->name, network_type_to_name(network_type),
- sizeof(wrqu->name) - 1);
- wrqu->name[sizeof(wrqu->name)-1] = 0;
- return 0;
-}
-
-static int iw_get_freq(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- NDIS_STATUS res;
- struct ndis_configuration req;
-
- ENTER2("");
- memset(&req, 0, sizeof(req));
- res = mp_query(wnd, OID_802_11_CONFIGURATION, &req, sizeof(req));
- if (res) {
- WARNING("getting configuration failed (%08X)", res);
- EXIT2(return -EOPNOTSUPP);
- }
-
- memset(&(wrqu->freq), 0, sizeof(struct iw_freq));
-
- /* see comment in wireless.h above the "struct iw_freq"
- definition for an explanation of this if
- NOTE: 1000000 is due to the kHz
- */
- if (req.ds_config > 1000000) {
- wrqu->freq.m = req.ds_config / 10;
- wrqu->freq.e = 1;
- }
- else
- wrqu->freq.m = req.ds_config;
-
- /* convert from kHz to Hz */
- wrqu->freq.e += 3;
-
- return 0;
-}
-
-static int iw_set_freq(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- NDIS_STATUS res;
- struct ndis_configuration req;
-
- ENTER2("");
- /* this OID is valid only when not associated */
- if (netif_carrier_ok(wnd->net_dev))
- EXIT2(return 0);
- memset(&req, 0, sizeof(req));
- res = mp_query(wnd, OID_802_11_CONFIGURATION, &req, sizeof(req));
- if (res) {
- WARNING("getting configuration failed (%08X)", res);
- EXIT2(return 0);
- }
-
- if (wrqu->freq.m < 1000 && wrqu->freq.e == 0) {
- if (wrqu->freq.m >= 1 &&
- wrqu->freq.m <= (sizeof(freq_chan) / sizeof(freq_chan[0])))
- req.ds_config = freq_chan[wrqu->freq.m - 1] * 1000;
- else
- return -EINVAL;
- } else {
- int i;
- req.ds_config = wrqu->freq.m;
- for (i = wrqu->freq.e; i > 0; i--)
- req.ds_config *= 10;
- req.ds_config /= 1000;
- }
- res = mp_set(wnd, OID_802_11_CONFIGURATION, &req, sizeof(req));
- if (res)
- WARNING("setting configuration failed (%08X)", res);
- return 0;
-}
-
-static int iw_get_tx_power(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- ndis_tx_power_level ndis_power;
- NDIS_STATUS res;
-
- ENTER2("");
- res = mp_query(wnd, OID_802_11_TX_POWER_LEVEL,
- &ndis_power, sizeof(ndis_power));
- if (res)
- return -EOPNOTSUPP;
- wrqu->txpower.flags = IW_TXPOW_MWATT;
- wrqu->txpower.disabled = 0;
- wrqu->txpower.fixed = 0;
- wrqu->txpower.value = ndis_power;
- return 0;
-}
-
-static int iw_set_tx_power(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- ndis_tx_power_level ndis_power;
- NDIS_STATUS res;
-
- ENTER2("");
- if (wrqu->txpower.disabled)
- ndis_power = 0;
- else {
- if (wrqu->txpower.flags == IW_TXPOW_MWATT)
- ndis_power = wrqu->txpower.value;
- else { // wrqu->txpower.flags == IW_TXPOW_DBM
- if (wrqu->txpower.value > 20)
- ndis_power = 128;
- else if (wrqu->txpower.value < -43)
- ndis_power = 127;
- else {
- signed char tmp;
- tmp = wrqu->txpower.value;
- tmp = -12 - tmp;
- tmp <<= 2;
- ndis_power = (unsigned char)tmp;
- }
- }
- }
- TRACE2("%d", ndis_power);
- res = mp_set(wnd, OID_802_11_TX_POWER_LEVEL,
- &ndis_power, sizeof(ndis_power));
- if (res)
- EXIT2(return -EOPNOTSUPP);
- if (ndis_power == 0)
- res = disassociate(wnd, 0);
- EXIT2(return 0);
-}
-
-static int iw_get_bitrate(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- ULONG ndis_rate;
- int res;
-
- ENTER2("");
- res = mp_query(wnd, OID_GEN_LINK_SPEED, &ndis_rate, sizeof(ndis_rate));
- if (res) {
- WARNING("getting bitrate failed (%08X)", res);
- ndis_rate = 0;
- }
-
- wrqu->bitrate.value = ndis_rate * 100;
- return 0;
-}
-
-static int iw_set_bitrate(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- int i, n;
- NDIS_STATUS res;
- ndis_rates_ex rates;
-
- ENTER2("");
- if (wrqu->bitrate.fixed == 0)
- EXIT2(return 0);
-
- res = mp_query_info(wnd, OID_802_11_SUPPORTED_RATES, &rates,
- sizeof(rates), &n, NULL);
- if (res) {
- WARNING("getting bit rate failed (%08X)", res);
- EXIT2(return 0);
- }
- for (i = 0; i < n; i++) {
- if (rates[i] & 0x80)
- continue;
- if ((rates[i] & 0x7f) * 500000 > wrqu->bitrate.value) {
- TRACE2("setting rate %d to 0",
- (rates[i] & 0x7f) * 500000);
- rates[i] = 0;
- }
- }
-
- res = mp_set(wnd, OID_802_11_DESIRED_RATES, &rates, n);
- if (res) {
- WARNING("setting bit rate failed (%08X)", res);
- EXIT2(return 0);
- }
-
- return 0;
-}
-
-static int iw_set_dummy(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- /* Do nothing. Used for ioctls that are not implemented. */
- return 0;
-}
-
-static int iw_get_rts_threshold(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- ndis_rts_threshold threshold;
- NDIS_STATUS res;
-
- ENTER2("");
- res = mp_query(wnd, OID_802_11_RTS_THRESHOLD,
- &threshold, sizeof(threshold));
- if (res)
- return -EOPNOTSUPP;
-
- wrqu->rts.value = threshold;
- return 0;
-}
-
-static int iw_set_rts_threshold(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- ndis_rts_threshold threshold;
- NDIS_STATUS res;
-
- ENTER2("");
- threshold = wrqu->rts.value;
- res = mp_set(wnd, OID_802_11_RTS_THRESHOLD,
- &threshold, sizeof(threshold));
- if (res == NDIS_STATUS_INVALID_DATA)
- return -EINVAL;
- if (res)
- return -EOPNOTSUPP;
-
- return 0;
-}
-
-static int iw_get_frag_threshold(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- ndis_fragmentation_threshold frag_threshold;
- NDIS_STATUS res;
-
- ENTER2("");
- res = mp_query(wnd, OID_802_11_FRAGMENTATION_THRESHOLD,
- &frag_threshold, sizeof(frag_threshold));
- if (res)
- return -ENOTSUPP;
-
- wrqu->frag.value = frag_threshold;
- return 0;
-}
-
-static int iw_set_frag_threshold(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- ndis_rts_threshold threshold;
- NDIS_STATUS res;
-
- ENTER2("");
- threshold = wrqu->frag.value;
- res = mp_set(wnd, OID_802_11_FRAGMENTATION_THRESHOLD,
- &threshold, sizeof(threshold));
- if (res == NDIS_STATUS_INVALID_DATA)
- return -EINVAL;
- if (res)
- return -EOPNOTSUPP;
- return 0;
-}
-
-int get_ap_address(struct ndis_device *wnd, mac_address ap_addr)
-{
- NDIS_STATUS res;
-
- res = mp_query(wnd, OID_802_11_BSSID, ap_addr, ETH_ALEN);
- TRACE2(MACSTRSEP, MAC2STR(ap_addr));
- if (res) {
- TRACE2("res: %08X", res);
- memset(ap_addr, 0x0, ETH_ALEN);
- EXIT2(return -EOPNOTSUPP);
- }
- EXIT2(return 0);
-}
-
-static int iw_get_ap_address(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- mac_address ap_addr;
-
- ENTER2("");
- get_ap_address(wnd, ap_addr);
- memcpy(wrqu->ap_addr.sa_data, ap_addr, ETH_ALEN);
- wrqu->ap_addr.sa_family = ARPHRD_ETHER;
- EXIT2(return 0);
-}
-
-static int iw_set_ap_address(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- NDIS_STATUS res;
- mac_address ap_addr;
-
- ENTER2("");
- memcpy(ap_addr, wrqu->ap_addr.sa_data, ETH_ALEN);
- TRACE2(MACSTRSEP, MAC2STR(ap_addr));
- res = mp_set(wnd, OID_802_11_BSSID, ap_addr, ETH_ALEN);
- /* user apps may set ap's mac address, which is not required;
- * they may fail to work if this function fails, so return
- * success */
- if (res)
- WARNING("setting AP mac address failed (%08X)", res);
-
- EXIT2(return 0);
-}
-
-int set_iw_auth_mode(struct ndis_device *wnd, int wpa_version,
- int auth_80211_alg)
-{
- NDIS_STATUS res;
- ULONG auth_mode;
-
- ENTER2("%d, %d", wpa_version, auth_80211_alg);
- if (wpa_version & IW_AUTH_WPA_VERSION_WPA2) {
- if (wnd->iw_auth_key_mgmt & IW_AUTH_KEY_MGMT_802_1X)
- auth_mode = Ndis802_11AuthModeWPA2;
- else
- auth_mode = Ndis802_11AuthModeWPA2PSK;
- } else if (wpa_version & IW_AUTH_WPA_VERSION_WPA) {
- if (wnd->iw_auth_key_mgmt & IW_AUTH_KEY_MGMT_802_1X)
- auth_mode = Ndis802_11AuthModeWPA;
- else if (wnd->iw_auth_key_mgmt & IW_AUTH_KEY_MGMT_PSK)
- auth_mode = Ndis802_11AuthModeWPAPSK;
- else
- auth_mode = Ndis802_11AuthModeWPANone;
- } else if (auth_80211_alg & IW_AUTH_ALG_SHARED_KEY) {
- if (auth_80211_alg & IW_AUTH_ALG_OPEN_SYSTEM)
- auth_mode = Ndis802_11AuthModeAutoSwitch;
- else
- auth_mode = Ndis802_11AuthModeShared;
- } else
- auth_mode = Ndis802_11AuthModeOpen;
-
- res = mp_set_int(wnd, OID_802_11_AUTHENTICATION_MODE, auth_mode);
- if (res) {
- WARNING("setting auth mode to %u failed (%08X)",
- auth_mode, res);
- if (res == NDIS_STATUS_INVALID_DATA)
- EXIT2(return -EINVAL);
- return -EOPNOTSUPP;
- }
- wnd->iw_auth_wpa_version = wpa_version;
- wnd->iw_auth_80211_alg = auth_80211_alg;
- EXIT2(return 0);
-}
-
-int set_ndis_auth_mode(struct ndis_device *wnd, ULONG auth_mode)
-{
- NDIS_STATUS res;
-
- ENTER2("%d", auth_mode);
- res = mp_set_int(wnd, OID_802_11_AUTHENTICATION_MODE, auth_mode);
- if (res) {
- WARNING("setting auth mode to %u failed (%08X)",
- auth_mode, res);
- if (res == NDIS_STATUS_INVALID_DATA)
- EXIT2(return -EINVAL);
- return -EOPNOTSUPP;
- }
- switch (auth_mode) {
- case Ndis802_11AuthModeWPA:
- wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_WPA;
- wnd->iw_auth_key_mgmt = IW_AUTH_KEY_MGMT_802_1X;
- break;
- case Ndis802_11AuthModeWPAPSK:
- wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_WPA;
- wnd->iw_auth_key_mgmt = IW_AUTH_KEY_MGMT_PSK;
- case Ndis802_11AuthModeWPANone:
- wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_DISABLED;
- wnd->iw_auth_key_mgmt = IW_AUTH_KEY_MGMT_PSK;
- break;
- case Ndis802_11AuthModeWPA2:
- wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_WPA2;
- wnd->iw_auth_key_mgmt = IW_AUTH_KEY_MGMT_802_1X;
- break;
- case Ndis802_11AuthModeWPA2PSK:
- wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_WPA2;
- wnd->iw_auth_key_mgmt = IW_AUTH_KEY_MGMT_PSK;
- break;
- case Ndis802_11AuthModeOpen:
- wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_DISABLED;
- wnd->iw_auth_80211_alg = IW_AUTH_ALG_OPEN_SYSTEM;
- break;
- case Ndis802_11AuthModeShared:
- wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_DISABLED;
- wnd->iw_auth_80211_alg = IW_AUTH_ALG_SHARED_KEY;
- break;
- case Ndis802_11AuthModeAutoSwitch:
- wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_DISABLED;
- wnd->iw_auth_80211_alg = IW_AUTH_ALG_SHARED_KEY;
- wnd->iw_auth_80211_alg |= IW_AUTH_ALG_OPEN_SYSTEM;
- break;
- default:
- WARNING("invalid authentication algorithm: %d", auth_mode);
- break;
- }
- EXIT2(return 0);
-}
-
-int set_auth_mode(struct ndis_device *wnd)
-{
- return set_iw_auth_mode(wnd, wnd->iw_auth_wpa_version,
- wnd->iw_auth_80211_alg);
-}
-
-int get_ndis_auth_mode(struct ndis_device *wnd)
-{
- ULONG mode;
- NDIS_STATUS res;
-
- res = mp_query_int(wnd, OID_802_11_AUTHENTICATION_MODE, &mode);
- if (res) {
- WARNING("getting authentication mode failed (%08X)", res);
- EXIT2(return -EOPNOTSUPP);
- }
- TRACE2("%d", mode);
- return mode;
-}
-
-int set_iw_encr_mode(struct ndis_device *wnd, int cipher_pairwise,
- int cipher_groupwise)
-{
- NDIS_STATUS res;
- ULONG ndis_mode;
-
- ENTER2("%d, %d", cipher_pairwise, cipher_groupwise);
- if (cipher_pairwise & IW_AUTH_CIPHER_CCMP)
- ndis_mode = Ndis802_11Encryption3Enabled;
- else if (cipher_pairwise & IW_AUTH_CIPHER_TKIP)
- ndis_mode = Ndis802_11Encryption2Enabled;
- else if (cipher_pairwise &
- (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104))
- ndis_mode = Ndis802_11Encryption1Enabled;
- else if (cipher_groupwise & IW_AUTH_CIPHER_CCMP)
- ndis_mode = Ndis802_11Encryption3Enabled;
- else if (cipher_groupwise & IW_AUTH_CIPHER_TKIP)
- ndis_mode = Ndis802_11Encryption2Enabled;
- else
- ndis_mode = Ndis802_11EncryptionDisabled;
-
- res = mp_set_int(wnd, OID_802_11_ENCRYPTION_STATUS, ndis_mode);
- if (res) {
- WARNING("setting encryption mode to %u failed (%08X)",
- ndis_mode, res);
- if (res == NDIS_STATUS_INVALID_DATA)
- EXIT2(return -EINVAL);
- return -EOPNOTSUPP;
- }
- wnd->iw_auth_cipher_pairwise = cipher_pairwise;
- wnd->iw_auth_cipher_group = cipher_groupwise;
- EXIT2(return 0);
-}
-
-int set_encr_mode(struct ndis_device *wnd)
-{
- return set_iw_encr_mode(wnd, wnd->iw_auth_cipher_pairwise,
- wnd->iw_auth_cipher_group);
-}
-
-int get_ndis_encr_mode(struct ndis_device *wnd)
-{
- ULONG mode;
- NDIS_STATUS res;
-
- ENTER2("");
- res = mp_query_int(wnd, OID_802_11_ENCRYPTION_STATUS, &mode);
- if (res) {
- WARNING("getting encryption status failed (%08X)", res);
- EXIT2(return -EOPNOTSUPP);
- } else
- EXIT2(return mode);
-}
-
-static int iw_get_encr(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- int index, mode;
- struct encr_info *encr_info = &wnd->encr_info;
-
- ENTER2("wnd = %p", wnd);
- wrqu->data.length = 0;
- extra[0] = 0;
-
- index = (wrqu->encoding.flags & IW_ENCODE_INDEX);
- TRACE2("index = %u", index);
- if (index > 0)
- index--;
- else
- index = encr_info->tx_key_index;
-
- if (index < 0 || index >= MAX_ENCR_KEYS) {
- WARNING("encryption index out of range (%u)", index);
- EXIT2(return -EINVAL);
- }
-
- if (index != encr_info->tx_key_index) {
- if (encr_info->keys[index].length > 0) {
- wrqu->data.flags |= IW_ENCODE_ENABLED;
- wrqu->data.length = encr_info->keys[index].length;
- memcpy(extra, encr_info->keys[index].key,
- encr_info->keys[index].length);
- }
- else
- wrqu->data.flags |= IW_ENCODE_DISABLED;
-
- EXIT2(return 0);
- }
-
- /* transmit key */
- mode = get_ndis_encr_mode(wnd);
- if (mode < 0)
- EXIT2(return -EOPNOTSUPP);
-
- if (mode == Ndis802_11EncryptionDisabled ||
- mode == Ndis802_11EncryptionNotSupported)
- wrqu->data.flags |= IW_ENCODE_DISABLED;
- else {
- if (mode == Ndis802_11Encryption1KeyAbsent ||
- mode == Ndis802_11Encryption2KeyAbsent ||
- mode == Ndis802_11Encryption3KeyAbsent)
- wrqu->data.flags |= IW_ENCODE_NOKEY;
- else {
- wrqu->data.flags |= IW_ENCODE_ENABLED;
- wrqu->encoding.flags |= index+1;
- wrqu->data.length = encr_info->keys[index].length;
- memcpy(extra, encr_info->keys[index].key,
- encr_info->keys[index].length);
- }
- }
- mode = get_ndis_auth_mode(wnd);
- if (mode < 0)
- EXIT2(return -EOPNOTSUPP);
-
- if (mode == Ndis802_11AuthModeOpen)
- wrqu->data.flags |= IW_ENCODE_OPEN;
- else if (mode == Ndis802_11AuthModeAutoSwitch)
- wrqu->data.flags |= IW_ENCODE_RESTRICTED;
- else // Ndis802_11AuthModeAutoSwitch, Ndis802_11AuthModeWPA etc.
- wrqu->data.flags |= IW_ENCODE_RESTRICTED;
-
- EXIT2(return 0);
-}
-
-/* index must be 0 - N, as per NDIS */
-int add_wep_key(struct ndis_device *wnd, char *key, int key_len,
- int index)
-{
- struct ndis_encr_key ndis_key;
- NDIS_STATUS res;
-
- ENTER2("key index: %d, length: %d", index, key_len);
- if (key_len <= 0 || key_len > NDIS_ENCODING_TOKEN_MAX) {
- WARNING("invalid key length (%d)", key_len);
- EXIT2(return -EINVAL);
- }
- if (index < 0 || index >= MAX_ENCR_KEYS) {
- WARNING("invalid key index (%d)", index);
- EXIT2(return -EINVAL);
- }
- ndis_key.struct_size = sizeof(ndis_key);
- ndis_key.length = key_len;
- memcpy(&ndis_key.key, key, key_len);
- ndis_key.index = index;
-
- if (index == wnd->encr_info.tx_key_index) {
- ndis_key.index |= (1 << 31);
- res = set_iw_encr_mode(wnd, IW_AUTH_CIPHER_WEP104,
- IW_AUTH_CIPHER_NONE);
- if (res)
- WARNING("encryption couldn't be enabled (%08X)", res);
- }
- TRACE2("key %d: " MACSTRSEP, index, MAC2STR(key));
- res = mp_set(wnd, OID_802_11_ADD_WEP, &ndis_key, sizeof(ndis_key));
- if (res) {
- WARNING("adding encryption key %d failed (%08X)",
- index+1, res);
- EXIT2(return -EINVAL);
- }
-
- /* Atheros driver messes up ndis_key during ADD_WEP, so
- * don't rely on that; instead use info in key and key_len */
- wnd->encr_info.keys[index].length = key_len;
- memcpy(&wnd->encr_info.keys[index].key, key, key_len);
-
- EXIT2(return 0);
-}
-
-/* remove_key is for both wep and wpa */
-static int remove_key(struct ndis_device *wnd, int index,
- mac_address bssid)
-{
- NDIS_STATUS res;
- if (wnd->encr_info.keys[index].length == 0)
- EXIT2(return 0);
- wnd->encr_info.keys[index].length = 0;
- memset(&wnd->encr_info.keys[index].key, 0,
- sizeof(wnd->encr_info.keys[index].length));
- if (wnd->iw_auth_cipher_pairwise == IW_AUTH_CIPHER_TKIP ||
- wnd->iw_auth_cipher_pairwise == IW_AUTH_CIPHER_CCMP ||
- wnd->iw_auth_cipher_group == IW_AUTH_CIPHER_TKIP ||
- wnd->iw_auth_cipher_group == IW_AUTH_CIPHER_CCMP) {
- struct ndis_remove_key remove_key;
- remove_key.struct_size = sizeof(remove_key);
- remove_key.index = index;
- if (bssid) {
- /* pairwise key */
- if (memcmp(bssid, "\xff\xff\xff\xff\xff\xff",
- ETH_ALEN) != 0)
- remove_key.index |= (1 << 30);
- memcpy(remove_key.bssid, bssid,
- sizeof(remove_key.bssid));
- } else
- memset(remove_key.bssid, 0xff,
- sizeof(remove_key.bssid));
- if (mp_set(wnd, OID_802_11_REMOVE_KEY,
- &remove_key, sizeof(remove_key)))
- EXIT2(return -EINVAL);
- } else {
- ndis_key_index keyindex = index;
- res = mp_set_int(wnd, OID_802_11_REMOVE_WEP, keyindex);
- if (res) {
- WARNING("removing encryption key %d failed (%08X)",
- keyindex, res);
- EXIT2(return -EINVAL);
- }
- }
- /* if it is transmit key, disable encryption */
- if (index == wnd->encr_info.tx_key_index) {
- res = set_iw_encr_mode(wnd, IW_AUTH_CIPHER_NONE,
- IW_AUTH_CIPHER_NONE);
- if (res)
- WARNING("changing encr status failed (%08X)", res);
- }
- TRACE2("key %d removed", index);
- EXIT2(return 0);
-}
-
-static int iw_set_wep(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- NDIS_STATUS res;
- unsigned int index, key_len;
- struct encr_info *encr_info = &wnd->encr_info;
- unsigned char *key;
-
- ENTER2("");
- index = (wrqu->encoding.flags & IW_ENCODE_INDEX);
- TRACE2("index = %u", index);
-
- /* iwconfig gives index as 1 - N */
- if (index > 0)
- index--;
- else
- index = encr_info->tx_key_index;
-
- if (index < 0 || index >= MAX_ENCR_KEYS) {
- WARNING("encryption index out of range (%u)", index);
- EXIT2(return -EINVAL);
- }
-
- /* remove key if disabled */
- if (wrqu->data.flags & IW_ENCODE_DISABLED) {
- if (remove_key(wnd, index, NULL))
- EXIT2(return -EINVAL);
- else
- EXIT2(return 0);
- }
-
- /* global encryption state (for all keys) */
- if (wrqu->data.flags & IW_ENCODE_OPEN)
- res = set_ndis_auth_mode(wnd, Ndis802_11AuthModeOpen);
- else // if (wrqu->data.flags & IW_ENCODE_RESTRICTED)
- res = set_ndis_auth_mode(wnd, Ndis802_11AuthModeShared);
- if (res) {
- WARNING("setting authentication mode failed (%08X)", res);
- EXIT2(return -EINVAL);
- }
-
- TRACE2("key length: %d", wrqu->data.length);
-
- if (wrqu->data.length > 0) {
- key_len = wrqu->data.length;
- key = extra;
- } else { // must be set as tx key
- if (encr_info->keys[index].length == 0) {
- WARNING("key %d is not set", index+1);
- EXIT2(return -EINVAL);
- }
- key_len = encr_info->keys[index].length;
- key = encr_info->keys[index].key;
- encr_info->tx_key_index = index;
- }
-
- if (add_wep_key(wnd, key, key_len, index))
- EXIT2(return -EINVAL);
-
- if (index == encr_info->tx_key_index) {
- /* if transmit key is at index other than 0, some
- * drivers, at least Atheros and TI, want another
- * (global) non-transmit key to be set; don't know why */
- if (index != 0) {
- int i;
- for (i = 0; i < MAX_ENCR_KEYS; i++)
- if (i != index &&
- encr_info->keys[i].length != 0)
- break;
- if (i == MAX_ENCR_KEYS) {
- if (index == 0)
- i = index + 1;
- else
- i = index - 1;
- if (add_wep_key(wnd, key, key_len, i))
- WARNING("couldn't add broadcast key"
- " at %d", i);
- }
- }
- /* ndis drivers want essid to be set after setting encr */
- set_essid(wnd, wnd->essid.essid, wnd->essid.length);
- }
- EXIT2(return 0);
-}
-
-static int iw_set_nick(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
-
- if (wrqu->data.length >= IW_ESSID_MAX_SIZE || wrqu->data.length <= 0)
- return -EINVAL;
- memcpy(wnd->nick, extra, wrqu->data.length);
- wnd->nick[wrqu->data.length] = 0;
- return 0;
-}
-
-static int iw_get_nick(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
-
- wrqu->data.length = strlen(wnd->nick);
- memcpy(extra, wnd->nick, wrqu->data.length);
- return 0;
-}
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) && !defined(IW_REQUEST_FLAG_COMPAT)
-#define iwe_stream_add_event(a, b, c, d, e) iwe_stream_add_event(b, c, d, e)
-#define iwe_stream_add_point(a, b, c, d, e) iwe_stream_add_point(b, c, d, e)
-#define iwe_stream_add_value(a, b, c, d, e, f) \
- iwe_stream_add_value(b, c, d, e, f)
-#define iwe_stream_lcp_len(a) IW_EV_LCP_LEN
-#endif
-
-static char *ndis_translate_scan(struct net_device *dev,
- struct iw_request_info *info, char *event,
- char *end_buf, void *item)
-{
- struct iw_event iwe;
- char *current_val;
- int i, nrates;
- unsigned char buf[MAX_WPA_IE_LEN * 2 + 30];
- struct ndis_wlan_bssid *bssid;
- struct ndis_wlan_bssid_ex *bssid_ex;
-
- ENTER2("%p, %p", event, item);
- bssid = item;
- bssid_ex = item;
- /* add mac address */
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = SIOCGIWAP;
- iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
- iwe.len = IW_EV_ADDR_LEN;
- memcpy(iwe.u.ap_addr.sa_data, bssid->mac, ETH_ALEN);
- event = iwe_stream_add_event(info, event, end_buf, &iwe,
- IW_EV_ADDR_LEN);
-
- /* add essid */
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = SIOCGIWESSID;
- iwe.u.data.length = bssid->ssid.length;
- if (iwe.u.data.length > IW_ESSID_MAX_SIZE)
- iwe.u.data.length = IW_ESSID_MAX_SIZE;
- iwe.u.data.flags = 1;
- iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
- event = iwe_stream_add_point(info, event, end_buf, &iwe,
- bssid->ssid.essid);
-
- /* add protocol name */
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = SIOCGIWNAME;
- strncpy(iwe.u.name, network_type_to_name(bssid->net_type), IFNAMSIZ);
- event = iwe_stream_add_event(info, event, end_buf, &iwe,
- IW_EV_CHAR_LEN);
-
- /* add mode */
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = SIOCGIWMODE;
- if (bssid->mode == Ndis802_11IBSS)
- iwe.u.mode = IW_MODE_ADHOC;
- else if (bssid->mode == Ndis802_11Infrastructure)
- iwe.u.mode = IW_MODE_INFRA;
- else // if (bssid->mode == Ndis802_11AutoUnknown)
- iwe.u.mode = IW_MODE_AUTO;
- event = iwe_stream_add_event(info, event, end_buf, &iwe,
- IW_EV_UINT_LEN);
-
- /* add freq */
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = SIOCGIWFREQ;
- iwe.u.freq.m = bssid->config.ds_config;
- if (bssid->config.ds_config > 1000000) {
- iwe.u.freq.m = bssid->config.ds_config / 10;
- iwe.u.freq.e = 1;
- }
- else
- iwe.u.freq.m = bssid->config.ds_config;
- /* convert from kHz to Hz */
- iwe.u.freq.e += 3;
- iwe.len = IW_EV_FREQ_LEN;
- event = iwe_stream_add_event(info, event, end_buf, &iwe,
- IW_EV_FREQ_LEN);
-
- /* add qual */
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = IWEVQUAL;
- i = 100 * (bssid->rssi - WL_NOISE) / (WL_SIGMAX - WL_NOISE);
- if (i < 0)
- i = 0;
- else if (i > 100)
- i = 100;
- iwe.u.qual.level = bssid->rssi;
- iwe.u.qual.noise = WL_NOISE;
- iwe.u.qual.qual = i;
- iwe.len = IW_EV_QUAL_LEN;
- event = iwe_stream_add_event(info, event, end_buf, &iwe,
- IW_EV_QUAL_LEN);
-
- /* add key info */
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = SIOCGIWENCODE;
- if (bssid->privacy == Ndis802_11PrivFilterAcceptAll)
- iwe.u.data.flags = IW_ENCODE_DISABLED;
- else
- iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
- iwe.u.data.length = 0;
- iwe.len = IW_EV_POINT_LEN;
- event = iwe_stream_add_point(info, event, end_buf, &iwe,
- bssid->ssid.essid);
-
- /* add rate */
- memset(&iwe, 0, sizeof(iwe));
- current_val = event + iwe_stream_lcp_len(info);
- iwe.cmd = SIOCGIWRATE;
- if (bssid->length > sizeof(*bssid))
- nrates = NDIS_MAX_RATES_EX;
- else
- nrates = NDIS_MAX_RATES;
- for (i = 0 ; i < nrates ; i++) {
- if (bssid->rates[i] & 0x7f) {
- iwe.u.bitrate.value = ((bssid->rates[i] & 0x7f) *
- 500000);
- current_val = iwe_stream_add_value(info, event,
- current_val,
- end_buf, &iwe,
- IW_EV_PARAM_LEN);
- }
- }
-
- if ((current_val - event) > iwe_stream_lcp_len(info))
- event = current_val;
-
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = IWEVCUSTOM;
- sprintf(buf, "bcn_int=%d", bssid->config.beacon_period);
- iwe.u.data.length = strlen(buf);
- event = iwe_stream_add_point(info, event, end_buf, &iwe, buf);
-
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = IWEVCUSTOM;
- sprintf(buf, "atim=%u", bssid->config.atim_window);
- iwe.u.data.length = strlen(buf);
- event = iwe_stream_add_point(info, event, end_buf, &iwe, buf);
-
- TRACE2("%d, %u", bssid->length, (unsigned int)sizeof(*bssid));
- if (bssid->length > sizeof(*bssid)) {
- unsigned char *iep = (unsigned char *)bssid_ex->ies +
- sizeof(struct ndis_fixed_ies);
- no_warn_unused unsigned char *end = iep + bssid_ex->ie_length;
-
- while (iep + 1 < end && iep + 2 + iep[1] <= end) {
- unsigned char ielen = 2 + iep[1];
-
- if (ielen > SSID_MAX_WPA_IE_LEN) {
- iep += ielen;
- continue;
- }
- if ((iep[0] == WLAN_EID_GENERIC && iep[1] >= 4 &&
- memcmp(iep + 2, "\x00\x50\xf2\x01", 4) == 0) ||
- iep[0] == RSN_INFO_ELEM) {
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = IWEVGENIE;
- iwe.u.data.length = ielen;
- event = iwe_stream_add_point(info, event,
- end_buf, &iwe,
- iep);
- }
- iep += ielen;
- }
- }
- TRACE2("event = %p, current_val = %p", event, current_val);
- EXIT2(return event);
-}
-
-int set_scan(struct ndis_device *wnd)
-{
- NDIS_STATUS res;
-
- ENTER2("");
- res = mp_set(wnd, OID_802_11_BSSID_LIST_SCAN, NULL, 0);
- if (res) {
- WARNING("scanning failed (%08X)", res);
- EXIT2(return -EOPNOTSUPP);
- }
- wnd->scan_timestamp = jiffies;
- EXIT2(return 0);
-}
-
-static int iw_set_scan(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- return set_scan(wnd);
-}
-
-static int iw_get_scan(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- unsigned int i, list_len, needed;
- NDIS_STATUS res;
- struct ndis_bssid_list *bssid_list = NULL;
- char *event = extra;
- struct ndis_wlan_bssid *cur_item ;
-
- ENTER2("");
- if (time_before(jiffies, wnd->scan_timestamp + 3 * HZ))
- return -EAGAIN;
- /* try with space for a few scan items */
- list_len = sizeof(ULONG) + sizeof(struct ndis_wlan_bssid_ex) * 8;
- bssid_list = kmalloc(list_len, GFP_KERNEL);
- if (!bssid_list) {
- ERROR("couldn't allocate memory");
- return -ENOMEM;
- }
- /* some drivers don't set bssid_list->num_items to 0 if
- OID_802_11_BSSID_LIST returns no items (prism54 driver, e.g.,) */
- memset(bssid_list, 0, list_len);
-
- needed = 0;
- res = mp_query_info(wnd, OID_802_11_BSSID_LIST,
- bssid_list, list_len, NULL, &needed);
- if (res == NDIS_STATUS_INVALID_LENGTH ||
- res == NDIS_STATUS_BUFFER_TOO_SHORT) {
- /* now try with required space */
- kfree(bssid_list);
- list_len = needed;
- bssid_list = kmalloc(list_len, GFP_KERNEL);
- if (!bssid_list) {
- ERROR("couldn't allocate memory");
- return -ENOMEM;
- }
- memset(bssid_list, 0, list_len);
-
- res = mp_query(wnd, OID_802_11_BSSID_LIST,
- bssid_list, list_len);
- }
- if (res) {
- WARNING("getting BSSID list failed (%08X)", res);
- kfree(bssid_list);
- EXIT2(return -EOPNOTSUPP);
- }
- TRACE2("%d", bssid_list->num_items);
- cur_item = &bssid_list->bssid[0];
- for (i = 0; i < bssid_list->num_items; i++) {
- event = ndis_translate_scan(dev, info, event,
- extra + IW_SCAN_MAX_DATA, cur_item);
- cur_item = (struct ndis_wlan_bssid *)((char *)cur_item +
- cur_item->length);
- }
- wrqu->data.length = event - extra;
- wrqu->data.flags = 0;
- kfree(bssid_list);
- EXIT2(return 0);
-}
-
-static int iw_set_power_mode(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- NDIS_STATUS res;
- ULONG power_mode;
-
- if (wrqu->power.disabled == 1)
- power_mode = NDIS_POWER_OFF;
- else if (wrqu->power.flags & IW_POWER_MIN)
- power_mode = NDIS_POWER_MIN;
- else // if (wrqu->power.flags & IW_POWER_MAX)
- power_mode = NDIS_POWER_MAX;
-
- TRACE2("%d", power_mode);
- res = mp_set(wnd, OID_802_11_POWER_MODE,
- &power_mode, sizeof(power_mode));
- if (res)
- WARNING("setting power mode failed (%08X)", res);
- return 0;
-}
-
-static int iw_get_power_mode(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- NDIS_STATUS res;
- ULONG power_mode;
-
- ENTER2("");
- res = mp_query(wnd, OID_802_11_POWER_MODE,
- &power_mode, sizeof(power_mode));
- if (res)
- return -ENOTSUPP;
-
- if (power_mode == NDIS_POWER_OFF)
- wrqu->power.disabled = 1;
- else {
- if (wrqu->power.flags != 0)
- return 0;
- wrqu->power.flags |= IW_POWER_ALL_R;
- wrqu->power.flags |= IW_POWER_TIMEOUT;
- wrqu->power.value = 0;
- wrqu->power.disabled = 0;
-
- if (power_mode == NDIS_POWER_MIN)
- wrqu->power.flags |= IW_POWER_MIN;
- else // if (power_mode == NDIS_POWER_MAX)
- wrqu->power.flags |= IW_POWER_MAX;
- }
- return 0;
-}
-
-static int iw_get_sensitivity(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- NDIS_STATUS res;
- ndis_rssi rssi_trigger;
-
- ENTER2("");
- res = mp_query(wnd, OID_802_11_RSSI_TRIGGER,
- &rssi_trigger, sizeof(rssi_trigger));
- if (res)
- return -EOPNOTSUPP;
- wrqu->param.value = rssi_trigger;
- wrqu->param.disabled = (rssi_trigger == 0);
- wrqu->param.fixed = 1;
- return 0;
-}
-
-static int iw_set_sensitivity(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- NDIS_STATUS res;
- ndis_rssi rssi_trigger;
-
- ENTER2("");
- if (wrqu->param.disabled)
- rssi_trigger = 0;
- else
- rssi_trigger = wrqu->param.value;
- res = mp_set(wnd, OID_802_11_RSSI_TRIGGER,
- &rssi_trigger, sizeof(rssi_trigger));
- if (res == NDIS_STATUS_INVALID_DATA)
- return -EINVAL;
- if (res)
- return -EOPNOTSUPP;
- return 0;
-}
-
-static int iw_get_ndis_stats(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- struct iw_statistics *stats = &wnd->iw_stats;
- memcpy(&wrqu->qual, &stats->qual, sizeof(stats->qual));
- return 0;
-}
-
-static int iw_get_range(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct iw_range *range = (struct iw_range *)extra;
- struct iw_point *data = &wrqu->data;
- struct ndis_device *wnd = netdev_priv(dev);
- unsigned int i, n;
- NDIS_STATUS res;
- ndis_rates_ex rates;
- ndis_tx_power_level tx_power;
-
- ENTER2("");
- data->length = sizeof(struct iw_range);
- memset(range, 0, sizeof(struct iw_range));
-
- range->txpower_capa = IW_TXPOW_MWATT;
- range->num_txpower = 0;
-
- res = mp_query(wnd, OID_802_11_TX_POWER_LEVEL,
- &tx_power, sizeof(tx_power));
- if (!res) {
- range->num_txpower = 1;
- range->txpower[0] = tx_power;
- }
-
- range->we_version_compiled = WIRELESS_EXT;
- range->we_version_source = 18;
-
- range->retry_capa = IW_RETRY_LIMIT;
- range->retry_flags = IW_RETRY_LIMIT;
- range->min_retry = 0;
- range->max_retry = 255;
-
- range->num_channels = 1;
-
- range->max_qual.qual = 100;
- range->max_qual.level = 154;
- range->max_qual.noise = 154;
- range->sensitivity = 3;
-
- range->max_encoding_tokens = 4;
- range->num_encoding_sizes = 2;
- range->encoding_size[0] = 5;
- range->encoding_size[1] = 13;
-
- range->num_bitrates = 0;
- memset(&rates, 0, sizeof(rates));
- res = mp_query_info(wnd, OID_802_11_SUPPORTED_RATES,
- &rates, sizeof(rates), &n, NULL);
- if (res)
- WARNING("getting bit rates failed: %08X", res);
- else {
- for (i = 0; i < n && range->num_bitrates < IW_MAX_BITRATES; i++)
- if (rates[i] & 0x80)
- continue;
- else if (rates[i] & 0x7f) {
- range->bitrate[range->num_bitrates] =
- (rates[i] & 0x7f) * 500000;
- range->num_bitrates++;
- }
- }
-
- range->num_channels = (sizeof(freq_chan)/sizeof(freq_chan[0]));
-
- for (i = 0; i < (sizeof(freq_chan)/sizeof(freq_chan[0])) &&
- i < IW_MAX_FREQUENCIES; i++) {
- range->freq[i].i = i + 1;
- range->freq[i].m = freq_chan[i] * 100000;
- range->freq[i].e = 1;
- }
- range->num_frequency = i;
-
- range->min_rts = 0;
- range->max_rts = 2347;
- range->min_frag = 256;
- range->max_frag = 2346;
-
- /* Event capability (kernel + driver) */
- range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
- IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
- IW_EVENT_CAPA_MASK(SIOCGIWAP) |
- IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
- range->event_capa[1] = IW_EVENT_CAPA_K_1;
- range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVTXDROP) |
- IW_EVENT_CAPA_MASK(IWEVCUSTOM) |
- IW_EVENT_CAPA_MASK(IWEVREGISTERED) |
- IW_EVENT_CAPA_MASK(IWEVEXPIRED));
-
- range->enc_capa = 0;
-
- if (test_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr))
- range->enc_capa |= IW_ENC_CAPA_CIPHER_TKIP;
- if (test_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr))
- range->enc_capa |= IW_ENC_CAPA_CIPHER_CCMP;
-
- if (test_bit(Ndis802_11AuthModeWPA, &wnd->capa.auth) ||
- test_bit(Ndis802_11AuthModeWPAPSK, &wnd->capa.auth))
- range->enc_capa |= IW_ENC_CAPA_WPA;
- if (test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) ||
- test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth))
- range->enc_capa |= IW_ENC_CAPA_WPA2;
-
- return 0;
-}
-
-void set_default_iw_params(struct ndis_device *wnd)
-{
- wnd->iw_auth_key_mgmt = 0;
- wnd->iw_auth_wpa_version = 0;
- set_infra_mode(wnd, Ndis802_11Infrastructure);
- set_ndis_auth_mode(wnd, Ndis802_11AuthModeOpen);
- set_priv_filter(wnd);
- set_iw_encr_mode(wnd, IW_AUTH_CIPHER_NONE, IW_AUTH_CIPHER_NONE);
-}
-
-static int deauthenticate(struct ndis_device *wnd)
-{
- int ret;
-
- ENTER2("");
- ret = disassociate(wnd, 1);
- set_default_iw_params(wnd);
- EXIT2(return ret);
-}
-
-NDIS_STATUS disassociate(struct ndis_device *wnd, int reset_ssid)
-{
- NDIS_STATUS res;
- u8 buf[NDIS_ESSID_MAX_SIZE];
- int i;
-
- TRACE2("");
- res = mp_set(wnd, OID_802_11_DISASSOCIATE, NULL, 0);
- /* disassociate causes radio to be turned off; if reset_ssid
- * is given, set ssid to random to enable radio */
- if (reset_ssid) {
- get_random_bytes(buf, sizeof(buf));
- for (i = 0; i < sizeof(buf); i++)
- buf[i] = 'a' + (buf[i] % 26);
- set_essid(wnd, buf, sizeof(buf));
- }
- return res;
-}
-
-static ULONG ndis_priv_mode(struct ndis_device *wnd)
-{
- if (wnd->iw_auth_wpa_version & IW_AUTH_WPA_VERSION_WPA2 ||
- wnd->iw_auth_wpa_version & IW_AUTH_WPA_VERSION_WPA)
- return Ndis802_11PrivFilter8021xWEP;
- else
- return Ndis802_11PrivFilterAcceptAll;
-}
-
-int set_priv_filter(struct ndis_device *wnd)
-{
- NDIS_STATUS res;
- ULONG flags;
-
- flags = ndis_priv_mode(wnd);
- ENTER2("filter: %d", flags);
- res = mp_set_int(wnd, OID_802_11_PRIVACY_FILTER, flags);
- if (res)
- TRACE2("setting privacy filter to %d failed (%08X)",
- flags, res);
- EXIT2(return 0);
-}
-
-static int iw_set_mlme(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- struct iw_mlme *mlme = (struct iw_mlme *)extra;
-
- ENTER2("");
- switch (mlme->cmd) {
- case IW_MLME_DEAUTH:
- return deauthenticate(wnd);
- case IW_MLME_DISASSOC:
- TRACE2("cmd=%d reason_code=%d", mlme->cmd, mlme->reason_code);
- return disassociate(wnd, 1);
- default:
- return -EOPNOTSUPP;
- }
-
- return 0;
-}
-
-static int iw_set_genie(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- /*
- * NDIS drivers do not allow IEs to be configured; this is
- * done by the driver based on other configuration. Return 0
- * to avoid causing issues with user space programs that
- * expect this function to succeed.
- */
- return 0;
-}
-
-static int iw_set_auth(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- TRACE2("index=%d value=%d", wrqu->param.flags & IW_AUTH_INDEX,
- wrqu->param.value);
- switch (wrqu->param.flags & IW_AUTH_INDEX) {
- case IW_AUTH_WPA_VERSION:
- wnd->iw_auth_wpa_version = wrqu->param.value;
- break;
- case IW_AUTH_CIPHER_PAIRWISE:
- wnd->iw_auth_cipher_pairwise = wrqu->param.value;
- break;
- case IW_AUTH_CIPHER_GROUP:
- wnd->iw_auth_cipher_group = wrqu->param.value;
- break;
- case IW_AUTH_KEY_MGMT:
- wnd->iw_auth_key_mgmt = wrqu->param.value;
- break;
- case IW_AUTH_80211_AUTH_ALG:
- wnd->iw_auth_80211_alg = wrqu->param.value;
- break;
- case IW_AUTH_WPA_ENABLED:
- if (wrqu->param.value)
- deauthenticate(wnd);
- break;
- case IW_AUTH_TKIP_COUNTERMEASURES:
- case IW_AUTH_DROP_UNENCRYPTED:
- case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- case IW_AUTH_PRIVACY_INVOKED:
- TRACE2("%d not implemented: %d",
- wrqu->param.flags & IW_AUTH_INDEX, wrqu->param.value);
- break;
- default:
- WARNING("invalid cmd %d", wrqu->param.flags & IW_AUTH_INDEX);
- return -EOPNOTSUPP;
- }
- return 0;
-}
-
-static int iw_get_auth(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
-
- ENTER2("index=%d", wrqu->param.flags & IW_AUTH_INDEX);
- switch (wrqu->param.flags & IW_AUTH_INDEX) {
- case IW_AUTH_WPA_VERSION:
- wrqu->param.value = wnd->iw_auth_wpa_version;
- break;
- case IW_AUTH_CIPHER_PAIRWISE:
- wrqu->param.value = wnd->iw_auth_cipher_pairwise;
- break;
- case IW_AUTH_CIPHER_GROUP:
- wrqu->param.value = wnd->iw_auth_cipher_group;
- break;
- case IW_AUTH_KEY_MGMT:
- wrqu->param.value = wnd->iw_auth_key_mgmt;
- break;
- case IW_AUTH_80211_AUTH_ALG:
- wrqu->param.value = wnd->iw_auth_80211_alg;
- break;
- default:
- WARNING("invalid cmd %d", wrqu->param.flags & IW_AUTH_INDEX);
- return -EOPNOTSUPP;
- }
- return 0;
-}
-
-static int iw_set_encodeext(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- struct ndis_device *wnd = netdev_priv(dev);
- struct ndis_add_key ndis_key;
- int i, keyidx;
- NDIS_STATUS res;
- u8 *addr;
-
- keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX;
- ENTER2("%d", keyidx);
- if (keyidx)
- keyidx--;
- else
- keyidx = wnd->encr_info.tx_key_index;
-
- if (keyidx < 0 || keyidx >= MAX_ENCR_KEYS)
- return -EINVAL;
-
- if (ext->alg == WPA_ALG_WEP) {
- if (!test_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr))
- EXIT2(return -1);
- if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
- wnd->encr_info.tx_key_index = keyidx;
- if (add_wep_key(wnd, ext->key, ext->key_len, keyidx))
- EXIT2(return -1);
- else
- EXIT2(return 0);
- }
- if ((wrqu->encoding.flags & IW_ENCODE_DISABLED) ||
- ext->alg == IW_ENCODE_ALG_NONE || ext->key_len == 0)
- EXIT2(return remove_key(wnd, keyidx, ndis_key.bssid));
-
- if (ext->key_len > sizeof(ndis_key.key)) {
- TRACE2("incorrect key length (%u)", ext->key_len);
- EXIT2(return -1);
- }
-
- memset(&ndis_key, 0, sizeof(ndis_key));
-
- ndis_key.struct_size =
- sizeof(ndis_key) - sizeof(ndis_key.key) + ext->key_len;
- ndis_key.length = ext->key_len;
- ndis_key.index = keyidx;
-
- if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
- for (i = 0; i < 6 ; i++)
- ndis_key.rsc |= (((u64)ext->rx_seq[i]) << (i * 8));
- TRACE2("0x%Lx", ndis_key.rsc);
- ndis_key.index |= 1 << 29;
- }
-
- addr = ext->addr.sa_data;
- if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
- /* group key */
- if (wnd->infrastructure_mode == Ndis802_11IBSS)
- memset(ndis_key.bssid, 0xff, ETH_ALEN);
- else
- get_ap_address(wnd, ndis_key.bssid);
- } else {
- /* pairwise key */
- ndis_key.index |= (1 << 30);
- memcpy(ndis_key.bssid, addr, ETH_ALEN);
- }
- TRACE2(MACSTRSEP, MAC2STR(ndis_key.bssid));
-
- if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
- ndis_key.index |= (1 << 31);
-
- if (ext->alg == IW_ENCODE_ALG_TKIP && ext->key_len == 32) {
- /* wpa_supplicant gives us the Michael MIC RX/TX keys in
- * different order than NDIS spec, so swap the order here. */
- memcpy(ndis_key.key, ext->key, 16);
- memcpy(ndis_key.key + 16, ext->key + 24, 8);
- memcpy(ndis_key.key + 24, ext->key + 16, 8);
- } else
- memcpy(ndis_key.key, ext->key, ext->key_len);
-
- res = mp_set(wnd, OID_802_11_ADD_KEY, &ndis_key, ndis_key.struct_size);
- if (res) {
- TRACE2("adding key failed (%08X), %u",
- res, ndis_key.struct_size);
- EXIT2(return -1);
- }
- wnd->encr_info.keys[keyidx].length = ext->key_len;
- memcpy(&wnd->encr_info.keys[keyidx].key, ndis_key.key, ext->key_len);
- if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
- wnd->encr_info.tx_key_index = keyidx;
- TRACE2("key %d added", keyidx);
-
- EXIT2(return 0);
-}
-
-static int iw_get_encodeext(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- /* struct iw_encode_ext *ext = (struct iw_encode_ext *) extra; */
- /* TODO */
- ENTER2("");
- return 0;
-}
-
-static int iw_set_pmksa(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct iw_pmksa *pmksa = (struct iw_pmksa *)extra;
- struct ndis_pmkid pmkid;
- NDIS_STATUS res;
- struct ndis_device *wnd = netdev_priv(dev);
-
- /* TODO: must keep local list of PMKIDs since NDIS drivers
- * expect that all PMKID entries are included whenever a new
- * one is added. */
-
- ENTER2("%d", pmksa->cmd);
- if ((pmksa->cmd == IW_PMKSA_ADD || pmksa->cmd == IW_PMKSA_REMOVE) &&
- (!(wnd->iw_auth_wpa_version & IW_AUTH_WPA_VERSION_WPA2)))
- EXIT2(return -EOPNOTSUPP);
-
- memset(&pmkid, 0, sizeof(pmkid));
- if (pmksa->cmd == IW_PMKSA_ADD) {
- pmkid.bssid_info_count = 1;
- memcpy(pmkid.bssid_info[0].bssid, pmksa->bssid.sa_data,
- ETH_ALEN);
- memcpy(pmkid.bssid_info[0].pmkid, pmksa->pmkid, IW_PMKID_LEN);
- }
- pmkid.length = sizeof(pmkid);
-
- res = mp_set(wnd, OID_802_11_PMKID, &pmkid, pmkid.length);
- if (res == NDIS_STATUS_FAILURE)
- EXIT2(return -EOPNOTSUPP);
- TRACE2("OID_802_11_PMKID -> %d", res);
- if (res)
- return -EINVAL;
-
- return 0;
-}
-
-#define WEXT(id) [id - SIOCIWFIRST]
-
-static const iw_handler ndis_handler[] = {
- WEXT(SIOCGIWNAME) = iw_get_network_type,
- WEXT(SIOCSIWESSID) = iw_set_essid,
- WEXT(SIOCGIWESSID) = iw_get_essid,
- WEXT(SIOCSIWMODE) = iw_set_infra_mode,
- WEXT(SIOCGIWMODE) = iw_get_infra_mode,
- WEXT(SIOCGIWFREQ) = iw_get_freq,
- WEXT(SIOCSIWFREQ) = iw_set_freq,
- WEXT(SIOCGIWTXPOW) = iw_get_tx_power,
- WEXT(SIOCSIWTXPOW) = iw_set_tx_power,
- WEXT(SIOCGIWRATE) = iw_get_bitrate,
- WEXT(SIOCSIWRATE) = iw_set_bitrate,
- WEXT(SIOCGIWRTS) = iw_get_rts_threshold,
- WEXT(SIOCSIWRTS) = iw_set_rts_threshold,
- WEXT(SIOCGIWFRAG) = iw_get_frag_threshold,
- WEXT(SIOCSIWFRAG) = iw_set_frag_threshold,
- WEXT(SIOCGIWAP) = iw_get_ap_address,
- WEXT(SIOCSIWAP) = iw_set_ap_address,
- WEXT(SIOCSIWENCODE) = iw_set_wep,
- WEXT(SIOCGIWENCODE) = iw_get_encr,
- WEXT(SIOCSIWSCAN) = iw_set_scan,
- WEXT(SIOCGIWSCAN) = iw_get_scan,
- WEXT(SIOCGIWPOWER) = iw_get_power_mode,
- WEXT(SIOCSIWPOWER) = iw_set_power_mode,
- WEXT(SIOCGIWRANGE) = iw_get_range,
- WEXT(SIOCGIWSTATS) = iw_get_ndis_stats,
- WEXT(SIOCGIWSENS) = iw_get_sensitivity,
- WEXT(SIOCSIWSENS) = iw_set_sensitivity,
- WEXT(SIOCGIWNICKN) = iw_get_nick,
- WEXT(SIOCSIWNICKN) = iw_set_nick,
- WEXT(SIOCSIWCOMMIT) = iw_set_dummy,
- WEXT(SIOCSIWMLME) = iw_set_mlme,
- WEXT(SIOCSIWGENIE) = iw_set_genie,
- WEXT(SIOCSIWAUTH) = iw_set_auth,
- WEXT(SIOCGIWAUTH) = iw_get_auth,
- WEXT(SIOCSIWENCODEEXT) = iw_set_encodeext,
- WEXT(SIOCGIWENCODEEXT) = iw_get_encodeext,
- WEXT(SIOCSIWPMKSA) = iw_set_pmksa,
-};
-
-/* private ioctl's */
-
-static int priv_reset(struct net_device *dev, struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int res;
- ENTER2("");
- res = mp_reset(netdev_priv(dev));
- if (res) {
- WARNING("reset failed: %08X", res);
- return -EOPNOTSUPP;
- }
- return 0;
-}
-
-static int priv_deauthenticate(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int res;
- ENTER2("");
- res = deauthenticate(netdev_priv(dev));
- return res;
-}
-
-static int priv_power_profile(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- struct miniport *mp;
- ULONG profile_inf;
-
- ENTER2("");
- mp = &wnd->wd->driver->ndis_driver->mp;
- if (!mp->pnp_event_notify)
- EXIT2(return -EOPNOTSUPP);
-
- /* 1 for AC and 0 for Battery */
- if (wrqu->param.value)
- profile_inf = NdisPowerProfileAcOnLine;
- else
- profile_inf = NdisPowerProfileBattery;
-
- LIN2WIN4(mp->pnp_event_notify, wnd->nmb->mp_ctx,
- NdisDevicePnPEventPowerProfileChanged,
- &profile_inf, sizeof(profile_inf));
- EXIT2(return 0);
-}
-
-static int priv_network_type(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- enum network_type network_type;
- NDIS_STATUS res;
- char type;
-
- ENTER2("");
- type = wrqu->param.value;
- if (type == 'f')
- network_type = Ndis802_11FH;
- else if (type == 'b')
- network_type = Ndis802_11DS;
- else if (type == 'a')
- network_type = Ndis802_11OFDM5;
- else if (type == 'g' || type == 'n')
- network_type = Ndis802_11OFDM24;
- else
- network_type = Ndis802_11Automode;
-
- res = mp_set_int(wnd, OID_802_11_NETWORK_TYPE_IN_USE, network_type);
- if (res) {
- WARNING("setting network type to %d failed (%08X)",
- network_type, res);
- EXIT2(return -EINVAL);
- }
-
- EXIT2(return 0);
-}
-
-static int priv_media_stream_mode(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- NDIS_STATUS res;
- int mode;
-
- ENTER2("");
- if (wrqu->param.value > 0)
- mode = Ndis802_11MediaStreamOn;
- else
- mode = Ndis802_11MediaStreamOff;
- res = mp_set_int(wnd, OID_802_11_MEDIA_STREAM_MODE, mode);
- if (res) {
- WARNING("oid failed (%08X)", res);
- EXIT2(return -EINVAL);
- }
- EXIT2(return 0);
-}
-
-static int priv_reload_defaults(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- int res;
- ENTER2("");
- res = mp_set_int(wnd, OID_802_11_RELOAD_DEFAULTS,
- Ndis802_11ReloadWEPKeys);
- if (res) {
- WARNING("reloading defaults failed: %08X", res);
- return -EOPNOTSUPP;
- }
- return 0;
-}
-
-static const struct iw_priv_args priv_args[] = {
- {PRIV_RESET, 0, 0, "ndis_reset"},
- {PRIV_POWER_PROFILE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
- "power_profile"},
- {PRIV_DEAUTHENTICATE, 0, 0, "deauthenticate"},
- {PRIV_NETWORK_TYPE, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 1, 0,
- "network_type"},
- {PRIV_MEDIA_STREAM_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
- "media_stream"},
-
- {PRIV_RELOAD_DEFAULTS, 0, 0, "reload_defaults"},
-};
-
-#define WEPRIV(id) [id - SIOCIWFIRSTPRIV]
-
-static const iw_handler priv_handler[] = {
- WEPRIV(PRIV_RESET) = priv_reset,
- WEPRIV(PRIV_POWER_PROFILE) = priv_power_profile,
- WEPRIV(PRIV_DEAUTHENTICATE) = priv_deauthenticate,
- WEPRIV(PRIV_NETWORK_TYPE) = priv_network_type,
- WEPRIV(PRIV_MEDIA_STREAM_MODE) = priv_media_stream_mode,
- WEPRIV(PRIV_RELOAD_DEFAULTS) = priv_reload_defaults,
-};
-
-const struct iw_handler_def ndis_handler_def = {
- .num_standard = sizeof(ndis_handler) / sizeof(ndis_handler[0]),
- .num_private = sizeof(priv_handler) / sizeof(priv_handler[0]),
- .num_private_args = sizeof(priv_args) / sizeof(priv_args[0]),
-
- .standard = (iw_handler *)ndis_handler,
- .private = (iw_handler *)priv_handler,
- .private_args = (struct iw_priv_args *)priv_args,
- .get_wireless_stats = get_iw_stats,
-};
+++ /dev/null
-/*
- * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef _IW_NDIS_H_
-#define _IW_NDIS_H_
-
-#include "ndis.h"
-
-#define WL_NOISE -96 /* typical noise level in dBm */
-#define WL_SIGMAX -32 /* typical maximum signal level in dBm */
-
-struct ndis_encr_key {
- ULONG struct_size;
- ULONG index;
- ULONG length;
- UCHAR key[NDIS_ENCODING_TOKEN_MAX];
-};
-
-struct ndis_add_key {
- ULONG struct_size;
- ndis_key_index index;
- ULONG length;
- mac_address bssid;
- UCHAR pad[6];
- ndis_key_rsc rsc;
- UCHAR key[NDIS_ENCODING_TOKEN_MAX];
-};
-
-struct ndis_remove_key {
- ULONG struct_size;
- ndis_key_index index;
- mac_address bssid;
-};
-
-struct ndis_fixed_ies {
- UCHAR time_stamp[8];
- USHORT beacon_interval;
- USHORT capa;
-};
-
-struct ndis_variable_ies {
- ULONG elem_id;
- UCHAR length;
- UCHAR data[1];
-};
-
-enum ndis_reload_defaults { Ndis802_11ReloadWEPKeys };
-
-struct ndis_assoc_info {
- ULONG length;
- USHORT req_ies;
- struct req_ie {
- USHORT capa;
- USHORT listen_interval;
- mac_address cur_ap_address;
- } req_ie;
- ULONG req_ie_length;
- ULONG offset_req_ies;
- USHORT resp_ies;
- struct resp_ie {
- USHORT capa;
- USHORT status_code;
- USHORT assoc_id;
- } resp_ie;
- ULONG resp_ie_length;
- ULONG offset_resp_ies;
-};
-
-struct ndis_configuration_fh {
- ULONG length;
- ULONG hop_pattern;
- ULONG hop_set;
- ULONG dwell_time;
-};
-
-struct ndis_configuration {
- ULONG length;
- ULONG beacon_period;
- ULONG atim_window;
- ULONG ds_config;
- struct ndis_configuration_fh fh_config;
-};
-
-struct ndis_wlan_bssid {
- ULONG length;
- mac_address mac;
- UCHAR reserved[2];
- struct ndis_essid ssid;
- ULONG privacy;
- ndis_rssi rssi;
- UINT net_type;
- struct ndis_configuration config;
- UINT mode;
- ndis_rates rates;
-};
-
-struct ndis_wlan_bssid_ex {
- ULONG length;
- mac_address mac;
- UCHAR reserved[2];
- struct ndis_essid ssid;
- ULONG privacy;
- ndis_rssi rssi;
- UINT net_type;
- struct ndis_configuration config;
- UINT mode;
- ndis_rates_ex rates_ex;
- ULONG ie_length;
- UCHAR ies[1];
-};
-
-/* we use bssid_list as bssid_list_ex also */
-struct ndis_bssid_list {
- ULONG num_items;
- struct ndis_wlan_bssid bssid[1];
-};
-
-enum ndis_priv_filter {
- Ndis802_11PrivFilterAcceptAll, Ndis802_11PrivFilter8021xWEP
-};
-
-enum network_type {
- Ndis802_11FH, Ndis802_11DS, Ndis802_11OFDM5, Ndis802_11OFDM24,
- /* MSDN site uses Ndis802_11Automode, which is not mentioned
- * in DDK, so add one and assign it to
- * Ndis802_11NetworkTypeMax */
- Ndis802_11Automode, Ndis802_11NetworkTypeMax = Ndis802_11Automode
-};
-
-struct network_type_list {
- ULONG num;
- enum network_type types[1];
-};
-
-enum ndis_power {
- NDIS_POWER_OFF = 0, NDIS_POWER_MAX, NDIS_POWER_MIN,
-};
-
-struct ndis_auth_req {
- ULONG length;
- mac_address bssid;
- ULONG flags;
-};
-
-struct ndis_bssid_info {
- mac_address bssid;
- ndis_pmkid_vavlue pmkid;
-};
-
-struct ndis_pmkid {
- ULONG length;
- ULONG bssid_info_count;
- struct ndis_bssid_info bssid_info[1];
-};
-
-int add_wep_key(struct ndis_device *wnd, char *key, int key_len,
- int index);
-int set_essid(struct ndis_device *wnd, const char *ssid, int ssid_len);
-int set_infra_mode(struct ndis_device *wnd,
- enum ndis_infrastructure_mode mode);
-int get_ap_address(struct ndis_device *wnd, mac_address mac);
-int set_ndis_auth_mode(struct ndis_device *wnd, ULONG auth_mode);
-int set_iw_auth_mode(struct ndis_device *wnd, int wpa_version,
- int auth_80211_alg);
-int set_auth_mode(struct ndis_device *wnd);
-int set_ndis_encr_mode(struct ndis_device *wnd, int cipher_pairwise,
- int cipher_groupwise);
-int get_ndis_encr_mode(struct ndis_device *wnd);
-int set_encr_mode(struct ndis_device *wnd);
-int set_iw_encr_mode(struct ndis_device *wnd, int cipher_pairwise,
- int cipher_groupwise);
-int get_ndis_auth_mode(struct ndis_device *wnd);
-int set_priv_filter(struct ndis_device *wnd);
-int set_scan(struct ndis_device *wnd);
-NDIS_STATUS disassociate(struct ndis_device *wnd, int reset_ssid);
-void set_default_iw_params(struct ndis_device *wnd);
-extern const struct iw_handler_def ndis_handler_def;
-
-#define PRIV_RESET SIOCIWFIRSTPRIV+16
-#define PRIV_POWER_PROFILE SIOCIWFIRSTPRIV+17
-#define PRIV_NETWORK_TYPE SIOCIWFIRSTPRIV+18
-#define PRIV_DEAUTHENTICATE SIOCIWFIRSTPRIV+19
-#define PRIV_MEDIA_STREAM_MODE SIOCIWFIRSTPRIV+20
-#define PRIV_RELOAD_DEFAULTS SIOCIWFIRSTPRIV+23
-
-#define RSN_INFO_ELEM 0x30
-
-/* these have to match what is in wpa_supplicant */
-
-typedef enum { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP } wpa_alg;
-typedef enum { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP,
- CIPHER_WEP104 } wpa_cipher;
-typedef enum { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE,
- KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE } wpa_key_mgmt;
-
-#endif // IW_NDIS_H
+++ /dev/null
-/*
- * Copyright (C) 2006 Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#ifdef CONFIG_X86_64
-
-/* Windows functions must have 32 bytes of shadow space for arguments
- * above return address, irrespective of number of args. So argc >= 4
- */
-
-#define alloc_win_stack_frame(argc) \
- "sub $(" #argc "+1)*8, %%rsp\n\t"
-#define free_win_stack_frame(argc) \
- "add $(" #argc "+1)*8, %%rsp\n\t"
-
-/* m is index of Windows arg required; Windows arg 1 should be at
- * 0(%rsp), arg 2 at 8(%rsp) and so on after the frame is allocated.
-*/
-
-#define lin2win_win_arg(m) "(" #m "-1)*8(%%rsp)"
-
-/* args for Windows function must be in clobber / output list */
-
-#define outputs() \
- "=a" (_ret), "=c" (_dummy), "=d" (_dummy), \
- "=r" (r8), "=r" (r9), "=r" (r10), "=r" (r11)
-
-#define clobbers() "cc"
-
-#define LIN2WIN0(func) \
-({ \
- u64 _ret, _dummy; \
- register u64 r8 __asm__("r8"); \
- register u64 r9 __asm__("r9"); \
- register u64 r10 __asm__("r10"); \
- register u64 r11 __asm__("r11"); \
- __asm__ __volatile__( \
- alloc_win_stack_frame(4) \
- "callq *%[fptr]\n\t" \
- free_win_stack_frame(4) \
- : outputs() \
- : [fptr] "r" (func) \
- : clobbers()); \
- _ret; \
-})
-
-#define LIN2WIN1(func, arg1) \
-({ \
- u64 _ret, _dummy; \
- register u64 r8 __asm__("r8"); \
- register u64 r9 __asm__("r9"); \
- register u64 r10 __asm__("r10"); \
- register u64 r11 __asm__("r11"); \
- __asm__ __volatile__( \
- alloc_win_stack_frame(4) \
- "callq *%[fptr]\n\t" \
- free_win_stack_frame(4) \
- : outputs() \
- : "c" (arg1), [fptr] "r" (func) \
- : clobbers()); \
- _ret; \
-})
-
-#define LIN2WIN2(func, arg1, arg2) \
-({ \
- u64 _ret, _dummy; \
- register u64 r8 __asm__("r8"); \
- register u64 r9 __asm__("r9"); \
- register u64 r10 __asm__("r10"); \
- register u64 r11 __asm__("r11"); \
- __asm__ __volatile__( \
- alloc_win_stack_frame(4) \
- "callq *%[fptr]\n\t" \
- free_win_stack_frame(4) \
- : outputs() \
- : "c" (arg1), "d" (arg2), [fptr] "r" (func) \
- : clobbers()); \
- _ret; \
-})
-
-#define LIN2WIN3(func, arg1, arg2, arg3) \
-({ \
- u64 _ret, _dummy; \
- register u64 r8 __asm__("r8") = (u64)arg3; \
- register u64 r9 __asm__("r9"); \
- register u64 r10 __asm__("r10"); \
- register u64 r11 __asm__("r11"); \
- __asm__ __volatile__( \
- alloc_win_stack_frame(4) \
- "callq *%[fptr]\n\t" \
- free_win_stack_frame(4) \
- : outputs() \
- : "c" (arg1), "d" (arg2), "r" (r8), \
- [fptr] "r" (func) \
- : clobbers()); \
- _ret; \
-})
-
-#define LIN2WIN4(func, arg1, arg2, arg3, arg4) \
-({ \
- u64 _ret, _dummy; \
- register u64 r8 __asm__("r8") = (u64)arg3; \
- register u64 r9 __asm__("r9") = (u64)arg4; \
- register u64 r10 __asm__("r10"); \
- register u64 r11 __asm__("r11"); \
- __asm__ __volatile__( \
- alloc_win_stack_frame(4) \
- "callq *%[fptr]\n\t" \
- free_win_stack_frame(4) \
- : outputs() \
- : "c" (arg1), "d" (arg2), "r" (r8), "r" (r9), \
- [fptr] "r" (func) \
- : clobbers()); \
- _ret; \
-})
-
-#define LIN2WIN5(func, arg1, arg2, arg3, arg4, arg5) \
-({ \
- u64 _ret, _dummy; \
- register u64 r8 __asm__("r8") = (u64)arg3; \
- register u64 r9 __asm__("r9") = (u64)arg4; \
- register u64 r10 __asm__("r10"); \
- register u64 r11 __asm__("r11"); \
- __asm__ __volatile__( \
- alloc_win_stack_frame(5) \
- "movq %[rarg5], " lin2win_win_arg(5) "\n\t" \
- "callq *%[fptr]\n\t" \
- free_win_stack_frame(5) \
- : outputs() \
- : "c" (arg1), "d" (arg2), "r" (r8), "r" (r9), \
- [rarg5] "ri" ((u64)arg5), \
- [fptr] "r" (func) \
- : clobbers()); \
- _ret; \
-})
-
-#define LIN2WIN6(func, arg1, arg2, arg3, arg4, arg5, arg6) \
-({ \
- u64 _ret, _dummy; \
- register u64 r8 __asm__("r8") = (u64)arg3; \
- register u64 r9 __asm__("r9") = (u64)arg4; \
- register u64 r10 __asm__("r10"); \
- register u64 r11 __asm__("r11"); \
- __asm__ __volatile__( \
- alloc_win_stack_frame(6) \
- "movq %[rarg5], " lin2win_win_arg(5) "\n\t" \
- "movq %[rarg6], " lin2win_win_arg(6) "\n\t" \
- "callq *%[fptr]\n\t" \
- free_win_stack_frame(6) \
- : outputs() \
- : "c" (arg1), "d" (arg2), "r" (r8), "r" (r9), \
- [rarg5] "ri" ((u64)arg5), [rarg6] "ri" ((u64)arg6), \
- [fptr] "r" (func) \
- : clobbers()); \
- _ret; \
-})
-
-#else // CONFIG_X86_64
-
-#define LIN2WIN1(func, arg1) \
-({ \
- TRACE6("calling %p", func); \
- func(arg1); \
-})
-#define LIN2WIN2(func, arg1, arg2) \
-({ \
- TRACE6("calling %p", func); \
- func(arg1, arg2); \
-})
-#define LIN2WIN3(func, arg1, arg2, arg3) \
-({ \
- TRACE6("calling %p", func); \
- func(arg1, arg2, arg3); \
-})
-#define LIN2WIN4(func, arg1, arg2, arg3, arg4) \
-({ \
- TRACE6("calling %p", func); \
- func(arg1, arg2, arg3, arg4); \
-})
-#define LIN2WIN5(func, arg1, arg2, arg3, arg4, arg5) \
-({ \
- TRACE6("calling %p", func); \
- func(arg1, arg2, arg3, arg4, arg5); \
-})
-#define LIN2WIN6(func, arg1, arg2, arg3, arg4, arg5, arg6) \
-({ \
- TRACE6("calling %p", func); \
- func(arg1, arg2, arg3, arg4, arg5, arg6); \
-})
-
-#endif // CONFIG_X86_64
+++ /dev/null
-/*
- * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include "ndis.h"
-#include "loader.h"
-#include "wrapndis.h"
-#include "pnp.h"
-
-#include <linux/module.h>
-#include <linux/kmod.h>
-#include <linux/miscdevice.h>
-#include <asm/uaccess.h>
-
-/*
- Network adapter: ClassGuid = {4d36e972-e325-11ce-bfc1-08002be10318}
- Network client: ClassGuid = {4d36e973-e325-11ce-bfc1-08002be10318}
- PCMCIA adapter: ClassGuid = {4d36e977-e325-11ce-bfc1-08002be10318}
- USB: ClassGuid = {36fc9e60-c465-11cf-8056-444553540000}
-*/
-
-/* the indices used here must match macros WRAP_NDIS_DEVICE etc. */
-static struct guid class_guids[] = {
- /* Network */
- {0x4d36e972, 0xe325, 0x11ce, },
- /* USB WDM */
- {0x36fc9e60, 0xc465, 0x11cf, },
- /* Bluetooth */
- {0xe0cbf06c, 0xcd8b, 0x4647, },
- /* ivtcorporatino.com's bluetooth device claims this is
- * bluetooth guid */
- {0xf12d3cf8, 0xb11d, 0x457e, },
-};
-
-struct semaphore loader_mutex;
-static struct completion loader_complete;
-
-static struct nt_list wrap_devices;
-static struct nt_list wrap_drivers;
-
-static int wrap_device_type(int data1)
-{
- int i;
- for (i = 0; i < sizeof(class_guids) / sizeof(class_guids[0]); i++)
- if (data1 == class_guids[i].data1)
- return i;
- ERROR("unknown device: 0x%x\n", data1);
- return -1;
-}
-
-/* load driver for given device, if not already loaded */
-struct wrap_driver *load_wrap_driver(struct wrap_device *wd)
-{
- int ret;
- struct nt_list *cur;
- struct wrap_driver *wrap_driver;
-
- ENTER1("device: %04X:%04X:%04X:%04X", wd->vendor, wd->device,
- wd->subvendor, wd->subdevice);
- if (down_interruptible(&loader_mutex)) {
- WARNING("couldn't obtain loader_mutex");
- EXIT1(return NULL);
- }
- wrap_driver = NULL;
- nt_list_for_each(cur, &wrap_drivers) {
- wrap_driver = container_of(cur, struct wrap_driver, list);
- if (!stricmp(wrap_driver->name, wd->driver_name)) {
- TRACE1("driver %s already loaded", wrap_driver->name);
- break;
- } else
- wrap_driver = NULL;
- }
- up(&loader_mutex);
-
- if (!wrap_driver) {
- char *argv[] = {"loadndisdriver", WRAP_CMD_LOAD_DRIVER,
-#if defined(DEBUG) && DEBUG >= 1
- "1",
-#else
- "0",
-#endif
- UTILS_VERSION, wd->driver_name,
- wd->conf_file_name, NULL};
- char *env[] = {NULL};
-
- TRACE1("loading driver %s", wd->driver_name);
- if (down_interruptible(&loader_mutex)) {
- WARNING("couldn't obtain loader_mutex");
- EXIT1(return NULL);
- }
- INIT_COMPLETION(loader_complete);
- ret = call_usermodehelper("/sbin/loadndisdriver", argv, env, 1);
- if (ret) {
- up(&loader_mutex);
- ERROR("couldn't load driver %s; check system log "
- "for messages from 'loadndisdriver'",
- wd->driver_name);
- EXIT1(return NULL);
- }
- wait_for_completion(&loader_complete);
- TRACE1("%s", wd->driver_name);
- wrap_driver = NULL;
- nt_list_for_each(cur, &wrap_drivers) {
- wrap_driver = container_of(cur, struct wrap_driver,
- list);
- if (!stricmp(wrap_driver->name, wd->driver_name)) {
- wd->driver = wrap_driver;
- break;
- } else
- wrap_driver = NULL;
- }
- up(&loader_mutex);
- if (wrap_driver)
- TRACE1("driver %s is loaded", wrap_driver->name);
- else
- ERROR("couldn't load driver '%s'", wd->driver_name);
- }
- EXIT1(return wrap_driver);
-}
-
-/* load the driver files from userspace. */
-static int load_sys_files(struct wrap_driver *driver,
- struct load_driver *load_driver)
-{
- int i, err;
-
- TRACE1("num_pe_images = %d", load_driver->num_sys_files);
- TRACE1("loading driver: %s", load_driver->name);
- strncpy(driver->name, load_driver->name, sizeof(driver->name));
- driver->name[sizeof(driver->name)-1] = 0;
- TRACE1("driver: %s", driver->name);
- err = 0;
- driver->num_pe_images = 0;
- for (i = 0; i < load_driver->num_sys_files; i++) {
- struct pe_image *pe_image;
- pe_image = &driver->pe_images[driver->num_pe_images];
-
- strncpy(pe_image->name, load_driver->sys_files[i].name,
- sizeof(pe_image->name));
- pe_image->name[sizeof(pe_image->name)-1] = 0;
- TRACE1("image size: %lu bytes",
- (unsigned long)load_driver->sys_files[i].size);
-
-#ifdef CONFIG_X86_64
-#ifdef PAGE_KERNEL_EXECUTABLE
- pe_image->image =
- __vmalloc(load_driver->sys_files[i].size,
- GFP_KERNEL | __GFP_HIGHMEM,
- PAGE_KERNEL_EXECUTABLE);
-#elif defined PAGE_KERNEL_EXEC
- pe_image->image =
- __vmalloc(load_driver->sys_files[i].size,
- GFP_KERNEL | __GFP_HIGHMEM,
- PAGE_KERNEL_EXEC);
-#else
-#error x86_64 should have either PAGE_KERNEL_EXECUTABLE or PAGE_KERNEL_EXEC
-#endif
-#else
- /* hate to play with kernel macros, but PAGE_KERNEL_EXEC is
- * not available to modules! */
-#ifdef cpu_has_nx
- if (cpu_has_nx)
- pe_image->image =
- __vmalloc(load_driver->sys_files[i].size,
- GFP_KERNEL | __GFP_HIGHMEM,
- __pgprot(__PAGE_KERNEL & ~_PAGE_NX));
- else
- pe_image->image =
- vmalloc(load_driver->sys_files[i].size);
-#else
- pe_image->image =
- vmalloc(load_driver->sys_files[i].size);
-#endif
-#endif
- if (!pe_image->image) {
- ERROR("couldn't allocate memory");
- err = -ENOMEM;
- break;
- }
- TRACE1("image is at %p", pe_image->image);
-
- if (copy_from_user(pe_image->image,
- load_driver->sys_files[i].data,
- load_driver->sys_files[i].size)) {
- ERROR("couldn't load file %s",
- load_driver->sys_files[i].name);
- err = -EFAULT;
- break;
- }
- pe_image->size = load_driver->sys_files[i].size;
- driver->num_pe_images++;
- }
-
- if (!err && link_pe_images(driver->pe_images, driver->num_pe_images)) {
- ERROR("couldn't prepare driver '%s'", load_driver->name);
- err = -EINVAL;
- }
-
- if (driver->num_pe_images < load_driver->num_sys_files || err) {
- for (i = 0; i < driver->num_pe_images; i++)
- if (driver->pe_images[i].image)
- vfree(driver->pe_images[i].image);
- driver->num_pe_images = 0;
- EXIT1(return err);
- } else
- EXIT1(return 0);
-}
-
-struct wrap_bin_file *get_bin_file(char *bin_file_name)
-{
- int i = 0;
- struct wrap_driver *driver, *cur;
-
- ENTER1("%s", bin_file_name);
- if (down_interruptible(&loader_mutex)) {
- WARNING("couldn't obtain loader_mutex");
- EXIT1(return NULL);
- }
- driver = NULL;
- nt_list_for_each_entry(cur, &wrap_drivers, list) {
- for (i = 0; i < cur->num_bin_files; i++)
- if (!stricmp(cur->bin_files[i].name, bin_file_name)) {
- driver = cur;
- break;
- }
- if (driver)
- break;
- }
- up(&loader_mutex);
- if (!driver) {
- TRACE1("coudln't find bin file '%s'", bin_file_name);
- return NULL;
- }
-
- if (!driver->bin_files[i].data) {
- char *argv[] = {"loadndisdriver", WRAP_CMD_LOAD_BIN_FILE,
-#if defined(DEBUG) && DEBUG >= 1
- "1",
-#else
- "0",
-#endif
- UTILS_VERSION, driver->name,
- driver->bin_files[i].name, NULL};
- char *env[] = {NULL};
- int ret;
-
- TRACE1("loading bin file %s/%s", driver->name,
- driver->bin_files[i].name);
- if (down_interruptible(&loader_mutex)) {
- WARNING("couldn't obtain loader_mutex");
- EXIT1(return NULL);
- }
- INIT_COMPLETION(loader_complete);
- ret = call_usermodehelper("/sbin/loadndisdriver", argv, env, 1);
- if (ret) {
- up(&loader_mutex);
- ERROR("couldn't load file %s/%s; check system log "
- "for messages from 'loadndisdriver' (%d)",
- driver->name, driver->bin_files[i].name, ret);
- EXIT1(return NULL);
- }
- wait_for_completion(&loader_complete);
- up(&loader_mutex);
- if (!driver->bin_files[i].data) {
- WARNING("couldn't load binary file %s",
- driver->bin_files[i].name);
- EXIT1(return NULL);
- }
- }
- EXIT2(return &(driver->bin_files[i]));
-}
-
-/* called with loader_mutex down */
-static int add_bin_file(struct load_driver_file *driver_file)
-{
- struct wrap_driver *driver, *cur;
- struct wrap_bin_file *bin_file;
- int i = 0;
-
- driver = NULL;
- nt_list_for_each_entry(cur, &wrap_drivers, list) {
- for (i = 0; i < cur->num_bin_files; i++)
- if (!stricmp(cur->bin_files[i].name,
- driver_file->name)) {
- driver = cur;
- break;
- }
- if (driver)
- break;
- }
- if (!driver) {
- ERROR("couldn't find %s", driver_file->name);
- return -EINVAL;
- }
- bin_file = &driver->bin_files[i];
- strncpy(bin_file->name, driver_file->name, sizeof(bin_file->name));
- bin_file->name[sizeof(bin_file->name)-1] = 0;
- bin_file->data = vmalloc(driver_file->size);
- if (!bin_file->data) {
- ERROR("couldn't allocate memory");
- return -ENOMEM;
- }
- bin_file->size = driver_file->size;
- if (copy_from_user(bin_file->data, driver_file->data, bin_file->size)) {
- ERROR("couldn't copy data");
- free_bin_file(bin_file);
- return -EFAULT;
- }
- return 0;
-}
-
-void free_bin_file(struct wrap_bin_file *bin_file)
-{
- TRACE2("unloading %s", bin_file->name);
- if (bin_file->data)
- vfree(bin_file->data);
- bin_file->data = NULL;
- bin_file->size = 0;
- EXIT2(return);
-}
-
-/* load firmware files from userspace */
-static int load_bin_files_info(struct wrap_driver *driver,
- struct load_driver *load_driver)
-{
- struct wrap_bin_file *bin_files;
- int i;
-
- ENTER1("%s, %d", load_driver->name, load_driver->num_bin_files);
- driver->num_bin_files = 0;
- driver->bin_files = NULL;
- if (load_driver->num_bin_files == 0)
- EXIT1(return 0);
- bin_files = kzalloc(load_driver->num_bin_files * sizeof(*bin_files),
- GFP_KERNEL);
- if (!bin_files) {
- ERROR("couldn't allocate memory");
- EXIT1(return -ENOMEM);
- }
-
- for (i = 0; i < load_driver->num_bin_files; i++) {
- strncpy(bin_files[i].name, load_driver->bin_files[i].name,
- sizeof(bin_files[i].name));
- bin_files[i].name[sizeof(bin_files[i].name)-1] = 0;
- TRACE2("loaded bin file %s", bin_files[i].name);
- }
- driver->num_bin_files = load_driver->num_bin_files;
- driver->bin_files = bin_files;
- EXIT1(return 0);
-}
-
-/* load settnigs for a device. called with loader_mutex down */
-static int load_settings(struct wrap_driver *wrap_driver,
- struct load_driver *load_driver)
-{
- int i, num_settings;
-
- ENTER1("%p, %p", wrap_driver, load_driver);
-
- num_settings = 0;
- for (i = 0; i < load_driver->num_settings; i++) {
- struct load_device_setting *load_setting =
- &load_driver->settings[i];
- struct wrap_device_setting *setting;
- ULONG data1;
-
- setting = kzalloc(sizeof(*setting), GFP_KERNEL);
- if (!setting) {
- ERROR("couldn't allocate memory");
- break;
- }
- strncpy(setting->name, load_setting->name,
- sizeof(setting->name));
- setting->name[sizeof(setting->name)-1] = 0;
- strncpy(setting->value, load_setting->value,
- sizeof(setting->value));
- setting->value[sizeof(setting->value)-1] = 0;
- TRACE2("%p: %s=%s", setting, setting->name, setting->value);
-
- if (strcmp(setting->name, "driver_version") == 0) {
- strncpy(wrap_driver->version, setting->value,
- sizeof(wrap_driver->version));
- wrap_driver->version[sizeof(wrap_driver->version)-1] = 0;
- } else if (strcmp(setting->name, "class_guid") == 0 &&
- sscanf(setting->value, "%x", &data1) == 1) {
- wrap_driver->dev_type = wrap_device_type(data1);
- if (wrap_driver->dev_type < 0) {
- WARNING("unknown guid: %x", data1);
- wrap_driver->dev_type = 0;
- }
- }
- InsertTailList(&wrap_driver->settings, &setting->list);
- num_settings++;
- }
- /* it is not a fatal error if some settings couldn't be loaded */
- if (num_settings > 0)
- EXIT1(return 0);
- else
- EXIT1(return -EINVAL);
-}
-
-void unload_wrap_device(struct wrap_device *wd)
-{
- struct nt_list *cur;
- ENTER1("unloading device %p (%04X:%04X:%04X:%04X), driver %s", wd,
- wd->vendor, wd->device, wd->subvendor, wd->subdevice,
- wd->driver_name);
- if (down_interruptible(&loader_mutex))
- WARNING("couldn't obtain loader_mutex");
- while ((cur = RemoveHeadList(&wd->settings))) {
- struct wrap_device_setting *setting;
- setting = container_of(cur, struct wrap_device_setting, list);
- kfree(setting);
- }
- RemoveEntryList(&wd->list);
- up(&loader_mutex);
- kfree(wd);
- EXIT1(return);
-}
-
-/* should be called with loader_mutex down */
-void unload_wrap_driver(struct wrap_driver *driver)
-{
- int i;
- struct driver_object *drv_obj;
- struct nt_list *cur, *next;
-
- ENTER1("unloading driver: %s (%p)", driver->name, driver);
- TRACE1("freeing %d images", driver->num_pe_images);
- drv_obj = driver->drv_obj;
- for (i = 0; i < driver->num_pe_images; i++)
- if (driver->pe_images[i].image) {
- TRACE1("freeing image at %p",
- driver->pe_images[i].image);
- vfree(driver->pe_images[i].image);
- }
-
- TRACE1("freeing %d bin files", driver->num_bin_files);
- for (i = 0; i < driver->num_bin_files; i++) {
- TRACE1("freeing image at %p", driver->bin_files[i].data);
- if (driver->bin_files[i].data)
- vfree(driver->bin_files[i].data);
- }
- if (driver->bin_files)
- kfree(driver->bin_files);
- RtlFreeUnicodeString(&drv_obj->name);
- RemoveEntryList(&driver->list);
- nt_list_for_each_safe(cur, next, &driver->settings) {
- struct wrap_device_setting *setting;
- struct ndis_configuration_parameter *param;
-
- setting = container_of(cur, struct wrap_device_setting, list);
- TRACE2("%p", setting);
- param = setting->encoded;
- if (param) {
- TRACE2("%p", param);
- if (param->type == NdisParameterString)
- RtlFreeUnicodeString(¶m->data.string);
- ExFreePool(param);
- }
- kfree(setting);
- }
- /* this frees driver */
- free_custom_extensions(drv_obj->drv_ext);
- kfree(drv_obj->drv_ext);
- TRACE1("drv_obj: %p", drv_obj);
-
- EXIT1(return);
-}
-
-/* call the entry point of the driver */
-static int start_wrap_driver(struct wrap_driver *driver)
-{
- int i;
- NTSTATUS ret, res;
- struct driver_object *drv_obj;
- typeof(driver->pe_images[0].entry) entry;
-
- ENTER1("%s", driver->name);
- drv_obj = driver->drv_obj;
- for (ret = res = 0, i = 0; i < driver->num_pe_images; i++)
- /* dlls are already started by loader */
- if (driver->pe_images[i].type == IMAGE_FILE_EXECUTABLE_IMAGE) {
- entry = driver->pe_images[i].entry;
- drv_obj->start = driver->pe_images[i].entry;
- drv_obj->driver_size = driver->pe_images[i].size;
- TRACE1("entry: %p, %p, drv_obj: %p",
- entry, *entry, drv_obj);
- res = LIN2WIN2(entry, drv_obj, &drv_obj->name);
- ret |= res;
- TRACE1("entry returns %08X", res);
- break;
- }
- if (ret) {
- ERROR("driver initialization failed: %08X", ret);
- RtlFreeUnicodeString(&drv_obj->name);
- /* this frees ndis_driver */
- free_custom_extensions(drv_obj->drv_ext);
- kfree(drv_obj->drv_ext);
- TRACE1("drv_obj: %p", drv_obj);
- ObDereferenceObject(drv_obj);
- EXIT1(return -EINVAL);
- }
- EXIT1(return 0);
-}
-
-/*
- * add driver to list of loaded driver but make sure this driver is
- * not loaded before. called with loader_mutex down
- */
-static int add_wrap_driver(struct wrap_driver *driver)
-{
- struct wrap_driver *tmp;
-
- ENTER1("name: %s", driver->name);
- nt_list_for_each_entry(tmp, &wrap_drivers, list) {
- if (stricmp(tmp->name, driver->name) == 0) {
- ERROR("cannot add duplicate driver");
- EXIT1(return -EBUSY);
- }
- }
- InsertHeadList(&wrap_drivers, &driver->list);
- EXIT1(return 0);
-}
-
-/* load a driver from userspace and initialize it. called with
- * loader_mutex down */
-static int load_user_space_driver(struct load_driver *load_driver)
-{
- struct driver_object *drv_obj;
- struct ansi_string ansi_reg;
- struct wrap_driver *wrap_driver = NULL;
-
- ENTER1("%p", load_driver);
- drv_obj = allocate_object(sizeof(*drv_obj), OBJECT_TYPE_DRIVER, NULL);
- if (!drv_obj) {
- ERROR("couldn't allocate memory");
- EXIT1(return -ENOMEM);
- }
- TRACE1("drv_obj: %p", drv_obj);
- drv_obj->drv_ext = kzalloc(sizeof(*(drv_obj->drv_ext)), GFP_KERNEL);
- if (!drv_obj->drv_ext) {
- ERROR("couldn't allocate memory");
- ObDereferenceObject(drv_obj);
- EXIT1(return -ENOMEM);
- }
- InitializeListHead(&drv_obj->drv_ext->custom_ext);
- if (IoAllocateDriverObjectExtension(drv_obj,
- (void *)WRAP_DRIVER_CLIENT_ID,
- sizeof(*wrap_driver),
- (void **)&wrap_driver) !=
- STATUS_SUCCESS)
- EXIT1(return -ENOMEM);
- TRACE1("driver: %p", wrap_driver);
- memset(wrap_driver, 0, sizeof(*wrap_driver));
- InitializeListHead(&wrap_driver->list);
- InitializeListHead(&wrap_driver->settings);
- InitializeListHead(&wrap_driver->wrap_devices);
- wrap_driver->drv_obj = drv_obj;
- RtlInitAnsiString(&ansi_reg, "/tmp");
- if (RtlAnsiStringToUnicodeString(&drv_obj->name, &ansi_reg, TRUE) !=
- STATUS_SUCCESS) {
- ERROR("couldn't initialize registry path");
- free_custom_extensions(drv_obj->drv_ext);
- kfree(drv_obj->drv_ext);
- TRACE1("drv_obj: %p", drv_obj);
- ObDereferenceObject(drv_obj);
- EXIT1(return -EINVAL);
- }
- strncpy(wrap_driver->name, load_driver->name, sizeof(wrap_driver->name));
- wrap_driver->name[sizeof(wrap_driver->name)-1] = 0;
- if (load_sys_files(wrap_driver, load_driver) ||
- load_bin_files_info(wrap_driver, load_driver) ||
- load_settings(wrap_driver, load_driver) ||
- start_wrap_driver(wrap_driver) ||
- add_wrap_driver(wrap_driver)) {
- unload_wrap_driver(wrap_driver);
- EXIT1(return -EINVAL);
- } else {
- printk(KERN_INFO "%s: driver %s (%s) loaded\n",
- DRIVER_NAME, wrap_driver->name, wrap_driver->version);
- add_taint(TAINT_PROPRIETARY_MODULE);
- EXIT1(return 0);
- }
-}
-
-static struct pci_device_id wrap_pci_id_table[] = {
- {PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID},
-};
-
-static struct pci_driver wrap_pci_driver = {
- .name = DRIVER_NAME,
- .id_table = wrap_pci_id_table,
- .probe = wrap_pnp_start_pci_device,
- .remove = __devexit_p(wrap_pnp_remove_pci_device),
- .suspend = wrap_pnp_suspend_pci_device,
- .resume = wrap_pnp_resume_pci_device,
-};
-
-#ifdef ENABLE_USB
-static struct usb_device_id wrap_usb_id_table[] = {
- {
- .driver_info = 1
- },
-};
-
-static struct usb_driver wrap_usb_driver = {
- .name = DRIVER_NAME,
- .id_table = wrap_usb_id_table,
- .probe = wrap_pnp_start_usb_device,
- .disconnect = __devexit_p(wrap_pnp_remove_usb_device),
- .suspend = wrap_pnp_suspend_usb_device,
- .resume = wrap_pnp_resume_usb_device,
-};
-#endif
-
-/* register drivers for pci and usb */
-static void register_devices(void)
-{
- int res;
-
- res = pci_register_driver(&wrap_pci_driver);
- if (res < 0) {
- ERROR("couldn't register pci driver: %d", res);
- wrap_pci_driver.name = NULL;
- }
-
-#ifdef ENABLE_USB
- res = usb_register(&wrap_usb_driver);
- if (res < 0) {
- ERROR("couldn't register usb driver: %d", res);
- wrap_usb_driver.name = NULL;
- }
-#endif
- EXIT1(return);
-}
-
-static void unregister_devices(void)
-{
- struct nt_list *cur, *next;
-
- if (down_interruptible(&loader_mutex))
- WARNING("couldn't obtain loader_mutex");
- nt_list_for_each_safe(cur, next, &wrap_devices) {
- struct wrap_device *wd;
- wd = container_of(cur, struct wrap_device, list);
- set_bit(HW_PRESENT, &wd->hw_status);
- }
- up(&loader_mutex);
-
- if (wrap_pci_driver.name)
- pci_unregister_driver(&wrap_pci_driver);
-#ifdef ENABLE_USB
- if (wrap_usb_driver.name)
- usb_deregister(&wrap_usb_driver);
-#endif
-}
-
-struct wrap_device *load_wrap_device(struct load_device *load_device)
-{
- int ret;
- struct nt_list *cur;
- struct wrap_device *wd = NULL;
- char vendor[5], device[5], subvendor[5], subdevice[5], bus[5];
-
- ENTER1("%04x, %04x, %04x, %04x", load_device->vendor,
- load_device->device, load_device->subvendor,
- load_device->subdevice);
- if (sprintf(vendor, "%04x", load_device->vendor) == 4 &&
- sprintf(device, "%04x", load_device->device) == 4 &&
- sprintf(subvendor, "%04x", load_device->subvendor) == 4 &&
- sprintf(subdevice, "%04x", load_device->subdevice) == 4 &&
- sprintf(bus, "%04x", load_device->bus) == 4) {
- char *argv[] = {"loadndisdriver", WRAP_CMD_LOAD_DEVICE,
-#if defined(DEBUG) && DEBUG >= 1
- "1",
-#else
- "0",
-#endif
- UTILS_VERSION, vendor, device,
- subvendor, subdevice, bus, NULL};
- char *env[] = {NULL};
- TRACE2("%s, %s, %s, %s, %s", vendor, device,
- subvendor, subdevice, bus);
- if (down_interruptible(&loader_mutex)) {
- WARNING("couldn't obtain loader_mutex");
- EXIT1(return NULL);
- }
- INIT_COMPLETION(loader_complete);
- ret = call_usermodehelper("/sbin/loadndisdriver", argv, env, 1);
- if (ret) {
- up(&loader_mutex);
- TRACE1("couldn't load device %04x:%04x; check system "
- "log for messages from 'loadndisdriver'",
- load_device->vendor, load_device->device);
- EXIT1(return NULL);
- }
- wait_for_completion(&loader_complete);
- wd = NULL;
- nt_list_for_each(cur, &wrap_devices) {
- wd = container_of(cur, struct wrap_device, list);
- TRACE2("%p, %04x, %04x, %04x, %04x", wd, wd->vendor,
- wd->device, wd->subvendor, wd->subdevice);
- if (wd->vendor == load_device->vendor &&
- wd->device == load_device->device)
- break;
- else
- wd = NULL;
- }
- up(&loader_mutex);
- } else
- wd = NULL;
- EXIT1(return wd);
-}
-
-struct wrap_device *get_wrap_device(void *dev, int bus)
-{
- struct nt_list *cur;
- struct wrap_device *wd;
-
- if (down_interruptible(&loader_mutex)) {
- WARNING("couldn't obtain loader_mutex");
- return NULL;
- }
- wd = NULL;
- nt_list_for_each(cur, &wrap_devices) {
- wd = container_of(cur, struct wrap_device, list);
- if (bus == WRAP_PCI_BUS &&
- wrap_is_pci_bus(wd->dev_bus) && wd->pci.pdev == dev)
- break;
- else if (bus == WRAP_USB_BUS &&
- wrap_is_usb_bus(wd->dev_bus) && wd->usb.udev == dev)
- break;
- else
- wd = NULL;
- }
- up(&loader_mutex);
- return wd;
-}
-
-static DEFINE_MUTEX(ndiswrapper_ioctl_mutex);
-
-/* called with loader_mutex is down */
-static long wrapper_ioctl(struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- struct load_driver *load_driver;
- struct load_device load_device;
- struct load_driver_file load_bin_file;
- int ret;
- void __user *addr = (void __user *)arg;
-
- mutex_lock(&ndiswrapper_ioctl_mutex);
-
- ENTER1("cmd: %u", cmd);
-
- ret = 0;
- switch (cmd) {
- case WRAP_IOCTL_LOAD_DEVICE:
- if (copy_from_user(&load_device, addr, sizeof(load_device))) {
- ret = -EFAULT;
- break;
- }
- TRACE2("%04x, %04x, %04x, %04x", load_device.vendor,
- load_device.device, load_device.subvendor,
- load_device.subdevice);
- if (load_device.vendor) {
- struct wrap_device *wd;
- wd = kzalloc(sizeof(*wd), GFP_KERNEL);
- if (!wd) {
- ret = -ENOMEM;
- break;
- }
- InitializeListHead(&wd->settings);
- wd->dev_bus = WRAP_BUS(load_device.bus);
- wd->vendor = load_device.vendor;
- wd->device = load_device.device;
- wd->subvendor = load_device.subvendor;
- wd->subdevice = load_device.subdevice;
- strncpy(wd->conf_file_name, load_device.conf_file_name,
- sizeof(wd->conf_file_name));
- wd->conf_file_name[sizeof(wd->conf_file_name)-1] = 0;
- strncpy(wd->driver_name, load_device.driver_name,
- sizeof(wd->driver_name));
- wd->driver_name[sizeof(wd->driver_name)-1] = 0;
- InsertHeadList(&wrap_devices, &wd->list);
- ret = 0;
- } else
- ret = -EINVAL;
- break;
- case WRAP_IOCTL_LOAD_DRIVER:
- TRACE1("loading driver at %p", addr);
- load_driver = vmalloc(sizeof(*load_driver));
- if (!load_driver) {
- ret = -ENOMEM;
- break;
- }
- if (copy_from_user(load_driver, addr, sizeof(*load_driver)))
- ret = -EFAULT;
- else
- ret = load_user_space_driver(load_driver);
- vfree(load_driver);
- break;
- case WRAP_IOCTL_LOAD_BIN_FILE:
- if (copy_from_user(&load_bin_file, addr, sizeof(load_bin_file)))
- ret = -EFAULT;
- else
- ret = add_bin_file(&load_bin_file);
- break;
- default:
- ERROR("unknown ioctl %u", cmd);
- ret = -EINVAL;
- break;
- }
- complete(&loader_complete);
-
- mutex_unlock(&ndiswrapper_ioctl_mutex);
-
- EXIT1(return ret);
-}
-
-static int wrapper_ioctl_release(struct inode *inode, struct file *file)
-{
- ENTER1("");
- return 0;
-}
-
-static struct file_operations wrapper_fops = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = wrapper_ioctl,
- .release = wrapper_ioctl_release,
-};
-
-static struct miscdevice wrapper_misc = {
- .name = DRIVER_NAME,
- .minor = MISC_DYNAMIC_MINOR,
- .fops = &wrapper_fops
-};
-
-int loader_init(void)
-{
- int err;
-
- InitializeListHead(&wrap_drivers);
- InitializeListHead(&wrap_devices);
- sema_init(&loader_mutex, 1);
- init_completion(&loader_complete);
- if ((err = misc_register(&wrapper_misc)) < 0 ) {
- ERROR("couldn't register module (%d)", err);
- unregister_devices();
- EXIT1(return err);
- }
- register_devices();
- EXIT1(return 0);
-}
-
-void loader_exit(void)
-{
- struct nt_list *cur, *next;
-
- ENTER1("");
- misc_deregister(&wrapper_misc);
- unregister_devices();
- if (down_interruptible(&loader_mutex))
- WARNING("couldn't obtain loader_mutex");
- nt_list_for_each_safe(cur, next, &wrap_drivers) {
- struct wrap_driver *driver;
- driver = container_of(cur, struct wrap_driver, list);
- unload_wrap_driver(driver);
- }
- up(&loader_mutex);
- EXIT1(return);
-}
+++ /dev/null
-/*
- * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef _LOADER_H_
-#define _LOADER_H_
-
-#include "ndiswrapper.h"
-
-#ifndef __KERNEL__
-#define __user
-#endif
-
-struct load_driver_file {
- char driver_name[MAX_DRIVER_NAME_LEN];
- char name[MAX_DRIVER_NAME_LEN];
- size_t size;
- void __user *data;
-};
-
-struct load_device_setting {
- char name[MAX_SETTING_NAME_LEN];
- char value[MAX_SETTING_VALUE_LEN];
-};
-
-struct load_device {
- int bus;
- int vendor;
- int device;
- int subvendor;
- int subdevice;
- char conf_file_name[MAX_DRIVER_NAME_LEN];
- char driver_name[MAX_DRIVER_NAME_LEN];
-};
-
-struct load_devices {
- int count;
- struct load_device *devices;
-};
-
-struct load_driver {
- char name[MAX_DRIVER_NAME_LEN];
- char conf_file_name[MAX_DRIVER_NAME_LEN];
- unsigned int num_sys_files;
- struct load_driver_file sys_files[MAX_DRIVER_PE_IMAGES];
- unsigned int num_settings;
- struct load_device_setting settings[MAX_DEVICE_SETTINGS];
- unsigned int num_bin_files;
- struct load_driver_file bin_files[MAX_DRIVER_BIN_FILES];
-};
-
-#define WRAP_IOCTL_LOAD_DEVICE _IOW(('N' + 'd' + 'i' + 'S'), 0, \
- struct load_device *)
-#define WRAP_IOCTL_LOAD_DRIVER _IOW(('N' + 'd' + 'i' + 'S'), 1, \
- struct load_driver *)
-#define WRAP_IOCTL_LOAD_BIN_FILE _IOW(('N' + 'd' + 'i' + 'S'), 2, \
- struct load_driver_file *)
-
-#define WRAP_CMD_LOAD_DEVICE "load_device"
-#define WRAP_CMD_LOAD_DRIVER "load_driver"
-#define WRAP_CMD_LOAD_BIN_FILE "load_bin_file"
-
-int loader_init(void);
-void loader_exit(void);
-
-#ifdef __KERNEL__
-struct wrap_device *load_wrap_device(struct load_device *load_device);
-struct wrap_driver *load_wrap_driver(struct wrap_device *device);
-struct wrap_bin_file *get_bin_file(char *bin_file_name);
-void free_bin_file(struct wrap_bin_file *bin_file);
-void unload_wrap_driver(struct wrap_driver *driver);
-void unload_wrap_device(struct wrap_device *wd);
-struct wrap_device *get_wrap_device(void *dev, int bus_type);
-
-extern struct semaphore loader_mutex;
-#endif
-
-#endif /* LOADER_H */
-
+++ /dev/null
-/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
- Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000
- Free Software Foundation, Inc.
-
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
-
-/* You have to define the following before including this file:
-
- UWtype -- An unsigned type, default type for operations (typically a "word")
- UHWtype -- An unsigned type, at least half the size of UWtype.
- UDWtype -- An unsigned type, at least twice as large a UWtype
- W_TYPE_SIZE -- size in bits of UWtype
-
- UQItype -- Unsigned 8 bit type.
- SItype, USItype -- Signed and unsigned 32 bit types.
- DItype, UDItype -- Signed and unsigned 64 bit types.
-
- On a 32 bit machine UWtype should typically be USItype;
- on a 64 bit machine, UWtype should typically be UDItype.
-*/
-
-#define __BITS4 (W_TYPE_SIZE / 4)
-#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
-#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
-#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
-
-#ifndef W_TYPE_SIZE
-#define W_TYPE_SIZE 32
-#define UWtype USItype
-#define UHWtype USItype
-#define UDWtype UDItype
-#endif
-
-/* Define auxiliary asm macros.
-
- 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) multiplies two
- UWtype integers MULTIPLER and MULTIPLICAND, and generates a two UWtype
- word product in HIGH_PROD and LOW_PROD.
-
- 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a
- UDWtype product. This is just a variant of umul_ppmm.
-
- 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
- denominator) divides a UDWtype, composed by the UWtype integers
- HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient
- in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less
- than DENOMINATOR for correct operation. If, in addition, the most
- significant bit of DENOMINATOR must be 1, then the pre-processor symbol
- UDIV_NEEDS_NORMALIZATION is defined to 1.
-
- 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
- denominator). Like udiv_qrnnd but the numbers are signed. The quotient
- is rounded towards 0.
-
- 5) count_leading_zeros(count, x) counts the number of zero-bits from the
- msb to the first nonzero bit in the UWtype X. This is the number of
- steps X needs to be shifted left to set the msb. Undefined for X == 0,
- unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value.
-
- 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts
- from the least significant end.
-
- 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
- high_addend_2, low_addend_2) adds two UWtype integers, composed by
- HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2
- respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow
- (i.e. carry out) is not stored anywhere, and is lost.
-
- 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend,
- high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers,
- composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and
- LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE
- and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere,
- and is lost.
-
- If any of these macros are left undefined for a particular CPU,
- C macros are used. */
-
-/* The CPUs come in alphabetical order below.
-
- Please add support for more CPUs here, or improve the current support
- for the CPUs below!
- (E.g. WE32100, IBM360.) */
-
-#if defined (__GNUC__) && !defined (NO_ASM)
-
-/* We sometimes need to clobber "cc" with gcc2, but that would not be
- understood by gcc1. Use cpp to avoid major code duplication. */
-#if __GNUC__ < 2
-#define __CLOBBER_CC
-#define __AND_CLOBBER_CC
-#else /* __GNUC__ >= 2 */
-#define __CLOBBER_CC : "cc"
-#define __AND_CLOBBER_CC , "cc"
-#endif /* __GNUC__ < 2 */
-
-#if defined (__alpha) && W_TYPE_SIZE == 64
-#define umul_ppmm(ph, pl, m0, m1) \
- do { \
- UDItype __m0 = (m0), __m1 = (m1); \
- __asm__ ("umulh %r1,%2,%0" \
- : "=r" ((UDItype) ph) \
- : "%rJ" (__m0), \
- "rI" (__m1)); \
- (pl) = __m0 * __m1; \
- } while (0)
-#define UMUL_TIME 46
-#ifndef LONGLONG_STANDALONE
-#define udiv_qrnnd(q, r, n1, n0, d) \
- do { UDItype __r; \
- (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \
- (r) = __r; \
- } while (0)
-extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype);
-#define UDIV_TIME 220
-#endif /* LONGLONG_STANDALONE */
-#ifdef __alpha_cix__
-#define count_leading_zeros(COUNT,X) \
- __asm__("ctlz %1,%0" : "=r"(COUNT) : "r"(X))
-#define count_trailing_zeros(COUNT,X) \
- __asm__("cttz %1,%0" : "=r"(COUNT) : "r"(X))
-#define COUNT_LEADING_ZEROS_0 64
-#else
-extern const UQItype __clz_tab[];
-#define count_leading_zeros(COUNT,X) \
- do { \
- UDItype __xr = (X), __t, __a; \
- __asm__("cmpbge $31,%1,%0" : "=r"(__t) : "r"(__xr)); \
- __a = __clz_tab[__t ^ 0xff] - 1; \
- __asm__("extbl %1,%2,%0" : "=r"(__t) : "r"(__xr), "r"(__a)); \
- (COUNT) = 64 - (__clz_tab[__t] + __a*8); \
- } while (0)
-#define count_trailing_zeros(COUNT,X) \
- do { \
- UDItype __xr = (X), __t, __a; \
- __asm__("cmpbge $31,%1,%0" : "=r"(__t) : "r"(__xr)); \
- __t = ~__t & -~__t; \
- __a = ((__t & 0xCC) != 0) * 2; \
- __a += ((__t & 0xF0) != 0) * 4; \
- __a += ((__t & 0xAA) != 0); \
- __asm__("extbl %1,%2,%0" : "=r"(__t) : "r"(__xr), "r"(__a)); \
- __a <<= 3; \
- __t &= -__t; \
- __a += ((__t & 0xCC) != 0) * 2; \
- __a += ((__t & 0xF0) != 0) * 4; \
- __a += ((__t & 0xAA) != 0); \
- (COUNT) = __a; \
- } while (0)
-#endif /* __alpha_cix__ */
-#endif /* __alpha */
-
-#if defined (__arc__) && W_TYPE_SIZE == 32
-#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
- __asm__ ("add.f %1, %4, %5\n\tadc %0, %2, %3" \
- : "=r" ((USItype) (sh)), \
- "=&r" ((USItype) (sl)) \
- : "%r" ((USItype) (ah)), \
- "rIJ" ((USItype) (bh)), \
- "%r" ((USItype) (al)), \
- "rIJ" ((USItype) (bl)))
-#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- __asm__ ("sub.f %1, %4, %5\n\tsbc %0, %2, %3" \
- : "=r" ((USItype) (sh)), \
- "=&r" ((USItype) (sl)) \
- : "r" ((USItype) (ah)), \
- "rIJ" ((USItype) (bh)), \
- "r" ((USItype) (al)), \
- "rIJ" ((USItype) (bl)))
-/* Call libgcc routine. */
-#define umul_ppmm(w1, w0, u, v) \
-do { \
- DWunion __w; \
- __w.ll = __umulsidi3 (u, v); \
- w1 = __w.s.high; \
- w0 = __w.s.low; \
-} while (0)
-#define __umulsidi3 __umulsidi3
-UDItype __umulsidi3 (USItype, USItype);
-#endif
-
-#if defined (__arm__) && W_TYPE_SIZE == 32
-#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
- __asm__ ("adds %1, %4, %5\n\tadc %0, %2, %3" \
- : "=r" ((USItype) (sh)), \
- "=&r" ((USItype) (sl)) \
- : "%r" ((USItype) (ah)), \
- "rI" ((USItype) (bh)), \
- "%r" ((USItype) (al)), \
- "rI" ((USItype) (bl)))
-#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- __asm__ ("subs %1, %4, %5\n\tsbc %0, %2, %3" \
- : "=r" ((USItype) (sh)), \
- "=&r" ((USItype) (sl)) \
- : "r" ((USItype) (ah)), \
- "rI" ((USItype) (bh)), \
- "r" ((USItype) (al)), \
- "rI" ((USItype) (bl)))
-#define umul_ppmm(xh, xl, a, b) \
-{register USItype __t0, __t1, __t2; \
- __asm__ ("%@ Inlined umul_ppmm\n" \
- " mov %2, %5, lsr #16\n" \
- " mov %0, %6, lsr #16\n" \
- " bic %3, %5, %2, lsl #16\n" \
- " bic %4, %6, %0, lsl #16\n" \
- " mul %1, %3, %4\n" \
- " mul %4, %2, %4\n" \
- " mul %3, %0, %3\n" \
- " mul %0, %2, %0\n" \
- " adds %3, %4, %3\n" \
- " addcs %0, %0, #65536\n" \
- " adds %1, %1, %3, lsl #16\n" \
- " adc %0, %0, %3, lsr #16" \
- : "=&r" ((USItype) (xh)), \
- "=r" ((USItype) (xl)), \
- "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
- : "r" ((USItype) (a)), \
- "r" ((USItype) (b)));}
-#define UMUL_TIME 20
-#define UDIV_TIME 100
-#endif /* __arm__ */
-
-#if defined (__hppa) && W_TYPE_SIZE == 32
-#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
- __asm__ ("add %4,%5,%1\n\taddc %2,%3,%0" \
- : "=r" ((USItype) (sh)), \
- "=&r" ((USItype) (sl)) \
- : "%rM" ((USItype) (ah)), \
- "rM" ((USItype) (bh)), \
- "%rM" ((USItype) (al)), \
- "rM" ((USItype) (bl)))
-#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- __asm__ ("sub %4,%5,%1\n\tsubb %2,%3,%0" \
- : "=r" ((USItype) (sh)), \
- "=&r" ((USItype) (sl)) \
- : "rM" ((USItype) (ah)), \
- "rM" ((USItype) (bh)), \
- "rM" ((USItype) (al)), \
- "rM" ((USItype) (bl)))
-#if defined (_PA_RISC1_1)
-#define umul_ppmm(w1, w0, u, v) \
- do { \
- union \
- { \
- UDItype __f; \
- struct {USItype __w1, __w0;} __w1w0; \
- } __t; \
- __asm__ ("xmpyu %1,%2,%0" \
- : "=x" (__t.__f) \
- : "x" ((USItype) (u)), \
- "x" ((USItype) (v))); \
- (w1) = __t.__w1w0.__w1; \
- (w0) = __t.__w1w0.__w0; \
- } while (0)
-#define UMUL_TIME 8
-#else
-#define UMUL_TIME 30
-#endif
-#define UDIV_TIME 40
-#define count_leading_zeros(count, x) \
- do { \
- USItype __tmp; \
- __asm__ ( \
- "ldi 1,%0\n" \
-" extru,= %1,15,16,%%r0 ; Bits 31..16 zero?\n" \
-" extru,tr %1,15,16,%1 ; No. Shift down, skip add.\n"\
-" ldo 16(%0),%0 ; Yes. Perform add.\n" \
-" extru,= %1,23,8,%%r0 ; Bits 15..8 zero?\n" \
-" extru,tr %1,23,8,%1 ; No. Shift down, skip add.\n"\
-" ldo 8(%0),%0 ; Yes. Perform add.\n" \
-" extru,= %1,27,4,%%r0 ; Bits 7..4 zero?\n" \
-" extru,tr %1,27,4,%1 ; No. Shift down, skip add.\n"\
-" ldo 4(%0),%0 ; Yes. Perform add.\n" \
-" extru,= %1,29,2,%%r0 ; Bits 3..2 zero?\n" \
-" extru,tr %1,29,2,%1 ; No. Shift down, skip add.\n"\
-" ldo 2(%0),%0 ; Yes. Perform add.\n" \
-" extru %1,30,1,%1 ; Extract bit 1.\n" \
-" sub %0,%1,%0 ; Subtract it.\n" \
- : "=r" (count), "=r" (__tmp) : "1" (x)); \
- } while (0)
-#endif
-
-#if (defined (__i370__) || defined (__mvs__)) && W_TYPE_SIZE == 32
-#define umul_ppmm(xh, xl, m0, m1) \
- do { \
- union {UDItype __ll; \
- struct {USItype __h, __l;} __i; \
- } __xx; \
- USItype __m0 = (m0), __m1 = (m1); \
- __asm__ ("mr %0,%3" \
- : "=r" (__xx.__i.__h), \
- "=r" (__xx.__i.__l) \
- : "%1" (__m0), \
- "r" (__m1)); \
- (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
- (xh) += ((((SItype) __m0 >> 31) & __m1) \
- + (((SItype) __m1 >> 31) & __m0)); \
- } while (0)
-#define smul_ppmm(xh, xl, m0, m1) \
- do { \
- union {DItype __ll; \
- struct {USItype __h, __l;} __i; \
- } __xx; \
- __asm__ ("mr %0,%3" \
- : "=r" (__xx.__i.__h), \
- "=r" (__xx.__i.__l) \
- : "%1" (m0), \
- "r" (m1)); \
- (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
- } while (0)
-#define sdiv_qrnnd(q, r, n1, n0, d) \
- do { \
- union {DItype __ll; \
- struct {USItype __h, __l;} __i; \
- } __xx; \
- __xx.__i.__h = n1; __xx.__i.__l = n0; \
- __asm__ ("dr %0,%2" \
- : "=r" (__xx.__ll) \
- : "0" (__xx.__ll), "r" (d)); \
- (q) = __xx.__i.__l; (r) = __xx.__i.__h; \
- } while (0)
-#endif
-
-#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32
-#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
- __asm__ ("addl %5,%1\n\tadcl %3,%0" \
- : "=r" ((USItype) (sh)), \
- "=&r" ((USItype) (sl)) \
- : "%0" ((USItype) (ah)), \
- "g" ((USItype) (bh)), \
- "%1" ((USItype) (al)), \
- "g" ((USItype) (bl)))
-#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- __asm__ ("subl %5,%1\n\tsbbl %3,%0" \
- : "=r" ((USItype) (sh)), \
- "=&r" ((USItype) (sl)) \
- : "0" ((USItype) (ah)), \
- "g" ((USItype) (bh)), \
- "1" ((USItype) (al)), \
- "g" ((USItype) (bl)))
-#define umul_ppmm(w1, w0, u, v) \
- __asm__ ("mull %3" \
- : "=a" ((USItype) (w0)), \
- "=d" ((USItype) (w1)) \
- : "%0" ((USItype) (u)), \
- "rm" ((USItype) (v)))
-#define udiv_qrnnd(q, r, n1, n0, dv) \
- __asm__ ("divl %4" \
- : "=a" ((USItype) (q)), \
- "=d" ((USItype) (r)) \
- : "0" ((USItype) (n0)), \
- "1" ((USItype) (n1)), \
- "rm" ((USItype) (dv)))
-#define count_leading_zeros(count, x) \
- do { \
- USItype __cbtmp; \
- __asm__ ("bsrl %1,%0" \
- : "=r" (__cbtmp) : "rm" ((USItype) (x))); \
- (count) = __cbtmp ^ 31; \
- } while (0)
-#define count_trailing_zeros(count, x) \
- __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x)))
-#define UMUL_TIME 40
-#define UDIV_TIME 40
-#endif /* 80x86 */
-
-#if defined (__i960__) && W_TYPE_SIZE == 32
-#define umul_ppmm(w1, w0, u, v) \
- ({union {UDItype __ll; \
- struct {USItype __l, __h;} __i; \
- } __xx; \
- __asm__ ("emul %2,%1,%0" \
- : "=d" (__xx.__ll) \
- : "%dI" ((USItype) (u)), \
- "dI" ((USItype) (v))); \
- (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
-#define __umulsidi3(u, v) \
- ({UDItype __w; \
- __asm__ ("emul %2,%1,%0" \
- : "=d" (__w) \
- : "%dI" ((USItype) (u)), \
- "dI" ((USItype) (v))); \
- __w; })
-#endif /* __i960__ */
-
-#if defined (__M32R__) && W_TYPE_SIZE == 32
-#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
- /* The cmp clears the condition bit. */ \
- __asm__ ("cmp %0,%0\n\taddx %%5,%1\n\taddx %%3,%0" \
- : "=r" ((USItype) (sh)), \
- "=&r" ((USItype) (sl)) \
- : "%0" ((USItype) (ah)), \
- "r" ((USItype) (bh)), \
- "%1" ((USItype) (al)), \
- "r" ((USItype) (bl)) \
- : "cbit")
-#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- /* The cmp clears the condition bit. */ \
- __asm__ ("cmp %0,%0\n\tsubx %5,%1\n\tsubx %3,%0" \
- : "=r" ((USItype) (sh)), \
- "=&r" ((USItype) (sl)) \
- : "0" ((USItype) (ah)), \
- "r" ((USItype) (bh)), \
- "1" ((USItype) (al)), \
- "r" ((USItype) (bl)) \
- : "cbit")
-#endif /* __M32R__ */
-
-#if defined (__mc68000__) && W_TYPE_SIZE == 32
-#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
- __asm__ ("add%.l %5,%1\n\taddx%.l %3,%0" \
- : "=d" ((USItype) (sh)), \
- "=&d" ((USItype) (sl)) \
- : "%0" ((USItype) (ah)), \
- "d" ((USItype) (bh)), \
- "%1" ((USItype) (al)), \
- "g" ((USItype) (bl)))
-#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- __asm__ ("sub%.l %5,%1\n\tsubx%.l %3,%0" \
- : "=d" ((USItype) (sh)), \
- "=&d" ((USItype) (sl)) \
- : "0" ((USItype) (ah)), \
- "d" ((USItype) (bh)), \
- "1" ((USItype) (al)), \
- "g" ((USItype) (bl)))
-
-/* The '020, '030, '040 and CPU32 have 32x32->64 and 64/32->32q-32r. */
-#if defined (__mc68020__) || defined(mc68020) \
- || defined(__mc68030__) || defined(mc68030) \
- || defined(__mc68040__) || defined(mc68040) \
- || defined(__mcpu32__) || defined(mcpu32)
-#define umul_ppmm(w1, w0, u, v) \
- __asm__ ("mulu%.l %3,%1:%0" \
- : "=d" ((USItype) (w0)), \
- "=d" ((USItype) (w1)) \
- : "%0" ((USItype) (u)), \
- "dmi" ((USItype) (v)))
-#define UMUL_TIME 45
-#define udiv_qrnnd(q, r, n1, n0, d) \
- __asm__ ("divu%.l %4,%1:%0" \
- : "=d" ((USItype) (q)), \
- "=d" ((USItype) (r)) \
- : "0" ((USItype) (n0)), \
- "1" ((USItype) (n1)), \
- "dmi" ((USItype) (d)))
-#define UDIV_TIME 90
-#define sdiv_qrnnd(q, r, n1, n0, d) \
- __asm__ ("divs%.l %4,%1:%0" \
- : "=d" ((USItype) (q)), \
- "=d" ((USItype) (r)) \
- : "0" ((USItype) (n0)), \
- "1" ((USItype) (n1)), \
- "dmi" ((USItype) (d)))
-
-#else /* not mc68020 */
-#if !defined(__mcf5200__)
-/* %/ inserts REGISTER_PREFIX, %# inserts IMMEDIATE_PREFIX. */
-#define umul_ppmm(xh, xl, a, b) \
- __asm__ ("| Inlined umul_ppmm\n" \
- " move%.l %2,%/d0\n" \
- " move%.l %3,%/d1\n" \
- " move%.l %/d0,%/d2\n" \
- " swap %/d0\n" \
- " move%.l %/d1,%/d3\n" \
- " swap %/d1\n" \
- " move%.w %/d2,%/d4\n" \
- " mulu %/d3,%/d4\n" \
- " mulu %/d1,%/d2\n" \
- " mulu %/d0,%/d3\n" \
- " mulu %/d0,%/d1\n" \
- " move%.l %/d4,%/d0\n" \
- " eor%.w %/d0,%/d0\n" \
- " swap %/d0\n" \
- " add%.l %/d0,%/d2\n" \
- " add%.l %/d3,%/d2\n" \
- " jcc 1f\n" \
- " add%.l %#65536,%/d1\n" \
- "1: swap %/d2\n" \
- " moveq %#0,%/d0\n" \
- " move%.w %/d2,%/d0\n" \
- " move%.w %/d4,%/d2\n" \
- " move%.l %/d2,%1\n" \
- " add%.l %/d1,%/d0\n" \
- " move%.l %/d0,%0" \
- : "=g" ((USItype) (xh)), \
- "=g" ((USItype) (xl)) \
- : "g" ((USItype) (a)), \
- "g" ((USItype) (b)) \
- : "d0", "d1", "d2", "d3", "d4")
-#define UMUL_TIME 100
-#define UDIV_TIME 400
-#endif /* not mcf5200 */
-#endif /* not mc68020 */
-
-/* The '020, '030, '040 and '060 have bitfield insns. */
-#if defined (__mc68020__) || defined(mc68020) \
- || defined(__mc68030__) || defined(mc68030) \
- || defined(__mc68040__) || defined(mc68040) \
- || defined(__mc68060__) || defined(mc68060)
-#define count_leading_zeros(count, x) \
- __asm__ ("bfffo %1{%b2:%b2},%0" \
- : "=d" ((USItype) (count)) \
- : "od" ((USItype) (x)), "n" (0))
-#endif
-#endif /* mc68000 */
-
-#if defined (__m88000__) && W_TYPE_SIZE == 32
-#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
- __asm__ ("addu.co %1,%r4,%r5\n\taddu.ci %0,%r2,%r3" \
- : "=r" ((USItype) (sh)), \
- "=&r" ((USItype) (sl)) \
- : "%rJ" ((USItype) (ah)), \
- "rJ" ((USItype) (bh)), \
- "%rJ" ((USItype) (al)), \
- "rJ" ((USItype) (bl)))
-#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- __asm__ ("subu.co %1,%r4,%r5\n\tsubu.ci %0,%r2,%r3" \
- : "=r" ((USItype) (sh)), \
- "=&r" ((USItype) (sl)) \
- : "rJ" ((USItype) (ah)), \
- "rJ" ((USItype) (bh)), \
- "rJ" ((USItype) (al)), \
- "rJ" ((USItype) (bl)))
-#define count_leading_zeros(count, x) \
- do { \
- USItype __cbtmp; \
- __asm__ ("ff1 %0,%1" \
- : "=r" (__cbtmp) \
- : "r" ((USItype) (x))); \
- (count) = __cbtmp ^ 31; \
- } while (0)
-#define COUNT_LEADING_ZEROS_0 63 /* sic */
-#if defined (__mc88110__)
-#define umul_ppmm(wh, wl, u, v) \
- do { \
- union {UDItype __ll; \
- struct {USItype __h, __l;} __i; \
- } __xx; \
- __asm__ ("mulu.d %0,%1,%2" \
- : "=r" (__xx.__ll) \
- : "r" ((USItype) (u)), \
- "r" ((USItype) (v))); \
- (wh) = __xx.__i.__h; \
- (wl) = __xx.__i.__l; \
- } while (0)
-#define udiv_qrnnd(q, r, n1, n0, d) \
- ({union {UDItype __ll; \
- struct {USItype __h, __l;} __i; \
- } __xx; \
- USItype __q; \
- __xx.__i.__h = (n1); __xx.__i.__l = (n0); \
- __asm__ ("divu.d %0,%1,%2" \
- : "=r" (__q) \
- : "r" (__xx.__ll), \
- "r" ((USItype) (d))); \
- (r) = (n0) - __q * (d); (q) = __q; })
-#define UMUL_TIME 5
-#define UDIV_TIME 25
-#else
-#define UMUL_TIME 17
-#define UDIV_TIME 150
-#endif /* __mc88110__ */
-#endif /* __m88000__ */
-
-#if defined (__mips__) && W_TYPE_SIZE == 32
-#define umul_ppmm(w1, w0, u, v) \
- __asm__ ("multu %2,%3" \
- : "=l" ((USItype) (w0)), \
- "=h" ((USItype) (w1)) \
- : "d" ((USItype) (u)), \
- "d" ((USItype) (v)))
-#define UMUL_TIME 10
-#define UDIV_TIME 100
-#endif /* __mips__ */
-
-#if defined (__ns32000__) && W_TYPE_SIZE == 32
-#define umul_ppmm(w1, w0, u, v) \
- ({union {UDItype __ll; \
- struct {USItype __l, __h;} __i; \
- } __xx; \
- __asm__ ("meid %2,%0" \
- : "=g" (__xx.__ll) \
- : "%0" ((USItype) (u)), \
- "g" ((USItype) (v))); \
- (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
-#define __umulsidi3(u, v) \
- ({UDItype __w; \
- __asm__ ("meid %2,%0" \
- : "=g" (__w) \
- : "%0" ((USItype) (u)), \
- "g" ((USItype) (v))); \
- __w; })
-#define udiv_qrnnd(q, r, n1, n0, d) \
- ({union {UDItype __ll; \
- struct {USItype __l, __h;} __i; \
- } __xx; \
- __xx.__i.__h = (n1); __xx.__i.__l = (n0); \
- __asm__ ("deid %2,%0" \
- : "=g" (__xx.__ll) \
- : "0" (__xx.__ll), \
- "g" ((USItype) (d))); \
- (r) = __xx.__i.__l; (q) = __xx.__i.__h; })
-#define count_trailing_zeros(count,x) \
- do { \
- __asm__ ("ffsd %2,%0" \
- : "=r" ((USItype) (count)) \
- : "0" ((USItype) 0), \
- "r" ((USItype) (x))); \
- } while (0)
-#endif /* __ns32000__ */
-
-/* FIXME: We should test _IBMR2 here when we add assembly support for the
- system vendor compilers.
- FIXME: What's needed for gcc PowerPC VxWorks? __vxworks__ is not good
- enough, since that hits ARM and m68k too. */
-#if (defined (_ARCH_PPC) /* AIX */ \
- || defined (_ARCH_PWR) /* AIX */ \
- || defined (_ARCH_COM) /* AIX */ \
- || defined (__powerpc__) /* gcc */ \
- || defined (__POWERPC__) /* BEOS */ \
- || defined (__ppc__) /* Darwin */ \
- || defined (PPC) /* GNU/Linux, SysV */ \
- ) && W_TYPE_SIZE == 32
-#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
- do { \
- if (__builtin_constant_p (bh) && (bh) == 0) \
- __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
- else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \
- __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
- else \
- __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
- : "=r" (sh), "=&r" (sl) \
- : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \
- } while (0)
-#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- do { \
- if (__builtin_constant_p (ah) && (ah) == 0) \
- __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
- else if (__builtin_constant_p (ah) && (ah) == ~(USItype) 0) \
- __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
- else if (__builtin_constant_p (bh) && (bh) == 0) \
- __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
- else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \
- __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
- else \
- __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \
- : "=r" (sh), "=&r" (sl) \
- : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \
- } while (0)
-#define count_leading_zeros(count, x) \
- __asm__ ("{cntlz|cntlzw} %0,%1" : "=r" (count) : "r" (x))
-#define COUNT_LEADING_ZEROS_0 32
-#if defined (_ARCH_PPC) || defined (__powerpc__) || defined (__POWERPC__) \
- || defined (__ppc__) || defined (PPC) || defined (__vxworks__)
-#define umul_ppmm(ph, pl, m0, m1) \
- do { \
- USItype __m0 = (m0), __m1 = (m1); \
- __asm__ ("mulhwu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \
- (pl) = __m0 * __m1; \
- } while (0)
-#define UMUL_TIME 15
-#define smul_ppmm(ph, pl, m0, m1) \
- do { \
- SItype __m0 = (m0), __m1 = (m1); \
- __asm__ ("mulhw %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \
- (pl) = __m0 * __m1; \
- } while (0)
-#define SMUL_TIME 14
-#define UDIV_TIME 120
-#elif defined (_ARCH_PWR)
-#define UMUL_TIME 8
-#define smul_ppmm(xh, xl, m0, m1) \
- __asm__ ("mul %0,%2,%3" : "=r" (xh), "=q" (xl) : "r" (m0), "r" (m1))
-#define SMUL_TIME 4
-#define sdiv_qrnnd(q, r, nh, nl, d) \
- __asm__ ("div %0,%2,%4" : "=r" (q), "=q" (r) : "r" (nh), "1" (nl), "r" (d))
-#define UDIV_TIME 100
-#endif
-#endif /* 32-bit POWER architecture variants. */
-
-/* We should test _IBMR2 here when we add assembly support for the system
- vendor compilers. */
-#if (defined (_ARCH_PPC64) || defined (__powerpc64__)) && W_TYPE_SIZE == 64
-#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
- do { \
- if (__builtin_constant_p (bh) && (bh) == 0) \
- __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
- else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
- __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
- else \
- __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
- : "=r" (sh), "=&r" (sl) \
- : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \
- } while (0)
-#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- do { \
- if (__builtin_constant_p (ah) && (ah) == 0) \
- __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
- else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \
- __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
- else if (__builtin_constant_p (bh) && (bh) == 0) \
- __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
- else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
- __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
- : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
- else \
- __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \
- : "=r" (sh), "=&r" (sl) \
- : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \
- } while (0)
-#define count_leading_zeros(count, x) \
- __asm__ ("cntlzd %0,%1" : "=r" (count) : "r" (x))
-#define COUNT_LEADING_ZEROS_0 64
-#define umul_ppmm(ph, pl, m0, m1) \
- do { \
- UDItype __m0 = (m0), __m1 = (m1); \
- __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \
- (pl) = __m0 * __m1; \
- } while (0)
-#define UMUL_TIME 15
-#define smul_ppmm(ph, pl, m0, m1) \
- do { \
- DItype __m0 = (m0), __m1 = (m1); \
- __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \
- (pl) = __m0 * __m1; \
- } while (0)
-#define SMUL_TIME 14 /* ??? */
-#define UDIV_TIME 120 /* ??? */
-#endif /* 64-bit PowerPC. */
-
-#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32
-#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
- __asm__ ("a %1,%5\n\tae %0,%3" \
- : "=r" ((USItype) (sh)), \
- "=&r" ((USItype) (sl)) \
- : "%0" ((USItype) (ah)), \
- "r" ((USItype) (bh)), \
- "%1" ((USItype) (al)), \
- "r" ((USItype) (bl)))
-#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- __asm__ ("s %1,%5\n\tse %0,%3" \
- : "=r" ((USItype) (sh)), \
- "=&r" ((USItype) (sl)) \
- : "0" ((USItype) (ah)), \
- "r" ((USItype) (bh)), \
- "1" ((USItype) (al)), \
- "r" ((USItype) (bl)))
-#define umul_ppmm(ph, pl, m0, m1) \
- do { \
- USItype __m0 = (m0), __m1 = (m1); \
- __asm__ ( \
- "s r2,r2\n" \
-" mts r10,%2\n" \
-" m r2,%3\n" \
-" m r2,%3\n" \
-" m r2,%3\n" \
-" m r2,%3\n" \
-" m r2,%3\n" \
-" m r2,%3\n" \
-" m r2,%3\n" \
-" m r2,%3\n" \
-" m r2,%3\n" \
-" m r2,%3\n" \
-" m r2,%3\n" \
-" m r2,%3\n" \
-" m r2,%3\n" \
-" m r2,%3\n" \
-" m r2,%3\n" \
-" m r2,%3\n" \
-" cas %0,r2,r0\n" \
-" mfs r10,%1" \
- : "=r" ((USItype) (ph)), \
- "=r" ((USItype) (pl)) \
- : "%r" (__m0), \
- "r" (__m1) \
- : "r2"); \
- (ph) += ((((SItype) __m0 >> 31) & __m1) \
- + (((SItype) __m1 >> 31) & __m0)); \
- } while (0)
-#define UMUL_TIME 20
-#define UDIV_TIME 200
-#define count_leading_zeros(count, x) \
- do { \
- if ((x) >= 0x10000) \
- __asm__ ("clz %0,%1" \
- : "=r" ((USItype) (count)) \
- : "r" ((USItype) (x) >> 16)); \
- else \
- { \
- __asm__ ("clz %0,%1" \
- : "=r" ((USItype) (count)) \
- : "r" ((USItype) (x))); \
- (count) += 16; \
- } \
- } while (0)
-#endif
-
-#if defined (__sh2__) && W_TYPE_SIZE == 32
-#define umul_ppmm(w1, w0, u, v) \
- __asm__ ( \
- "dmulu.l %2,%3\n\tsts macl,%1\n\tsts mach,%0" \
- : "=r" ((USItype)(w1)), \
- "=r" ((USItype)(w0)) \
- : "r" ((USItype)(u)), \
- "r" ((USItype)(v)) \
- : "macl", "mach")
-#define UMUL_TIME 5
-#endif
-
-#if defined (__SH5__) && __SHMEDIA__ && W_TYPE_SIZE == 32
-#define __umulsidi3(u,v) ((UDItype)(USItype)u*(USItype)v)
-#define count_leading_zeros(count, x) \
- do \
- { \
- UDItype x_ = (USItype)(x); \
- SItype c_; \
- \
- __asm__ ("nsb %1, %0" : "=r" (c_) : "r" (x_)); \
- (count) = c_ - 31; \
- } \
- while (0)
-#define COUNT_LEADING_ZEROS_0 32
-#endif
-
-#if defined (__sparc__) && !defined (__arch64__) && !defined (__sparcv9) \
- && W_TYPE_SIZE == 32
-#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
- __asm__ ("addcc %r4,%5,%1\n\taddx %r2,%3,%0" \
- : "=r" ((USItype) (sh)), \
- "=&r" ((USItype) (sl)) \
- : "%rJ" ((USItype) (ah)), \
- "rI" ((USItype) (bh)), \
- "%rJ" ((USItype) (al)), \
- "rI" ((USItype) (bl)) \
- __CLOBBER_CC)
-#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- __asm__ ("subcc %r4,%5,%1\n\tsubx %r2,%3,%0" \
- : "=r" ((USItype) (sh)), \
- "=&r" ((USItype) (sl)) \
- : "rJ" ((USItype) (ah)), \
- "rI" ((USItype) (bh)), \
- "rJ" ((USItype) (al)), \
- "rI" ((USItype) (bl)) \
- __CLOBBER_CC)
-#if defined (__sparc_v8__)
-#define umul_ppmm(w1, w0, u, v) \
- __asm__ ("umul %2,%3,%1;rd %%y,%0" \
- : "=r" ((USItype) (w1)), \
- "=r" ((USItype) (w0)) \
- : "r" ((USItype) (u)), \
- "r" ((USItype) (v)))
-#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \
- __asm__ ("mov %2,%%y;nop;nop;nop;udiv %3,%4,%0;umul %0,%4,%1;sub %3,%1,%1"\
- : "=&r" ((USItype) (__q)), \
- "=&r" ((USItype) (__r)) \
- : "r" ((USItype) (__n1)), \
- "r" ((USItype) (__n0)), \
- "r" ((USItype) (__d)))
-#else
-#if defined (__sparclite__)
-/* This has hardware multiply but not divide. It also has two additional
- instructions scan (ffs from high bit) and divscc. */
-#define umul_ppmm(w1, w0, u, v) \
- __asm__ ("umul %2,%3,%1;rd %%y,%0" \
- : "=r" ((USItype) (w1)), \
- "=r" ((USItype) (w0)) \
- : "r" ((USItype) (u)), \
- "r" ((USItype) (v)))
-#define udiv_qrnnd(q, r, n1, n0, d) \
- __asm__ ("! Inlined udiv_qrnnd\n" \
-" wr %%g0,%2,%%y ! Not a delayed write for sparclite\n" \
-" tst %%g0\n" \
-" divscc %3,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%%g1\n" \
-" divscc %%g1,%4,%0\n" \
-" rd %%y,%1\n" \
-" bl,a 1f\n" \
-" add %1,%4,%1\n" \
-"1: ! End of inline udiv_qrnnd" \
- : "=r" ((USItype) (q)), \
- "=r" ((USItype) (r)) \
- : "r" ((USItype) (n1)), \
- "r" ((USItype) (n0)), \
- "rI" ((USItype) (d)) \
- : "g1" __AND_CLOBBER_CC)
-#define UDIV_TIME 37
-#define count_leading_zeros(count, x) \
- do { \
- __asm__ ("scan %1,1,%0" \
- : "=r" ((USItype) (count)) \
- : "r" ((USItype) (x))); \
- } while (0)
-/* Early sparclites return 63 for an argument of 0, but they warn that future
- implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0
- undefined. */
-#else
-/* SPARC without integer multiplication and divide instructions.
- (i.e. at least Sun4/20,40,60,65,75,110,260,280,330,360,380,470,490) */
-#define umul_ppmm(w1, w0, u, v) \
- __asm__ ("! Inlined umul_ppmm\n" \
-" wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr\n"\
-" sra %3,31,%%o5 ! Don't move this insn\n" \
-" and %2,%%o5,%%o5 ! Don't move this insn\n" \
-" andcc %%g0,0,%%g1 ! Don't move this insn\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,%3,%%g1\n" \
-" mulscc %%g1,0,%%g1\n" \
-" add %%g1,%%o5,%0\n" \
-" rd %%y,%1" \
- : "=r" ((USItype) (w1)), \
- "=r" ((USItype) (w0)) \
- : "%rI" ((USItype) (u)), \
- "r" ((USItype) (v)) \
- : "g1", "o5" __AND_CLOBBER_CC)
-#define UMUL_TIME 39 /* 39 instructions */
-/* It's quite necessary to add this much assembler for the sparc.
- The default udiv_qrnnd (in C) is more than 10 times slower! */
-#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \
- __asm__ ("! Inlined udiv_qrnnd\n" \
-" mov 32,%%g1\n" \
-" subcc %1,%2,%%g0\n" \
-"1: bcs 5f\n" \
-" addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n" \
-" sub %1,%2,%1 ! this kills msb of n\n" \
-" addx %1,%1,%1 ! so this can't give carry\n" \
-" subcc %%g1,1,%%g1\n" \
-"2: bne 1b\n" \
-" subcc %1,%2,%%g0\n" \
-" bcs 3f\n" \
-" addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n" \
-" b 3f\n" \
-" sub %1,%2,%1 ! this kills msb of n\n" \
-"4: sub %1,%2,%1\n" \
-"5: addxcc %1,%1,%1\n" \
-" bcc 2b\n" \
-" subcc %%g1,1,%%g1\n" \
-"! Got carry from n. Subtract next step to cancel this carry.\n" \
-" bne 4b\n" \
-" addcc %0,%0,%0 ! shift n1n0 and a 0-bit in lsb\n" \
-" sub %1,%2,%1\n" \
-"3: xnor %0,0,%0\n" \
-" ! End of inline udiv_qrnnd" \
- : "=&r" ((USItype) (__q)), \
- "=&r" ((USItype) (__r)) \
- : "r" ((USItype) (__d)), \
- "1" ((USItype) (__n1)), \
- "0" ((USItype) (__n0)) : "g1" __AND_CLOBBER_CC)
-#define UDIV_TIME (3+7*32) /* 7 instructions/iteration. 32 iterations. */
-#endif /* __sparclite__ */
-#endif /* __sparc_v8__ */
-#endif /* sparc32 */
-
-#if ((defined (__sparc__) && defined (__arch64__)) || defined (__sparcv9)) \
- && W_TYPE_SIZE == 64
-#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
- __asm__ ("addcc %r4,%5,%1\n\t" \
- "add %r2,%3,%0\n\t" \
- "bcs,a,pn %%xcc, 1f\n\t" \
- "add %0, 1, %0\n" \
- "1:" \
- : "=r" ((UDItype)(sh)), \
- "=&r" ((UDItype)(sl)) \
- : "%rJ" ((UDItype)(ah)), \
- "rI" ((UDItype)(bh)), \
- "%rJ" ((UDItype)(al)), \
- "rI" ((UDItype)(bl)) \
- __CLOBBER_CC)
-
-#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- __asm__ ("subcc %r4,%5,%1\n\t" \
- "sub %r2,%3,%0\n\t" \
- "bcs,a,pn %%xcc, 1f\n\t" \
- "sub %0, 1, %0\n\t" \
- "1:" \
- : "=r" ((UDItype)(sh)), \
- "=&r" ((UDItype)(sl)) \
- : "rJ" ((UDItype)(ah)), \
- "rI" ((UDItype)(bh)), \
- "rJ" ((UDItype)(al)), \
- "rI" ((UDItype)(bl)) \
- __CLOBBER_CC)
-
-#define umul_ppmm(wh, wl, u, v) \
- do { \
- UDItype tmp1, tmp2, tmp3, tmp4; \
- __asm__ __volatile__ ( \
- "srl %7,0,%3\n\t" \
- "mulx %3,%6,%1\n\t" \
- "srlx %6,32,%2\n\t" \
- "mulx %2,%3,%4\n\t" \
- "sllx %4,32,%5\n\t" \
- "srl %6,0,%3\n\t" \
- "sub %1,%5,%5\n\t" \
- "srlx %5,32,%5\n\t" \
- "addcc %4,%5,%4\n\t" \
- "srlx %7,32,%5\n\t" \
- "mulx %3,%5,%3\n\t" \
- "mulx %2,%5,%5\n\t" \
- "sethi %%hi(0x80000000),%2\n\t" \
- "addcc %4,%3,%4\n\t" \
- "srlx %4,32,%4\n\t" \
- "add %2,%2,%2\n\t" \
- "movcc %%xcc,%%g0,%2\n\t" \
- "addcc %5,%4,%5\n\t" \
- "sllx %3,32,%3\n\t" \
- "add %1,%3,%1\n\t" \
- "add %5,%2,%0" \
- : "=r" ((UDItype)(wh)), \
- "=&r" ((UDItype)(wl)), \
- "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4) \
- : "r" ((UDItype)(u)), \
- "r" ((UDItype)(v)) \
- __CLOBBER_CC); \
- } while (0)
-#define UMUL_TIME 96
-#define UDIV_TIME 230
-#endif /* sparc64 */
-
-#if defined (__vax__) && W_TYPE_SIZE == 32
-#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
- __asm__ ("addl2 %5,%1\n\tadwc %3,%0" \
- : "=g" ((USItype) (sh)), \
- "=&g" ((USItype) (sl)) \
- : "%0" ((USItype) (ah)), \
- "g" ((USItype) (bh)), \
- "%1" ((USItype) (al)), \
- "g" ((USItype) (bl)))
-#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- __asm__ ("subl2 %5,%1\n\tsbwc %3,%0" \
- : "=g" ((USItype) (sh)), \
- "=&g" ((USItype) (sl)) \
- : "0" ((USItype) (ah)), \
- "g" ((USItype) (bh)), \
- "1" ((USItype) (al)), \
- "g" ((USItype) (bl)))
-#define umul_ppmm(xh, xl, m0, m1) \
- do { \
- union { \
- UDItype __ll; \
- struct {USItype __l, __h;} __i; \
- } __xx; \
- USItype __m0 = (m0), __m1 = (m1); \
- __asm__ ("emul %1,%2,$0,%0" \
- : "=r" (__xx.__ll) \
- : "g" (__m0), \
- "g" (__m1)); \
- (xh) = __xx.__i.__h; \
- (xl) = __xx.__i.__l; \
- (xh) += ((((SItype) __m0 >> 31) & __m1) \
- + (((SItype) __m1 >> 31) & __m0)); \
- } while (0)
-#define sdiv_qrnnd(q, r, n1, n0, d) \
- do { \
- union {DItype __ll; \
- struct {SItype __l, __h;} __i; \
- } __xx; \
- __xx.__i.__h = n1; __xx.__i.__l = n0; \
- __asm__ ("ediv %3,%2,%0,%1" \
- : "=g" (q), "=g" (r) \
- : "g" (__xx.__ll), "g" (d)); \
- } while (0)
-#endif /* __vax__ */
-
-#if defined (__z8000__) && W_TYPE_SIZE == 16
-#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
- __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \
- : "=r" ((unsigned int)(sh)), \
- "=&r" ((unsigned int)(sl)) \
- : "%0" ((unsigned int)(ah)), \
- "r" ((unsigned int)(bh)), \
- "%1" ((unsigned int)(al)), \
- "rQR" ((unsigned int)(bl)))
-#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \
- : "=r" ((unsigned int)(sh)), \
- "=&r" ((unsigned int)(sl)) \
- : "0" ((unsigned int)(ah)), \
- "r" ((unsigned int)(bh)), \
- "1" ((unsigned int)(al)), \
- "rQR" ((unsigned int)(bl)))
-#define umul_ppmm(xh, xl, m0, m1) \
- do { \
- union {long int __ll; \
- struct {unsigned int __h, __l;} __i; \
- } __xx; \
- unsigned int __m0 = (m0), __m1 = (m1); \
- __asm__ ("mult %S0,%H3" \
- : "=r" (__xx.__i.__h), \
- "=r" (__xx.__i.__l) \
- : "%1" (__m0), \
- "rQR" (__m1)); \
- (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
- (xh) += ((((signed int) __m0 >> 15) & __m1) \
- + (((signed int) __m1 >> 15) & __m0)); \
- } while (0)
-#endif /* __z8000__ */
-
-#endif /* __GNUC__ */
-
-/* If this machine has no inline assembler, use C macros. */
-
-#if !defined (add_ssaaaa)
-#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
- do { \
- UWtype __x; \
- __x = (al) + (bl); \
- (sh) = (ah) + (bh) + (__x < (al)); \
- (sl) = __x; \
- } while (0)
-#endif
-
-#if !defined (sub_ddmmss)
-#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- do { \
- UWtype __x; \
- __x = (al) - (bl); \
- (sh) = (ah) - (bh) - (__x > (al)); \
- (sl) = __x; \
- } while (0)
-#endif
-
-#if !defined (umul_ppmm)
-#define umul_ppmm(w1, w0, u, v) \
- do { \
- UWtype __x0, __x1, __x2, __x3; \
- UHWtype __ul, __vl, __uh, __vh; \
- \
- __ul = __ll_lowpart (u); \
- __uh = __ll_highpart (u); \
- __vl = __ll_lowpart (v); \
- __vh = __ll_highpart (v); \
- \
- __x0 = (UWtype) __ul * __vl; \
- __x1 = (UWtype) __ul * __vh; \
- __x2 = (UWtype) __uh * __vl; \
- __x3 = (UWtype) __uh * __vh; \
- \
- __x1 += __ll_highpart (__x0);/* this can't give carry */ \
- __x1 += __x2; /* but this indeed can */ \
- if (__x1 < __x2) /* did we get it? */ \
- __x3 += __ll_B; /* yes, add it in the proper pos. */ \
- \
- (w1) = __x3 + __ll_highpart (__x1); \
- (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \
- } while (0)
-#endif
-
-#if !defined (__umulsidi3)
-#define __umulsidi3(u, v) \
- ({DWunion __w; \
- umul_ppmm (__w.s.high, __w.s.low, u, v); \
- __w.ll; })
-#endif
-
-/* Define this unconditionally, so it can be used for debugging. */
-#define __udiv_qrnnd_c(q, r, n1, n0, d) \
- do { \
- UWtype __d1, __d0, __q1, __q0; \
- UWtype __r1, __r0, __m; \
- __d1 = __ll_highpart (d); \
- __d0 = __ll_lowpart (d); \
- \
- __r1 = (n1) % __d1; \
- __q1 = (n1) / __d1; \
- __m = (UWtype) __q1 * __d0; \
- __r1 = __r1 * __ll_B | __ll_highpart (n0); \
- if (__r1 < __m) \
- { \
- __q1--, __r1 += (d); \
- if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
- if (__r1 < __m) \
- __q1--, __r1 += (d); \
- } \
- __r1 -= __m; \
- \
- __r0 = __r1 % __d1; \
- __q0 = __r1 / __d1; \
- __m = (UWtype) __q0 * __d0; \
- __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
- if (__r0 < __m) \
- { \
- __q0--, __r0 += (d); \
- if (__r0 >= (d)) \
- if (__r0 < __m) \
- __q0--, __r0 += (d); \
- } \
- __r0 -= __m; \
- \
- (q) = (UWtype) __q1 * __ll_B | __q0; \
- (r) = __r0; \
- } while (0)
-
-/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through
- __udiv_w_sdiv (defined in libgcc or elsewhere). */
-#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd)
-#define udiv_qrnnd(q, r, nh, nl, d) \
- do { \
- USItype __r; \
- (q) = __udiv_w_sdiv (&__r, nh, nl, d); \
- (r) = __r; \
- } while (0)
-#endif
-
-/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */
-#if !defined (udiv_qrnnd)
-#define UDIV_NEEDS_NORMALIZATION 1
-#define udiv_qrnnd __udiv_qrnnd_c
-#endif
-
-#if !defined (count_leading_zeros)
-extern const UQItype __clz_tab[];
-#define count_leading_zeros(count, x) \
- do { \
- UWtype __xr = (x); \
- UWtype __a; \
- \
- if (W_TYPE_SIZE <= 32) \
- { \
- __a = __xr < ((UWtype)1<<2*__BITS4) \
- ? (__xr < ((UWtype)1<<__BITS4) ? 0 : __BITS4) \
- : (__xr < ((UWtype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \
- } \
- else \
- { \
- for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \
- if (((__xr >> __a) & 0xff) != 0) \
- break; \
- } \
- \
- (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \
- } while (0)
-#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE
-#endif
-
-#if !defined (count_trailing_zeros)
-/* Define count_trailing_zeros using count_leading_zeros. The latter might be
- defined in asm, but if it is not, the C version above is good enough. */
-#define count_trailing_zeros(count, x) \
- do { \
- UWtype __ctz_x = (x); \
- UWtype __ctz_c; \
- count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \
- (count) = W_TYPE_SIZE - 1 - __ctz_c; \
- } while (0)
-#endif
-
-#ifndef UDIV_NEEDS_NORMALIZATION
-#define UDIV_NEEDS_NORMALIZATION 0
-#endif
+++ /dev/null
-#! /bin/sh
-
-# Generate exports symbol table from C files
-
-input="$1"
-output="$2"
-exports=$(basename "$output" .h)
-exec >"$output"
-
-echo "/* automatically generated from src */";
-
-sed -n -e '/^\(wstdcall\|wfastcall\|noregparm\|__attribute__\)/{
-:more
-N
-s/\([^{]\)$/\1/
-t more
-s/\n{$/;/
-p
-}' $input
-
-echo "#ifdef CONFIG_X86_64";
-
-sed -n \
- -e 's/.*WIN_FUNC(\([^\,]\+\) *\, *\([0-9]\+\)).*/'\
-'WIN_FUNC_DECL(\1, \2)/p' \
- -e 's/.*WIN_FUNC_PTR(\([^\,]\+\) *\, *\([0-9]\+\)).*/'\
-'WIN_FUNC_DECL(\1, \2)/p' $input | sort -u
-
-echo "#endif"
-echo "extern struct wrap_export $exports[];"
-echo "struct wrap_export $exports[] = {"
-
-sed -n \
- -e 's/.*WIN_FUNC(_win_\([^\,]\+\) *\, *\([0-9]\+\)).*/'\
-' WIN_WIN_SYMBOL(\1, \2),/p' \
- -e 's/.*WIN_FUNC(\([^\,]\+\) *\, *\([0-9]\+\)).*/'\
-' WIN_SYMBOL(\1, \2),/p' \
- -e 's/.*WIN_SYMBOL_MAP(\("[^"]\+"\)[ ,\n]\+\([^)]\+\)).*/'\
-' {\1, (generic_func)\2},/p' $input | sort -u
-
-echo " {NULL, NULL}"
-echo "};"
+++ /dev/null
-#! /bin/sh
-
-for file in "$@"; do
- echo
- echo "# automatically generated from $file"
- sed -n \
- -e 's/.*WIN_FUNC(\([^\,]\+\) *\, *\([0-9]\+\)).*/\
- win2lin(\1, \2)/p' \
- -e 's/.*WIN_FUNC_PTR(\([^\,]\+\) *\, *\([0-9]\+\)).*/\
- win2lin(\1, \2)/p' \
- $file | sed -e 's/[ \t ]\+//' | sort -u; \
-done
+++ /dev/null
-/*
- * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include "ndis.h"
-#include "iw_ndis.h"
-#include "wrapndis.h"
-#include "pnp.h"
-#include "loader.h"
-#include <linux/kernel_stat.h>
-#include <asm/dma.h>
-#include "ndis_exports.h"
-
-#define MAX_ALLOCATED_NDIS_PACKETS TX_RING_SIZE
-#define MAX_ALLOCATED_NDIS_BUFFERS TX_RING_SIZE
-
-static void ndis_worker(worker_param_t dummy);
-static work_struct_t ndis_work;
-static struct nt_list ndis_work_list;
-static spinlock_t ndis_work_list_lock;
-
-workqueue_struct_t *ndis_wq;
-static struct nt_thread *ndis_worker_thread;
-
-static void *ndis_get_routine_address(char *name);
-
-wstdcall void WIN_FUNC(NdisInitializeWrapper,4)
- (void **driver_handle, struct driver_object *driver,
- struct unicode_string *reg_path, void *unused)
-{
- ENTER1("handle: %p, driver: %p", driver_handle, driver);
- *driver_handle = driver;
- EXIT1(return);
-}
-
-wstdcall void WIN_FUNC(NdisTerminateWrapper,2)
- (struct device_object *dev_obj, void *system_specific)
-{
- EXIT1(return);
-}
-
-wstdcall NDIS_STATUS WIN_FUNC(NdisMRegisterMiniport,3)
- (struct driver_object *drv_obj, struct miniport *mp, UINT length)
-{
- int min_length;
- struct wrap_driver *wrap_driver;
- struct ndis_driver *ndis_driver;
-
- min_length = ((char *)&mp->co_create_vc) - ((char *)mp);
-
- ENTER1("%p %p %d", drv_obj, mp, length);
-
- if (mp->major_version < 4) {
- ERROR("Driver is using ndis version %d which is too old.",
- mp->major_version);
- EXIT1(return NDIS_STATUS_BAD_VERSION);
- }
-
- if (length < min_length) {
- ERROR("Characteristics length %d is too small", length);
- EXIT1(return NDIS_STATUS_BAD_CHARACTERISTICS);
- }
-
- TRACE1("%d.%d, %d, %u", mp->major_version, mp->minor_version, length,
- (u32)sizeof(struct miniport));
- wrap_driver = IoGetDriverObjectExtension(drv_obj,
- (void *)WRAP_DRIVER_CLIENT_ID);
- if (!wrap_driver) {
- ERROR("couldn't get wrap_driver");
- EXIT1(return NDIS_STATUS_RESOURCES);
- }
- if (IoAllocateDriverObjectExtension(
- drv_obj, (void *)NDIS_DRIVER_CLIENT_ID,
- sizeof(*ndis_driver), (void **)&ndis_driver) !=
- STATUS_SUCCESS)
- EXIT1(return NDIS_STATUS_RESOURCES);
- wrap_driver->ndis_driver = ndis_driver;
- TRACE1("driver: %p", ndis_driver);
- memcpy(&ndis_driver->mp, mp, min_t(int, sizeof(*mp), length));
-
- DBG_BLOCK(2) {
- int i;
- void **func;
- char *mp_funcs[] = {
- "queryinfo", "reconfig", "reset", "send", "setinfo",
- "tx_data", "return_packet", "send_packets",
- "alloc_complete", "co_create_vc", "co_delete_vc",
- "co_activate_vc", "co_deactivate_vc",
- "co_send_packets", "co_request", "cancel_send_packets",
- "pnp_event_notify", "shutdown",
- };
- func = (void **)&ndis_driver->mp.queryinfo;
- for (i = 0; i < (sizeof(mp_funcs) / sizeof(mp_funcs[0])); i++)
- TRACE2("function '%s' is at %p", mp_funcs[i], func[i]);
- }
- EXIT1(return NDIS_STATUS_SUCCESS);
-}
-
-wstdcall NDIS_STATUS WIN_FUNC(NdisMRegisterDevice,6)
- (struct driver_object *drv_obj, struct unicode_string *dev_name,
- struct unicode_string *link, void **funcs,
- struct device_object **dev_obj, void **dev_obj_handle)
-{
- NTSTATUS status;
- struct device_object *tmp;
- int i;
-
- ENTER1("%p, %p, %p", drv_obj, dev_name, link);
- status = IoCreateDevice(drv_obj, 0, dev_name, FILE_DEVICE_NETWORK, 0,
- FALSE, &tmp);
-
- if (status != STATUS_SUCCESS)
- EXIT1(return NDIS_STATUS_RESOURCES);
- if (link)
- status = IoCreateSymbolicLink(link, dev_name);
- if (status != STATUS_SUCCESS) {
- IoDeleteDevice(tmp);
- EXIT1(return NDIS_STATUS_RESOURCES);
- }
-
- *dev_obj = tmp;
- *dev_obj_handle = *dev_obj;
- for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
- if (funcs[i] && i != IRP_MJ_PNP && i != IRP_MJ_POWER) {
- drv_obj->major_func[i] = funcs[i];
- TRACE1("mj_fn for 0x%x is at %p", i, funcs[i]);
- }
- EXIT1(return NDIS_STATUS_SUCCESS);
-}
-
-wstdcall NDIS_STATUS WIN_FUNC(NdisMDeregisterDevice,1)
- (struct device_object *dev_obj)
-{
- ENTER2("%p", dev_obj);
- IoDeleteDevice(dev_obj);
- return NDIS_STATUS_SUCCESS;
-}
-
-wstdcall NDIS_STATUS WIN_FUNC(NdisAllocateMemoryWithTag,3)
- (void **dest, UINT length, ULONG tag)
-{
- void *addr;
-
- assert_irql(_irql_ <= DISPATCH_LEVEL);
- addr = ExAllocatePoolWithTag(NonPagedPool, length, tag);
- TRACE4("%p", addr);
- if (addr) {
- *dest = addr;
- EXIT4(return NDIS_STATUS_SUCCESS);
- } else
- EXIT4(return NDIS_STATUS_FAILURE);
-}
-
-wstdcall NDIS_STATUS WIN_FUNC(NdisAllocateMemory,4)
- (void **dest, UINT length, UINT flags, NDIS_PHY_ADDRESS highest_address)
-{
- return NdisAllocateMemoryWithTag(dest, length, 0);
-}
-
-/* length_tag is either length or tag, depending on if
- * NdisAllocateMemory or NdisAllocateMemoryTag is used to allocate
- * memory */
-wstdcall void WIN_FUNC(NdisFreeMemory,3)
- (void *addr, UINT length_tag, UINT flags)
-{
- TRACE4("%p", addr);
- ExFreePool(addr);
-}
-
-noregparm void WIN_FUNC(NdisWriteErrorLogEntry,12)
- (struct driver_object *drv_obj, ULONG error, ULONG count, ...)
-{
- va_list args;
- int i;
- ULONG code;
-
- va_start(args, count);
- ERROR("log: %08X, count: %d, return_address: %p",
- error, count, __builtin_return_address(0));
- for (i = 0; i < count; i++) {
- code = va_arg(args, ULONG);
- ERROR("code: 0x%x", code);
- }
- va_end(args);
- EXIT2(return);
-}
-
-wstdcall void WIN_FUNC(NdisOpenConfiguration,3)
- (NDIS_STATUS *status, struct ndis_mp_block **conf_handle,
- struct ndis_mp_block *handle)
-{
- ENTER2("%p", conf_handle);
- *conf_handle = handle;
- *status = NDIS_STATUS_SUCCESS;
- EXIT2(return);
-}
-
-wstdcall void WIN_FUNC(NdisOpenProtocolConfiguration,3)
- (NDIS_STATUS *status, void **confhandle,
- struct unicode_string *section)
-{
- ENTER2("%p", confhandle);
- *status = NDIS_STATUS_SUCCESS;
- EXIT2(return);
-}
-
-wstdcall void WIN_FUNC(NdisOpenConfigurationKeyByName,4)
- (NDIS_STATUS *status, void *handle,
- struct unicode_string *key, void **subkeyhandle)
-{
- struct ansi_string ansi;
- ENTER2("");
- if (RtlUnicodeStringToAnsiString(&ansi, key, TRUE) == STATUS_SUCCESS) {
- TRACE2("%s", ansi.buf);
- RtlFreeAnsiString(&ansi);
- }
- *subkeyhandle = handle;
- *status = NDIS_STATUS_SUCCESS;
- EXIT2(return);
-}
-
-wstdcall void WIN_FUNC(NdisOpenConfigurationKeyByIndex,5)
- (NDIS_STATUS *status, void *handle, ULONG index,
- struct unicode_string *key, void **subkeyhandle)
-{
- ENTER2("%u", index);
-// *subkeyhandle = handle;
- *status = NDIS_STATUS_FAILURE;
- EXIT2(return);
-}
-
-wstdcall void WIN_FUNC(NdisCloseConfiguration,1)
- (void *handle)
-{
- /* instead of freeing all configuration parameters as we are
- * supposed to do here, we free them when the device is
- * removed */
- ENTER2("%p", handle);
- return;
-}
-
-wstdcall void WIN_FUNC(NdisOpenFile,5)
- (NDIS_STATUS *status, struct wrap_bin_file **file,
- UINT *filelength, struct unicode_string *filename,
- NDIS_PHY_ADDRESS highest_address)
-{
- struct ansi_string ansi;
- struct wrap_bin_file *bin_file;
-
- ENTER2("%p, %d, %llx, %p", status, *filelength, highest_address, *file);
- if (RtlUnicodeStringToAnsiString(&ansi, filename, TRUE) !=
- STATUS_SUCCESS) {
- *status = NDIS_STATUS_RESOURCES;
- EXIT2(return);
- }
- TRACE2("%s", ansi.buf);
- bin_file = get_bin_file(ansi.buf);
- if (bin_file) {
- *file = bin_file;
- *filelength = bin_file->size;
- *status = NDIS_STATUS_SUCCESS;
- } else
- *status = NDIS_STATUS_FILE_NOT_FOUND;
-
- RtlFreeAnsiString(&ansi);
- EXIT2(return);
-}
-
-wstdcall void WIN_FUNC(NdisMapFile,3)
- (NDIS_STATUS *status, void **mappedbuffer, struct wrap_bin_file *file)
-{
- ENTER2("%p", file);
-
- if (!file) {
- *status = NDIS_STATUS_ALREADY_MAPPED;
- EXIT2(return);
- }
-
- *status = NDIS_STATUS_SUCCESS;
- *mappedbuffer = file->data;
- EXIT2(return);
-}
-
-wstdcall void WIN_FUNC(NdisUnmapFile,1)
- (struct wrap_bin_file *file)
-{
- ENTER2("%p", file);
- EXIT2(return);
-}
-
-wstdcall void WIN_FUNC(NdisCloseFile,1)
- (struct wrap_bin_file *file)
-{
- ENTER2("%p", file);
- free_bin_file(file);
- EXIT2(return);
-}
-
-wstdcall void WIN_FUNC(NdisGetSystemUpTime,1)
- (ULONG *ms)
-{
- *ms = 1000 * jiffies / HZ;
- EXIT5(return);
-}
-
-wstdcall ULONG WIN_FUNC(NDIS_BUFFER_TO_SPAN_PAGES,1)
- (ndis_buffer *buffer)
-{
- ULONG n, length;
-
- if (buffer == NULL)
- EXIT2(return 0);
- if (MmGetMdlByteCount(buffer) == 0)
- EXIT2(return 1);
-
- length = MmGetMdlByteCount(buffer);
- n = SPAN_PAGES(MmGetMdlVirtualAddress(buffer), length);
- TRACE4("%p, %p, %d, %d", buffer->startva, buffer->mappedsystemva,
- length, n);
- EXIT3(return n);
-}
-
-wstdcall void WIN_FUNC(NdisGetBufferPhysicalArraySize,2)
- (ndis_buffer *buffer, UINT *arraysize)
-{
- ENTER3("%p", buffer);
- *arraysize = NDIS_BUFFER_TO_SPAN_PAGES(buffer);
- EXIT3(return);
-}
-
-static struct ndis_configuration_parameter *
-ndis_encode_setting(struct wrap_device_setting *setting,
- enum ndis_parameter_type type)
-{
- struct ansi_string ansi;
- struct ndis_configuration_parameter *param;
-
- param = setting->encoded;
- if (param) {
- if (param->type == type)
- EXIT2(return param);
- if (param->type == NdisParameterString)
- RtlFreeUnicodeString(¶m->data.string);
- setting->encoded = NULL;
- } else
- param = ExAllocatePoolWithTag(NonPagedPool, sizeof(*param), 0);
- if (!param) {
- ERROR("couldn't allocate memory");
- return NULL;
- }
- switch(type) {
- case NdisParameterInteger:
- param->data.integer = simple_strtol(setting->value, NULL, 0);
- TRACE2("0x%x", (ULONG)param->data.integer);
- break;
- case NdisParameterHexInteger:
- param->data.integer = simple_strtol(setting->value, NULL, 16);
- TRACE2("0x%x", (ULONG)param->data.integer);
- break;
- case NdisParameterString:
- RtlInitAnsiString(&ansi, setting->value);
- TRACE2("'%s'", ansi.buf);
- if (RtlAnsiStringToUnicodeString(¶m->data.string,
- &ansi, TRUE)) {
- ExFreePool(param);
- EXIT2(return NULL);
- }
- break;
- case NdisParameterBinary:
- param->data.integer = simple_strtol(setting->value, NULL, 2);
- TRACE2("0x%x", (ULONG)param->data.integer);
- break;
- default:
- ERROR("unknown type: %d", type);
- ExFreePool(param);
- return NULL;
- }
- param->type = type;
- setting->encoded = param;
- EXIT2(return param);
-}
-
-static int ndis_decode_setting(struct wrap_device_setting *setting,
- struct ndis_configuration_parameter *param)
-{
- struct ansi_string ansi;
- struct ndis_configuration_parameter *prev;
-
- ENTER2("%p, %p", setting, param);
- prev = setting->encoded;
- if (prev && prev->type == NdisParameterString) {
- RtlFreeUnicodeString(&prev->data.string);
- setting->encoded = NULL;
- }
- switch(param->type) {
- case NdisParameterInteger:
- snprintf(setting->value, sizeof(u32), "%u",
- param->data.integer);
- setting->value[sizeof(ULONG)] = 0;
- break;
- case NdisParameterHexInteger:
- snprintf(setting->value, sizeof(u32), "%x",
- param->data.integer);
- setting->value[sizeof(ULONG)] = 0;
- break;
- case NdisParameterString:
- ansi.buf = setting->value;
- ansi.max_length = MAX_SETTING_VALUE_LEN;
- if ((RtlUnicodeStringToAnsiString(&ansi, ¶m->data.string,
- FALSE) != STATUS_SUCCESS)
- || ansi.length >= MAX_SETTING_VALUE_LEN) {
- EXIT1(return -1);
- }
- if (ansi.length == ansi.max_length)
- ansi.length--;
- setting->value[ansi.length] = 0;
- break;
- case NdisParameterBinary:
- snprintf(setting->value, sizeof(u32), "%u",
- param->data.integer);
- setting->value[sizeof(ULONG)] = 0;
- break;
- default:
- TRACE2("unknown setting type: %d", param->type);
- return -1;
- }
- TRACE2("setting changed %s='%s', %d", setting->name, setting->value,
- ansi.length);
- return 0;
-}
-
-static int read_setting(struct nt_list *setting_list, char *keyname, int length,
- struct ndis_configuration_parameter **param,
- enum ndis_parameter_type type)
-{
- struct wrap_device_setting *setting;
- if (down_interruptible(&loader_mutex))
- WARNING("couldn't obtain loader_mutex");
- nt_list_for_each_entry(setting, setting_list, list) {
- if (strnicmp(keyname, setting->name, length) == 0) {
- TRACE2("setting %s='%s'", keyname, setting->value);
- up(&loader_mutex);
- *param = ndis_encode_setting(setting, type);
- if (*param)
- EXIT2(return 0);
- else
- EXIT2(return -1);
- }
- }
- up(&loader_mutex);
- EXIT2(return -1);
-}
-
-wstdcall void WIN_FUNC(NdisReadConfiguration,5)
- (NDIS_STATUS *status, struct ndis_configuration_parameter **param,
- struct ndis_mp_block *nmb, struct unicode_string *key,
- enum ndis_parameter_type type)
-{
- struct ansi_string ansi;
- int ret;
-
- ENTER2("nmb: %p", nmb);
- ret = RtlUnicodeStringToAnsiString(&ansi, key, TRUE);
- if (ret != STATUS_SUCCESS || ansi.buf == NULL) {
- *param = NULL;
- *status = NDIS_STATUS_FAILURE;
- RtlFreeAnsiString(&ansi);
- EXIT2(return);
- }
- TRACE2("%d, %s", type, ansi.buf);
-
- if (read_setting(&nmb->wnd->wd->settings, ansi.buf,
- ansi.length, param, type) == 0 ||
- read_setting(&nmb->wnd->wd->driver->settings, ansi.buf,
- ansi.length, param, type) == 0)
- *status = NDIS_STATUS_SUCCESS;
- else {
- TRACE2("setting %s not found (type:%d)", ansi.buf, type);
- *status = NDIS_STATUS_FAILURE;
- }
- RtlFreeAnsiString(&ansi);
- EXIT2(return);
-
-}
-
-wstdcall void WIN_FUNC(NdisWriteConfiguration,4)
- (NDIS_STATUS *status, struct ndis_mp_block *nmb,
- struct unicode_string *key, struct ndis_configuration_parameter *param)
-{
- struct ansi_string ansi;
- char *keyname;
- struct wrap_device_setting *setting;
-
- ENTER2("nmb: %p", nmb);
- if (RtlUnicodeStringToAnsiString(&ansi, key, TRUE)) {
- *status = NDIS_STATUS_FAILURE;
- EXIT2(return);
- }
- keyname = ansi.buf;
- TRACE2("%s", keyname);
-
- if (down_interruptible(&loader_mutex))
- WARNING("couldn't obtain loader_mutex");
- nt_list_for_each_entry(setting, &nmb->wnd->wd->settings, list) {
- if (strnicmp(keyname, setting->name, ansi.length) == 0) {
- up(&loader_mutex);
- if (ndis_decode_setting(setting, param))
- *status = NDIS_STATUS_FAILURE;
- else
- *status = NDIS_STATUS_SUCCESS;
- RtlFreeAnsiString(&ansi);
- EXIT2(return);
- }
- }
- up(&loader_mutex);
- setting = kzalloc(sizeof(*setting), GFP_KERNEL);
- if (setting) {
- if (ansi.length == ansi.max_length)
- ansi.length--;
- memcpy(setting->name, keyname, ansi.length);
- setting->name[ansi.length] = 0;
- if (ndis_decode_setting(setting, param))
- *status = NDIS_STATUS_FAILURE;
- else {
- *status = NDIS_STATUS_SUCCESS;
- if (down_interruptible(&loader_mutex))
- WARNING("couldn't obtain loader_mutex");
- InsertTailList(&nmb->wnd->wd->settings, &setting->list);
- up(&loader_mutex);
- }
- } else
- *status = NDIS_STATUS_RESOURCES;
-
- RtlFreeAnsiString(&ansi);
- EXIT2(return);
-}
-
-wstdcall void WIN_FUNC(NdisReadNetworkAddress,4)
- (NDIS_STATUS *status, void **addr, UINT *len,
- struct ndis_mp_block *nmb)
-{
- struct ndis_device *wnd = nmb->wnd;
- struct ndis_configuration_parameter *param;
- struct unicode_string key;
- struct ansi_string ansi;
- typeof(wnd->mac) mac;
- int i, ret;
-
- ENTER2("%p", nmb);
- RtlInitAnsiString(&ansi, "NetworkAddress");
- *status = NDIS_STATUS_FAILURE;
- if (RtlAnsiStringToUnicodeString(&key, &ansi, TRUE) != STATUS_SUCCESS)
- EXIT1(return);
-
- NdisReadConfiguration(&ret, ¶m, nmb, &key, NdisParameterString);
- RtlFreeUnicodeString(&key);
- if (ret != NDIS_STATUS_SUCCESS)
- EXIT1(return);
- ret = RtlUnicodeStringToAnsiString(&ansi, ¶m->data.string, TRUE);
- if (ret != STATUS_SUCCESS)
- EXIT1(return);
-
- i = 0;
- if (ansi.length >= 2 * sizeof(mac)) {
- for (i = 0; i < sizeof(mac); i++) {
- char c[3];
- int x;
- c[0] = ansi.buf[i*2];
- c[1] = ansi.buf[i*2+1];
- c[2] = 0;
- ret = sscanf(c, "%x", &x);
- if (ret != 1)
- break;
- mac[i] = x;
- }
- }
- TRACE2("%s, %d, " MACSTR, ansi.buf, i, MAC2STR(mac));
- RtlFreeAnsiString(&ansi);
- if (i == sizeof(mac)) {
- memcpy(wnd->mac, mac, sizeof(wnd->mac));
- *len = sizeof(mac);
- *addr = wnd->mac;
- *status = NDIS_STATUS_SUCCESS;
- }
- EXIT1(return);
-}
-
-wstdcall void WIN_FUNC(NdisInitializeString,2)
- (struct unicode_string *dest, UCHAR *src)
-{
- struct ansi_string ansi;
-
- ENTER2("");
- if (src == NULL) {
- dest->length = dest->max_length = 0;
- dest->buf = NULL;
- } else {
- RtlInitAnsiString(&ansi, src);
- /* the string is freed with NdisFreeMemory */
- RtlAnsiStringToUnicodeString(dest, &ansi, TRUE);
- }
- EXIT2(return);
-}
-
-wstdcall void WIN_FUNC(NdisInitAnsiString,2)
- (struct ansi_string *dst, CHAR *src)
-{
- RtlInitAnsiString(dst, src);
- EXIT2(return);
-}
-
-wstdcall void WIN_FUNC(NdisInitUnicodeString,2)
- (struct unicode_string *dest, const wchar_t *src)
-{
- RtlInitUnicodeString(dest, src);
- return;
-}
-
-wstdcall NDIS_STATUS WIN_FUNC(NdisAnsiStringToUnicodeString,2)
- (struct unicode_string *dst, struct ansi_string *src)
-{
- ENTER2("");
- if (dst == NULL || src == NULL)
- EXIT2(return NDIS_STATUS_FAILURE);
- if (RtlAnsiStringToUnicodeString(dst, src, FALSE) == STATUS_SUCCESS)
- return NDIS_STATUS_SUCCESS;
- else
- return NDIS_STATUS_FAILURE;
-}
-
-wstdcall NDIS_STATUS WIN_FUNC(NdisUnicodeStringToAnsiString,2)
- (struct ansi_string *dst, struct unicode_string *src)
-{
- ENTER2("");
- if (dst == NULL || src == NULL)
- EXIT2(return NDIS_STATUS_FAILURE);
- if (RtlUnicodeStringToAnsiString(dst, src, FALSE) == STATUS_SUCCESS)
- return NDIS_STATUS_SUCCESS;
- else
- return NDIS_STATUS_FAILURE;
-}
-
-wstdcall NTSTATUS WIN_FUNC(NdisUpcaseUnicodeString,2)
- (struct unicode_string *dst, struct unicode_string *src)
-{
- EXIT2(return RtlUpcaseUnicodeString(dst, src, FALSE));
-}
-
-wstdcall void WIN_FUNC(NdisMSetAttributesEx,5)
- (struct ndis_mp_block *nmb, void *mp_ctx,
- UINT hangcheck_interval, UINT attributes, ULONG adaptertype)
-{
- struct ndis_device *wnd;
-
- ENTER1("%p, %p, %d, %08x, %d", nmb, mp_ctx, hangcheck_interval,
- attributes, adaptertype);
- wnd = nmb->wnd;
- nmb->mp_ctx = mp_ctx;
- wnd->attributes = attributes;
-
- if ((attributes & NDIS_ATTRIBUTE_BUS_MASTER) &&
- wrap_is_pci_bus(wnd->wd->dev_bus))
- pci_set_master(wnd->wd->pci.pdev);
-
- if (hangcheck_interval > 0)
- wnd->hangcheck_interval = 2 * hangcheck_interval * HZ;
- else
- wnd->hangcheck_interval = 2 * HZ;
-
- EXIT1(return);
-}
-
-wstdcall ULONG WIN_FUNC(NdisReadPciSlotInformation,5)
- (struct ndis_mp_block *nmb, ULONG slot,
- ULONG offset, char *buf, ULONG len)
-{
- struct wrap_device *wd = nmb->wnd->wd;
- ULONG i;
- for (i = 0; i < len; i++)
- if (pci_read_config_byte(wd->pci.pdev, offset + i, &buf[i]) !=
- PCIBIOS_SUCCESSFUL)
- break;
- DBG_BLOCK(2) {
- if (i != len)
- WARNING("%u, %u", i, len);
- }
- return i;
-}
-
-wstdcall ULONG WIN_FUNC(NdisImmediateReadPciSlotInformation,5)
- (struct ndis_mp_block *nmb, ULONG slot,
- ULONG offset, char *buf, ULONG len)
-{
- return NdisReadPciSlotInformation(nmb, slot, offset, buf, len);
-}
-
-wstdcall ULONG WIN_FUNC(NdisWritePciSlotInformation,5)
- (struct ndis_mp_block *nmb, ULONG slot,
- ULONG offset, char *buf, ULONG len)
-{
- struct wrap_device *wd = nmb->wnd->wd;
- ULONG i;
- for (i = 0; i < len; i++)
- if (pci_write_config_byte(wd->pci.pdev, offset + i, buf[i]) !=
- PCIBIOS_SUCCESSFUL)
- break;
- DBG_BLOCK(2) {
- if (i != len)
- WARNING("%u, %u", i, len);
- }
- return i;
-}
-
-wstdcall NDIS_STATUS WIN_FUNC(NdisMRegisterIoPortRange,4)
- (void **virt, struct ndis_mp_block *nmb, UINT start, UINT len)
-{
- ENTER3("%08x %08x", start, len);
- *virt = (void *)(ULONG_PTR)start;
- return NDIS_STATUS_SUCCESS;
-}
-
-wstdcall void WIN_FUNC(NdisMDeregisterIoPortRange,4)
- (struct ndis_mp_block *nmb, UINT start, UINT len, void* virt)
-{
- ENTER1("%08x %08x", start, len);
-}
-
-wstdcall void WIN_FUNC(NdisReadPortUchar,3)
- (struct ndis_mp_block *nmb, ULONG port, char *data)
-{
- *data = inb(port);
-}
-
-wstdcall void WIN_FUNC(NdisImmediateReadPortUchar,3)
- (struct ndis_mp_block *nmb, ULONG port, char *data)
-{
- *data = inb(port);
-}
-
-wstdcall void WIN_FUNC(NdisWritePortUchar,3)
- (struct ndis_mp_block *nmb, ULONG port, char data)
-{
- outb(data, port);
-}
-
-wstdcall void WIN_FUNC(NdisImmediateWritePortUchar,3)
- (struct ndis_mp_block *nmb, ULONG port, char data)
-{
- outb(data, port);
-}
-
-wstdcall void WIN_FUNC(NdisMQueryAdapterResources,4)
- (NDIS_STATUS *status, struct ndis_mp_block *nmb,
- NDIS_RESOURCE_LIST *resource_list, UINT *size)
-{
- struct ndis_device *wnd = nmb->wnd;
- NDIS_RESOURCE_LIST *list;
- UINT resource_length;
-
- list = &wnd->wd->resource_list->list->partial_resource_list;
- resource_length = sizeof(struct cm_partial_resource_list) +
- sizeof(struct cm_partial_resource_descriptor) *
- (list->count - 1);
- TRACE2("%p, %p,%d (%d), %p %d %d", wnd, resource_list, *size,
- resource_length, &list->partial_descriptors[list->count-1],
- list->partial_descriptors[list->count-1].u.interrupt.level,
- list->partial_descriptors[list->count-1].u.interrupt.vector);
- if (*size < sizeof(*list)) {
- *size = resource_length;
- *status = NDIS_STATUS_BUFFER_TOO_SHORT;
- } else {
- ULONG count;
- if (*size >= resource_length) {
- *size = resource_length;
- count = list->count;
- } else {
- UINT n = sizeof(*list);
- count = 1;
- while (count++ < list->count && n < *size)
- n += sizeof(list->partial_descriptors);
- *size = n;
- }
- memcpy(resource_list, list, *size);
- resource_list->count = count;
- *status = NDIS_STATUS_SUCCESS;
- }
- EXIT2(return);
-}
-
-wstdcall NDIS_STATUS WIN_FUNC(NdisMPciAssignResources,3)
- (struct ndis_mp_block *nmb, ULONG slot_number,
- NDIS_RESOURCE_LIST **resources)
-{
- struct ndis_device *wnd = nmb->wnd;
-
- ENTER2("%p, %p", wnd, wnd->wd->resource_list);
- *resources = &wnd->wd->resource_list->list->partial_resource_list;
- EXIT2(return NDIS_STATUS_SUCCESS);
-}
-
-wstdcall NDIS_STATUS WIN_FUNC(NdisMMapIoSpace,4)
- (void __iomem **virt, struct ndis_mp_block *nmb,
- NDIS_PHY_ADDRESS phy_addr, UINT len)
-{
- struct ndis_device *wnd = nmb->wnd;
-
- ENTER2("%Lx, %d", phy_addr, len);
- *virt = MmMapIoSpace(phy_addr, len, MmCached);
- if (*virt == NULL) {
- ERROR("ioremap failed");
- EXIT2(return NDIS_STATUS_FAILURE);
- }
- wnd->mem_start = phy_addr;
- wnd->mem_end = phy_addr + len;
- TRACE2("%p", *virt);
- EXIT2(return NDIS_STATUS_SUCCESS);
-}
-
-wstdcall void WIN_FUNC(NdisMUnmapIoSpace,3)
- (struct ndis_mp_block *nmb, void __iomem *virt, UINT len)
-{
- ENTER2("%p, %d", virt, len);
- MmUnmapIoSpace(virt, len);
- EXIT2(return);
-}
-
-wstdcall void WIN_FUNC(NdisAllocateSpinLock,1)
- (struct ndis_spinlock *lock)
-{
- TRACE4("lock %p, %p", lock, &lock->klock);
- KeInitializeSpinLock(&lock->klock);
- lock->irql = PASSIVE_LEVEL;
- return;
-}
-
-wstdcall void WIN_FUNC(NdisFreeSpinLock,1)
- (struct ndis_spinlock *lock)
-{
- TRACE4("lock %p, %p", lock, &lock->klock);
- return;
-}
-
-wstdcall void WIN_FUNC(NdisAcquireSpinLock,1)
- (struct ndis_spinlock *lock)
-{
- ENTER6("lock %p, %p", lock, &lock->klock);
-// assert_irql(_irql_ <= DISPATCH_LEVEL);
- lock->irql = nt_spin_lock_irql(&lock->klock, DISPATCH_LEVEL);
- return;
-}
-
-wstdcall void WIN_FUNC(NdisReleaseSpinLock,1)
- (struct ndis_spinlock *lock)
-{
- ENTER6("lock %p, %p", lock, &lock->klock);
-// assert_irql(_irql_ == DISPATCH_LEVEL);
- nt_spin_unlock_irql(&lock->klock, lock->irql);
- return;
-}
-
-wstdcall void WIN_FUNC(NdisDprAcquireSpinLock,1)
- (struct ndis_spinlock *lock)
-{
- ENTER6("lock %p", &lock->klock);
-// assert_irql(_irql_ == DISPATCH_LEVEL);
- nt_spin_lock(&lock->klock);
- return;
-}
-
-wstdcall void WIN_FUNC(NdisDprReleaseSpinLock,1)
- (struct ndis_spinlock *lock)
-{
- ENTER6("lock %p", &lock->klock);
-// assert_irql(_irql_ == DISPATCH_LEVEL);
- nt_spin_unlock(&lock->klock);
- return;
-}
-
-wstdcall void WIN_FUNC(NdisInitializeReadWriteLock,1)
- (struct ndis_rw_lock *rw_lock)
-{
- ENTER3("%p", rw_lock);
- memset(rw_lock, 0, sizeof(*rw_lock));
- KeInitializeSpinLock(&rw_lock->klock);
- return;
-}
-
-/* read/write locks are implemented in a rather simplisitic way - we
- * should probably use Linux's rw_lock implementation */
-
-wstdcall void WIN_FUNC(NdisAcquireReadWriteLock,3)
- (struct ndis_rw_lock *rw_lock, BOOLEAN write,
- struct lock_state *lock_state)
-{
- if (write) {
- while (1) {
- if (cmpxchg(&rw_lock->count, 0, -1) == 0)
- return;
- while (rw_lock->count)
- cpu_relax();
- }
- return;
- }
- while (1) {
- typeof(rw_lock->count) count;
- while ((count = rw_lock->count) < 0)
- cpu_relax();
- if (cmpxchg(&rw_lock->count, count, count + 1) == count)
- return;
- }
-}
-
-wstdcall void WIN_FUNC(NdisReleaseReadWriteLock,2)
- (struct ndis_rw_lock *rw_lock, struct lock_state *lock_state)
-{
- if (rw_lock->count > 0)
- pre_atomic_add(rw_lock->count, -1);
- else if (rw_lock->count == -1)
- rw_lock->count = 0;
- else
- WARNING("invalid state: %d", rw_lock->count);
-}
-
-wstdcall NDIS_STATUS WIN_FUNC(NdisMAllocateMapRegisters,5)
- (struct ndis_mp_block *nmb, UINT dmachan,
- NDIS_DMA_SIZE dmasize, ULONG basemap, ULONG max_buf_size)
-{
- struct ndis_device *wnd = nmb->wnd;
-
- ENTER2("%p, %d %d %d %d", wnd, dmachan, dmasize, basemap, max_buf_size);
- if (wnd->dma_map_count > 0) {
- WARNING("%s: map registers already allocated: %u",
- wnd->net_dev->name, wnd->dma_map_count);
- EXIT2(return NDIS_STATUS_RESOURCES);
- }
- if (dmasize == NDIS_DMA_24BITS) {
- if (pci_set_dma_mask(wnd->wd->pci.pdev, DMA_BIT_MASK(24)) ||
- pci_set_consistent_dma_mask(wnd->wd->pci.pdev,
- DMA_BIT_MASK(24)))
- WARNING("setting dma mask failed");
- } else if (dmasize == NDIS_DMA_32BITS) {
- /* consistent dma is in low 32-bits by default */
- if (pci_set_dma_mask(wnd->wd->pci.pdev, DMA_BIT_MASK(32)))
- WARNING("setting dma mask failed");
-#ifdef CONFIG_X86_64
- } else if (dmasize == NDIS_DMA_64BITS) {
- if (pci_set_dma_mask(wnd->wd->pci.pdev, DMA_BIT_MASK(64)) ||
- pci_set_consistent_dma_mask(wnd->wd->pci.pdev,
- DMA_BIT_MASK(64)))
- WARNING("setting dma mask failed");
- else
- wnd->net_dev->features |= NETIF_F_HIGHDMA;
-#endif
- }
- /* since memory for buffer is allocated with kmalloc, buffer
- * is physically contiguous, so entire map will fit in one
- * register */
- if (basemap > 64) {
- WARNING("Windows driver %s requesting too many (%u) "
- "map registers", wnd->wd->driver->name, basemap);
- /* As per NDIS, NDIS_STATUS_RESOURCES should be
- * returned, but with that Atheros PCI driver fails -
- * for now tolerate it */
-// EXIT2(return NDIS_STATUS_RESOURCES);
- }
-
- wnd->dma_map_addr = kmalloc(basemap * sizeof(*(wnd->dma_map_addr)),
- GFP_KERNEL);
- if (!wnd->dma_map_addr)
- EXIT2(return NDIS_STATUS_RESOURCES);
- memset(wnd->dma_map_addr, 0, basemap * sizeof(*(wnd->dma_map_addr)));
- wnd->dma_map_count = basemap;
- TRACE2("%u", wnd->dma_map_count);
- EXIT2(return NDIS_STATUS_SUCCESS);
-}
-
-wstdcall void WIN_FUNC(NdisMFreeMapRegisters,1)
- (struct ndis_mp_block *nmb)
-{
- struct ndis_device *wnd = nmb->wnd;
- int i;
-
- ENTER2("wnd: %p", wnd);
- if (wnd->dma_map_addr) {
- for (i = 0; i < wnd->dma_map_count; i++) {
- if (wnd->dma_map_addr[i])
- WARNING("%s: dma addr %p not freed by "
- "Windows driver", wnd->net_dev->name,
- (void *)wnd->dma_map_addr[i]);
- }
- kfree(wnd->dma_map_addr);
- wnd->dma_map_addr = NULL;
- } else
- WARNING("map registers already freed?");
- wnd->dma_map_count = 0;
- EXIT2(return);
-}
-
-wstdcall void WIN_FUNC(NdisMStartBufferPhysicalMapping,6)
- (struct ndis_mp_block *nmb, ndis_buffer *buf,
- ULONG index, BOOLEAN write_to_dev,
- struct ndis_phy_addr_unit *phy_addr_array, UINT *array_size)
-{
- struct ndis_device *wnd = nmb->wnd;
-
- ENTER3("%p, %p, %u, %u", wnd, buf, index, wnd->dma_map_count);
- if (unlikely(wnd->sg_dma_size || !write_to_dev ||
- index >= wnd->dma_map_count)) {
- WARNING("invalid request: %d, %d, %d, %d", wnd->sg_dma_size,
- write_to_dev, index, wnd->dma_map_count);
- phy_addr_array[0].phy_addr = 0;
- phy_addr_array[0].length = 0;
- *array_size = 0;
- return;
- }
- if (wnd->dma_map_addr[index]) {
- TRACE2("buffer %p at %d is already mapped: %lx", buf, index,
- (unsigned long)wnd->dma_map_addr[index]);
-// *array_size = 1;
- return;
- }
- TRACE3("%p, %p, %u", buf, MmGetSystemAddressForMdl(buf),
- MmGetMdlByteCount(buf));
- DBG_BLOCK(4) {
- dump_bytes(__func__, MmGetSystemAddressForMdl(buf),
- MmGetMdlByteCount(buf));
- }
- wnd->dma_map_addr[index] =
- PCI_DMA_MAP_SINGLE(wnd->wd->pci.pdev,
- MmGetSystemAddressForMdl(buf),
- MmGetMdlByteCount(buf), PCI_DMA_TODEVICE);
- phy_addr_array[0].phy_addr = wnd->dma_map_addr[index];
- phy_addr_array[0].length = MmGetMdlByteCount(buf);
- TRACE4("%Lx, %d, %d", phy_addr_array[0].phy_addr,
- phy_addr_array[0].length, index);
- *array_size = 1;
-}
-
-wstdcall void WIN_FUNC(NdisMCompleteBufferPhysicalMapping,3)
- (struct ndis_mp_block *nmb, ndis_buffer *buf, ULONG index)
-{
- struct ndis_device *wnd = nmb->wnd;
-
- ENTER3("%p, %p %u (%u)", wnd, buf, index, wnd->dma_map_count);
-
- if (unlikely(wnd->sg_dma_size))
- WARNING("buffer %p may have been unmapped already", buf);
- if (index >= wnd->dma_map_count) {
- ERROR("invalid map register (%u >= %u)",
- index, wnd->dma_map_count);
- return;
- }
- TRACE4("%lx", (unsigned long)wnd->dma_map_addr[index]);
- if (wnd->dma_map_addr[index]) {
- PCI_DMA_UNMAP_SINGLE(wnd->wd->pci.pdev, wnd->dma_map_addr[index],
- MmGetMdlByteCount(buf), PCI_DMA_TODEVICE);
- wnd->dma_map_addr[index] = 0;
- } else
- WARNING("map registers at %u not used", index);
-}
-
-wstdcall void WIN_FUNC(NdisMAllocateSharedMemory,5)
- (struct ndis_mp_block *nmb, ULONG size,
- BOOLEAN cached, void **virt, NDIS_PHY_ADDRESS *phys)
-{
- dma_addr_t dma_addr;
- struct wrap_device *wd = nmb->wnd->wd;
-
- ENTER3("size: %u, cached: %d", size, cached);
- *virt = PCI_DMA_ALLOC_COHERENT(wd->pci.pdev, size, &dma_addr);
- if (*virt)
- *phys = dma_addr;
- else
- WARNING("couldn't allocate %d bytes of %scached DMA memory",
- size, cached ? "" : "un-");
- EXIT3(return);
-}
-
-wstdcall void WIN_FUNC(NdisMFreeSharedMemory,5)
- (struct ndis_mp_block *nmb, ULONG size, BOOLEAN cached,
- void *virt, NDIS_PHY_ADDRESS addr)
-{
- struct wrap_device *wd = nmb->wnd->wd;
- ENTER3("%p, %Lx, %u", virt, addr, size);
- PCI_DMA_FREE_COHERENT(wd->pci.pdev, size, virt, addr);
- EXIT3(return);
-}
-
-wstdcall void alloc_shared_memory_async(void *arg1, void *arg2)
-{
- struct ndis_device *wnd;
- struct alloc_shared_mem *alloc_shared_mem;
- struct miniport *mp;
- void *virt;
- NDIS_PHY_ADDRESS phys;
- KIRQL irql;
-
- wnd = arg1;
- alloc_shared_mem = arg2;
- mp = &wnd->wd->driver->ndis_driver->mp;
- NdisMAllocateSharedMemory(wnd->nmb, alloc_shared_mem->size,
- alloc_shared_mem->cached, &virt, &phys);
- irql = serialize_lock_irql(wnd);
- assert_irql(_irql_ == DISPATCH_LEVEL);
- LIN2WIN5(mp->alloc_complete, wnd->nmb, virt,
- &phys, alloc_shared_mem->size, alloc_shared_mem->ctx);
- serialize_unlock_irql(wnd, irql);
- kfree(alloc_shared_mem);
-}
-WIN_FUNC_DECL(alloc_shared_memory_async,2)
-
-wstdcall NDIS_STATUS WIN_FUNC(NdisMAllocateSharedMemoryAsync,4)
- (struct ndis_mp_block *nmb, ULONG size, BOOLEAN cached, void *ctx)
-{
- struct ndis_device *wnd = nmb->wnd;
- struct alloc_shared_mem *alloc_shared_mem;
-
- ENTER3("wnd: %p", wnd);
- alloc_shared_mem = kmalloc(sizeof(*alloc_shared_mem), irql_gfp());
- if (!alloc_shared_mem) {
- WARNING("couldn't allocate memory");
- return NDIS_STATUS_FAILURE;
- }
-
- alloc_shared_mem->size = size;
- alloc_shared_mem->cached = cached;
- alloc_shared_mem->ctx = ctx;
- if (schedule_ntos_work_item(WIN_FUNC_PTR(alloc_shared_memory_async,2),
- wnd, alloc_shared_mem))
- EXIT3(return NDIS_STATUS_FAILURE);
- EXIT3(return NDIS_STATUS_PENDING);
-}
-
-/* Some drivers allocate NDIS_BUFFER (aka MDL) very often; instead of
- * allocating and freeing with kernel functions, we chain them into
- * ndis_buffer_pool. When an MDL is freed, it is added to the list of
- * free MDLs. When allocated, we first check if there is one in free
- * list and if so just return it; otherwise, we allocate a new one and
- * return that. This reduces memory fragmentation. Windows DDK says
- * that the driver itself shouldn't check what is returned in
- * pool_handle, presumably because buffer pools are not used in
- * XP. However, as long as driver follows rest of the semantics - that
- * it should indicate maximum number of MDLs used with num_descr and
- * pass the same pool_handle in other buffer functions, this should
- * work. Sadly, though, NdisFreeBuffer doesn't pass the pool_handle,
- * so we use 'process' field of MDL to store pool_handle. */
-
-wstdcall void WIN_FUNC(NdisAllocateBufferPool,3)
- (NDIS_STATUS *status, struct ndis_buffer_pool **pool_handle,
- UINT num_descr)
-{
- struct ndis_buffer_pool *pool;
-
- ENTER1("buffers: %d", num_descr);
- pool = kmalloc(sizeof(*pool), irql_gfp());
- if (!pool) {
- *status = NDIS_STATUS_RESOURCES;
- EXIT3(return);
- }
- spin_lock_init(&pool->lock);
- pool->max_descr = num_descr;
- pool->num_allocated_descr = 0;
- pool->free_descr = NULL;
- *pool_handle = pool;
- *status = NDIS_STATUS_SUCCESS;
- TRACE1("pool: %p, num_descr: %d", pool, num_descr);
- EXIT1(return);
-}
-
-wstdcall void WIN_FUNC(NdisAllocateBuffer,5)
- (NDIS_STATUS *status, ndis_buffer **buffer,
- struct ndis_buffer_pool *pool, void *virt, UINT length)
-{
- ndis_buffer *descr;
-
- ENTER4("pool: %p (%d)", pool, pool->num_allocated_descr);
- /* NDIS drivers should call this at DISPATCH_LEVEL, but
- * alloc_tx_packet calls at SOFT_IRQL */
- assert_irql(_irql_ <= SOFT_LEVEL);
- if (!pool) {
- *status = NDIS_STATUS_FAILURE;
- *buffer = NULL;
- EXIT4(return);
- }
- spin_lock_bh(&pool->lock);
- if ((descr = pool->free_descr))
- pool->free_descr = descr->next;
- spin_unlock_bh(&pool->lock);
- if (descr) {
- typeof(descr->flags) flags;
- flags = descr->flags;
- memset(descr, 0, sizeof(*descr));
- MmInitializeMdl(descr, virt, length);
- if (flags & MDL_CACHE_ALLOCATED)
- descr->flags |= MDL_CACHE_ALLOCATED;
- } else {
- if (pool->num_allocated_descr > pool->max_descr) {
- TRACE2("pool %p is full: %d(%d)", pool,
- pool->num_allocated_descr, pool->max_descr);
-#ifndef ALLOW_POOL_OVERFLOW
- *status = NDIS_STATUS_FAILURE;
- *buffer = NULL;
- return;
-#endif
- }
- descr = allocate_init_mdl(virt, length);
- if (!descr) {
- WARNING("couldn't allocate buffer");
- *status = NDIS_STATUS_FAILURE;
- *buffer = NULL;
- EXIT4(return);
- }
- TRACE4("buffer %p for %p, %d", descr, virt, length);
- atomic_inc_var(pool->num_allocated_descr);
- }
- /* TODO: make sure this mdl can map given buffer */
- MmBuildMdlForNonPagedPool(descr);
-// descr->flags |= MDL_ALLOCATED_FIXED_SIZE |
-// MDL_MAPPED_TO_SYSTEM_VA | MDL_PAGES_LOCKED;
- descr->pool = pool;
- *buffer = descr;
- *status = NDIS_STATUS_SUCCESS;
- TRACE4("buffer: %p", descr);
- EXIT4(return);
-}
-
-wstdcall void WIN_FUNC(NdisFreeBuffer,1)
- (ndis_buffer *buffer)
-{
- struct ndis_buffer_pool *pool;
-
- ENTER4("%p", buffer);
- if (!buffer || !buffer->pool) {
- ERROR("invalid buffer");
- EXIT4(return);
- }
- pool = buffer->pool;
- if (pool->num_allocated_descr > MAX_ALLOCATED_NDIS_BUFFERS) {
- /* NB NB NB: set mdl's 'pool' field to NULL before
- * calling free_mdl; otherwise free_mdl calls
- * NdisFreeBuffer back */
- atomic_dec_var(pool->num_allocated_descr);
- buffer->pool = NULL;
- free_mdl(buffer);
- } else {
- spin_lock_bh(&pool->lock);
- buffer->next = pool->free_descr;
- pool->free_descr = buffer;
- spin_unlock_bh(&pool->lock);
- }
- EXIT4(return);
-}
-
-wstdcall void WIN_FUNC(NdisFreeBufferPool,1)
- (struct ndis_buffer_pool *pool)
-{
- ndis_buffer *cur, *next;
-
- TRACE3("pool: %p", pool);
- if (!pool) {
- WARNING("invalid pool");
- EXIT3(return);
- }
- spin_lock_bh(&pool->lock);
- cur = pool->free_descr;
- while (cur) {
- next = cur->next;
- cur->pool = NULL;
- free_mdl(cur);
- cur = next;
- }
- spin_unlock_bh(&pool->lock);
- kfree(pool);
- pool = NULL;
- EXIT3(return);
-}
-
-wstdcall void WIN_FUNC(NdisAdjustBufferLength,2)
- (ndis_buffer *buffer, UINT length)
-{
- ENTER4("%p, %d", buffer, length);
- buffer->bytecount = length;
-}
-
-wstdcall void WIN_FUNC(NdisQueryBuffer,3)
- (ndis_buffer *buffer, void **virt, UINT *length)
-{
- ENTER4("buffer: %p", buffer);
- if (virt)
- *virt = MmGetSystemAddressForMdl(buffer);
- *length = MmGetMdlByteCount(buffer);
- TRACE4("%p, %u", virt? *virt : NULL, *length);
- return;
-}
-
-wstdcall void WIN_FUNC(NdisQueryBufferSafe,4)
- (ndis_buffer *buffer, void **virt, UINT *length,
- enum mm_page_priority priority)
-{
- ENTER4("%p, %p, %p, %d", buffer, virt, length, priority);
- if (virt)
- *virt = MmGetSystemAddressForMdlSafe(buffer, priority);
- *length = MmGetMdlByteCount(buffer);
- TRACE4("%p, %u", virt? *virt : NULL, *length);
-}
-
-wstdcall void *WIN_FUNC(NdisBufferVirtualAddress,1)
- (ndis_buffer *buffer)
-{
- ENTER3("%p", buffer);
- return MmGetSystemAddressForMdl(buffer);
-}
-
-wstdcall ULONG WIN_FUNC(NdisBufferLength,1)
- (ndis_buffer *buffer)
-{
- ENTER3("%p", buffer);
- return MmGetMdlByteCount(buffer);
-}
-
-wstdcall void WIN_FUNC(NdisQueryBufferOffset,3)
- (ndis_buffer *buffer, UINT *offset, UINT *length)
-{
- ENTER3("%p", buffer);
- *offset = MmGetMdlByteOffset(buffer);
- *length = MmGetMdlByteCount(buffer);
- TRACE3("%d, %d", *offset, *length);
-}
-
-wstdcall void WIN_FUNC(NdisUnchainBufferAtBack,2)
- (struct ndis_packet *packet, ndis_buffer **buffer)
-{
- ndis_buffer *b, *btail;
-
- ENTER3("%p", packet);
- b = packet->private.buffer_head;
- if (!b) {
- /* no buffer in packet */
- *buffer = NULL;
- EXIT3(return);
- }
- btail = packet->private.buffer_tail;
- *buffer = btail;
- if (b == btail) {
- /* one buffer in packet */
- packet->private.buffer_head = NULL;
- packet->private.buffer_tail = NULL;
- } else {
- while (b->next != btail)
- b = b->next;
- packet->private.buffer_tail = b;
- b->next = NULL;
- }
- packet->private.valid_counts = FALSE;
- EXIT3(return);
-}
-
-wstdcall void WIN_FUNC(NdisUnchainBufferAtFront,2)
- (struct ndis_packet *packet, ndis_buffer **buffer)
-{
- ENTER3("%p", packet);
- if (packet->private.buffer_head == NULL) {
- /* no buffer in packet */
- *buffer = NULL;
- EXIT3(return);
- }
-
- *buffer = packet->private.buffer_head;
- if (packet->private.buffer_head == packet->private.buffer_tail) {
- /* one buffer in packet */
- packet->private.buffer_head = NULL;
- packet->private.buffer_tail = NULL;
- } else
- packet->private.buffer_head = (*buffer)->next;
-
- packet->private.valid_counts = FALSE;
- EXIT3(return);
-}
-
-wstdcall void WIN_FUNC(NdisGetFirstBufferFromPacketSafe,6)
- (struct ndis_packet *packet, ndis_buffer **first_buffer,
- void **first_buffer_va, UINT *first_buffer_length,
- UINT *total_buffer_length, enum mm_page_priority priority)
-{
- ndis_buffer *b = packet->private.buffer_head;
-
- ENTER3("%p(%p)", packet, b);
- *first_buffer = b;
- if (b) {
- *first_buffer_va = MmGetSystemAddressForMdlSafe(b, priority);
- *first_buffer_length = *total_buffer_length =
- MmGetMdlByteCount(b);
- for (b = b->next; b; b = b->next)
- *total_buffer_length += MmGetMdlByteCount(b);
- } else {
- *first_buffer_va = NULL;
- *first_buffer_length = 0;
- *total_buffer_length = 0;
- }
- TRACE3("%p, %d, %d", *first_buffer_va, *first_buffer_length,
- *total_buffer_length);
- EXIT3(return);
-}
-
-wstdcall void WIN_FUNC(NdisGetFirstBufferFromPacket,6)
- (struct ndis_packet *packet, ndis_buffer **first_buffer,
- void **first_buffer_va, UINT *first_buffer_length,
- UINT *total_buffer_length, enum mm_page_priority priority)
-{
- NdisGetFirstBufferFromPacketSafe(packet, first_buffer,
- first_buffer_va, first_buffer_length,
- total_buffer_length,
- NormalPagePriority);
-}
-
-wstdcall void WIN_FUNC(NdisAllocatePacketPoolEx,5)
- (NDIS_STATUS *status, struct ndis_packet_pool **pool_handle,
- UINT num_descr, UINT overflowsize, UINT proto_rsvd_length)
-{
- struct ndis_packet_pool *pool;
-
- ENTER3("buffers: %d, length: %d", num_descr, proto_rsvd_length);
- pool = kzalloc(sizeof(*pool), irql_gfp());
- if (!pool) {
- *status = NDIS_STATUS_RESOURCES;
- EXIT3(return);
- }
- spin_lock_init(&pool->lock);
- pool->max_descr = num_descr;
- pool->num_allocated_descr = 0;
- pool->num_used_descr = 0;
- pool->free_descr = NULL;
- pool->proto_rsvd_length = proto_rsvd_length;
- *pool_handle = pool;
- *status = NDIS_STATUS_SUCCESS;
- TRACE3("pool: %p", pool);
- EXIT3(return);
-}
-
-wstdcall void WIN_FUNC(NdisAllocatePacketPool,4)
- (NDIS_STATUS *status, struct ndis_packet_pool **pool_handle,
- UINT num_descr, UINT proto_rsvd_length)
-{
- NdisAllocatePacketPoolEx(status, pool_handle, num_descr, 0,
- proto_rsvd_length);
- EXIT3(return);
-}
-
-wstdcall void WIN_FUNC(NdisFreePacketPool,1)
- (struct ndis_packet_pool *pool)
-{
- struct ndis_packet *packet, *next;
-
- ENTER3("pool: %p", pool);
- if (!pool) {
- WARNING("invalid pool");
- EXIT3(return);
- }
- spin_lock_bh(&pool->lock);
- packet = pool->free_descr;
- while (packet) {
- next = (struct ndis_packet *)packet->reserved[0];
- kfree(packet);
- packet = next;
- }
- pool->num_allocated_descr = 0;
- pool->num_used_descr = 0;
- pool->free_descr = NULL;
- spin_unlock_bh(&pool->lock);
- kfree(pool);
- EXIT3(return);
-}
-
-wstdcall UINT WIN_FUNC(NdisPacketPoolUsage,1)
- (struct ndis_packet_pool *pool)
-{
- EXIT4(return pool->num_used_descr);
-}
-
-wstdcall void WIN_FUNC(NdisAllocatePacket,3)
- (NDIS_STATUS *status, struct ndis_packet **ndis_packet,
- struct ndis_packet_pool *pool)
-{
- struct ndis_packet *packet;
- int packet_length;
-
- ENTER4("pool: %p", pool);
- if (!pool) {
- *status = NDIS_STATUS_RESOURCES;
- *ndis_packet = NULL;
- EXIT4(return);
- }
- assert_irql(_irql_ <= SOFT_LEVEL);
- if (pool->num_used_descr > pool->max_descr) {
- TRACE3("pool %p is full: %d(%d)", pool,
- pool->num_used_descr, pool->max_descr);
-#ifndef ALLOW_POOL_OVERFLOW
- *status = NDIS_STATUS_RESOURCES;
- *ndis_packet = NULL;
- return;
-#endif
- }
- /* packet has space for 1 byte in protocol_reserved field */
- packet_length = sizeof(*packet) - 1 + pool->proto_rsvd_length +
- sizeof(struct ndis_packet_oob_data);
- spin_lock_bh(&pool->lock);
- if ((packet = pool->free_descr))
- pool->free_descr = (void *)packet->reserved[0];
- spin_unlock_bh(&pool->lock);
- if (!packet) {
- packet = kmalloc(packet_length, irql_gfp());
- if (!packet) {
- WARNING("couldn't allocate packet");
- *status = NDIS_STATUS_RESOURCES;
- *ndis_packet = NULL;
- return;
- }
- atomic_inc_var(pool->num_allocated_descr);
- }
- TRACE4("%p, %p", pool, packet);
- atomic_inc_var(pool->num_used_descr);
- memset(packet, 0, packet_length);
- packet->private.oob_offset =
- packet_length - sizeof(struct ndis_packet_oob_data);
- packet->private.packet_flags = fPACKET_ALLOCATED_BY_NDIS;
- packet->private.pool = pool;
- *ndis_packet = packet;
- *status = NDIS_STATUS_SUCCESS;
- EXIT4(return);
-}
-
-wstdcall void WIN_FUNC(NdisDprAllocatePacket,3)
- (NDIS_STATUS *status, struct ndis_packet **packet,
- struct ndis_packet_pool *pool)
-{
- NdisAllocatePacket(status, packet, pool);
-}
-
-wstdcall void WIN_FUNC(NdisFreePacket,1)
- (struct ndis_packet *packet)
-{
- struct ndis_packet_pool *pool;
-
- ENTER4("%p, %p", packet, packet->private.pool);
- pool = packet->private.pool;
- if (!pool) {
- ERROR("invalid pool %p", packet);
- EXIT4(return);
- }
- assert((int)pool->num_used_descr > 0);
- atomic_dec_var(pool->num_used_descr);
- if (packet->reserved[1]) {
- TRACE3("%p, %p", packet, (void *)packet->reserved[1]);
- kfree((void *)packet->reserved[1]);
- packet->reserved[1] = 0;
- }
- if (pool->num_allocated_descr > MAX_ALLOCATED_NDIS_PACKETS) {
- TRACE3("%p", pool);
- atomic_dec_var(pool->num_allocated_descr);
- kfree(packet);
- } else {
- TRACE4("%p, %p, %p", pool, packet, pool->free_descr);
- spin_lock_bh(&pool->lock);
- packet->reserved[0] =
- (typeof(packet->reserved[0]))pool->free_descr;
- pool->free_descr = packet;
- spin_unlock_bh(&pool->lock);
- }
- EXIT4(return);
-}
-
-wstdcall struct ndis_packet_stack *WIN_FUNC(NdisIMGetCurrentPacketStack,2)
- (struct ndis_packet *packet, BOOLEAN *stacks_remain)
-{
- struct ndis_packet_stack *stack;
-
- if (!packet->reserved[1]) {
- stack = kzalloc(2 * sizeof(*stack), irql_gfp());
- TRACE3("%p, %p", packet, stack);
- packet->reserved[1] = (typeof(packet->reserved[1]))stack;
- } else {
- stack = (void *)packet->reserved[1];;
- if (xchg(&stack->ndis_reserved[0], 1)) {
- stack++;
- if (xchg(&stack->ndis_reserved[0], 1))
- stack = NULL;
- }
- TRACE3("%p", stack);
- }
- if (stack)
- *stacks_remain = TRUE;
- else
- *stacks_remain = FALSE;
-
- EXIT3(return stack);
-}
-
-wstdcall void WIN_FUNC(NdisCopyFromPacketToPacketSafe,7)
- (struct ndis_packet *dst, UINT dst_offset, UINT num_to_copy,
- struct ndis_packet *src, UINT src_offset, UINT *num_copied,
- enum mm_page_priority priority)
-{
- UINT dst_n, src_n, n, left;
- ndis_buffer *dst_buf;
- ndis_buffer *src_buf;
-
- ENTER4("");
- if (!dst || !src) {
- *num_copied = 0;
- EXIT4(return);
- }
-
- dst_buf = dst->private.buffer_head;
- src_buf = src->private.buffer_head;
-
- if (!dst_buf || !src_buf) {
- *num_copied = 0;
- EXIT4(return);
- }
- dst_n = MmGetMdlByteCount(dst_buf) - dst_offset;
- src_n = MmGetMdlByteCount(src_buf) - src_offset;
-
- n = min(src_n, dst_n);
- n = min(n, num_to_copy);
- memcpy(MmGetSystemAddressForMdl(dst_buf) + dst_offset,
- MmGetSystemAddressForMdl(src_buf) + src_offset, n);
-
- left = num_to_copy - n;
- while (left > 0) {
- src_offset += n;
- dst_offset += n;
- dst_n -= n;
- src_n -= n;
- if (dst_n == 0) {
- dst_buf = dst_buf->next;
- if (!dst_buf)
- break;
- dst_n = MmGetMdlByteCount(dst_buf);
- dst_offset = 0;
- }
- if (src_n == 0) {
- src_buf = src_buf->next;
- if (!src_buf)
- break;
- src_n = MmGetMdlByteCount(src_buf);
- src_offset = 0;
- }
-
- n = min(src_n, dst_n);
- n = min(n, left);
- memcpy(MmGetSystemAddressForMdl(dst_buf) + dst_offset,
- MmGetSystemAddressForMdl(src_buf) + src_offset, n);
- left -= n;
- }
- *num_copied = num_to_copy - left;
- EXIT4(return);
-}
-
-wstdcall void WIN_FUNC(NdisCopyFromPacketToPacket,6)
- (struct ndis_packet *dst, UINT dst_offset, UINT num_to_copy,
- struct ndis_packet *src, UINT src_offset, UINT *num_copied)
-{
- NdisCopyFromPacketToPacketSafe(dst, dst_offset, num_to_copy,
- src, src_offset, num_copied,
- NormalPagePriority);
- return;
-}
-
-wstdcall void WIN_FUNC(NdisIMCopySendPerPacketInfo,2)
- (struct ndis_packet *dst, struct ndis_packet *src)
-{
- struct ndis_packet_oob_data *dst_oob, *src_oob;
- dst_oob = NDIS_PACKET_OOB_DATA(dst);
- src_oob = NDIS_PACKET_OOB_DATA(src);
- memcpy(&dst_oob->ext, &src_oob->ext, sizeof(dst_oob->ext));
- return;
-}
-
-wstdcall void WIN_FUNC(NdisSend,3)
- (NDIS_STATUS *status, struct ndis_mp_block *nmb,
- struct ndis_packet *packet)
-{
- struct ndis_device *wnd = nmb->wnd;
- struct miniport *mp;
- KIRQL irql;
-
- mp = &wnd->wd->driver->ndis_driver->mp;
- if (mp->send_packets) {
- irql = serialize_lock_irql(wnd);
- assert_irql(_irql_ == DISPATCH_LEVEL);
- LIN2WIN3(mp->send_packets, wnd->nmb->mp_ctx, &packet, 1);
- serialize_unlock_irql(wnd, irql);
- if (deserialized_driver(wnd))
- *status = NDIS_STATUS_PENDING;
- else {
- struct ndis_packet_oob_data *oob_data;
- oob_data = NDIS_PACKET_OOB_DATA(packet);
- *status = oob_data->status;
- switch (*status) {
- case NDIS_STATUS_SUCCESS:
- free_tx_packet(wnd, packet, *status);
- break;
- case NDIS_STATUS_PENDING:
- break;
- case NDIS_STATUS_RESOURCES:
- wnd->tx_ok = 0;
- break;
- case NDIS_STATUS_FAILURE:
- default:
- free_tx_packet(wnd, packet, *status);
- break;
- }
- }
- } else {
- irql = serialize_lock_irql(wnd);
- assert_irql(_irql_ == DISPATCH_LEVEL);
- *status = LIN2WIN3(mp->send, wnd->nmb->mp_ctx, packet, 0);
- serialize_unlock_irql(wnd, irql);
- switch (*status) {
- case NDIS_STATUS_SUCCESS:
- free_tx_packet(wnd, packet, *status);
- break;
- case NDIS_STATUS_PENDING:
- break;
- case NDIS_STATUS_RESOURCES:
- wnd->tx_ok = 0;
- break;
- case NDIS_STATUS_FAILURE:
- default:
- free_tx_packet(wnd, packet, *status);
- break;
- }
- }
- EXIT3(return);
-}
-
-/* called for serialized drivers only */
-wstdcall void mp_timer_dpc(struct kdpc *kdpc, void *ctx, void *arg1, void *arg2)
-{
- struct ndis_mp_timer *timer;
- struct ndis_mp_block *nmb;
-
- timer = ctx;
- TIMERENTER("%p, %p, %p, %p", timer, timer->func, timer->ctx, timer->nmb);
- assert_irql(_irql_ == DISPATCH_LEVEL);
- nmb = timer->nmb;
- serialize_lock(nmb->wnd);
- LIN2WIN4(timer->func, NULL, timer->ctx, NULL, NULL);
- serialize_unlock(nmb->wnd);
- TIMEREXIT(return);
-}
-WIN_FUNC_DECL(mp_timer_dpc,4)
-
-wstdcall void WIN_FUNC(NdisMInitializeTimer,4)
- (struct ndis_mp_timer *timer, struct ndis_mp_block *nmb,
- DPC func, void *ctx)
-{
- TIMERENTER("%p, %p, %p, %p", timer, func, ctx, nmb);
- assert_irql(_irql_ == PASSIVE_LEVEL);
- timer->func = func;
- timer->ctx = ctx;
- timer->nmb = nmb;
- if (deserialized_driver(nmb->wnd))
- KeInitializeDpc(&timer->kdpc, func, ctx);
- else
- KeInitializeDpc(&timer->kdpc, WIN_FUNC_PTR(mp_timer_dpc,4),
- timer);
- wrap_init_timer(&timer->nt_timer, NotificationTimer, nmb);
- TIMEREXIT(return);
-}
-
-wstdcall void WIN_FUNC(NdisMSetPeriodicTimer,2)
- (struct ndis_mp_timer *timer, UINT period_ms)
-{
- unsigned long expires = MSEC_TO_HZ(period_ms);
-
- TIMERENTER("%p, %u, %ld", timer, period_ms, expires);
- assert_irql(_irql_ <= DISPATCH_LEVEL);
- wrap_set_timer(&timer->nt_timer, expires, expires, &timer->kdpc);
- TIMEREXIT(return);
-}
-
-wstdcall void WIN_FUNC(NdisMCancelTimer,2)
- (struct ndis_mp_timer *timer, BOOLEAN *canceled)
-{
- TIMERENTER("%p", timer);
- assert_irql(_irql_ <= DISPATCH_LEVEL);
- *canceled = KeCancelTimer(&timer->nt_timer);
- TIMERTRACE("%d", *canceled);
- return;
-}
-
-wstdcall void WIN_FUNC(NdisInitializeTimer,3)
- (struct ndis_timer *timer, void *func, void *ctx)
-{
- TIMERENTER("%p, %p, %p", timer, func, ctx);
- assert_irql(_irql_ == PASSIVE_LEVEL);
- KeInitializeDpc(&timer->kdpc, func, ctx);
- wrap_init_timer(&timer->nt_timer, NotificationTimer, NULL);
- TIMEREXIT(return);
-}
-
-/* NdisMSetTimer is a macro that calls NdisSetTimer with
- * ndis_mp_timer typecast to ndis_timer */
-
-wstdcall void WIN_FUNC(NdisSetTimer,2)
- (struct ndis_timer *timer, UINT duetime_ms)
-{
- unsigned long expires = MSEC_TO_HZ(duetime_ms);
-
- TIMERENTER("%p, %p, %u, %ld", timer, timer->nt_timer.wrap_timer,
- duetime_ms, expires);
- assert_irql(_irql_ <= DISPATCH_LEVEL);
- wrap_set_timer(&timer->nt_timer, expires, 0, &timer->kdpc);
- TIMEREXIT(return);
-}
-
-wstdcall void WIN_FUNC(NdisCancelTimer,2)
- (struct ndis_timer *timer, BOOLEAN *canceled)
-{
- TIMERENTER("%p", timer);
- assert_irql(_irql_ <= DISPATCH_LEVEL);
- *canceled = KeCancelTimer(&timer->nt_timer);
- TIMEREXIT(return);
-}
-
-wstdcall void WIN_FUNC(NdisMRegisterAdapterShutdownHandler,3)
- (struct ndis_mp_block *nmb, void *ctx, void *func)
-{
- struct ndis_device *wnd = nmb->wnd;
- ENTER1("%p", func);
- wnd->wd->driver->ndis_driver->mp.shutdown = func;
- wnd->shutdown_ctx = ctx;
-}
-
-wstdcall void WIN_FUNC(NdisMDeregisterAdapterShutdownHandler,1)
- (struct ndis_mp_block *nmb)
-{
- struct ndis_device *wnd = nmb->wnd;
- wnd->wd->driver->ndis_driver->mp.shutdown = NULL;
- wnd->shutdown_ctx = NULL;
-}
-
-/* TODO: rt61 (serialized) driver doesn't want MiniportEnableInterrupt
- * to be called in irq handler, but mrv800c (deserialized) driver
- * wants. NDIS is confusing about when to call MiniportEnableInterrupt
- * For now, handle these cases with two separate irq handlers based on
- * observation of these two drivers. However, it is likely not
- * correct. */
-wstdcall void deserialized_irq_handler(struct kdpc *kdpc, void *ctx,
- void *arg1, void *arg2)
-{
- struct ndis_device *wnd = ctx;
- ndis_interrupt_handler irq_handler = arg1;
- struct miniport *mp = arg2;
-
- TRACE6("%p", irq_handler);
- assert_irql(_irql_ == DISPATCH_LEVEL);
- LIN2WIN1(irq_handler, wnd->nmb->mp_ctx);
- if (mp->enable_interrupt)
- LIN2WIN1(mp->enable_interrupt, wnd->nmb->mp_ctx);
- EXIT6(return);
-}
-WIN_FUNC_DECL(deserialized_irq_handler,4)
-
-wstdcall void serialized_irq_handler(struct kdpc *kdpc, void *ctx,
- void *arg1, void *arg2)
-{
- struct ndis_device *wnd = ctx;
- ndis_interrupt_handler irq_handler = arg1;
-
- TRACE6("%p, %p, %p", wnd, irq_handler, arg2);
- assert_irql(_irql_ == DISPATCH_LEVEL);
- serialize_lock(wnd);
- LIN2WIN1(irq_handler, arg2);
- serialize_unlock(wnd);
- EXIT6(return);
-}
-WIN_FUNC_DECL(serialized_irq_handler,4)
-
-wstdcall BOOLEAN ndis_isr(struct kinterrupt *kinterrupt, void *ctx)
-{
- struct ndis_mp_interrupt *mp_interrupt = ctx;
- struct ndis_device *wnd = mp_interrupt->nmb->wnd;
- BOOLEAN recognized = TRUE, queue_handler = TRUE;
-
- TRACE6("%p", wnd);
- /* kernel may call ISR when registering interrupt, in
- * the same context if DEBUG_SHIRQ is enabled */
- assert_irql(_irql_ == DIRQL || _irql_ == PASSIVE_LEVEL);
- if (mp_interrupt->shared)
- LIN2WIN3(mp_interrupt->isr, &recognized, &queue_handler,
- wnd->nmb->mp_ctx);
- else {
- struct miniport *mp;
- mp = &wnd->wd->driver->ndis_driver->mp;
- LIN2WIN1(mp->disable_interrupt, wnd->nmb->mp_ctx);
- /* it is not shared interrupt, so handler must be called */
- recognized = queue_handler = TRUE;
- }
- if (recognized) {
- if (queue_handler) {
- TRACE5("%p", &wnd->irq_kdpc);
- queue_kdpc(&wnd->irq_kdpc);
- }
- EXIT6(return TRUE);
- }
- EXIT6(return FALSE);
-}
-WIN_FUNC_DECL(ndis_isr,2)
-
-wstdcall NDIS_STATUS WIN_FUNC(NdisMRegisterInterrupt,7)
- (struct ndis_mp_interrupt *mp_interrupt,
- struct ndis_mp_block *nmb, UINT vector, UINT level,
- BOOLEAN req_isr, BOOLEAN shared, enum kinterrupt_mode mode)
-{
- struct ndis_device *wnd = nmb->wnd;
- struct miniport *mp;
-
- ENTER1("%p, vector:%d, level:%d, req_isr:%d, shared:%d, mode:%d",
- mp_interrupt, vector, level, req_isr, shared, mode);
-
- mp = &wnd->wd->driver->ndis_driver->mp;
- nt_spin_lock_init(&mp_interrupt->lock);
- mp_interrupt->irq = vector;
- mp_interrupt->isr = mp->isr;
- mp_interrupt->mp_dpc = mp->handle_interrupt;
- mp_interrupt->nmb = nmb;
- mp_interrupt->req_isr = req_isr;
- if (shared && !req_isr)
- WARNING("shared but dynamic interrupt!");
- mp_interrupt->shared = shared;
- wnd->mp_interrupt = mp_interrupt;
- if (mp->enable_interrupt)
- mp_interrupt->enable = TRUE;
- else
- mp_interrupt->enable = FALSE;
-
- if (deserialized_driver(wnd)) {
- KeInitializeDpc(&wnd->irq_kdpc,
- WIN_FUNC_PTR(deserialized_irq_handler,4),
- nmb->wnd);
- wnd->irq_kdpc.arg1 = mp->handle_interrupt;
- wnd->irq_kdpc.arg2 = mp;
- TRACE2("%p, %p, %p, %p", wnd->irq_kdpc.arg1, wnd->irq_kdpc.arg2,
- nmb->wnd, nmb->mp_ctx);
- } else {
- KeInitializeDpc(&wnd->irq_kdpc,
- WIN_FUNC_PTR(serialized_irq_handler,4),
- nmb->wnd);
- wnd->irq_kdpc.arg1 = mp->handle_interrupt;
- wnd->irq_kdpc.arg2 = nmb->mp_ctx;
- TRACE2("%p, %p, %p", wnd->irq_kdpc.arg1, wnd->irq_kdpc.arg2,
- nmb->wnd);
- }
-
- if (IoConnectInterrupt(&mp_interrupt->kinterrupt,
- WIN_FUNC_PTR(ndis_isr,2), mp_interrupt, NULL,
- vector, DIRQL, DIRQL, mode, shared, 0, FALSE) !=
- STATUS_SUCCESS) {
- printk(KERN_WARNING "%s: request for IRQ %d failed\n",
- DRIVER_NAME, vector);
- return NDIS_STATUS_RESOURCES;
- }
- printk(KERN_INFO "%s: using IRQ %d\n", DRIVER_NAME, vector);
- EXIT1(return NDIS_STATUS_SUCCESS);
-}
-
-wstdcall void WIN_FUNC(NdisMDeregisterInterrupt,1)
- (struct ndis_mp_interrupt *mp_interrupt)
-{
- struct ndis_mp_block *nmb;
-
- ENTER1("%p", mp_interrupt);
- nmb = xchg(&mp_interrupt->nmb, NULL);
- TRACE1("%p", nmb);
- if (!nmb) {
- WARNING("interrupt already freed?");
- return;
- }
- nmb->wnd->mp_interrupt = NULL;
- if (dequeue_kdpc(&nmb->wnd->irq_kdpc))
- TRACE2("interrupt kdpc was pending");
- flush_workqueue(wrapndis_wq);
- IoDisconnectInterrupt(mp_interrupt->kinterrupt);
- EXIT1(return);
-}
-
-wstdcall BOOLEAN WIN_FUNC(NdisMSynchronizeWithInterrupt,3)
- (struct ndis_mp_interrupt *mp_interrupt,
- PKSYNCHRONIZE_ROUTINE sync_func, void *ctx)
-{
- return KeSynchronizeExecution(mp_interrupt->kinterrupt, sync_func, ctx);
-}
-
-/* called via function pointer; but 64-bit RNDIS driver calls directly */
-wstdcall void WIN_FUNC(NdisMIndicateStatus,4)
- (struct ndis_mp_block *nmb, NDIS_STATUS status, void *buf, UINT len)
-{
- struct ndis_device *wnd = nmb->wnd;
- struct ndis_status_indication *si;
-
- ENTER2("status=0x%x len=%d", status, len);
- switch (status) {
- case NDIS_STATUS_MEDIA_CONNECT:
- set_media_state(wnd, NdisMediaStateConnected);
- break;
- case NDIS_STATUS_MEDIA_DISCONNECT:
- set_media_state(wnd, NdisMediaStateDisconnected);
- break;
- case NDIS_STATUS_MEDIA_SPECIFIC_INDICATION:
- if (!buf)
- break;
- si = buf;
- TRACE2("status_type=%d", si->status_type);
- switch (si->status_type) {
- case Ndis802_11StatusType_MediaStreamMode:
- break;
-#ifdef CONFIG_WIRELESS_EXT
- case Ndis802_11StatusType_Authentication:
- buf = (char *)buf + sizeof(*si);
- len -= sizeof(*si);
- while (len > 0) {
- int pairwise_error = 0, group_error = 0;
- struct ndis_auth_req *auth_req =
- (struct ndis_auth_req *)buf;
- TRACE1(MACSTRSEP, MAC2STR(auth_req->bssid));
- if (auth_req->flags & 0x01)
- TRACE2("reauth request");
- if (auth_req->flags & 0x02)
- TRACE2("key update request");
- if (auth_req->flags & 0x06) {
- pairwise_error = 1;
- TRACE2("pairwise_error");
- }
- if (auth_req->flags & 0x0E) {
- group_error = 1;
- TRACE2("group_error");
- }
- if (pairwise_error || group_error) {
- union iwreq_data wrqu;
- struct iw_michaelmicfailure micfailure;
-
- memset(&micfailure, 0, sizeof(micfailure));
- if (pairwise_error)
- micfailure.flags |=
- IW_MICFAILURE_PAIRWISE;
- if (group_error)
- micfailure.flags |=
- IW_MICFAILURE_GROUP;
- memcpy(micfailure.src_addr.sa_data,
- auth_req->bssid, ETH_ALEN);
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.data.length = sizeof(micfailure);
- wireless_send_event(wnd->net_dev,
- IWEVMICHAELMICFAILURE,
- &wrqu, (u8 *)&micfailure);
- }
- len -= auth_req->length;
- buf = (char *)buf + auth_req->length;
- }
- break;
- case Ndis802_11StatusType_PMKID_CandidateList:
- {
- u8 *end;
- unsigned long i;
- struct ndis_pmkid_candidate_list *cand;
-
- cand = buf + sizeof(struct ndis_status_indication);
- if (len < sizeof(struct ndis_status_indication) +
- sizeof(struct ndis_pmkid_candidate_list) ||
- cand->version != 1) {
- WARNING("unrecognized PMKID ignored");
- EXIT1(return);
- }
-
- end = (u8 *)buf + len;
- TRACE2("PMKID ver %d num_cand %d",
- cand->version, cand->num_candidates);
- for (i = 0; i < cand->num_candidates; i++) {
- struct iw_pmkid_cand pcand;
- union iwreq_data wrqu;
- struct ndis_pmkid_candidate *c =
- &cand->candidates[i];
- if ((u8 *)(c + 1) > end) {
- TRACE2("truncated PMKID");
- break;
- }
- TRACE2("%ld: " MACSTRSEP " 0x%x",
- i, MAC2STR(c->bssid), c->flags);
- memset(&pcand, 0, sizeof(pcand));
- if (c->flags & 0x01)
- pcand.flags |= IW_PMKID_CAND_PREAUTH;
- pcand.index = i;
- memcpy(pcand.bssid.sa_data, c->bssid, ETH_ALEN);
-
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.data.length = sizeof(pcand);
- wireless_send_event(wnd->net_dev, IWEVPMKIDCAND,
- &wrqu, (u8 *)&pcand);
- }
- break;
- }
- case Ndis802_11StatusType_RadioState:
- {
- struct ndis_radio_status_indication *radio_status = buf;
- if (radio_status->radio_state ==
- Ndis802_11RadioStatusOn)
- INFO("radio is turned on");
- else if (radio_status->radio_state ==
- Ndis802_11RadioStatusHardwareOff)
- INFO("radio is turned off by hardware");
- else if (radio_status->radio_state ==
- Ndis802_11RadioStatusSoftwareOff)
- INFO("radio is turned off by software");
- break;
- }
-#endif
- default:
- /* is this RSSI indication? */
- TRACE2("unknown indication: %x", si->status_type);
- break;
- }
- break;
- default:
- TRACE2("unknown status: %08X", status);
- break;
- }
-
- EXIT2(return);
-}
-
-/* called via function pointer; but 64-bit RNDIS driver calls directly */
-wstdcall void WIN_FUNC(NdisMIndicateStatusComplete,1)
- (struct ndis_mp_block *nmb)
-{
- struct ndis_device *wnd = nmb->wnd;
- ENTER2("%p", wnd);
- if (wnd->tx_ok)
- schedule_wrapndis_work(&wnd->tx_work);
-}
-
-/* called via function pointer */
-wstdcall void NdisMSendComplete(struct ndis_mp_block *nmb,
- struct ndis_packet *packet, NDIS_STATUS status)
-{
- struct ndis_device *wnd = nmb->wnd;
- ENTER4("%p, %08X", packet, status);
- assert_irql(_irql_ <= DISPATCH_LEVEL);
- if (deserialized_driver(wnd))
- free_tx_packet(wnd, packet, status);
- else {
- struct ndis_packet_oob_data *oob_data;
- NDIS_STATUS pkt_status;
- TRACE3("%p, %08x", packet, status);
- oob_data = NDIS_PACKET_OOB_DATA(packet);
- switch ((pkt_status = xchg(&oob_data->status, status))) {
- case NDIS_STATUS_NOT_RECOGNIZED:
- free_tx_packet(wnd, packet, status);
- break;
- case NDIS_STATUS_PENDING:
- case 0:
- break;
- default:
- WARNING("%p: invalid status: %08X", packet, pkt_status);
- break;
- }
- /* In case a serialized driver has earlier requested a
- * pause by returning NDIS_STATUS_RESOURCES during
- * MiniportSend(Packets), wakeup tx worker now.
- */
- if (xchg(&wnd->tx_ok, 1) == 0) {
- TRACE3("%d, %d", wnd->tx_ring_start, wnd->tx_ring_end);
- schedule_wrapndis_work(&wnd->tx_work);
- }
- }
- EXIT3(return);
-}
-
-/* called via function pointer */
-wstdcall void NdisMSendResourcesAvailable(struct ndis_mp_block *nmb)
-{
- struct ndis_device *wnd = nmb->wnd;
- ENTER3("%d, %d", wnd->tx_ring_start, wnd->tx_ring_end);
- wnd->tx_ok = 1;
- schedule_wrapndis_work(&wnd->tx_work);
- EXIT3(return);
-}
-
-wstdcall void return_packet(void *arg1, void *arg2)
-{
- struct ndis_device *wnd;
- struct ndis_packet *packet;
- struct miniport *mp;
- KIRQL irql;
-
- wnd = arg1;
- packet = arg2;
- ENTER4("%p, %p", wnd, packet);
- mp = &wnd->wd->driver->ndis_driver->mp;
- irql = serialize_lock_irql(wnd);
- assert_irql(_irql_ == DISPATCH_LEVEL);
- LIN2WIN2(mp->return_packet, wnd->nmb->mp_ctx, packet);
- serialize_unlock_irql(wnd, irql);
- EXIT4(return);
-}
-WIN_FUNC_DECL(return_packet,2)
-
-/* called via function pointer */
-wstdcall void NdisMIndicateReceivePacket(struct ndis_mp_block *nmb,
- struct ndis_packet **packets,
- UINT nr_packets)
-{
- struct ndis_device *wnd;
- ndis_buffer *buffer;
- struct ndis_packet *packet;
- struct sk_buff *skb;
- ULONG i, length, total_length;
- struct ndis_packet_oob_data *oob_data;
- void *virt;
- struct ndis_tcp_ip_checksum_packet_info csum;
-
- ENTER3("%p, %d", nmb, nr_packets);
- assert_irql(_irql_ <= DISPATCH_LEVEL);
- wnd = nmb->wnd;
- for (i = 0; i < nr_packets; i++) {
- packet = packets[i];
- if (!packet) {
- WARNING("empty packet ignored");
- continue;
- }
- wnd->net_dev->last_rx = jiffies;
- /* get total number of bytes in packet */
- NdisGetFirstBufferFromPacketSafe(packet, &buffer, &virt,
- &length, &total_length,
- NormalPagePriority);
- TRACE3("%d, %d", length, total_length);
- oob_data = NDIS_PACKET_OOB_DATA(packet);
- TRACE3("0x%x, 0x%x, %Lu", packet->private.flags,
- packet->private.packet_flags, oob_data->time_rxed);
- skb = dev_alloc_skb(total_length);
- if (skb) {
- while (buffer) {
- memcpy_skb(skb, MmGetSystemAddressForMdl(buffer),
- MmGetMdlByteCount(buffer));
- buffer = buffer->next;
- }
- skb->dev = wnd->net_dev;
- skb->protocol = eth_type_trans(skb, wnd->net_dev);
- pre_atomic_add(wnd->net_stats.rx_bytes, total_length);
- atomic_inc_var(wnd->net_stats.rx_packets);
- csum.value = (typeof(csum.value))(ULONG_PTR)
- oob_data->ext.info[TcpIpChecksumPacketInfo];
- TRACE3("0x%05x", csum.value);
- if (wnd->rx_csum.value &&
- (csum.rx.tcp_succeeded || csum.rx.udp_succeeded ||
- csum.rx.ip_succeeded))
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- else
- skb->ip_summed = CHECKSUM_NONE;
-
- if (in_interrupt())
- netif_rx(skb);
- else
- netif_rx_ni(skb);
- } else {
- WARNING("couldn't allocate skb; packet dropped");
- atomic_inc_var(wnd->net_stats.rx_dropped);
- }
-
- /* serialized drivers check the status upon return
- * from this function */
- if (!deserialized_driver(wnd)) {
- oob_data->status = NDIS_STATUS_SUCCESS;
- continue;
- }
-
- /* if a deserialized driver sets
- * NDIS_STATUS_RESOURCES, then it reclaims the packet
- * upon return from this function */
- if (oob_data->status == NDIS_STATUS_RESOURCES)
- continue;
-
- assert(oob_data->status == NDIS_STATUS_SUCCESS);
- /* deserialized driver doesn't check the status upon
- * return from this function; we need to call
- * MiniportReturnPacket later for this packet. Calling
- * MiniportReturnPacket from here is not correct - the
- * driver doesn't expect it (at least Centrino driver
- * crashes) */
- schedule_ntos_work_item(WIN_FUNC_PTR(return_packet,2),
- wnd, packet);
- }
- EXIT3(return);
-}
-
-/* called via function pointer (by NdisMEthIndicateReceive macro); the
- * first argument is nmb->eth_db */
-wstdcall void EthRxIndicateHandler(struct ndis_mp_block *nmb, void *rx_ctx,
- char *header1, char *header, UINT header_size,
- void *look_ahead, UINT look_ahead_size,
- UINT packet_size)
-{
- struct sk_buff *skb = NULL;
- struct ndis_device *wnd;
- unsigned int skb_size = 0;
- KIRQL irql;
- struct ndis_packet_oob_data *oob_data;
-
- ENTER3("nmb = %p, rx_ctx = %p, buf = %p, size = %d, buf = %p, "
- "size = %d, packet = %d", nmb, rx_ctx, header, header_size,
- look_ahead, look_ahead_size, packet_size);
-
- wnd = nmb->wnd;
- TRACE3("wnd = %p", wnd);
- if (!wnd) {
- ERROR("nmb is NULL");
- EXIT3(return);
- }
- wnd->net_dev->last_rx = jiffies;
-
- if (look_ahead_size < packet_size) {
- struct ndis_packet *packet;
- struct miniport *mp;
- unsigned int bytes_txed;
- NDIS_STATUS res;
-
- NdisAllocatePacket(&res, &packet, wnd->tx_packet_pool);
- if (res != NDIS_STATUS_SUCCESS) {
- atomic_inc_var(wnd->net_stats.rx_dropped);
- EXIT3(return);
- }
- oob_data = NDIS_PACKET_OOB_DATA(packet);
- mp = &wnd->wd->driver->ndis_driver->mp;
- irql = serialize_lock_irql(wnd);
- assert_irql(_irql_ == DISPATCH_LEVEL);
- res = LIN2WIN6(mp->tx_data, packet, &bytes_txed, nmb,
- rx_ctx, look_ahead_size, packet_size);
- serialize_unlock_irql(wnd, irql);
- TRACE3("%d, %d, %d", header_size, look_ahead_size, bytes_txed);
- if (res == NDIS_STATUS_SUCCESS) {
- ndis_buffer *buffer;
- struct ndis_tcp_ip_checksum_packet_info csum;
- skb = dev_alloc_skb(header_size + look_ahead_size +
- bytes_txed);
- if (!skb) {
- ERROR("couldn't allocate skb; packet dropped");
- atomic_inc_var(wnd->net_stats.rx_dropped);
- NdisFreePacket(packet);
- return;
- }
- memcpy_skb(skb, header, header_size);
- memcpy_skb(skb, look_ahead, look_ahead_size);
- buffer = packet->private.buffer_head;
- while (buffer) {
- memcpy_skb(skb,
- MmGetSystemAddressForMdl(buffer),
- MmGetMdlByteCount(buffer));
- buffer = buffer->next;
- }
- skb_size = header_size + look_ahead_size + bytes_txed;
- csum.value = (typeof(csum.value))(ULONG_PTR)
- oob_data->ext.info[TcpIpChecksumPacketInfo];
- TRACE3("0x%05x", csum.value);
- if (wnd->rx_csum.value &&
- (csum.rx.tcp_succeeded || csum.rx.udp_succeeded))
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- else
- skb->ip_summed = CHECKSUM_NONE;
- NdisFreePacket(packet);
- } else if (res == NDIS_STATUS_PENDING) {
- /* driver will call td_complete */
- oob_data->look_ahead = kmalloc(look_ahead_size,
- GFP_ATOMIC);
- if (!oob_data->look_ahead) {
- NdisFreePacket(packet);
- ERROR("packet dropped");
- atomic_inc_var(wnd->net_stats.rx_dropped);
- EXIT3(return);
- }
- assert(sizeof(oob_data->header) == header_size);
- memcpy(oob_data->header, header,
- sizeof(oob_data->header));
- memcpy(oob_data->look_ahead, look_ahead,
- look_ahead_size);
- oob_data->look_ahead_size = look_ahead_size;
- EXIT3(return);
- } else {
- WARNING("packet dropped: %08X", res);
- atomic_inc_var(wnd->net_stats.rx_dropped);
- NdisFreePacket(packet);
- EXIT3(return);
- }
- } else {
- skb_size = header_size + packet_size;
- skb = dev_alloc_skb(skb_size);
- if (skb) {
- memcpy_skb(skb, header, header_size);
- memcpy_skb(skb, look_ahead, packet_size);
- }
- }
-
- if (skb) {
- skb->dev = wnd->net_dev;
- skb->protocol = eth_type_trans(skb, wnd->net_dev);
- pre_atomic_add(wnd->net_stats.rx_bytes, skb_size);
- atomic_inc_var(wnd->net_stats.rx_packets);
- if (in_interrupt())
- netif_rx(skb);
- else
- netif_rx_ni(skb);
- }
-
- EXIT3(return);
-}
-
-/* called via function pointer */
-wstdcall void NdisMTransferDataComplete(struct ndis_mp_block *nmb,
- struct ndis_packet *packet,
- NDIS_STATUS status, UINT bytes_txed)
-{
- struct ndis_device *wnd = nmb->wnd;
- struct sk_buff *skb;
- unsigned int skb_size;
- struct ndis_packet_oob_data *oob_data;
- ndis_buffer *buffer;
- struct ndis_tcp_ip_checksum_packet_info csum;
-
- ENTER3("wnd = %p, packet = %p, bytes_txed = %d",
- wnd, packet, bytes_txed);
- if (!packet) {
- WARNING("illegal packet");
- EXIT3(return);
- }
- wnd->net_dev->last_rx = jiffies;
- oob_data = NDIS_PACKET_OOB_DATA(packet);
- skb_size = sizeof(oob_data->header) + oob_data->look_ahead_size +
- bytes_txed;
- skb = dev_alloc_skb(skb_size);
- if (!skb) {
- kfree(oob_data->look_ahead);
- NdisFreePacket(packet);
- ERROR("couldn't allocate skb; packet dropped");
- atomic_inc_var(wnd->net_stats.rx_dropped);
- EXIT3(return);
- }
- memcpy_skb(skb, oob_data->header, sizeof(oob_data->header));
- memcpy_skb(skb, oob_data->look_ahead, oob_data->look_ahead_size);
- buffer = packet->private.buffer_head;
- while (buffer) {
- memcpy_skb(skb, MmGetSystemAddressForMdl(buffer),
- MmGetMdlByteCount(buffer));
- buffer = buffer->next;
- }
- kfree(oob_data->look_ahead);
- NdisFreePacket(packet);
- skb->dev = wnd->net_dev;
- skb->protocol = eth_type_trans(skb, wnd->net_dev);
- pre_atomic_add(wnd->net_stats.rx_bytes, skb_size);
- atomic_inc_var(wnd->net_stats.rx_packets);
-
- csum.value = (typeof(csum.value))(ULONG_PTR)
- oob_data->ext.info[TcpIpChecksumPacketInfo];
- TRACE3("0x%05x", csum.value);
- if (wnd->rx_csum.value &&
- (csum.rx.tcp_succeeded || csum.rx.udp_succeeded))
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- else
- skb->ip_summed = CHECKSUM_NONE;
-
- if (in_interrupt())
- netif_rx(skb);
- else
- netif_rx_ni(skb);
-}
-
-/* called via function pointer */
-wstdcall void EthRxComplete(struct ndis_mp_block *nmb)
-{
- TRACE3("");
-}
-
-/* called via function pointer */
-wstdcall void NdisMQueryInformationComplete(struct ndis_mp_block *nmb,
- NDIS_STATUS status)
-{
- struct ndis_device *wnd = nmb->wnd;
- typeof(wnd->ndis_req_task) task;
-
- ENTER2("nmb: %p, wnd: %p, %08X", nmb, wnd, status);
- wnd->ndis_req_status = status;
- wnd->ndis_req_done = 1;
- if ((task = xchg(&wnd->ndis_req_task, NULL)))
- wake_up_process(task);
- else
- WARNING("invalid task");
- EXIT2(return);
-}
-
-/* called via function pointer */
-wstdcall void NdisMSetInformationComplete(struct ndis_mp_block *nmb,
- NDIS_STATUS status)
-{
- struct ndis_device *wnd = nmb->wnd;
- typeof(wnd->ndis_req_task) task;
-
- ENTER2("status = %08X", status);
- wnd->ndis_req_status = status;
- wnd->ndis_req_done = 1;
- if ((task = xchg(&wnd->ndis_req_task, NULL)))
- wake_up_process(task);
- else
- WARNING("invalid task");
- EXIT2(return);
-}
-
-/* called via function pointer */
-wstdcall void NdisMResetComplete(struct ndis_mp_block *nmb,
- NDIS_STATUS status, BOOLEAN address_reset)
-{
- struct ndis_device *wnd = nmb->wnd;
- typeof(wnd->ndis_req_task) task;
-
- ENTER2("status: %08X, %u", status, address_reset);
- wnd->ndis_req_status = status;
- wnd->ndis_req_done = address_reset + 1;
- if ((task = xchg(&wnd->ndis_req_task, NULL)))
- wake_up_process(task);
- else
- WARNING("invalid task");
- EXIT2(return);
-}
-
-wstdcall void WIN_FUNC(NdisMSleep,1)
- (ULONG us)
-{
- unsigned long delay;
-
- ENTER4("%p: us: %u", current, us);
- delay = USEC_TO_HZ(us);
- sleep_hz(delay);
- TRACE4("%p: done", current);
-}
-
-wstdcall void WIN_FUNC(NdisGetCurrentSystemTime,1)
- (LARGE_INTEGER *time)
-{
- *time = ticks_1601();
- TRACE5("%Lu, %lu", *time, jiffies);
-}
-
-wstdcall LONG WIN_FUNC(NdisInterlockedDecrement,1)
- (LONG *val)
-{
- return InterlockedDecrement(val);
-}
-
-wstdcall LONG WIN_FUNC(NdisInterlockedIncrement,1)
- (LONG *val)
-{
- return InterlockedIncrement(val);
-}
-
-wstdcall struct nt_list *WIN_FUNC(NdisInterlockedInsertHeadList,3)
- (struct nt_list *head, struct nt_list *entry,
- struct ndis_spinlock *lock)
-{
- return ExInterlockedInsertHeadList(head, entry, &lock->klock);
-}
-
-wstdcall struct nt_list *WIN_FUNC(NdisInterlockedInsertTailList,3)
- (struct nt_list *head, struct nt_list *entry,
- struct ndis_spinlock *lock)
-{
- return ExInterlockedInsertTailList(head, entry, &lock->klock);
-}
-
-wstdcall struct nt_list *WIN_FUNC(NdisInterlockedRemoveHeadList,2)
- (struct nt_list *head, struct ndis_spinlock *lock)
-{
- return ExInterlockedRemoveHeadList(head, &lock->klock);
-}
-
-wstdcall NDIS_STATUS WIN_FUNC(NdisMInitializeScatterGatherDma,3)
- (struct ndis_mp_block *nmb, BOOLEAN dma_size, ULONG max_phy_map)
-{
- struct ndis_device *wnd = nmb->wnd;
- ENTER2("dma_size=%d, maxtransfer=%u", dma_size, max_phy_map);
-#ifdef CONFIG_X86_64
- if (dma_size != NDIS_DMA_64BITS) {
- TRACE1("DMA size is not 64-bits");
- if (pci_set_dma_mask(wnd->wd->pci.pdev, DMA_BIT_MASK(32)) ||
- pci_set_consistent_dma_mask(wnd->wd->pci.pdev,
- DMA_BIT_MASK(32)))
- WARNING("setting dma mask failed");
- }
-#endif
- if ((wnd->attributes & NDIS_ATTRIBUTE_BUS_MASTER) &&
- wrap_is_pci_bus(wnd->wd->dev_bus)) {
- wnd->sg_dma_size = max_phy_map;
- return NDIS_STATUS_SUCCESS;
- } else
- EXIT1(return NDIS_STATUS_NOT_SUPPORTED);
-}
-
-wstdcall ULONG WIN_FUNC(NdisMGetDmaAlignment,1)
- (struct ndis_mp_block *nmb)
-{
- ENTER3("");
- return dma_get_cache_alignment();
-}
-
-wstdcall CHAR WIN_FUNC(NdisSystemProcessorCount,0)
- (void)
-{
- return (CHAR)NR_CPUS;
-}
-
-wstdcall void WIN_FUNC(NdisGetCurrentProcessorCounts,3)
- (ULONG *idle, ULONG *kernel_user, ULONG *index)
-{
- int cpu = smp_processor_id();
- *idle = kstat_cpu(cpu).cpustat.idle;
- *kernel_user = kstat_cpu(cpu).cpustat.system +
- kstat_cpu(cpu).cpustat.user;
- *index = cpu;
-}
-
-wstdcall void WIN_FUNC(NdisInitializeEvent,1)
- (struct ndis_event *ndis_event)
-{
- EVENTENTER("%p", ndis_event);
- KeInitializeEvent(&ndis_event->nt_event, NotificationEvent, 0);
-}
-
-wstdcall BOOLEAN WIN_FUNC(NdisWaitEvent,2)
- (struct ndis_event *ndis_event, UINT ms)
-{
- LARGE_INTEGER ticks;
- NTSTATUS res;
-
- EVENTENTER("%p %u", ndis_event, ms);
- ticks = -((LARGE_INTEGER)ms * TICKSPERMSEC);
- res = KeWaitForSingleObject(&ndis_event->nt_event, 0, 0, TRUE,
- ms == 0 ? NULL : &ticks);
- if (res == STATUS_SUCCESS)
- EXIT3(return TRUE);
- else
- EXIT3(return FALSE);
-}
-
-wstdcall void WIN_FUNC(NdisSetEvent,1)
- (struct ndis_event *ndis_event)
-{
- EVENTENTER("%p", ndis_event);
- KeSetEvent(&ndis_event->nt_event, 0, 0);
-}
-
-wstdcall void WIN_FUNC(NdisResetEvent,1)
- (struct ndis_event *ndis_event)
-{
- EVENTENTER("%p", ndis_event);
- KeResetEvent(&ndis_event->nt_event);
-}
-
-static void ndis_worker(worker_param_t dummy)
-{
- struct nt_list *ent;
- struct ndis_work_item *ndis_work_item;
-
- WORKENTER("");
- while (1) {
- spin_lock_bh(&ndis_work_list_lock);
- ent = RemoveHeadList(&ndis_work_list);
- spin_unlock_bh(&ndis_work_list_lock);
- if (!ent)
- break;
- ndis_work_item = container_of(ent, struct ndis_work_item, list);
- WORKTRACE("%p: %p, %p", ndis_work_item,
- ndis_work_item->func, ndis_work_item->ctx);
- LIN2WIN2(ndis_work_item->func, ndis_work_item,
- ndis_work_item->ctx);
- WORKTRACE("%p done", ndis_work_item);
- }
- WORKEXIT(return);
-}
-
-wstdcall NDIS_STATUS WIN_FUNC(NdisScheduleWorkItem,1)
- (struct ndis_work_item *ndis_work_item)
-{
- ENTER3("%p", ndis_work_item);
- spin_lock_bh(&ndis_work_list_lock);
- InsertTailList(&ndis_work_list, &ndis_work_item->list);
- spin_unlock_bh(&ndis_work_list_lock);
- WORKTRACE("scheduling %p", ndis_work_item);
- schedule_ndis_work(&ndis_work);
- EXIT3(return NDIS_STATUS_SUCCESS);
-}
-
-wstdcall void WIN_FUNC(NdisMGetDeviceProperty,6)
- (struct ndis_mp_block *nmb, void **phy_dev, void **func_dev,
- void **next_dev, void **alloc_res, void**trans_res)
-{
- ENTER2("nmb: %p, phy_dev = %p, func_dev = %p, next_dev = %p, "
- "alloc_res = %p, trans_res = %p", nmb, phy_dev, func_dev,
- next_dev, alloc_res, trans_res);
- if (phy_dev)
- *phy_dev = nmb->pdo;
- if (func_dev)
- *func_dev = nmb->fdo;
- if (next_dev)
- *next_dev = nmb->next_device;
-}
-
-wstdcall void WIN_FUNC(NdisMRegisterUnloadHandler,2)
- (struct driver_object *drv_obj, void *unload)
-{
- if (drv_obj)
- drv_obj->unload = unload;
- return;
-}
-
-wstdcall UINT WIN_FUNC(NdisGetVersion,0)
- (void)
-{
- return 0x00050001;
-}
-
-wstdcall NDIS_STATUS WIN_FUNC(NdisMQueryAdapterInstanceName,2)
- (struct unicode_string *name, struct ndis_mp_block *nmb)
-{
- struct ndis_device *wnd = nmb->wnd;
- struct ansi_string ansi;
-
- if (wrap_is_pci_bus(wnd->wd->dev_bus))
- RtlInitAnsiString(&ansi, "PCI Ethernet Adapter");
- else
- RtlInitAnsiString(&ansi, "USB Ethernet Adapter");
-
- if (RtlAnsiStringToUnicodeString(name, &ansi, TRUE))
- EXIT2(return NDIS_STATUS_RESOURCES);
- else
- EXIT2(return NDIS_STATUS_SUCCESS);
-}
-
-wstdcall NDIS_STATUS WIN_FUNC(NdisWriteEventLogEntry,7)
- (void *handle, NDIS_STATUS code, ULONG value, USHORT n,
- void *strings, ULONG datasize, void *data)
-{
- TRACE1("0x%x, 0x%x, %u, %u", code, value, n, datasize);
- return NDIS_STATUS_SUCCESS;
-}
-
-wstdcall void *WIN_FUNC(NdisGetRoutineAddress,1)
- (struct unicode_string *unicode_string)
-{
- struct ansi_string ansi_string;
- void *address;
-
- if (RtlUnicodeStringToAnsiString(&ansi_string, unicode_string, TRUE) !=
- STATUS_SUCCESS)
- EXIT1(return NULL);
- INFO("%s", ansi_string.buf);
- address = ndis_get_routine_address(ansi_string.buf);
- RtlFreeAnsiString(&ansi_string);
- return address;
-}
-
-wstdcall ULONG WIN_FUNC(NdisReadPcmciaAttributeMemory,4)
- (struct ndis_mp_block *nmb, ULONG offset, void *buffer,
- ULONG length)
-{
- TODO();
- return 0;
-}
-
-wstdcall ULONG WIN_FUNC(NdisWritePcmciaAttributeMemory,4)
- (struct ndis_mp_block *nmb, ULONG offset, void *buffer,
- ULONG length)
-{
- TODO();
- return 0;
-}
-
-wstdcall void WIN_FUNC(NdisMCoIndicateReceivePacket,3)
- (struct ndis_mp_block *nmb, struct ndis_packet **packets,
- UINT nr_packets)
-{
- ENTER3("nmb = %p", nmb);
- NdisMIndicateReceivePacket(nmb, packets, nr_packets);
- EXIT3(return);
-}
-
-wstdcall void WIN_FUNC(NdisMCoSendComplete,3)
- (NDIS_STATUS status, struct ndis_mp_block *nmb,
- struct ndis_packet *packet)
-{
- ENTER3("%08x", status);
- NdisMSendComplete(nmb, packet, status);
- EXIT3(return);
-}
-
-wstdcall void WIN_FUNC(NdisMCoRequestComplete,3)
- (NDIS_STATUS status, struct ndis_mp_block *nmb,
- struct ndis_request *ndis_request)
-{
- struct ndis_device *wnd = nmb->wnd;
- typeof(wnd->ndis_req_task) task;
-
- ENTER3("%08X", status);
- wnd->ndis_req_status = status;
- wnd->ndis_req_done = 1;
- if ((task = xchg(&wnd->ndis_req_task, NULL)))
- wake_up_process(task);
- else
- WARNING("invalid task");
- EXIT3(return);
-}
-
-wstdcall NDIS_STATUS WIN_FUNC(NdisIMNotifiyPnPEvent,2)
- (struct ndis_mp_block *nmb, struct net_pnp_event *event)
-{
- ENTER2("%p, %d", nmb, event->code);
- /* NdisWrapper never calls protocol's pnp event notifier, so
- * nothing to do here */
- EXIT2(return NDIS_STATUS_SUCCESS);
-}
-
-wstdcall void WIN_FUNC(NdisCompletePnPEvent,2)
- (NDIS_STATUS status, void *handle, struct net_pnp_event *event)
-{
- ENTER2("%d, %p, %d", status, handle, event->code);
- /* NdisWrapper never calls protocol's pnp event notifier, so
- * nothing to do here */
- EXIT2(return);
-}
-
-wstdcall NDIS_STATUS WIN_FUNC(NdisMSetMiniportSecondary,2)
- (struct ndis_mp_block *nmb2, struct ndis_mp_block *nmb1)
-{
- ENTER3("%p, %p", nmb1, nmb2);
- TODO();
- EXIT3(return NDIS_STATUS_SUCCESS);
-}
-
-wstdcall NDIS_STATUS WIN_FUNC(NdisMPromoteMiniport,1)
- (struct ndis_mp_block *nmb)
-{
- ENTER3("%p", nmb);
- TODO();
- EXIT3(return NDIS_STATUS_SUCCESS);
-}
-
-wstdcall void WIN_FUNC(NdisMCoActivateVcComplete,3)
- (NDIS_STATUS status, void *handle, void *params)
-{
- TODO();
-}
-
-wstdcall void WIN_FUNC(NdisMCoDeactivateVcComplete,2)
- (NDIS_STATUS status, void *handle)
-{
- TODO();
-}
-
-wstdcall void WIN_FUNC(NdisMRemoveMiniport,1)
- (void *handle)
-{
- TODO();
-}
-
-static void *ndis_get_routine_address(char *name)
-{
- int i;
- ENTER2("%p", name);
- for (i = 0; i < sizeof(ndis_exports) / sizeof(ndis_exports[0]); i++) {
- if (strcmp(name, ndis_exports[i].name) == 0) {
- TRACE2("%p", ndis_exports[i].func);
- return ndis_exports[i].func;
- }
- }
- EXIT2(return NULL);
-}
-
-/* ndis_init_device is called for each device */
-int ndis_init_device(struct ndis_device *wnd)
-{
- struct ndis_mp_block *nmb = wnd->nmb;
-
- KeInitializeSpinLock(&nmb->lock);
- wnd->mp_interrupt = NULL;
- wnd->wrap_timer_slist.next = NULL;
- if (wnd->wd->driver->ndis_driver)
- wnd->wd->driver->ndis_driver->mp.shutdown = NULL;
-
- nmb->filterdbs.eth_db = nmb;
- nmb->filterdbs.tr_db = nmb;
- nmb->filterdbs.fddi_db = nmb;
- nmb->filterdbs.arc_db = nmb;
-
- nmb->rx_packet = WIN_FUNC_PTR(NdisMIndicateReceivePacket,3);
- nmb->send_complete = WIN_FUNC_PTR(NdisMSendComplete,3);
- nmb->send_resource_avail = WIN_FUNC_PTR(NdisMSendResourcesAvailable,1);
- nmb->status = WIN_FUNC_PTR(NdisMIndicateStatus,4);
- nmb->status_complete = WIN_FUNC_PTR(NdisMIndicateStatusComplete,1);
- nmb->queryinfo_complete = WIN_FUNC_PTR(NdisMQueryInformationComplete,2);
- nmb->setinfo_complete = WIN_FUNC_PTR(NdisMSetInformationComplete,2);
- nmb->reset_complete = WIN_FUNC_PTR(NdisMResetComplete,3);
- nmb->eth_rx_indicate = WIN_FUNC_PTR(EthRxIndicateHandler,8);
- nmb->eth_rx_complete = WIN_FUNC_PTR(EthRxComplete,1);
- nmb->td_complete = WIN_FUNC_PTR(NdisMTransferDataComplete,4);
- return 0;
-}
-
-/* ndis_exit_device is called for each device */
-void ndis_exit_device(struct ndis_device *wnd)
-{
- struct wrap_device_setting *setting;
- ENTER2("%p", wnd);
- if (down_interruptible(&loader_mutex))
- WARNING("couldn't obtain loader_mutex");
- nt_list_for_each_entry(setting, &wnd->wd->settings, list) {
- struct ndis_configuration_parameter *param;
- param = setting->encoded;
- if (param) {
- if (param->type == NdisParameterString)
- RtlFreeUnicodeString(¶m->data.string);
- ExFreePool(param);
- setting->encoded = NULL;
- }
- }
- up(&loader_mutex);
-}
-
-/* ndis_init is called once when module is loaded */
-int ndis_init(void)
-{
- InitializeListHead(&ndis_work_list);
- spin_lock_init(&ndis_work_list_lock);
- initialize_work(&ndis_work, ndis_worker, NULL);
-
- ndis_wq = create_singlethread_workqueue("ndis_wq");
- if (!ndis_wq) {
- WARNING("couldn't create worker thread");
- EXIT1(return -ENOMEM);
- }
-
- ndis_worker_thread = wrap_worker_init(ndis_wq);
- TRACE1("%p", ndis_worker_thread);
- return 0;
-}
-
-/* ndis_exit is called once when module is removed */
-void ndis_exit(void)
-{
- ENTER1("");
- if (ndis_wq)
- destroy_workqueue(ndis_wq);
- TRACE1("%p", ndis_worker_thread);
- if (ndis_worker_thread)
- ObDereferenceObject(ndis_worker_thread);
- EXIT1(return);
-}
+++ /dev/null
-/*
- * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef _NDIS_H_
-#define _NDIS_H_
-
-#include "ntoskernel.h"
-
-//#define ALLOW_POOL_OVERFLOW 1
-
-#define NDIS_DMA_24BITS 0
-#define NDIS_DMA_32BITS 1
-#define NDIS_DMA_64BITS 2
-
-#ifdef CONFIG_X86_64
-#define MAXIMUM_PROCESSORS 64
-#else
-#define MAXIMUM_PROCESSORS 32
-#endif
-
-typedef UINT NDIS_STATUS;
-typedef UCHAR NDIS_DMA_SIZE;
-typedef LONG ndis_rssi;
-typedef ULONG ndis_key_index;
-typedef ULONG ndis_tx_power_level;
-typedef ULONGULONG ndis_key_rsc;
-typedef UCHAR ndis_rates[NDIS_MAX_RATES];
-typedef UCHAR ndis_rates_ex[NDIS_MAX_RATES_EX];
-typedef UCHAR mac_address[ETH_ALEN];
-typedef ULONG ndis_fragmentation_threshold;
-typedef ULONG ndis_rts_threshold;
-typedef ULONG ndis_antenna;
-typedef ULONG ndis_oid;
-
-typedef UCHAR ndis_pmkid_vavlue[16];
-
-typedef uint64_t NDIS_PHY_ADDRESS;
-
-struct ndis_sg_element {
- PHYSICAL_ADDRESS address;
- ULONG length;
- ULONG_PTR reserved;
-};
-
-struct ndis_sg_list {
- ULONG nent;
- ULONG_PTR reserved;
- struct ndis_sg_element elements[];
-};
-
-/* when sending packets, ndiswrapper associates exactly one sg element
- * in sg list */
-struct wrap_tx_sg_list {
- ULONG nent;
- ULONG_PTR reserved;
- struct ndis_sg_element elements[1];
-};
-
-struct ndis_phy_addr_unit {
- NDIS_PHY_ADDRESS phy_addr;
- UINT length;
-};
-
-typedef struct mdl ndis_buffer;
-
-struct ndis_buffer_pool {
- ndis_buffer *free_descr;
-// NT_SPIN_LOCK lock;
- spinlock_t lock;
- UINT max_descr;
- UINT num_allocated_descr;
-};
-
-#define NDIS_PROTOCOL_ID_DEFAULT 0x00
-#define NDIS_PROTOCOL_ID_TCP_IP 0x02
-#define NDIS_PROTOCOL_ID_IPX 0x06
-#define NDIS_PROTOCOL_ID_NBF 0x07
-#define NDIS_PROTOCOL_ID_MAX 0x0F
-#define NDIS_PROTOCOL_ID_MASK 0x0F
-
-#define fPACKET_WRAPPER_RESERVED 0x3F
-#define fPACKET_CONTAINS_MEDIA_SPECIFIC_INFO 0x40
-#define fPACKET_ALLOCATED_BY_NDIS 0x80
-
-#define PROTOCOL_RESERVED_SIZE_IN_PACKET (4 * sizeof(void *))
-
-struct transport_header_offset {
- USHORT protocol_type;
- USHORT header_offset;
-};
-
-struct ndis_network_address {
- USHORT length;
- USHORT type;
- UCHAR address[1];
-};
-
-struct ndis_network_address_list {
- LONG count;
- USHORT type;
- struct ndis_network_address address[1];
-};
-
-struct ndis_tcp_ip_checksum_packet_info {
- union {
- struct {
- ULONG v4:1;
- ULONG v6:1;
- ULONG tcp:1;
- ULONG udp:1;
- ULONG ip:1;
- } tx;
- struct {
- ULONG tcp_failed:1;
- ULONG udp_failed:1;
- ULONG ip_failed:1;
- ULONG tcp_succeeded:1;
- ULONG udp_succeeded:1;
- ULONG ip_succeeded:1;
- ULONG loopback:1;
- } rx;
- ULONG value;
- };
-};
-
-enum ndis_task {
- TcpIpChecksumNdisTask, IpSecNdisTask, TcpLargeSendNdisTask, MaxNdisTask
-};
-
-enum ndis_encapsulation {
- UNSPECIFIED_Encapsulation, NULL_Encapsulation,
- IEEE_802_3_Encapsulation, IEEE_802_5_Encapsulation,
- LLC_SNAP_ROUTED_Encapsulation, LLC_SNAP_BRIDGED_Encapsulation
-};
-
-#define NDIS_TASK_OFFLOAD_VERSION 1
-
-struct ndis_encapsulation_format {
- enum ndis_encapsulation encap;
- struct {
- ULONG fixed_header_size:1;
- ULONG reserved:31;
- } flags;
- ULONG header_size;
-};
-
-struct ndis_task_offload_header {
- ULONG version;
- ULONG size;
- ULONG reserved;
- ULONG offset_first_task;
- struct ndis_encapsulation_format encap_format;
-};
-
-struct ndis_task_offload {
- ULONG version;
- ULONG size;
- enum ndis_task task;
- ULONG offset_next_task;
- ULONG task_buf_length;
- UCHAR task_buf[1];
-};
-
-struct v4_checksum {
- union {
- struct {
- ULONG ip_opts:1;
- ULONG tcp_opts:1;
- ULONG tcp_csum:1;
- ULONG udp_csum:1;
- ULONG ip_csum:1;
- };
- ULONG value;
- };
-};
-
-struct v6_checksum {
- ULONG ip_supported:1;
- ULONG tcp_supported:1;
- ULONG tcp_csum:1;
- ULONG udp_csum:1;
-};
-
-struct ndis_task_tcp_ip_checksum {
- struct v4_checksum v4_tx;
- struct v4_checksum v4_rx;
- struct v6_checksum v6_tx;
- struct v6_checksum v6_rx;
-};
-
-struct ndis_task_tcp_large_send {
- ULONG version;
- ULONG max_size;
- ULONG min_seg_count;
- BOOLEAN tcp_opts;
- BOOLEAN ip_opts;
-};
-
-struct ndis_packet;
-
-struct ndis_packet_pool {
- struct ndis_packet *free_descr;
-// NT_SPIN_LOCK lock;
- spinlock_t lock;
- UINT max_descr;
- UINT num_allocated_descr;
- UINT num_used_descr;
- UINT proto_rsvd_length;
-};
-
-struct ndis_packet_stack {
- ULONG_PTR IM_reserved[2];
- ULONG_PTR ndis_reserved[4];
-};
-
-enum ndis_per_packet_info {
- TcpIpChecksumPacketInfo, IpSecPacketInfo, TcpLargeSendPacketInfo,
- ClassificationHandlePacketInfo, NdisReserved,
- ScatterGatherListPacketInfo, Ieee8021QInfo, OriginalPacketInfo,
- PacketCancelId, MaxPerPacketInfo
-};
-
-struct ndis_packet_extension {
- void *info[MaxPerPacketInfo];
-};
-
-struct ndis_packet_private {
- UINT nr_pages;
- UINT len;
- ndis_buffer *buffer_head;
- ndis_buffer *buffer_tail;
- struct ndis_packet_pool *pool;
- UINT count;
- ULONG flags;
- BOOLEAN valid_counts;
- UCHAR packet_flags;
- USHORT oob_offset;
-};
-
-struct ndis_packet {
- struct ndis_packet_private private;
- /* for use by miniport */
- union {
- /* for connectionless mininports */
- struct {
- UCHAR miniport_reserved[2 * sizeof(void *)];
- UCHAR wrapper_reserved[2 * sizeof(void *)];
- } cl_reserved;
- /* for deserialized miniports */
- struct {
- UCHAR miniport_reserved_ex[3 * sizeof(void *)];
- UCHAR wrapper_reserved_ex[sizeof(void *)];
- } deserailized_reserved;
- struct {
- UCHAR mac_reserved[4 * sizeof(void *)];
- } mac_reserved;
- };
- ULONG_PTR reserved[2];
- UCHAR protocol_reserved[1];
-};
-
-/* OOB data */
-struct ndis_packet_oob_data {
- union {
- ULONGLONG time_to_tx;
- ULONGLONG time_txed;
- };
- ULONGLONG time_rxed;
- UINT header_size;
- UINT media_size;
- void *media;
- NDIS_STATUS status;
-
- /* ndiswrapper specific info; extension should be right after
- * ndis's oob_data */
- struct ndis_packet_extension ext;
- union {
- /* used for tx only */
- struct {
- struct sk_buff *tx_skb;
- union {
- struct wrap_tx_sg_list wrap_tx_sg_list;
- struct ndis_sg_list *tx_sg_list;
- };
- };
- /* used for rx only */
- struct {
- unsigned char header[ETH_HLEN];
- unsigned char *look_ahead;
- UINT look_ahead_size;
- };
- };
-};
-
-#define NDIS_PACKET_OOB_DATA(packet) \
- (struct ndis_packet_oob_data *)(((void *)(packet)) + \
- (packet)->private.oob_offset)
-
-enum ndis_device_pnp_event {
- NdisDevicePnPEventQueryRemoved, NdisDevicePnPEventRemoved,
- NdisDevicePnPEventSurpriseRemoved, NdisDevicePnPEventQueryStopped,
- NdisDevicePnPEventStopped, NdisDevicePnPEventPowerProfileChanged,
- NdisDevicePnPEventMaximum
-};
-
-enum ndis_request_type {
- NdisRequestQueryInformation, NdisRequestSetInformation,
- NdisRequestQueryStatistics, NdisRequestOpen, NdisRequestClose,
- NdisRequestSend, NdisRequestTransferData, NdisRequestReset,
- NdisRequestGeneric1, NdisRequestGeneric2, NdisRequestGeneric3,
- NdisRequestGeneric4
-};
-
-struct ndis_request {
- mac_address mac;
- enum ndis_request_type request_type;
- union data {
- struct query_info {
- UINT oid;
- void *buf;
- UINT buf_len;
- UINT written;
- UINT needed;
- } query_info;
- struct set_info {
- UINT oid;
- void *buf;
- UINT buf_len;
- UINT written;
- UINT needed;
- } set_info;
- } data;
-};
-
-enum ndis_medium {
- NdisMedium802_3, NdisMedium802_5, NdisMediumFddi, NdisMediumWan,
- NdisMediumLocalTalk, NdisMediumDix, NdisMediumArcnetRaw,
- NdisMediumArcnet878_2, NdisMediumAtm, NdisMediumWirelessWan,
- NdisMediumIrda, NdisMediumBpc, NdisMediumCoWan,
- NdisMedium1394, NdisMediumMax
-};
-
-enum ndis_physical_medium {
- NdisPhysicalMediumUnspecified, NdisPhysicalMediumWirelessLan,
- NdisPhysicalMediumCableModem, NdisPhysicalMediumPhoneLine,
- NdisPhysicalMediumPowerLine, NdisPhysicalMediumDSL,
- NdisPhysicalMediumFibreChannel, NdisPhysicalMedium1394,
- NdisPhysicalMediumWirelessWan, NdisPhysicalMediumMax
-};
-
-enum ndis_power_state {
- NdisDeviceStateUnspecified = 0,
- NdisDeviceStateD0, NdisDeviceStateD1, NdisDeviceStateD2,
- NdisDeviceStateD3, NdisDeviceStateMaximum
-};
-
-enum ndis_power_profile {
- NdisPowerProfileBattery, NdisPowerProfileAcOnLine
-};
-
-struct ndis_pm_wakeup_capabilities {
- enum ndis_power_state min_magic_packet_wakeup;
- enum ndis_power_state min_pattern_wakeup;
- enum ndis_power_state min_link_change_wakeup;
-};
-
-#define NDIS_PNP_WAKE_UP_MAGIC_PACKET 0x00000001
-#define NDIS_PNP_WAKE_UP_PATTERN_MATCH 0x00000002
-#define NDIS_PNP_WAKE_UP_LINK_CHANGE 0x00000004
-
-enum net_pnp_event_code {
- NetEventSetPower, NetEventQueryPower, NetEventQueryRemoveDevice,
- NetEventCancelRemoveDevice, NetEventReconfigure, NetEventBindList,
- NetEventBindsComplete, NetEventPnPCapabilities, NetEventMaximum
-};
-
-struct net_pnp_event {
- enum net_pnp_event_code code;
- void *buf;
- ULONG buf_length;
- ULONG_PTR ndis_reserved[4];
- ULONG_PTR transport_reserved[4];
- ULONG_PTR tdi_reserved[4];
- ULONG_PTR tdi_client_reserved[4];
-};
-
-struct ndis_pnp_capabilities {
- ULONG flags;
- struct ndis_pm_wakeup_capabilities wakeup;
-};
-
-typedef void (*ndis_isr_handler)(BOOLEAN *recognized, BOOLEAN *queue_handler,
- void *handle) wstdcall;
-typedef void (*ndis_interrupt_handler)(void *ctx) wstdcall;
-
-struct miniport {
- /* NDIS 3.0 */
- UCHAR major_version;
- UCHAR minor_version;
- USHORT filler;
- UINT reserved;
- BOOLEAN (*hangcheck)(void *ctx) wstdcall;
- void (*disable_interrupt)(void *ctx) wstdcall;
- void (*enable_interrupt)(void *ctx) wstdcall;
- void (*mp_halt)(void *ctx) wstdcall;
- ndis_interrupt_handler handle_interrupt;
- NDIS_STATUS (*init)(NDIS_STATUS *error_status, UINT *medium_index,
- enum ndis_medium medium[], UINT medium_array_size,
- void *handle, void *conf_handle) wstdcall;
- ndis_isr_handler isr;
- NDIS_STATUS (*queryinfo)(void *ctx, ndis_oid oid, void *buffer,
- ULONG buflen, ULONG *written,
- ULONG *needed) wstdcall;
- void *reconfig;
- NDIS_STATUS (*reset)(BOOLEAN *reset_address, void *ctx) wstdcall;
- NDIS_STATUS (*send)(void *ctx, struct ndis_packet *packet,
- UINT flags) wstdcall;
- NDIS_STATUS (*setinfo)(void *ctx, ndis_oid oid, void *buffer,
- ULONG buflen, ULONG *written,
- ULONG *needed) wstdcall;
- NDIS_STATUS (*tx_data)(struct ndis_packet *ndis_packet,
- UINT *bytes_txed, void *mp_ctx, void *rx_ctx,
- UINT offset, UINT bytes_to_tx) wstdcall;
- /* NDIS 4.0 extensions */
- void (*return_packet)(void *ctx, void *packet) wstdcall;
- void (*send_packets)(void *ctx, struct ndis_packet **packets,
- INT nr_of_packets) wstdcall;
- void (*alloc_complete)(void *handle, void *virt,
- NDIS_PHY_ADDRESS *phys,
- ULONG size, void *ctx) wstdcall;
- /* NDIS 5.0 extensions */
- NDIS_STATUS (*co_create_vc)(void *ctx, void *vc_handle,
- void *vc_ctx) wstdcall;
- NDIS_STATUS (*co_delete_vc)(void *vc_ctx) wstdcall;
- NDIS_STATUS (*co_activate_vc)(void *vc_ctx, void *call_params) wstdcall;
- NDIS_STATUS (*co_deactivate_vc)(void *vc_ctx) wstdcall;
- NDIS_STATUS (*co_send_packets)(void *vc_ctx, void **packets,
- UINT nr_of_packets) wstdcall;
- NDIS_STATUS (*co_request)(void *ctx, void *vc_ctx, UINT *req) wstdcall;
- /* NDIS 5.1 extensions */
- void (*cancel_send_packets)(void *ctx, void *id) wstdcall;
- void (*pnp_event_notify)(void *ctx, enum ndis_device_pnp_event event,
- void *inf_buf, ULONG inf_buf_len) wstdcall;
- void (*shutdown)(void *ctx) wstdcall;
- void *reserved1;
- void *reserved2;
- void *reserved3;
- void *reserved4;
-};
-
-struct ndis_spinlock {
- NT_SPIN_LOCK klock;
- KIRQL irql;
-};
-
-union ndis_rw_lock_refcount {
- UCHAR cache_line[16];
-};
-
-struct ndis_rw_lock {
- union {
- struct {
- NT_SPIN_LOCK klock;
- void *context;
- };
- UCHAR reserved[16];
- };
- union {
- union ndis_rw_lock_refcount ref_count[MAXIMUM_PROCESSORS];
- /* ndiswrapper specific */
- volatile int count;
- };
-};
-
-struct lock_state {
- USHORT state;
- KIRQL irql;
-};
-
-struct ndis_work_item;
-typedef void (*NDIS_PROC)(struct ndis_work_item *, void *) wstdcall;
-
-struct ndis_work_item {
- void *ctx;
- NDIS_PROC func;
- union {
- UCHAR reserved[8 * sizeof(void *)];
- /* ndiswrapper specific */
- struct nt_list list;
- };
-};
-
-struct alloc_shared_mem {
- void *ctx;
- ULONG size;
- BOOLEAN cached;
-};
-
-struct ndis_mp_block;
-
-/* this is opaque to drivers, so we can use it as we please */
-struct ndis_mp_interrupt {
- struct kinterrupt *kinterrupt;
- NT_SPIN_LOCK lock;
- union {
- void *reserved;
- unsigned int irq;
- };
- ndis_isr_handler isr;
- ndis_interrupt_handler mp_dpc;
- struct kdpc intr_dpc;
- struct ndis_mp_block *nmb;
- UCHAR dpc_count;
- BOOLEAN enable;
- struct nt_event dpc_completed_event;
- BOOLEAN shared;
- BOOLEAN req_isr;
-};
-
-struct ndis_binary_data {
- USHORT len;
- void *buf;
-};
-
-enum ndis_parameter_type {
- NdisParameterInteger, NdisParameterHexInteger,
- NdisParameterString, NdisParameterMultiString, NdisParameterBinary,
-};
-
-typedef struct unicode_string NDIS_STRING;
-
-struct ndis_configuration_parameter {
- enum ndis_parameter_type type;
- union {
- ULONG integer;
- NDIS_STRING string;
- } data;
-};
-
-struct ndis_driver {
- struct miniport mp;
-};
-
-/* IDs used to store extensions in driver_object's custom extension */
-#define NDIS_DRIVER_CLIENT_ID 10
-
-struct ndis_wireless_stats {
- ULONG length;
- LARGE_INTEGER tx_frag;
- LARGE_INTEGER tx_multi_frag;
- LARGE_INTEGER failed;
- LARGE_INTEGER retry;
- LARGE_INTEGER multi_retry;
- LARGE_INTEGER rtss_succ;
- LARGE_INTEGER rtss_fail;
- LARGE_INTEGER ack_fail;
- LARGE_INTEGER frame_dup;
- LARGE_INTEGER rx_frag;
- LARGE_INTEGER rx_multi_frag;
- LARGE_INTEGER fcs_err;
- LARGE_INTEGER tkip_local_mic_failures;
- LARGE_INTEGER tkip_icv_errors;
- LARGE_INTEGER tkip_counter_measures_invoked;
- LARGE_INTEGER tkip_replays;
- LARGE_INTEGER ccmp_format_errors;
- LARGE_INTEGER ccmp_replays;
- LARGE_INTEGER ccmp_decrypt_errors;
- LARGE_INTEGER fourway_handshake_failures;
- LARGE_INTEGER wep_undecryptable_count;
- LARGE_INTEGER wep_icv_errorcount;
- LARGE_INTEGER decrypt_success_count;
- LARGE_INTEGER decrypt_failure_count;
-};
-
-enum ndis_status_type {
- Ndis802_11StatusType_Authentication,
- Ndis802_11StatusType_MediaStreamMode,
- Ndis802_11StatusType_PMKID_CandidateList,
- Ndis802_11StatusType_RadioState,
-};
-
-struct ndis_status_indication {
- enum ndis_status_type status_type;
-};
-
-enum ndis_radio_status {
- Ndis802_11RadioStatusOn, Ndis802_11RadioStatusHardwareOff,
- Ndis802_11RadioStatusSoftwareOff,
-};
-
-struct ndis_radio_status_indication
-{
- enum ndis_status_type status_type;
- enum ndis_radio_status radio_state;
-};
-
-enum ndis_media_state {
- NdisMediaStateConnected,
- NdisMediaStateDisconnected,
-};
-
-enum ndis_media_stream_mode {
- Ndis802_11MediaStreamOff, Ndis802_11MediaStreamOn
-};
-
-enum wrapper_work {
- LINK_STATUS_OFF, LINK_STATUS_ON, SET_MULTICAST_LIST, COLLECT_IW_STATS,
- HANGCHECK, NETIF_WAKEQ,
-};
-
-struct encr_info {
- struct encr_key {
- ULONG length;
- UCHAR key[NDIS_ENCODING_TOKEN_MAX];
- } keys[MAX_ENCR_KEYS];
- unsigned short tx_key_index;
-};
-
-struct ndis_essid {
- ULONG length;
- UCHAR essid[NDIS_ESSID_MAX_SIZE];
-};
-
-enum ndis_infrastructure_mode {
- Ndis802_11IBSS, Ndis802_11Infrastructure, Ndis802_11AutoUnknown,
- Ndis802_11InfrastructureMax
-};
-
-enum authentication_mode {
- Ndis802_11AuthModeOpen, Ndis802_11AuthModeShared,
- Ndis802_11AuthModeAutoSwitch, Ndis802_11AuthModeWPA,
- Ndis802_11AuthModeWPAPSK, Ndis802_11AuthModeWPANone,
- Ndis802_11AuthModeWPA2, Ndis802_11AuthModeWPA2PSK,
- Ndis802_11AuthModeMax
-};
-
-enum encryption_status {
- Ndis802_11WEPEnabled,
- Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
- Ndis802_11WEPDisabled,
- Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
- Ndis802_11WEPKeyAbsent,
- Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
- Ndis802_11WEPNotSupported,
- Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
- Ndis802_11Encryption2Enabled, Ndis802_11Encryption2KeyAbsent,
- Ndis802_11Encryption3Enabled, Ndis802_11Encryption3KeyAbsent
-};
-
-struct ndis_auth_encr_pair {
- enum authentication_mode auth_mode;
- enum encryption_status encr_mode;
-};
-
-struct ndis_capability {
- ULONG length;
- ULONG version;
- ULONG num_PMKIDs;
- ULONG num_auth_encr_pair;
- struct ndis_auth_encr_pair auth_encr_pair[1];
-};
-
-struct ndis_guid {
- struct guid guid;
- union {
- ndis_oid oid;
- NDIS_STATUS status;
- };
- ULONG size;
- ULONG flags;
-};
-
-struct ndis_timer {
- struct nt_timer nt_timer;
- struct kdpc kdpc;
-};
-
-struct ndis_mp_timer {
- struct nt_timer nt_timer;
- struct kdpc kdpc;
- DPC func;
- void *ctx;
- struct ndis_mp_block *nmb;
- struct ndis_mp_timer *next;
-};
-
-typedef struct cm_partial_resource_list NDIS_RESOURCE_LIST;
-
-struct ndis_event {
- struct nt_event nt_event;
-};
-
-struct ndis_bind_paths {
- UINT number;
- struct unicode_string paths[1];
-};
-
-struct ndis_reference {
- NT_SPIN_LOCK lock;
- USHORT ref_count;
- BOOLEAN closing;
-};
-
-struct ndis_filterdbs {
- union {
- void *eth_db;
- void *null_db;
- };
- void *tr_db;
- void *fddi_db;
- void *arc_db;
-};
-
-enum ndis_interface_type {
- NdisInterfaceInternal, NdisInterfaceIsa, NdisInterfaceEisa,
- NdisInterfaceMca, NdisInterfaceTurboChannel, NdisInterfacePci,
- NdisInterfacePcMcia,
-};
-
-struct auth_encr_capa {
- unsigned long auth;
- unsigned long encr;
-};
-
-struct ndis_pmkid_candidate {
- mac_address bssid;
- DWORD flags;
-};
-
-struct ndis_pmkid_candidate_list {
- ULONG version;
- ULONG num_candidates;
- struct ndis_pmkid_candidate candidates[1];
-};
-
-/*
- * This struct contains function pointers that the drivers references
- * directly via macros, so it's important that they are at the correct
- * position.
- */
-struct ndis_mp_block {
- void *signature;
- struct ndis_mp_block *next;
- struct driver_object *drv_obj;
- void *mp_ctx;
- struct unicode_string name;
- struct ndis_bind_paths *bindpaths;
- void *openqueue;
- struct ndis_reference reference;
- void *device_ctx;
- UCHAR padding;
- UCHAR lock_acquired;
- UCHAR pmode_opens;
- UCHAR assigned_cpu;
- NT_SPIN_LOCK lock;
- enum ndis_request_type *mediarequest;
- struct ndis_mp_interrupt *interrupt;
- ULONG flags;
- ULONG pnp_flags;
- struct nt_list packet_list;
- struct ndis_packet *first_pending_tx_packet;
- struct ndis_packet *return_packet_queue;
- ULONG request_buffer;
- void *set_mcast_buffer;
- struct ndis_mp_block *primary_mp;
- void *wrapper_ctx;
- void *bus_data_ctx;
- ULONG pnp_capa;
- void *resources;
- struct ndis_timer wakeup_dpc_timer;
- struct unicode_string basename;
- struct unicode_string symlink_name;
- ULONG ndis_hangcheck_interval;
- USHORT hanghcheck_ticks;
- USHORT hangcheck_tick;
- NDIS_STATUS ndis_reset_status;
- void *resetopen;
- struct ndis_filterdbs filterdbs;
- void *rx_packet;
- void *send_complete;
- void *send_resource_avail;
- void *reset_complete;
-
- enum ndis_medium media_type;
- ULONG bus_number;
- enum ndis_interface_type bus_type;
- enum ndis_interface_type adapter_type;
- struct device_object *fdo;
- struct device_object *pdo;
- struct device_object *next_device;
- void *mapreg;
- void *call_mgraflist;
- void *mp_thread;
- void *setinfobuf;
- USHORT setinfo_buf_len;
- USHORT max_send_pkts;
- NDIS_STATUS fake_status;
- void *lock_handler;
- struct unicode_string *adapter_instance_name;
- void *timer_queue;
- UINT mac_options;
- void *pending_req;
- UINT max_long_addrs;
- UINT max_short_addrs;
- UINT cur_lookahead;
- UINT max_lookahead;
-
- ndis_interrupt_handler irq_bh;
- void *disable_intr;
- void *enable_intr;
- void *send_pkts;
- void *deferred_send;
- void *eth_rx_indicate;
- void *tr_rx_indicate;
- void *fddi_rx_indicate;
- void *eth_rx_complete;
- void *tr_rx_complete;
- void *fddi_rx_complete;
-
- void *status;
- void *status_complete;
- void *td_complete;
-
- void *queryinfo_complete;
- void *setinfo_complete;
- void *wan_tx_complete;
- void *wan_rx;
- void *wan_rx_complete;
- /* ndiswrapper specific */
- struct ndis_device *wnd;
-};
-
-struct ndis_device {
- struct ndis_mp_block *nmb;
- struct wrap_device *wd;
- struct net_device *net_dev;
- void *shutdown_ctx;
- struct ndis_mp_interrupt *mp_interrupt;
- struct kdpc irq_kdpc;
- unsigned long mem_start;
- unsigned long mem_end;
-
- struct net_device_stats net_stats;
- struct iw_statistics iw_stats;
- BOOLEAN iw_stats_enabled;
- struct ndis_wireless_stats ndis_stats;
-
- work_struct_t tx_work;
- struct ndis_packet *tx_ring[TX_RING_SIZE];
- u8 tx_ring_start;
- u8 tx_ring_end;
- u8 is_tx_ring_full;
- u8 tx_ok;
- spinlock_t tx_ring_lock;
- struct semaphore tx_ring_mutex;
- unsigned int max_tx_packets;
- struct semaphore ndis_req_mutex;
- struct task_struct *ndis_req_task;
- int ndis_req_done;
- NDIS_STATUS ndis_req_status;
- ULONG packet_filter;
-
- ULONG sg_dma_size;
- ULONG dma_map_count;
- dma_addr_t *dma_map_addr;
-
- int hangcheck_interval;
- struct timer_list hangcheck_timer;
- int iw_stats_interval;
- struct timer_list iw_stats_timer;
- unsigned long scan_timestamp;
- struct encr_info encr_info;
- char nick[IW_ESSID_MAX_SIZE + 1];
- struct ndis_essid essid;
- struct auth_encr_capa capa;
- enum ndis_infrastructure_mode infrastructure_mode;
- int max_pmkids;
- int num_pmkids;
- struct ndis_pmkid *pmkids;
- mac_address mac;
- struct proc_dir_entry *procfs_iface;
-
- work_struct_t ndis_work;
- unsigned long ndis_pending_work;
- UINT attributes;
- int iw_auth_wpa_version;
- int iw_auth_cipher_pairwise;
- int iw_auth_cipher_group;
- int iw_auth_key_mgmt;
- int iw_auth_80211_alg;
- struct ndis_packet_pool *tx_packet_pool;
- struct ndis_buffer_pool *tx_buffer_pool;
- int multicast_size;
- struct v4_checksum rx_csum;
- struct v4_checksum tx_csum;
- enum ndis_physical_medium physical_medium;
- ULONG ndis_wolopts;
- struct nt_slist wrap_timer_slist;
- int drv_ndis_version;
- struct ndis_pnp_capabilities pnp_capa;
- char netdev_name[IFNAMSIZ];
-};
-
-BOOLEAN ndis_isr(struct kinterrupt *kinterrupt, void *ctx) wstdcall;
-
-int ndis_init(void);
-void ndis_exit(void);
-int ndis_init_device(struct ndis_device *wnd);
-void ndis_exit_device(struct ndis_device *wnd);
-
-int wrap_procfs_add_ndis_device(struct ndis_device *wnd);
-void wrap_procfs_remove_ndis_device(struct ndis_device *wnd);
-
-void NdisAllocatePacketPoolEx(NDIS_STATUS *status,
- struct ndis_packet_pool **pool_handle,
- UINT num_descr, UINT overflowsize,
- UINT proto_rsvd_length) wstdcall;
-void NdisFreePacketPool(struct ndis_packet_pool *pool) wstdcall;
-void NdisAllocatePacket(NDIS_STATUS *status, struct ndis_packet **packet,
- struct ndis_packet_pool *pool) wstdcall;
-void NdisFreePacket(struct ndis_packet *descr) wstdcall;
-void NdisAllocateBufferPool(NDIS_STATUS *status,
- struct ndis_buffer_pool **pool_handle,
- UINT num_descr) wstdcall;
-void NdisFreeBufferPool(struct ndis_buffer_pool *pool) wstdcall;
-void NdisAllocateBuffer(NDIS_STATUS *status, ndis_buffer **buffer,
- struct ndis_buffer_pool *pool, void *virt,
- UINT length) wstdcall;
-void NdisFreeBuffer(ndis_buffer *descr) wstdcall;
-void NdisMIndicateReceivePacket(struct ndis_mp_block *nmb,
- struct ndis_packet **packets,
- UINT nr_packets) wstdcall;
-void NdisMSendComplete(struct ndis_mp_block *nmb, struct ndis_packet *packet,
- NDIS_STATUS status) wstdcall;
-void NdisMSendResourcesAvailable(struct ndis_mp_block *nmb) wstdcall;
-void NdisMIndicateStatus(struct ndis_mp_block *nmb,
- NDIS_STATUS status, void *buf, UINT len) wstdcall;
-void NdisMIndicateStatusComplete(struct ndis_mp_block *nmb) wstdcall;
-void NdisMQueryInformationComplete(struct ndis_mp_block *nmb,
- NDIS_STATUS status) wstdcall;
-void NdisMSetInformationComplete(struct ndis_mp_block *nmb,
- NDIS_STATUS status) wstdcall;
-void NdisMResetComplete(struct ndis_mp_block *nmb, NDIS_STATUS status,
- BOOLEAN address_reset) wstdcall;
-ULONG NDIS_BUFFER_TO_SPAN_PAGES(ndis_buffer *buffer) wstdcall;
-BOOLEAN NdisWaitEvent(struct ndis_event *event, UINT timeout) wstdcall;
-void NdisSetEvent(struct ndis_event *event) wstdcall;
-void NdisMDeregisterInterrupt(struct ndis_mp_interrupt *mp_interrupt) wstdcall;
-void EthRxIndicateHandler(struct ndis_mp_block *nmb, void *rx_ctx,
- char *header1, char *header, UINT header_size,
- void *look_ahead, UINT look_ahead_size,
- UINT packet_size) wstdcall;
-void EthRxComplete(struct ndis_mp_block *nmb) wstdcall;
-void NdisMTransferDataComplete(struct ndis_mp_block *nmb,
- struct ndis_packet *packet, NDIS_STATUS status,
- UINT bytes_txed) wstdcall;
-void NdisWriteConfiguration(NDIS_STATUS *status, struct ndis_mp_block *nmb,
- struct unicode_string *key,
- struct ndis_configuration_parameter *param) wstdcall;
-void NdisReadConfiguration(NDIS_STATUS *status,
- struct ndis_configuration_parameter **param,
- struct ndis_mp_block *nmb,
- struct unicode_string *key,
- enum ndis_parameter_type type) wstdcall;
-
-/* Required OIDs */
-#define OID_GEN_SUPPORTED_LIST 0x00010101
-#define OID_GEN_HARDWARE_STATUS 0x00010102
-#define OID_GEN_MEDIA_SUPPORTED 0x00010103
-#define OID_GEN_MEDIA_IN_USE 0x00010104
-#define OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105
-#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106
-#define OID_GEN_LINK_SPEED 0x00010107
-#define OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108
-#define OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109
-#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A
-#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B
-#define OID_GEN_VENDOR_ID 0x0001010C
-#define OID_GEN_VENDOR_DESCRIPTION 0x0001010D
-#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010E
-#define OID_GEN_CURRENT_LOOKAHEAD 0x0001010F
-#define OID_GEN_DRIVER_VERSION 0x00010110
-#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111
-#define OID_GEN_PROTOCOL_OPTIONS 0x00010112
-#define OID_GEN_MAC_OPTIONS 0x00010113
-#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114
-#define OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115
-#define OID_GEN_VENDOR_DRIVER_VERSION 0x00010116
-#define OID_GEN_SUPPORTED_GUIDS 0x00010117
-#define OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118 /* Set only */
-#define OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119 /* Set only */
-#define OID_GEN_MACHINE_NAME 0x0001021A
-#define OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B /* Set only */
-#define OID_GEN_VLAN_ID 0x0001021C
-
-/* Optional OIDs. */
-#define OID_GEN_MEDIA_CAPABILITIES 0x00010201
-#define OID_GEN_PHYSICAL_MEDIUM 0x00010202
-
-/* Required statistics OIDs. */
-#define OID_GEN_XMIT_OK 0x00020101
-#define OID_GEN_RCV_OK 0x00020102
-#define OID_GEN_XMIT_ERROR 0x00020103
-#define OID_GEN_RCV_ERROR 0x00020104
-#define OID_GEN_RCV_NO_BUFFER 0x00020105
-
-/* Optional OID statistics */
-#define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201
-#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202
-#define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203
-#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204
-#define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205
-#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206
-#define OID_GEN_DIRECTED_BYTES_RCV 0x00020207
-#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208
-#define OID_GEN_MULTICAST_BYTES_RCV 0x00020209
-#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A
-#define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B
-#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C
-#define OID_GEN_RCV_CRC_ERROR 0x0002020D
-#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E
-#define OID_GEN_GET_TIME_CAPS 0x0002020F
-#define OID_GEN_GET_NETCARD_TIME 0x00020210
-#define OID_GEN_NETCARD_LOAD 0x00020211
-#define OID_GEN_DEVICE_PROFILE 0x00020212
-
-/* 802.3 (ethernet) OIDs */
-#define OID_802_3_PERMANENT_ADDRESS 0x01010101
-#define OID_802_3_CURRENT_ADDRESS 0x01010102
-#define OID_802_3_MULTICAST_LIST 0x01010103
-#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104
-#define OID_802_3_MAC_OPTIONS 0x01010105
-#define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001
-#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101
-#define OID_802_3_XMIT_ONE_COLLISION 0x01020102
-#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103
-#define OID_802_3_XMIT_DEFERRED 0x01020201
-#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202
-#define OID_802_3_RCV_OVERRUN 0x01020203
-#define OID_802_3_XMIT_UNDERRUN 0x01020204
-#define OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205
-#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206
-#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207
-
-/* PnP and power management OIDs */
-#define OID_PNP_CAPABILITIES 0xFD010100
-#define OID_PNP_SET_POWER 0xFD010101
-#define OID_PNP_QUERY_POWER 0xFD010102
-#define OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103
-#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104
-#define OID_PNP_WAKE_UP_PATTERN_LIST 0xFD010105
-#define OID_PNP_ENABLE_WAKE_UP 0xFD010106
-
-/* PnP/PM Statistics (Optional). */
-#define OID_PNP_WAKE_UP_OK 0xFD020200
-#define OID_PNP_WAKE_UP_ERROR 0xFD020201
-
-/* The following bits are defined for OID_PNP_ENABLE_WAKE_UP */
-#define NDIS_PNP_WAKE_UP_MAGIC_PACKET 0x00000001
-#define NDIS_PNP_WAKE_UP_PATTERN_MATCH 0x00000002
-#define NDIS_PNP_WAKE_UP_LINK_CHANGE 0x00000004
-
-/* 802.11 OIDs */
-#define OID_802_11_BSSID 0x0D010101
-#define OID_802_11_SSID 0x0D010102
-#define OID_802_11_NETWORK_TYPES_SUPPORTED 0x0D010203
-#define OID_802_11_NETWORK_TYPE_IN_USE 0x0D010204
-#define OID_802_11_TX_POWER_LEVEL 0x0D010205
-#define OID_802_11_RSSI 0x0D010206
-#define OID_802_11_RSSI_TRIGGER 0x0D010207
-#define OID_802_11_INFRASTRUCTURE_MODE 0x0D010108
-#define OID_802_11_FRAGMENTATION_THRESHOLD 0x0D010209
-#define OID_802_11_RTS_THRESHOLD 0x0D01020A
-#define OID_802_11_NUMBER_OF_ANTENNAS 0x0D01020B
-#define OID_802_11_RX_ANTENNA_SELECTED 0x0D01020C
-#define OID_802_11_TX_ANTENNA_SELECTED 0x0D01020D
-#define OID_802_11_SUPPORTED_RATES 0x0D01020E
-#define OID_802_11_DESIRED_RATES 0x0D010210
-#define OID_802_11_CONFIGURATION 0x0D010211
-#define OID_802_11_STATISTICS 0x0D020212
-#define OID_802_11_ADD_WEP 0x0D010113
-#define OID_802_11_REMOVE_WEP 0x0D010114
-#define OID_802_11_DISASSOCIATE 0x0D010115
-#define OID_802_11_POWER_MODE 0x0D010216
-#define OID_802_11_BSSID_LIST 0x0D010217
-#define OID_802_11_AUTHENTICATION_MODE 0x0D010118
-#define OID_802_11_PRIVACY_FILTER 0x0D010119
-#define OID_802_11_BSSID_LIST_SCAN 0x0D01011A
-#define OID_802_11_WEP_STATUS 0x0D01011B
-#define OID_802_11_ENCRYPTION_STATUS OID_802_11_WEP_STATUS
-#define OID_802_11_RELOAD_DEFAULTS 0x0D01011C
-#define OID_802_11_ADD_KEY 0x0D01011D
-#define OID_802_11_REMOVE_KEY 0x0D01011E
-#define OID_802_11_ASSOCIATION_INFORMATION 0x0D01011F
-#define OID_802_11_TEST 0x0D010120
-#define OID_802_11_MEDIA_STREAM_MODE 0x0D010121
-#define OID_802_11_CAPABILITY 0x0D010122
-#define OID_802_11_PMKID 0x0D010123
-
-#define NDIS_STATUS_SUCCESS 0
-#define NDIS_STATUS_PENDING 0x00000103
-#define NDIS_STATUS_NOT_RECOGNIZED 0x00010001
-#define NDIS_STATUS_NOT_COPIED 0x00010002
-#define NDIS_STATUS_NOT_ACCEPTED 0x00010003
-#define NDIS_STATUS_CALL_ACTIVE 0x00010007
-#define NDIS_STATUS_ONLINE 0x40010003
-#define NDIS_STATUS_RESET_START 0x40010004
-#define NDIS_STATUS_RESET_END 0x40010005
-#define NDIS_STATUS_RING_STATUS 0x40010006
-#define NDIS_STATUS_CLOSED 0x40010007
-#define NDIS_STATUS_WAN_LINE_UP 0x40010008
-#define NDIS_STATUS_WAN_LINE_DOWN 0x40010009
-#define NDIS_STATUS_WAN_FRAGMENT 0x4001000A
-#define NDIS_STATUS_MEDIA_CONNECT 0x4001000B
-#define NDIS_STATUS_MEDIA_DISCONNECT 0x4001000C
-#define NDIS_STATUS_HARDWARE_LINE_UP 0x4001000D
-#define NDIS_STATUS_HARDWARE_LINE_DOWN 0x4001000E
-#define NDIS_STATUS_INTERFACE_UP 0x4001000F
-#define NDIS_STATUS_INTERFACE_DOWN 0x40010010
-#define NDIS_STATUS_MEDIA_BUSY 0x40010011
-#define NDIS_STATUS_MEDIA_SPECIFIC_INDICATION 0x40010012
-#define NDIS_STATUS_WW_INDICATION NDIS_STATUS_MEDIA_SPECIFIC_INDICATION
-#define NDIS_STATUS_LINK_SPEED_CHANGE 0x40010013
-#define NDIS_STATUS_WAN_GET_STATS 0x40010014
-#define NDIS_STATUS_WAN_CO_FRAGMENT 0x40010015
-#define NDIS_STATUS_WAN_CO_LINKPARAMS 0x40010016
-#define NDIS_STATUS_NOT_RESETTABLE 0x80010001
-#define NDIS_STATUS_SOFT_ERRORS 0x80010003
-#define NDIS_STATUS_HARD_ERRORS 0x80010004
-#define NDIS_STATUS_BUFFER_OVERFLOW 0x80000005
-#define NDIS_STATUS_FAILURE 0xC0000001
-#define NDIS_STATUS_INVALID_PARAMETER 0xC000000D
-#define NDIS_STATUS_RESOURCES 0xC000009A
-#define NDIS_STATUS_CLOSING 0xC0010002
-#define NDIS_STATUS_BAD_VERSION 0xC0010004
-#define NDIS_STATUS_BAD_CHARACTERISTICS 0xC0010005
-#define NDIS_STATUS_ADAPTER_NOT_FOUND 0xC0010006
-#define NDIS_STATUS_OPEN_FAILED 0xC0010007
-#define NDIS_STATUS_DEVICE_FAILED 0xC0010008
-#define NDIS_STATUS_MULTICAST_FULL 0xC0010009
-#define NDIS_STATUS_MULTICAST_EXISTS 0xC001000A
-#define NDIS_STATUS_MULTICAST_NOT_FOUND 0xC001000B
-#define NDIS_STATUS_REQUEST_ABORTED 0xC001000C
-#define NDIS_STATUS_RESET_IN_PROGRESS 0xC001000D
-#define NDIS_STATUS_CLOSING_INDICATING 0xC001000E
-#define NDIS_STATUS_BAD_VERSION 0xC0010004
-#define NDIS_STATUS_NOT_SUPPORTED 0xC00000BB
-#define NDIS_STATUS_INVALID_PACKET 0xC001000F
-#define NDIS_STATUS_OPEN_LIST_FULL 0xC0010010
-#define NDIS_STATUS_ADAPTER_NOT_READY 0xC0010011
-#define NDIS_STATUS_ADAPTER_NOT_OPEN 0xC0010012
-#define NDIS_STATUS_NOT_INDICATING 0xC0010013
-#define NDIS_STATUS_INVALID_LENGTH 0xC0010014
-#define NDIS_STATUS_INVALID_DATA 0xC0010015
-#define NDIS_STATUS_BUFFER_TOO_SHORT 0xC0010016
-#define NDIS_STATUS_INVALID_OID 0xC0010017
-#define NDIS_STATUS_ADAPTER_REMOVED 0xC0010018
-#define NDIS_STATUS_UNSUPPORTED_MEDIA 0xC0010019
-#define NDIS_STATUS_GROUP_ADDRESS_IN_USE 0xC001001A
-#define NDIS_STATUS_FILE_NOT_FOUND 0xC001001B
-#define NDIS_STATUS_ERROR_READING_FILE 0xC001001C
-#define NDIS_STATUS_ALREADY_MAPPED 0xC001001D
-#define NDIS_STATUS_RESOURCE_CONFLICT 0xC001001E
-#define NDIS_STATUS_NO_CABLE 0xC001001F
-#define NDIS_STATUS_INVALID_SAP 0xC0010020
-#define NDIS_STATUS_SAP_IN_USE 0xC0010021
-#define NDIS_STATUS_INVALID_ADDRESS 0xC0010022
-#define NDIS_STATUS_VC_NOT_ACTIVATED 0xC0010023
-#define NDIS_STATUS_DEST_OUT_OF_ORDER 0xC0010024
-#define NDIS_STATUS_VC_NOT_AVAILABLE 0xC0010025
-#define NDIS_STATUS_CELLRATE_NOT_AVAILABLE 0xC0010026
-#define NDIS_STATUS_INCOMPATABLE_QOS 0xC0010027
-#define NDIS_STATUS_AAL_PARAMS_UNSUPPORTED 0xC0010028
-#define NDIS_STATUS_NO_ROUTE_TO_DESTINATION 0xC0010029
-#define NDIS_STATUS_TOKEN_RING_OPEN_ERROR 0xC0011000
-#define NDIS_STATUS_INVALID_DEVICE_REQUEST 0xC0000010
-#define NDIS_STATUS_NETWORK_UNREACHABLE 0xC000023C
-
-/* Event codes */
-
-#define EVENT_NDIS_RESOURCE_CONFLICT 0xC0001388
-#define EVENT_NDIS_OUT_OF_RESOURCE 0xC0001389
-#define EVENT_NDIS_HARDWARE_FAILURE 0xC000138A
-#define EVENT_NDIS_ADAPTER_NOT_FOUND 0xC000138B
-#define EVENT_NDIS_INTERRUPT_CONNECT 0xC000138C
-#define EVENT_NDIS_DRIVER_FAILURE 0xC000138D
-#define EVENT_NDIS_BAD_VERSION 0xC000138E
-#define EVENT_NDIS_TIMEOUT 0x8000138F
-#define EVENT_NDIS_NETWORK_ADDRESS 0xC0001390
-#define EVENT_NDIS_UNSUPPORTED_CONFIGURATION 0xC0001391
-#define EVENT_NDIS_INVALID_VALUE_FROM_ADAPTER 0xC0001392
-#define EVENT_NDIS_MISSING_CONFIGURATION_PARAMETER 0xC0001393
-#define EVENT_NDIS_BAD_IO_BASE_ADDRESS 0xC0001394
-#define EVENT_NDIS_RECEIVE_SPACE_SMALL 0x40001395
-#define EVENT_NDIS_ADAPTER_DISABLED 0x80001396
-#define EVENT_NDIS_IO_PORT_CONFLICT 0x80001397
-#define EVENT_NDIS_PORT_OR_DMA_CONFLICT 0x80001398
-#define EVENT_NDIS_MEMORY_CONFLICT 0x80001399
-#define EVENT_NDIS_INTERRUPT_CONFLICT 0x8000139A
-#define EVENT_NDIS_DMA_CONFLICT 0x8000139B
-#define EVENT_NDIS_INVALID_DOWNLOAD_FILE_ERROR 0xC000139C
-#define EVENT_NDIS_MAXRECEIVES_ERROR 0x8000139D
-#define EVENT_NDIS_MAXTRANSMITS_ERROR 0x8000139E
-#define EVENT_NDIS_MAXFRAMESIZE_ERROR 0x8000139F
-#define EVENT_NDIS_MAXINTERNALBUFS_ERROR 0x800013A0
-#define EVENT_NDIS_MAXMULTICAST_ERROR 0x800013A1
-#define EVENT_NDIS_PRODUCTID_ERROR 0x800013A2
-#define EVENT_NDIS_LOBE_FAILUE_ERROR 0x800013A3
-#define EVENT_NDIS_SIGNAL_LOSS_ERROR 0x800013A4
-#define EVENT_NDIS_REMOVE_RECEIVED_ERROR 0x800013A5
-#define EVENT_NDIS_TOKEN_RING_CORRECTION 0x400013A6
-#define EVENT_NDIS_ADAPTER_CHECK_ERROR 0xC00013A7
-#define EVENT_NDIS_RESET_FAILURE_ERROR 0x800013A8
-#define EVENT_NDIS_CABLE_DISCONNECTED_ERROR 0x800013A9
-#define EVENT_NDIS_RESET_FAILURE_CORRECTION 0x800013AA
-
-/* packet filter bits used by NDIS_OID_PACKET_FILTER */
-#define NDIS_PACKET_TYPE_DIRECTED 0x00000001
-#define NDIS_PACKET_TYPE_MULTICAST 0x00000002
-#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004
-#define NDIS_PACKET_TYPE_BROADCAST 0x00000008
-#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010
-#define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020
-#define NDIS_PACKET_TYPE_SMT 0x00000040
-#define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080
-#define NDIS_PACKET_TYPE_GROUP 0x00001000
-#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00002000
-#define NDIS_PACKET_TYPE_FUNCTIONAL 0x00004000
-#define NDIS_PACKET_TYPE_MAC_FRAME 0x00008000
-
-/* memory allocation flags */
-#define NDIS_MEMORY_CONTIGUOUS 0x00000001
-#define NDIS_MEMORY_NONCACHED 0x00000002
-
-/* Atrribute flags to NdisMSetAtrributesEx */
-#define NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT 0x00000001
-#define NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT 0x00000002
-#define NDIS_ATTRIBUTE_IGNORE_TOKEN_RING_ERRORS 0x00000004
-#define NDIS_ATTRIBUTE_BUS_MASTER 0x00000008
-#define NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER 0x00000010
-#define NDIS_ATTRIBUTE_DESERIALIZE 0x00000020
-#define NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND 0x00000040
-#define NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK 0x00000080
-#define NDIS_ATTRIBUTE_NOT_CO_NDIS 0x00000100
-#define NDIS_ATTRIBUTE_USES_SAFE_BUFFER_APIS 0x00000200
-
-#define OID_TCP_TASK_OFFLOAD 0xFC010201
-
-#define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA 0x00000001
-#define NDIS_MAC_OPTION_RECEIVE_SERIALIZED 0x00000002
-#define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND 0x00000004
-#define NDIS_MAC_OPTION_NO_LOOPBACK 0x00000008
-#define NDIS_MAC_OPTION_FULL_DUPLEX 0x00000010
-#define NDIS_MAC_OPTION_EOTX_INDICATION 0x00000020
-#define NDIS_MAC_OPTION_8021P_PRIORITY 0x00000040
-#define NDIS_MAC_OPTION_SUPPORTS_MAC_ADDRESS_OVERWRITE 0x00000080
-#define NDIS_MAC_OPTION_RECEIVE_AT_DPC 0x00000100
-#define NDIS_MAC_OPTION_8021Q_VLAN 0x00000200
-#define NDIS_MAC_OPTION_RESERVED 0x80000000
-
-#define deserialized_driver(wnd) (wnd->attributes & NDIS_ATTRIBUTE_DESERIALIZE)
-
-static inline void serialize_lock(struct ndis_device *wnd)
-{
- nt_spin_lock(&wnd->nmb->lock);
-}
-
-static inline void serialize_unlock(struct ndis_device *wnd)
-{
- nt_spin_unlock(&wnd->nmb->lock);
-}
-
-static inline KIRQL serialize_lock_irql(struct ndis_device *wnd)
-{
- if (deserialized_driver(wnd))
- return raise_irql(DISPATCH_LEVEL);
- else
- return nt_spin_lock_irql(&wnd->nmb->lock, DISPATCH_LEVEL);
-}
-
-static inline void serialize_unlock_irql(struct ndis_device *wnd,
- KIRQL irql)
-{
- if (deserialized_driver(wnd))
- lower_irql(irql);
- else
- nt_spin_unlock_irql(&wnd->nmb->lock, irql);
-}
-
-static inline void if_serialize_lock(struct ndis_device *wnd)
-{
- if (!deserialized_driver(wnd))
- nt_spin_lock(&wnd->nmb->lock);
-}
-
-static inline void if_serialize_unlock(struct ndis_device *wnd)
-{
- if (!deserialized_driver(wnd))
- nt_spin_unlock(&wnd->nmb->lock);
-}
-
-#endif /* NDIS_H */
+++ /dev/null
-/*
- * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef _NDISWRAPPER_H_
-#define _NDISWRAPPER_H_
-
-#define DRIVER_VERSION "1.56"
-#define UTILS_VERSION "1.9"
-
-#define DRIVER_NAME "ndiswrapper"
-#define DRIVER_CONFIG_DIR "/etc/ndiswrapper"
-
-#define SSID_MAX_WPA_IE_LEN 40
-#define NDIS_ESSID_MAX_SIZE 32
-#define NDIS_ENCODING_TOKEN_MAX 32
-#define MAX_ENCR_KEYS 4
-#define TX_RING_SIZE 16
-#define NDIS_MAX_RATES 8
-#define NDIS_MAX_RATES_EX 16
-#define WLAN_EID_GENERIC 221
-#define MAX_WPA_IE_LEN 64
-#define MAX_STR_LEN 512
-
-#define WRAP_PCI_BUS 5
-#define WRAP_PCMCIA_BUS 8
-/* some USB devices, e.g., DWL-G120 have BusType as 0 */
-#define WRAP_INTERNAL_BUS 0
-/* documentation at msdn says 15 is PNP bus, but inf files from all
- * vendors say 15 is USB; which is correct? */
-#define WRAP_USB_BUS 15
-
-/* NDIS device must be 0, for compatability with old versions of
- * ndiswrapper where device type for NDIS drivers is 0 */
-#define WRAP_NDIS_DEVICE 0
-#define WRAP_USB_DEVICE 1
-#define WRAP_BLUETOOTH_DEVICE1 2
-#define WRAP_BLUETOOTH_DEVICE2 3
-
-#define WRAP_DEVICE_BUS(dev, bus) ((dev) << 8 | (bus))
-#define WRAP_BUS(dev_bus) ((dev_bus) & 0x000FF)
-#define WRAP_DEVICE(dev_bus) ((dev_bus) >> 8)
-
-#define MAX_DRIVER_NAME_LEN 32
-#define MAX_VERSION_STRING_LEN 64
-#define MAX_SETTING_NAME_LEN 128
-#define MAX_SETTING_VALUE_LEN 256
-
-#define MAX_DRIVER_PE_IMAGES 4
-#define MAX_DRIVER_BIN_FILES 5
-#define MAX_DEVICE_SETTINGS 512
-
-#define MAX_ALLOCATED_URBS 15
-
-#define DEV_ANY_ID -1
-
-#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
-#define MACSTRSEP "%02x:%02x:%02x:%02x:%02x:%02x"
-#define MACSTR "%02x%02x%02x%02x%02x%02x"
-#define MACINTADR(a) (int*)&((a)[0]), (int*)&((a)[1]), (int*)&((a)[2]), \
- (int*)&((a)[3]), (int*)&((a)[4]), (int*)&((a)[5])
-
-#ifdef __KERNEL__
-/* DEBUG macros */
-
-#define MSG(level, fmt, ...) \
- printk(level "ndiswrapper (%s:%d): " fmt "\n", \
- __func__, __LINE__ , ## __VA_ARGS__)
-
-#define WARNING(fmt, ...) MSG(KERN_WARNING, fmt, ## __VA_ARGS__)
-#define ERROR(fmt, ...) MSG(KERN_ERR, fmt , ## __VA_ARGS__)
-#define INFO(fmt, ...) MSG(KERN_INFO, fmt , ## __VA_ARGS__)
-#define TODO() WARNING("not fully implemented (yet)")
-
-#define TRACE(fmt, ...) do { } while (0)
-#define TRACE1(fmt, ...) do { } while (0)
-#define TRACE2(fmt, ...) do { } while (0)
-#define TRACE3(fmt, ...) do { } while (0)
-#define TRACE4(fmt, ...) do { } while (0)
-#define TRACE5(fmt, ...) do { } while (0)
-#define TRACE6(fmt, ...) do { } while (0)
-
-/* for a block of code */
-#define DBG_BLOCK(level) while (0)
-
-extern int debug;
-
-#if defined DEBUG
-#undef TRACE
-#define TRACE(level, fmt, ...) \
-do { \
- if (debug >= level) \
- printk(KERN_INFO "%s (%s:%d): " fmt "\n", DRIVER_NAME, \
- __func__, __LINE__ , ## __VA_ARGS__); \
-} while (0)
-#undef DBG_BLOCK
-#define DBG_BLOCK(level) if (debug >= level)
-#endif
-
-#if defined(DEBUG) && DEBUG >= 1
-#undef TRACE1
-#define TRACE1(fmt, ...) TRACE(1, fmt , ## __VA_ARGS__)
-#endif
-
-#if defined(DEBUG) && DEBUG >= 2
-#undef TRACE2
-#define TRACE2(fmt, ...) TRACE(2, fmt , ## __VA_ARGS__)
-#endif
-
-#if defined(DEBUG) && DEBUG >= 3
-#undef TRACE3
-#define TRACE3(fmt, ...) TRACE(3, fmt , ## __VA_ARGS__)
-#endif
-
-#if defined(DEBUG) && DEBUG >= 4
-#undef TRACE4
-#define TRACE4(fmt, ...) TRACE(4, fmt , ## __VA_ARGS__)
-#endif
-
-#if defined(DEBUG) && DEBUG >= 5
-#undef TRACE5
-#define TRACE5(fmt, ...) TRACE(5, fmt , ## __VA_ARGS__)
-#endif
-
-#if defined(DEBUG) && DEBUG >= 6
-#undef TRACE6
-#define TRACE6(fmt, ...) TRACE(6, fmt , ## __VA_ARGS__)
-#endif
-
-#define ENTER1(fmt, ...) TRACE1("Enter " fmt , ## __VA_ARGS__)
-#define ENTER2(fmt, ...) TRACE2("Enter " fmt , ## __VA_ARGS__)
-#define ENTER3(fmt, ...) TRACE3("Enter " fmt , ## __VA_ARGS__)
-#define ENTER4(fmt, ...) TRACE4("Enter " fmt , ## __VA_ARGS__)
-#define ENTER5(fmt, ...) TRACE5("Enter " fmt , ## __VA_ARGS__)
-#define ENTER6(fmt, ...) TRACE6("Enter " fmt , ## __VA_ARGS__)
-
-#define EXIT1(stmt) do { TRACE1("Exit"); stmt; } while(0)
-#define EXIT2(stmt) do { TRACE2("Exit"); stmt; } while(0)
-#define EXIT3(stmt) do { TRACE3("Exit"); stmt; } while(0)
-#define EXIT4(stmt) do { TRACE4("Exit"); stmt; } while(0)
-#define EXIT5(stmt) do { TRACE5("Exit"); stmt; } while(0)
-#define EXIT6(stmt) do { TRACE6("Exit"); stmt; } while(0)
-
-#if defined(USB_DEBUG)
-#define USBTRACE TRACE1
-#define USBENTER ENTER1
-#define USBEXIT EXIT1
-#else
-#define USBTRACE(fmt, ...)
-#define USBENTER(fmt, ...)
-#define USBEXIT(stmt) stmt
-#endif
-
-#if defined(EVENT_DEBUG)
-#define EVENTTRACE TRACE1
-#define EVENTENTER ENTER1
-#define EVENTEXIT EXIT1
-#else
-#define EVENTTRACE(fmt, ...)
-#define EVENTENTER(fmt, ...)
-#define EVENTEXIT(stmt) stmt
-#endif
-
-#if defined(TIMER_DEBUG)
-#define TIMERTRACE TRACE1
-#define TIMERENTER ENTER1
-#define TIMEREXIT EXIT1
-#else
-#define TIMERTRACE(fmt, ...)
-#define TIMERENTER(fmt, ...)
-#define TIMEREXIT(stmt) stmt
-#endif
-
-#if defined(IO_DEBUG)
-#define IOTRACE TRACE1
-#define IOENTER ENTER1
-#define IOEXIT EXIT1
-#else
-#define IOTRACE(fmt, ...)
-#define IOENTER(fmt, ...)
-#define IOEXIT(stmt) stmt
-#endif
-
-#if defined(WORK_DEBUG)
-#define WORKTRACE TRACE1
-#define WORKENTER ENTER1
-#define WORKEXIT EXIT1
-#else
-#define WORKTRACE(fmt, ...)
-#define WORKENTER(fmt, ...)
-#define WORKEXIT(stmt) stmt
-#endif
-
-#ifdef DEBUG
-#define assert(expr) \
-do { \
- if (!(expr)) { \
- ERROR("assertion '%s' failed", #expr); \
- dump_stack(); \
- } \
-} while (0)
-#else
-#define assert(expr) do { } while (0)
-#endif
-
-#endif // __KERNEL__
-
-#endif // NDISWRAPPER_H
+++ /dev/null
-/*
- * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include "ntoskernel.h"
-#include "ndis.h"
-#include "usb.h"
-#include "pnp.h"
-#include "loader.h"
-#include "ntoskernel_exports.h"
-
-/* MDLs describe a range of virtual address with an array of physical
- * pages right after the header. For different ranges of virtual
- * addresses, the number of entries of physical pages may be different
- * (depending on number of entries required). If we want to allocate
- * MDLs from a pool, the size has to be constant. So we assume that
- * maximum range used by a driver is MDL_CACHE_PAGES; if a driver
- * requests an MDL for a bigger region, we allocate it with kmalloc;
- * otherwise, we allocate from the pool */
-
-#define MDL_CACHE_PAGES 3
-#define MDL_CACHE_SIZE (sizeof(struct mdl) + \
- (sizeof(PFN_NUMBER) * MDL_CACHE_PAGES))
-struct wrap_mdl {
- struct nt_list list;
- struct mdl mdl[0];
-};
-
-/* everything here is for all drivers/devices - not per driver/device */
-static spinlock_t dispatcher_lock;
-spinlock_t ntoskernel_lock;
-static void *mdl_cache;
-static struct nt_list wrap_mdl_list;
-
-static work_struct_t kdpc_work;
-static void kdpc_worker(worker_param_t dummy);
-
-static struct nt_list kdpc_list;
-static spinlock_t kdpc_list_lock;
-
-static struct nt_list callback_objects;
-
-struct nt_list object_list;
-
-struct bus_driver {
- struct nt_list list;
- char name[MAX_DRIVER_NAME_LEN];
- struct driver_object drv_obj;
-};
-
-static struct nt_list bus_driver_list;
-
-static work_struct_t ntos_work;
-static struct nt_list ntos_work_list;
-static spinlock_t ntos_work_lock;
-static void ntos_work_worker(worker_param_t dummy);
-static struct nt_thread *ntos_worker_thread;
-spinlock_t irp_cancel_lock;
-static NT_SPIN_LOCK nt_list_lock;
-static struct nt_slist wrap_timer_slist;
-
-/* compute ticks (100ns) since 1601 until when system booted into
- * wrap_ticks_to_boot */
-u64 wrap_ticks_to_boot;
-
-#if defined(CONFIG_X86_64)
-static struct timer_list shared_data_timer;
-struct kuser_shared_data kuser_shared_data;
-static void update_user_shared_data_proc(unsigned long data);
-#endif
-
-WIN_SYMBOL_MAP("KeTickCount", &jiffies)
-
-WIN_SYMBOL_MAP("NlsMbCodePageTag", FALSE)
-
-workqueue_struct_t *ntos_wq;
-
-#ifdef WRAP_PREEMPT
-DEFINE_PER_CPU(irql_info_t, irql_info);
-#endif
-
-#if defined(CONFIG_X86_64)
-static void update_user_shared_data_proc(unsigned long data)
-{
- /* timer is supposed to be scheduled every 10ms, but bigger
- * intervals seem to work (tried upto 50ms) */
- *((ULONG64 *)&kuser_shared_data.system_time) = ticks_1601();
- *((ULONG64 *)&kuser_shared_data.interrupt_time) =
- jiffies * TICKSPERSEC / HZ;
- *((ULONG64 *)&kuser_shared_data.tick) = jiffies;
-
- mod_timer(&shared_data_timer, jiffies + MSEC_TO_HZ(30));
-}
-#endif
-
-void *allocate_object(ULONG size, enum common_object_type type,
- struct unicode_string *name)
-{
- struct common_object_header *hdr;
- void *body;
-
- /* we pad header as prefix to body */
- hdr = ExAllocatePoolWithTag(NonPagedPool, OBJECT_SIZE(size), 0);
- if (!hdr) {
- WARNING("couldn't allocate memory");
- return NULL;
- }
- memset(hdr, 0, OBJECT_SIZE(size));
- if (name) {
- hdr->name.buf = ExAllocatePoolWithTag(NonPagedPool,
- name->max_length, 0);
- if (!hdr->name.buf) {
- ExFreePool(hdr);
- return NULL;
- }
- memcpy(hdr->name.buf, name->buf, name->max_length);
- hdr->name.length = name->length;
- hdr->name.max_length = name->max_length;
- }
- hdr->type = type;
- hdr->ref_count = 1;
- spin_lock_bh(&ntoskernel_lock);
- /* threads are looked up often (in KeWaitForXXX), so optimize
- * for fast lookups of threads */
- if (type == OBJECT_TYPE_NT_THREAD)
- InsertHeadList(&object_list, &hdr->list);
- else
- InsertTailList(&object_list, &hdr->list);
- spin_unlock_bh(&ntoskernel_lock);
- body = HEADER_TO_OBJECT(hdr);
- TRACE3("allocated hdr: %p, body: %p", hdr, body);
- return body;
-}
-
-void free_object(void *object)
-{
- struct common_object_header *hdr;
-
- hdr = OBJECT_TO_HEADER(object);
- spin_lock_bh(&ntoskernel_lock);
- RemoveEntryList(&hdr->list);
- spin_unlock_bh(&ntoskernel_lock);
- TRACE3("freed hdr: %p, body: %p", hdr, object);
- if (hdr->name.buf)
- ExFreePool(hdr->name.buf);
- ExFreePool(hdr);
-}
-
-static int add_bus_driver(const char *name)
-{
- struct bus_driver *bus_driver;
-
- bus_driver = kzalloc(sizeof(*bus_driver), GFP_KERNEL);
- if (!bus_driver) {
- ERROR("couldn't allocate memory");
- return -ENOMEM;
- }
- strncpy(bus_driver->name, name, sizeof(bus_driver->name));
- bus_driver->name[sizeof(bus_driver->name)-1] = 0;
- spin_lock_bh(&ntoskernel_lock);
- InsertTailList(&bus_driver_list, &bus_driver->list);
- spin_unlock_bh(&ntoskernel_lock);
- TRACE1("bus driver %s is at %p", name, &bus_driver->drv_obj);
- return STATUS_SUCCESS;
-}
-
-struct driver_object *find_bus_driver(const char *name)
-{
- struct bus_driver *bus_driver;
- struct driver_object *drv_obj;
-
- spin_lock_bh(&ntoskernel_lock);
- drv_obj = NULL;
- nt_list_for_each_entry(bus_driver, &bus_driver_list, list) {
- if (strcmp(bus_driver->name, name) == 0) {
- drv_obj = &bus_driver->drv_obj;
- break;
- }
- }
- spin_unlock_bh(&ntoskernel_lock);
- return drv_obj;
-}
-
-wfastcall struct nt_list *WIN_FUNC(ExfInterlockedInsertHeadList,3)
- (struct nt_list *head, struct nt_list *entry, NT_SPIN_LOCK *lock)
-{
- struct nt_list *first;
- unsigned long flags;
-
- ENTER5("head = %p, entry = %p", head, entry);
- nt_spin_lock_irqsave(lock, flags);
- first = InsertHeadList(head, entry);
- nt_spin_unlock_irqrestore(lock, flags);
- TRACE5("head = %p, old = %p", head, first);
- return first;
-}
-
-wfastcall struct nt_list *WIN_FUNC(ExInterlockedInsertHeadList,3)
- (struct nt_list *head, struct nt_list *entry, NT_SPIN_LOCK *lock)
-{
- ENTER5("%p", head);
- return ExfInterlockedInsertHeadList(head, entry, lock);
-}
-
-wfastcall struct nt_list *WIN_FUNC(ExfInterlockedInsertTailList,3)
- (struct nt_list *head, struct nt_list *entry, NT_SPIN_LOCK *lock)
-{
- struct nt_list *last;
- unsigned long flags;
-
- ENTER5("head = %p, entry = %p", head, entry);
- nt_spin_lock_irqsave(lock, flags);
- last = InsertTailList(head, entry);
- nt_spin_unlock_irqrestore(lock, flags);
- TRACE5("head = %p, old = %p", head, last);
- return last;
-}
-
-wfastcall struct nt_list *WIN_FUNC(ExInterlockedInsertTailList,3)
- (struct nt_list *head, struct nt_list *entry, NT_SPIN_LOCK *lock)
-{
- ENTER5("%p", head);
- return ExfInterlockedInsertTailList(head, entry, lock);
-}
-
-wfastcall struct nt_list *WIN_FUNC(ExfInterlockedRemoveHeadList,2)
- (struct nt_list *head, NT_SPIN_LOCK *lock)
-{
- struct nt_list *ret;
- unsigned long flags;
-
- ENTER5("head = %p", head);
- nt_spin_lock_irqsave(lock, flags);
- ret = RemoveHeadList(head);
- nt_spin_unlock_irqrestore(lock, flags);
- TRACE5("head = %p, ret = %p", head, ret);
- return ret;
-}
-
-wfastcall struct nt_list *WIN_FUNC(ExInterlockedRemoveHeadList,2)
- (struct nt_list *head, NT_SPIN_LOCK *lock)
-{
- ENTER5("%p", head);
- return ExfInterlockedRemoveHeadList(head, lock);
-}
-
-wfastcall struct nt_list *WIN_FUNC(ExfInterlockedRemoveTailList,2)
- (struct nt_list *head, NT_SPIN_LOCK *lock)
-{
- struct nt_list *ret;
- unsigned long flags;
-
- ENTER5("head = %p", head);
- nt_spin_lock_irqsave(lock, flags);
- ret = RemoveTailList(head);
- nt_spin_unlock_irqrestore(lock, flags);
- TRACE5("head = %p, ret = %p", head, ret);
- return ret;
-}
-
-wfastcall struct nt_list *WIN_FUNC(ExInterlockedRemoveTailList,2)
- (struct nt_list *head, NT_SPIN_LOCK *lock)
-{
- ENTER5("%p", head);
- return ExfInterlockedRemoveTailList(head, lock);
-}
-
-wfastcall void WIN_FUNC(InitializeSListHead,1)
- (nt_slist_header *head)
-{
- memset(head, 0, sizeof(*head));
-}
-
-wfastcall struct nt_slist *WIN_FUNC(ExInterlockedPushEntrySList,3)
- (nt_slist_header *head, struct nt_slist *entry, NT_SPIN_LOCK *lock)
-{
- struct nt_slist *ret;
-
- ret = PushEntrySList(head, entry, lock);
- return ret;
-}
-
-wstdcall struct nt_slist *WIN_FUNC(ExpInterlockedPushEntrySList,2)
- (nt_slist_header *head, struct nt_slist *entry)
-{
- struct nt_slist *ret;
-
- ret = PushEntrySList(head, entry, &nt_list_lock);
- return ret;
-}
-
-wfastcall struct nt_slist *WIN_FUNC(InterlockedPushEntrySList,2)
- (nt_slist_header *head, struct nt_slist *entry)
-{
- struct nt_slist *ret;
-
- ret = PushEntrySList(head, entry, &nt_list_lock);
- return ret;
-}
-
-wfastcall struct nt_slist *WIN_FUNC(ExInterlockedPopEntrySList,2)
- (nt_slist_header *head, NT_SPIN_LOCK *lock)
-{
- struct nt_slist *ret;
-
- ret = PopEntrySList(head, lock);
- return ret;
-}
-
-wstdcall struct nt_slist *WIN_FUNC(ExpInterlockedPopEntrySList,1)
- (nt_slist_header *head)
-{
- struct nt_slist *ret;
-
- ret = PopEntrySList(head, &nt_list_lock);
- return ret;
-}
-
-wfastcall struct nt_slist *WIN_FUNC(InterlockedPopEntrySList,1)
- (nt_slist_header *head)
-{
- struct nt_slist *ret;
-
- ret = PopEntrySList(head, &nt_list_lock);
- return ret;
-}
-
-wstdcall USHORT WIN_FUNC(ExQueryDepthSList,1)
- (nt_slist_header *head)
-{
- USHORT depth;
- ENTER5("%p", head);
- depth = head->depth;
- TRACE5("%d, %p", depth, head->next);
- return depth;
-}
-
-wfastcall LONG WIN_FUNC(InterlockedIncrement,1)
- (LONG volatile *val)
-{
- return post_atomic_add(*val, 1);
-}
-
-wfastcall LONG WIN_FUNC(InterlockedDecrement,1)
- (LONG volatile *val)
-{
- return post_atomic_add(*val, -1);
-}
-
-wfastcall LONG WIN_FUNC(InterlockedExchange,2)
- (LONG volatile *target, LONG val)
-{
- return xchg(target, val);
-}
-
-wfastcall LONG WIN_FUNC(InterlockedCompareExchange,3)
- (LONG volatile *dest, LONG new, LONG old)
-{
- return cmpxchg(dest, old, new);
-}
-
-wfastcall void WIN_FUNC(ExInterlockedAddLargeStatistic,2)
- (LARGE_INTEGER volatile *plint, ULONG n)
-{
- unsigned long flags;
-
- local_irq_save(flags);
-#ifdef CONFIG_X86_64
- __asm__ __volatile__(
- "\n"
- LOCK_PREFIX "add %1, %0\n\t"
- : "+m" (*plint)
- : "r" (n));
-#else
- __asm__ __volatile__(
- "1:\t"
- " movl %1, %%ebx\n\t"
- " movl %%edx, %%ecx\n\t"
- " addl %%eax, %%ebx\n\t"
- " adcl $0, %%ecx\n\t"
- LOCK_PREFIX "cmpxchg8b %0\n\t"
- " jnz 1b\n\t"
- : "+m" (*plint)
- : "m" (n), "A" (*plint)
- : "ebx", "ecx");
-#endif
- local_irq_restore(flags);
-}
-
-static void initialize_object(struct dispatcher_header *dh, enum dh_type type,
- int state)
-{
- memset(dh, 0, sizeof(*dh));
- set_object_type(dh, type);
- dh->signal_state = state;
- InitializeListHead(&dh->wait_blocks);
-}
-
-static void timer_proc(unsigned long data)
-{
- struct wrap_timer *wrap_timer = (struct wrap_timer *)data;
- struct nt_timer *nt_timer;
- struct kdpc *kdpc;
-
- nt_timer = wrap_timer->nt_timer;
- TIMERENTER("%p(%p), %lu", wrap_timer, nt_timer, jiffies);
-#ifdef TIMER_DEBUG
- BUG_ON(wrap_timer->wrap_timer_magic != WRAP_TIMER_MAGIC);
- BUG_ON(nt_timer->wrap_timer_magic != WRAP_TIMER_MAGIC);
-#endif
- KeSetEvent((struct nt_event *)nt_timer, 0, FALSE);
- if (wrap_timer->repeat)
- mod_timer(&wrap_timer->timer, jiffies + wrap_timer->repeat);
- kdpc = nt_timer->kdpc;
- if (kdpc)
- queue_kdpc(kdpc);
- TIMEREXIT(return);
-}
-
-void wrap_init_timer(struct nt_timer *nt_timer, enum timer_type type,
- struct ndis_mp_block *nmb)
-{
- struct wrap_timer *wrap_timer;
-
- /* TODO: if a timer is initialized more than once, we allocate
- * memory for wrap_timer more than once for the same nt_timer,
- * wasting memory. We can check if nt_timer->wrap_timer_magic is
- * set and not allocate, but it is not guaranteed always to be
- * safe */
- TIMERENTER("%p", nt_timer);
- /* we allocate memory for wrap_timer behind driver's back and
- * there is no NDIS/DDK function where this memory can be
- * freed, so we use slack_kmalloc so it gets freed when driver
- * is unloaded */
- if (nmb)
- wrap_timer = kmalloc(sizeof(*wrap_timer), irql_gfp());
- else
- wrap_timer = slack_kmalloc(sizeof(*wrap_timer));
- if (!wrap_timer) {
- ERROR("couldn't allocate memory for timer");
- return;
- }
-
- memset(wrap_timer, 0, sizeof(*wrap_timer));
- init_timer(&wrap_timer->timer);
- wrap_timer->timer.data = (unsigned long)wrap_timer;
- wrap_timer->timer.function = timer_proc;
- wrap_timer->nt_timer = nt_timer;
-#ifdef TIMER_DEBUG
- wrap_timer->wrap_timer_magic = WRAP_TIMER_MAGIC;
-#endif
- nt_timer->wrap_timer = wrap_timer;
- nt_timer->kdpc = NULL;
- initialize_object(&nt_timer->dh, type, 0);
- nt_timer->wrap_timer_magic = WRAP_TIMER_MAGIC;
- TIMERTRACE("timer %p (%p)", wrap_timer, nt_timer);
- spin_lock_bh(&ntoskernel_lock);
- if (nmb) {
- wrap_timer->slist.next = nmb->wnd->wrap_timer_slist.next;
- nmb->wnd->wrap_timer_slist.next = &wrap_timer->slist;
- } else {
- wrap_timer->slist.next = wrap_timer_slist.next;
- wrap_timer_slist.next = &wrap_timer->slist;
- }
- spin_unlock_bh(&ntoskernel_lock);
- TIMEREXIT(return);
-}
-
-wstdcall void WIN_FUNC(KeInitializeTimerEx,2)
- (struct nt_timer *nt_timer, enum timer_type type)
-{
- TIMERENTER("%p", nt_timer);
- wrap_init_timer(nt_timer, type, NULL);
-}
-
-wstdcall void WIN_FUNC(KeInitializeTimer,1)
- (struct nt_timer *nt_timer)
-{
- TIMERENTER("%p", nt_timer);
- wrap_init_timer(nt_timer, NotificationTimer, NULL);
-}
-
-/* expires and repeat are in HZ */
-BOOLEAN wrap_set_timer(struct nt_timer *nt_timer, unsigned long expires_hz,
- unsigned long repeat_hz, struct kdpc *kdpc)
-{
- struct wrap_timer *wrap_timer;
-
- TIMERENTER("%p, %lu, %lu, %p, %lu",
- nt_timer, expires_hz, repeat_hz, kdpc, jiffies);
-
- wrap_timer = nt_timer->wrap_timer;
- TIMERTRACE("%p", wrap_timer);
-#ifdef TIMER_DEBUG
- if (wrap_timer->nt_timer != nt_timer)
- WARNING("bad timers: %p, %p, %p", wrap_timer, nt_timer,
- wrap_timer->nt_timer);
- if (nt_timer->wrap_timer_magic != WRAP_TIMER_MAGIC) {
- WARNING("buggy Windows timer didn't initialize timer %p",
- nt_timer);
- return FALSE;
- }
- if (wrap_timer->wrap_timer_magic != WRAP_TIMER_MAGIC) {
- WARNING("timer %p is not initialized (%lx)?",
- wrap_timer, wrap_timer->wrap_timer_magic);
- wrap_timer->wrap_timer_magic = WRAP_TIMER_MAGIC;
- }
-#endif
- KeClearEvent((struct nt_event *)nt_timer);
- nt_timer->kdpc = kdpc;
- wrap_timer->repeat = repeat_hz;
- if (mod_timer(&wrap_timer->timer, jiffies + expires_hz))
- TIMEREXIT(return TRUE);
- else
- TIMEREXIT(return FALSE);
-}
-
-wstdcall BOOLEAN WIN_FUNC(KeSetTimerEx,4)
- (struct nt_timer *nt_timer, LARGE_INTEGER duetime_ticks,
- LONG period_ms, struct kdpc *kdpc)
-{
- unsigned long expires_hz, repeat_hz;
-
- TIMERENTER("%p, %Ld, %d", nt_timer, duetime_ticks, period_ms);
- expires_hz = SYSTEM_TIME_TO_HZ(duetime_ticks);
- repeat_hz = MSEC_TO_HZ(period_ms);
- return wrap_set_timer(nt_timer, expires_hz, repeat_hz, kdpc);
-}
-
-wstdcall BOOLEAN WIN_FUNC(KeSetTimer,3)
- (struct nt_timer *nt_timer, LARGE_INTEGER duetime_ticks,
- struct kdpc *kdpc)
-{
- TIMERENTER("%p, %Ld, %p", nt_timer, duetime_ticks, kdpc);
- return KeSetTimerEx(nt_timer, duetime_ticks, 0, kdpc);
-}
-
-wstdcall BOOLEAN WIN_FUNC(KeCancelTimer,1)
- (struct nt_timer *nt_timer)
-{
- struct wrap_timer *wrap_timer;
- int ret;
-
- TIMERENTER("%p", nt_timer);
- wrap_timer = nt_timer->wrap_timer;
- if (!wrap_timer) {
- ERROR("invalid wrap_timer");
- return TRUE;
- }
-#ifdef TIMER_DEBUG
- BUG_ON(wrap_timer->wrap_timer_magic != WRAP_TIMER_MAGIC);
-#endif
- /* disable timer before deleting so if it is periodic timer, it
- * won't be re-armed after deleting */
- wrap_timer->repeat = 0;
- ret = del_timer_sync(&wrap_timer->timer);
- /* the documentation for KeCancelTimer suggests the DPC is
- * deqeued, but actually DPC is left to run */
- if (ret)
- TIMEREXIT(return TRUE);
- else
- TIMEREXIT(return FALSE);
-}
-
-wstdcall BOOLEAN WIN_FUNC(KeReadStateTimer,1)
- (struct nt_timer *nt_timer)
-{
- if (nt_timer->dh.signal_state)
- return TRUE;
- else
- return FALSE;
-}
-
-wstdcall void WIN_FUNC(KeInitializeDpc,3)
- (struct kdpc *kdpc, void *func, void *ctx)
-{
- ENTER3("%p, %p, %p", kdpc, func, ctx);
- memset(kdpc, 0, sizeof(*kdpc));
- kdpc->func = func;
- kdpc->ctx = ctx;
- InitializeListHead(&kdpc->list);
-}
-
-static void kdpc_worker(worker_param_t dummy)
-{
- struct nt_list *entry;
- struct kdpc *kdpc;
- unsigned long flags;
- KIRQL irql;
-
- WORKENTER("");
- irql = raise_irql(DISPATCH_LEVEL);
- while (1) {
- spin_lock_irqsave(&kdpc_list_lock, flags);
- entry = RemoveHeadList(&kdpc_list);
- if (entry) {
- kdpc = container_of(entry, struct kdpc, list);
- assert(kdpc->queued);
- kdpc->queued = 0;
- } else
- kdpc = NULL;
- spin_unlock_irqrestore(&kdpc_list_lock, flags);
- if (!kdpc)
- break;
- WORKTRACE("%p, %p, %p, %p, %p", kdpc, kdpc->func, kdpc->ctx,
- kdpc->arg1, kdpc->arg2);
- assert_irql(_irql_ == DISPATCH_LEVEL);
- LIN2WIN4(kdpc->func, kdpc, kdpc->ctx, kdpc->arg1, kdpc->arg2);
- assert_irql(_irql_ == DISPATCH_LEVEL);
- }
- lower_irql(irql);
- WORKEXIT(return);
-}
-
-wstdcall void WIN_FUNC(KeFlushQueuedDpcs,0)
- (void)
-{
- kdpc_worker(NULL);
-}
-
-BOOLEAN queue_kdpc(struct kdpc *kdpc)
-{
- BOOLEAN ret;
- unsigned long flags;
-
- WORKENTER("%p", kdpc);
- spin_lock_irqsave(&kdpc_list_lock, flags);
- if (kdpc->queued)
- ret = FALSE;
- else {
- if (unlikely(kdpc->importance == HighImportance))
- InsertHeadList(&kdpc_list, &kdpc->list);
- else
- InsertTailList(&kdpc_list, &kdpc->list);
- kdpc->queued = 1;
- ret = TRUE;
- }
- spin_unlock_irqrestore(&kdpc_list_lock, flags);
- if (ret == TRUE)
- schedule_ntos_work(&kdpc_work);
- WORKTRACE("%d", ret);
- return ret;
-}
-
-BOOLEAN dequeue_kdpc(struct kdpc *kdpc)
-{
- BOOLEAN ret;
- unsigned long flags;
-
- WORKENTER("%p", kdpc);
- spin_lock_irqsave(&kdpc_list_lock, flags);
- if (kdpc->queued) {
- RemoveEntryList(&kdpc->list);
- kdpc->queued = 0;
- ret = TRUE;
- } else
- ret = FALSE;
- spin_unlock_irqrestore(&kdpc_list_lock, flags);
- WORKTRACE("%d", ret);
- return ret;
-}
-
-wstdcall BOOLEAN WIN_FUNC(KeInsertQueueDpc,3)
- (struct kdpc *kdpc, void *arg1, void *arg2)
-{
- WORKENTER("%p, %p, %p", kdpc, arg1, arg2);
- kdpc->arg1 = arg1;
- kdpc->arg2 = arg2;
- return queue_kdpc(kdpc);
-}
-
-wstdcall BOOLEAN WIN_FUNC(KeRemoveQueueDpc,1)
- (struct kdpc *kdpc)
-{
- return dequeue_kdpc(kdpc);
-}
-
-wstdcall void WIN_FUNC(KeSetImportanceDpc,2)
- (struct kdpc *kdpc, enum kdpc_importance importance)
-{
- kdpc->importance = importance;
-}
-
-static void ntos_work_worker(worker_param_t dummy)
-{
- struct ntos_work_item *ntos_work_item;
- struct nt_list *cur;
-
- while (1) {
- spin_lock_bh(&ntos_work_lock);
- cur = RemoveHeadList(&ntos_work_list);
- spin_unlock_bh(&ntos_work_lock);
- if (!cur)
- break;
- ntos_work_item = container_of(cur, struct ntos_work_item, list);
- WORKTRACE("%p: executing %p, %p, %p", current,
- ntos_work_item->func, ntos_work_item->arg1,
- ntos_work_item->arg2);
- LIN2WIN2(ntos_work_item->func, ntos_work_item->arg1,
- ntos_work_item->arg2);
- kfree(ntos_work_item);
- }
- WORKEXIT(return);
-}
-
-int schedule_ntos_work_item(NTOS_WORK_FUNC func, void *arg1, void *arg2)
-{
- struct ntos_work_item *ntos_work_item;
-
- WORKENTER("adding work: %p, %p, %p", func, arg1, arg2);
- ntos_work_item = kmalloc(sizeof(*ntos_work_item), irql_gfp());
- if (!ntos_work_item) {
- ERROR("couldn't allocate memory");
- return -ENOMEM;
- }
- ntos_work_item->func = func;
- ntos_work_item->arg1 = arg1;
- ntos_work_item->arg2 = arg2;
- spin_lock_bh(&ntos_work_lock);
- InsertTailList(&ntos_work_list, &ntos_work_item->list);
- spin_unlock_bh(&ntos_work_lock);
- schedule_ntos_work(&ntos_work);
- WORKEXIT(return 0);
-}
-
-wstdcall void WIN_FUNC(KeInitializeSpinLock,1)
- (NT_SPIN_LOCK *lock)
-{
- ENTER6("%p", lock);
- nt_spin_lock_init(lock);
-}
-
-wstdcall void WIN_FUNC(KeAcquireSpinLock,2)
- (NT_SPIN_LOCK *lock, KIRQL *irql)
-{
- ENTER6("%p", lock);
- *irql = nt_spin_lock_irql(lock, DISPATCH_LEVEL);
-}
-
-wstdcall void WIN_FUNC(KeReleaseSpinLock,2)
- (NT_SPIN_LOCK *lock, KIRQL oldirql)
-{
- ENTER6("%p", lock);
- nt_spin_unlock_irql(lock, oldirql);
-}
-
-wstdcall void WIN_FUNC(KeAcquireSpinLockAtDpcLevel,1)
- (NT_SPIN_LOCK *lock)
-{
- ENTER6("%p", lock);
- nt_spin_lock(lock);
-}
-
-wstdcall void WIN_FUNC(KeReleaseSpinLockFromDpcLevel,1)
- (NT_SPIN_LOCK *lock)
-{
- ENTER6("%p", lock);
- nt_spin_unlock(lock);
-}
-
-wstdcall void WIN_FUNC(KeRaiseIrql,2)
- (KIRQL newirql, KIRQL *oldirql)
-{
- ENTER6("%d", newirql);
- *oldirql = raise_irql(newirql);
-}
-
-wstdcall KIRQL WIN_FUNC(KeRaiseIrqlToDpcLevel,0)
- (void)
-{
- return raise_irql(DISPATCH_LEVEL);
-}
-
-wstdcall void WIN_FUNC(KeLowerIrql,1)
- (KIRQL irql)
-{
- ENTER6("%d", irql);
- lower_irql(irql);
-}
-
-wstdcall KIRQL WIN_FUNC(KeAcquireSpinLockRaiseToDpc,1)
- (NT_SPIN_LOCK *lock)
-{
- ENTER6("%p", lock);
- return nt_spin_lock_irql(lock, DISPATCH_LEVEL);
-}
-
-#undef ExAllocatePoolWithTag
-
-wstdcall void *WIN_FUNC(ExAllocatePoolWithTag,3)
- (enum pool_type pool_type, SIZE_T size, ULONG tag)
-{
- void *addr;
-
- ENTER4("pool_type: %d, size: %lu, tag: 0x%x", pool_type, size, tag);
- assert_irql(_irql_ <= DISPATCH_LEVEL);
- if (size < PAGE_SIZE)
- addr = kmalloc(size, irql_gfp());
- else {
- if (irql_gfp() & GFP_ATOMIC) {
- addr = __vmalloc(size, GFP_ATOMIC | __GFP_HIGHMEM,
- PAGE_KERNEL);
- TRACE1("%p, %lu", addr, size);
- } else {
- addr = vmalloc(size);
- TRACE1("%p, %lu", addr, size);
- }
- }
- DBG_BLOCK(1) {
- if (addr)
- TRACE4("addr: %p, %lu", addr, size);
- else
- TRACE1("failed: %lu", size);
- }
- return addr;
-}
-WIN_FUNC_DECL(ExAllocatePoolWithTag,3)
-
-wstdcall void WIN_FUNC(ExFreePoolWithTag,2)
- (void *addr, ULONG tag)
-{
- TRACE4("%p", addr);
- if ((unsigned long)addr < VMALLOC_START ||
- (unsigned long)addr >= VMALLOC_END)
- kfree(addr);
- else
- vfree(addr);
-
- EXIT4(return);
-}
-
-wstdcall void WIN_FUNC(ExFreePool,1)
- (void *addr)
-{
- ExFreePoolWithTag(addr, 0);
-}
-WIN_FUNC_DECL(ExFreePool,1)
-
-wstdcall void WIN_FUNC(ExInitializeNPagedLookasideList,7)
- (struct npaged_lookaside_list *lookaside,
- LOOKASIDE_ALLOC_FUNC *alloc_func, LOOKASIDE_FREE_FUNC *free_func,
- ULONG flags, SIZE_T size, ULONG tag, USHORT depth)
-{
- ENTER3("lookaside: %p, size: %lu, flags: %u, head: %p, "
- "alloc: %p, free: %p", lookaside, size, flags,
- lookaside, alloc_func, free_func);
-
- memset(lookaside, 0, sizeof(*lookaside));
-
- lookaside->size = size;
- lookaside->tag = tag;
- lookaside->depth = 4;
- lookaside->maxdepth = 256;
- lookaside->pool_type = NonPagedPool;
-
- if (alloc_func)
- lookaside->alloc_func = alloc_func;
- else
- lookaside->alloc_func = WIN_FUNC_PTR(ExAllocatePoolWithTag,3);
- if (free_func)
- lookaside->free_func = free_func;
- else
- lookaside->free_func = WIN_FUNC_PTR(ExFreePool,1);
-
-#ifndef CONFIG_X86_64
- nt_spin_lock_init(&lookaside->obsolete);
-#endif
- EXIT3(return);
-}
-
-wstdcall void WIN_FUNC(ExDeleteNPagedLookasideList,1)
- (struct npaged_lookaside_list *lookaside)
-{
- struct nt_slist *entry;
-
- ENTER3("lookaside = %p", lookaside);
- while ((entry = ExpInterlockedPopEntrySList(&lookaside->head)))
- LIN2WIN1(lookaside->free_func, entry);
- EXIT3(return);
-}
-
-#if defined(ALLOC_DEBUG) && ALLOC_DEBUG > 1
-#define ExAllocatePoolWithTag(pool_type, size, tag) \
- wrap_ExAllocatePoolWithTag(pool_type, size, tag, __FILE__, __LINE__)
-#endif
-
-wstdcall NTSTATUS WIN_FUNC(ExCreateCallback,4)
- (struct callback_object **object, struct object_attributes *attributes,
- BOOLEAN create, BOOLEAN allow_multiple_callbacks)
-{
- struct callback_object *obj;
-
- ENTER2("");
- spin_lock_bh(&ntoskernel_lock);
- nt_list_for_each_entry(obj, &callback_objects, callback_funcs) {
- if (obj->attributes == attributes) {
- spin_unlock_bh(&ntoskernel_lock);
- *object = obj;
- return STATUS_SUCCESS;
- }
- }
- spin_unlock_bh(&ntoskernel_lock);
- obj = allocate_object(sizeof(struct callback_object),
- OBJECT_TYPE_CALLBACK, NULL);
- if (!obj)
- EXIT2(return STATUS_INSUFFICIENT_RESOURCES);
- InitializeListHead(&obj->callback_funcs);
- nt_spin_lock_init(&obj->lock);
- obj->allow_multiple_callbacks = allow_multiple_callbacks;
- obj->attributes = attributes;
- *object = obj;
- EXIT2(return STATUS_SUCCESS);
-}
-
-wstdcall void *WIN_FUNC(ExRegisterCallback,3)
- (struct callback_object *object, PCALLBACK_FUNCTION func, void *context)
-{
- struct callback_func *callback;
- KIRQL irql;
-
- ENTER2("");
- irql = nt_spin_lock_irql(&object->lock, DISPATCH_LEVEL);
- if (object->allow_multiple_callbacks == FALSE &&
- !IsListEmpty(&object->callback_funcs)) {
- nt_spin_unlock_irql(&object->lock, irql);
- EXIT2(return NULL);
- }
- nt_spin_unlock_irql(&object->lock, irql);
- callback = kmalloc(sizeof(*callback), GFP_KERNEL);
- if (!callback) {
- ERROR("couldn't allocate memory");
- return NULL;
- }
- callback->func = func;
- callback->context = context;
- callback->object = object;
- irql = nt_spin_lock_irql(&object->lock, DISPATCH_LEVEL);
- InsertTailList(&object->callback_funcs, &callback->list);
- nt_spin_unlock_irql(&object->lock, irql);
- EXIT2(return callback);
-}
-
-wstdcall void WIN_FUNC(ExUnregisterCallback,1)
- (struct callback_func *callback)
-{
- struct callback_object *object;
- KIRQL irql;
-
- ENTER3("%p", callback);
- if (!callback)
- return;
- object = callback->object;
- irql = nt_spin_lock_irql(&object->lock, DISPATCH_LEVEL);
- RemoveEntryList(&callback->list);
- nt_spin_unlock_irql(&object->lock, irql);
- kfree(callback);
- return;
-}
-
-wstdcall void WIN_FUNC(ExNotifyCallback,3)
- (struct callback_object *object, void *arg1, void *arg2)
-{
- struct callback_func *callback;
- KIRQL irql;
-
- ENTER3("%p", object);
- irql = nt_spin_lock_irql(&object->lock, DISPATCH_LEVEL);
- nt_list_for_each_entry(callback, &object->callback_funcs, list) {
- LIN2WIN3(callback->func, callback->context, arg1, arg2);
- }
- nt_spin_unlock_irql(&object->lock, irql);
- return;
-}
-
-/* check and set signaled state; should be called with dispatcher_lock held */
-/* @grab indicates if the event should be grabbed or checked
- * - note that a semaphore may stay in signaled state for multiple
- * 'grabs' if the count is > 1 */
-static int grab_object(struct dispatcher_header *dh,
- struct task_struct *thread, int grab)
-{
- EVENTTRACE("%p, %p, %d, %d", dh, thread, grab, dh->signal_state);
- if (unlikely(is_mutex_object(dh))) {
- struct nt_mutex *nt_mutex;
- nt_mutex = container_of(dh, struct nt_mutex, dh);
- EVENTTRACE("%p, %p, %d, %p, %d", nt_mutex,
- nt_mutex->owner_thread, dh->signal_state,
- thread, grab);
- /* either no thread owns the mutex or this thread owns
- * it */
- assert(dh->signal_state == 1 && nt_mutex->owner_thread == NULL);
- assert(dh->signal_state < 1 && nt_mutex->owner_thread != NULL);
- if ((dh->signal_state == 1 && nt_mutex->owner_thread == NULL) ||
- nt_mutex->owner_thread == thread) {
- if (grab) {
- dh->signal_state--;
- nt_mutex->owner_thread = thread;
- }
- EVENTEXIT(return 1);
- }
- } else if (dh->signal_state > 0) {
- /* to grab, decrement signal_state for synchronization
- * or semaphore objects */
- if (grab && (is_synch_object(dh) || is_semaphore_object(dh)))
- dh->signal_state--;
- EVENTEXIT(return 1);
- }
- EVENTEXIT(return 0);
-}
-
-/* this function should be called holding dispatcher_lock */
-static void object_signalled(struct dispatcher_header *dh)
-{
- struct nt_list *cur, *next;
- struct wait_block *wb;
-
- EVENTENTER("%p", dh);
- nt_list_for_each_safe(cur, next, &dh->wait_blocks) {
- wb = container_of(cur, struct wait_block, list);
- assert(wb->thread != NULL);
- assert(wb->object == NULL);
- if (!grab_object(dh, wb->thread, 1))
- continue;
- EVENTTRACE("%p (%p): waking %p", dh, wb, wb->thread);
- RemoveEntryList(cur);
- wb->object = dh;
- *(wb->wait_done) = 1;
- wake_up_process(wb->thread);
- }
- EVENTEXIT(return);
-}
-
-wstdcall NTSTATUS WIN_FUNC(KeWaitForMultipleObjects,8)
- (ULONG count, void *object[], enum wait_type wait_type,
- KWAIT_REASON wait_reason, KPROCESSOR_MODE wait_mode,
- BOOLEAN alertable, LARGE_INTEGER *timeout,
- struct wait_block *wait_block_array)
-{
- int i, res = 0, wait_count, wait_done;
- typeof(jiffies) wait_hz = 0;
- struct wait_block *wb, wb_array[THREAD_WAIT_OBJECTS];
- struct dispatcher_header *dh;
-
- EVENTENTER("%p, %d, %u, %p", current, count, wait_type, timeout);
-
- if (count > MAX_WAIT_OBJECTS ||
- (count > THREAD_WAIT_OBJECTS && wait_block_array == NULL))
- EVENTEXIT(return STATUS_INVALID_PARAMETER);
-
- if (wait_block_array == NULL)
- wb = wb_array;
- else
- wb = wait_block_array;
-
- /* If *timeout == 0: In the case of WaitAny, if an object can
- * be grabbed (object is in signaled state), grab and
- * return. In the case of WaitAll, we have to first make sure
- * all objects can be grabbed. If any/some of them can't be
- * grabbed, either we return STATUS_TIMEOUT or wait for them,
- * depending on how to satisfy wait. If all of them can be
- * grabbed, we will grab them in the next loop below */
-
- spin_lock_bh(&dispatcher_lock);
- for (i = wait_count = 0; i < count; i++) {
- dh = object[i];
- EVENTTRACE("%p: event %p (%d)", current, dh, dh->signal_state);
- /* wait_type == 1 for WaitAny, 0 for WaitAll */
- if (grab_object(dh, current, wait_type)) {
- if (wait_type == WaitAny) {
- spin_unlock_bh(&dispatcher_lock);
- EVENTEXIT(return STATUS_WAIT_0 + i);
- }
- } else {
- EVENTTRACE("%p: wait for %p", current, dh);
- wait_count++;
- }
- }
-
- if (timeout && *timeout == 0 && wait_count) {
- spin_unlock_bh(&dispatcher_lock);
- EVENTEXIT(return STATUS_TIMEOUT);
- }
-
- /* get the list of objects the thread needs to wait on and add
- * the thread on the wait list for each such object */
- /* if *timeout == 0, this step will grab all the objects */
- wait_done = 0;
- for (i = 0; i < count; i++) {
- dh = object[i];
- EVENTTRACE("%p: event %p (%d)", current, dh, dh->signal_state);
- wb[i].object = NULL;
- if (grab_object(dh, current, 1)) {
- EVENTTRACE("%p: no wait for %p (%d)",
- current, dh, dh->signal_state);
- /* mark that we are not waiting on this object */
- wb[i].thread = NULL;
- } else {
- wb[i].wait_done = &wait_done;
- wb[i].thread = current;
- EVENTTRACE("%p: wait for %p", current, dh);
- InsertTailList(&dh->wait_blocks, &wb[i].list);
- }
- }
- spin_unlock_bh(&dispatcher_lock);
- if (wait_count == 0)
- EVENTEXIT(return STATUS_SUCCESS);
-
- assert(timeout == NULL || *timeout != 0);
- if (timeout == NULL)
- wait_hz = 0;
- else
- wait_hz = SYSTEM_TIME_TO_HZ(*timeout);
-
- DBG_BLOCK(2) {
- KIRQL irql = current_irql();
- if (irql >= DISPATCH_LEVEL) {
- TRACE2("wait in atomic context: %lu, %d, %ld",
- wait_hz, in_atomic(), in_interrupt());
- }
- }
- assert_irql(_irql_ < DISPATCH_LEVEL);
- EVENTTRACE("%p: sleep for %ld on %p", current, wait_hz, &wait_done);
- /* we don't honor 'alertable' - according to decription for
- * this, even if waiting in non-alertable state, thread may be
- * alerted in some circumstances */
- while (wait_count) {
- res = wait_condition(wait_done, wait_hz, TASK_INTERRUPTIBLE);
- spin_lock_bh(&dispatcher_lock);
- EVENTTRACE("%p woke up: %d, %d", current, res, wait_done);
- /* the event may have been set by the time
- * wrap_wait_event returned and spinlock obtained, so
- * don't rely on value of 'res' - check event status */
- if (!wait_done) {
- assert(res <= 0);
- /* timed out or interrupted; remove from wait list */
- for (i = 0; i < count; i++) {
- if (!wb[i].thread)
- continue;
- EVENTTRACE("%p: timedout, dequeue %p (%p)",
- current, object[i], wb[i].object);
- assert(wb[i].object == NULL);
- RemoveEntryList(&wb[i].list);
- }
- spin_unlock_bh(&dispatcher_lock);
- if (res < 0)
- EVENTEXIT(return STATUS_ALERTED);
- else
- EVENTEXIT(return STATUS_TIMEOUT);
- }
- assert(res > 0);
- /* woken because object(s) signalled */
- for (i = 0; wait_count && i < count; i++) {
- if (!wb[i].thread || !wb[i].object)
- continue;
- DBG_BLOCK(1) {
- if (wb[i].object != object[i]) {
- EVENTTRACE("oops %p != %p",
- wb[i].object, object[i]);
- continue;
- }
- }
- wait_count--;
- if (wait_type == WaitAny) {
- int j;
- /* done; remove from rest of wait list */
- for (j = i + 1; j < count; j++) {
- if (wb[j].thread && !wb[j].object)
- RemoveEntryList(&wb[j].list);
- }
- spin_unlock_bh(&dispatcher_lock);
- EVENTEXIT(return STATUS_WAIT_0 + i);
- }
- }
- wait_done = 0;
- spin_unlock_bh(&dispatcher_lock);
- if (wait_count == 0)
- EVENTEXIT(return STATUS_SUCCESS);
-
- /* this thread is still waiting for more objects, so
- * let it wait for remaining time and those objects */
- if (timeout)
- wait_hz = res;
- else
- wait_hz = 0;
- }
- /* should never reach here, but compiler wants return value */
- ERROR("%p: wait_hz: %ld", current, wait_hz);
- EVENTEXIT(return STATUS_SUCCESS);
-}
-
-wstdcall NTSTATUS WIN_FUNC(KeWaitForSingleObject,5)
- (void *object, KWAIT_REASON wait_reason, KPROCESSOR_MODE wait_mode,
- BOOLEAN alertable, LARGE_INTEGER *timeout)
-{
- return KeWaitForMultipleObjects(1, &object, WaitAny, wait_reason,
- wait_mode, alertable, timeout, NULL);
-}
-
-wstdcall void WIN_FUNC(KeInitializeEvent,3)
- (struct nt_event *nt_event, enum event_type type, BOOLEAN state)
-{
- EVENTENTER("event = %p, type = %d, state = %d", nt_event, type, state);
- initialize_object(&nt_event->dh, type, state);
- EVENTEXIT(return);
-}
-
-wstdcall LONG WIN_FUNC(KeSetEvent,3)
- (struct nt_event *nt_event, KPRIORITY incr, BOOLEAN wait)
-{
- LONG old_state;
-
- EVENTENTER("%p, %d", nt_event, nt_event->dh.type);
- if (wait == TRUE)
- WARNING("wait = %d, not yet implemented", wait);
- spin_lock_bh(&dispatcher_lock);
- old_state = nt_event->dh.signal_state;
- nt_event->dh.signal_state = 1;
- if (old_state == 0)
- object_signalled(&nt_event->dh);
- spin_unlock_bh(&dispatcher_lock);
- EVENTEXIT(return old_state);
-}
-
-wstdcall void WIN_FUNC(KeClearEvent,1)
- (struct nt_event *nt_event)
-{
- EVENTENTER("%p", nt_event);
- nt_event->dh.signal_state = 0;
- EVENTEXIT(return);
-}
-
-wstdcall LONG WIN_FUNC(KeResetEvent,1)
- (struct nt_event *nt_event)
-{
- LONG old_state;
-
- EVENTENTER("%p", nt_event);
- old_state = xchg(&nt_event->dh.signal_state, 0);
- EVENTEXIT(return old_state);
-}
-
-wstdcall LONG WIN_FUNC(KeReadStateEvent,1)
- (struct nt_event *nt_event)
-{
- LONG state;
-
- state = nt_event->dh.signal_state;
- EVENTTRACE("%d", state);
- return state;
-}
-
-wstdcall void WIN_FUNC(KeInitializeMutex,2)
- (struct nt_mutex *mutex, ULONG level)
-{
- EVENTENTER("%p", mutex);
- initialize_object(&mutex->dh, MutexObject, 1);
- mutex->dh.size = sizeof(*mutex);
- InitializeListHead(&mutex->list);
- mutex->abandoned = FALSE;
- mutex->apc_disable = 1;
- mutex->owner_thread = NULL;
- EVENTEXIT(return);
-}
-
-wstdcall LONG WIN_FUNC(KeReleaseMutex,2)
- (struct nt_mutex *mutex, BOOLEAN wait)
-{
- LONG ret;
- struct task_struct *thread;
-
- EVENTENTER("%p, %d, %p", mutex, wait, current);
- if (wait == TRUE)
- WARNING("wait: %d", wait);
- thread = current;
- spin_lock_bh(&dispatcher_lock);
- EVENTTRACE("%p, %p, %p, %d", mutex, thread, mutex->owner_thread,
- mutex->dh.signal_state);
- if ((mutex->owner_thread == thread) && (mutex->dh.signal_state <= 0)) {
- ret = mutex->dh.signal_state++;
- if (ret == 0) {
- mutex->owner_thread = NULL;
- object_signalled(&mutex->dh);
- }
- } else {
- ret = STATUS_MUTANT_NOT_OWNED;
- WARNING("invalid mutex: %p, %p, %p", mutex, mutex->owner_thread,
- thread);
- }
- EVENTTRACE("%p, %p, %p, %d", mutex, thread, mutex->owner_thread,
- mutex->dh.signal_state);
- spin_unlock_bh(&dispatcher_lock);
- EVENTEXIT(return ret);
-}
-
-wstdcall void WIN_FUNC(KeInitializeSemaphore,3)
- (struct nt_semaphore *semaphore, LONG count, LONG limit)
-{
- EVENTENTER("%p: %d", semaphore, count);
- /* if limit > 1, we need to satisfy as many waits (until count
- * becomes 0); so we keep decrementing count everytime a wait
- * is satisified */
- initialize_object(&semaphore->dh, SemaphoreObject, count);
- semaphore->dh.size = sizeof(*semaphore);
- semaphore->limit = limit;
- EVENTEXIT(return);
-}
-
-wstdcall LONG WIN_FUNC(KeReleaseSemaphore,4)
- (struct nt_semaphore *semaphore, KPRIORITY incr, LONG adjustment,
- BOOLEAN wait)
-{
- LONG ret;
-
- EVENTENTER("%p", semaphore);
- spin_lock_bh(&dispatcher_lock);
- ret = semaphore->dh.signal_state;
- assert(ret >= 0);
- if (semaphore->dh.signal_state + adjustment <= semaphore->limit)
- semaphore->dh.signal_state += adjustment;
- else {
- WARNING("releasing %d over limit %d", adjustment,
- semaphore->limit);
- semaphore->dh.signal_state = semaphore->limit;
- }
- if (semaphore->dh.signal_state > 0)
- object_signalled(&semaphore->dh);
- spin_unlock_bh(&dispatcher_lock);
- EVENTEXIT(return ret);
-}
-
-wstdcall NTSTATUS WIN_FUNC(KeDelayExecutionThread,3)
- (KPROCESSOR_MODE wait_mode, BOOLEAN alertable, LARGE_INTEGER *interval)
-{
- int res;
- long timeout;
-
- if (wait_mode != 0)
- ERROR("invalid wait_mode %d", wait_mode);
-
- timeout = SYSTEM_TIME_TO_HZ(*interval);
- EVENTTRACE("%p, %Ld, %ld", current, *interval, timeout);
- if (timeout <= 0)
- EVENTEXIT(return STATUS_SUCCESS);
-
- if (alertable)
- set_current_state(TASK_INTERRUPTIBLE);
- else
- set_current_state(TASK_UNINTERRUPTIBLE);
-
- res = schedule_timeout(timeout);
- EVENTTRACE("%p, %d", current, res);
- if (res == 0)
- EVENTEXIT(return STATUS_SUCCESS);
- else
- EVENTEXIT(return STATUS_ALERTED);
-}
-
-wstdcall ULONGLONG WIN_FUNC(KeQueryInterruptTime,0)
- (void)
-{
- EXIT5(return jiffies * TICKSPERJIFFY);
-}
-
-wstdcall ULONG WIN_FUNC(KeQueryTimeIncrement,0)
- (void)
-{
- EXIT5(return TICKSPERSEC / HZ);
-}
-
-wstdcall void WIN_FUNC(KeQuerySystemTime,1)
- (LARGE_INTEGER *time)
-{
- *time = ticks_1601();
- TRACE5("%Lu, %lu", *time, jiffies);
-}
-
-wstdcall void WIN_FUNC(KeQueryTickCount,1)
- (LARGE_INTEGER *count)
-{
- *count = jiffies;
-}
-
-wstdcall LARGE_INTEGER WIN_FUNC(KeQueryPerformanceCounter,1)
- (LARGE_INTEGER *counter)
-{
- if (counter)
- *counter = HZ;
- return jiffies;
-}
-
-wstdcall KAFFINITY WIN_FUNC(KeQueryActiveProcessors,0)
- (void)
-{
- int i, n;
- KAFFINITY bits = 0;
-#ifdef num_online_cpus
- n = num_online_cpus();
-#else
- n = NR_CPUS;
-#endif
- for (i = 0; i < n; i++)
- bits = (bits << 1) | 1;
- return bits;
-}
-
-struct nt_thread *get_current_nt_thread(void)
-{
- struct task_struct *task = current;
- struct nt_thread *thread;
- struct common_object_header *header;
-
- TRACE6("task: %p", task);
- thread = NULL;
- spin_lock_bh(&ntoskernel_lock);
- nt_list_for_each_entry(header, &object_list, list) {
- TRACE6("%p, %d", header, header->type);
- if (header->type != OBJECT_TYPE_NT_THREAD)
- break;
- thread = HEADER_TO_OBJECT(header);
- TRACE6("%p, %p", thread, thread->task);
- if (thread->task == task)
- break;
- else
- thread = NULL;
- }
- spin_unlock_bh(&ntoskernel_lock);
- if (thread == NULL)
- TRACE4("couldn't find thread for task %p, %d", task, task->pid);
- TRACE6("%p", thread);
- return thread;
-}
-
-static struct task_struct *get_nt_thread_task(struct nt_thread *thread)
-{
- struct task_struct *task;
- struct common_object_header *header;
-
- TRACE6("%p", thread);
- task = NULL;
- spin_lock_bh(&ntoskernel_lock);
- nt_list_for_each_entry(header, &object_list, list) {
- TRACE6("%p, %d", header, header->type);
- if (header->type != OBJECT_TYPE_NT_THREAD)
- break;
- if (thread == HEADER_TO_OBJECT(header)) {
- task = thread->task;
- break;
- }
- }
- spin_unlock_bh(&ntoskernel_lock);
- if (task == NULL)
- TRACE2("%p: couldn't find task for %p", current, thread);
- return task;
-}
-
-static struct nt_thread *create_nt_thread(struct task_struct *task)
-{
- struct nt_thread *thread;
- thread = allocate_object(sizeof(*thread), OBJECT_TYPE_NT_THREAD, NULL);
- if (!thread) {
- ERROR("couldn't allocate thread object");
- EXIT2(return NULL);
- }
- thread->task = task;
- if (task)
- thread->pid = task->pid;
- else
- thread->pid = 0;
- nt_spin_lock_init(&thread->lock);
- InitializeListHead(&thread->irps);
- initialize_object(&thread->dh, ThreadObject, 0);
- thread->dh.size = sizeof(*thread);
- thread->prio = LOW_PRIORITY;
- return thread;
-}
-
-wstdcall struct nt_thread *WIN_FUNC(KeGetCurrentThread,0)
- (void)
-{
- struct nt_thread *thread = get_current_nt_thread();
- TRACE2("%p, %p", thread, current);
- return thread;
-}
-
-wstdcall KPRIORITY WIN_FUNC(KeQueryPriorityThread,1)
- (struct nt_thread *thread)
-{
- KPRIORITY prio;
- struct task_struct *task;
-
- TRACE2("%p", thread);
-#ifdef CONFIG_X86_64
- /* sis163u driver for amd64 passes 0x1f from thread created by
- * PsCreateSystemThread - no idea what is 0x1f */
- if (thread == (void *)0x1f)
- thread = get_current_nt_thread();
-#endif
- if (!thread) {
- TRACE2("invalid thread");
- EXIT2(return LOW_REALTIME_PRIORITY);
- }
- task = get_nt_thread_task(thread);
- if (!task) {
- TRACE2("couldn't find task for thread: %p", thread);
- EXIT2(return LOW_REALTIME_PRIORITY);
- }
-
- prio = thread->prio;
-
- TRACE2("%d", prio);
- return prio;
-}
-
-wstdcall KPRIORITY WIN_FUNC(KeSetPriorityThread,2)
- (struct nt_thread *thread, KPRIORITY prio)
-{
- KPRIORITY old_prio;
- struct task_struct *task;
-
- TRACE2("thread: %p, priority = %u", thread, prio);
-#ifdef CONFIG_X86_64
- if (thread == (void *)0x1f)
- thread = get_current_nt_thread();
-#endif
- if (!thread) {
- TRACE2("invalid thread");
- EXIT2(return LOW_REALTIME_PRIORITY);
- }
- task = get_nt_thread_task(thread);
- if (!task) {
- TRACE2("couldn't find task for thread: %p", thread);
- EXIT2(return LOW_REALTIME_PRIORITY);
- }
-
- old_prio = thread->prio;
- thread->prio = prio;
-
- TRACE2("%d, %d", old_prio, thread->prio);
- return old_prio;
-}
-
-struct thread_trampoline {
- void (*func)(void *) wstdcall;
- void *ctx;
- struct nt_thread *thread;
- struct completion started;
-};
-
-static int ntdriver_thread(void *data)
-{
- struct thread_trampoline *thread_tramp = data;
- /* yes, a tramp! */
- typeof(thread_tramp->func) func = thread_tramp->func;
- typeof(thread_tramp->ctx) ctx = thread_tramp->ctx;
-
- thread_tramp->thread->task = current;
- thread_tramp->thread->pid = current->pid;
- TRACE2("thread: %p, task: %p (%d)", thread_tramp->thread,
- current, current->pid);
- complete(&thread_tramp->started);
-
-#ifdef PF_NOFREEZE
- current->flags |= PF_NOFREEZE;
-#endif
- strncpy(current->comm, "ntdriver", sizeof(current->comm));
- current->comm[sizeof(current->comm)-1] = 0;
- LIN2WIN1(func, ctx);
- ERROR("task: %p", current);
- return 0;
-}
-
-wstdcall NTSTATUS WIN_FUNC(PsCreateSystemThread,7)
- (void **handle, ULONG access, void *obj_attr, void *process,
- void *client_id, void (*func)(void *) wstdcall, void *ctx)
-{
- struct thread_trampoline thread_tramp;
-
- ENTER2("handle = %p, access = %u, obj_attr = %p, process = %p, "
- "client_id = %p, func = %p, context = %p", handle, access,
- obj_attr, process, client_id, func, ctx);
-
- thread_tramp.thread = create_nt_thread(NULL);
- if (!thread_tramp.thread) {
- ERROR("couldn't allocate thread object");
- EXIT2(return STATUS_RESOURCES);
- }
- TRACE2("thread: %p", thread_tramp.thread);
- thread_tramp.func = func;
- thread_tramp.ctx = ctx;
- init_completion(&thread_tramp.started);
-
- thread_tramp.thread->task = kthread_run(ntdriver_thread,
- &thread_tramp, "ntdriver");
- if (IS_ERR(thread_tramp.thread->task)) {
- free_object(thread_tramp.thread);
- EXIT2(return STATUS_FAILURE);
- }
- TRACE2("created task: %p", thread_tramp.thread->task);
-
- wait_for_completion(&thread_tramp.started);
- *handle = OBJECT_TO_HEADER(thread_tramp.thread);
- TRACE2("created thread: %p, %p", thread_tramp.thread, *handle);
- EXIT2(return STATUS_SUCCESS);
-}
-
-wstdcall NTSTATUS WIN_FUNC(PsTerminateSystemThread,1)
- (NTSTATUS status)
-{
- struct nt_thread *thread;
-
- TRACE2("%p, %08X", current, status);
- thread = get_current_nt_thread();
- TRACE2("%p", thread);
- if (thread) {
- KeSetEvent((struct nt_event *)&thread->dh, 0, FALSE);
- while (1) {
- struct nt_list *ent;
- struct irp *irp;
- KIRQL irql;
- irql = nt_spin_lock_irql(&thread->lock, DISPATCH_LEVEL);
- ent = RemoveHeadList(&thread->irps);
- nt_spin_unlock_irql(&thread->lock, irql);
- if (!ent)
- break;
- irp = container_of(ent, struct irp, thread_list);
- IOTRACE("%p", irp);
- IoCancelIrp(irp);
- }
- /* the driver may later query this status with
- * ZwQueryInformationThread */
- thread->status = status;
- } else
- ERROR("couldn't find thread for task: %p", current);
-
- complete_and_exit(NULL, status);
- ERROR("oops: %p, %d", thread->task, thread->pid);
- return STATUS_FAILURE;
-}
-
-wstdcall BOOLEAN WIN_FUNC(KeRemoveEntryDeviceQueue,2)
- (struct kdevice_queue *dev_queue, struct kdevice_queue_entry *entry)
-{
- struct kdevice_queue_entry *e;
- KIRQL irql;
-
- irql = nt_spin_lock_irql(&dev_queue->lock, DISPATCH_LEVEL);
- nt_list_for_each_entry(e, &dev_queue->list, list) {
- if (e == entry) {
- RemoveEntryList(&e->list);
- nt_spin_unlock_irql(&dev_queue->lock, irql);
- return TRUE;
- }
- }
- nt_spin_unlock_irql(&dev_queue->lock, irql);
- return FALSE;
-}
-
-wstdcall BOOLEAN WIN_FUNC(KeSynchronizeExecution,3)
- (struct kinterrupt *interrupt, PKSYNCHRONIZE_ROUTINE synch_routine,
- void *ctx)
-{
- BOOLEAN ret;
- unsigned long flags;
-
- nt_spin_lock_irqsave(interrupt->actual_lock, flags);
- ret = LIN2WIN1(synch_routine, ctx);
- nt_spin_unlock_irqrestore(interrupt->actual_lock, flags);
- TRACE6("%d", ret);
- return ret;
-}
-
-wstdcall void *WIN_FUNC(MmAllocateContiguousMemorySpecifyCache,5)
- (SIZE_T size, PHYSICAL_ADDRESS lowest, PHYSICAL_ADDRESS highest,
- PHYSICAL_ADDRESS boundary, enum memory_caching_type cache_type)
-{
- void *addr;
- gfp_t flags;
-
- ENTER2("%lu, 0x%lx, 0x%lx, 0x%lx, %d", size, (long)lowest,
- (long)highest, (long)boundary, cache_type);
- flags = irql_gfp();
- addr = wrap_get_free_pages(flags, size);
- TRACE2("%p, %lu, 0x%x", addr, size, flags);
- if (addr && ((virt_to_phys(addr) + size) <= highest))
- EXIT2(return addr);
-#ifdef CONFIG_X86_64
- /* GFP_DMA is really only 16MB even on x86-64, but there is no
- * other zone available */
- if (highest <= DMA_BIT_MASK(31))
- flags |= __GFP_DMA;
- else if (highest <= DMA_BIT_MASK(32))
- flags |= __GFP_DMA32;
-#else
- if (highest <= DMA_BIT_MASK(24))
- flags |= __GFP_DMA;
- else if (highest > DMA_BIT_MASK(30))
- flags |= __GFP_HIGHMEM;
-#endif
- addr = wrap_get_free_pages(flags, size);
- TRACE2("%p, %lu, 0x%x", addr, size, flags);
- return addr;
-}
-
-wstdcall void WIN_FUNC(MmFreeContiguousMemorySpecifyCache,3)
- (void *base, SIZE_T size, enum memory_caching_type cache_type)
-{
- TRACE2("%p, %lu", base, size);
- free_pages((unsigned long)base, get_order(size));
-}
-
-wstdcall PHYSICAL_ADDRESS WIN_FUNC(MmGetPhysicalAddress,1)
- (void *base)
-{
- unsigned long phy = virt_to_phys(base);
- TRACE2("%p, %p", base, (void *)phy);
- return phy;
-}
-
-/* Atheros card with pciid 168C:0014 calls this function with 0xf0000
- * and 0xf6ef0 address, and then check for things that seem to be
- * related to ACPI: "_SM_" and "_DMI_". This may be the hack they do
- * to check if this card is installed in IBM thinkpads; we can
- * probably get this device to work if we create a buffer with the
- * strings as required by the driver and return virtual address for
- * that address instead */
-wstdcall void __iomem *WIN_FUNC(MmMapIoSpace,3)
- (PHYSICAL_ADDRESS phys_addr, SIZE_T size,
- enum memory_caching_type cache)
-{
- void __iomem *virt;
- ENTER1("cache type: %d", cache);
- if (cache == MmCached)
- virt = ioremap(phys_addr, size);
- else
- virt = ioremap_nocache(phys_addr, size);
- TRACE1("%Lx, %lu, %p", phys_addr, size, virt);
- return virt;
-}
-
-wstdcall void WIN_FUNC(MmUnmapIoSpace,2)
- (void __iomem *addr, SIZE_T size)
-{
- ENTER1("%p, %lu", addr, size);
- iounmap(addr);
- return;
-}
-
-wstdcall ULONG WIN_FUNC(MmSizeOfMdl,2)
- (void *base, ULONG length)
-{
- return sizeof(struct mdl) +
- (sizeof(PFN_NUMBER) * SPAN_PAGES(base, length));
-}
-
-struct mdl *allocate_init_mdl(void *virt, ULONG length)
-{
- struct wrap_mdl *wrap_mdl;
- struct mdl *mdl;
- int mdl_size = MmSizeOfMdl(virt, length);
-
- if (mdl_size <= MDL_CACHE_SIZE) {
- wrap_mdl = kmem_cache_alloc(mdl_cache, irql_gfp());
- if (!wrap_mdl)
- return NULL;
- spin_lock_bh(&dispatcher_lock);
- InsertHeadList(&wrap_mdl_list, &wrap_mdl->list);
- spin_unlock_bh(&dispatcher_lock);
- mdl = wrap_mdl->mdl;
- TRACE3("allocated mdl from cache: %p(%p), %p(%d)",
- wrap_mdl, mdl, virt, length);
- memset(mdl, 0, MDL_CACHE_SIZE);
- MmInitializeMdl(mdl, virt, length);
- /* mark the MDL as allocated from cache pool so when
- * it is freed, we free it back to the pool */
- mdl->flags = MDL_ALLOCATED_FIXED_SIZE | MDL_CACHE_ALLOCATED;
- } else {
- wrap_mdl =
- kmalloc(sizeof(*wrap_mdl) + mdl_size, irql_gfp());
- if (!wrap_mdl)
- return NULL;
- mdl = wrap_mdl->mdl;
- TRACE3("allocated mdl from memory: %p(%p), %p(%d)",
- wrap_mdl, mdl, virt, length);
- spin_lock_bh(&dispatcher_lock);
- InsertHeadList(&wrap_mdl_list, &wrap_mdl->list);
- spin_unlock_bh(&dispatcher_lock);
- memset(mdl, 0, mdl_size);
- MmInitializeMdl(mdl, virt, length);
- mdl->flags = MDL_ALLOCATED_FIXED_SIZE;
- }
- return mdl;
-}
-
-void free_mdl(struct mdl *mdl)
-{
- /* A driver may allocate Mdl with NdisAllocateBuffer and free
- * with IoFreeMdl (e.g., 64-bit Broadcom). Since we need to
- * treat buffers allocated with Ndis calls differently, we
- * must call NdisFreeBuffer if it is allocated with Ndis
- * function. We set 'pool' field in Ndis functions. */
- if (!mdl)
- return;
- if (mdl->pool)
- NdisFreeBuffer(mdl);
- else {
- struct wrap_mdl *wrap_mdl = (struct wrap_mdl *)
- ((char *)mdl - offsetof(struct wrap_mdl, mdl));
- spin_lock_bh(&dispatcher_lock);
- RemoveEntryList(&wrap_mdl->list);
- spin_unlock_bh(&dispatcher_lock);
-
- if (mdl->flags & MDL_CACHE_ALLOCATED) {
- TRACE3("freeing mdl cache: %p, %p, %p",
- wrap_mdl, mdl, mdl->mappedsystemva);
- kmem_cache_free(mdl_cache, wrap_mdl);
- } else {
- TRACE3("freeing mdl: %p, %p, %p",
- wrap_mdl, mdl, mdl->mappedsystemva);
- kfree(wrap_mdl);
- }
- }
- return;
-}
-
-wstdcall void WIN_FUNC(IoBuildPartialMdl,4)
- (struct mdl *source, struct mdl *target, void *virt, ULONG length)
-{
- MmInitializeMdl(target, virt, length);
- target->flags |= MDL_PARTIAL;
-}
-
-wstdcall void WIN_FUNC(MmBuildMdlForNonPagedPool,1)
- (struct mdl *mdl)
-{
- PFN_NUMBER *mdl_pages;
- int i, n;
-
- ENTER4("%p", mdl);
- /* already mapped */
-// mdl->mappedsystemva = MmGetMdlVirtualAddress(mdl);
- mdl->flags |= MDL_SOURCE_IS_NONPAGED_POOL;
- TRACE4("%p, %p, %p, %d, %d", mdl, mdl->mappedsystemva, mdl->startva,
- mdl->byteoffset, mdl->bytecount);
- n = SPAN_PAGES(MmGetSystemAddressForMdl(mdl), MmGetMdlByteCount(mdl));
- if (n > MDL_CACHE_PAGES)
- WARNING("%p, %d, %d", MmGetSystemAddressForMdl(mdl),
- MmGetMdlByteCount(mdl), n);
- mdl_pages = MmGetMdlPfnArray(mdl);
- for (i = 0; i < n; i++)
- mdl_pages[i] = (ULONG_PTR)mdl->startva + (i * PAGE_SIZE);
- EXIT4(return);
-}
-
-wstdcall void *WIN_FUNC(MmMapLockedPages,2)
- (struct mdl *mdl, KPROCESSOR_MODE access_mode)
-{
- /* already mapped */
-// mdl->mappedsystemva = MmGetMdlVirtualAddress(mdl);
- mdl->flags |= MDL_MAPPED_TO_SYSTEM_VA;
- /* what is the need for MDL_PARTIAL_HAS_BEEN_MAPPED? */
- if (mdl->flags & MDL_PARTIAL)
- mdl->flags |= MDL_PARTIAL_HAS_BEEN_MAPPED;
- return mdl->mappedsystemva;
-}
-
-wstdcall void *WIN_FUNC(MmMapLockedPagesSpecifyCache,6)
- (struct mdl *mdl, KPROCESSOR_MODE access_mode,
- enum memory_caching_type cache_type, void *base_address,
- ULONG bug_check, enum mm_page_priority priority)
-{
- return MmMapLockedPages(mdl, access_mode);
-}
-
-wstdcall void WIN_FUNC(MmUnmapLockedPages,2)
- (void *base, struct mdl *mdl)
-{
- mdl->flags &= ~MDL_MAPPED_TO_SYSTEM_VA;
- return;
-}
-
-wstdcall void WIN_FUNC(MmProbeAndLockPages,3)
- (struct mdl *mdl, KPROCESSOR_MODE access_mode,
- enum lock_operation operation)
-{
- /* already locked */
- mdl->flags |= MDL_PAGES_LOCKED;
- return;
-}
-
-wstdcall void WIN_FUNC(MmUnlockPages,1)
- (struct mdl *mdl)
-{
- mdl->flags &= ~MDL_PAGES_LOCKED;
- return;
-}
-
-wstdcall BOOLEAN WIN_FUNC(MmIsAddressValid,1)
- (void *virt_addr)
-{
- if (virt_addr_valid(virt_addr))
- return TRUE;
- else
- return FALSE;
-}
-
-wstdcall void *WIN_FUNC(MmLockPagableDataSection,1)
- (void *address)
-{
- return address;
-}
-
-wstdcall void WIN_FUNC(MmUnlockPagableImageSection,1)
- (void *handle)
-{
- return;
-}
-
-wstdcall NTSTATUS WIN_FUNC(ObReferenceObjectByHandle,6)
- (void *handle, ACCESS_MASK desired_access, void *obj_type,
- KPROCESSOR_MODE access_mode, void **object, void *handle_info)
-{
- struct common_object_header *hdr;
-
- TRACE2("%p", handle);
- hdr = HANDLE_TO_HEADER(handle);
- atomic_inc_var(hdr->ref_count);
- *object = HEADER_TO_OBJECT(hdr);
- TRACE2("%p, %p, %d, %p", hdr, object, hdr->ref_count, *object);
- return STATUS_SUCCESS;
-}
-
-/* DDK doesn't say if return value should be before incrementing or
- * after incrementing reference count, but according to #reactos
- * devels, it should be return value after incrementing */
-wfastcall LONG WIN_FUNC(ObfReferenceObject,1)
- (void *object)
-{
- struct common_object_header *hdr;
- LONG ret;
-
- hdr = OBJECT_TO_HEADER(object);
- ret = post_atomic_add(hdr->ref_count, 1);
- TRACE2("%p, %d, %p", hdr, hdr->ref_count, object);
- return ret;
-}
-
-static int dereference_object(void *object)
-{
- struct common_object_header *hdr;
- int ref_count;
-
- ENTER2("object: %p", object);
- hdr = OBJECT_TO_HEADER(object);
- TRACE2("hdr: %p", hdr);
- ref_count = post_atomic_add(hdr->ref_count, -1);
- TRACE2("object: %p, %d", object, ref_count);
- if (ref_count < 0)
- ERROR("invalid object: %p (%d)", object, ref_count);
- if (ref_count <= 0) {
- free_object(object);
- return 1;
- } else
- return 0;
-}
-
-wfastcall void WIN_FUNC(ObfDereferenceObject,1)
- (void *object)
-{
- TRACE2("%p", object);
- dereference_object(object);
-}
-
-wstdcall NTSTATUS WIN_FUNC(ZwCreateFile,11)
- (void **handle, ACCESS_MASK access_mask,
- struct object_attributes *obj_attr, struct io_status_block *iosb,
- LARGE_INTEGER *size, ULONG file_attr, ULONG share_access,
- ULONG create_disposition, ULONG create_options, void *ea_buffer,
- ULONG ea_length)
-{
- struct common_object_header *coh;
- struct file_object *fo;
- struct ansi_string ansi;
- struct wrap_bin_file *bin_file;
- char *file_basename;
- NTSTATUS status;
-
- spin_lock_bh(&ntoskernel_lock);
- nt_list_for_each_entry(coh, &object_list, list) {
- if (coh->type != OBJECT_TYPE_FILE)
- continue;
- /* TODO: check if file is opened in shared mode */
- if (!RtlCompareUnicodeString(&coh->name, obj_attr->name, TRUE)) {
- fo = HEADER_TO_OBJECT(coh);
- bin_file = fo->wrap_bin_file;
- *handle = coh;
- spin_unlock_bh(&ntoskernel_lock);
- ObReferenceObject(fo);
- iosb->status = FILE_OPENED;
- iosb->info = bin_file->size;
- EXIT2(return STATUS_SUCCESS);
- }
- }
- spin_unlock_bh(&ntoskernel_lock);
-
- if (RtlUnicodeStringToAnsiString(&ansi, obj_attr->name, TRUE) !=
- STATUS_SUCCESS)
- EXIT2(return STATUS_INSUFFICIENT_RESOURCES);
-
- file_basename = strrchr(ansi.buf, '\\');
- if (file_basename)
- file_basename++;
- else
- file_basename = ansi.buf;
- TRACE2("file: '%s', '%s'", ansi.buf, file_basename);
-
- fo = allocate_object(sizeof(struct file_object), OBJECT_TYPE_FILE,
- obj_attr->name);
- if (!fo) {
- RtlFreeAnsiString(&ansi);
- iosb->status = STATUS_INSUFFICIENT_RESOURCES;
- iosb->info = 0;
- EXIT2(return STATUS_FAILURE);
- }
- coh = OBJECT_TO_HEADER(fo);
- bin_file = get_bin_file(file_basename);
- if (bin_file) {
- TRACE2("%s, %s", bin_file->name, file_basename);
- fo->flags = FILE_OPENED;
- } else if (access_mask & FILE_WRITE_DATA) {
- bin_file = kzalloc(sizeof(*bin_file), GFP_KERNEL);
- if (bin_file) {
- strncpy(bin_file->name, file_basename,
- sizeof(bin_file->name));
- bin_file->name[sizeof(bin_file->name)-1] = 0;
- bin_file->data = vmalloc(*size);
- if (bin_file->data) {
- memset(bin_file->data, 0, *size);
- bin_file->size = *size;
- fo->flags = FILE_CREATED;
- } else {
- kfree(bin_file);
- bin_file = NULL;
- }
- }
- } else
- bin_file = NULL;
-
- RtlFreeAnsiString(&ansi);
- if (!bin_file) {
- iosb->status = FILE_DOES_NOT_EXIST;
- iosb->info = 0;
- free_object(fo);
- EXIT2(return STATUS_FAILURE);
- }
-
- fo->wrap_bin_file = bin_file;
- fo->current_byte_offset = 0;
- if (access_mask & FILE_READ_DATA)
- fo->read_access = TRUE;
- if (access_mask & FILE_WRITE_DATA)
- fo->write_access = TRUE;
- iosb->status = FILE_OPENED;
- iosb->info = bin_file->size;
- *handle = coh;
- TRACE2("handle: %p", *handle);
- status = STATUS_SUCCESS;
- EXIT2(return status);
-}
-
-wstdcall NTSTATUS WIN_FUNC(ZwOpenFile,6)
- (void **handle, ACCESS_MASK access_mask,
- struct object_attributes *obj_attr, struct io_status_block *iosb,
- ULONG share_access, ULONG open_options)
-{
- LARGE_INTEGER size;
- return ZwCreateFile(handle, access_mask, obj_attr, iosb, &size, 0,
- share_access, 0, open_options, NULL, 0);
-}
-
-wstdcall NTSTATUS WIN_FUNC(ZwReadFile,9)
- (void *handle, struct nt_event *event, void *apc_routine,
- void *apc_context, struct io_status_block *iosb, void *buffer,
- ULONG length, LARGE_INTEGER *byte_offset, ULONG *key)
-{
- struct file_object *fo;
- struct common_object_header *coh;
- ULONG count;
- size_t offset;
- struct wrap_bin_file *file;
-
- TRACE2("%p", handle);
- coh = handle;
- if (coh->type != OBJECT_TYPE_FILE) {
- ERROR("handle %p is invalid: %d", handle, coh->type);
- EXIT2(return STATUS_FAILURE);
- }
- fo = HANDLE_TO_OBJECT(coh);
- file = fo->wrap_bin_file;
- TRACE2("file: %s (%zu)", file->name, file->size);
- spin_lock_bh(&ntoskernel_lock);
- if (byte_offset)
- offset = *byte_offset;
- else
- offset = fo->current_byte_offset;
- count = min((size_t)length, file->size - offset);
- TRACE2("count: %u, offset: %zu, length: %u", count, offset, length);
- memcpy(buffer, ((void *)file->data) + offset, count);
- fo->current_byte_offset = offset + count;
- spin_unlock_bh(&ntoskernel_lock);
- iosb->status = STATUS_SUCCESS;
- iosb->info = count;
- EXIT2(return STATUS_SUCCESS);
-}
-
-wstdcall NTSTATUS WIN_FUNC(ZwWriteFile,9)
- (void *handle, struct nt_event *event, void *apc_routine,
- void *apc_context, struct io_status_block *iosb, void *buffer,
- ULONG length, LARGE_INTEGER *byte_offset, ULONG *key)
-{
- struct file_object *fo;
- struct common_object_header *coh;
- struct wrap_bin_file *file;
- unsigned long offset;
-
- TRACE2("%p", handle);
- coh = handle;
- if (coh->type != OBJECT_TYPE_FILE) {
- ERROR("handle %p is invalid: %d", handle, coh->type);
- EXIT2(return STATUS_FAILURE);
- }
- fo = HANDLE_TO_OBJECT(coh);
- file = fo->wrap_bin_file;
- TRACE2("file: %zu, %u", file->size, length);
- spin_lock_bh(&ntoskernel_lock);
- if (byte_offset)
- offset = *byte_offset;
- else
- offset = fo->current_byte_offset;
- if (length + offset > file->size) {
- WARNING("%lu, %u", length + offset, (unsigned int)file->size);
- /* TODO: implement writing past end of current size */
- iosb->status = STATUS_FAILURE;
- iosb->info = 0;
- } else {
- memcpy(file->data + offset, buffer, length);
- iosb->status = STATUS_SUCCESS;
- iosb->info = length;
- fo->current_byte_offset = offset + length;
- }
- spin_unlock_bh(&ntoskernel_lock);
- EXIT2(return iosb->status);
-}
-
-wstdcall NTSTATUS WIN_FUNC(ZwClose,1)
- (void *handle)
-{
- struct common_object_header *coh;
-
- TRACE2("%p", handle);
- if (handle == NULL) {
- TRACE1("");
- EXIT2(return STATUS_SUCCESS);
- }
- coh = handle;
- if (coh->type == OBJECT_TYPE_FILE) {
- struct file_object *fo;
- struct wrap_bin_file *bin_file;
- typeof(fo->flags) flags;
-
- fo = HANDLE_TO_OBJECT(handle);
- flags = fo->flags;
- bin_file = fo->wrap_bin_file;
- if (dereference_object(fo)) {
- if (flags == FILE_CREATED) {
- vfree(bin_file->data);
- kfree(bin_file);
- } else
- free_bin_file(bin_file);
- }
- } else if (coh->type == OBJECT_TYPE_NT_THREAD) {
- struct nt_thread *thread = HANDLE_TO_OBJECT(handle);
- TRACE2("thread: %p (%p)", thread, handle);
- ObDereferenceObject(thread);
- } else {
- /* TODO: can we just dereference object here? */
- WARNING("closing handle 0x%x not implemented", coh->type);
- }
- EXIT2(return STATUS_SUCCESS);
-}
-
-wstdcall NTSTATUS WIN_FUNC(ZwQueryInformationFile,5)
- (void *handle, struct io_status_block *iosb, void *info,
- ULONG length, enum file_info_class class)
-{
- struct file_object *fo;
- struct file_name_info *fni;
- struct file_std_info *fsi;
- struct wrap_bin_file *file;
- struct common_object_header *coh;
-
- ENTER2("%p", handle);
- coh = handle;
- if (coh->type != OBJECT_TYPE_FILE) {
- ERROR("handle %p is invalid: %d", coh, coh->type);
- EXIT2(return STATUS_FAILURE);
- }
- fo = HANDLE_TO_OBJECT(handle);
- TRACE2("fo: %p, %d", fo, class);
- switch (class) {
- case FileNameInformation:
- fni = info;
- fni->length = min(length, (typeof(length))coh->name.length);
- memcpy(fni->name, coh->name.buf, fni->length);
- iosb->status = STATUS_SUCCESS;
- iosb->info = fni->length;
- break;
- case FileStandardInformation:
- fsi = info;
- file = fo->wrap_bin_file;
- fsi->alloc_size = file->size;
- fsi->eof = file->size;
- fsi->num_links = 1;
- fsi->delete_pending = FALSE;
- fsi->dir = FALSE;
- iosb->status = STATUS_SUCCESS;
- iosb->info = 0;
- break;
- default:
- WARNING("type %d not implemented yet", class);
- iosb->status = STATUS_FAILURE;
- iosb->info = 0;
- break;
- }
- EXIT2(return iosb->status);
-}
-
-wstdcall NTSTATUS WIN_FUNC(ZwOpenSection,3)
- (void **handle, ACCESS_MASK access, struct object_attributes *obj_attrs)
-{
- INFO("%p, 0x%x, %d", obj_attrs, obj_attrs->attributes, access);
- TODO();
- *handle = obj_attrs;
- return STATUS_SUCCESS;
-}
-
-wstdcall NTSTATUS WIN_FUNC(ZwMapViewOfSection,10)
- (void *secn_handle, void *process_handle, void **base_address,
- ULONG zero_bits, LARGE_INTEGER *secn_offset, SIZE_T *view_size,
- enum section_inherit inherit, ULONG alloc_type, ULONG protect)
-{
- INFO("%p, %p, %p", secn_handle, process_handle, base_address);
- TODO();
- *base_address = (void *)0xdeadbeef;
- return STATUS_SUCCESS;
-}
-
-wstdcall NTSTATUS WIN_FUNC(ZwUnmapViewOfSection,2)
- (void *process_handle, void *base_address)
-{
- INFO("%p, %p", process_handle, base_address);
- TODO();
- return STATUS_SUCCESS;
-}
-
-wstdcall NTSTATUS WIN_FUNC(ZwCreateKey,7)
- (void **handle, ACCESS_MASK desired_access,
- struct object_attributes *attr, ULONG title_index,
- struct unicode_string *class, ULONG create_options,
- ULONG *disposition)
-{
- struct ansi_string ansi;
- if (RtlUnicodeStringToAnsiString(&ansi, attr->name, TRUE) ==
- STATUS_SUCCESS) {
- TRACE1("key: %s", ansi.buf);
- RtlFreeAnsiString(&ansi);
- }
- *handle = NULL;
- return STATUS_SUCCESS;
-}
-
-wstdcall NTSTATUS WIN_FUNC(ZwOpenKey,3)
- (void **handle, ACCESS_MASK desired_access,
- struct object_attributes *attr)
-{
- struct ansi_string ansi;
- if (RtlUnicodeStringToAnsiString(&ansi, attr->name, TRUE) ==
- STATUS_SUCCESS) {
- TRACE1("key: %s", ansi.buf);
- RtlFreeAnsiString(&ansi);
- }
- *handle = NULL;
- return STATUS_SUCCESS;
-}
-
-wstdcall NTSTATUS WIN_FUNC(ZwSetValueKey,6)
- (void *handle, struct unicode_string *name, ULONG title_index,
- ULONG type, void *data, ULONG data_size)
-{
- struct ansi_string ansi;
- if (RtlUnicodeStringToAnsiString(&ansi, name, TRUE) ==
- STATUS_SUCCESS) {
- TRACE1("key: %s", ansi.buf);
- RtlFreeAnsiString(&ansi);
- }
- return STATUS_SUCCESS;
-}
-
-wstdcall NTSTATUS WIN_FUNC(ZwQueryValueKey,6)
- (void *handle, struct unicode_string *name,
- enum key_value_information_class class, void *info,
- ULONG length, ULONG *res_length)
-{
- struct ansi_string ansi;
- if (RtlUnicodeStringToAnsiString(&ansi, name, TRUE) == STATUS_SUCCESS) {
- TRACE1("key: %s", ansi.buf);
- RtlFreeAnsiString(&ansi);
- }
- TODO();
- return STATUS_INVALID_PARAMETER;
-}
-
-wstdcall NTSTATUS WIN_FUNC(ZwDeleteKey,1)
- (void *handle)
-{
- ENTER2("%p", handle);
- return STATUS_SUCCESS;
-}
-
-wstdcall NTSTATUS WIN_FUNC(ZwPowerInformation,4)
- (INT info_level, void *in_buf, ULONG in_buf_len, void *out_buf,
- ULONG out_buf_len)
-{
- INFO("%d, %u, %u", info_level, in_buf_len, out_buf_len);
- TODO();
- return STATUS_ACCESS_DENIED;
-}
-
-wstdcall NTSTATUS WIN_FUNC(WmiSystemControl,4)
- (struct wmilib_context *info, struct device_object *dev_obj,
- struct irp *irp, void *irp_disposition)
-{
- TODO();
- return STATUS_SUCCESS;
-}
-
-wstdcall NTSTATUS WIN_FUNC(WmiCompleteRequest,5)
- (struct device_object *dev_obj, struct irp *irp, NTSTATUS status,
- ULONG buffer_used, CCHAR priority_boost)
-{
- TODO();
- return STATUS_SUCCESS;
-}
-
-noregparm NTSTATUS WIN_FUNC(WmiTraceMessage,12)
- (void *tracehandle, ULONG message_flags,
- void *message_guid, USHORT message_no, ...)
-{
- TODO();
- EXIT2(return STATUS_SUCCESS);
-}
-
-wstdcall NTSTATUS WIN_FUNC(WmiQueryTraceInformation,4)
- (enum trace_information_class trace_info_class, void *trace_info,
- ULONG *req_length, void *buf)
-{
- TODO();
- EXIT2(return STATUS_SUCCESS);
-}
-
-/* this function can't be wstdcall as it takes variable number of args */
-noregparm ULONG WIN_FUNC(DbgPrint,12)
- (char *format, ...)
-{
-#ifdef DEBUG
- va_list args;
- static char buf[100];
-
- va_start(args, format);
- vsnprintf(buf, sizeof(buf), format, args);
- printk(KERN_DEBUG "%s (%s): %s", DRIVER_NAME, __func__, buf);
- va_end(args);
-#endif
- return STATUS_SUCCESS;
-}
-
-wstdcall void WIN_FUNC(KeBugCheck,1)
- (ULONG code)
-{
- TODO();
- return;
-}
-
-wstdcall void WIN_FUNC(KeBugCheckEx,5)
- (ULONG code, ULONG_PTR param1, ULONG_PTR param2,
- ULONG_PTR param3, ULONG_PTR param4)
-{
- TODO();
- return;
-}
-
-wstdcall void WIN_FUNC(ExSystemTimeToLocalTime,2)
- (LARGE_INTEGER *system_time, LARGE_INTEGER *local_time)
-{
- *local_time = *system_time;
-}
-
-wstdcall ULONG WIN_FUNC(ExSetTimerResolution,2)
- (ULONG time, BOOLEAN set)
-{
- /* why a driver should change system wide timer resolution is
- * beyond me */
- return time;
-}
-
-wstdcall void WIN_FUNC(DbgBreakPoint,0)
- (void)
-{
- TODO();
-}
-
-wstdcall void WIN_FUNC(_except_handler3,0)
- (void)
-{
- TODO();
-}
-
-wstdcall void WIN_FUNC(__C_specific_handler,0)
- (void)
-{
- TODO();
-}
-
-wstdcall void WIN_FUNC(_purecall,0)
- (void)
-{
- TODO();
-}
-
-wstdcall void WIN_FUNC(__chkstk,0)
- (void)
-{
- TODO();
-}
-
-struct worker_init_struct {
- work_struct_t work;
- struct completion completion;
- struct nt_thread *nt_thread;
-};
-
-static void wrap_worker_init_func(worker_param_t param)
-{
- struct worker_init_struct *worker_init_struct;
-
- worker_init_struct =
- worker_param_data(param, struct worker_init_struct, work);
- TRACE1("%p", worker_init_struct);
- worker_init_struct->nt_thread = create_nt_thread(current);
- if (!worker_init_struct->nt_thread)
- WARNING("couldn't create worker thread");
- complete(&worker_init_struct->completion);
-}
-
-struct nt_thread *wrap_worker_init(workqueue_struct_t *wq)
-{
- struct worker_init_struct worker_init_struct;
-
- TRACE1("%p", &worker_init_struct);
- init_completion(&worker_init_struct.completion);
- initialize_work(&worker_init_struct.work, wrap_worker_init_func,
- &worker_init_struct);
- worker_init_struct.nt_thread = NULL;
- if (wq)
- queue_work(wq, &worker_init_struct.work);
- else
- schedule_work(&worker_init_struct.work);
- wait_for_completion(&worker_init_struct.completion);
- TRACE1("%p", worker_init_struct.nt_thread);
- return worker_init_struct.nt_thread;
-}
-
-int ntoskernel_init(void)
-{
- struct timeval now;
-
- spin_lock_init(&dispatcher_lock);
- spin_lock_init(&ntoskernel_lock);
- spin_lock_init(&ntos_work_lock);
- spin_lock_init(&kdpc_list_lock);
- spin_lock_init(&irp_cancel_lock);
- InitializeListHead(&wrap_mdl_list);
- InitializeListHead(&kdpc_list);
- InitializeListHead(&callback_objects);
- InitializeListHead(&bus_driver_list);
- InitializeListHead(&object_list);
- InitializeListHead(&ntos_work_list);
-
- nt_spin_lock_init(&nt_list_lock);
-
- initialize_work(&kdpc_work, kdpc_worker, NULL);
- initialize_work(&ntos_work, ntos_work_worker, NULL);
- wrap_timer_slist.next = NULL;
-
- do_gettimeofday(&now);
- wrap_ticks_to_boot = TICKS_1601_TO_1970;
- wrap_ticks_to_boot += (u64)now.tv_sec * TICKSPERSEC;
- wrap_ticks_to_boot += now.tv_usec * 10;
- wrap_ticks_to_boot -= jiffies * TICKSPERJIFFY;
- TRACE2("%Lu", wrap_ticks_to_boot);
-
-#ifdef WRAP_PREEMPT
- do {
- int cpu;
- for_each_possible_cpu(cpu) {
- irql_info_t *info;
- info = &per_cpu(irql_info, cpu);
- mutex_init(&(info->lock));
- info->task = NULL;
- info->count = 0;
- }
- } while (0);
-#endif
-
- ntos_wq = create_singlethread_workqueue("ntos_wq");
- if (!ntos_wq) {
- WARNING("couldn't create ntos_wq thread");
- return -ENOMEM;
- }
- ntos_worker_thread = wrap_worker_init(ntos_wq);
- TRACE1("%p", ntos_worker_thread);
-
- if (add_bus_driver("PCI")
-#ifdef ENABLE_USB
- || add_bus_driver("USB")
-#endif
- ) {
- ntoskernel_exit();
- return -ENOMEM;
- }
- mdl_cache =
- wrap_kmem_cache_create("wrap_mdl",
- sizeof(struct wrap_mdl) + MDL_CACHE_SIZE,
- 0, 0);
- TRACE2("%p", mdl_cache);
- if (!mdl_cache) {
- ERROR("couldn't allocate MDL cache");
- ntoskernel_exit();
- return -ENOMEM;
- }
-
-#if defined(CONFIG_X86_64)
- memset(&kuser_shared_data, 0, sizeof(kuser_shared_data));
- *((ULONG64 *)&kuser_shared_data.system_time) = ticks_1601();
- init_timer(&shared_data_timer);
- shared_data_timer.function = update_user_shared_data_proc;
- shared_data_timer.data = (unsigned long)0;
-#endif
- return 0;
-}
-
-int ntoskernel_init_device(struct wrap_device *wd)
-{
-#if defined(CONFIG_X86_64)
- if (kuser_shared_data.reserved1)
- mod_timer(&shared_data_timer, jiffies + MSEC_TO_HZ(30));
-#endif
- return 0;
-}
-
-void ntoskernel_exit_device(struct wrap_device *wd)
-{
- ENTER2("");
-
- KeFlushQueuedDpcs();
- EXIT2(return);
-}
-
-void ntoskernel_exit(void)
-{
- struct nt_list *cur;
-
- ENTER2("");
-
- /* free kernel (Ke) timers */
- TRACE2("freeing timers");
- while (1) {
- struct wrap_timer *wrap_timer;
- struct nt_slist *slist;
-
- spin_lock_bh(&ntoskernel_lock);
- if ((slist = wrap_timer_slist.next))
- wrap_timer_slist.next = slist->next;
- spin_unlock_bh(&ntoskernel_lock);
- TIMERTRACE("%p", slist);
- if (!slist)
- break;
- wrap_timer = container_of(slist, struct wrap_timer, slist);
- if (del_timer_sync(&wrap_timer->timer))
- WARNING("Buggy Windows driver left timer %p running",
- wrap_timer->nt_timer);
- memset(wrap_timer, 0, sizeof(*wrap_timer));
- slack_kfree(wrap_timer);
- }
-
- TRACE2("freeing MDLs");
- if (mdl_cache) {
- spin_lock_bh(&ntoskernel_lock);
- if (!IsListEmpty(&wrap_mdl_list))
- ERROR("Windows driver didn't free all MDLs; "
- "freeing them now");
- while ((cur = RemoveHeadList(&wrap_mdl_list))) {
- struct wrap_mdl *wrap_mdl;
- wrap_mdl = container_of(cur, struct wrap_mdl, list);
- if (wrap_mdl->mdl->flags & MDL_CACHE_ALLOCATED)
- kmem_cache_free(mdl_cache, wrap_mdl);
- else
- kfree(wrap_mdl);
- }
- spin_unlock_bh(&ntoskernel_lock);
- kmem_cache_destroy(mdl_cache);
- mdl_cache = NULL;
- }
-
- TRACE2("freeing callbacks");
- spin_lock_bh(&ntoskernel_lock);
- while ((cur = RemoveHeadList(&callback_objects))) {
- struct callback_object *object;
- struct nt_list *ent;
- object = container_of(cur, struct callback_object, list);
- while ((ent = RemoveHeadList(&object->callback_funcs))) {
- struct callback_func *f;
- f = container_of(ent, struct callback_func, list);
- kfree(f);
- }
- kfree(object);
- }
- spin_unlock_bh(&ntoskernel_lock);
-
- spin_lock_bh(&ntoskernel_lock);
- while ((cur = RemoveHeadList(&bus_driver_list))) {
- struct bus_driver *bus_driver;
- bus_driver = container_of(cur, struct bus_driver, list);
- /* TODO: make sure all all drivers are shutdown/removed */
- kfree(bus_driver);
- }
- spin_unlock_bh(&ntoskernel_lock);
-
-#if defined(CONFIG_X86_64)
- del_timer_sync(&shared_data_timer);
-#endif
- if (ntos_wq)
- destroy_workqueue(ntos_wq);
- TRACE1("%p", ntos_worker_thread);
- if (ntos_worker_thread)
- ObDereferenceObject(ntos_worker_thread);
- ENTER2("freeing objects");
- spin_lock_bh(&ntoskernel_lock);
- while ((cur = RemoveHeadList(&object_list))) {
- struct common_object_header *hdr;
- hdr = container_of(cur, struct common_object_header, list);
- if (hdr->type == OBJECT_TYPE_NT_THREAD)
- TRACE1("object %p(%d) was not freed, freeing it now",
- HEADER_TO_OBJECT(hdr), hdr->type);
- else
- WARNING("object %p(%d) was not freed, freeing it now",
- HEADER_TO_OBJECT(hdr), hdr->type);
- ExFreePool(hdr);
- }
- spin_unlock_bh(&ntoskernel_lock);
-
- EXIT2(return);
-}
+++ /dev/null
-/*
- * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef _NTOSKERNEL_H_
-#define _NTOSKERNEL_H_
-
-#include <linux/types.h>
-#include <linux/timer.h>
-#include <linux/time.h>
-#include <linux/module.h>
-#include <linux/kmod.h>
-
-#include <linux/netdevice.h>
-#include <linux/wireless.h>
-#include <linux/pci.h>
-#include <linux/wait.h>
-#include <linux/pm.h>
-#include <linux/delay.h>
-#include <linux/mm.h>
-#include <linux/random.h>
-#include <linux/ctype.h>
-#include <linux/list.h>
-#include <linux/sched.h>
-#include <linux/usb.h>
-#include <linux/spinlock.h>
-#include <asm/mman.h>
-#include <linux/version.h>
-#include <linux/etherdevice.h>
-#include <net/iw_handler.h>
-#include <linux/ethtool.h>
-#include <linux/if_arp.h>
-#include <linux/rtnetlink.h>
-#include <linux/highmem.h>
-#include <linux/percpu.h>
-#include <linux/kthread.h>
-#include <linux/workqueue.h>
-
-#if !defined(CONFIG_X86) && !defined(CONFIG_X86_64)
-#error "this module is for x86 or x86_64 architectures only"
-#endif
-
-/* Interrupt backwards compatibility stuff */
-#include <linux/interrupt.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
-#ifndef IRQ_HANDLED
-#define IRQ_HANDLED
-#define IRQ_NONE
-#define irqreturn_t void
-#endif
-#endif /* Linux < 2.6.29 */
-
-/* pci functions in 2.6 kernels have problems allocating dma buffers,
- * but seem to work fine with dma functions
- */
-#include <asm/dma-mapping.h>
-
-#define PCI_DMA_ALLOC_COHERENT(pci_dev,size,dma_handle) \
- dma_alloc_coherent(&pci_dev->dev,size,dma_handle, \
- GFP_KERNEL | __GFP_REPEAT)
-#define PCI_DMA_FREE_COHERENT(pci_dev,size,cpu_addr,dma_handle) \
- dma_free_coherent(&pci_dev->dev,size,cpu_addr,dma_handle)
-#define PCI_DMA_MAP_SINGLE(pci_dev,addr,size,direction) \
- dma_map_single(&pci_dev->dev,addr,size,direction)
-#define PCI_DMA_UNMAP_SINGLE(pci_dev,dma_handle,size,direction) \
- dma_unmap_single(&pci_dev->dev,dma_handle,size,direction)
-#define MAP_SG(pci_dev, sglist, nents, direction) \
- dma_map_sg(&pci_dev->dev, sglist, nents, direction)
-#define UNMAP_SG(pci_dev, sglist, nents, direction) \
- dma_unmap_sg(&pci_dev->dev, sglist, nents, direction)
-#define PCI_DMA_MAP_ERROR(dma_addr) dma_mapping_error(dma_addr)
-
-
-#if defined(CONFIG_NET_RADIO) && !defined(CONFIG_WIRELESS_EXT)
-#define CONFIG_WIRELESS_EXT
-#endif
-
-#define prepare_wait_condition(task, var, value) \
-do { \
- var = value; \
- task = current; \
- barrier(); \
-} while (0)
-
-/* Wait in wait_state (e.g., TASK_INTERRUPTIBLE) for condition to
- * become true; timeout is either jiffies (> 0) to wait or 0 to wait
- * forever.
- * When timeout == 0, return value is
- * > 0 if condition becomes true, or
- * < 0 if signal is pending on the thread.
- * When timeout > 0, return value is
- * > 0 if condition becomes true before timeout,
- * < 0 if signal is pending on the thread before timeout, or
- * 0 if timedout (condition may have become true at the same time)
- */
-
-#define wait_condition(condition, timeout, wait_state) \
-({ \
- long ret = timeout ? timeout : 1; \
- while (1) { \
- if (signal_pending(current)) { \
- ret = -ERESTARTSYS; \
- break; \
- } \
- set_current_state(wait_state); \
- if (condition) { \
- __set_current_state(TASK_RUNNING); \
- break; \
- } \
- if (timeout) { \
- ret = schedule_timeout(ret); \
- if (!ret) \
- break; \
- } else \
- schedule(); \
- } \
- ret; \
-})
-
-#ifdef WRAP_WQ
-
-struct workqueue_struct;
-
-struct workqueue_thread {
- spinlock_t lock;
- struct task_struct *task;
- struct completion *completion;
- char name[16];
- int pid;
- /* whether any work_structs pending? <0 implies quit */
- s8 pending;
- /* list of work_structs pending */
- struct list_head work_list;
-};
-
-typedef struct workqueue_struct {
- u8 singlethread;
- u8 qon;
- int num_cpus;
- struct workqueue_thread threads[0];
-} workqueue_struct_t;
-
-typedef struct {
- struct list_head list;
- void (*func)(void *data);
- void *data;
- /* whether/on which thread scheduled */
- struct workqueue_thread *thread;
-} work_struct_t;
-
-#define initialize_work(work, pfunc, pdata) \
- do { \
- (work)->func = (pfunc); \
- (work)->data = (pdata); \
- (work)->thread = NULL; \
- } while (0)
-
-#undef create_singlethread_workqueue
-#define create_singlethread_workqueue(name) wrap_create_wq(name, 1, 0)
-#undef create_workqueue
-#define create_workqueue(name) wrap_create_wq(name, 0, 0)
-#undef destroy_workqueue
-#define destroy_workqueue wrap_destroy_wq
-#undef queue_work
-#define queue_work wrap_queue_work
-#undef flush_workqueue
-#define flush_workqueue wrap_flush_wq
-
-workqueue_struct_t *wrap_create_wq(const char *name, u8 singlethread, u8 freeze);
-void wrap_destroy_wq_on(workqueue_struct_t *workq, int cpu);
-void wrap_destroy_wq(workqueue_struct_t *workq);
-int wrap_queue_work_on(workqueue_struct_t *workq, work_struct_t *work,
- int cpu);
-int wrap_queue_work(workqueue_struct_t *workq, work_struct_t *work);
-void wrap_cancel_work(work_struct_t *work);
-void wrap_flush_wq_on(workqueue_struct_t *workq, int cpu);
-void wrap_flush_wq(workqueue_struct_t *workq);
-typedef void *worker_param_t;
-#define worker_param_data(param, type, member) param
-
-#else // WRAP_WQ
-
-typedef struct workqueue_struct workqueue_struct_t;
-typedef struct work_struct work_struct_t;
-
-#if defined(INIT_WORK_NAR) || defined(INIT_DELAYED_WORK_DEFERRABLE)
-#define initialize_work(work, func, data) INIT_WORK(work, func)
-typedef struct work_struct *worker_param_t;
-#define worker_param_data(param, type, member) \
- container_of(param, type, member)
-#else
-#define initialize_work(work, func, data) INIT_WORK(work, func, data)
-typedef void *worker_param_t;
-#define worker_param_data(param, type, member) param
-#endif // INIT_WORK_NAR
-
-#endif // WRAP_WQ
-
-struct nt_thread *wrap_worker_init(workqueue_struct_t *wq);
-
-#ifdef module_param
-#define WRAP_MODULE_PARM_INT(name, perm) module_param(name, int, perm)
-#define WRAP_MODULE_PARM_STRING(name, perm) module_param(name, charp, perm)
-#else
-#define WRAP_MODULE_PARM_INT(name, perm) MODULE_PARM(name, "i")
-#define WRAP_MODULE_PARM_STRING(name, perm) MODULE_PARM(name, "s")
-#endif
-
-#ifndef LOCK_PREFIX
-#ifdef LOCK
-#define LOCK_PREFIX LOCK
-#else
-#ifdef CONFIG_SMP
-#define LOCK_PREFIX "lock ; "
-#else
-#define LOCK_PREFIX ""
-#endif
-#endif
-#endif
-
-#ifndef NETDEV_TX_OK
-#define NETDEV_TX_OK 0
-#endif
-
-#ifndef NETDEV_TX_BUSY
-#define NETDEV_TX_BUSY 1
-#endif
-
-#ifndef CHECKSUM_HW
-#define CHECKSUM_HW CHECKSUM_PARTIAL
-#endif
-
-#ifndef offset_in_page
-#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
-#endif
-
-#ifndef PMSG_SUSPEND
-#ifdef PM_SUSPEND
-/* this is not correct - the value of PM_SUSPEND is different from
- * PMSG_SUSPEND, but ndiswrapper doesn't care about the value when
- * suspending */
-#define PMSG_SUSPEND PM_SUSPEND
-#define PSMG_ON PM_ON
-#else
-typedef u32 pm_message_t;
-#define PMSG_SUSPEND 2
-#define PMSG_ON 0
-#endif
-#endif
-
-#ifndef PCI_D0
-#define PCI_D0 0
-#endif
-
-#ifndef PCI_D3hot
-#define PCI_D3hot 3
-#endif
-
-#ifndef PCI_D3cold
-#define PCI_D3cold 3
-#endif
-
-#ifndef PM_EVENT_SUSPEND
-#define PM_EVENT_SUSPEND 2
-#endif
-
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)
-#define ISR_PT_REGS_PARAM_DECL
-#define ISR_PT_REGS_ARG
-#else
-#define ISR_PT_REGS_PARAM_DECL , struct pt_regs *regs
-#define ISR_PT_REGS_ARG , NULL
-#endif
-
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16)
-#define for_each_possible_cpu(_cpu) for_each_cpu(_cpu)
-#endif
-
-#ifndef flush_icache_range
-#define flush_icache_range(start, end) do { } while (0)
-#endif
-
-#ifndef CHECKSUM_PARTIAL
-#define CHECKSUM_PARTIAL CHECKSUM_HW
-#endif
-
-#ifndef IRQF_SHARED
-#define IRQF_SHARED SA_SHIRQ
-#endif
-
-#define memcpy_skb(skb, from, length) \
- memcpy(skb_put(skb, length), from, length)
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
-#ifndef DMA_BIT_MASK
-#define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
-#endif
-#endif
-
-#ifndef __GFP_DMA32
-#define __GFP_DMA32 GFP_DMA
-#endif
-
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22)
-#define wrap_kmem_cache_create(name, size, align, flags) \
- kmem_cache_create(name, size, align, flags, NULL, NULL)
-#else
-#define wrap_kmem_cache_create(name, size, align, flags) \
- kmem_cache_create(name, size, align, flags, NULL)
-#endif
-
-#include "winnt_types.h"
-#include "ndiswrapper.h"
-#include "pe_linker.h"
-#include "wrapmem.h"
-#include "lin2win.h"
-#include "loader.h"
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
-static inline void netif_tx_lock(struct net_device *dev)
-{
- spin_lock(&dev->xmit_lock);
-}
-static inline void netif_tx_unlock(struct net_device *dev)
-{
- spin_unlock(&dev->xmit_lock);
-}
-static inline void netif_tx_lock_bh(struct net_device *dev)
-{
- spin_lock_bh(&dev->xmit_lock);
-}
-static inline void netif_tx_unlock_bh(struct net_device *dev)
-{
- spin_unlock_bh(&dev->xmit_lock);
-}
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-static inline void netif_poll_enable(struct net_device *dev)
-{
-}
-static inline void netif_poll_disable(struct net_device *dev)
-{
-}
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-#define proc_net_root init_net.proc_net
-#else
-#define proc_net_root proc_net
-#endif
-
-/* TICK is 100ns */
-#define TICKSPERSEC 10000000
-#define TICKSPERMSEC 10000
-#define SECSPERDAY 86400
-#define TICKSPERJIFFY ((TICKSPERSEC + HZ - 1) / HZ)
-
-#define int_div_round(x, y) (((x) + (y - 1)) / (y))
-
-/* 1601 to 1970 is 369 years plus 89 leap days */
-#define SECS_1601_TO_1970 ((369 * 365 + 89) * (u64)SECSPERDAY)
-#define TICKS_1601_TO_1970 (SECS_1601_TO_1970 * TICKSPERSEC)
-
-/* 100ns units to HZ; if sys_time is negative, relative to current
- * clock, otherwise from year 1601 */
-#define SYSTEM_TIME_TO_HZ(sys_time) \
- (((sys_time) <= 0) ? \
- int_div_round(((u64)HZ * (-(sys_time))), TICKSPERSEC) : \
- int_div_round(((s64)HZ * ((sys_time) - ticks_1601())), TICKSPERSEC))
-
-#define MSEC_TO_HZ(ms) int_div_round((ms * HZ), 1000)
-#define USEC_TO_HZ(us) int_div_round((us * HZ), 1000000)
-
-extern u64 wrap_ticks_to_boot;
-
-static inline u64 ticks_1601(void)
-{
- return wrap_ticks_to_boot + (u64)jiffies * TICKSPERJIFFY;
-}
-
-typedef void (*generic_func)(void);
-
-struct wrap_export {
- const char *name;
- generic_func func;
-};
-
-#ifdef CONFIG_X86_64
-
-#define WIN_SYMBOL(name, argc) \
- {#name, (generic_func) win2lin_ ## name ## _ ## argc}
-#define WIN_WIN_SYMBOL(name, argc) \
- {#name, (generic_func) win2lin__win_ ## name ## _ ## argc}
-#define WIN_FUNC_DECL(name, argc) \
- extern typeof(name) win2lin_ ## name ## _ ## argc;
-#define WIN_FUNC_PTR(name, argc) win2lin_ ## name ## _ ## argc
-
-#else
-
-#define WIN_SYMBOL(name, argc) {#name, (generic_func)name}
-#define WIN_WIN_SYMBOL(name, argc) {#name, (generic_func)_win_ ## name}
-#define WIN_FUNC_DECL(name, argc)
-#define WIN_FUNC_PTR(name, argc) name
-
-#endif
-
-#define WIN_FUNC(name, argc) name
-/* map name s to f - if f is different from s */
-#define WIN_SYMBOL_MAP(s, f)
-
-#define POOL_TAG(A, B, C, D) \
- ((ULONG)((A) + ((B) << 8) + ((C) << 16) + ((D) << 24)))
-
-struct pe_image {
- char name[MAX_DRIVER_NAME_LEN];
- UINT (*entry)(struct driver_object *, struct unicode_string *) wstdcall;
- void *image;
- int size;
- int type;
-
- IMAGE_NT_HEADERS *nt_hdr;
- IMAGE_OPTIONAL_HEADER *opt_hdr;
-};
-
-struct ndis_mp_block;
-
-struct wrap_timer {
- struct nt_slist slist;
- struct timer_list timer;
- struct nt_timer *nt_timer;
- long repeat;
-#ifdef TIMER_DEBUG
- unsigned long wrap_timer_magic;
-#endif
-};
-
-struct ntos_work_item {
- struct nt_list list;
- void *arg1;
- void *arg2;
- NTOS_WORK_FUNC func;
-};
-
-struct wrap_device_setting {
- struct nt_list list;
- char name[MAX_SETTING_NAME_LEN];
- char value[MAX_SETTING_VALUE_LEN];
- void *encoded;
-};
-
-struct wrap_bin_file {
- char name[MAX_DRIVER_NAME_LEN];
- size_t size;
- void *data;
-};
-
-#define WRAP_DRIVER_CLIENT_ID 1
-
-struct wrap_driver {
- struct nt_list list;
- struct driver_object *drv_obj;
- char name[MAX_DRIVER_NAME_LEN];
- char version[MAX_SETTING_VALUE_LEN];
- unsigned short num_pe_images;
- struct pe_image pe_images[MAX_DRIVER_PE_IMAGES];
- unsigned short num_bin_files;
- struct wrap_bin_file *bin_files;
- struct nt_list wrap_devices;
- struct nt_list settings;
- int dev_type;
- struct ndis_driver *ndis_driver;
-};
-
-enum hw_status {
- HW_INITIALIZED = 1, HW_SUSPENDED, HW_HALTED, HW_PRESENT,
-};
-
-struct wrap_device {
- /* first part is (de)initialized once by loader */
- struct nt_list list;
- int dev_bus;
- int vendor;
- int device;
- int subvendor;
- int subdevice;
- char conf_file_name[MAX_DRIVER_NAME_LEN];
- char driver_name[MAX_DRIVER_NAME_LEN];
- struct wrap_driver *driver;
- struct nt_list settings;
-
- /* rest should be (de)initialized when a device is
- * (un)plugged */
- struct cm_resource_list *resource_list;
- unsigned long hw_status;
- struct device_object *pdo;
- union {
- struct {
- struct pci_dev *pdev;
- enum device_power_state wake_state;
- } pci;
- struct {
- struct usb_device *udev;
- struct usb_interface *intf;
- int num_alloc_urbs;
- struct nt_list wrap_urb_list;
- } usb;
- };
- union {
- struct ndis_device *wnd;
- };
-};
-
-#define wrap_is_pci_bus(dev_bus) \
- (WRAP_BUS(dev_bus) == WRAP_PCI_BUS || \
- WRAP_BUS(dev_bus) == WRAP_PCMCIA_BUS)
-#ifdef ENABLE_USB
-/* earlier versions of ndiswrapper used 0 as USB_BUS */
-#define wrap_is_usb_bus(dev_bus) \
- (WRAP_BUS(dev_bus) == WRAP_USB_BUS || \
- WRAP_BUS(dev_bus) == WRAP_INTERNAL_BUS)
-#else
-#define wrap_is_usb_bus(dev_bus) 0
-#endif
-#define wrap_is_bluetooth_device(dev_bus) \
- (WRAP_DEVICE(dev_bus) == WRAP_BLUETOOTH_DEVICE1 || \
- WRAP_DEVICE(dev_bus) == WRAP_BLUETOOTH_DEVICE2)
-
-extern workqueue_struct_t *ntos_wq;
-#define schedule_ntos_work(work_struct) queue_work(ntos_wq, work_struct)
-#define schedule_work(work_struct) queue_work(ntos_wq, work_struct)
-
-extern workqueue_struct_t *ndis_wq;
-#define schedule_ndis_work(work_struct) queue_work(ndis_wq, work_struct)
-
-extern workqueue_struct_t *wrapndis_wq;
-#define schedule_wrapndis_work(work_struct) queue_work(wrapndis_wq, work_struct)
-
-#define atomic_unary_op(var, size, oper) \
-do { \
- if (size == 1) \
- __asm__ __volatile__( \
- LOCK_PREFIX oper "b %b0\n\t" : "+m" (var)); \
- else if (size == 2) \
- __asm__ __volatile__( \
- LOCK_PREFIX oper "w %w0\n\t" : "+m" (var)); \
- else if (size == 4) \
- __asm__ __volatile__( \
- LOCK_PREFIX oper "l %0\n\t" : "+m" (var)); \
- else if (size == 8) \
- __asm__ __volatile__( \
- LOCK_PREFIX oper "q %q0\n\t" : "+m" (var)); \
- else { \
- extern void _invalid_op_size_(void); \
- _invalid_op_size_(); \
- } \
-} while (0)
-
-#define atomic_inc_var_size(var, size) atomic_unary_op(var, size, "inc")
-
-#define atomic_inc_var(var) atomic_inc_var_size(var, sizeof(var))
-
-#define atomic_dec_var_size(var, size) atomic_unary_op(var, size, "dec")
-
-#define atomic_dec_var(var) atomic_dec_var_size(var, sizeof(var))
-
-#define pre_atomic_add(var, i) \
-({ \
- typeof(var) pre; \
- __asm__ __volatile__( \
- LOCK_PREFIX "xadd %0, %1\n\t" \
- : "=r"(pre), "+m"(var) \
- : "0"(i)); \
- pre; \
-})
-
-#define post_atomic_add(var, i) (pre_atomic_add(var, i) + i)
-
-#ifndef in_atomic
-#define in_atomic() in_interrupt()
-#endif
-
-#ifndef preempt_enable_no_resched
-#define preempt_enable_no_resched() preempt_enable()
-#endif
-
-//#define DEBUG_IRQL 1
-
-#ifdef DEBUG_IRQL
-#define assert_irql(cond) \
-do { \
- KIRQL _irql_ = current_irql(); \
- if (!(cond)) { \
- WARNING("assertion '%s' failed: %d", #cond, _irql_); \
- DBG_BLOCK(4) { \
- dump_stack(); \
- } \
- } \
-} while (0)
-#else
-#define assert_irql(cond) do { } while (0)
-#endif
-
-/* When preempt is enabled, we should preempt_disable to raise IRQL to
- * DISPATCH_LEVEL, to be consistent with the semantics. However, using
- * a mutex instead, so that only ndiswrapper threads run one at a time
- * on a processor when at DISPATCH_LEVEL seems to be enough. So that
- * is what we will use until we learn otherwise. If
- * preempt_(en|dis)able is required for some reason, comment out
- * following #define. */
-
-#define WRAP_PREEMPT 1
-
-#if !defined(CONFIG_PREEMPT) || defined(CONFIG_PREEMPT_RT)
-#ifndef WRAP_PREEMPT
-#define WRAP_PREEMPT 1
-#endif
-#endif
-
-//#undef WRAP_PREEMPT
-
-#ifdef WRAP_PREEMPT
-
-typedef struct {
- int count;
- struct mutex lock;
-#ifdef CONFIG_SMP
- typeof(current->cpus_allowed) cpus_allowed;
-#endif
- struct task_struct *task;
-} irql_info_t;
-
-DECLARE_PER_CPU(irql_info_t, irql_info);
-
-static inline KIRQL raise_irql(KIRQL newirql)
-{
- irql_info_t *info;
-
- assert(newirql == DISPATCH_LEVEL);
- info = &get_cpu_var(irql_info);
- if (info->task == current) {
- assert(info->count > 0);
- assert(mutex_is_locked(&info->lock));
-#if defined(CONFIG_SMP) && defined(DEBUG)
- do {
- cpumask_t cpumask;
- cpumask = cpumask_of_cpu(smp_processor_id());
- cpus_xor(cpumask, cpumask, current->cpus_allowed);
- assert(cpus_empty(cpumask));
- } while (0);
-#endif
- info->count++;
- put_cpu_var(irql_info);
- return DISPATCH_LEVEL;
- }
- /* TODO: is this enough to pin down to current cpu? */
-#ifdef CONFIG_SMP
- assert(task_cpu(current) == smp_processor_id());
- info->cpus_allowed = current->cpus_allowed;
- current->cpus_allowed = cpumask_of_cpu(smp_processor_id());
-#endif
- put_cpu_var(irql_info);
- mutex_lock(&info->lock);
- assert(info->count == 0);
- assert(info->task == NULL);
- info->count = 1;
- info->task = current;
- return PASSIVE_LEVEL;
-}
-
-static inline void lower_irql(KIRQL oldirql)
-{
- irql_info_t *info;
-
- assert(oldirql <= DISPATCH_LEVEL);
- info = &get_cpu_var(irql_info);
- assert(info->task == current);
- assert(mutex_is_locked(&info->lock));
- assert(info->count > 0);
- if (--info->count == 0) {
- info->task = NULL;
-#ifdef CONFIG_SMP
- current->cpus_allowed = info->cpus_allowed;
-#endif
- mutex_unlock(&info->lock);
- }
- put_cpu_var(irql_info);
-}
-
-static inline KIRQL current_irql(void)
-{
- int count;
- if (in_irq() || irqs_disabled())
- EXIT4(return DIRQL);
- if (in_atomic() || in_interrupt())
- EXIT4(return SOFT_IRQL);
- count = get_cpu_var(irql_info).count;
- put_cpu_var(irql_info);
- if (count)
- EXIT6(return DISPATCH_LEVEL);
- else
- EXIT6(return PASSIVE_LEVEL);
-}
-
-#else
-
-static inline KIRQL current_irql(void)
-{
- if (in_irq() || irqs_disabled())
- EXIT4(return DIRQL);
- if (in_interrupt())
- EXIT4(return SOFT_IRQL);
- if (in_atomic())
- EXIT6(return DISPATCH_LEVEL);
- else
- EXIT6(return PASSIVE_LEVEL);
-}
-
-static inline KIRQL raise_irql(KIRQL newirql)
-{
- KIRQL ret = in_atomic() ? DISPATCH_LEVEL : PASSIVE_LEVEL;
- assert(newirql == DISPATCH_LEVEL);
- assert(current_irql() <= DISPATCH_LEVEL);
- preempt_disable();
- return ret;
-}
-
-static inline void lower_irql(KIRQL oldirql)
-{
- assert(current_irql() == DISPATCH_LEVEL);
- preempt_enable();
-}
-
-#endif
-
-#define irql_gfp() (in_atomic() ? GFP_ATOMIC : GFP_KERNEL)
-
-/* Windows spinlocks are of type ULONG_PTR which is not big enough to
- * store Linux spinlocks; so we implement Windows spinlocks using
- * ULONG_PTR space with our own functions/macros */
-
-/* Windows seems to use 0 for unlocked state of spinlock - if Linux
- * convention of 1 for unlocked state is used, at least prism54 driver
- * crashes */
-
-#define NT_SPIN_LOCK_UNLOCKED 0
-#define NT_SPIN_LOCK_LOCKED 1
-
-static inline void nt_spin_lock_init(NT_SPIN_LOCK *lock)
-{
- *lock = NT_SPIN_LOCK_UNLOCKED;
-}
-
-#ifdef CONFIG_SMP
-
-static inline void nt_spin_lock(NT_SPIN_LOCK *lock)
-{
- __asm__ __volatile__(
- "1:\t"
- " xchgl %1, %0\n\t"
- " testl %1, %1\n\t"
- " jz 3f\n"
- "2:\t"
- " rep; nop\n\t"
- " cmpl %2, %0\n\t"
- " je 1b\n\t"
- " jmp 2b\n"
- "3:\n\t"
- : "+m" (*lock)
- : "r" (NT_SPIN_LOCK_LOCKED), "i" (NT_SPIN_LOCK_UNLOCKED));
-}
-
-static inline void nt_spin_unlock(NT_SPIN_LOCK *lock)
-{
- *lock = NT_SPIN_LOCK_UNLOCKED;
-}
-
-#else // CONFIG_SMP
-
-#define nt_spin_lock(lock) do { } while (0)
-
-#define nt_spin_unlock(lock) do { } while (0)
-
-#endif // CONFIG_SMP
-
-/* When kernel would've disabled preempt (e.g., in interrupt
- * handlers), we need to fake preempt so driver thinks it is running
- * at right IRQL */
-
-/* raise IRQL to given (higher) IRQL if necessary before locking */
-static inline KIRQL nt_spin_lock_irql(NT_SPIN_LOCK *lock, KIRQL newirql)
-{
- KIRQL oldirql = raise_irql(newirql);
- nt_spin_lock(lock);
- return oldirql;
-}
-
-/* lower IRQL to given (lower) IRQL if necessary after unlocking */
-static inline void nt_spin_unlock_irql(NT_SPIN_LOCK *lock, KIRQL oldirql)
-{
- nt_spin_unlock(lock);
- lower_irql(oldirql);
-}
-
-#define nt_spin_lock_irqsave(lock, flags) \
-do { \
- local_irq_save(flags); \
- preempt_disable(); \
- nt_spin_lock(lock); \
-} while (0)
-
-#define nt_spin_unlock_irqrestore(lock, flags) \
-do { \
- nt_spin_unlock(lock); \
- preempt_enable_no_resched(); \
- local_irq_restore(flags); \
- preempt_check_resched(); \
-} while (0)
-
-static inline ULONG SPAN_PAGES(void *ptr, SIZE_T length)
-{
- return PAGE_ALIGN(((unsigned long)ptr & (PAGE_SIZE - 1)) + length)
- >> PAGE_SHIFT;
-}
-
-#ifdef CONFIG_X86_64
-
-/* TODO: can these be implemented without using spinlock? */
-
-static inline struct nt_slist *PushEntrySList(nt_slist_header *head,
- struct nt_slist *entry,
- NT_SPIN_LOCK *lock)
-{
- KIRQL irql = nt_spin_lock_irql(lock, DISPATCH_LEVEL);
- entry->next = head->next;
- head->next = entry;
- head->depth++;
- nt_spin_unlock_irql(lock, irql);
- TRACE4("%p, %p, %p", head, entry, entry->next);
- return entry->next;
-}
-
-static inline struct nt_slist *PopEntrySList(nt_slist_header *head,
- NT_SPIN_LOCK *lock)
-{
- struct nt_slist *entry;
- KIRQL irql = nt_spin_lock_irql(lock, DISPATCH_LEVEL);
- entry = head->next;
- if (entry) {
- head->next = entry->next;
- head->depth--;
- }
- nt_spin_unlock_irql(lock, irql);
- TRACE4("%p, %p", head, entry);
- return entry;
-}
-
-#else
-
-#define u64_low_32(x) ((u32)x)
-#define u64_high_32(x) ((u32)(x >> 32))
-
-static inline u64 nt_cmpxchg8b(volatile u64 *ptr, u64 old, u64 new)
-{
- u64 prev;
-
- __asm__ __volatile__(
- "\n"
- LOCK_PREFIX "cmpxchg8b %0\n"
- : "+m" (*ptr), "=A" (prev)
- : "A" (old), "b" (u64_low_32(new)), "c" (u64_high_32(new)));
- return prev;
-}
-
-/* slist routines below update slist atomically - no need for
- * spinlocks */
-
-static inline struct nt_slist *PushEntrySList(nt_slist_header *head,
- struct nt_slist *entry,
- NT_SPIN_LOCK *lock)
-{
- nt_slist_header old, new;
- do {
- old.align = head->align;
- entry->next = old.next;
- new.next = entry;
- new.depth = old.depth + 1;
- } while (nt_cmpxchg8b(&head->align, old.align, new.align) != old.align);
- TRACE4("%p, %p, %p", head, entry, old.next);
- return old.next;
-}
-
-static inline struct nt_slist *PopEntrySList(nt_slist_header *head,
- NT_SPIN_LOCK *lock)
-{
- struct nt_slist *entry;
- nt_slist_header old, new;
- do {
- old.align = head->align;
- entry = old.next;
- if (!entry)
- break;
- new.next = entry->next;
- new.depth = old.depth - 1;
- } while (nt_cmpxchg8b(&head->align, old.align, new.align) != old.align);
- TRACE4("%p, %p", head, entry);
- return entry;
-}
-
-#endif
-
-#define sleep_hz(n) \
-do { \
- set_current_state(TASK_INTERRUPTIBLE); \
- schedule_timeout(n); \
-} while (0)
-
-int ntoskernel_init(void);
-void ntoskernel_exit(void);
-int ntoskernel_init_device(struct wrap_device *wd);
-void ntoskernel_exit_device(struct wrap_device *wd);
-void *allocate_object(ULONG size, enum common_object_type type,
- struct unicode_string *name);
-void free_object(void *object);
-
-int usb_init(void);
-void usb_exit(void);
-int usb_init_device(struct wrap_device *wd);
-void usb_exit_device(struct wrap_device *wd);
-void usb_cancel_pending_urbs(void);
-
-int crt_init(void);
-void crt_exit(void);
-int rtl_init(void);
-void rtl_exit(void);
-int wrap_procfs_init(void);
-void wrap_procfs_remove(void);
-
-int link_pe_images(struct pe_image *pe_image, unsigned short n);
-
-int stricmp(const char *s1, const char *s2);
-void dump_bytes(const char *name, const u8 *from, int len);
-struct mdl *allocate_init_mdl(void *virt, ULONG length);
-void free_mdl(struct mdl *mdl);
-struct driver_object *find_bus_driver(const char *name);
-void free_custom_extensions(struct driver_extension *drv_obj_ext);
-struct nt_thread *get_current_nt_thread(void);
-u64 ticks_1601(void);
-int schedule_ntos_work_item(NTOS_WORK_FUNC func, void *arg1, void *arg2);
-void wrap_init_timer(struct nt_timer *nt_timer, enum timer_type type,
- struct ndis_mp_block *nmb);
-BOOLEAN wrap_set_timer(struct nt_timer *nt_timer, unsigned long expires_hz,
- unsigned long repeat_hz, struct kdpc *kdpc);
-
-LONG InterlockedDecrement(LONG volatile *val) wfastcall;
-LONG InterlockedIncrement(LONG volatile *val) wfastcall;
-struct nt_list *ExInterlockedInsertHeadList
- (struct nt_list *head, struct nt_list *entry,
- NT_SPIN_LOCK *lock) wfastcall;
-struct nt_list *ExInterlockedInsertTailList
- (struct nt_list *head, struct nt_list *entry,
- NT_SPIN_LOCK *lock) wfastcall;
-struct nt_list *ExInterlockedRemoveHeadList
- (struct nt_list *head, NT_SPIN_LOCK *lock) wfastcall;
-NTSTATUS IofCallDriver(struct device_object *dev_obj, struct irp *irp) wfastcall;
-KIRQL KfRaiseIrql(KIRQL newirql) wfastcall;
-void KfLowerIrql(KIRQL oldirql) wfastcall;
-KIRQL KfAcquireSpinLock(NT_SPIN_LOCK *lock) wfastcall;
-void KfReleaseSpinLock(NT_SPIN_LOCK *lock, KIRQL oldirql) wfastcall;
-void IofCompleteRequest(struct irp *irp, CHAR prio_boost) wfastcall;
-void KefReleaseSpinLockFromDpcLevel(NT_SPIN_LOCK *lock) wfastcall;
-
-LONG ObfReferenceObject(void *object) wfastcall;
-void ObfDereferenceObject(void *object) wfastcall;
-
-#define ObReferenceObject(object) ObfReferenceObject(object)
-#define ObDereferenceObject(object) ObfDereferenceObject(object)
-
-void WRITE_PORT_UCHAR(ULONG_PTR port, UCHAR value) wstdcall;
-UCHAR READ_PORT_UCHAR(ULONG_PTR port) wstdcall;
-
-#undef ExAllocatePoolWithTag
-void *ExAllocatePoolWithTag(enum pool_type pool_type, SIZE_T size,
- ULONG tag) wstdcall;
-#if defined(ALLOC_DEBUG) && ALLOC_DEBUG > 1
-#define ExAllocatePoolWithTag(pool_type, size, tag) \
- wrap_ExAllocatePoolWithTag(pool_type, size, tag, __FILE__, __LINE__)
-#endif
-
-void ExFreePool(void *p) wstdcall;
-ULONG MmSizeOfMdl(void *base, ULONG length) wstdcall;
-void __iomem *MmMapIoSpace(PHYSICAL_ADDRESS phys_addr, SIZE_T size,
- enum memory_caching_type cache) wstdcall;
-void MmUnmapIoSpace(void __iomem *addr, SIZE_T size) wstdcall;
-void MmProbeAndLockPages(struct mdl *mdl, KPROCESSOR_MODE access_mode,
- enum lock_operation operation) wstdcall;
-void MmUnlockPages(struct mdl *mdl) wstdcall;
-void KeInitializeEvent(struct nt_event *nt_event,
- enum event_type type, BOOLEAN state) wstdcall;
-LONG KeSetEvent(struct nt_event *nt_event, KPRIORITY incr,
- BOOLEAN wait) wstdcall;
-LONG KeResetEvent(struct nt_event *nt_event) wstdcall;
-void KeClearEvent(struct nt_event *nt_event) wstdcall;
-void KeInitializeDpc(struct kdpc *kdpc, void *func, void *ctx) wstdcall;
-BOOLEAN queue_kdpc(struct kdpc *kdpc);
-BOOLEAN dequeue_kdpc(struct kdpc *kdpc);
-
-void KeFlushQueuedDpcs(void) wstdcall;
-NTSTATUS IoConnectInterrupt(struct kinterrupt **kinterrupt,
- PKSERVICE_ROUTINE service_routine,
- void *service_context, NT_SPIN_LOCK *lock,
- ULONG vector, KIRQL irql, KIRQL synch_irql,
- enum kinterrupt_mode interrupt_mode,
- BOOLEAN shareable, KAFFINITY processor_enable_mask,
- BOOLEAN floating_save) wstdcall;
-void IoDisconnectInterrupt(struct kinterrupt *interrupt) wstdcall;
-BOOLEAN KeSynchronizeExecution(struct kinterrupt *interrupt,
- PKSYNCHRONIZE_ROUTINE synch_routine,
- void *ctx) wstdcall;
-
-NTSTATUS KeWaitForSingleObject(void *object, KWAIT_REASON reason,
- KPROCESSOR_MODE waitmode, BOOLEAN alertable,
- LARGE_INTEGER *timeout) wstdcall;
-struct mdl *IoAllocateMdl(void *virt, ULONG length, BOOLEAN second_buf,
- BOOLEAN charge_quota, struct irp *irp) wstdcall;
-void MmBuildMdlForNonPagedPool(struct mdl *mdl) wstdcall;
-void IoFreeMdl(struct mdl *mdl) wstdcall;
-NTSTATUS IoCreateDevice(struct driver_object *driver, ULONG dev_ext_length,
- struct unicode_string *dev_name, DEVICE_TYPE dev_type,
- ULONG dev_chars, BOOLEAN exclusive,
- struct device_object **dev_obj) wstdcall;
-NTSTATUS IoCreateSymbolicLink(struct unicode_string *link,
- struct unicode_string *dev_name) wstdcall;
-void IoDeleteDevice(struct device_object *dev) wstdcall;
-void IoDetachDevice(struct device_object *topdev) wstdcall;
-struct device_object *IoGetAttachedDevice(struct device_object *dev) wstdcall;
-struct device_object *IoGetAttachedDeviceReference
- (struct device_object *dev) wstdcall;
-NTSTATUS IoAllocateDriverObjectExtension
- (struct driver_object *drv_obj, void *client_id, ULONG extlen,
- void **ext) wstdcall;
-void *IoGetDriverObjectExtension(struct driver_object *drv,
- void *client_id) wstdcall;
-struct device_object *IoAttachDeviceToDeviceStack
- (struct device_object *src, struct device_object *dst) wstdcall;
-void KeInitializeEvent(struct nt_event *nt_event, enum event_type type,
- BOOLEAN state) wstdcall;
-struct irp *IoAllocateIrp(char stack_count, BOOLEAN charge_quota) wstdcall;
-void IoFreeIrp(struct irp *irp) wstdcall;
-BOOLEAN IoCancelIrp(struct irp *irp) wstdcall;
-struct irp *IoBuildSynchronousFsdRequest
- (ULONG major_func, struct device_object *dev_obj, void *buf,
- ULONG length, LARGE_INTEGER *offset, struct nt_event *event,
- struct io_status_block *status) wstdcall;
-struct irp *IoBuildAsynchronousFsdRequest
- (ULONG major_func, struct device_object *dev_obj, void *buf,
- ULONG length, LARGE_INTEGER *offset,
- struct io_status_block *status) wstdcall;
-NTSTATUS PoCallDriver(struct device_object *dev_obj, struct irp *irp) wstdcall;
-
-NTSTATUS IoPassIrpDown(struct device_object *dev_obj, struct irp *irp) wstdcall;
-WIN_FUNC_DECL(IoPassIrpDown,2);
-NTSTATUS IoSyncForwardIrp(struct device_object *dev_obj,
- struct irp *irp) wstdcall;
-NTSTATUS IoAsyncForwardIrp(struct device_object *dev_obj,
- struct irp *irp) wstdcall;
-NTSTATUS IoInvalidDeviceRequest(struct device_object *dev_obj,
- struct irp *irp) wstdcall;
-
-KIRQL KeGetCurrentIrql(void) wstdcall;
-void KeInitializeSpinLock(NT_SPIN_LOCK *lock) wstdcall;
-void KeAcquireSpinLock(NT_SPIN_LOCK *lock, KIRQL *irql) wstdcall;
-void KeReleaseSpinLock(NT_SPIN_LOCK *lock, KIRQL oldirql) wstdcall;
-KIRQL KeAcquireSpinLockRaiseToDpc(NT_SPIN_LOCK *lock) wstdcall;
-
-void IoAcquireCancelSpinLock(KIRQL *irql) wstdcall;
-void IoReleaseCancelSpinLock(KIRQL irql) wstdcall;
-
-void RtlCopyMemory(void *dst, const void *src, SIZE_T length) wstdcall;
-NTSTATUS RtlUnicodeStringToAnsiString
- (struct ansi_string *dst, const struct unicode_string *src,
- BOOLEAN dup) wstdcall;
-NTSTATUS RtlAnsiStringToUnicodeString
- (struct unicode_string *dst, const struct ansi_string *src,
- BOOLEAN dup) wstdcall;
-void RtlInitAnsiString(struct ansi_string *dst, const char *src) wstdcall;
-void RtlInitString(struct ansi_string *dst, const char *src) wstdcall;
-void RtlInitUnicodeString(struct unicode_string *dest,
- const wchar_t *src) wstdcall;
-void RtlFreeUnicodeString(struct unicode_string *string) wstdcall;
-void RtlFreeAnsiString(struct ansi_string *string) wstdcall;
-LONG RtlCompareUnicodeString(const struct unicode_string *s1,
- const struct unicode_string *s2,
- BOOLEAN case_insensitive) wstdcall;
-void RtlCopyUnicodeString(struct unicode_string *dst,
- struct unicode_string *src) wstdcall;
-NTSTATUS RtlUpcaseUnicodeString(struct unicode_string *dst,
- struct unicode_string *src,
- BOOLEAN alloc) wstdcall;
-void KeInitializeTimer(struct nt_timer *nt_timer) wstdcall;
-void KeInitializeTimerEx(struct nt_timer *nt_timer,
- enum timer_type type) wstdcall;
-BOOLEAN KeSetTimerEx(struct nt_timer *nt_timer, LARGE_INTEGER duetime_ticks,
- LONG period_ms, struct kdpc *kdpc) wstdcall;
-BOOLEAN KeSetTimer(struct nt_timer *nt_timer, LARGE_INTEGER duetime_ticks,
- struct kdpc *kdpc) wstdcall;
-BOOLEAN KeCancelTimer(struct nt_timer *nt_timer) wstdcall;
-void KeInitializeDpc(struct kdpc *kdpc, void *func, void *ctx) wstdcall;
-struct nt_thread *KeGetCurrentThread(void) wstdcall;
-NTSTATUS ObReferenceObjectByHandle(void *handle, ACCESS_MASK desired_access,
- void *obj_type, KPROCESSOR_MODE access_mode,
- void **object, void *handle_info) wstdcall;
-
-void adjust_user_shared_data_addr(char *driver, unsigned long length);
-
-extern spinlock_t ntoskernel_lock;
-extern spinlock_t irp_cancel_lock;
-extern struct nt_list object_list;
-#ifdef CONFIG_X86_64
-extern struct kuser_shared_data kuser_shared_data;
-#endif
-
-#define IoCompleteRequest(irp, prio) IofCompleteRequest(irp, prio)
-#define IoCallDriver(dev, irp) IofCallDriver(dev, irp)
-
-#if defined(IO_DEBUG)
-#define DUMP_IRP(_irp) \
-do { \
- struct io_stack_location *_irp_sl; \
- _irp_sl = IoGetCurrentIrpStackLocation(_irp); \
- IOTRACE("irp: %p, stack size: %d, cl: %d, sl: %p, dev_obj: %p, " \
- "mj_fn: %d, minor_fn: %d, nt_urb: %p, event: %p", \
- _irp, _irp->stack_count, (_irp)->current_location, \
- _irp_sl, _irp_sl->dev_obj, _irp_sl->major_fn, \
- _irp_sl->minor_fn, IRP_URB(_irp), \
- (_irp)->user_event); \
-} while (0)
-#else
-#define DUMP_IRP(_irp) do { } while (0)
-#endif
-
-#endif // _NTOSKERNEL_H_
+++ /dev/null
-/*
- * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include "ntoskernel.h"
-#include "ndis.h"
-#include "wrapndis.h"
-#include "usb.h"
-#include "loader.h"
-#include "ntoskernel_io_exports.h"
-
-wstdcall void WIN_FUNC(IoAcquireCancelSpinLock,1)
- (KIRQL *irql) __acquires(irql)
-{
- spin_lock_bh(&irp_cancel_lock);
- *irql = 0;
-}
-
-wstdcall void WIN_FUNC(IoReleaseCancelSpinLock,1)
- (KIRQL irql) __releases(irql)
-{
- spin_unlock_bh(&irp_cancel_lock);
-}
-
-wstdcall int WIN_FUNC(IoIsWdmVersionAvailable,2)
- (UCHAR major, UCHAR minor)
-{
- IOENTER("%d, %x", major, minor);
- if (major == 1 &&
- (minor == 0x30 || // Windows 2003
- minor == 0x20 || // Windows XP
- minor == 0x10)) // Windows 2000
- IOEXIT(return TRUE);
- IOEXIT(return FALSE);
-}
-
-wstdcall BOOLEAN WIN_FUNC(IoIs32bitProcess,1)
- (struct irp *irp)
-{
-#ifdef CONFIG_X86_64
- return FALSE;
-#else
- return TRUE;
-#endif
-}
-
-wstdcall void WIN_FUNC(IoInitializeIrp,3)
- (struct irp *irp, USHORT size, CCHAR stack_count)
-{
- IOENTER("irp: %p, %d, %d", irp, size, stack_count);
-
- memset(irp, 0, size);
- irp->size = size;
- irp->stack_count = stack_count;
- irp->current_location = stack_count;
- IoGetCurrentIrpStackLocation(irp) = IRP_SL(irp, stack_count);
- IOEXIT(return);
-}
-
-wstdcall void WIN_FUNC(IoReuseIrp,2)
- (struct irp *irp, NTSTATUS status)
-{
- IOENTER("%p, %d", irp, status);
- if (irp) {
- UCHAR alloc_flags;
-
- alloc_flags = irp->alloc_flags;
- IoInitializeIrp(irp, irp->size, irp->stack_count);
- irp->alloc_flags = alloc_flags;
- irp->io_status.status = status;
- }
- IOEXIT(return);
-}
-
-wstdcall struct irp *WIN_FUNC(IoAllocateIrp,2)
- (char stack_count, BOOLEAN charge_quota)
-{
- struct irp *irp;
- int irp_size;
-
- IOENTER("count: %d", stack_count);
- stack_count++;
- irp_size = IoSizeOfIrp(stack_count);
- irp = kmalloc(irp_size, irql_gfp());
- if (irp)
- IoInitializeIrp(irp, irp_size, stack_count);
- IOTRACE("irp %p", irp);
- IOEXIT(return irp);
-}
-
-wstdcall BOOLEAN WIN_FUNC(IoCancelIrp,1)
- (struct irp *irp)
-{
- typeof(irp->cancel_routine) cancel_routine;
-
- /* NB: this function may be called at DISPATCH_LEVEL */
- IOTRACE("irp: %p", irp);
- if (!irp)
- return FALSE;
- DUMP_IRP(irp);
- IoAcquireCancelSpinLock(&irp->cancel_irql);
- cancel_routine = xchg(&irp->cancel_routine, NULL);
- IOTRACE("%p", cancel_routine);
- irp->cancel = TRUE;
- if (cancel_routine) {
- struct io_stack_location *irp_sl;
- irp_sl = IoGetCurrentIrpStackLocation(irp);
- IOTRACE("%p, %p", irp_sl, irp_sl->dev_obj);
- /* cancel_routine will release the spin lock */
- __release(irp->cancel_irql);
- LIN2WIN2(cancel_routine, irp_sl->dev_obj, irp);
- /* in usb's cancel, irp->cancel is set to indicate
- * status of cancel */
- IOEXIT(return xchg(&irp->cancel, TRUE));
- } else {
- IOTRACE("irp %p already canceled", irp);
- IoReleaseCancelSpinLock(irp->cancel_irql);
- IOEXIT(return FALSE);
- }
-}
-
-wstdcall void IoQueueThreadIrp(struct irp *irp)
-{
- struct nt_thread *thread;
- KIRQL irql;
-
- thread = get_current_nt_thread();
- if (thread) {
- IOTRACE("thread: %p, task: %p", thread, thread->task);
- irp->flags |= IRP_SYNCHRONOUS_API;
- irql = nt_spin_lock_irql(&thread->lock, DISPATCH_LEVEL);
- InsertTailList(&thread->irps, &irp->thread_list);
- IoIrpThread(irp) = thread;
- nt_spin_unlock_irql(&thread->lock, irql);
- } else
- IoIrpThread(irp) = NULL;
-}
-
-wstdcall void IoDequeueThreadIrp(struct irp *irp)
-{
- struct nt_thread *thread;
- KIRQL irql;
-
- thread = IoIrpThread(irp);
- if (thread) {
- irql = nt_spin_lock_irql(&thread->lock, DISPATCH_LEVEL);
- RemoveEntryList(&irp->thread_list);
- nt_spin_unlock_irql(&thread->lock, irql);
- }
-}
-
-wstdcall void WIN_FUNC(IoFreeIrp,1)
- (struct irp *irp)
-{
- IOENTER("irp = %p", irp);
- if (irp->flags & IRP_SYNCHRONOUS_API)
- IoDequeueThreadIrp(irp);
- kfree(irp);
-
- IOEXIT(return);
-}
-
-wstdcall struct irp *WIN_FUNC(IoBuildAsynchronousFsdRequest,6)
- (ULONG major_fn, struct device_object *dev_obj, void *buffer,
- ULONG length, LARGE_INTEGER *offset,
- struct io_status_block *user_status)
-{
- struct irp *irp;
- struct io_stack_location *irp_sl;
-
- IOENTER("%p", dev_obj);
- if (!dev_obj)
- IOEXIT(return NULL);
- irp = IoAllocateIrp(dev_obj->stack_count, FALSE);
- if (irp == NULL) {
- WARNING("couldn't allocate irp");
- IOEXIT(return NULL);
- }
-
- irp_sl = IoGetNextIrpStackLocation(irp);
- irp_sl->major_fn = major_fn;
- IOTRACE("major_fn: %d", major_fn);
- irp_sl->minor_fn = 0;
- irp_sl->flags = 0;
- irp_sl->control = 0;
- irp_sl->dev_obj = dev_obj;
- irp_sl->file_obj = NULL;
- irp_sl->completion_routine = NULL;
-
- if (dev_obj->flags & DO_DIRECT_IO) {
- irp->mdl = IoAllocateMdl(buffer, length, FALSE, FALSE, irp);
- if (irp->mdl == NULL) {
- IoFreeIrp(irp);
- return NULL;
- }
- MmProbeAndLockPages(irp->mdl, KernelMode,
- major_fn == IRP_MJ_WRITE ?
- IoReadAccess : IoWriteAccess);
- IOTRACE("mdl: %p", irp->mdl);
- } else if (dev_obj->flags & DO_BUFFERED_IO) {
- irp->associated_irp.system_buffer = buffer;
- irp->flags = IRP_BUFFERED_IO;
- irp->mdl = NULL;
- IOTRACE("buffer: %p", buffer);
- }
- if (major_fn == IRP_MJ_READ) {
- irp_sl->params.read.length = length;
- irp_sl->params.read.byte_offset = *offset;
- } else if (major_fn == IRP_MJ_WRITE) {
- irp_sl->params.write.length = length;
- irp_sl->params.write.byte_offset = *offset;
- }
- irp->user_status = user_status;
- IOTRACE("irp: %p", irp);
- return irp;
-}
-
-wstdcall struct irp *WIN_FUNC(IoBuildSynchronousFsdRequest,7)
- (ULONG major_fn, struct device_object *dev_obj, void *buf,
- ULONG length, LARGE_INTEGER *offset, struct nt_event *event,
- struct io_status_block *user_status)
-{
- struct irp *irp;
-
- irp = IoBuildAsynchronousFsdRequest(major_fn, dev_obj, buf, length,
- offset, user_status);
- if (irp == NULL)
- return NULL;
- irp->user_event = event;
- IoQueueThreadIrp(irp);
- return irp;
-}
-
-wstdcall struct irp *WIN_FUNC(IoBuildDeviceIoControlRequest,9)
- (ULONG ioctl, struct device_object *dev_obj,
- void *input_buf, ULONG input_buf_len, void *output_buf,
- ULONG output_buf_len, BOOLEAN internal_ioctl,
- struct nt_event *event, struct io_status_block *io_status)
-{
- struct irp *irp;
- struct io_stack_location *irp_sl;
- ULONG buf_len;
-
- IOENTER("%p, 0x%08x, %d", dev_obj, ioctl, internal_ioctl);
- if (!dev_obj)
- IOEXIT(return NULL);
- irp = IoAllocateIrp(dev_obj->stack_count, FALSE);
- if (irp == NULL) {
- WARNING("couldn't allocate irp");
- return NULL;
- }
- irp_sl = IoGetNextIrpStackLocation(irp);
- irp_sl->params.dev_ioctl.code = ioctl;
- irp_sl->params.dev_ioctl.input_buf_len = input_buf_len;
- irp_sl->params.dev_ioctl.output_buf_len = output_buf_len;
- irp_sl->major_fn = (internal_ioctl) ?
- IRP_MJ_INTERNAL_DEVICE_CONTROL : IRP_MJ_DEVICE_CONTROL;
- IOTRACE("%d", IO_METHOD_FROM_CTL_CODE(ioctl));
-
- switch (IO_METHOD_FROM_CTL_CODE(ioctl)) {
- case METHOD_BUFFERED:
- buf_len = max(input_buf_len, output_buf_len);
- if (buf_len) {
- irp->associated_irp.system_buffer =
- ExAllocatePoolWithTag(NonPagedPool, buf_len, 0);
- if (!irp->associated_irp.system_buffer) {
- IoFreeIrp(irp);
- IOEXIT(return NULL);
- }
- irp->associated_irp.system_buffer = input_buf;
- if (input_buf)
- memcpy(irp->associated_irp.system_buffer,
- input_buf, input_buf_len);
- irp->flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER;
- if (output_buf)
- irp->flags = IRP_INPUT_OPERATION;
- irp->user_buf = output_buf;
- } else
- irp->user_buf = NULL;
- break;
- case METHOD_IN_DIRECT:
- case METHOD_OUT_DIRECT:
- if (input_buf) {
- irp->associated_irp.system_buffer =
- ExAllocatePoolWithTag(NonPagedPool,
- input_buf_len, 0);
- if (!irp->associated_irp.system_buffer) {
- IoFreeIrp(irp);
- IOEXIT(return NULL);
- }
- memcpy(irp->associated_irp.system_buffer,
- input_buf, input_buf_len);
- irp->flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER;
- }
- /* TODO: we are supposed to setup MDL, but USB layer
- * doesn't use MDLs. Moreover, USB layer mirrors
- * non-DMAable buffers, so no need to allocate
- * DMAable buffer here */
- if (output_buf) {
- irp->associated_irp.system_buffer =
- ExAllocatePoolWithTag(NonPagedPool,
- output_buf_len, 0);
- if (!irp->associated_irp.system_buffer) {
- IoFreeIrp(irp);
- IOEXIT(return NULL);
- }
- irp->flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER;
- }
- break;
- case METHOD_NEITHER:
- irp->user_buf = output_buf;
- irp_sl->params.dev_ioctl.type3_input_buf = input_buf;
- break;
- }
-
- irp->user_status = io_status;
- irp->user_event = event;
- IoQueueThreadIrp(irp);
-
- IOTRACE("irp: %p", irp);
- IOEXIT(return irp);
-}
-
-wfastcall NTSTATUS WIN_FUNC(IofCallDriver,2)
- (struct device_object *dev_obj, struct irp *irp)
-{
- struct io_stack_location *irp_sl;
- NTSTATUS status;
- driver_dispatch_t *major_func;
- struct driver_object *drv_obj;
-
- if (irp->current_location <= 0) {
- ERROR("invalid irp: %p, %d", irp, irp->current_location);
- return STATUS_INVALID_PARAMETER;
- }
- IOTRACE("%p, %p, %p, %d, %d, %p", dev_obj, irp, dev_obj->drv_obj,
- irp->current_location, irp->stack_count,
- IoGetCurrentIrpStackLocation(irp));
- IoSetNextIrpStackLocation(irp);
- DUMP_IRP(irp);
- irp_sl = IoGetCurrentIrpStackLocation(irp);
- drv_obj = dev_obj->drv_obj;
- irp_sl->dev_obj = dev_obj;
- major_func = drv_obj->major_func[irp_sl->major_fn];
- IOTRACE("major_func: %p, dev_obj: %p", major_func, dev_obj);
- if (major_func)
- status = LIN2WIN2(major_func, dev_obj, irp);
- else {
- ERROR("major_function %d is not implemented",
- irp_sl->major_fn);
- status = STATUS_NOT_SUPPORTED;
- }
- IOEXIT(return status);
-}
-
-wfastcall void WIN_FUNC(IofCompleteRequest,2)
- (struct irp *irp, CHAR prio_boost)
-{
- struct io_stack_location *irp_sl;
-
-#ifdef IO_DEBUG
- DUMP_IRP(irp);
- if (irp->io_status.status == STATUS_PENDING) {
- ERROR("invalid irp: %p, STATUS_PENDING", irp);
- return;
- }
- if (irp->current_location < 0 ||
- irp->current_location >= irp->stack_count) {
- ERROR("invalid irp: %p, %d", irp, irp->current_location);
- return;
- }
-#endif
- for (irp_sl = IoGetCurrentIrpStackLocation(irp);
- irp->current_location < irp->stack_count; irp_sl++) {
- struct device_object *dev_obj;
- NTSTATUS status;
-
- DUMP_IRP(irp);
- if (irp_sl->control & SL_PENDING_RETURNED)
- irp->pending_returned = TRUE;
-
- /* current_location and dev_obj must be same as when
- * driver called IoSetCompletionRoutine, which sets
- * completion routine at next (lower) location, which
- * is what we are going to call below; so we set
- * current_location and dev_obj for the previous
- * (higher) location */
- IoSkipCurrentIrpStackLocation(irp);
- if (irp->current_location < irp->stack_count)
- dev_obj = IoGetCurrentIrpStackLocation(irp)->dev_obj;
- else
- dev_obj = NULL;
-
- IOTRACE("%d, %d, %p", irp->current_location, irp->stack_count,
- dev_obj);
- if (irp_sl->completion_routine &&
- ((irp->io_status.status == STATUS_SUCCESS &&
- irp_sl->control & SL_INVOKE_ON_SUCCESS) ||
- (irp->io_status.status != STATUS_SUCCESS &&
- irp_sl->control & SL_INVOKE_ON_ERROR) ||
- (irp->cancel == TRUE &&
- irp_sl->control & SL_INVOKE_ON_CANCEL))) {
- IOTRACE("calling completion_routine at: %p, %p",
- irp_sl->completion_routine, irp_sl->context);
- status = LIN2WIN3(irp_sl->completion_routine,
- dev_obj, irp, irp_sl->context);
- IOTRACE("status: %08X", status);
- if (status == STATUS_MORE_PROCESSING_REQUIRED)
- IOEXIT(return);
- } else {
- /* propagate pending status to next irp_sl */
- if (irp->pending_returned &&
- irp->current_location < irp->stack_count)
- IoMarkIrpPending(irp);
- }
- }
-
- if (irp->user_status) {
- irp->user_status->status = irp->io_status.status;
- irp->user_status->info = irp->io_status.info;
- }
-
- if (irp->user_event) {
- IOTRACE("setting event %p", irp->user_event);
- KeSetEvent(irp->user_event, prio_boost, FALSE);
- }
-
- if (irp->associated_irp.system_buffer &&
- (irp->flags & IRP_DEALLOCATE_BUFFER))
- ExFreePool(irp->associated_irp.system_buffer);
- else {
- struct mdl *mdl;
- while ((mdl = irp->mdl)) {
- irp->mdl = mdl->next;
- MmUnlockPages(mdl);
- IoFreeMdl(mdl);
- }
- }
- IOTRACE("freeing irp %p", irp);
- IoFreeIrp(irp);
- IOEXIT(return);
-}
-
-wstdcall NTSTATUS IoPassIrpDown(struct device_object *dev_obj, struct irp *irp)
-{
- IoSkipCurrentIrpStackLocation(irp);
- IOEXIT(return IoCallDriver(dev_obj, irp));
-}
-
-wstdcall NTSTATUS IoIrpSyncComplete(struct device_object *dev_obj,
- struct irp *irp, void *context)
-{
- if (irp->pending_returned == TRUE)
- KeSetEvent(context, IO_NO_INCREMENT, FALSE);
- IOEXIT(return STATUS_MORE_PROCESSING_REQUIRED);
-}
-WIN_FUNC_DECL(IoIrpSyncComplete,3)
-
-wstdcall NTSTATUS IoSyncForwardIrp(struct device_object *dev_obj,
- struct irp *irp)
-{
- struct nt_event event;
- NTSTATUS status;
-
- IoCopyCurrentIrpStackLocationToNext(irp);
- KeInitializeEvent(&event, SynchronizationEvent, FALSE);
- /* completion function is called as Windows function */
- IoSetCompletionRoutine(irp, WIN_FUNC_PTR(IoIrpSyncComplete,3), &event,
- TRUE, TRUE, TRUE);
- status = IoCallDriver(dev_obj, irp);
- IOTRACE("%08X", status);
- if (status == STATUS_PENDING) {
- KeWaitForSingleObject(&event, Executive, KernelMode, FALSE,
- NULL);
- status = irp->io_status.status;
- }
- IOTRACE("%08X", status);
- IOEXIT(return status);
-}
-WIN_FUNC_DECL(IoSyncForwardIrp,2)
-
-wstdcall NTSTATUS IoAsyncForwardIrp(struct device_object *dev_obj,
- struct irp *irp)
-{
- NTSTATUS status;
-
- IoCopyCurrentIrpStackLocationToNext(irp);
- status = IoCallDriver(dev_obj, irp);
- IOEXIT(return status);
-}
-WIN_FUNC_DECL(IoAsyncForwardIrp,2)
-
-wstdcall NTSTATUS IoInvalidDeviceRequest(struct device_object *dev_obj,
- struct irp *irp)
-{
- struct io_stack_location *irp_sl;
- NTSTATUS status;
-
- irp_sl = IoGetCurrentIrpStackLocation(irp);
- WARNING("%d:%d not implemented", irp_sl->major_fn, irp_sl->minor_fn);
- irp->io_status.status = STATUS_SUCCESS;
- irp->io_status.info = 0;
- status = irp->io_status.status;
- IoCompleteRequest(irp, IO_NO_INCREMENT);
- IOEXIT(return status);
-}
-WIN_FUNC_DECL(IoInvalidDeviceRequest,2)
-
-static irqreturn_t io_irq_isr(int irq, void *data ISR_PT_REGS_PARAM_DECL)
-{
- struct kinterrupt *interrupt = data;
- BOOLEAN ret;
-
-#ifdef CONFIG_DEBUG_SHIRQ
- if (!interrupt->u.enabled)
- EXIT1(return IRQ_NONE);
-#endif
- TRACE6("%p", interrupt);
- nt_spin_lock(interrupt->actual_lock);
- ret = LIN2WIN2(interrupt->isr, interrupt, interrupt->isr_ctx);
- nt_spin_unlock(interrupt->actual_lock);
- if (ret == TRUE)
- EXIT6(return IRQ_HANDLED);
- else
- EXIT6(return IRQ_NONE);
-}
-
-wstdcall NTSTATUS WIN_FUNC(IoConnectInterrupt,11)
- (struct kinterrupt **kinterrupt, PKSERVICE_ROUTINE isr, void *isr_ctx,
- NT_SPIN_LOCK *lock, ULONG vector, KIRQL irql, KIRQL synch_irql,
- enum kinterrupt_mode mode, BOOLEAN shared, KAFFINITY cpu_mask,
- BOOLEAN save_fp)
-{
- struct kinterrupt *interrupt;
- IOENTER("");
- interrupt = kzalloc(sizeof(*interrupt), GFP_KERNEL);
- if (!interrupt)
- IOEXIT(return STATUS_INSUFFICIENT_RESOURCES);
- interrupt->vector = vector;
- interrupt->cpu_mask = cpu_mask;
- nt_spin_lock_init(&interrupt->lock);
- if (lock)
- interrupt->actual_lock = lock;
- else
- interrupt->actual_lock = &interrupt->lock;
- interrupt->shared = shared;
- interrupt->save_fp = save_fp;
- interrupt->isr = isr;
- interrupt->isr_ctx = isr_ctx;
- InitializeListHead(&interrupt->list);
- interrupt->irql = irql;
- interrupt->synch_irql = synch_irql;
- interrupt->mode = mode;
- if (request_irq(vector, io_irq_isr, shared ? IRQF_SHARED : 0,
- "ndiswrapper", interrupt)) {
- WARNING("request for irq %d failed", vector);
- kfree(interrupt);
- IOEXIT(return STATUS_INSUFFICIENT_RESOURCES);
- }
- *kinterrupt = interrupt;
-#ifdef CONFIG_DEBUG_SHIRQ
- interrupt->u.enabled = 1;
-#endif
- IOEXIT(return STATUS_SUCCESS);
-}
-
-wstdcall void WIN_FUNC(IoDisconnectInterrupt,1)
- (struct kinterrupt *interrupt)
-{
-#ifdef CONFIG_DEBUG_SHIRQ
- interrupt->u.enabled = 0;
-#endif
- free_irq(interrupt->vector, interrupt);
- kfree(interrupt);
-}
-
-wstdcall struct mdl *WIN_FUNC(IoAllocateMdl,5)
- (void *virt, ULONG length, BOOLEAN second_buf, BOOLEAN charge_quota,
- struct irp *irp)
-{
- struct mdl *mdl;
- mdl = allocate_init_mdl(virt, length);
- if (!mdl)
- return NULL;
- if (irp) {
- if (second_buf == TRUE) {
- struct mdl *last;
-
- last = irp->mdl;
- while (last->next)
- last = last->next;
- last->next = mdl;
- } else
- irp->mdl = mdl;
- }
- IOTRACE("%p", mdl);
- return mdl;
-}
-
-wstdcall void WIN_FUNC(IoFreeMdl,1)
- (struct mdl *mdl)
-{
- IOTRACE("%p", mdl);
- free_mdl(mdl);
-}
-
-wstdcall struct io_workitem *WIN_FUNC(IoAllocateWorkItem,1)
- (struct device_object *dev_obj)
-{
- struct io_workitem *io_workitem;
-
- IOENTER("%p", dev_obj);
- io_workitem = kmalloc(sizeof(*io_workitem), irql_gfp());
- if (!io_workitem)
- IOEXIT(return NULL);
- io_workitem->dev_obj = dev_obj;
- IOEXIT(return io_workitem);
-}
-
-wstdcall void WIN_FUNC(IoFreeWorkItem,1)
- (struct io_workitem *io_workitem)
-{
- kfree(io_workitem);
- IOEXIT(return);
-}
-
-wstdcall void WIN_FUNC(IoQueueWorkItem,4)
- (struct io_workitem *io_workitem, void *func,
- enum work_queue_type queue_type, void *context)
-{
- IOENTER("%p, %p", io_workitem, io_workitem->dev_obj);
- io_workitem->worker_routine = func;
- io_workitem->context = context;
- schedule_ntos_work_item(func, io_workitem->dev_obj, context);
- IOEXIT(return);
-}
-
-wstdcall void WIN_FUNC(ExQueueWorkItem,2)
- (struct io_workitem *io_workitem, enum work_queue_type queue_type)
-{
- IOENTER("%p", io_workitem);
- schedule_ntos_work_item(io_workitem->worker_routine,
- io_workitem->dev_obj, io_workitem->context);
-}
-
-wstdcall NTSTATUS WIN_FUNC(IoAllocateDriverObjectExtension,4)
- (struct driver_object *drv_obj, void *client_id, ULONG extlen,
- void **ext)
-{
- struct custom_ext *ce;
-
- IOENTER("%p, %p", drv_obj, client_id);
- ce = kmalloc(sizeof(*ce) + extlen, irql_gfp());
- if (ce == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- IOTRACE("custom_ext: %p", ce);
- ce->client_id = client_id;
- spin_lock_bh(&ntoskernel_lock);
- InsertTailList(&drv_obj->drv_ext->custom_ext, &ce->list);
- spin_unlock_bh(&ntoskernel_lock);
-
- *ext = (void *)ce + sizeof(*ce);
- IOTRACE("ext: %p", *ext);
- IOEXIT(return STATUS_SUCCESS);
-}
-
-wstdcall void *WIN_FUNC(IoGetDriverObjectExtension,2)
- (struct driver_object *drv_obj, void *client_id)
-{
- struct custom_ext *ce;
- void *ret;
-
- IOENTER("drv_obj: %p, client_id: %p", drv_obj, client_id);
- ret = NULL;
- spin_lock_bh(&ntoskernel_lock);
- nt_list_for_each_entry(ce, &drv_obj->drv_ext->custom_ext, list) {
- if (ce->client_id == client_id) {
- ret = (void *)ce + sizeof(*ce);
- break;
- }
- }
- spin_unlock_bh(&ntoskernel_lock);
- IOTRACE("ret: %p", ret);
- return ret;
-}
-
-void free_custom_extensions(struct driver_extension *drv_ext)
-{
- struct nt_list *ent;
-
- IOENTER("%p", drv_ext);
- spin_lock_bh(&ntoskernel_lock);
- while ((ent = RemoveHeadList(&drv_ext->custom_ext)))
- kfree(ent);
- spin_unlock_bh(&ntoskernel_lock);
- IOEXIT(return);
-}
-
-wstdcall NTSTATUS WIN_FUNC(IoCreateDevice,7)
- (struct driver_object *drv_obj, ULONG dev_ext_length,
- struct unicode_string *dev_name, DEVICE_TYPE dev_type,
- ULONG dev_chars, BOOLEAN exclusive, struct device_object **newdev)
-{
- struct device_object *dev;
- struct dev_obj_ext *dev_obj_ext;
- int size;
-
- IOENTER("%p, %u, %p", drv_obj, dev_ext_length, dev_name);
-
- size = sizeof(*dev) + dev_ext_length + sizeof(*dev_obj_ext);
- dev = allocate_object(size, OBJECT_TYPE_DEVICE, dev_name);
- if (!dev)
- IOEXIT(return STATUS_INSUFFICIENT_RESOURCES);
- if (dev_ext_length)
- dev->dev_ext = dev + 1;
- else
- dev->dev_ext = NULL;
-
- dev_obj_ext = ((void *)(dev + 1)) + dev_ext_length;
- dev_obj_ext->dev_obj = dev;
- dev_obj_ext->size = 0;
- dev_obj_ext->type = IO_TYPE_DEVICE;
- dev->dev_obj_ext = dev_obj_ext;
-
- dev->type = dev_type;
- dev->flags = 0;
- dev->size = sizeof(*dev) + dev_ext_length;
- dev->ref_count = 1;
- dev->attached = NULL;
- dev->stack_count = 1;
-
- dev->drv_obj = drv_obj;
- dev->next = drv_obj->dev_obj;
- drv_obj->dev_obj = dev;
-
- dev->align_req = 1;
- dev->characteristics = dev_chars;
- dev->io_timer = NULL;
- KeInitializeEvent(&dev->lock, SynchronizationEvent, TRUE);
- dev->vpb = NULL;
-
- IOTRACE("dev: %p, ext: %p", dev, dev->dev_ext);
- *newdev = dev;
- IOEXIT(return STATUS_SUCCESS);
-}
-
-wstdcall NTSTATUS WIN_FUNC(IoCreateUnprotectedSymbolicLink,2)
- (struct unicode_string *link, struct unicode_string *dev_name)
-{
- struct ansi_string ansi;
-
- IOENTER("%p, %p", dev_name, link);
- if (dev_name && (RtlUnicodeStringToAnsiString(&ansi, dev_name, TRUE) ==
- STATUS_SUCCESS)) {
- IOTRACE("dev_name: %s", ansi.buf);
- RtlFreeAnsiString(&ansi);
- }
- if (link && (RtlUnicodeStringToAnsiString(&ansi, link, TRUE) ==
- STATUS_SUCCESS)) {
- IOTRACE("link: %s", ansi.buf);
- RtlFreeAnsiString(&ansi);
- }
-// TODO();
- IOEXIT(return STATUS_SUCCESS);
-}
-
-wstdcall NTSTATUS WIN_FUNC(IoCreateSymbolicLink,2)
- (struct unicode_string *link, struct unicode_string *dev_name)
-{
- IOEXIT(return IoCreateUnprotectedSymbolicLink(link, dev_name));
-}
-
-wstdcall NTSTATUS WIN_FUNC(IoDeleteSymbolicLink,1)
- (struct unicode_string *link)
-{
- struct ansi_string ansi;
-
- IOENTER("%p", link);
- if (link && (RtlUnicodeStringToAnsiString(&ansi, link, TRUE) ==
- STATUS_SUCCESS)) {
- IOTRACE("dev_name: %s", ansi.buf);
- RtlFreeAnsiString(&ansi);
- }
- IOEXIT(return STATUS_SUCCESS);
-}
-
-wstdcall void WIN_FUNC(IoDeleteDevice,1)
- (struct device_object *dev)
-{
- IOENTER("%p", dev);
- if (dev == NULL)
- IOEXIT(return);
- IOTRACE("drv_obj: %p", dev->drv_obj);
- if (dev->drv_obj) {
- struct device_object *prev;
-
- prev = dev->drv_obj->dev_obj;
- IOTRACE("dev_obj: %p", prev);
- if (prev == dev)
- dev->drv_obj->dev_obj = dev->next;
- else if (prev) {
- while (prev->next != dev)
- prev = prev->next;
- prev->next = dev->next;
- }
- }
- ObDereferenceObject(dev);
- IOEXIT(return);
-}
-
-wstdcall void WIN_FUNC(IoDetachDevice,1)
- (struct device_object *tgt)
-{
- struct device_object *tail;
-
- IOENTER("%p", tgt);
- if (!tgt)
- IOEXIT(return);
- tail = tgt->attached;
- if (!tail)
- IOEXIT(return);
- IOTRACE("tail: %p", tail);
-
- spin_lock_bh(&ntoskernel_lock);
- tgt->attached = tail->attached;
- IOTRACE("attached:%p", tgt->attached);
- for ( ; tail; tail = tail->attached) {
- IOTRACE("tail:%p", tail);
- tail->stack_count--;
- }
- spin_unlock_bh(&ntoskernel_lock);
- IOEXIT(return);
-}
-
-wstdcall struct device_object *WIN_FUNC(IoGetAttachedDevice,1)
- (struct device_object *dev)
-{
- IOENTER("%p", dev);
- if (!dev)
- IOEXIT(return NULL);
- spin_lock_bh(&ntoskernel_lock);
- while (dev->attached)
- dev = dev->attached;
- spin_unlock_bh(&ntoskernel_lock);
- IOEXIT(return dev);
-}
-
-wstdcall struct device_object *WIN_FUNC(IoGetAttachedDeviceReference,1)
- (struct device_object *dev)
-{
- IOENTER("%p", dev);
- if (!dev)
- IOEXIT(return NULL);
- dev = IoGetAttachedDevice(dev);
- ObReferenceObject(dev);
- IOEXIT(return dev);
-}
-
-wstdcall struct device_object *WIN_FUNC(IoAttachDeviceToDeviceStack,2)
- (struct device_object *src, struct device_object *tgt)
-{
- struct device_object *attached;
- struct dev_obj_ext *src_dev_ext;
-
- IOENTER("%p, %p", src, tgt);
- attached = IoGetAttachedDevice(tgt);
- IOTRACE("%p", attached);
- src_dev_ext = src->dev_obj_ext;
- spin_lock_bh(&ntoskernel_lock);
- if (attached)
- attached->attached = src;
- src->attached = NULL;
- src->stack_count = attached->stack_count + 1;
- src_dev_ext->attached_to = attached;
- spin_unlock_bh(&ntoskernel_lock);
- IOTRACE("stack_count: %d -> %d", attached->stack_count,
- src->stack_count);
- IOEXIT(return attached);
-}
-
-wstdcall NTSTATUS WIN_FUNC(IoGetDeviceProperty,5)
- (struct device_object *pdo, enum device_registry_property dev_property,
- ULONG buffer_len, void *buffer, ULONG *result_len)
-{
- struct ansi_string ansi;
- struct unicode_string unicode;
- struct wrap_device *wd;
- ULONG need;
-
- IOENTER("dev_obj = %p, dev_property = %d, buffer_len = %u, "
- "buffer = %p, result_len = %p", pdo, dev_property,
- buffer_len, buffer, result_len);
-
- wd = pdo->reserved;
- switch (dev_property) {
- case DevicePropertyDeviceDescription:
- case DevicePropertyFriendlyName:
- case DevicePropertyDriverKeyName:
- if (wrap_is_pci_bus(wd->dev_bus))
- RtlInitAnsiString(&ansi, "PCI");
- else // if (wrap_is_usb_bus(wd->dev_bus))
- RtlInitAnsiString(&ansi, "USB");
- need = sizeof(wchar_t) * (ansi.max_length + 1);
- if (buffer_len < need) {
- *result_len = need;
- IOEXIT(return STATUS_BUFFER_TOO_SMALL);
- }
- unicode.max_length = buffer_len;
- unicode.buf = buffer;
- if (RtlAnsiStringToUnicodeString(&unicode, &ansi,
- FALSE) != STATUS_SUCCESS) {
- *result_len = unicode.length;
- IOEXIT(return STATUS_BUFFER_TOO_SMALL);
- }
- IOEXIT(return STATUS_SUCCESS);
- default:
- WARNING("%d not implemented", dev_property);
- IOEXIT(return STATUS_INVALID_PARAMETER_2);
- }
-}
-
-wstdcall NTSTATUS WIN_FUNC(IoGetDeviceObjectPointer,4)
- (struct unicode_string *name, ACCESS_MASK desired_access,
- void *file_obj, struct device_object *dev_obj)
-{
- struct common_object_header *coh;
-
- dev_obj = NULL;
- /* TODO: access is not checked and file_obj is set to NULL */
- file_obj = NULL;
- spin_lock_bh(&ntoskernel_lock);
- nt_list_for_each_entry(coh, &object_list, list) {
- TRACE5("header: %p, type: %d", coh, coh->type);
- if (coh->type != OBJECT_TYPE_DEVICE)
- continue;
- if (!RtlCompareUnicodeString(&coh->name, name, TRUE)) {
- dev_obj = HEADER_TO_OBJECT(coh);
- TRACE5("dev_obj: %p", dev_obj);
- break;
- }
- }
- spin_unlock_bh(&ntoskernel_lock);
- if (dev_obj)
- IOEXIT(return STATUS_SUCCESS);
- else
- IOEXIT(return STATUS_OBJECT_NAME_INVALID);
-}
-
-/* NOTE: Make sure to compile with -freg-struct-return, so gcc will
- * return union in register, like Windows */
-wstdcall union power_state WIN_FUNC(PoSetPowerState,3)
- (struct device_object *dev_obj, enum power_state_type type,
- union power_state state)
-{
- IOEXIT(return state);
-}
-
-wstdcall NTSTATUS WIN_FUNC(PoCallDriver,2)
- (struct device_object *dev_obj, struct irp *irp)
-{
- return IoCallDriver(dev_obj, irp);
-}
-
-wstdcall NTSTATUS WIN_FUNC(PoRequestPowerIrp,6)
- (struct device_object *dev_obj, UCHAR minor_fn,
- union power_state power_state, void *completion_func,
- void *context, struct irp **pirp)
-{
- struct irp *irp;
- struct io_stack_location *irp_sl;
-
- TRACE1("%p, %d, %p", dev_obj, dev_obj->stack_count, dev_obj->drv_obj);
- irp = IoAllocateIrp(dev_obj->stack_count, FALSE);
- if (!irp)
- return STATUS_INSUFFICIENT_RESOURCES;
- irp_sl = IoGetNextIrpStackLocation(irp);
- irp_sl->major_fn = IRP_MJ_POWER;
- irp_sl->minor_fn = minor_fn;
- if (minor_fn == IRP_MN_WAIT_WAKE)
- irp_sl->params.power.type = SystemPowerState;
- else
- irp_sl->params.power.type = DevicePowerState;
- irp_sl->params.power.state = power_state;
- irp_sl->completion_routine = completion_func;
- irp->io_status.status = STATUS_NOT_SUPPORTED;
- *pirp = irp;
- return PoCallDriver(dev_obj, irp);
-}
-
-wstdcall void WIN_FUNC(PoStartNextPowerIrp,1)
- (struct irp *irp)
-{
- IOENTER("irp = %p", irp);
- IOEXIT(return);
-}
-
-wstdcall void WIN_FUNC(IoInitializeRemoveLockEx,5)
- (struct io_remove_lock *lock, ULONG alloc_tag, ULONG max_locked_min,
- ULONG high_mark, ULONG lock_size)
-{
- TODO();
-}
-
-wstdcall void *WIN_FUNC(IoAllocateErrorLogEntry,2)
- (void *io_object, UCHAR entry_size)
-{
- /* not implemented fully */
- void *ret = kmalloc(sizeof(struct io_error_log_packet) + entry_size,
- irql_gfp());
- TRACE2("%p", ret);
- if (ret)
- return ret + sizeof(struct io_error_log_packet);
- else
- return NULL;
-}
-
-wstdcall void WIN_FUNC(IoWriteErrorLogEntry,1)
- (void *entry)
-{
- /* TODO: log error with codes and message */
- ERROR("");
-}
-
-wstdcall void WIN_FUNC(IoFreeErrorLogEntry,1)
- (void *entry)
-{
- TRACE2("%p", entry);
- kfree(entry - sizeof(struct io_error_log_packet));
-}
-
-wstdcall NTSTATUS WIN_FUNC(IoAcquireRemoveLockEx,5)
- (struct io_remove_lock lock, void *tag, char *file, ULONG line,
- ULONG lock_size)
-{
- TODO();
- IOEXIT(return STATUS_SUCCESS);
-}
-
-wstdcall NTSTATUS WIN_FUNC(IoReleaseRemoveLockEx,3)
- (struct io_remove_lock lock, void *tag, ULONG lock_size)
-{
- TODO();
- IOEXIT(return STATUS_SUCCESS);
-}
-
-wstdcall NTSTATUS WIN_FUNC(IoRegisterDeviceInterface,4)
- (struct device_object *pdo, struct guid *guid_class,
- struct unicode_string *reference, struct unicode_string *link)
-{
- struct ansi_string ansi;
-
- /* TODO: check if pdo is valid */
- RtlInitAnsiString(&ansi, "ndis");
- ENTER1("pdo: %p, ref: %p, link: %p, %x, %x, %x", pdo, reference, link,
- guid_class->data1, guid_class->data2, guid_class->data3);
- return RtlAnsiStringToUnicodeString(link, &ansi, TRUE);
-}
-
-wstdcall NTSTATUS WIN_FUNC(IoSetDeviceInterfaceState,2)
- (struct unicode_string *link, BOOLEAN enable)
-{
- ENTER1("link: %p, enable: %d", link, enable);
- return STATUS_SUCCESS;
-}
-
-wstdcall NTSTATUS WIN_FUNC(IoOpenDeviceRegistryKey,4)
- (struct device_object *dev_obj, ULONG type, ACCESS_MASK mask,
- void **handle)
-{
- ENTER1("dev_obj: %p", dev_obj);
- *handle = dev_obj;
- return STATUS_SUCCESS;
-}
-
-wstdcall NTSTATUS WIN_FUNC(IoWMIRegistrationControl,2)
- (struct device_object *dev_obj, ULONG action)
-{
- ENTER2("%p, %d", dev_obj, action);
- EXIT2(return STATUS_SUCCESS);
-}
-
-wstdcall void WIN_FUNC(IoInvalidateDeviceRelations,2)
- (struct device_object *dev_obj, enum device_relation_type type)
-{
- INFO("%p, %d", dev_obj, type);
- TODO();
-}
-
-wstdcall void WIN_FUNC(IoInvalidateDeviceState,1)
- (struct device_object *pdo)
-{
- INFO("%p", pdo);
- TODO();
-}
+++ /dev/null
-/*
- * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#ifdef TEST_LOADER
-
-#include "usr_linker.h"
-
-#else
-
-#include <linux/types.h>
-#include <asm/errno.h>
-
-//#define DEBUGLINKER 2
-
-#include "ntoskernel.h"
-
-#endif
-
-struct pe_exports {
- char *dll;
- char *name;
- generic_func addr;
-};
-
-static struct pe_exports pe_exports[40];
-static int num_pe_exports;
-
-#define RVA2VA(image, rva, type) (type)(ULONG_PTR)((void *)image + rva)
-#define CHECK_SZ(a,b) { if (sizeof(a) != b) { \
- ERROR("%s is bad, got %zd, expected %d", \
- #a , sizeof(a), (b)); return -EINVAL; } }
-
-#if defined(DEBUGLINKER) && DEBUGLINKER > 0
-#define DBGLINKER(fmt, ...) printk(KERN_INFO "%s (%s:%d): " fmt "\n", \
- DRIVER_NAME, __func__, \
- __LINE__ , ## __VA_ARGS__);
-static const char *image_directory_name[] = {
- "EXPORT",
- "IMPORT",
- "RESOURCE",
- "EXCEPTION",
- "SECURITY",
- "BASERELOC",
- "DEBUG",
- "COPYRIGHT",
- "GLOBALPTR",
- "TLS",
- "LOAD_CONFIG",
- "BOUND_IMPORT",
- "IAT",
- "DELAY_IMPORT",
- "COM_DESCRIPTOR" };
-#else
-#define DBGLINKER(fmt, ...) do { } while (0)
-#endif
-
-#ifndef TEST_LOADER
-extern struct wrap_export ntoskernel_exports[], ntoskernel_io_exports[],
- ndis_exports[], crt_exports[], hal_exports[], rtl_exports[];
-#ifdef ENABLE_USB
-extern struct wrap_export usb_exports[];
-#endif
-
-static int get_export(char *name, generic_func *func)
-{
- int i, j;
-
- struct wrap_export *exports[] = {
- ntoskernel_exports,
- ntoskernel_io_exports,
- ndis_exports,
- crt_exports,
- hal_exports,
- rtl_exports,
-#ifdef ENABLE_USB
- usb_exports,
-#endif
- };
-
- for (j = 0; j < ARRAY_SIZE(exports); j++)
- for (i = 0; exports[j][i].name != NULL; i++)
- if (strcmp(exports[j][i].name, name) == 0) {
- *func = exports[j][i].func;
- return 0;
- }
-
- for (i = 0; i < num_pe_exports; i++)
- if (strcmp(pe_exports[i].name, name) == 0) {
- *func = pe_exports[i].addr;
- return 0;
- }
-
- return -1;
-}
-#endif // TEST_LOADER
-
-static void *get_dll_init(char *name)
-{
- int i;
- for (i = 0; i < num_pe_exports; i++)
- if ((strcmp(pe_exports[i].dll, name) == 0) &&
- (strcmp(pe_exports[i].name, "DllInitialize") == 0))
- return (void *)pe_exports[i].addr;
- return NULL;
-}
-
-/*
- * Find and validate the coff header
- *
- */
-static int check_nt_hdr(IMAGE_NT_HEADERS *nt_hdr)
-{
- int i;
- WORD attr;
- PIMAGE_OPTIONAL_HEADER opt_hdr;
-
- /* Validate the "PE\0\0" signature */
- if (nt_hdr->Signature != IMAGE_NT_SIGNATURE) {
- ERROR("is this driver file? bad signature %08x",
- nt_hdr->Signature);
- return -EINVAL;
- }
-
- opt_hdr = &nt_hdr->OptionalHeader;
- /* Make sure Image is PE32 or PE32+ */
-#ifdef CONFIG_X86_64
- if (opt_hdr->Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
- ERROR("kernel is 64-bit, but Windows driver is not 64-bit;"
- "bad magic: %04X", opt_hdr->Magic);
- return -EINVAL;
- }
-#else
- if (opt_hdr->Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
- ERROR("kernel is 32-bit, but Windows driver is not 32-bit;"
- "bad magic: %04X", opt_hdr->Magic);
- return -EINVAL;
- }
-#endif
-
- /* Validate the image for the current architecture. */
-#ifdef CONFIG_X86_64
- if (nt_hdr->FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64) {
- ERROR("kernel is 64-bit, but Windows driver is not 64-bit;"
- " (PE signature is %04X)", nt_hdr->FileHeader.Machine);
- return -EINVAL;
- }
-#else
- if (nt_hdr->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) {
- ERROR("kernel is 32-bit, but Windows driver is not 32-bit;"
- " (PE signature is %04X)", nt_hdr->FileHeader.Machine);
- return -EINVAL;
- }
-#endif
-
- /* Must have attributes */
-#ifdef CONFIG_X86_64
- attr = IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_LARGE_ADDRESS_AWARE;
-#else
- attr = IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_32BIT_MACHINE;
-#endif
- if ((nt_hdr->FileHeader.Characteristics & attr) != attr)
- return -EINVAL;
-
- /* Must be relocatable */
- attr = IMAGE_FILE_RELOCS_STRIPPED;
- if ((nt_hdr->FileHeader.Characteristics & attr))
- return -EINVAL;
-
- /* Make sure we have at least one section */
- if (nt_hdr->FileHeader.NumberOfSections == 0)
- return -EINVAL;
-
- if (opt_hdr->SectionAlignment < opt_hdr->FileAlignment) {
- ERROR("alignment mismatch: secion: 0x%x, file: 0x%x",
- opt_hdr->SectionAlignment, opt_hdr->FileAlignment);
- return -EINVAL;
- }
-
- DBGLINKER("number of datadictionary entries %d",
- opt_hdr->NumberOfRvaAndSizes);
- for (i = 0; i < opt_hdr->NumberOfRvaAndSizes; i++) {
- DBGLINKER("datadirectory %s RVA:%X Size:%d",
- (i<=IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR)?
- image_directory_name[i] : "unknown",
- opt_hdr->DataDirectory[i].VirtualAddress,
- opt_hdr->DataDirectory[i].Size);
- }
-
- if ((nt_hdr->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE))
- return IMAGE_FILE_EXECUTABLE_IMAGE;
- if ((nt_hdr->FileHeader.Characteristics & IMAGE_FILE_DLL))
- return IMAGE_FILE_DLL;
- return -EINVAL;
-}
-
-static int import(void *image, IMAGE_IMPORT_DESCRIPTOR *dirent, char *dll)
-{
- ULONG_PTR *lookup_tbl, *address_tbl;
- char *symname = NULL;
- int i;
- int ret = 0;
- generic_func adr;
-
- lookup_tbl = RVA2VA(image, dirent->u.OriginalFirstThunk, ULONG_PTR *);
- address_tbl = RVA2VA(image, dirent->FirstThunk, ULONG_PTR *);
-
- for (i = 0; lookup_tbl[i]; i++) {
- if (IMAGE_SNAP_BY_ORDINAL(lookup_tbl[i])) {
- ERROR("ordinal import not supported: %Lu",
- (uint64_t)lookup_tbl[i]);
- return -1;
- }
- else {
- symname = RVA2VA(image,
- ((lookup_tbl[i] &
- ~IMAGE_ORDINAL_FLAG) + 2), char *);
- }
-
- ret = get_export(symname, &adr);
- if (ret < 0) {
- ERROR("unknown symbol: %s:'%s'", dll, symname);
- } else {
- DBGLINKER("found symbol: %s:%s: addr: %p, rva = %Lu",
- dll, symname, adr, (uint64_t)address_tbl[i]);
- address_tbl[i] = (ULONG_PTR)adr;
- }
- }
- return ret;
-}
-
-static int read_exports(struct pe_image *pe)
-{
- IMAGE_EXPORT_DIRECTORY *export_dir_table;
- uint32_t *export_addr_table;
- int i;
- uint32_t *name_table;
- PIMAGE_OPTIONAL_HEADER opt_hdr;
- IMAGE_DATA_DIRECTORY *export_data_dir;
-
- opt_hdr = &pe->nt_hdr->OptionalHeader;
- export_data_dir =
- &opt_hdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
-
- if (export_data_dir->Size == 0) {
- DBGLINKER("no exports");
- return 0;
- }
-
- export_dir_table =
- RVA2VA(pe->image, export_data_dir->VirtualAddress,
- IMAGE_EXPORT_DIRECTORY *);
-
- name_table = (unsigned int *)(pe->image +
- export_dir_table->AddressOfNames);
- export_addr_table = (uint32_t *)
- (pe->image + export_dir_table->AddressOfFunctions);
-
- for (i = 0; i < export_dir_table->NumberOfNames; i++) {
-
- if (export_data_dir->VirtualAddress <= *export_addr_table ||
- *export_addr_table >= (export_data_dir->VirtualAddress +
- export_data_dir->Size))
- DBGLINKER("forwarder rva");
-
- DBGLINKER("export symbol: %s, at %p",
- (char *)(pe->image + *name_table),
- pe->image + *export_addr_table);
-
- pe_exports[num_pe_exports].dll = pe->name;
- pe_exports[num_pe_exports].name = pe->image + *name_table;
- pe_exports[num_pe_exports].addr =
- pe->image + *export_addr_table;
-
- num_pe_exports++;
- name_table++;
- export_addr_table++;
- }
- return 0;
-}
-
-static int fixup_imports(void *image, IMAGE_NT_HEADERS *nt_hdr)
-{
- int i;
- char *name;
- int ret = 0;
- IMAGE_IMPORT_DESCRIPTOR *dirent;
- IMAGE_DATA_DIRECTORY *import_data_dir;
- PIMAGE_OPTIONAL_HEADER opt_hdr;
-
- opt_hdr = &nt_hdr->OptionalHeader;
- import_data_dir =
- &opt_hdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
- dirent = RVA2VA(image, import_data_dir->VirtualAddress,
- IMAGE_IMPORT_DESCRIPTOR *);
-
- for (i = 0; dirent[i].Name; i++) {
- name = RVA2VA(image, dirent[i].Name, char*);
-
- DBGLINKER("imports from dll: %s", name);
- ret += import(image, &dirent[i], name);
- }
- return ret;
-}
-
-static int fixup_reloc(void *image, IMAGE_NT_HEADERS *nt_hdr)
-{
- ULONG_PTR base;
- ULONG_PTR size;
- IMAGE_BASE_RELOCATION *fixup_block;
- IMAGE_DATA_DIRECTORY *base_reloc_data_dir;
- PIMAGE_OPTIONAL_HEADER opt_hdr;
-
- opt_hdr = &nt_hdr->OptionalHeader;
- base = opt_hdr->ImageBase;
- base_reloc_data_dir =
- &opt_hdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
- if (base_reloc_data_dir->Size == 0)
- return 0;
-
- fixup_block = RVA2VA(image, base_reloc_data_dir->VirtualAddress,
- IMAGE_BASE_RELOCATION *);
- DBGLINKER("fixup_block=%p, image=%p", fixup_block, image);
- DBGLINKER("fixup_block info: %x %d",
- fixup_block->VirtualAddress, fixup_block->SizeOfBlock);
-
- while (fixup_block->SizeOfBlock) {
- int i;
- WORD fixup, offset;
-
- size = (fixup_block->SizeOfBlock -
- sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
- DBGLINKER("found %Lu relocations in this block",
- (uint64_t)size);
-
- for (i = 0; i < size; i++) {
- fixup = fixup_block->TypeOffset[i];
- offset = fixup & 0xfff;
- switch ((fixup >> 12) & 0x0f) {
- case IMAGE_REL_BASED_ABSOLUTE:
- break;
-
- case IMAGE_REL_BASED_HIGHLOW: {
- uint32_t addr;
- uint32_t *loc =
- RVA2VA(image,
- fixup_block->VirtualAddress +
- offset, uint32_t *);
- addr = RVA2VA(image, (*loc - base), uint32_t);
- DBGLINKER("relocation: *%p (Val:%X)= %X",
- loc, *loc, addr);
- *loc = addr;
- }
- break;
-
- case IMAGE_REL_BASED_DIR64: {
- uint64_t addr;
- uint64_t *loc =
- RVA2VA(image,
- fixup_block->VirtualAddress +
- offset, uint64_t *);
- addr = RVA2VA(image, (*loc - base), uint64_t);
- DBGLINKER("relocation: *%p (Val:%llX)= %llx",
- loc, *loc, addr);
- *loc = addr;
- }
- break;
-
- default:
- ERROR("unknown fixup: %08X",
- (fixup >> 12) & 0x0f);
- return -EOPNOTSUPP;
- break;
- }
- }
- DBGLINKER("finished relocating block");
-
- fixup_block = (IMAGE_BASE_RELOCATION *)
- ((void *)fixup_block + fixup_block->SizeOfBlock);
- };
- DBGLINKER("done relocating all");
-
- return 0;
-}
-
-/* Expand the image in memroy if necessary. The image on disk does not
- * necessarily maps the image of the driver in memory, so we have to
- * re-write it in order to fullfill the sections alignements. The
- * advantage to do that is that rva_to_va becomes a simple
- * addition. */
-static int fix_pe_image(struct pe_image *pe)
-{
- void *image;
- IMAGE_SECTION_HEADER *sect_hdr;
- int i, sections;
- int image_size;
-
- if (pe->size == pe->opt_hdr->SizeOfImage) {
- /* Nothing to do */
- return 0;
- }
-
- image_size = pe->opt_hdr->SizeOfImage;
-#ifdef CONFIG_X86_64
-#ifdef PAGE_KERNEL_EXECUTABLE
- image = __vmalloc(image_size, GFP_KERNEL | __GFP_HIGHMEM,
- PAGE_KERNEL_EXECUTABLE);
-#elif defined PAGE_KERNEL_EXEC
- image = __vmalloc(image_size, GFP_KERNEL | __GFP_HIGHMEM,
- PAGE_KERNEL_EXEC);
-#else
-#error x86_64 should have either PAGE_KERNEL_EXECUTABLE or PAGE_KERNEL_EXEC
-#endif
-#else
-#ifdef cpu_has_nx
- /* hate to play with kernel macros, but PAGE_KERNEL_EXEC is
- * not available to modules! */
- if (cpu_has_nx)
- image = __vmalloc(image_size, GFP_KERNEL | __GFP_HIGHMEM,
- __pgprot(__PAGE_KERNEL & ~_PAGE_NX));
- else
- image = vmalloc(image_size);
-#else
- image = vmalloc(image_size);
-#endif
-#endif
- if (image == NULL) {
- ERROR("failed to allocate enough space for new image:"
- " %d bytes", image_size);
- return -ENOMEM;
- }
-
- /* Copy all the headers, ie everything before the first section. */
-
- sections = pe->nt_hdr->FileHeader.NumberOfSections;
- sect_hdr = IMAGE_FIRST_SECTION(pe->nt_hdr);
-
- DBGLINKER("copying headers: %u bytes", sect_hdr->PointerToRawData);
-
- memcpy(image, pe->image, sect_hdr->PointerToRawData);
-
- /* Copy all the sections */
- for (i = 0; i < sections; i++) {
- DBGLINKER("Copy section %s from %x to %x",
- sect_hdr->Name, sect_hdr->PointerToRawData,
- sect_hdr->VirtualAddress);
- if (sect_hdr->VirtualAddress+sect_hdr->SizeOfRawData >
- image_size) {
- ERROR("Invalid section %s in driver", sect_hdr->Name);
- vfree(image);
- return -EINVAL;
- }
-
- memcpy(image+sect_hdr->VirtualAddress,
- pe->image + sect_hdr->PointerToRawData,
- sect_hdr->SizeOfRawData);
- sect_hdr++;
- }
-
- vfree(pe->image);
- pe->image = image;
- pe->size = image_size;
-
- /* Update our internal pointers */
- pe->nt_hdr = (IMAGE_NT_HEADERS *)
- (pe->image + ((IMAGE_DOS_HEADER *)pe->image)->e_lfanew);
- pe->opt_hdr = &pe->nt_hdr->OptionalHeader;
-
- DBGLINKER("set nt headers: nt_hdr=%p, opt_hdr=%p, image=%p",
- pe->nt_hdr, pe->opt_hdr, pe->image);
-
- return 0;
-}
-
-#if defined(CONFIG_X86_64)
-static void fix_user_shared_data_addr(char *driver, unsigned long length)
-{
- unsigned long i, n, max_addr, *addr;
-
- n = length - sizeof(unsigned long);
- max_addr = KI_USER_SHARED_DATA + sizeof(kuser_shared_data);
- for (i = 0; i < n; i++) {
- addr = (unsigned long *)(driver + i);
- if (*addr >= KI_USER_SHARED_DATA && *addr < max_addr) {
- *addr -= KI_USER_SHARED_DATA;
- *addr += (unsigned long)&kuser_shared_data;
- kuser_shared_data.reserved1 = 1;
- }
- }
-}
-#endif
-
-int link_pe_images(struct pe_image *pe_image, unsigned short n)
-{
- int i;
- struct pe_image *pe;
-
-#ifdef DEBUG
- /* Sanity checkings */
- CHECK_SZ(IMAGE_SECTION_HEADER, IMAGE_SIZEOF_SECTION_HEADER);
- CHECK_SZ(IMAGE_FILE_HEADER, IMAGE_SIZEOF_FILE_HEADER);
- CHECK_SZ(IMAGE_OPTIONAL_HEADER, IMAGE_SIZEOF_NT_OPTIONAL_HEADER);
- CHECK_SZ(IMAGE_NT_HEADERS, 4 + IMAGE_SIZEOF_FILE_HEADER +
- IMAGE_SIZEOF_NT_OPTIONAL_HEADER);
- CHECK_SZ(IMAGE_DOS_HEADER, 0x40);
- CHECK_SZ(IMAGE_EXPORT_DIRECTORY, 40);
- CHECK_SZ(IMAGE_BASE_RELOCATION, 8);
- CHECK_SZ(IMAGE_IMPORT_DESCRIPTOR, 20);
-#endif
-
- for (i = 0; i < n; i++) {
- IMAGE_DOS_HEADER *dos_hdr;
- pe = &pe_image[i];
- dos_hdr = pe->image;
-
- if (pe->size < sizeof(IMAGE_DOS_HEADER)) {
- TRACE1("image too small: %d", pe->size);
- return -EINVAL;
- }
-
- pe->nt_hdr =
- (IMAGE_NT_HEADERS *)(pe->image + dos_hdr->e_lfanew);
- pe->opt_hdr = &pe->nt_hdr->OptionalHeader;
-
- pe->type = check_nt_hdr(pe->nt_hdr);
- if (pe->type <= 0) {
- TRACE1("type <= 0");
- return -EINVAL;
- }
-
- if (fix_pe_image(pe)) {
- TRACE1("bad PE image");
- return -EINVAL;
- }
-
- if (read_exports(pe)) {
- TRACE1("read exports failed");
- return -EINVAL;
- }
- }
-
- for (i = 0; i < n; i++) {
- pe = &pe_image[i];
-
- if (fixup_reloc(pe->image, pe->nt_hdr)) {
- TRACE1("fixup reloc failed");
- return -EINVAL;
- }
- if (fixup_imports(pe->image, pe->nt_hdr)) {
- TRACE1("fixup imports failed");
- return -EINVAL;
- }
-#if defined(CONFIG_X86_64)
- INFO("fixing KI_USER_SHARED_DATA address in the driver");
- fix_user_shared_data_addr(pe_image[i].image, pe_image[i].size);
-#endif
- flush_icache_range(pe->image, pe->size);
-
- pe->entry =
- RVA2VA(pe->image,
- pe->opt_hdr->AddressOfEntryPoint, void *);
- TRACE1("entry is at %p, rva at %08X", pe->entry,
- pe->opt_hdr->AddressOfEntryPoint);
- }
-
- for (i = 0; i < n; i++) {
- pe = &pe_image[i];
-
- if (pe->type == IMAGE_FILE_DLL) {
- struct unicode_string ustring;
- char *buf = "0/0t0m0p00";
- int (*dll_entry)(struct unicode_string *ustring)
- wstdcall;
-
- memset(&ustring, 0, sizeof(ustring));
- ustring.buf = (wchar_t *)buf;
- dll_entry = (void *)get_dll_init(pe->name);
-
- TRACE1("calling dll_init at %p", dll_entry);
- if (!dll_entry || dll_entry(&ustring))
- ERROR("DLL initialize failed for %s",
- pe->name);
- }
- else if (pe->type != IMAGE_FILE_EXECUTABLE_IMAGE)
- ERROR("illegal image type: %d", pe->type);
- }
- return 0;
-}
+++ /dev/null
-/*
- * This file is an excerpt of winnt.h from WINE, which bears the
- * following copyright:
- *
- * Win32 definitions for Windows NT
- *
- * Copyright 1996 Alexandre Julliard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * File formats definitions
- */
-typedef struct _IMAGE_DOS_HEADER {
- WORD e_magic; /* 00: MZ Header signature */
- WORD e_cblp; /* 02: Bytes on last page of file */
- WORD e_cp; /* 04: Pages in file */
- WORD e_crlc; /* 06: Relocations */
- WORD e_cparhdr; /* 08: Size of header in paragraphs */
- WORD e_minalloc; /* 0a: Minimum extra paragraphs needed */
- WORD e_maxalloc; /* 0c: Maximum extra paragraphs needed */
- WORD e_ss; /* 0e: Initial (relative) SS value */
- WORD e_sp; /* 10: Initial SP value */
- WORD e_csum; /* 12: Checksum */
- WORD e_ip; /* 14: Initial IP value */
- WORD e_cs; /* 16: Initial (relative) CS value */
- WORD e_lfarlc; /* 18: File address of relocation table */
- WORD e_ovno; /* 1a: Overlay number */
- WORD e_res[4]; /* 1c: Reserved words */
- WORD e_oemid; /* 24: OEM identifier (for e_oeminfo) */
- WORD e_oeminfo; /* 26: OEM information; e_oemid specific */
- WORD e_res2[10]; /* 28: Reserved words */
- DWORD e_lfanew; /* 3c: Offset to extended header */
-} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
-
-#define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */
-#define IMAGE_OS2_SIGNATURE 0x454E /* NE */
-#define IMAGE_OS2_SIGNATURE_LE 0x454C /* LE */
-#define IMAGE_OS2_SIGNATURE_LX 0x584C /* LX */
-#define IMAGE_VXD_SIGNATURE 0x454C /* LE */
-#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */
-
-/*
- * This is the Windows executable (NE) header.
- * the name IMAGE_OS2_HEADER is misleading, but in the SDK this way.
- */
-typedef struct
-{
- WORD ne_magic; /* 00 NE signature 'NE' */
- BYTE ne_ver; /* 02 Linker version number */
- BYTE ne_rev; /* 03 Linker revision number */
- WORD ne_enttab; /* 04 Offset to entry table relative to NE */
- WORD ne_cbenttab; /* 06 Length of entry table in bytes */
- LONG ne_crc; /* 08 Checksum */
- WORD ne_flags; /* 0c Flags about segments in this file */
- WORD ne_autodata; /* 0e Automatic data segment number */
- WORD ne_heap; /* 10 Initial size of local heap */
- WORD ne_stack; /* 12 Initial size of stack */
- DWORD ne_csip; /* 14 Initial CS:IP */
- DWORD ne_sssp; /* 18 Initial SS:SP */
- WORD ne_cseg; /* 1c # of entries in segment table */
- WORD ne_cmod; /* 1e # of entries in module reference tab. */
- WORD ne_cbnrestab; /* 20 Length of nonresident-name table */
- WORD ne_segtab; /* 22 Offset to segment table */
- WORD ne_rsrctab; /* 24 Offset to resource table */
- WORD ne_restab; /* 26 Offset to resident-name table */
- WORD ne_modtab; /* 28 Offset to module reference table */
- WORD ne_imptab; /* 2a Offset to imported name table */
- DWORD ne_nrestab; /* 2c Offset to nonresident-name table */
- WORD ne_cmovent; /* 30 # of movable entry points */
- WORD ne_align; /* 32 Logical sector alignment shift count */
- WORD ne_cres; /* 34 # of resource segments */
- BYTE ne_exetyp; /* 36 Flags indicating target OS */
- BYTE ne_flagsothers; /* 37 Additional information flags */
- WORD ne_pretthunks; /* 38 Offset to return thunks */
- WORD ne_psegrefbytes; /* 3a Offset to segment ref. bytes */
- WORD ne_swaparea; /* 3c Reserved by Microsoft */
- WORD ne_expver; /* 3e Expected Windows version number */
-} IMAGE_OS2_HEADER, *PIMAGE_OS2_HEADER;
-
-typedef struct _IMAGE_VXD_HEADER {
- WORD e32_magic;
- BYTE e32_border;
- BYTE e32_worder;
- DWORD e32_level;
- WORD e32_cpu;
- WORD e32_os;
- DWORD e32_ver;
- DWORD e32_mflags;
- DWORD e32_mpages;
- DWORD e32_startobj;
- DWORD e32_eip;
- DWORD e32_stackobj;
- DWORD e32_esp;
- DWORD e32_pagesize;
- DWORD e32_lastpagesize;
- DWORD e32_fixupsize;
- DWORD e32_fixupsum;
- DWORD e32_ldrsize;
- DWORD e32_ldrsum;
- DWORD e32_objtab;
- DWORD e32_objcnt;
- DWORD e32_objmap;
- DWORD e32_itermap;
- DWORD e32_rsrctab;
- DWORD e32_rsrccnt;
- DWORD e32_restab;
- DWORD e32_enttab;
- DWORD e32_dirtab;
- DWORD e32_dircnt;
- DWORD e32_fpagetab;
- DWORD e32_frectab;
- DWORD e32_impmod;
- DWORD e32_impmodcnt;
- DWORD e32_impproc;
- DWORD e32_pagesum;
- DWORD e32_datapage;
- DWORD e32_preload;
- DWORD e32_nrestab;
- DWORD e32_cbnrestab;
- DWORD e32_nressum;
- DWORD e32_autodata;
- DWORD e32_debuginfo;
- DWORD e32_debuglen;
- DWORD e32_instpreload;
- DWORD e32_instdemand;
- DWORD e32_heapsize;
- BYTE e32_res3[12];
- DWORD e32_winresoff;
- DWORD e32_winreslen;
- WORD e32_devid;
- WORD e32_ddkver;
-} IMAGE_VXD_HEADER, *PIMAGE_VXD_HEADER;
-
-/* These defines describe the meanings of the bits in the
- Characteristics field */
-
-#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 /* No relocation info */
-#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
-#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004
-#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008
-#define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010
-#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020
-#define IMAGE_FILE_16BIT_MACHINE 0x0040
-#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080
-#define IMAGE_FILE_32BIT_MACHINE 0x0100
-#define IMAGE_FILE_DEBUG_STRIPPED 0x0200
-#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400
-#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800
-#define IMAGE_FILE_SYSTEM 0x1000
-#define IMAGE_FILE_DLL 0x2000
-#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000
-#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
-
-/* These are the settings of the Machine field. */
-#define IMAGE_FILE_MACHINE_UNKNOWN 0
-#define IMAGE_FILE_MACHINE_I860 0x014d
-#define IMAGE_FILE_MACHINE_I386 0x014c
-#define IMAGE_FILE_MACHINE_R3000 0x0162
-#define IMAGE_FILE_MACHINE_R4000 0x0166
-#define IMAGE_FILE_MACHINE_R10000 0x0168
-#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169
-#define IMAGE_FILE_MACHINE_ALPHA 0x0184
-#define IMAGE_FILE_MACHINE_SH3 0x01a2
-#define IMAGE_FILE_MACHINE_SH3DSP 0x01a3
-#define IMAGE_FILE_MACHINE_SH3E 0x01a4
-#define IMAGE_FILE_MACHINE_SH4 0x01a6
-#define IMAGE_FILE_MACHINE_SH5 0x01a8
-#define IMAGE_FILE_MACHINE_ARM 0x01c0
-#define IMAGE_FILE_MACHINE_THUMB 0x01c2
-#define IMAGE_FILE_MACHINE_AM33 0x01d3
-#define IMAGE_FILE_MACHINE_POWERPC 0x01f0
-#define IMAGE_FILE_MACHINE_POWERPCFP 0x01f1
-#define IMAGE_FILE_MACHINE_IA64 0x0200
-#define IMAGE_FILE_MACHINE_MIPS16 0x0266
-#define IMAGE_FILE_MACHINE_ALPHA64 0x0284
-#define IMAGE_FILE_MACHINE_MIPSFPU 0x0366
-#define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466
-#define IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64
-#define IMAGE_FILE_MACHINE_TRICORE 0x0520
-#define IMAGE_FILE_MACHINE_CEF 0x0cef
-#define IMAGE_FILE_MACHINE_EBC 0x0ebc
-#define IMAGE_FILE_MACHINE_AMD64 0x8664
-#define IMAGE_FILE_MACHINE_M32R 0x9041
-#define IMAGE_FILE_MACHINE_CEE 0xc0ee
-
-#define IMAGE_SIZEOF_FILE_HEADER 20
-#define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER 56
-#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28
-#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER32 224
-#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER64 240
-#define IMAGE_SIZEOF_SHORT_NAME 8
-#define IMAGE_SIZEOF_SECTION_HEADER 40
-#define IMAGE_SIZEOF_SYMBOL 18
-#define IMAGE_SIZEOF_AUX_SYMBOL 18
-#define IMAGE_SIZEOF_RELOCATION 10
-#define IMAGE_SIZEOF_BASE_RELOCATION 8
-#define IMAGE_SIZEOF_LINENUMBER 6
-#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60
-
-/* Possible Magic values */
-#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x010b
-#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x020b
-#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x0107
-
-#ifdef CONFIG_X86_64
-#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER IMAGE_SIZEOF_NT_OPTIONAL_HEADER64
-#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR64_MAGIC
-#else
-#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER IMAGE_SIZEOF_NT_OPTIONAL_HEADER32
-#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR32_MAGIC
-#endif
-
-/* These are indexes into the DataDirectory array */
-#define IMAGE_FILE_EXPORT_DIRECTORY 0
-#define IMAGE_FILE_IMPORT_DIRECTORY 1
-#define IMAGE_FILE_RESOURCE_DIRECTORY 2
-#define IMAGE_FILE_EXCEPTION_DIRECTORY 3
-#define IMAGE_FILE_SECURITY_DIRECTORY 4
-#define IMAGE_FILE_BASE_RELOCATION_TABLE 5
-#define IMAGE_FILE_DEBUG_DIRECTORY 6
-#define IMAGE_FILE_DESCRIPTION_STRING 7
-#define IMAGE_FILE_MACHINE_VALUE 8 /* Mips */
-#define IMAGE_FILE_THREAD_LOCAL_STORAGE 9
-#define IMAGE_FILE_CALLBACK_DIRECTORY 10
-
-/* Directory Entries, indices into the DataDirectory array */
-
-#define IMAGE_DIRECTORY_ENTRY_EXPORT 0
-#define IMAGE_DIRECTORY_ENTRY_IMPORT 1
-#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2
-#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3
-#define IMAGE_DIRECTORY_ENTRY_SECURITY 4
-#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5
-#define IMAGE_DIRECTORY_ENTRY_DEBUG 6
-#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7
-#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 /* (MIPS GP) */
-#define IMAGE_DIRECTORY_ENTRY_TLS 9
-#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10
-#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11
-#define IMAGE_DIRECTORY_ENTRY_IAT 12 /* Import Address Table */
-#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13
-#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14
-
-/* Subsystem Values */
-
-#define IMAGE_SUBSYSTEM_UNKNOWN 0
-#define IMAGE_SUBSYSTEM_NATIVE 1
-#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 /* Windows GUI subsystem */
-#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 /* Windows character subsystem */
-#define IMAGE_SUBSYSTEM_OS2_CUI 5
-#define IMAGE_SUBSYSTEM_POSIX_CUI 7
-#define IMAGE_SUBSYSTEM_NATIVE_WINDOWS 8 /* native Win9x driver */
-#define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9 /* Windows CE subsystem */
-#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10
-#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11
-#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12
-#define IMAGE_SUBSYSTEM_EFI_ROM 13
-#define IMAGE_SUBSYSTEM_XBOX 14
-
-typedef struct _IMAGE_FILE_HEADER {
- WORD Machine;
- WORD NumberOfSections;
- DWORD TimeDateStamp;
- DWORD PointerToSymbolTable;
- DWORD NumberOfSymbols;
- WORD SizeOfOptionalHeader;
- WORD Characteristics;
-} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
-
-typedef struct _IMAGE_DATA_DIRECTORY {
- DWORD VirtualAddress;
- DWORD Size;
-} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
-
-#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
-
-typedef struct _IMAGE_OPTIONAL_HEADER32 {
-
- /* Standard fields */
-
- WORD Magic;
- BYTE MajorLinkerVersion;
- BYTE MinorLinkerVersion;
- DWORD SizeOfCode;
- DWORD SizeOfInitializedData;
- DWORD SizeOfUninitializedData;
- DWORD AddressOfEntryPoint;
- DWORD BaseOfCode;
- DWORD BaseOfData;
-
- /* NT additional fields */
- DWORD ImageBase;
- DWORD SectionAlignment;
- DWORD FileAlignment;
- WORD MajorOperatingSystemVersion;
- WORD MinorOperatingSystemVersion;
- WORD MajorImageVersion;
- WORD MinorImageVersion;
- WORD MajorSubsystemVersion;
- WORD MinorSubsystemVersion;
- DWORD Win32VersionValue;
- DWORD SizeOfImage;
- DWORD SizeOfHeaders;
- DWORD CheckSum;
- WORD Subsystem;
- WORD DllCharacteristics;
- DWORD SizeOfStackReserve;
- DWORD SizeOfStackCommit;
- DWORD SizeOfHeapReserve;
- DWORD SizeOfHeapCommit;
- DWORD LoaderFlags;
- DWORD NumberOfRvaAndSizes;
- IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
-} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
-
-typedef struct _IMAGE_OPTIONAL_HEADER64 {
-
- /* Standard fields */
-
- WORD Magic;
- BYTE MajorLinkerVersion;
- BYTE MinorLinkerVersion;
- DWORD SizeOfCode;
- DWORD SizeOfInitializedData;
- DWORD SizeOfUninitializedData;
- DWORD AddressOfEntryPoint;
- DWORD BaseOfCode;
-
- /* NT additional fields */
- ULONGLONG ImageBase;
- DWORD SectionAlignment;
- DWORD FileAlignment;
- WORD MajorOperatingSystemVersion;
- WORD MinorOperatingSystemVersion;
- WORD MajorImageVersion;
- WORD MinorImageVersion;
- WORD MajorSubsystemVersion;
- WORD MinorSubsystemVersion;
- DWORD Win32VersionValue;
- DWORD SizeOfImage;
- DWORD SizeOfHeaders;
- DWORD CheckSum;
- WORD Subsystem;
- WORD DllCharacteristics;
- ULONGLONG SizeOfStackReserve;
- ULONGLONG SizeOfStackCommit;
- ULONGLONG SizeOfHeapReserve;
- ULONGLONG SizeOfHeapCommit;
- DWORD LoaderFlags;
- DWORD NumberOfRvaAndSizes;
- IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
-} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;
-
-#ifdef CONFIG_X86_64
-typedef IMAGE_OPTIONAL_HEADER64 IMAGE_OPTIONAL_HEADER;
-typedef PIMAGE_OPTIONAL_HEADER64 PIMAGE_OPTIONAL_HEADER;
-#else
-typedef IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER;
-typedef PIMAGE_OPTIONAL_HEADER32 PIMAGE_OPTIONAL_HEADER;
-#endif
-
-typedef struct _IMAGE_NT_HEADERS32 {
- DWORD Signature; /* "PE"\0\0 */ /* 0x00 */
- IMAGE_FILE_HEADER FileHeader; /* 0x04 */
- IMAGE_OPTIONAL_HEADER32 OptionalHeader; /* 0x18 */
-} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
-
-typedef struct _IMAGE_NT_HEADERS64 {
- DWORD Signature; /* "PE"\0\0 */ /* 0x00 */
- IMAGE_FILE_HEADER FileHeader; /* 0x04 */
- IMAGE_OPTIONAL_HEADER64 OptionalHeader; /* 0x18 */
-} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;
-
-#ifdef CONFIG_X86_64
-typedef IMAGE_NT_HEADERS64 IMAGE_NT_HEADERS;
-typedef PIMAGE_NT_HEADERS64 PIMAGE_NT_HEADERS;
-#else
-typedef IMAGE_NT_HEADERS32 IMAGE_NT_HEADERS;
-typedef PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS;
-#endif
-
-#define IMAGE_SIZEOF_SHORT_NAME 8
-
-typedef struct _IMAGE_SECTION_HEADER {
- BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
- union {
- DWORD PhysicalAddress;
- DWORD VirtualSize;
- } Misc;
- DWORD VirtualAddress;
- DWORD SizeOfRawData;
- DWORD PointerToRawData;
- DWORD PointerToRelocations;
- DWORD PointerToLinenumbers;
- WORD NumberOfRelocations;
- WORD NumberOfLinenumbers;
- DWORD Characteristics;
-} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
-
-#define IMAGE_SIZEOF_SECTION_HEADER 40
-
-#define IMAGE_FIRST_SECTION(ntheader) \
-((PIMAGE_SECTION_HEADER)((LPBYTE)&((PIMAGE_NT_HEADERS)(ntheader))->OptionalHeader + \
-((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader))
-
-/* These defines are for the Characteristics bitfield. */
-/* #define IMAGE_SCN_TYPE_REG 0x00000000 - Reserved */
-/* #define IMAGE_SCN_TYPE_DSECT 0x00000001 - Reserved */
-/* #define IMAGE_SCN_TYPE_NOLOAD 0x00000002 - Reserved */
-/* #define IMAGE_SCN_TYPE_GROUP 0x00000004 - Reserved */
-#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* Reserved */
-/* #define IMAGE_SCN_TYPE_COPY 0x00000010 - Reserved */
-
-#define IMAGE_SCN_CNT_CODE 0x00000020
-#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
-#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080
-
-#define IMAGE_SCN_LNK_OTHER 0x00000100
-#define IMAGE_SCN_LNK_INFO 0x00000200
-/* #define IMAGE_SCN_TYPE_OVER 0x00000400 - Reserved */
-#define IMAGE_SCN_LNK_REMOVE 0x00000800
-#define IMAGE_SCN_LNK_COMDAT 0x00001000
-
-/* 0x00002000 - Reserved */
-/* #define IMAGE_SCN_MEM_PROTECTED 0x00004000 - Obsolete */
-#define IMAGE_SCN_MEM_FARDATA 0x00008000
-
-/* #define IMAGE_SCN_MEM_SYSHEAP 0x00010000 - Obsolete */
-#define IMAGE_SCN_MEM_PURGEABLE 0x00020000
-#define IMAGE_SCN_MEM_16BIT 0x00020000
-#define IMAGE_SCN_MEM_LOCKED 0x00040000
-#define IMAGE_SCN_MEM_PRELOAD 0x00080000
-
-#define IMAGE_SCN_ALIGN_1BYTES 0x00100000
-#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
-#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
-#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
-#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 /* Default */
-#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
-#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
-#define IMAGE_SCN_ALIGN_128BYTES 0x00800000
-#define IMAGE_SCN_ALIGN_256BYTES 0x00900000
-#define IMAGE_SCN_ALIGN_512BYTES 0x00A00000
-#define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000
-#define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000
-#define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000
-#define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000
-/* 0x00F00000 - Unused */
-#define IMAGE_SCN_ALIGN_MASK 0x00F00000
-
-#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000
-
-
-#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
-#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000
-#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000
-#define IMAGE_SCN_MEM_SHARED 0x10000000
-#define IMAGE_SCN_MEM_EXECUTE 0x20000000
-#define IMAGE_SCN_MEM_READ 0x40000000
-#define IMAGE_SCN_MEM_WRITE 0x80000000
-
-typedef struct _IMAGE_SYMBOL {
- union {
- BYTE ShortName[8];
- struct {
- DWORD Short;
- DWORD Long;
- } Name;
- DWORD LongName[2];
- } N;
- DWORD Value;
- SHORT SectionNumber;
- WORD Type;
- BYTE StorageClass;
- BYTE NumberOfAuxSymbols;
-} IMAGE_SYMBOL;
-typedef IMAGE_SYMBOL *PIMAGE_SYMBOL;
-
-#define IMAGE_SIZEOF_SYMBOL 18
-
-typedef struct _IMAGE_LINENUMBER {
- union {
- DWORD SymbolTableIndex;
- DWORD VirtualAddress;
- } Type;
- WORD Linenumber;
-} IMAGE_LINENUMBER;
-typedef IMAGE_LINENUMBER *PIMAGE_LINENUMBER;
-
-#define IMAGE_SIZEOF_LINENUMBER 6
-
-typedef union _IMAGE_AUX_SYMBOL {
- struct {
- DWORD TagIndex;
- union {
- struct {
- WORD Linenumber;
- WORD Size;
- } LnSz;
- DWORD TotalSize;
- } Misc;
- union {
- struct {
- DWORD PointerToLinenumber;
- DWORD PointerToNextFunction;
- } Function;
- struct {
- WORD Dimension[4];
- } Array;
- } FcnAry;
- WORD TvIndex;
- } Sym;
- struct {
- BYTE Name[IMAGE_SIZEOF_SYMBOL];
- } File;
- struct {
- DWORD Length;
- WORD NumberOfRelocations;
- WORD NumberOfLinenumbers;
- DWORD CheckSum;
- SHORT Number;
- BYTE Selection;
- } Section;
-} IMAGE_AUX_SYMBOL;
-typedef IMAGE_AUX_SYMBOL *PIMAGE_AUX_SYMBOL;
-
-#define IMAGE_SIZEOF_AUX_SYMBOL 18
-
-#define IMAGE_SYM_UNDEFINED (SHORT)0
-#define IMAGE_SYM_ABSOLUTE (SHORT)-1
-#define IMAGE_SYM_DEBUG (SHORT)-2
-
-#define IMAGE_SYM_TYPE_NULL 0x0000
-#define IMAGE_SYM_TYPE_VOID 0x0001
-#define IMAGE_SYM_TYPE_CHAR 0x0002
-#define IMAGE_SYM_TYPE_SHORT 0x0003
-#define IMAGE_SYM_TYPE_INT 0x0004
-#define IMAGE_SYM_TYPE_LONG 0x0005
-#define IMAGE_SYM_TYPE_FLOAT 0x0006
-#define IMAGE_SYM_TYPE_DOUBLE 0x0007
-#define IMAGE_SYM_TYPE_STRUCT 0x0008
-#define IMAGE_SYM_TYPE_UNION 0x0009
-#define IMAGE_SYM_TYPE_ENUM 0x000A
-#define IMAGE_SYM_TYPE_MOE 0x000B
-#define IMAGE_SYM_TYPE_BYTE 0x000C
-#define IMAGE_SYM_TYPE_WORD 0x000D
-#define IMAGE_SYM_TYPE_UINT 0x000E
-#define IMAGE_SYM_TYPE_DWORD 0x000F
-#define IMAGE_SYM_TYPE_PCODE 0x8000
-
-#define IMAGE_SYM_DTYPE_NULL 0
-#define IMAGE_SYM_DTYPE_POINTER 1
-#define IMAGE_SYM_DTYPE_FUNCTION 2
-#define IMAGE_SYM_DTYPE_ARRAY 3
-
-#define IMAGE_SYM_CLASS_END_OF_FUNCTION (BYTE )-1
-#define IMAGE_SYM_CLASS_NULL 0x0000
-#define IMAGE_SYM_CLASS_AUTOMATIC 0x0001
-#define IMAGE_SYM_CLASS_EXTERNAL 0x0002
-#define IMAGE_SYM_CLASS_STATIC 0x0003
-#define IMAGE_SYM_CLASS_REGISTER 0x0004
-#define IMAGE_SYM_CLASS_EXTERNAL_DEF 0x0005
-#define IMAGE_SYM_CLASS_LABEL 0x0006
-#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 0x0007
-#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 0x0008
-#define IMAGE_SYM_CLASS_ARGUMENT 0x0009
-#define IMAGE_SYM_CLASS_STRUCT_TAG 0x000A
-#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 0x000B
-#define IMAGE_SYM_CLASS_UNION_TAG 0x000C
-#define IMAGE_SYM_CLASS_TYPE_DEFINITION 0x000D
-#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 0x000E
-#define IMAGE_SYM_CLASS_ENUM_TAG 0x000F
-#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 0x0010
-#define IMAGE_SYM_CLASS_REGISTER_PARAM 0x0011
-#define IMAGE_SYM_CLASS_BIT_FIELD 0x0012
-
-#define IMAGE_SYM_CLASS_FAR_EXTERNAL 0x0044
-#define IMAGE_SYM_CLASS_BLOCK 0x0064
-#define IMAGE_SYM_CLASS_FUNCTION 0x0065
-#define IMAGE_SYM_CLASS_END_OF_STRUCT 0x0066
-#define IMAGE_SYM_CLASS_FILE 0x0067
-#define IMAGE_SYM_CLASS_SECTION 0x0068
-#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 0x0069
-
-#define N_BTMASK 0x000F
-#define N_TMASK 0x0030
-#define N_TMASK1 0x00C0
-#define N_TMASK2 0x00F0
-#define N_BTSHFT 4
-#define N_TSHIFT 2
-
-#define BTYPE(x) ((x) & N_BTMASK)
-
-#ifndef ISPTR
-#define ISPTR(x) (((x) & N_TMASK) == (IMAGE_SYM_DTYPE_POINTER << N_BTSHFT))
-#endif
-
-#ifndef ISFCN
-#define ISFCN(x) (((x) & N_TMASK) == (IMAGE_SYM_DTYPE_FUNCTION << N_BTSHFT))
-#endif
-
-#ifndef ISARY
-#define ISARY(x) (((x) & N_TMASK) == (IMAGE_SYM_DTYPE_ARRAY << N_BTSHFT))
-#endif
-
-#ifndef ISTAG
-#define ISTAG(x) ((x)==IMAGE_SYM_CLASS_STRUCT_TAG || (x)==IMAGE_SYM_CLASS_UNION_TAG || (x)==IMAGE_SYM_CLASS_ENUM_TAG)
-#endif
-
-#ifndef INCREF
-#define INCREF(x) ((((x)&~N_BTMASK)<<N_TSHIFT)|(IMAGE_SYM_DTYPE_POINTER<<N_BTSHFT)|((x)&N_BTMASK))
-#endif
-#ifndef DECREF
-#define DECREF(x) ((((x)>>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK))
-#endif
-
-#define IMAGE_COMDAT_SELECT_NODUPLICATES 1
-#define IMAGE_COMDAT_SELECT_ANY 2
-#define IMAGE_COMDAT_SELECT_SAME_SIZE 3
-#define IMAGE_COMDAT_SELECT_EXACT_MATCH 4
-#define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5
-#define IMAGE_COMDAT_SELECT_LARGEST 6
-#define IMAGE_COMDAT_SELECT_NEWEST 7
-
-#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1
-#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2
-#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3
-
-/* Export module directory */
-
-typedef struct _IMAGE_EXPORT_DIRECTORY {
- DWORD Characteristics;
- DWORD TimeDateStamp;
- WORD MajorVersion;
- WORD MinorVersion;
- DWORD Name;
- DWORD Base;
- DWORD NumberOfFunctions;
- DWORD NumberOfNames;
- DWORD AddressOfFunctions;
- DWORD AddressOfNames;
- DWORD AddressOfNameOrdinals;
-} IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY;
-
-/* Import name entry */
-typedef struct _IMAGE_IMPORT_BY_NAME {
- WORD Hint;
- BYTE Name[1];
-} IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME;
-
-/* Import thunk */
-typedef struct _IMAGE_THUNK_DATA32 {
- union {
- DWORD ForwarderString;
- DWORD Function;
- DWORD Ordinal;
- DWORD AddressOfData;
- } u1;
-} IMAGE_THUNK_DATA32,*PIMAGE_THUNK_DATA32;
-
-typedef struct _IMAGE_THUNK_DATA64 {
- union {
- ULONGLONG ForwarderString;
- ULONGLONG Function;
- ULONGLONG Ordinal;
- ULONGLONG AddressOfData;
- } u1;
-} IMAGE_THUNK_DATA64,*PIMAGE_THUNK_DATA64;
-
-#ifdef CONFIG_X86_64
-typedef IMAGE_THUNK_DATA32 IMAGE_THUNK_DATA;
-typedef PIMAGE_THUNK_DATA32 PIMAGE_THUNK_DATA;
-#else
-typedef IMAGE_THUNK_DATA64 IMAGE_THUNK_DATA;
-typedef PIMAGE_THUNK_DATA64 PIMAGE_THUNK_DATA;
-#endif
-
-/* Import module directory */
-
-typedef struct __packed _IMAGE_IMPORT_DESCRIPTOR {
- union {
- DWORD Characteristics; /* 0 for terminating null
- * import descriptor */
- DWORD OriginalFirstThunk; /* RVA to original unbound
- * IAT */
- } u;
- DWORD TimeDateStamp; /* 0 if not bound,
- * -1 if bound, and real date\time stamp
- * in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT
- * (new BIND)
- * otherwise date/time stamp of DLL bound to
- * (Old BIND)
- */
- DWORD ForwarderChain; /* -1 if no forwarders */
- DWORD Name;
- /* RVA to IAT (if bound this IAT has actual addresses) */
- DWORD FirstThunk;
-} IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR;
-
-#define IMAGE_ORDINAL_FLAG32 0x80000000
-#define IMAGE_ORDINAL_FLAG64 0x8000000000000000UL
-#define IMAGE_SNAP_BY_ORDINAL32(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG32) != 0)
-#define IMAGE_SNAP_BY_ORDINAL64(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG64) != 0)
-#define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff)
-
-#ifdef CONFIG_X86_64
-#define IMAGE_ORDINAL_FLAG IMAGE_ORDINAL_FLAG64
-#define IMAGE_SNAP_BY_ORDINAL IMAGE_SNAP_BY_ORDINAL64
-#else
-#define IMAGE_ORDINAL_FLAG IMAGE_ORDINAL_FLAG32
-#define IMAGE_SNAP_BY_ORDINAL IMAGE_SNAP_BY_ORDINAL32
-#endif
-
-typedef struct _IMAGE_BOUND_IMPORT_DESCRIPTOR
-{
- DWORD TimeDateStamp;
- WORD OffsetModuleName;
- WORD NumberOfModuleForwarderRefs;
-/* Array of zero or more IMAGE_BOUND_FORWARDER_REF follows */
-} IMAGE_BOUND_IMPORT_DESCRIPTOR, *PIMAGE_BOUND_IMPORT_DESCRIPTOR;
-
-typedef struct _IMAGE_BOUND_FORWARDER_REF
-{
- DWORD TimeDateStamp;
- WORD OffsetModuleName;
- WORD Reserved;
-} IMAGE_BOUND_FORWARDER_REF, *PIMAGE_BOUND_FORWARDER_REF;
-
-typedef struct _IMAGE_BASE_RELOCATION
-{
- DWORD VirtualAddress;
- DWORD SizeOfBlock;
- WORD TypeOffset[0];
-} IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION;
-
-typedef struct _IMAGE_RELOCATION
-{
- union {
- DWORD VirtualAddress;
- DWORD RelocCount;
- } DUMMYUNIONNAME;
- DWORD SymbolTableIndex;
- WORD Type;
-} IMAGE_RELOCATION, *PIMAGE_RELOCATION;
-
-#define IMAGE_SIZEOF_RELOCATION 10
-
-/* generic relocation types */
-#define IMAGE_REL_BASED_ABSOLUTE 0
-#define IMAGE_REL_BASED_HIGH 1
-#define IMAGE_REL_BASED_LOW 2
-#define IMAGE_REL_BASED_HIGHLOW 3
-#define IMAGE_REL_BASED_HIGHADJ 4
-#define IMAGE_REL_BASED_MIPS_JMPADDR 5
-#define IMAGE_REL_BASED_SECTION 6
-#define IMAGE_REL_BASED_REL 7
-#define IMAGE_REL_BASED_MIPS_JMPADDR16 9
-#define IMAGE_REL_BASED_IA64_IMM64 9 /* yes, 9 too */
-#define IMAGE_REL_BASED_DIR64 10
-#define IMAGE_REL_BASED_HIGH3ADJ 11
-
-/* I386 relocation types */
-#define IMAGE_REL_I386_ABSOLUTE 0
-#define IMAGE_REL_I386_DIR16 1
-#define IMAGE_REL_I386_REL16 2
-#define IMAGE_REL_I386_DIR32 6
-#define IMAGE_REL_I386_DIR32NB 7
-#define IMAGE_REL_I386_SEG12 9
-#define IMAGE_REL_I386_SECTION 10
-#define IMAGE_REL_I386_SECREL 11
-#define IMAGE_REL_I386_REL32 20
-
-/* MIPS relocation types */
-#define IMAGE_REL_MIPS_ABSOLUTE 0x0000
-#define IMAGE_REL_MIPS_REFHALF 0x0001
-#define IMAGE_REL_MIPS_REFWORD 0x0002
-#define IMAGE_REL_MIPS_JMPADDR 0x0003
-#define IMAGE_REL_MIPS_REFHI 0x0004
-#define IMAGE_REL_MIPS_REFLO 0x0005
-#define IMAGE_REL_MIPS_GPREL 0x0006
-#define IMAGE_REL_MIPS_LITERAL 0x0007
-#define IMAGE_REL_MIPS_SECTION 0x000A
-#define IMAGE_REL_MIPS_SECREL 0x000B
-#define IMAGE_REL_MIPS_SECRELLO 0x000C
-#define IMAGE_REL_MIPS_SECRELHI 0x000D
-#define IMAGE_REL_MIPS_JMPADDR16 0x0010
-#define IMAGE_REL_MIPS_REFWORDNB 0x0022
-#define IMAGE_REL_MIPS_PAIR 0x0025
-
-/* ALPHA relocation types */
-#define IMAGE_REL_ALPHA_ABSOLUTE 0x0000
-#define IMAGE_REL_ALPHA_REFLONG 0x0001
-#define IMAGE_REL_ALPHA_REFQUAD 0x0002
-#define IMAGE_REL_ALPHA_GPREL 0x0003
-#define IMAGE_REL_ALPHA_LITERAL 0x0004
-#define IMAGE_REL_ALPHA_LITUSE 0x0005
-#define IMAGE_REL_ALPHA_GPDISP 0x0006
-#define IMAGE_REL_ALPHA_BRADDR 0x0007
-#define IMAGE_REL_ALPHA_HINT 0x0008
-#define IMAGE_REL_ALPHA_INLINE_REFLONG 0x0009
-#define IMAGE_REL_ALPHA_REFHI 0x000A
-#define IMAGE_REL_ALPHA_REFLO 0x000B
-#define IMAGE_REL_ALPHA_PAIR 0x000C
-#define IMAGE_REL_ALPHA_MATCH 0x000D
-#define IMAGE_REL_ALPHA_SECTION 0x000E
-#define IMAGE_REL_ALPHA_SECREL 0x000F
-#define IMAGE_REL_ALPHA_REFLONGNB 0x0010
-#define IMAGE_REL_ALPHA_SECRELLO 0x0011
-#define IMAGE_REL_ALPHA_SECRELHI 0x0012
-#define IMAGE_REL_ALPHA_REFQ3 0x0013
-#define IMAGE_REL_ALPHA_REFQ2 0x0014
-#define IMAGE_REL_ALPHA_REFQ1 0x0015
-#define IMAGE_REL_ALPHA_GPRELLO 0x0016
-#define IMAGE_REL_ALPHA_GPRELHI 0x0017
-
-/* PowerPC relocation types */
-#define IMAGE_REL_PPC_ABSOLUTE 0x0000
-#define IMAGE_REL_PPC_ADDR64 0x0001
-#define IMAGE_REL_PPC_ADDR 0x0002
-#define IMAGE_REL_PPC_ADDR24 0x0003
-#define IMAGE_REL_PPC_ADDR16 0x0004
-#define IMAGE_REL_PPC_ADDR14 0x0005
-#define IMAGE_REL_PPC_REL24 0x0006
-#define IMAGE_REL_PPC_REL14 0x0007
-#define IMAGE_REL_PPC_TOCREL16 0x0008
-#define IMAGE_REL_PPC_TOCREL14 0x0009
-#define IMAGE_REL_PPC_ADDR32NB 0x000A
-#define IMAGE_REL_PPC_SECREL 0x000B
-#define IMAGE_REL_PPC_SECTION 0x000C
-#define IMAGE_REL_PPC_IFGLUE 0x000D
-#define IMAGE_REL_PPC_IMGLUE 0x000E
-#define IMAGE_REL_PPC_SECREL16 0x000F
-#define IMAGE_REL_PPC_REFHI 0x0010
-#define IMAGE_REL_PPC_REFLO 0x0011
-#define IMAGE_REL_PPC_PAIR 0x0012
-#define IMAGE_REL_PPC_SECRELLO 0x0013
-#define IMAGE_REL_PPC_SECRELHI 0x0014
-#define IMAGE_REL_PPC_GPREL 0x0015
-#define IMAGE_REL_PPC_TYPEMASK 0x00FF
-/* modifier bits */
-#define IMAGE_REL_PPC_NEG 0x0100
-#define IMAGE_REL_PPC_BRTAKEN 0x0200
-#define IMAGE_REL_PPC_BRNTAKEN 0x0400
-#define IMAGE_REL_PPC_TOCDEFN 0x0800
-
-/* SH3 ? relocation type */
-#define IMAGE_REL_SH3_ABSOLUTE 0x0000
-#define IMAGE_REL_SH3_DIRECT16 0x0001
-#define IMAGE_REL_SH3_DIRECT 0x0002
-#define IMAGE_REL_SH3_DIRECT8 0x0003
-#define IMAGE_REL_SH3_DIRECT8_WORD 0x0004
-#define IMAGE_REL_SH3_DIRECT8_LONG 0x0005
-#define IMAGE_REL_SH3_DIRECT4 0x0006
-#define IMAGE_REL_SH3_DIRECT4_WORD 0x0007
-#define IMAGE_REL_SH3_DIRECT4_LONG 0x0008
-#define IMAGE_REL_SH3_PCREL8_WORD 0x0009
-#define IMAGE_REL_SH3_PCREL8_LONG 0x000A
-#define IMAGE_REL_SH3_PCREL12_WORD 0x000B
-#define IMAGE_REL_SH3_STARTOF_SECTION 0x000C
-#define IMAGE_REL_SH3_SIZEOF_SECTION 0x000D
-#define IMAGE_REL_SH3_SECTION 0x000E
-#define IMAGE_REL_SH3_SECREL 0x000F
-#define IMAGE_REL_SH3_DIRECT32_NB 0x0010
-
-/* ARM (Archimedes?) relocation types */
-#define IMAGE_REL_ARM_ABSOLUTE 0x0000
-#define IMAGE_REL_ARM_ADDR 0x0001
-#define IMAGE_REL_ARM_ADDR32NB 0x0002
-#define IMAGE_REL_ARM_BRANCH24 0x0003
-#define IMAGE_REL_ARM_BRANCH11 0x0004
-#define IMAGE_REL_ARM_SECTION 0x000E
-#define IMAGE_REL_ARM_SECREL 0x000F
-
-/* IA64 relocation types */
-#define IMAGE_REL_IA64_ABSOLUTE 0x0000
-#define IMAGE_REL_IA64_IMM14 0x0001
-#define IMAGE_REL_IA64_IMM22 0x0002
-#define IMAGE_REL_IA64_IMM64 0x0003
-#define IMAGE_REL_IA64_DIR 0x0004
-#define IMAGE_REL_IA64_DIR64 0x0005
-#define IMAGE_REL_IA64_PCREL21B 0x0006
-#define IMAGE_REL_IA64_PCREL21M 0x0007
-#define IMAGE_REL_IA64_PCREL21F 0x0008
-#define IMAGE_REL_IA64_GPREL22 0x0009
-#define IMAGE_REL_IA64_LTOFF22 0x000A
-#define IMAGE_REL_IA64_SECTION 0x000B
-#define IMAGE_REL_IA64_SECREL22 0x000C
-#define IMAGE_REL_IA64_SECREL64I 0x000D
-#define IMAGE_REL_IA64_SECREL 0x000E
-#define IMAGE_REL_IA64_LTOFF64 0x000F
-#define IMAGE_REL_IA64_DIR32NB 0x0010
-#define IMAGE_REL_IA64_RESERVED_11 0x0011
-#define IMAGE_REL_IA64_RESERVED_12 0x0012
-#define IMAGE_REL_IA64_RESERVED_13 0x0013
-#define IMAGE_REL_IA64_RESERVED_14 0x0014
-#define IMAGE_REL_IA64_RESERVED_15 0x0015
-#define IMAGE_REL_IA64_RESERVED_16 0x0016
-#define IMAGE_REL_IA64_ADDEND 0x001F
-
-/* archive format */
-
-#define IMAGE_ARCHIVE_START_SIZE 8
-#define IMAGE_ARCHIVE_START "!<arch>\n"
-#define IMAGE_ARCHIVE_END "`\n"
-#define IMAGE_ARCHIVE_PAD "\n"
-#define IMAGE_ARCHIVE_LINKER_MEMBER "/ "
-#define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// "
-
-typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER
-{
- BYTE Name[16];
- BYTE Date[12];
- BYTE UserID[6];
- BYTE GroupID[6];
- BYTE Mode[8];
- BYTE Size[10];
- BYTE EndHeader[2];
-} IMAGE_ARCHIVE_MEMBER_HEADER, *PIMAGE_ARCHIVE_MEMBER_HEADER;
-
-#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60
-
-/*
- * Resource directory stuff
- */
-typedef struct _IMAGE_RESOURCE_DIRECTORY {
- DWORD Characteristics;
- DWORD TimeDateStamp;
- WORD MajorVersion;
- WORD MinorVersion;
- WORD NumberOfNamedEntries;
- WORD NumberOfIdEntries;
- /* IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[]; */
-} IMAGE_RESOURCE_DIRECTORY,*PIMAGE_RESOURCE_DIRECTORY;
-
-#define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000
-#define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000
-
-typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {
- union {
- struct {
-#ifdef BITFIELDS_BIGENDIAN
- unsigned NameIsString:1;
- unsigned NameOffset:31;
-#else
- unsigned NameOffset:31;
- unsigned NameIsString:1;
-#endif
- } DUMMYSTRUCTNAME1;
- DWORD Name;
- struct {
-#ifdef WORDS_BIGENDIAN
- WORD __pad;
- WORD Id;
-#else
- WORD Id;
- WORD __pad;
-#endif
- } DUMMYSTRUCTNAME2;
- } DUMMYUNIONNAME1;
- union {
- DWORD OffsetToData;
- struct {
-#ifdef BITFIELDS_BIGENDIAN
- unsigned DataIsDirectory:1;
- unsigned OffsetToDirectory:31;
-#else
- unsigned OffsetToDirectory:31;
- unsigned DataIsDirectory:1;
-#endif
- } DUMMYSTRUCTNAME3;
- } DUMMYUNIONNAME2;
-} IMAGE_RESOURCE_DIRECTORY_ENTRY,*PIMAGE_RESOURCE_DIRECTORY_ENTRY;
-
-
-typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING {
- WORD Length;
- CHAR NameString[ 1 ];
-} IMAGE_RESOURCE_DIRECTORY_STRING,*PIMAGE_RESOURCE_DIRECTORY_STRING;
-
+++ /dev/null
-/*
- * Copyright (C) 2005 Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include "usb.h"
-#include "pnp.h"
-#include "wrapndis.h"
-#include "loader.h"
-
-/* Functions callable from the NDIS driver */
-wstdcall NTSTATUS pdoDispatchDeviceControl(struct device_object *pdo,
- struct irp *irp);
-wstdcall NTSTATUS pdoDispatchPnp(struct device_object *pdo, struct irp *irp);
-wstdcall NTSTATUS pdoDispatchPower(struct device_object *pdo, struct irp *irp);
-
-static NTSTATUS start_pdo(struct device_object *pdo)
-{
- int i, ret, count, resources_size;
- struct wrap_device *wd;
- struct pci_dev *pdev;
- struct cm_partial_resource_descriptor *entry;
- struct cm_partial_resource_list *partial_resource_list;
-
- ENTER1("%p, %p", pdo, pdo->reserved);
- wd = pdo->reserved;
- if (ntoskernel_init_device(wd))
- EXIT1(return STATUS_FAILURE);
- if (wrap_is_usb_bus(wd->dev_bus)) {
-#ifdef ENABLE_USB
- if (usb_init_device(wd)) {
- ntoskernel_exit_device(wd);
- EXIT1(return STATUS_FAILURE);
- }
-#endif
- EXIT1(return STATUS_SUCCESS);
- }
- if (!wrap_is_pci_bus(wd->dev_bus))
- EXIT1(return STATUS_SUCCESS);
- pdev = wd->pci.pdev;
- ret = pci_enable_device(pdev);
- if (ret) {
- ERROR("couldn't enable PCI device: %x", ret);
- return STATUS_FAILURE;
- }
- ret = pci_request_regions(pdev, DRIVER_NAME);
- if (ret) {
- ERROR("couldn't request PCI regions: %x", ret);
- goto err_enable;
- }
- pci_set_power_state(pdev, PCI_D0);
-#ifdef CONFIG_X86_64
- /* 64-bit broadcom driver doesn't work if DMA is allocated
- * from over 1GB */
- if (wd->vendor == 0x14e4) {
- if (pci_set_dma_mask(pdev, DMA_BIT_MASK(30)) ||
- pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(30)))
- WARNING("couldn't set DMA mask; this driver "
- "may not work with more than 1GB RAM");
- }
-#endif
- /* IRQ resource entry is filled in from pdev, instead of
- * pci_resource macros */
- for (i = count = 0; pci_resource_start(pdev, i); i++)
- if ((pci_resource_flags(pdev, i) & IORESOURCE_MEM) ||
- (pci_resource_flags(pdev, i) & IORESOURCE_IO))
- count++;
- /* space for entry for IRQ is already in
- * cm_partial_resource_list */
- resources_size = sizeof(struct cm_resource_list) +
- sizeof(struct cm_partial_resource_descriptor) * count;
- TRACE2("resources: %d, %d", count, resources_size);
- wd->resource_list = kzalloc(resources_size, GFP_KERNEL);
- if (!wd->resource_list) {
- WARNING("couldn't allocate memory");
- goto err_regions;
- }
- wd->resource_list->count = 1;
- wd->resource_list->list[0].interface_type = PCIBus;
- /* bus_number is not used by WDM drivers */
- wd->resource_list->list[0].bus_number = pdev->bus->number;
-
- partial_resource_list =
- &wd->resource_list->list->partial_resource_list;
- partial_resource_list->version = 1;
- partial_resource_list->revision = 1;
- partial_resource_list->count = count + 1;
-
- for (i = count = 0; pci_resource_start(pdev, i); i++) {
- entry = &partial_resource_list->partial_descriptors[count];
- TRACE2("%d", count);
- if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) {
- entry->type = CmResourceTypeMemory;
- entry->flags = CM_RESOURCE_MEMORY_READ_WRITE;
- entry->share = CmResourceShareDeviceExclusive;
- } else if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
- entry->type = CmResourceTypePort;
- entry->flags = CM_RESOURCE_PORT_IO;
- entry->share = CmResourceShareDeviceExclusive;
-#if 0
- } else if (pci_resource_flags(pdev, i) & IORESOURCE_DMA) {
- /* it looks like no driver uses this resource */
- typeof(pci_resource_flags(pdev, 0)) flags;
- entry->type = CmResourceTypeDma;
- flags = pci_resource_flags(pdev, i);
- if (flags & IORESOURCE_DMA_TYPEA)
- entry->flags |= CM_RESOURCE_DMA_TYPE_A;
- else if (flags & IORESOURCE_DMA_TYPEB)
- entry->flags |= CM_RESOURCE_DMA_TYPE_B;
- else if (flags & IORESOURCE_DMA_TYPEF)
- entry->flags |= CM_RESOURCE_DMA_TYPE_F;
- if (flags & IORESOURCE_DMA_8BIT)
- entry->flags |= CM_RESOURCE_DMA_8;
- else if (flags & IORESOURCE_DMA_16BIT)
- entry->flags |= CM_RESOURCE_DMA_16;
- /* what about 32bit DMA? */
- else if (flags & IORESOURCE_DMA_8AND16BIT)
- entry->flags |= CM_RESOURCE_DMA_8_AND_16;
- if (flags & IORESOURCE_DMA_MASTER)
- entry->flags |= CM_RESOURCE_DMA_BUS_MASTER;
- entry->u.dma.channel = pci_resource_start(pdev, i);
- /* what should this be? */
- entry->u.dma.port = 1;
-#endif
- } else
- continue;
- /* TODO: Add other resource types? */
- entry->u.generic.start =
- (ULONG_PTR)pci_resource_start(pdev, i);
- entry->u.generic.length = pci_resource_len(pdev, i);
- count++;
- }
-
- /* put IRQ resource at the end */
- entry = &partial_resource_list->partial_descriptors[count++];
- entry->type = CmResourceTypeInterrupt;
- entry->flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
- /* we assume all devices use shared IRQ */
- entry->share = CmResourceShareShared;
- /* as per documentation, interrupt level should be DIRQL, but
- * examples from DDK as well some drivers, such as AR5211,
- * RT8180L use interrupt level as interrupt vector also in
- * NdisMRegisterInterrupt */
- entry->u.interrupt.level = pdev->irq;
- entry->u.interrupt.vector = pdev->irq;
- entry->u.interrupt.affinity = -1;
-
- TRACE2("resource list count %d, irq: %d",
- partial_resource_list->count, pdev->irq);
- pci_set_drvdata(pdev, wd);
- EXIT1(return STATUS_SUCCESS);
-err_regions:
- pci_release_regions(pdev);
-err_enable:
- pci_disable_device(pdev);
- wd->pci.pdev = NULL;
- wd->pdo = NULL;
- EXIT1(return STATUS_FAILURE);
-}
-
-static void remove_pdo(struct device_object *pdo)
-{
- struct wrap_device *wd = pdo->reserved;
-
- ntoskernel_exit_device(wd);
- if (wrap_is_pci_bus(wd->dev_bus)) {
- struct pci_dev *pdev = wd->pci.pdev;
- pci_release_regions(pdev);
- pci_disable_device(pdev);
- wd->pci.pdev = NULL;
- pci_set_drvdata(pdev, NULL);
- } else if (wrap_is_usb_bus(wd->dev_bus)) {
-#ifdef ENABLE_USB
- usb_exit_device(wd);
-#endif
- }
- if (wd->resource_list)
- kfree(wd->resource_list);
- wd->resource_list = NULL;
- return;
-}
-
-static NTSTATUS IoSendIrpTopDev(struct device_object *dev_obj, ULONG major_fn,
- ULONG minor_fn, struct io_stack_location *sl)
-{
- NTSTATUS status;
- struct nt_event event;
- struct irp *irp;
- struct io_stack_location *irp_sl;
- struct device_object *top_dev = IoGetAttachedDeviceReference(dev_obj);
-
- KeInitializeEvent(&event, NotificationEvent, FALSE);
- irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, top_dev, NULL, 0, NULL,
- &event, NULL);
- irp->io_status.status = STATUS_NOT_IMPLEMENTED;
- irp->io_status.info = 0;
- irp_sl = IoGetNextIrpStackLocation(irp);
- if (sl)
- memcpy(irp_sl, sl, sizeof(*irp_sl));
- irp_sl->major_fn = major_fn;
- irp_sl->minor_fn = minor_fn;
- status = IoCallDriver(top_dev, irp);
- if (status == STATUS_PENDING) {
- KeWaitForSingleObject(&event, Executive, KernelMode,
- FALSE, NULL);
- status = irp->io_status.status;
- }
- ObDereferenceObject(top_dev);
- return status;
-}
-
-wstdcall NTSTATUS pdoDispatchDeviceControl(struct device_object *pdo,
- struct irp *irp)
-{
- struct io_stack_location *irp_sl;
- NTSTATUS status;
-
- DUMP_IRP(irp);
- irp_sl = IoGetCurrentIrpStackLocation(irp);
-#ifdef ENABLE_USB
- status = wrap_submit_irp(pdo, irp);
- IOTRACE("status: %08X", status);
- if (status != STATUS_PENDING)
- IoCompleteRequest(irp, IO_NO_INCREMENT);
-#else
- status = irp->io_status.status = STATUS_NOT_IMPLEMENTED;
- IoCompleteRequest(irp, IO_NO_INCREMENT);
-#endif
- IOEXIT(return status);
-}
-WIN_FUNC_DECL(pdoDispatchDeviceControl,2)
-
-wstdcall NTSTATUS pdoDispatchPnp(struct device_object *pdo, struct irp *irp)
-{
- struct io_stack_location *irp_sl;
- struct wrap_device *wd;
- NTSTATUS status;
-#ifdef ENABLE_USB
- struct usbd_bus_interface_usbdi *usb_intf;
-#endif
-
- irp_sl = IoGetCurrentIrpStackLocation(irp);
- TRACE2("%p %d:%d", pdo, irp_sl->major_fn, irp_sl->minor_fn);
- wd = pdo->reserved;
- switch (irp_sl->minor_fn) {
- case IRP_MN_START_DEVICE:
- status = start_pdo(pdo);
- break;
- case IRP_MN_QUERY_STOP_DEVICE:
- case IRP_MN_STOP_DEVICE:
- case IRP_MN_QUERY_REMOVE_DEVICE:
- status = STATUS_SUCCESS;
- break;
- case IRP_MN_REMOVE_DEVICE:
- remove_pdo(pdo);
- status = STATUS_SUCCESS;
- break;
- case IRP_MN_QUERY_INTERFACE:
-#ifdef ENABLE_USB
- if (!wrap_is_usb_bus(wd->dev_bus)) {
- status = STATUS_NOT_IMPLEMENTED;
- break;
- }
- TRACE2("type: %x, size: %d, version: %d",
- irp_sl->params.query_intf.type->data1,
- irp_sl->params.query_intf.size,
- irp_sl->params.query_intf.version);
- usb_intf = (struct usbd_bus_interface_usbdi *)
- irp_sl->params.query_intf.intf;
- usb_intf->Context = wd;
- usb_intf->InterfaceReference = USBD_InterfaceReference;
- usb_intf->InterfaceDereference = USBD_InterfaceDereference;
- usb_intf->GetUSBDIVersion = USBD_InterfaceGetUSBDIVersion;
- usb_intf->QueryBusTime = USBD_InterfaceQueryBusTime;
- usb_intf->SubmitIsoOutUrb = USBD_InterfaceSubmitIsoOutUrb;
- usb_intf->QueryBusInformation =
- USBD_InterfaceQueryBusInformation;
- if (irp_sl->params.query_intf.version >=
- USB_BUSIF_USBDI_VERSION_1)
- usb_intf->IsDeviceHighSpeed =
- USBD_InterfaceIsDeviceHighSpeed;
- if (irp_sl->params.query_intf.version >=
- USB_BUSIF_USBDI_VERSION_2)
- usb_intf->LogEntry = USBD_InterfaceLogEntry;
- status = STATUS_SUCCESS;
-#else
- status = STATUS_NOT_IMPLEMENTED;
-#endif
- break;
- default:
- TRACE2("fn %d not implemented", irp_sl->minor_fn);
- status = STATUS_SUCCESS;
- break;
- }
- irp->io_status.status = status;
- TRACE2("status: %08X", status);
- IoCompleteRequest(irp, IO_NO_INCREMENT);
- IOEXIT(return status);
-}
-WIN_FUNC_DECL(pdoDispatchPnp,2)
-
-wstdcall NTSTATUS pdoDispatchPower(struct device_object *pdo, struct irp *irp)
-{
- struct io_stack_location *irp_sl;
- struct wrap_device *wd;
- union power_state power_state;
- struct pci_dev *pdev;
- NTSTATUS status;
-
- irp_sl = IoGetCurrentIrpStackLocation(irp);
- wd = pdo->reserved;
- TRACE2("pdo: %p, fn: %d:%d, wd: %p",
- pdo, irp_sl->major_fn, irp_sl->minor_fn, wd);
- switch (irp_sl->minor_fn) {
- case IRP_MN_WAIT_WAKE:
- /* TODO: this is not complete/correct */
- TRACE2("state: %d, completion: %p",
- irp_sl->params.power.state.system_state,
- irp_sl->completion_routine);
- IoMarkIrpPending(irp);
- status = STATUS_PENDING;
- break;
- case IRP_MN_SET_POWER:
- power_state = irp_sl->params.power.state;
- if (power_state.device_state == PowerDeviceD0) {
- TRACE2("resuming %p", wd);
- if (wrap_is_pci_bus(wd->dev_bus)) {
- pdev = wd->pci.pdev;
- pci_restore_state(pdev);
- if (wd->pci.wake_state == PowerDeviceD3) {
- pci_enable_wake(wd->pci.pdev,
- PCI_D3hot, 0);
- pci_enable_wake(wd->pci.pdev,
- PCI_D3cold, 0);
- }
- pci_set_power_state(pdev, PCI_D0);
- } else { // usb device
-#ifdef ENABLE_USB
- wrap_resume_urbs(wd);
-#endif
- }
- } else {
- TRACE2("suspending device %p", wd);
- if (wrap_is_pci_bus(wd->dev_bus)) {
- pdev = wd->pci.pdev;
- pci_save_state(pdev);
- TRACE2("%d", wd->pci.wake_state);
- if (wd->pci.wake_state == PowerDeviceD3) {
- pci_enable_wake(wd->pci.pdev,
- PCI_D3hot, 1);
- pci_enable_wake(wd->pci.pdev,
- PCI_D3cold, 1);
- }
- pci_set_power_state(pdev, PCI_D3hot);
- } else { // usb device
-#ifdef ENABLE_USB
- wrap_suspend_urbs(wd);
-#endif
- }
- }
- status = STATUS_SUCCESS;
- break;
- case IRP_MN_QUERY_POWER:
- status = STATUS_SUCCESS;
- break;
- default:
- TRACE2("fn %d not implemented", irp_sl->minor_fn);
- status = STATUS_SUCCESS;
- break;
- }
- irp->io_status.status = status;
- IoCompleteRequest(irp, IO_NO_INCREMENT);
- return status;
-}
-WIN_FUNC_DECL(pdoDispatchPower,2)
-
-static NTSTATUS pnp_set_device_power_state(struct wrap_device *wd,
- enum device_power_state state)
-{
- NTSTATUS status;
- struct device_object *pdo;
- struct io_stack_location irp_sl;
-
- pdo = wd->pdo;
- IOTRACE("%p, %p", pdo, IoGetAttachedDevice(pdo));
- memset(&irp_sl, 0, sizeof(irp_sl));
- irp_sl.params.power.state.device_state = state;
- irp_sl.params.power.type = DevicePowerState;
- if (state > PowerDeviceD0) {
- status = IoSendIrpTopDev(pdo, IRP_MJ_POWER, IRP_MN_QUERY_POWER,
- &irp_sl);
- if (status != STATUS_SUCCESS) {
- TRACE1("query of power to %d returns %08X",
- state, status);
- EXIT1(return status);
- }
- }
- status = IoSendIrpTopDev(pdo, IRP_MJ_POWER, IRP_MN_SET_POWER, &irp_sl);
- if (status != STATUS_SUCCESS)
- WARNING("setting power to %d failed: %08X", state, status);
- EXIT1(return status);
-}
-
-NTSTATUS pnp_start_device(struct wrap_device *wd)
-{
- struct device_object *fdo;
- struct device_object *pdo;
- struct io_stack_location irp_sl;
- NTSTATUS status;
-
- pdo = wd->pdo;
- /* TODO: for now we use same resources for both translated
- * resources and raw resources */
- memset(&irp_sl, 0, sizeof(irp_sl));
- irp_sl.params.start_device.allocated_resources =
- wd->resource_list;
- irp_sl.params.start_device.allocated_resources_translated =
- wd->resource_list;
- status = IoSendIrpTopDev(pdo, IRP_MJ_PNP, IRP_MN_START_DEVICE, &irp_sl);
- fdo = IoGetAttachedDevice(pdo);
- if (status == STATUS_SUCCESS)
- fdo->drv_obj->drv_ext->count++;
- else
- WARNING("Windows driver couldn't initialize the device (%08X)",
- status);
- EXIT1(return status);
-}
-
-NTSTATUS pnp_stop_device(struct wrap_device *wd)
-{
- struct device_object *pdo;
- NTSTATUS status;
-
- pdo = wd->pdo;
- status = IoSendIrpTopDev(pdo, IRP_MJ_PNP, IRP_MN_QUERY_STOP_DEVICE,
- NULL);
- if (status != STATUS_SUCCESS)
- WARNING("status: %08X", status);
- /* for now we ignore query status */
- status = IoSendIrpTopDev(pdo, IRP_MJ_PNP, IRP_MN_STOP_DEVICE, NULL);
- if (status != STATUS_SUCCESS)
- WARNING("status: %08X", status);
- if (status != STATUS_SUCCESS)
- WARNING("status: %08X", status);
- EXIT2(return status);
-}
-
-NTSTATUS pnp_remove_device(struct wrap_device *wd)
-{
- struct device_object *pdo, *fdo;
- struct driver_object *fdo_drv_obj;
- NTSTATUS status;
-
- pdo = wd->pdo;
- fdo = IoGetAttachedDevice(pdo);
- fdo_drv_obj = fdo->drv_obj;
- TRACE2("%p, %p, %p", pdo, fdo, fdo_drv_obj);
- status = IoSendIrpTopDev(pdo, IRP_MJ_PNP, IRP_MN_QUERY_REMOVE_DEVICE,
- NULL);
- if (status != STATUS_SUCCESS)
- WARNING("status: %08X", status);
-
- status = IoSendIrpTopDev(pdo, IRP_MJ_PNP, IRP_MN_REMOVE_DEVICE, NULL);
- if (status != STATUS_SUCCESS)
- WARNING("status: %08X", status);
- /* TODO: should we use count in drv_ext or driver's Object
- * header reference count to keep count of devices associated
- * with a driver? */
- if (status == STATUS_SUCCESS)
- fdo_drv_obj->drv_ext->count--;
- TRACE1("count: %d", fdo_drv_obj->drv_ext->count);
- if (fdo_drv_obj->drv_ext->count < 0)
- WARNING("wrong count: %d", fdo_drv_obj->drv_ext->count);
- if (fdo_drv_obj->drv_ext->count == 0) {
- struct wrap_driver *wrap_driver;
- TRACE1("unloading driver: %p", fdo_drv_obj);
- wrap_driver =
- IoGetDriverObjectExtension(fdo_drv_obj,
- (void *)WRAP_DRIVER_CLIENT_ID);
- if (fdo_drv_obj->unload)
- LIN2WIN1(fdo_drv_obj->unload, fdo_drv_obj);
- if (wrap_driver) {
- if (down_interruptible(&loader_mutex))
- WARNING("couldn't obtain loader_mutex");
- unload_wrap_driver(wrap_driver);
- up(&loader_mutex);
- } else
- ERROR("couldn't get wrap_driver");
- ObDereferenceObject(fdo_drv_obj);
- }
- IoDeleteDevice(pdo);
- unload_wrap_device(wd);
- EXIT1(return status);
-}
-
-WIN_FUNC_DECL(IoInvalidDeviceRequest,2)
-
-static struct device_object *alloc_pdo(struct driver_object *drv_obj)
-{
- struct device_object *pdo;
- NTSTATUS status ;
- int i;
- struct ansi_string ansi_name;
- struct unicode_string unicode_name;
-
- RtlInitAnsiString(&ansi_name, "NDISpdo");
- if (RtlAnsiStringToUnicodeString(&unicode_name, &ansi_name, TRUE) ==
- STATUS_SUCCESS) {
- status = IoCreateDevice(drv_obj, 0, &unicode_name,
- FILE_DEVICE_UNKNOWN,
- FILE_AUTOGENERATED_DEVICE_NAME,
- FALSE, &pdo);
- RtlFreeUnicodeString(&unicode_name);
- } else {
- status = IoCreateDevice(drv_obj, 0, NULL,
- FILE_DEVICE_UNKNOWN,
- FILE_AUTOGENERATED_DEVICE_NAME,
- FALSE, &pdo);
- }
- TRACE1("%p, %d, %p", drv_obj, status, pdo);
- if (status != STATUS_SUCCESS)
- return NULL;
- /* dispatch routines are called as Windows functions */
- for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
- drv_obj->major_func[i] = WIN_FUNC_PTR(IoInvalidDeviceRequest,2);
- drv_obj->major_func[IRP_MJ_INTERNAL_DEVICE_CONTROL] =
- WIN_FUNC_PTR(pdoDispatchDeviceControl,2);
- drv_obj->major_func[IRP_MJ_DEVICE_CONTROL] =
- WIN_FUNC_PTR(pdoDispatchDeviceControl,2);
- drv_obj->major_func[IRP_MJ_POWER] = WIN_FUNC_PTR(pdoDispatchPower,2);
- drv_obj->major_func[IRP_MJ_PNP] = WIN_FUNC_PTR(pdoDispatchPnp,2);
- return pdo;
-}
-
-static int wrap_pnp_start_device(struct wrap_device *wd)
-{
- struct wrap_driver *driver;
- struct device_object *pdo;
- struct driver_object *pdo_drv_obj;
-
- ENTER1("wd: %p", wd);
-
- if (!((wrap_is_pci_bus(wd->dev_bus)) ||
- (wrap_is_usb_bus(wd->dev_bus)))) {
- ERROR("bus type %d (%d) not supported",
- WRAP_BUS(wd->dev_bus), wd->dev_bus);
- EXIT1(return -EINVAL);
- }
- driver = load_wrap_driver(wd);
- if (!driver)
- return -ENODEV;
-
- wd->driver = driver;
- wd->dev_bus = WRAP_DEVICE_BUS(driver->dev_type, WRAP_BUS(wd->dev_bus));
- TRACE1("dev type: %d, bus type: %d, %d", WRAP_DEVICE(wd->dev_bus),
- WRAP_BUS(wd->dev_bus), wd->dev_bus);
- TRACE1("%d, %d", driver->dev_type, wrap_is_usb_bus(wd->dev_bus));
- /* first create pdo */
- if (wrap_is_pci_bus(wd->dev_bus))
- pdo_drv_obj = find_bus_driver("PCI");
- else // if (wrap_is_usb_bus(wd->dev_bus))
- pdo_drv_obj = find_bus_driver("USB");
- if (!pdo_drv_obj)
- return -EINVAL;
- pdo = alloc_pdo(pdo_drv_obj);
- if (!pdo)
- return -ENOMEM;
- wd->pdo = pdo;
- pdo->reserved = wd;
- if (WRAP_DEVICE(wd->dev_bus) == WRAP_NDIS_DEVICE) {
- if (init_ndis_driver(driver->drv_obj)) {
- IoDeleteDevice(pdo);
- return -EINVAL;
- }
- }
- TRACE1("%p", driver->drv_obj->drv_ext->add_device);
- if (driver->drv_obj->drv_ext->add_device(driver->drv_obj, pdo) !=
- STATUS_SUCCESS) {
- IoDeleteDevice(pdo);
- return -ENOMEM;
- }
- if (pnp_start_device(wd) != STATUS_SUCCESS) {
- /* TODO: we need proper cleanup, to deallocate memory,
- * for example */
- pnp_remove_device(wd);
- return -EINVAL;
- }
- return 0;
-}
-
-/*
- * This function should not be marked __devinit because PCI IDs are
- * added dynamically.
- */
-int wrap_pnp_start_pci_device(struct pci_dev *pdev,
- const struct pci_device_id *ent)
-{
- struct load_device load_device;
- struct wrap_device *wd;
-
- ENTER1("called for %04x:%04x:%04x:%04x", pdev->vendor, pdev->device,
- pdev->subsystem_vendor, pdev->subsystem_device);
-
- load_device.bus = WRAP_PCI_BUS;
- load_device.vendor = pdev->vendor;
- load_device.device = pdev->device;
- load_device.subvendor = pdev->subsystem_vendor;
- load_device.subdevice = pdev->subsystem_device;
- wd = load_wrap_device(&load_device);
- if (!wd)
- EXIT1(return -ENODEV);
- wd->pci.pdev = pdev;
- return wrap_pnp_start_device(wd);
-}
-
-void wrap_pnp_remove_pci_device(struct pci_dev *pdev)
-{
- struct wrap_device *wd;
-
- wd = (struct wrap_device *)pci_get_drvdata(pdev);
- ENTER1("%p, %p", pdev, wd);
- if (!wd)
- EXIT1(return);
- pnp_remove_device(wd);
-}
-
-int wrap_pnp_suspend_pci_device(struct pci_dev *pdev, pm_message_t state)
-{
- struct wrap_device *wd;
-
- wd = (struct wrap_device *)pci_get_drvdata(pdev);
- return pnp_set_device_power_state(wd, PowerDeviceD3);
-}
-
-int wrap_pnp_resume_pci_device(struct pci_dev *pdev)
-{
- struct wrap_device *wd;
-
- wd = (struct wrap_device *)pci_get_drvdata(pdev);
- return pnp_set_device_power_state(wd, PowerDeviceD0);
-}
-
-#ifdef ENABLE_USB
-int wrap_pnp_start_usb_device(struct usb_interface *intf,
- const struct usb_device_id *usb_id)
-{
- struct wrap_device *wd;
- int ret;
- struct usb_device *udev = interface_to_usbdev(intf);
- ENTER1("%04x, %04x, %04x", udev->descriptor.idVendor,
- udev->descriptor.idProduct, udev->descriptor.bDeviceClass);
-
- /* USB device (e.g., RNDIS) may have multiple interfaces;
- initialize one interface only (is there a way to know which
- of these interfaces is for network?) */
-
- if ((wd = get_wrap_device(udev, WRAP_USB_BUS))) {
- TRACE1("device already initialized: %p", wd);
- usb_set_intfdata(intf, NULL);
- ret = 0;
- } else {
- struct load_device load_device;
-
- load_device.bus = WRAP_USB_BUS;
- load_device.vendor = le16_to_cpu(udev->descriptor.idVendor);
- load_device.device = le16_to_cpu(udev->descriptor.idProduct);
- load_device.subvendor = 0;
- load_device.subdevice = 0;
- wd = load_wrap_device(&load_device);
- TRACE2("%p", wd);
- if (wd) {
- /* some devices (e.g., TI 4150, RNDIS) need
- * full reset */
- ret = usb_reset_device(udev);
- if (ret)
- WARNING("reset failed: %d", ret);
- usb_set_intfdata(intf, wd);
- wd->usb.intf = intf;
- wd->usb.udev = udev;
- ret = wrap_pnp_start_device(wd);
- } else
- ret = -ENODEV;
- }
-
- TRACE2("ret: %d", ret);
- if (ret)
- EXIT1(return ret);
- else
- return 0;
-}
-
-void __devexit wrap_pnp_remove_usb_device(struct usb_interface *intf)
-{
- struct wrap_device *wd;
-
- wd = (struct wrap_device *)usb_get_intfdata(intf);
- TRACE1("%p, %p", intf, wd);
- if (wd == NULL)
- EXIT1(return);
- usb_set_intfdata(intf, NULL);
- wd->usb.intf = NULL;
- pnp_remove_device(wd);
-}
-
-int wrap_pnp_suspend_usb_device(struct usb_interface *intf, pm_message_t state)
-{
- struct wrap_device *wd;
- struct device_object *pdo;
-
- wd = usb_get_intfdata(intf);
- ENTER1("%p, %p", intf, wd);
- if (!wd)
- EXIT1(return 0);
- pdo = wd->pdo;
- if (pnp_set_device_power_state(wd, PowerDeviceD3))
- return -1;
- return 0;
-}
-
-int wrap_pnp_resume_usb_device(struct usb_interface *intf)
-{
- struct wrap_device *wd;
- wd = usb_get_intfdata(intf);
- ENTER1("%p, %p", intf, wd);
- if (!wd)
- EXIT1(return 0);
- if (pnp_set_device_power_state(wd, PowerDeviceD0))
- return -1;
- return 0;
-}
-
-#endif // USB
+++ /dev/null
-/*
- * Copyright (C) 2005 Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef _PNP_H_
-#define _PNP_H_
-
-#include "ntoskernel.h"
-#include "ndis.h"
-#include "wrapndis.h"
-
-NTSTATUS pnp_start_device(struct wrap_device *wd);
-NTSTATUS pnp_stop_device(struct wrap_device *wd);
-NTSTATUS pnp_remove_device(struct wrap_device *wd);
-
-int wrap_pnp_start_pci_device(struct pci_dev *pdev,
- const struct pci_device_id *ent);
-void __devexit wrap_pnp_remove_pci_device(struct pci_dev *pdev);
-int wrap_pnp_suspend_pci_device(struct pci_dev *pdev, pm_message_t state);
-int wrap_pnp_resume_pci_device(struct pci_dev *pdev);
-
-#ifdef ENABLE_USB
-int wrap_pnp_start_usb_device(struct usb_interface *intf,
- const struct usb_device_id *usb_id);
-void wrap_pnp_remove_usb_device(struct usb_interface *intf);
-int wrap_pnp_suspend_usb_device(struct usb_interface *intf,
- pm_message_t state);
-int wrap_pnp_resume_usb_device(struct usb_interface *intf);
-#endif
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-#include <linux/proc_fs.h>
-#include <linux/module.h>
-#include <asm/uaccess.h>
-
-#include "ndis.h"
-#include "iw_ndis.h"
-#include "wrapndis.h"
-#include "pnp.h"
-#include "wrapper.h"
-
-#define MAX_PROC_STR_LEN 32
-
-static struct proc_dir_entry *wrap_procfs_entry;
-
-static int procfs_read_ndis_stats(char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- char *p = page;
- struct ndis_device *wnd = (struct ndis_device *)data;
- struct ndis_wireless_stats stats;
- NDIS_STATUS res;
- ndis_rssi rssi;
-
- if (off != 0) {
- *eof = 1;
- return 0;
- }
-
- res = mp_query(wnd, OID_802_11_RSSI, &rssi, sizeof(rssi));
- if (!res)
- p += sprintf(p, "signal_level=%d dBm\n", (s32)rssi);
-
- res = mp_query(wnd, OID_802_11_STATISTICS, &stats, sizeof(stats));
- if (!res) {
-
- p += sprintf(p, "tx_frames=%Lu\n", stats.tx_frag);
- p += sprintf(p, "tx_multicast_frames=%Lu\n",
- stats.tx_multi_frag);
- p += sprintf(p, "tx_failed=%Lu\n", stats.failed);
- p += sprintf(p, "tx_retry=%Lu\n", stats.retry);
- p += sprintf(p, "tx_multi_rerty=%Lu\n", stats.multi_retry);
- p += sprintf(p, "tx_rtss_success=%Lu\n", stats.rtss_succ);
- p += sprintf(p, "tx_rtss_fail=%Lu\n", stats.rtss_fail);
- p += sprintf(p, "ack_fail=%Lu\n", stats.ack_fail);
- p += sprintf(p, "frame_duplicates=%Lu\n", stats.frame_dup);
- p += sprintf(p, "rx_frames=%Lu\n", stats.rx_frag);
- p += sprintf(p, "rx_multicast_frames=%Lu\n",
- stats.rx_multi_frag);
- p += sprintf(p, "fcs_errors=%Lu\n", stats.fcs_err);
- }
-
- if (p - page > count) {
- ERROR("wrote %lu bytes (limit is %u)\n",
- (unsigned long)(p - page), count);
- *eof = 1;
- }
-
- return p - page;
-}
-
-static int procfs_read_ndis_encr(char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- char *p = page;
- struct ndis_device *wnd = (struct ndis_device *)data;
- int i, encr_status, auth_mode, infra_mode;
- NDIS_STATUS res;
- struct ndis_essid essid;
- mac_address ap_address;
-
- if (off != 0) {
- *eof = 1;
- return 0;
- }
-
- res = mp_query(wnd, OID_802_11_BSSID,
- &ap_address, sizeof(ap_address));
- if (res)
- memset(ap_address, 0, ETH_ALEN);
- p += sprintf(p, "ap_address=%2.2X", ap_address[0]);
- for (i = 1 ; i < ETH_ALEN ; i++)
- p += sprintf(p, ":%2.2X", ap_address[i]);
- p += sprintf(p, "\n");
-
- res = mp_query(wnd, OID_802_11_SSID, &essid, sizeof(essid));
- if (!res)
- p += sprintf(p, "essid=%.*s\n", essid.length, essid.essid);
-
- res = mp_query_int(wnd, OID_802_11_ENCRYPTION_STATUS, &encr_status);
- if (!res) {
- typeof(&wnd->encr_info.keys[0]) tx_key;
- p += sprintf(p, "tx_key=%u\n", wnd->encr_info.tx_key_index);
- p += sprintf(p, "key=");
- tx_key = &wnd->encr_info.keys[wnd->encr_info.tx_key_index];
- if (tx_key->length > 0)
- for (i = 0; i < tx_key->length; i++)
- p += sprintf(p, "%2.2X", tx_key->key[i]);
- else
- p += sprintf(p, "off");
- p += sprintf(p, "\n");
- p += sprintf(p, "encr_mode=%d\n", encr_status);
- }
- res = mp_query_int(wnd, OID_802_11_AUTHENTICATION_MODE, &auth_mode);
- if (!res)
- p += sprintf(p, "auth_mode=%d\n", auth_mode);
- res = mp_query_int(wnd, OID_802_11_INFRASTRUCTURE_MODE, &infra_mode);
- p += sprintf(p, "mode=%s\n", (infra_mode == Ndis802_11IBSS) ?
- "adhoc" : (infra_mode == Ndis802_11Infrastructure) ?
- "managed" : "auto");
- if (p - page > count) {
- WARNING("wrote %lu bytes (limit is %u)",
- (unsigned long)(p - page), count);
- *eof = 1;
- }
-
- return p - page;
-}
-
-static int procfs_read_ndis_hw(char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- char *p = page;
- struct ndis_device *wnd = (struct ndis_device *)data;
- struct ndis_configuration config;
- unsigned int power_mode;
- NDIS_STATUS res;
- ndis_tx_power_level tx_power;
- ULONG bit_rate;
- ndis_rts_threshold rts_threshold;
- ndis_fragmentation_threshold frag_threshold;
- ndis_antenna antenna;
- ULONG packet_filter;
- int n;
- mac_address mac;
- char *hw_status[] = {"ready", "initializing", "resetting", "closing",
- "not ready"};
-
- if (off != 0) {
- *eof = 1;
- return 0;
- }
-
- res = mp_query_int(wnd, OID_GEN_HARDWARE_STATUS, &n);
- if (res == NDIS_STATUS_SUCCESS &&
- n >= 0 && n < sizeof(hw_status) / sizeof(hw_status[0]))
- p += sprintf(p, "status=%s\n", hw_status[n]);
-
- res = mp_query(wnd, OID_802_3_CURRENT_ADDRESS, mac, sizeof(mac));
- if (!res)
- p += sprintf(p, "mac: " MACSTRSEP "\n", MAC2STR(mac));
- res = mp_query(wnd, OID_802_11_CONFIGURATION, &config, sizeof(config));
- if (!res) {
- p += sprintf(p, "beacon_period=%u msec\n",
- config.beacon_period);
- p += sprintf(p, "atim_window=%u msec\n", config.atim_window);
- p += sprintf(p, "frequency=%u kHZ\n", config.ds_config);
- p += sprintf(p, "hop_pattern=%u\n",
- config.fh_config.hop_pattern);
- p += sprintf(p, "hop_set=%u\n",
- config.fh_config.hop_set);
- p += sprintf(p, "dwell_time=%u msec\n",
- config.fh_config.dwell_time);
- }
-
- res = mp_query(wnd, OID_802_11_TX_POWER_LEVEL,
- &tx_power, sizeof(tx_power));
- if (!res)
- p += sprintf(p, "tx_power=%u mW\n", tx_power);
-
- res = mp_query(wnd, OID_GEN_LINK_SPEED, &bit_rate, sizeof(bit_rate));
- if (!res)
- p += sprintf(p, "bit_rate=%u kBps\n", (u32)bit_rate / 10);
-
- res = mp_query(wnd, OID_802_11_RTS_THRESHOLD,
- &rts_threshold, sizeof(rts_threshold));
- if (!res)
- p += sprintf(p, "rts_threshold=%u bytes\n", rts_threshold);
-
- res = mp_query(wnd, OID_802_11_FRAGMENTATION_THRESHOLD,
- &frag_threshold, sizeof(frag_threshold));
- if (!res)
- p += sprintf(p, "frag_threshold=%u bytes\n", frag_threshold);
-
- res = mp_query_int(wnd, OID_802_11_POWER_MODE, &power_mode);
- if (!res)
- p += sprintf(p, "power_mode=%s\n",
- (power_mode == NDIS_POWER_OFF) ? "always_on" :
- (power_mode == NDIS_POWER_MAX) ?
- "max_savings" : "min_savings");
-
- res = mp_query(wnd, OID_802_11_NUMBER_OF_ANTENNAS,
- &antenna, sizeof(antenna));
- if (!res)
- p += sprintf(p, "num_antennas=%u\n", antenna);
-
- res = mp_query(wnd, OID_802_11_TX_ANTENNA_SELECTED,
- &antenna, sizeof(antenna));
- if (!res)
- p += sprintf(p, "tx_antenna=%u\n", antenna);
-
- res = mp_query(wnd, OID_802_11_RX_ANTENNA_SELECTED,
- &antenna, sizeof(antenna));
- if (!res)
- p += sprintf(p, "rx_antenna=%u\n", antenna);
-
- p += sprintf(p, "encryption_modes=%s%s%s%s%s%s%s\n",
- test_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr) ?
- "WEP" : "none",
-
- test_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr) ?
- "; TKIP with WPA" : "",
- test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) ?
- ", WPA2" : "",
- test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth) ?
- ", WPA2PSK" : "",
-
- test_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr) ?
- "; AES/CCMP with WPA" : "",
- test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) ?
- ", WPA2" : "",
- test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth) ?
- ", WPA2PSK" : "");
-
- res = mp_query_int(wnd, OID_GEN_CURRENT_PACKET_FILTER, &packet_filter);
- if (!res) {
- if (packet_filter != wnd->packet_filter)
- WARNING("wrong packet_filter? 0x%08x, 0x%08x\n",
- packet_filter, wnd->packet_filter);
- p += sprintf(p, "packet_filter: 0x%08x\n", packet_filter);
- }
- if (p - page > count) {
- WARNING("wrote %lu bytes (limit is %u)",
- (unsigned long)(p - page), count);
- *eof = 1;
- }
-
- return p - page;
-}
-
-static int procfs_read_ndis_settings(char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- char *p = page;
- struct ndis_device *wnd = (struct ndis_device *)data;
- struct wrap_device_setting *setting;
-
- if (off != 0) {
- *eof = 1;
- return 0;
- }
-
- p += sprintf(p, "hangcheck_interval=%d\n",
- hangcheck_interval == 0 ?
- (int)(wnd->hangcheck_interval / HZ) : -1);
-
- list_for_each_entry(setting, &wnd->wd->settings, list) {
- p += sprintf(p, "%s=%s\n", setting->name, setting->value);
- }
-
- list_for_each_entry(setting, &wnd->wd->driver->settings, list) {
- p += sprintf(p, "%s=%s\n", setting->name, setting->value);
- }
-
- return p - page;
-}
-
-static int procfs_write_ndis_settings(struct file *file, const char __user *buf,
- unsigned long count, void *data)
-{
- struct ndis_device *wnd = (struct ndis_device *)data;
- char setting[MAX_PROC_STR_LEN], *p;
- unsigned int i;
- NDIS_STATUS res;
-
- if (count > MAX_PROC_STR_LEN)
- return -EINVAL;
-
- memset(setting, 0, sizeof(setting));
- if (copy_from_user(setting, buf, count))
- return -EFAULT;
-
- if ((p = strchr(setting, '\n')))
- *p = 0;
-
- if ((p = strchr(setting, '=')))
- *p = 0;
-
- if (!strcmp(setting, "hangcheck_interval")) {
- if (!p)
- return -EINVAL;
- p++;
- i = simple_strtol(p, NULL, 10);
- hangcheck_del(wnd);
- if (i > 0) {
- wnd->hangcheck_interval = i * HZ;
- hangcheck_add(wnd);
- }
- } else if (!strcmp(setting, "suspend")) {
- if (!p)
- return -EINVAL;
- p++;
- i = simple_strtol(p, NULL, 10);
- if (i <= 0 || i > 3)
- return -EINVAL;
- if (wrap_is_pci_bus(wnd->wd->dev_bus))
- i = wrap_pnp_suspend_pci_device(wnd->wd->pci.pdev,
- PMSG_SUSPEND);
- else
-#ifdef ENABLE_USB
- i = wrap_pnp_suspend_usb_device(wnd->wd->usb.intf,
- PMSG_SUSPEND);
-#else
- i = -1;
-#endif
- if (i)
- return -EINVAL;
- } else if (!strcmp(setting, "resume")) {
- if (wrap_is_pci_bus(wnd->wd->dev_bus))
- i = wrap_pnp_resume_pci_device(wnd->wd->pci.pdev);
- else
-#ifdef ENABLE_USB
- i = wrap_pnp_resume_usb_device(wnd->wd->usb.intf);
-#else
- i = -1;
-#endif
- if (i)
- return -EINVAL;
- } else if (!strcmp(setting, "stats_enabled")) {
- if (!p)
- return -EINVAL;
- p++;
- i = simple_strtol(p, NULL, 10);
- if (i > 0)
- wnd->iw_stats_enabled = TRUE;
- else
- wnd->iw_stats_enabled = FALSE;
- } else if (!strcmp(setting, "packet_filter")) {
- if (!p)
- return -EINVAL;
- p++;
- i = simple_strtol(p, NULL, 10);
- res = mp_set_int(wnd, OID_GEN_CURRENT_PACKET_FILTER, i);
- if (res)
- WARNING("setting packet_filter failed: %08X", res);
- } else if (!strcmp(setting, "reinit")) {
- if (ndis_reinit(wnd) != NDIS_STATUS_SUCCESS)
- return -EFAULT;
- } else {
- struct ndis_configuration_parameter param;
- struct unicode_string key;
- struct ansi_string ansi;
-
- if (!p)
- return -EINVAL;
- p++;
- RtlInitAnsiString(&ansi, p);
- if (RtlAnsiStringToUnicodeString(¶m.data.string, &ansi,
- TRUE) != STATUS_SUCCESS)
- EXIT1(return -EFAULT);
- param.type = NdisParameterString;
- RtlInitAnsiString(&ansi, setting);
- if (RtlAnsiStringToUnicodeString(&key, &ansi,
- TRUE) != STATUS_SUCCESS) {
- RtlFreeUnicodeString(¶m.data.string);
- EXIT1(return -EINVAL);
- }
- NdisWriteConfiguration(&res, wnd->nmb, &key, ¶m);
- RtlFreeUnicodeString(&key);
- RtlFreeUnicodeString(¶m.data.string);
- if (res != NDIS_STATUS_SUCCESS)
- return -EFAULT;
- }
- return count;
-}
-
-int wrap_procfs_add_ndis_device(struct ndis_device *wnd)
-{
- struct proc_dir_entry *procfs_entry;
-
- if (wrap_procfs_entry == NULL)
- return -ENOMEM;
-
- if (wnd->procfs_iface) {
- ERROR("%s already registered?", wnd->netdev_name);
- return -EINVAL;
- }
- wnd->procfs_iface = proc_mkdir(wnd->netdev_name, wrap_procfs_entry);
- if (wnd->procfs_iface == NULL) {
- ERROR("couldn't create proc directory");
- return -ENOMEM;
- }
- wnd->procfs_iface->uid = proc_uid;
- wnd->procfs_iface->gid = proc_gid;
-
- procfs_entry = create_proc_entry("hw", S_IFREG | S_IRUSR | S_IRGRP,
- wnd->procfs_iface);
- if (procfs_entry == NULL) {
- ERROR("couldn't create proc entry for 'hw'");
- goto err_hw;
- } else {
- procfs_entry->uid = proc_uid;
- procfs_entry->gid = proc_gid;
- procfs_entry->data = wnd;
- procfs_entry->read_proc = procfs_read_ndis_hw;
- }
-
- procfs_entry = create_proc_entry("stats", S_IFREG | S_IRUSR | S_IRGRP,
- wnd->procfs_iface);
- if (procfs_entry == NULL) {
- ERROR("couldn't create proc entry for 'stats'");
- goto err_stats;
- } else {
- procfs_entry->uid = proc_uid;
- procfs_entry->gid = proc_gid;
- procfs_entry->data = wnd;
- procfs_entry->read_proc = procfs_read_ndis_stats;
- }
-
- procfs_entry = create_proc_entry("encr", S_IFREG | S_IRUSR | S_IRGRP,
- wnd->procfs_iface);
- if (procfs_entry == NULL) {
- ERROR("couldn't create proc entry for 'encr'");
- goto err_encr;
- } else {
- procfs_entry->uid = proc_uid;
- procfs_entry->gid = proc_gid;
- procfs_entry->data = wnd;
- procfs_entry->read_proc = procfs_read_ndis_encr;
- }
-
- procfs_entry = create_proc_entry("settings", S_IFREG |
- S_IRUSR | S_IRGRP |
- S_IWUSR | S_IWGRP, wnd->procfs_iface);
- if (procfs_entry == NULL) {
- ERROR("couldn't create proc entry for 'settings'");
- goto err_settings;
- } else {
- procfs_entry->uid = proc_uid;
- procfs_entry->gid = proc_gid;
- procfs_entry->data = wnd;
- procfs_entry->read_proc = procfs_read_ndis_settings;
- procfs_entry->write_proc = procfs_write_ndis_settings;
- }
- return 0;
-
-err_settings:
- remove_proc_entry("encr", wnd->procfs_iface);
-err_encr:
- remove_proc_entry("stats", wnd->procfs_iface);
-err_stats:
- remove_proc_entry("hw", wnd->procfs_iface);
-err_hw:
- remove_proc_entry(wnd->netdev_name, wrap_procfs_entry);
- wnd->procfs_iface = NULL;
- return -ENOMEM;
-}
-
-void wrap_procfs_remove_ndis_device(struct ndis_device *wnd)
-{
- struct proc_dir_entry *procfs_iface = xchg(&wnd->procfs_iface, NULL);
-
- if (procfs_iface == NULL)
- return;
- remove_proc_entry("hw", procfs_iface);
- remove_proc_entry("stats", procfs_iface);
- remove_proc_entry("encr", procfs_iface);
- remove_proc_entry("settings", procfs_iface);
- if (wrap_procfs_entry)
- remove_proc_entry(wnd->netdev_name, wrap_procfs_entry);
-}
-
-static int procfs_read_debug(char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- char *p = page;
- enum alloc_type type;
-
- if (off != 0) {
- *eof = 1;
- return 0;
- }
- p += sprintf(p, "%d\n", debug);
- type = 0;
-#ifdef ALLOC_DEBUG
- for (type = 0; type < ALLOC_TYPE_MAX; type++)
- p += sprintf(p, "total size of allocations in %d: %d\n",
- type, alloc_size(type));
-#endif
- return p - page;
-}
-
-static int procfs_write_debug(struct file *file, const char __user *buf,
- unsigned long count, void *data)
-{
- int i;
- char setting[MAX_PROC_STR_LEN], *p;
-
- if (count > MAX_PROC_STR_LEN)
- return -EINVAL;
-
- memset(setting, 0, sizeof(setting));
- if (copy_from_user(setting, buf, count))
- return -EFAULT;
-
- if ((p = strchr(setting, '\n')))
- *p = 0;
-
- if ((p = strchr(setting, '=')))
- *p = 0;
-
- i = simple_strtol(setting, NULL, 10);
- if (i >= 0 && i < 10)
- debug = i;
- else
- return -EINVAL;
- return count;
-}
-
-int wrap_procfs_init(void)
-{
- struct proc_dir_entry *procfs_entry;
-
- wrap_procfs_entry = proc_mkdir(DRIVER_NAME, proc_net_root);
- if (wrap_procfs_entry == NULL) {
- ERROR("couldn't create procfs directory");
- return -ENOMEM;
- }
- wrap_procfs_entry->uid = proc_uid;
- wrap_procfs_entry->gid = proc_gid;
-
- procfs_entry = create_proc_entry("debug", S_IFREG | S_IRUSR | S_IRGRP,
- wrap_procfs_entry);
- if (procfs_entry == NULL) {
- ERROR("couldn't create proc entry for 'debug'");
- return -ENOMEM;
- } else {
- procfs_entry->uid = proc_uid;
- procfs_entry->gid = proc_gid;
- procfs_entry->read_proc = procfs_read_debug;
- procfs_entry->write_proc = procfs_write_debug;
- }
- return 0;
-}
-
-void wrap_procfs_remove(void)
-{
- if (wrap_procfs_entry == NULL)
- return;
- remove_proc_entry("debug", wrap_procfs_entry);
- remove_proc_entry(DRIVER_NAME, proc_net_root);
-}
+++ /dev/null
-/*
- * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include "ntoskernel.h"
-#include "rtl_exports.h"
-
-wstdcall SIZE_T WIN_FUNC(RtlCompareMemory,3)
- (const void *a, const void *b, SIZE_T len)
-{
- size_t i;
- char *x, *y;
-
- x = (char *)a;
- y = (char *)b;
- /* MSDN says this should return number of bytes that compare as
- * equal. This can be interpretted as either all bytes that are
- * equal in 'len' bytes or that only until the bytes compare as
- * not equal. Initially we had it the former way, but Realtek driver
- * doesn't like it that way - it takes many attempts to associate
- * with WPA. ReactOS returns the number of bytes that are equal
- * upto when they compare as not equal.
- * According to lords at #reactos, that is the way it should be
- * and that msdn is wrong about it!
- */
- for (i = 0; i < len && x[i] == y[i]; i++)
- ;
- return i;
-}
-
-wstdcall void WIN_FUNC(RtlCopyMemory,3)
- (void *dst, const void *src, SIZE_T length)
-{
- memcpy(dst, src, length);
-}
-
-wstdcall void WIN_FUNC(RtlZeroMemory,2)
- (void *dst, SIZE_T length)
-{
- memset(dst, 0, length);
-}
-
-wstdcall void WIN_FUNC(RtlSecureZeroMemory,2)
- (void *dst, SIZE_T length)
-{
- memset(dst, 0, length);
-}
-
-wstdcall void WIN_FUNC(RtlFillMemory,3)
- (void *dest, SIZE_T length, UCHAR fill)
-{
- memset(dest, fill, length);
-}
-
-wstdcall void WIN_FUNC(RtlMoveMemory,3)
- (void *dest, const void *src, SIZE_T length)
-{
- memmove(dest, src, length);
-}
-
-wstdcall LONG WIN_FUNC(RtlCompareString,3)
- (const struct ansi_string *s1, const struct ansi_string *s2,
- BOOLEAN case_insensitive)
-{
- unsigned int len;
- LONG ret = 0;
- const char *p1, *p2;
-
- ENTER2("");
- len = min(s1->length, s2->length);
- p1 = s1->buf;
- p2 = s2->buf;
- if (case_insensitive)
- while (!ret && len--)
- ret = toupper(*p1++) - toupper(*p2++);
- else
- while (!ret && len--)
- ret = *p1++ - *p2++;
- if (!ret)
- ret = s1->length - s2->length;
- EXIT2(return ret);
-}
-
-wstdcall LONG WIN_FUNC(RtlCompareUnicodeString,3)
- (const struct unicode_string *s1, const struct unicode_string *s2,
- BOOLEAN case_insensitive)
-{
- unsigned int len;
- LONG ret = 0;
- const wchar_t *p1, *p2;
-
- ENTER2("");
-
- len = min(s1->length, s2->length) / sizeof(wchar_t);
- p1 = s1->buf;
- p2 = s2->buf;
- if (case_insensitive)
- while (!ret && len--)
- ret = toupper((u8)*p1++) - toupper((u8)*p2++);
- else
- while (!ret && len--)
- ret = (u8)*p1++ - (u8)*p2++;
- if (!ret)
- ret = s1->length - s2->length;
- TRACE2("len: %d, ret: %d", len, ret);
- EXIT2(return ret);
-}
-
-wstdcall BOOLEAN WIN_FUNC(RtlEqualString,3)
- (const struct ansi_string *s1, const struct ansi_string *s2,
- BOOLEAN case_insensitive)
-{
- ENTER1("");
- if (s1->length != s2->length)
- return FALSE;
- return !RtlCompareString(s1, s2, case_insensitive);
-}
-
-wstdcall BOOLEAN WIN_FUNC(RtlEqualUnicodeString,3)
- (const struct unicode_string *s1, const struct unicode_string *s2,
- BOOLEAN case_insensitive)
-{
- if (s1->length != s2->length)
- return FALSE;
- return !RtlCompareUnicodeString(s1, s2, case_insensitive);
-}
-
-wstdcall void WIN_FUNC(RtlCopyUnicodeString,2)
- (struct unicode_string *dst, struct unicode_string *src)
-{
- ENTER1("%p, %p", dst, src);
- if (src && src->buf && dst->buf) {
- dst->length = min(src->length, dst->max_length);
- memcpy(dst->buf, src->buf, dst->length);
- if (dst->length < dst->max_length)
- dst->buf[dst->length / sizeof(dst->buf[0])] = 0;
- } else
- dst->length = 0;
- EXIT1(return);
-}
-
-wstdcall void WIN_FUNC(RtlCopyString,2)
- (struct ansi_string *dst, struct ansi_string *src)
-{
- ENTER1("%p, %p", dst, src);
- if (src && src->buf && dst->buf) {
- dst->length = min(src->length, dst->max_length);
- memcpy(dst->buf, src->buf, dst->length);
- if (dst->length < dst->max_length)
- dst->buf[dst->length] = 0;
- } else
- dst->length = 0;
- EXIT1(return);
-}
-
-wstdcall NTSTATUS WIN_FUNC(RtlAppendUnicodeToString,2)
- (struct unicode_string *dst, wchar_t *src)
-{
- if (src) {
- int len;
- for (len = 0; src[len]; len++)
- ;
- if (dst->length + (len * sizeof(dst->buf[0])) > dst->max_length)
- return STATUS_BUFFER_TOO_SMALL;
- memcpy(&dst->buf[dst->length], src, len * sizeof(dst->buf[0]));
- dst->length += len * sizeof(dst->buf[0]);
- if (dst->max_length > dst->length)
- dst->buf[dst->length / sizeof(dst->buf[0])] = 0;
- }
- return STATUS_SUCCESS;
-}
-
-wstdcall NTSTATUS WIN_FUNC(RtlAppendUnicodeStringToString,2)
- (struct unicode_string *dst, struct unicode_string *src)
-{
- if (dst->max_length < src->length + dst->length)
- return STATUS_BUFFER_TOO_SMALL;
- if (src->length) {
- memcpy(&dst->buf[dst->length], src->buf, src->length);
- dst->length += src->length;
- if (dst->max_length > dst->length)
- dst->buf[dst->length / sizeof(dst->buf[0])] = 0;
- }
- EXIT2(return STATUS_SUCCESS);
-}
-
-wstdcall ULONG WIN_FUNC(RtlxAnsiStringToUnicodeSize,1)
- (const struct ansi_string *string)
-{
- int i;
-
- for (i = 0; i < string->max_length && string->buf[i]; i++)
- ;
- return i * sizeof(wchar_t);
-}
-
-wstdcall ULONG WIN_FUNC(RtlxUnicodeStringToAnsiSize,1)
- (const struct unicode_string *string)
-{
- int i;
-
- for (i = 0; i < string->max_length && string->buf[i]; i++)
- ;
- return i;
-}
-
-wstdcall NTSTATUS WIN_FUNC(RtlAnsiStringToUnicodeString,3)
- (struct unicode_string *dst, const struct ansi_string *src,
- BOOLEAN alloc)
-{
- int i, n;
-
- n = RtlxAnsiStringToUnicodeSize(src);
- TRACE2("%d, %d, %d, %d, %p", n, dst->max_length, src->length,
- src->max_length, src->buf);
- if (alloc == TRUE) {
-#if 0
- if (n == 0) {
- dst->length = dst->max_length = 0;
- dst->buf = NULL;
- EXIT2(return STATUS_SUCCESS);
- }
-#endif
- dst->max_length = n + sizeof(dst->buf[0]);
- dst->buf = ExAllocatePoolWithTag(NonPagedPool,
- dst->max_length, 0);
- if (!dst->buf) {
- dst->max_length = dst->length = 0;
- EXIT2(return STATUS_NO_MEMORY);
- }
- } else if (dst->max_length < n)
- EXIT2(return STATUS_BUFFER_TOO_SMALL);
-
- dst->length = n;
- n /= sizeof(dst->buf[0]);
- for (i = 0; i < n; i++)
- dst->buf[i] = src->buf[i];
- if (i * sizeof(dst->buf[0]) < dst->max_length)
- dst->buf[i] = 0;
- TRACE2("dst: length: %d, max_length: %d, string: %p",
- dst->length, dst->max_length, src->buf);
- EXIT2(return STATUS_SUCCESS);
-}
-
-wstdcall NTSTATUS WIN_FUNC(RtlUnicodeStringToAnsiString,3)
- (struct ansi_string *dst, const struct unicode_string *src,
- BOOLEAN alloc)
-{
- int i, n;
-
- n = RtlxUnicodeStringToAnsiSize(src);
- TRACE2("%d, %d, %d, %d, %p", n, dst->max_length, src->length,
- src->max_length, src->buf);
- if (alloc == TRUE) {
-#if 0
- if (n == 0) {
- dst->length = dst->max_length = 0;
- dst->buf = NULL;
- EXIT2(return STATUS_SUCCESS);
- }
-#endif
- dst->max_length = n + sizeof(dst->buf[0]);
- dst->buf = ExAllocatePoolWithTag(NonPagedPool,
- dst->max_length, 0);
- if (!dst->buf) {
- dst->max_length = dst->length = 0;
- EXIT1(return STATUS_NO_MEMORY);
- }
- } else if (dst->max_length < n)
- EXIT2(return STATUS_BUFFER_TOO_SMALL);
-
- dst->length = n;
- for (i = 0; i < n; i++)
- dst->buf[i] = src->buf[i];
- if (i < dst->max_length)
- dst->buf[i] = 0;
- TRACE2("string: %p, len: %d(%d)", dst->buf, dst->length,
- dst->max_length);
- EXIT2(return STATUS_SUCCESS);
-}
-
-wstdcall NTSTATUS WIN_FUNC(RtlUnicodeStringToInteger,3)
- (struct unicode_string *ustring, ULONG base, ULONG *value)
-{
- int i, sign = 1;
- ULONG res;
- typeof(ustring->buf) string;
-
- if (ustring->length == 0) {
- *value = 0;
- return STATUS_SUCCESS;
- }
-
- string = ustring->buf;
- i = 0;
- while (i < (ustring->length / sizeof(*string)) && string[i] == ' ')
- i++;
- if (string[i] == '+')
- i++;
- else if (string[i] == '-') {
- i++;
- sign = -1;
- }
- if (base == 0) {
- base = 10;
- if (i <= ((ustring->length / sizeof(*string)) - 2) &&
- string[i] == '0') {
- i++;
- if (string[i] == 'b') {
- base = 2;
- i++;
- } else if (string[i] == 'o') {
- base = 8;
- i++;
- } else if (string[i] == 'x') {
- base = 16;
- i++;
- }
- }
- }
- if (!(base == 2 || base == 8 || base == 10 || base == 16))
- EXIT2(return STATUS_INVALID_PARAMETER);
-
- for (res = 0; i < (ustring->length / sizeof(*string)); i++) {
- int v;
- if (isdigit((char)string[i]))
- v = string[i] - '0';
- else if (isxdigit((char)string[i]))
- v = tolower((char)string[i]) - 'a' + 10;
- else
- v = base;
- if (v >= base)
- EXIT2(return STATUS_INVALID_PARAMETER);
- res = res * base + v;
- }
- *value = sign * res;
- EXIT3(return STATUS_SUCCESS);
-}
-
-wstdcall NTSTATUS WIN_FUNC(RtlCharToInteger,3)
- (const char *string, ULONG base, ULONG *value)
-{
- int sign = 1;
- ULONG res;
-
- if (!string || !value)
- EXIT2(return STATUS_INVALID_PARAMETER);
- while (*string == ' ')
- string++;
- if (*string == '+')
- string++;
- else if (*string == '-') {
- string++;
- sign = -1;
- }
- if (base == 0) {
- base = 10;
- if (*string == '0') {
- string++;
- if (*string == 'b') {
- base = 2;
- string++;
- } else if (*string == 'o') {
- base = 8;
- string++;
- } else if (*string == 'x') {
- base = 16;
- string++;
- }
- }
- }
- if (!(base == 2 || base == 8 || base == 10 || base == 16))
- EXIT2(return STATUS_INVALID_PARAMETER);
-
- for (res = 0; *string; string++) {
- int v;
- if (isdigit(*string))
- v = *string - '0';
- else if (isxdigit(*string))
- v = tolower(*string) - 'a' + 10;
- else
- v = base;
- if (v >= base)
- EXIT2(return STATUS_INVALID_PARAMETER);
- res = res * base + v;
- }
- *value = sign * res;
- EXIT3(return STATUS_SUCCESS);
-}
-
-wstdcall NTSTATUS WIN_FUNC(RtlIntegerToUnicodeString,3)
- (ULONG value, ULONG base, struct unicode_string *ustring)
-{
- typeof(ustring->buf) buf = ustring->buf;
- int i;
-
- if (base == 0)
- base = 10;
- if (!(base == 2 || base == 8 || base == 10 || base == 16))
- return STATUS_INVALID_PARAMETER;
- for (i = 0; value && i < ustring->max_length / sizeof(*buf); i++) {
- int r;
- r = value % base;
- value /= base;
- if (r < 10)
- buf[i] = r + '0';
- else
- buf[i] = r + 'a' - 10;
- }
- if (value)
- return STATUS_BUFFER_OVERFLOW;
- ustring->length = i * sizeof(*buf);
- return STATUS_SUCCESS;
-}
-
-wstdcall LARGE_INTEGER WIN_FUNC(RtlConvertUlongToLargeInteger,1)
- (ULONG ul)
-{
- LARGE_INTEGER li = ul;
- return li;
-}
-
-wfastcall USHORT WIN_FUNC(RtlUshortByteSwap,1)
- (USHORT src)
-{
- return __swab16(src);
-}
-
-wfastcall ULONG WIN_FUNC(RtlUlongByteSwap,1)
- (ULONG src)
-{
- /* ULONG is 32 bits for both 32-bit and 64-bit architectures */
- return __swab32(src);
-}
-
-wstdcall NTSTATUS WIN_FUNC(RtlUpcaseUnicodeString,3)
- (struct unicode_string *dst, struct unicode_string *src, BOOLEAN alloc)
-{
- USHORT i, n;
-
- if (alloc) {
- dst->buf = ExAllocatePoolWithTag(NonPagedPool, src->length, 0);
- if (dst->buf)
- dst->max_length = src->length;
- else
- EXIT2(return STATUS_NO_MEMORY);
- } else {
- if (dst->max_length < src->length)
- EXIT2(return STATUS_BUFFER_OVERFLOW);
- }
-
- n = src->length / sizeof(src->buf[0]);
- for (i = 0; i < n; i++)
- dst->buf[i] = toupper(src->buf[i]);
-
- dst->length = src->length;
- EXIT3(return STATUS_SUCCESS);
-}
-
-wstdcall void WIN_FUNC(RtlInitUnicodeString,2)
- (struct unicode_string *dst, const wchar_t *src)
-{
- ENTER2("%p", dst);
- if (dst == NULL)
- EXIT1(return);
- if (src == NULL) {
- dst->max_length = dst->length = 0;
- dst->buf = NULL;
- } else {
- int i;
- for (i = 0; (char)src[i]; i++)
- ;
- dst->buf = (typeof(dst->buf))src;
- dst->length = i * sizeof(dst->buf[0]);
- dst->max_length = (i + 1) * sizeof(dst->buf[0]);
- }
- EXIT1(return);
-}
-
-wstdcall void WIN_FUNC(RtlInitAnsiString,2)
- (struct ansi_string *dst, const char *src)
-{
- ENTER2("%p", dst);
- if (dst == NULL)
- EXIT2(return);
- if (src == NULL) {
- dst->max_length = dst->length = 0;
- dst->buf = NULL;
- } else {
- int i;
- for (i = 0; src[i]; i++)
- ;
- dst->buf = (typeof(dst->buf))src;
- dst->length = i;
- dst->max_length = i + 1;
- }
- TRACE2("%p", dst->buf);
- EXIT2(return);
-}
-
-wstdcall void WIN_FUNC(RtlInitString,2)
- (struct ansi_string *dst, const char *src)
-{
- ENTER2("%p", dst);
- RtlInitAnsiString(dst, src);
- EXIT2(return);
-}
-
-wstdcall void WIN_FUNC(RtlFreeUnicodeString,1)
- (struct unicode_string *string)
-{
- ENTER2("%p", string);
- if (string == NULL)
- return;
- if (string->buf)
- ExFreePool(string->buf);
- string->length = string->max_length = 0;
- string->buf = NULL;
- return;
-}
-
-wstdcall void WIN_FUNC(RtlFreeAnsiString,1)
- (struct ansi_string *string)
-{
- ENTER2("%p", string);
- if (string == NULL)
- return;
- if (string->buf)
- ExFreePool(string->buf);
- string->length = string->max_length = 0;
- string->buf = NULL;
- return;
-}
-
-/* guid string is of the form: {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
-wstdcall NTSTATUS WIN_FUNC(RtlGUIDFromString,2)
- (struct unicode_string *guid_string, struct guid *guid)
-{
- struct ansi_string ansi;
- NTSTATUS ret;
- int i, j, k, l, m;
-
- ret = RtlUnicodeStringToAnsiString(&ansi, guid_string, TRUE);
- if (ret != STATUS_SUCCESS)
- return ret;
- if (ansi.length != 37 || ansi.buf[0] != '{' ||
- ansi.buf[36] != '}' || ansi.buf[9] != '-' ||
- ansi.buf[14] != '-' || ansi.buf[19] != '-' ||
- ansi.buf[24] != '-') {
- RtlFreeAnsiString(&ansi);
- EXIT2(return STATUS_INVALID_PARAMETER);
- }
- memcpy(&guid->data4, &ansi.buf[29], sizeof(guid->data3));
- /* set end of data3 for scanf */
- ansi.buf[29] = 0;
- if (sscanf(&ansi.buf[1], "%x", &i) == 1 &&
- sscanf(&ansi.buf[10], "%x", &j) == 1 &&
- sscanf(&ansi.buf[15], "%x", &k) == 1 &&
- sscanf(&ansi.buf[20], "%x", &l) == 1 &&
- sscanf(&ansi.buf[25], "%x", &m) == 1) {
- guid->data1 = (i << 16) | (j < 8) | k;
- guid->data2 = l;
- guid->data3 = m;
- ret = STATUS_SUCCESS;
- } else
- ret = STATUS_INVALID_PARAMETER;
- RtlFreeAnsiString(&ansi);
- return ret;
-}
-
-wstdcall NTSTATUS WIN_FUNC(RtlQueryRegistryValues,5)
- (ULONG relative, wchar_t *path, struct rtl_query_registry_table *tbl,
- void *context, void *env)
-{
- struct ansi_string ansi;
- struct unicode_string unicode;
- NTSTATUS status, ret;
- static int i = 0;
-
- ENTER3("%x, %p", relative, tbl);
-// TODO();
-
- RtlInitUnicodeString(&unicode, path);
- if (RtlUnicodeStringToAnsiString(&ansi, &unicode, TRUE) ==
- STATUS_SUCCESS) {
- TRACE2("%s", ansi.buf);
- RtlFreeAnsiString(&ansi);
- }
- ret = STATUS_SUCCESS;
- for (; tbl->name; tbl++) {
- RtlInitUnicodeString(&unicode, tbl->name);
- if (RtlUnicodeStringToAnsiString(&ansi, &unicode, TRUE) ==
- STATUS_SUCCESS) {
- TRACE2("name: %s", ansi.buf);
- RtlFreeAnsiString(&ansi);
- }
- TRACE2("flags: %08X", tbl->flags);
- if (tbl->flags == RTL_QUERY_REGISTRY_DIRECT) {
- TRACE2("type: %08X", tbl->def_type);
- if (tbl->def_type == REG_DWORD) {
- /* Atheros USB driver needs this, but
- * don't know where and how to get its
- * value */
- if (tbl->def_data) {
- TRACE2("def_data: %x",
- *(int *)tbl->def_data);
- *(DWORD *)tbl->context = 0x5f292a + i++;
-// *(DWORD *)tbl->def_data;
- } else
- *(DWORD *)tbl->context = 0x2345dbe;
- }
- } else {
- void *data;
- ULONG type, length;
-
- if (!tbl->query_func) {
- ERROR("oops: no query_func");
- ret = STATUS_INVALID_PARAMETER;
- break;
- }
- if (tbl->flags & RTL_QUERY_REGISTRY_NOVALUE) {
- data = NULL;
- type = REG_NONE;
- length = 0;
- } else {
- data = tbl->def_data;
- type = tbl->def_type;
- length = tbl->def_length;;
- }
- TRACE2("calling query_func: %p", tbl->query_func);
- status = LIN2WIN6(tbl->query_func, tbl->name, type,
- data, length, context, env);
- TRACE2("status: %08X", status);
- if (status) {
- if (status == STATUS_BUFFER_TOO_SMALL)
- ret = STATUS_BUFFER_TOO_SMALL;
- else
- EXIT2(return STATUS_INVALID_PARAMETER);
- }
- }
- }
- EXIT3(return ret);
-}
-
-wstdcall NTSTATUS WIN_FUNC(RtlWriteRegistryValue,6)
- (ULONG relative, wchar_t *path, wchar_t *name, ULONG type,
- void *data, ULONG length)
-{
- struct ansi_string ansi;
- struct unicode_string unicode;
-
- ENTER3("%d", relative);
- TODO();
-
- RtlInitUnicodeString(&unicode, path);
- if (RtlUnicodeStringToAnsiString(&ansi, &unicode, TRUE) ==
- STATUS_SUCCESS) {
- TRACE2("%s", ansi.buf);
- RtlFreeAnsiString(&ansi);
- }
- RtlInitUnicodeString(&unicode, name);
- if (RtlUnicodeStringToAnsiString(&ansi, &unicode, TRUE) ==
- STATUS_SUCCESS) {
- TRACE2("%s", ansi.buf);
- RtlFreeAnsiString(&ansi);
- }
- EXIT5(return STATUS_SUCCESS);
-}
-
-wstdcall NTSTATUS WIN_FUNC(RtlDeleteRegistryValue,3)
- (ULONG relative, wchar_t *path, wchar_t *name)
-{
- return STATUS_SUCCESS;
-}
-
-wstdcall void WIN_FUNC(RtlAssert,4)
- (char *failed_assertion, char *file_name, ULONG line_num, char *message)
-{
- ERROR("assertion '%s' failed at %s line %d%s",
- failed_assertion, file_name, line_num, message ? message : "");
- return;
-}
-
-wstdcall void WIN_FUNC(RtlUnwind,0)
- (void)
-{
- TODO();
-}
-
-wstdcall void WIN_FUNC(RtlRaiseException,1)
- (void *exception_record)
-{
- TODO();
-}
-
-int rtl_init(void)
-{
- return 0;
-}
-
-/* called when module is being removed */
-void rtl_exit(void)
-{
- EXIT4(return);
-}
+++ /dev/null
-/*
- * Copyright (C) 2004 Jan Kiszka
- * Copyright (C) 2005 Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include "ndis.h"
-#include "usb.h"
-#include "usb_exports.h"
-
-#ifdef USB_DEBUG
-static unsigned int urb_id = 0;
-
-#define DUMP_WRAP_URB(wrap_urb, dir) \
- USBTRACE("urb %p (%d) %s: buf: %p, len: %d, pipe: 0x%x, %d", \
- (wrap_urb)->urb, (wrap_urb)->id, \
- (dir == USB_DIR_OUT) ? "going down" : "coming back", \
- (wrap_urb)->urb->transfer_buffer, \
- (wrap_urb)->urb->transfer_buffer_length, \
- (wrap_urb)->urb->pipe, (wrap_urb)->urb->status)
-
-#define DUMP_URB_BUFFER(urb, dir) \
- while (debug >= 2) { \
- int i; \
- char msg[20], *t; \
- if (!urb->transfer_buffer) \
- break; \
- if (!((usb_pipein(urb->pipe) && dir == USB_DIR_IN) || \
- (usb_pipeout(urb->pipe) && dir == USB_DIR_OUT))) \
- break; \
- t = msg; \
- t += sprintf(t, "%d: ", (urb)->actual_length); \
- for (i = 0; i < urb->actual_length && \
- t < &msg[sizeof(msg) - 4]; i++) \
- t += sprintf(t, "%02X ", \
- ((char *)urb->transfer_buffer)[i]); \
- *t = 0; \
- USBTRACE("%s", msg); \
- break; \
- }
-
-#else
-
-#define DUMP_WRAP_URB(wrap_urb, dir) (void)0
-#define DUMP_URB_BUFFER(urb, dir) (void)0
-
-#endif
-
-#define CUR_ALT_SETTING(intf) (intf)->cur_altsetting
-
-#ifndef USB_CTRL_SET_TIMEOUT
-#define USB_CTRL_SET_TIMEOUT 5000
-#endif
-
-#ifndef USB_CTRL_GET_TIMEOUT
-#define USB_CTRL_GET_TIMEOUT 5000
-#endif
-
-#ifndef URB_NO_TRANSFER_DMA_MAP
-#define URB_NO_TRANSFER_DMA_MAP 0
-#endif
-
-/* wrap_urb->flags */
-/* transfer_buffer for urb is allocated; free it in wrap_free_urb */
-#define WRAP_URB_COPY_BUFFER 0x01
-
-static int inline wrap_cancel_urb(struct wrap_urb *wrap_urb)
-{
- int ret;
- USBTRACE("%p, %p, %d", wrap_urb, wrap_urb->urb, wrap_urb->state);
- if (wrap_urb->state != URB_SUBMITTED)
- USBEXIT(return -1);
- ret = usb_unlink_urb(wrap_urb->urb);
- USBTRACE("ret: %d", ret);
- if (ret == -EINPROGRESS)
- return 0;
- else {
- WARNING("unlink failed: %d", ret);
- return ret;
- }
-}
-
-#define URB_STATUS(wrap_urb) (wrap_urb->urb->status)
-
-static struct nt_list wrap_urb_complete_list;
-static spinlock_t wrap_urb_complete_list_lock;
-
-static work_struct_t wrap_urb_complete_work;
-static void wrap_urb_complete_worker(worker_param_t dummy);
-
-static void kill_all_urbs(struct wrap_device *wd, int complete)
-{
- struct nt_list *ent;
- struct wrap_urb *wrap_urb;
- KIRQL irql;
-
- USBTRACE("%d", wd->usb.num_alloc_urbs);
- while (1) {
- IoAcquireCancelSpinLock(&irql);
- ent = RemoveHeadList(&wd->usb.wrap_urb_list);
- IoReleaseCancelSpinLock(irql);
- if (!ent)
- break;
- wrap_urb = container_of(ent, struct wrap_urb, list);
- if (wrap_urb->state == URB_SUBMITTED) {
- WARNING("Windows driver %s didn't free urb: %p",
- wd->driver->name, wrap_urb->urb);
- if (!complete)
- wrap_urb->urb->complete = NULL;
- usb_kill_urb(wrap_urb->urb);
- }
- USBTRACE("%p, %p", wrap_urb, wrap_urb->urb);
- usb_free_urb(wrap_urb->urb);
- kfree(wrap_urb);
- }
- wd->usb.num_alloc_urbs = 0;
-}
-
-/* for a given Linux urb status code, return corresponding NT urb status */
-static USBD_STATUS wrap_urb_status(int urb_status)
-{
- switch (urb_status) {
- case 0:
- return USBD_STATUS_SUCCESS;
- case -EPROTO:
- return USBD_STATUS_TIMEOUT;
- case -EILSEQ:
- return USBD_STATUS_CRC;
- case -EPIPE:
- return USBD_STATUS_INVALID_PIPE_HANDLE;
- case -ECOMM:
- return USBD_STATUS_DATA_OVERRUN;
- case -ENOSR:
- return USBD_STATUS_DATA_UNDERRUN;
- case -EOVERFLOW:
- return USBD_STATUS_BABBLE_DETECTED;
- case -EREMOTEIO:
- return USBD_STATUS_ERROR_SHORT_TRANSFER;;
- case -ENODEV:
- case -ESHUTDOWN:
- case -ENOENT:
- return USBD_STATUS_DEVICE_GONE;
- case -ENOMEM:
- return USBD_STATUS_NO_MEMORY;
- case -EINVAL:
- return USBD_STATUS_REQUEST_FAILED;
- default:
- return USBD_STATUS_NOT_SUPPORTED;
- }
-}
-
-/* for a given USBD_STATUS, return its corresponding NTSTATUS (for irp) */
-static NTSTATUS nt_urb_irp_status(USBD_STATUS nt_urb_status)
-{
- switch (nt_urb_status) {
- case USBD_STATUS_SUCCESS:
- return STATUS_SUCCESS;
- case USBD_STATUS_DEVICE_GONE:
- return STATUS_DEVICE_REMOVED;
- case USBD_STATUS_PENDING:
- return STATUS_PENDING;
- case USBD_STATUS_NOT_SUPPORTED:
- return STATUS_NOT_IMPLEMENTED;
- case USBD_STATUS_NO_MEMORY:
- return STATUS_NO_MEMORY;
- case USBD_STATUS_REQUEST_FAILED:
- return STATUS_NOT_SUPPORTED;
- default:
- return STATUS_FAILURE;
- }
-}
-
-static void wrap_free_urb(struct urb *urb)
-{
- struct irp *irp;
- struct wrap_urb *wrap_urb;
-
- USBTRACE("freeing urb: %p", urb);
- wrap_urb = urb->context;
- irp = wrap_urb->irp;
- if (wrap_urb->flags & WRAP_URB_COPY_BUFFER) {
- USBTRACE("freeing DMA buffer for URB: %p %p",
- urb, urb->transfer_buffer);
- usb_free_coherent(IRP_WRAP_DEVICE(irp)->usb.udev,
- urb->transfer_buffer_length,
- urb->transfer_buffer, urb->transfer_dma);
- }
- if (urb->setup_packet)
- kfree(urb->setup_packet);
- if (IRP_WRAP_DEVICE(irp)->usb.num_alloc_urbs > MAX_ALLOCATED_URBS) {
- IoAcquireCancelSpinLock(&irp->cancel_irql);
- RemoveEntryList(&wrap_urb->list);
- IRP_WRAP_DEVICE(irp)->usb.num_alloc_urbs--;
- IoReleaseCancelSpinLock(irp->cancel_irql);
- usb_free_urb(urb);
- kfree(wrap_urb);
- } else {
- wrap_urb->state = URB_FREE;
- wrap_urb->flags = 0;
- wrap_urb->irp = NULL;
- }
- return;
-}
-
-void wrap_suspend_urbs(struct wrap_device *wd)
-{
- /* TODO: do we need to cancel urbs? */
- USBTRACE("%p, %d", wd, wd->usb.num_alloc_urbs);
-}
-
-void wrap_resume_urbs(struct wrap_device *wd)
-{
- /* TODO: do we need to resubmit urbs? */
- USBTRACE("%p, %d", wd, wd->usb.num_alloc_urbs);
-}
-
-wstdcall void wrap_cancel_irp(struct device_object *dev_obj, struct irp *irp)
-{
- struct urb *urb;
-
- /* NB: this function is called holding Cancel spinlock */
- USBENTER("irp: %p", irp);
- urb = IRP_WRAP_URB(irp)->urb;
- USBTRACE("canceling urb %p", urb);
- if (wrap_cancel_urb(IRP_WRAP_URB(irp))) {
- irp->cancel = FALSE;
- ERROR("urb %p can't be canceled: %d", urb,
- IRP_WRAP_URB(irp)->state);
- } else
- USBTRACE("urb %p canceled", urb);
- IoReleaseCancelSpinLock(irp->cancel_irql);
- return;
-}
-WIN_FUNC_DECL(wrap_cancel_irp,2)
-
-static struct urb *wrap_alloc_urb(struct irp *irp, unsigned int pipe,
- void *buf, unsigned int buf_len)
-{
- struct urb *urb;
- gfp_t alloc_flags;
- struct wrap_urb *wrap_urb;
- struct wrap_device *wd;
-
- USBENTER("irp: %p", irp);
- wd = IRP_WRAP_DEVICE(irp);
- alloc_flags = irql_gfp();
- IoAcquireCancelSpinLock(&irp->cancel_irql);
- urb = NULL;
- nt_list_for_each_entry(wrap_urb, &wd->usb.wrap_urb_list, list) {
- if (cmpxchg(&wrap_urb->state, URB_FREE,
- URB_ALLOCATED) == URB_FREE) {
- urb = wrap_urb->urb;
- usb_init_urb(urb);
- break;
- }
- }
- if (!urb) {
- IoReleaseCancelSpinLock(irp->cancel_irql);
- wrap_urb = kzalloc(sizeof(*wrap_urb), alloc_flags);
- if (!wrap_urb) {
- WARNING("couldn't allocate memory");
- return NULL;
- }
- urb = usb_alloc_urb(0, alloc_flags);
- if (!urb) {
- WARNING("couldn't allocate urb");
- kfree(wrap_urb);
- return NULL;
- }
- IoAcquireCancelSpinLock(&irp->cancel_irql);
- wrap_urb->urb = urb;
- wrap_urb->state = URB_ALLOCATED;
- InsertTailList(&wd->usb.wrap_urb_list, &wrap_urb->list);
- wd->usb.num_alloc_urbs++;
- }
-
-#ifdef URB_ASYNC_UNLINK
- urb->transfer_flags |= URB_ASYNC_UNLINK;
-#elif defined(USB_ASYNC_UNLINK)
- urb->transfer_flags |= USB_ASYNC_UNLINK;
-#endif
- urb->context = wrap_urb;
- wrap_urb->irp = irp;
- IRP_WRAP_URB(irp) = wrap_urb;
- /* called as Windows function */
- irp->cancel_routine = WIN_FUNC_PTR(wrap_cancel_irp,2);
- IoReleaseCancelSpinLock(irp->cancel_irql);
- USBTRACE("urb: %p", urb);
-
- urb->transfer_buffer_length = buf_len;
- if (buf_len && buf && (!virt_addr_valid(buf)
-#if defined(CONFIG_HIGHMEM) || defined(CONFIG_HIGHMEM4G)
- || PageHighMem(virt_to_page(buf))
-#endif
- )) {
- urb->transfer_buffer =
- usb_alloc_coherent(wd->usb.udev, buf_len, alloc_flags,
- &urb->transfer_dma);
- if (!urb->transfer_buffer) {
- WARNING("couldn't allocate dma buf");
- IoAcquireCancelSpinLock(&irp->cancel_irql);
- wrap_urb->state = URB_FREE;
- wrap_urb->irp = NULL;
- IRP_WRAP_URB(irp) = NULL;
- IoReleaseCancelSpinLock(irp->cancel_irql);
- return NULL;
- }
- if (urb->transfer_dma)
- urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- wrap_urb->flags |= WRAP_URB_COPY_BUFFER;
- if (usb_pipeout(pipe))
- memcpy(urb->transfer_buffer, buf, buf_len);
- USBTRACE("DMA buf for urb %p: %p", urb, urb->transfer_buffer);
- } else
- urb->transfer_buffer = buf;
- return urb;
-}
-
-static USBD_STATUS wrap_submit_urb(struct irp *irp)
-{
- int ret;
- struct urb *urb;
- union nt_urb *nt_urb;
-
- urb = IRP_WRAP_URB(irp)->urb;
- nt_urb = IRP_URB(irp);
-#ifdef USB_DEBUG
- if (IRP_WRAP_URB(irp)->state != URB_ALLOCATED) {
- ERROR("urb %p is in wrong state: %d",
- urb, IRP_WRAP_URB(irp)->state);
- NT_URB_STATUS(nt_urb) = USBD_STATUS_REQUEST_FAILED;
- return NT_URB_STATUS(nt_urb);
- }
- IRP_WRAP_URB(irp)->id = pre_atomic_add(urb_id, 1);
-#endif
- DUMP_WRAP_URB(IRP_WRAP_URB(irp), USB_DIR_OUT);
- irp->io_status.status = STATUS_PENDING;
- irp->io_status.info = 0;
- NT_URB_STATUS(nt_urb) = USBD_STATUS_PENDING;
- IoMarkIrpPending(irp);
- DUMP_URB_BUFFER(urb, USB_DIR_OUT);
- USBTRACE("%p", urb);
- IRP_WRAP_URB(irp)->state = URB_SUBMITTED;
- ret = usb_submit_urb(urb, irql_gfp());
- if (ret) {
- USBTRACE("ret: %d", ret);
- wrap_free_urb(urb);
- /* we assume that IRP was not in pending state before */
- IoUnmarkIrpPending(irp);
- NT_URB_STATUS(nt_urb) = wrap_urb_status(ret);
- USBEXIT(return NT_URB_STATUS(nt_urb));
- } else
- USBEXIT(return USBD_STATUS_PENDING);
-}
-
-static void wrap_urb_complete(struct urb *urb ISR_PT_REGS_PARAM_DECL)
-{
- struct irp *irp;
- struct wrap_urb *wrap_urb;
-
- wrap_urb = urb->context;
- USBTRACE("%p (%p) completed", wrap_urb, urb);
- irp = wrap_urb->irp;
- DUMP_WRAP_URB(wrap_urb, USB_DIR_IN);
- irp->cancel_routine = NULL;
-#ifdef USB_DEBUG
- if (wrap_urb->state != URB_SUBMITTED) {
- WARNING("urb %p in wrong state: %d (%d)", urb, wrap_urb->state,
- urb->status);
- return;
- }
-#endif
- wrap_urb->state = URB_COMPLETED;
- spin_lock(&wrap_urb_complete_list_lock);
- InsertTailList(&wrap_urb_complete_list, &wrap_urb->complete_list);
- spin_unlock(&wrap_urb_complete_list_lock);
- schedule_ntos_work(&wrap_urb_complete_work);
-}
-
-/* one worker for all devices */
-static void wrap_urb_complete_worker(worker_param_t dummy)
-{
- struct irp *irp;
- struct urb *urb;
- struct usbd_bulk_or_intr_transfer *bulk_int_tx;
- struct usbd_vendor_or_class_request *vc_req;
- union nt_urb *nt_urb;
- struct wrap_urb *wrap_urb;
- struct nt_list *ent;
- unsigned long flags;
-
- USBENTER("");
- while (1) {
- spin_lock_irqsave(&wrap_urb_complete_list_lock, flags);
- ent = RemoveHeadList(&wrap_urb_complete_list);
- spin_unlock_irqrestore(&wrap_urb_complete_list_lock, flags);
- if (!ent)
- break;
- wrap_urb = container_of(ent, struct wrap_urb, complete_list);
- urb = wrap_urb->urb;
-#ifdef USB_DEBUG
- if (wrap_urb->state != URB_COMPLETED &&
- wrap_urb->state != URB_INT_UNLINKED)
- WARNING("urb %p in wrong state: %d",
- urb, wrap_urb->state);
-#endif
- irp = wrap_urb->irp;
- DUMP_IRP(irp);
- nt_urb = IRP_URB(irp);
- USBTRACE("urb: %p, nt_urb: %p, status: %d",
- urb, nt_urb, urb->status);
- switch (urb->status) {
- case 0:
- /* succesfully transferred */
- irp->io_status.info = urb->actual_length;
- if (nt_urb->header.function ==
- URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER) {
- bulk_int_tx = &nt_urb->bulk_int_transfer;
- bulk_int_tx->transfer_buffer_length =
- urb->actual_length;
- DUMP_URB_BUFFER(urb, USB_DIR_IN);
- if ((wrap_urb->flags & WRAP_URB_COPY_BUFFER) &&
- usb_pipein(urb->pipe))
- memcpy(bulk_int_tx->transfer_buffer,
- urb->transfer_buffer,
- urb->actual_length);
- } else { // vendor or class request
- vc_req = &nt_urb->vendor_class_request;
- vc_req->transfer_buffer_length =
- urb->actual_length;
- DUMP_URB_BUFFER(urb, USB_DIR_IN);
- if ((wrap_urb->flags & WRAP_URB_COPY_BUFFER) &&
- usb_pipein(urb->pipe))
- memcpy(vc_req->transfer_buffer,
- urb->transfer_buffer,
- urb->actual_length);
- }
- NT_URB_STATUS(nt_urb) = USBD_STATUS_SUCCESS;
- irp->io_status.status = STATUS_SUCCESS;
- break;
- case -ENOENT:
- case -ECONNRESET:
- /* urb canceled */
- irp->io_status.info = 0;
- TRACE2("urb %p canceled", urb);
- NT_URB_STATUS(nt_urb) = USBD_STATUS_SUCCESS;
- irp->io_status.status = STATUS_CANCELLED;
- break;
- default:
- TRACE2("irp: %p, urb: %p, status: %d/%d",
- irp, urb, urb->status, wrap_urb->state);
- irp->io_status.info = 0;
- NT_URB_STATUS(nt_urb) = wrap_urb_status(urb->status);
- irp->io_status.status =
- nt_urb_irp_status(NT_URB_STATUS(nt_urb));
- break;
- }
- wrap_free_urb(urb);
- IoCompleteRequest(irp, IO_NO_INCREMENT);
- }
- USBEXIT(return);
-}
-
-static USBD_STATUS wrap_bulk_or_intr_trans(struct irp *irp)
-{
- usbd_pipe_handle pipe_handle;
- struct urb *urb;
- unsigned int pipe;
- struct usbd_bulk_or_intr_transfer *bulk_int_tx;
- USBD_STATUS status;
- struct usb_device *udev;
- union nt_urb *nt_urb;
-
- nt_urb = IRP_URB(irp);
- udev = IRP_WRAP_DEVICE(irp)->usb.udev;
- bulk_int_tx = &nt_urb->bulk_int_transfer;
- pipe_handle = bulk_int_tx->pipe_handle;
- USBTRACE("flags: 0x%x, length: %u, buffer: %p, handle: %p",
- bulk_int_tx->transfer_flags,
- bulk_int_tx->transfer_buffer_length,
- bulk_int_tx->transfer_buffer, pipe_handle);
-
- if (USBD_IS_BULK_PIPE(pipe_handle)) {
- if (bulk_int_tx->transfer_flags & USBD_TRANSFER_DIRECTION_IN)
- pipe = usb_rcvbulkpipe(udev,
- pipe_handle->bEndpointAddress);
- else
- pipe = usb_sndbulkpipe(udev,
- pipe_handle->bEndpointAddress);
- } else {
- if (bulk_int_tx->transfer_flags & USBD_TRANSFER_DIRECTION_IN)
- pipe = usb_rcvintpipe(udev,
- pipe_handle->bEndpointAddress);
- else
- pipe = usb_sndintpipe(udev,
- pipe_handle->bEndpointAddress);
- }
-
- DUMP_IRP(irp);
- urb = wrap_alloc_urb(irp, pipe, bulk_int_tx->transfer_buffer,
- bulk_int_tx->transfer_buffer_length);
- if (!urb) {
- ERROR("couldn't allocate urb");
- return USBD_STATUS_NO_MEMORY;
- }
- if (usb_pipein(pipe) &&
- (!(bulk_int_tx->transfer_flags & USBD_SHORT_TRANSFER_OK))) {
- USBTRACE("short not ok");
- urb->transfer_flags |= URB_SHORT_NOT_OK;
- }
- if (usb_pipebulk(pipe)) {
- usb_fill_bulk_urb(urb, udev, pipe, urb->transfer_buffer,
- bulk_int_tx->transfer_buffer_length,
- wrap_urb_complete, urb->context);
- USBTRACE("submitting bulk urb %p on pipe 0x%x (ep 0x%x)",
- urb, urb->pipe, pipe_handle->bEndpointAddress);
- } else {
- usb_fill_int_urb(urb, udev, pipe, urb->transfer_buffer,
- bulk_int_tx->transfer_buffer_length,
- wrap_urb_complete, urb->context,
- pipe_handle->bInterval);
- USBTRACE("submitting interrupt urb %p on pipe 0x%x (ep 0x%x), "
- "intvl: %d", urb, urb->pipe,
- pipe_handle->bEndpointAddress, pipe_handle->bInterval);
- }
- status = wrap_submit_urb(irp);
- USBTRACE("status: %08X", status);
- USBEXIT(return status);
-}
-
-static USBD_STATUS wrap_vendor_or_class_req(struct irp *irp)
-{
- u8 req_type;
- unsigned int pipe;
- struct usbd_vendor_or_class_request *vc_req;
- struct usb_device *udev;
- union nt_urb *nt_urb;
- USBD_STATUS status;
- struct urb *urb;
- struct usb_ctrlrequest *dr;
-
- nt_urb = IRP_URB(irp);
- udev = IRP_WRAP_DEVICE(irp)->usb.udev;
- vc_req = &nt_urb->vendor_class_request;
- USBTRACE("bits: %x, req: %x, val: %08x, index: %08x, flags: %x,"
- "buf: %p, len: %d", vc_req->reserved_bits, vc_req->request,
- vc_req->value, vc_req->index, vc_req->transfer_flags,
- vc_req->transfer_buffer, vc_req->transfer_buffer_length);
-
- USBTRACE("%x", nt_urb->header.function);
- switch (nt_urb->header.function) {
- case URB_FUNCTION_VENDOR_DEVICE:
- req_type = USB_TYPE_VENDOR | USB_RECIP_DEVICE;
- break;
- case URB_FUNCTION_VENDOR_INTERFACE:
- req_type = USB_TYPE_VENDOR | USB_RECIP_INTERFACE;
- break;
- case URB_FUNCTION_VENDOR_ENDPOINT:
- req_type = USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
- break;
- case URB_FUNCTION_VENDOR_OTHER:
- req_type = USB_TYPE_VENDOR | USB_RECIP_OTHER;
- break;
- case URB_FUNCTION_CLASS_DEVICE:
- req_type = USB_TYPE_CLASS | USB_RECIP_DEVICE;
- break;
- case URB_FUNCTION_CLASS_INTERFACE:
- req_type = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
- break;
- case URB_FUNCTION_CLASS_ENDPOINT:
- req_type = USB_TYPE_CLASS | USB_RECIP_ENDPOINT;
- break;
- case URB_FUNCTION_CLASS_OTHER:
- req_type = USB_TYPE_CLASS | USB_RECIP_OTHER;
- break;
- default:
- ERROR("unknown request type: %x", nt_urb->header.function);
- req_type = 0;
- break;
- }
-
- req_type |= vc_req->reserved_bits;
- USBTRACE("req type: %08x", req_type);
-
- if (vc_req->transfer_flags & USBD_TRANSFER_DIRECTION_IN) {
- pipe = usb_rcvctrlpipe(udev, 0);
- req_type |= USB_DIR_IN;
- USBTRACE("pipe: %x, dir in", pipe);
- } else {
- pipe = usb_sndctrlpipe(udev, 0);
- req_type |= USB_DIR_OUT;
- USBTRACE("pipe: %x, dir out", pipe);
- }
- urb = wrap_alloc_urb(irp, pipe, vc_req->transfer_buffer,
- vc_req->transfer_buffer_length);
- if (!urb) {
- ERROR("couldn't allocate urb");
- return USBD_STATUS_NO_MEMORY;
- }
-
- if (usb_pipein(pipe) &&
- (!(vc_req->transfer_flags & USBD_SHORT_TRANSFER_OK))) {
- USBTRACE("short not ok");
- urb->transfer_flags |= URB_SHORT_NOT_OK;
- }
-
- dr = kzalloc(sizeof(*dr), GFP_ATOMIC);
- if (!dr) {
- ERROR("couldn't allocate memory");
- wrap_free_urb(urb);
- return USBD_STATUS_NO_MEMORY;
- }
- dr->bRequestType = req_type;
- dr->bRequest = vc_req->request;
- dr->wValue = cpu_to_le16(vc_req->value);
- dr->wIndex = cpu_to_le16((u16)vc_req->index);
- dr->wLength = cpu_to_le16((u16)urb->transfer_buffer_length);
-
- usb_fill_control_urb(urb, udev, pipe, (unsigned char *)dr,
- urb->transfer_buffer, urb->transfer_buffer_length,
- wrap_urb_complete, urb->context);
- status = wrap_submit_urb(irp);
- USBTRACE("status: %08X", status);
- USBEXIT(return status);
-}
-
-static USBD_STATUS wrap_reset_pipe(struct usb_device *udev, struct irp *irp)
-{
- int ret;
- union nt_urb *nt_urb;
- usbd_pipe_handle pipe_handle;
- unsigned int pipe1, pipe2;
-
- nt_urb = IRP_URB(irp);
- pipe_handle = nt_urb->pipe_req.pipe_handle;
- /* TODO: not clear if both directions should be cleared? */
- if (USBD_IS_BULK_PIPE(pipe_handle)) {
- pipe1 = usb_rcvbulkpipe(udev, pipe_handle->bEndpointAddress);
- pipe2 = usb_sndbulkpipe(udev, pipe_handle->bEndpointAddress);
- } else if (USBD_IS_INT_PIPE(pipe_handle)) {
- pipe1 = usb_rcvintpipe(udev, pipe_handle->bEndpointAddress);
- pipe2 = pipe1;
- } else {
- WARNING("invalid pipe %d", pipe_handle->bEndpointAddress);
- return USBD_STATUS_INVALID_PIPE_HANDLE;
- }
- USBTRACE("ep: %d, pipe: 0x%x", pipe_handle->bEndpointAddress, pipe1);
- ret = usb_clear_halt(udev, pipe1);
- if (ret)
- USBTRACE("resetting pipe %d failed: %d", pipe1, ret);
- if (pipe2 != pipe1) {
- ret = usb_clear_halt(udev, pipe2);
- if (ret)
- USBTRACE("resetting pipe %d failed: %d", pipe2, ret);
- }
-// return wrap_urb_status(ret);
- return USBD_STATUS_SUCCESS;
-}
-
-static USBD_STATUS wrap_abort_pipe(struct usb_device *udev, struct irp *irp)
-{
- union nt_urb *nt_urb;
- usbd_pipe_handle pipe_handle;
- struct wrap_urb *wrap_urb;
- struct wrap_device *wd;
- KIRQL irql;
-
- wd = IRP_WRAP_DEVICE(irp);
- nt_urb = IRP_URB(irp);
- pipe_handle = nt_urb->pipe_req.pipe_handle;
- USBENTER("%p, %x", irp, pipe_handle->bEndpointAddress);
- IoAcquireCancelSpinLock(&irql);
- nt_list_for_each_entry(wrap_urb, &wd->usb.wrap_urb_list, list) {
- USBTRACE("%p, %p, %d, %x, %x", wrap_urb, wrap_urb->urb,
- wrap_urb->state, wrap_urb->urb->pipe,
- usb_pipeendpoint(wrap_urb->urb->pipe));
- /* for WG111T driver, urbs for endpoint 0 should also
- * be canceled */
- if ((usb_pipeendpoint(wrap_urb->urb->pipe) ==
- pipe_handle->bEndpointAddress) ||
- (usb_pipeendpoint(wrap_urb->urb->pipe) == 0)) {
- if (wrap_cancel_urb(wrap_urb) == 0)
- USBTRACE("canceled wrap_urb: %p", wrap_urb);
- }
- }
- IoReleaseCancelSpinLock(irql);
- NT_URB_STATUS(nt_urb) = USBD_STATUS_CANCELED;
- USBEXIT(return USBD_STATUS_SUCCESS);
-}
-
-static USBD_STATUS wrap_set_clear_feature(struct usb_device *udev,
- struct irp *irp)
-{
- union nt_urb *nt_urb;
- struct urb_control_feature_request *feat_req;
- int ret = 0;
- __u8 request, type;
- __u16 feature;
-
- nt_urb = IRP_URB(irp);
- feat_req = &nt_urb->feat_req;
- feature = feat_req->feature_selector;
- switch (nt_urb->header.function) {
- case URB_FUNCTION_SET_FEATURE_TO_DEVICE:
- request = USB_REQ_SET_FEATURE;
- type = USB_DT_DEVICE;
- break;
- case URB_FUNCTION_SET_FEATURE_TO_INTERFACE:
- request = USB_REQ_SET_FEATURE;
- type = USB_DT_INTERFACE;
- break;
- case URB_FUNCTION_SET_FEATURE_TO_ENDPOINT:
- request = USB_REQ_SET_FEATURE;
- type = USB_DT_ENDPOINT;
- break;
- case URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE:
- request = USB_REQ_CLEAR_FEATURE;
- type = USB_DT_DEVICE;
- break;
- case URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE:
- request = USB_REQ_CLEAR_FEATURE;
- type = USB_DT_INTERFACE;
- break;
- case URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT:
- request = USB_REQ_CLEAR_FEATURE;
- type = USB_DT_ENDPOINT;
- break;
- default:
- WARNING("invalid function: %x", nt_urb->header.function);
- NT_URB_STATUS(nt_urb) = USBD_STATUS_NOT_SUPPORTED;
- return NT_URB_STATUS(nt_urb);
- }
- ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), request, type,
- feature, feat_req->index, NULL, 0, 1000);
- NT_URB_STATUS(nt_urb) = wrap_urb_status(ret);
- USBEXIT(return NT_URB_STATUS(nt_urb));
-}
-
-static USBD_STATUS wrap_get_status_request(struct usb_device *udev,
- struct irp *irp)
-{
- union nt_urb *nt_urb;
- struct urb_control_get_status_request *status_req;
- int ret = 0;
- __u8 type;
-
- nt_urb = IRP_URB(irp);
- status_req = &nt_urb->status_req;
- switch (nt_urb->header.function) {
- case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
- type = USB_RECIP_DEVICE;
- break;
- case URB_FUNCTION_GET_STATUS_FROM_INTERFACE:
- type = USB_RECIP_INTERFACE;
- break;
- case URB_FUNCTION_GET_STATUS_FROM_ENDPOINT:
- type = USB_RECIP_ENDPOINT;
- break;
- default:
- WARNING("invalid function: %x", nt_urb->header.function);
- NT_URB_STATUS(nt_urb) = USBD_STATUS_NOT_SUPPORTED;
- return NT_URB_STATUS(nt_urb);
- }
- assert(status_req->transfer_buffer_length == sizeof(u16));
- ret = usb_get_status(udev, type, status_req->index,
- status_req->transfer_buffer);
- if (ret >= 0) {
- assert(ret <= status_req->transfer_buffer_length);
- status_req->transfer_buffer_length = ret;
- NT_URB_STATUS(nt_urb) = USBD_STATUS_SUCCESS;
- } else
- NT_URB_STATUS(nt_urb) = wrap_urb_status(ret);
- USBEXIT(return NT_URB_STATUS(nt_urb));
-}
-
-static void set_intf_pipe_info(struct wrap_device *wd,
- struct usb_interface *usb_intf,
- struct usbd_interface_information *intf)
-{
- int i;
- struct usb_endpoint_descriptor *ep;
- struct usbd_pipe_information *pipe;
-
- for (i = 0; i < CUR_ALT_SETTING(usb_intf)->desc.bNumEndpoints; i++) {
- ep = &(CUR_ALT_SETTING(usb_intf)->endpoint[i]).desc;
- if (i >= intf->bNumEndpoints) {
- ERROR("intf %p has only %d endpoints, "
- "ignoring endpoints above %d",
- intf, intf->bNumEndpoints, i);
- break;
- }
- pipe = &intf->pipes[i];
-
- if (pipe->flags & USBD_PF_CHANGE_MAX_PACKET)
- USBTRACE("pkt_sz: %d: %d", pipe->wMaxPacketSize,
- pipe->max_tx_size);
- USBTRACE("driver wants max_tx_size to %d",
- pipe->max_tx_size);
-
- pipe->wMaxPacketSize = le16_to_cpu(ep->wMaxPacketSize);
- pipe->bEndpointAddress = ep->bEndpointAddress;
- pipe->type = ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
- if (pipe->type == UsbdPipeTypeInterrupt) {
- /* Windows and Linux differ in how the
- * bInterval is interpretted */
- /* for low speed:
- interval (Windows) -> frames per ms (Linux)
- 0 to 15 -> 8
- 16 to 35 -> 16
- 36 to 255 -> 32
-
- for full speed: interval -> frames per ms
- 1 -> 1
- 2 to 3 -> 2
- 4 to 7 -> 4
- 8 to 15 -> 8
- 16 to 31 -> 16
- 32 to 255 -> 32
-
- for high speed: interval -> microframes
- 1 -> 1
- 2 -> 2
- 3 -> 4
- 4 -> 8
- 5 -> 16
- 6 -> 32
- 7 to 255 -> 32
- */
- if (wd->usb.udev->speed == USB_SPEED_LOW)
- pipe->bInterval = ep->bInterval + 5;
- else if (wd->usb.udev->speed == USB_SPEED_FULL)
- pipe->bInterval = ep->bInterval;
- else {
- int j, k;
- for (j = k = 1; j < ep->bInterval; k++)
- j *= 2;
- pipe->bInterval = k;
- }
- }
- pipe->handle = ep;
- USBTRACE("%d: ep 0x%x, type %d, pkt_sz %d, intv %d (%d),"
- "type: %d, handle %p", i, ep->bEndpointAddress,
- ep->bmAttributes, pipe->wMaxPacketSize, ep->bInterval,
- pipe->bInterval, pipe->type, pipe->handle);
- }
-}
-
-static USBD_STATUS wrap_select_configuration(struct wrap_device *wd,
- union nt_urb *nt_urb,
- struct irp *irp)
-{
- int i, ret;
- struct usbd_select_configuration *sel_conf;
- struct usb_device *udev;
- struct usbd_interface_information *intf;
- struct usb_config_descriptor *config;
- struct usb_interface *usb_intf;
-
- udev = wd->usb.udev;
- sel_conf = &nt_urb->select_conf;
- config = sel_conf->config;
- USBTRACE("%p", config);
- if (config == NULL) {
- kill_all_urbs(wd, 1);
- ret = usb_reset_configuration(udev);
- return wrap_urb_status(ret);
- }
-
- USBTRACE("conf: %d, type: %d, length: %d, numif: %d, attr: %08x",
- config->bConfigurationValue, config->bDescriptorType,
- config->wTotalLength, config->bNumInterfaces,
- config->bmAttributes);
- ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- USB_REQ_SET_CONFIGURATION, 0,
- config->bConfigurationValue, 0,
- NULL, 0, USB_CTRL_SET_TIMEOUT);
- if (ret < 0) {
- ERROR("ret: %d", ret);
- return wrap_urb_status(ret);
- }
- sel_conf->handle = udev->actconfig;
- intf = &sel_conf->intf;
- for (i = 0; i < config->bNumInterfaces && intf->bLength > 0;
- i++, intf = (((void *)intf) + intf->bLength)) {
-
- USBTRACE("intf: %d, alt setting: %d",
- intf->bInterfaceNumber, intf->bAlternateSetting);
- ret = usb_set_interface(udev, intf->bInterfaceNumber,
- intf->bAlternateSetting);
- if (ret < 0) {
- ERROR("failed with %d", ret);
- return wrap_urb_status(ret);
- }
- usb_intf = usb_ifnum_to_if(udev, intf->bInterfaceNumber);
- if (!usb_intf) {
- ERROR("couldn't obtain ifnum");
- return USBD_STATUS_REQUEST_FAILED;
- }
- USBTRACE("intf: %p, num ep: %d", intf, intf->bNumEndpoints);
- set_intf_pipe_info(wd, usb_intf, intf);
- }
- return USBD_STATUS_SUCCESS;
-}
-
-static USBD_STATUS wrap_select_interface(struct wrap_device *wd,
- union nt_urb *nt_urb,
- struct irp *irp)
-{
- int ret;
- struct usbd_select_interface *sel_intf;
- struct usb_device *udev;
- struct usbd_interface_information *intf;
- struct usb_interface *usb_intf;
-
- udev = wd->usb.udev;
- sel_intf = &nt_urb->select_intf;
- intf = &sel_intf->intf;
-
- ret = usb_set_interface(udev, intf->bInterfaceNumber,
- intf->bAlternateSetting);
- if (ret < 0) {
- ERROR("failed with %d", ret);
- return wrap_urb_status(ret);
- }
- usb_intf = usb_ifnum_to_if(udev, intf->bInterfaceNumber);
- if (!usb_intf) {
- ERROR("couldn't get interface information");
- return USBD_STATUS_REQUEST_FAILED;
- }
- USBTRACE("intf: %p, num ep: %d", usb_intf, intf->bNumEndpoints);
- set_intf_pipe_info(wd, usb_intf, intf);
- return USBD_STATUS_SUCCESS;
-}
-
-static int wrap_usb_get_string(struct usb_device *udev, unsigned short langid,
- unsigned char index, void *buf, int size)
-{
- int i, ret;
- /* if langid is 0, return array of langauges supported in
- * buf */
- for (i = 0; i < 3; i++) {
- ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
- (USB_DT_STRING << 8) + index, langid,
- buf, size, USB_CTRL_GET_TIMEOUT);
- if (ret > 0 || ret == -EPIPE)
- break;
- }
- return ret;
-}
-
-static USBD_STATUS wrap_get_descriptor(struct wrap_device *wd,
- union nt_urb *nt_urb, struct irp *irp)
-{
- struct usbd_control_descriptor_request *control_desc;
- int ret = 0;
- struct usb_device *udev;
-
- udev = wd->usb.udev;
- control_desc = &nt_urb->control_desc;
- USBTRACE("desctype = %d, descindex = %d, transfer_buffer = %p,"
- "transfer_buffer_length = %d", control_desc->desc_type,
- control_desc->index, control_desc->transfer_buffer,
- control_desc->transfer_buffer_length);
-
- if (control_desc->desc_type == USB_DT_STRING) {
- USBTRACE("langid: %x", control_desc->language_id);
- ret = wrap_usb_get_string(udev, control_desc->language_id,
- control_desc->index,
- control_desc->transfer_buffer,
- control_desc->transfer_buffer_length);
- } else {
- ret = usb_get_descriptor(udev, control_desc->desc_type,
- control_desc->index,
- control_desc->transfer_buffer,
- control_desc->transfer_buffer_length);
- }
- if (ret < 0) {
- USBTRACE("request %d failed: %d", control_desc->desc_type, ret);
- control_desc->transfer_buffer_length = 0;
- return wrap_urb_status(ret);
- } else {
- USBTRACE("ret: %08x", ret);
- control_desc->transfer_buffer_length = ret;
- irp->io_status.info = ret;
- return USBD_STATUS_SUCCESS;
- }
-}
-
-static USBD_STATUS wrap_process_nt_urb(struct irp *irp)
-{
- union nt_urb *nt_urb;
- struct usb_device *udev;
- USBD_STATUS status;
- struct wrap_device *wd;
-
- wd = IRP_WRAP_DEVICE(irp);
- udev = wd->usb.udev;
- nt_urb = IRP_URB(irp);
- USBENTER("nt_urb = %p, irp = %p, length = %d, function = %x",
- nt_urb, irp, nt_urb->header.length, nt_urb->header.function);
-
- DUMP_IRP(irp);
- switch (nt_urb->header.function) {
- /* bulk/int and vendor/class urbs are submitted to
- * Linux USB core; if the call is sucessful, urb's
- * completion worker will return IRP later */
- case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
- USBTRACE("submitting bulk/int irp: %p", irp);
- status = wrap_bulk_or_intr_trans(irp);
- break;
-
- case URB_FUNCTION_VENDOR_DEVICE:
- case URB_FUNCTION_VENDOR_INTERFACE:
- case URB_FUNCTION_VENDOR_ENDPOINT:
- case URB_FUNCTION_VENDOR_OTHER:
- case URB_FUNCTION_CLASS_DEVICE:
- case URB_FUNCTION_CLASS_INTERFACE:
- case URB_FUNCTION_CLASS_ENDPOINT:
- case URB_FUNCTION_CLASS_OTHER:
- USBTRACE("submitting vendor/class irp: %p", irp);
- status = wrap_vendor_or_class_req(irp);
- break;
-
- /* rest are synchronous */
- case URB_FUNCTION_SELECT_CONFIGURATION:
- status = wrap_select_configuration(wd, nt_urb, irp);
- NT_URB_STATUS(nt_urb) = status;
- break;
-
- case URB_FUNCTION_SELECT_INTERFACE:
- status = wrap_select_interface(wd, nt_urb, irp);
- NT_URB_STATUS(nt_urb) = status;
- break;
-
- case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
- status = wrap_get_descriptor(wd, nt_urb, irp);
- NT_URB_STATUS(nt_urb) = status;
- break;
-
- case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL:
- status = wrap_reset_pipe(udev, irp);
- NT_URB_STATUS(nt_urb) = status;
- break;
-
- case URB_FUNCTION_ABORT_PIPE:
- status = wrap_abort_pipe(udev, irp);
- break;
-
- case URB_FUNCTION_SET_FEATURE_TO_DEVICE:
- case URB_FUNCTION_SET_FEATURE_TO_INTERFACE:
- case URB_FUNCTION_SET_FEATURE_TO_ENDPOINT:
- case URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE:
- case URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE:
- case URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT:
- status = wrap_set_clear_feature(udev, irp);
- break;
-
- case URB_FUNCTION_GET_STATUS_FROM_DEVICE:
- case URB_FUNCTION_GET_STATUS_FROM_INTERFACE:
- case URB_FUNCTION_GET_STATUS_FROM_ENDPOINT:
- status = wrap_get_status_request(udev, irp);
- break;
-
- default:
- ERROR("function %x not implemented", nt_urb->header.function);
- status = NT_URB_STATUS(nt_urb) = USBD_STATUS_NOT_SUPPORTED;
- break;
- }
- USBTRACE("status: %08X", status);
- return status;
-}
-
-static USBD_STATUS wrap_reset_port(struct irp *irp)
-{
- no_warn_unused int ret, lock = 0;
- struct wrap_device *wd;
-
- wd = IRP_WRAP_DEVICE(irp);
- USBENTER("%p, %p", wd, wd->usb.udev);
- lock = usb_lock_device_for_reset(wd->usb.udev, wd->usb.intf);
- if (lock < 0) {
- WARNING("locking failed: %d", lock);
-// return wrap_urb_status(lock);
- return USBD_STATUS_SUCCESS;
- }
- ret = usb_reset_device(wd->usb.udev);
- if (ret < 0)
- USBTRACE("reset failed: %d", ret);
- /* TODO: should reconfigure? */
- if (lock)
- usb_unlock_device(wd->usb.udev);
-// return wrap_urb_status(ret);
- return USBD_STATUS_SUCCESS;
-}
-
-static USBD_STATUS wrap_get_port_status(struct irp *irp)
-{
- struct wrap_device *wd;
- ULONG *status;
- enum usb_device_state state;
-
- wd = IRP_WRAP_DEVICE(irp);
- USBENTER("%p, %p", wd, wd->usb.udev);
- status = IoGetCurrentIrpStackLocation(irp)->params.others.arg1;
- state = wd->usb.udev->state;
- if (state != USB_STATE_NOTATTACHED &&
- state != USB_STATE_SUSPENDED) {
- *status |= USBD_PORT_CONNECTED;
- if (state == USB_STATE_CONFIGURED)
- *status |= USBD_PORT_ENABLED;
- }
- USBTRACE("state: %d, *status: %08X", state, *status);
- return USBD_STATUS_SUCCESS;
-}
-
-NTSTATUS wrap_submit_irp(struct device_object *pdo, struct irp *irp)
-{
- struct io_stack_location *irp_sl;
- struct wrap_device *wd;
- USBD_STATUS status;
- struct usbd_idle_callback *idle_callback;
-
- USBENTER("%p, %p", pdo, irp);
- wd = pdo->reserved;
- if (wd->usb.intf == NULL) {
- USBTRACE("%p", irp);
- irp->io_status.status = STATUS_DEVICE_REMOVED;
- irp->io_status.info = 0;
- USBEXIT(return STATUS_DEVICE_REMOVED);
- }
- IRP_WRAP_DEVICE(irp) = wd;
- irp_sl = IoGetCurrentIrpStackLocation(irp);
- switch (irp_sl->params.dev_ioctl.code) {
- case IOCTL_INTERNAL_USB_SUBMIT_URB:
- status = wrap_process_nt_urb(irp);
- break;
- case IOCTL_INTERNAL_USB_RESET_PORT:
- status = wrap_reset_port(irp);
- break;
- case IOCTL_INTERNAL_USB_GET_PORT_STATUS:
- status = wrap_get_port_status(irp);
- break;
- case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION:
- idle_callback = irp_sl->params.dev_ioctl.type3_input_buf;
- USBTRACE("suspend function: %p", idle_callback->callback);
- status = USBD_STATUS_NOT_SUPPORTED;
- break;
- default:
- ERROR("ioctl %08X NOT IMPLEMENTED",
- irp_sl->params.dev_ioctl.code);
- status = USBD_STATUS_NOT_SUPPORTED;
- break;
- }
-
- USBTRACE("status: %08X", status);
- if (status == USBD_STATUS_PENDING) {
- /* don't touch this IRP - it may have been already
- * completed/returned */
- return STATUS_PENDING;
- } else {
- irp->io_status.status = nt_urb_irp_status(status);
- if (status != USBD_STATUS_SUCCESS)
- irp->io_status.info = 0;
- USBEXIT(return irp->io_status.status);
- }
-}
-
-/* TODO: The example on msdn in reference section suggests that second
- * argument should be an array of usbd_interface_information, but
- * description and examples elsewhere suggest that it should be
- * usbd_interface_list_entry structre. Which is correct? */
-
-wstdcall union nt_urb *WIN_FUNC(USBD_CreateConfigurationRequestEx,2)
- (struct usb_config_descriptor *config,
- struct usbd_interface_list_entry *intf_list)
-{
- int size, i, n;
- struct usbd_interface_information *intf;
- struct usbd_pipe_information *pipe;
- struct usb_interface_descriptor *intf_desc;
- struct usbd_select_configuration *select_conf;
-
- USBENTER("config = %p, intf_list = %p", config, intf_list);
-
- /* calculate size required; select_conf already has space for
- * one intf structure */
- size = sizeof(*select_conf) - sizeof(*intf);
- for (n = 0; n < config->bNumInterfaces; n++) {
- i = intf_list[n].intf_desc->bNumEndpoints;
- /* intf already has space for one pipe */
- size += sizeof(*intf) + (i - 1) * sizeof(*pipe);
- }
- /* don't use kmalloc - driver frees it with ExFreePool */
- select_conf = ExAllocatePoolWithTag(NonPagedPool, size,
- POOL_TAG('L', 'U', 'S', 'B'));
- if (!select_conf) {
- WARNING("couldn't allocate memory");
- return NULL;
- }
- memset(select_conf, 0, size);
- intf = &select_conf->intf;
- select_conf->handle = config;
- for (n = 0; n < config->bNumInterfaces && intf_list[n].intf_desc; n++) {
- /* initialize 'intf' fields in intf_list so they point
- * to appropriate entry; these may be read/written by
- * driver after this function returns */
- intf_list[n].intf = intf;
- intf_desc = intf_list[n].intf_desc;
-
- i = intf_desc->bNumEndpoints;
- intf->bLength = sizeof(*intf) + (i - 1) * sizeof(*pipe);
-
- intf->bInterfaceNumber = intf_desc->bInterfaceNumber;
- intf->bAlternateSetting = intf_desc->bAlternateSetting;
- intf->bInterfaceClass = intf_desc->bInterfaceClass;
- intf->bInterfaceSubClass = intf_desc->bInterfaceSubClass;
- intf->bInterfaceProtocol = intf_desc->bInterfaceProtocol;
- intf->bNumEndpoints = intf_desc->bNumEndpoints;
-
- pipe = &intf->pipes[0];
- for (i = 0; i < intf->bNumEndpoints; i++) {
- memset(&pipe[i], 0, sizeof(*pipe));
- pipe[i].max_tx_size =
- USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE;
- }
- intf->handle = intf_desc;
- intf = (((void *)intf) + intf->bLength);
- }
- select_conf->header.function = URB_FUNCTION_SELECT_CONFIGURATION;
- select_conf->header.length = size;
- select_conf->config = config;
- USBEXIT(return (union nt_urb *)select_conf);
-}
-
-WIN_SYMBOL_MAP("_USBD_CreateConfigurationRequestEx@8", USBD_CreateConfigurationRequestEx)
-
-wstdcall struct usb_interface_descriptor *
-WIN_FUNC(USBD_ParseConfigurationDescriptorEx,7)
- (struct usb_config_descriptor *config, void *start,
- LONG bInterfaceNumber, LONG bAlternateSetting, LONG bInterfaceClass,
- LONG bInterfaceSubClass, LONG bInterfaceProtocol)
-{
- void *pos;
- struct usb_interface_descriptor *intf;
-
- USBENTER("config = %p, start = %p, ifnum = %d, alt_setting = %d,"
- " class = %d, subclass = %d, proto = %d", config, start,
- bInterfaceNumber, bAlternateSetting, bInterfaceClass,
- bInterfaceSubClass, bInterfaceProtocol);
-
- for (pos = start;
- pos < ((void *)config + le16_to_cpu(config->wTotalLength));
- pos += intf->bLength) {
-
- intf = pos;
-
- if ((intf->bDescriptorType == USB_DT_INTERFACE) &&
- ((bInterfaceNumber == -1) ||
- (intf->bInterfaceNumber == bInterfaceNumber)) &&
- ((bAlternateSetting == -1) ||
- (intf->bAlternateSetting == bAlternateSetting)) &&
- ((bInterfaceClass == -1) ||
- (intf->bInterfaceClass == bInterfaceClass)) &&
- ((bInterfaceSubClass == -1) ||
- (intf->bInterfaceSubClass == bInterfaceSubClass)) &&
- ((bInterfaceProtocol == -1) ||
- (intf->bInterfaceProtocol == bInterfaceProtocol))) {
- USBTRACE("selected interface = %p", intf);
- USBEXIT(return intf);
- }
- }
- USBEXIT(return NULL);
-}
-
-WIN_SYMBOL_MAP("_USBD_ParseConfigurationDescriptorEx@28", USBD_ParseConfigurationDescriptorEx)
-
-wstdcall union nt_urb *WIN_FUNC(USBD_CreateConfigurationRequest,2)
- (struct usb_config_descriptor *config, USHORT *size)
-{
- union nt_urb *nt_urb;
- struct usbd_interface_list_entry intf_list[2];
- struct usb_interface_descriptor *intf_desc;
-
- USBENTER("config = %p, urb_size = %p", config, size);
-
- intf_desc = USBD_ParseConfigurationDescriptorEx(config, config, -1, -1,
- -1, -1, -1);
- intf_list[0].intf_desc = intf_desc;
- intf_list[0].intf = NULL;
- intf_list[1].intf_desc = NULL;
- intf_list[1].intf = NULL;
- nt_urb = USBD_CreateConfigurationRequestEx(config, intf_list);
- if (!nt_urb)
- return NULL;
-
- *size = nt_urb->select_conf.header.length;
- USBEXIT(return nt_urb);
-}
-
-wstdcall struct usb_interface_descriptor *
-WIN_FUNC(USBD_ParseConfigurationDescriptor,3)
- (struct usb_config_descriptor *config, UCHAR bInterfaceNumber,
- UCHAR bAlternateSetting)
-{
- return USBD_ParseConfigurationDescriptorEx(config, config,
- bInterfaceNumber,
- bAlternateSetting,
- -1, -1, -1);
-}
-
-wstdcall usb_common_descriptor_t *WIN_FUNC(USBD_ParseDescriptors,4)
- (void *buf, ULONG length, void *start, LONG type)
-{
- usb_common_descriptor_t *descr = start;
-
- while ((void *)descr < buf + length) {
- if (descr->bDescriptorType == type)
- return descr;
- if (descr->bLength == 0)
- break;
- descr = (void *)descr + descr->bLength;
- }
- USBEXIT(return NULL);
-}
-
-WIN_SYMBOL_MAP("_USBD_ParseDescriptors@16", USBD_ParseDescriptors)
-
-wstdcall void WIN_FUNC(USBD_GetUSBDIVersion,1)
- (struct usbd_version_info *version_info)
-{
- /* this function is obsolete in Windows XP */
- if (version_info) {
- version_info->usbdi_version = USBDI_VERSION_XP;
- /* TODO: how do we get this correctly? */
- version_info->supported_usb_version = 0x110;
- }
- USBEXIT(return);
-}
-
-wstdcall void
-USBD_InterfaceGetUSBDIVersion(void *context,
- struct usbd_version_info *version_info,
- ULONG *hcd_capa)
-{
- struct wrap_device *wd = context;
-
- if (version_info) {
- version_info->usbdi_version = USBDI_VERSION_XP;
- if (wd->usb.udev->speed == USB_SPEED_HIGH)
- version_info->supported_usb_version = 0x200;
- else
- version_info->supported_usb_version = 0x110;
- }
- *hcd_capa = USB_HCD_CAPS_SUPPORTS_RT_THREADS;
- USBEXIT(return);
-}
-
-wstdcall BOOLEAN USBD_InterfaceIsDeviceHighSpeed(void *context)
-{
- struct wrap_device *wd = context;
-
- USBTRACE("wd: %p", wd);
- if (wd->usb.udev->speed == USB_SPEED_HIGH)
- USBEXIT(return TRUE);
- else
- USBEXIT(return FALSE);
-}
-
-wstdcall void USBD_InterfaceReference(void *context)
-{
- USBTRACE("%p", context);
- TODO();
-}
-
-wstdcall void USBD_InterfaceDereference(void *context)
-{
- USBTRACE("%p", context);
- TODO();
-}
-
-wstdcall NTSTATUS USBD_InterfaceQueryBusTime(void *context, ULONG *frame)
-{
- struct wrap_device *wd = context;
-
- *frame = usb_get_current_frame_number(wd->usb.udev);
- USBEXIT(return STATUS_SUCCESS);
-}
-
-wstdcall NTSTATUS USBD_InterfaceSubmitIsoOutUrb(void *context,
- union nt_urb *nt_urb)
-{
- /* TODO: implement this */
- TODO();
- USBEXIT(return STATUS_NOT_IMPLEMENTED);
-}
-
-wstdcall NTSTATUS
-USBD_InterfaceQueryBusInformation(void *context, ULONG level, void *buf,
- ULONG *buf_length, ULONG *buf_actual_length)
-{
- struct wrap_device *wd = context;
- struct usb_bus_information_level *bus_info;
- struct usb_bus *bus;
-
- bus = wd->usb.udev->bus;
- bus_info = buf;
- TODO();
- USBEXIT(return STATUS_NOT_IMPLEMENTED);
-}
-
-wstdcall NTSTATUS
-USBD_InterfaceLogEntry(void *context, ULONG driver_tag, ULONG enum_tag,
- ULONG p1, ULONG p2)
-{
- ERROR("%p, %x, %x, %x, %x", context, driver_tag, enum_tag, p1, p2);
- USBEXIT(return STATUS_SUCCESS);
-}
-
-int usb_init(void)
-{
- InitializeListHead(&wrap_urb_complete_list);
- spin_lock_init(&wrap_urb_complete_list_lock);
- initialize_work(&wrap_urb_complete_work, wrap_urb_complete_worker, NULL);
-#ifdef USB_DEBUG
- urb_id = 0;
-#endif
- return 0;
-}
-
-void usb_exit(void)
-{
- USBEXIT(return);
-}
-
-int usb_init_device(struct wrap_device *wd)
-{
- InitializeListHead(&wd->usb.wrap_urb_list);
- wd->usb.num_alloc_urbs = 0;
- USBEXIT(return 0);
-}
-
-void usb_exit_device(struct wrap_device *wd)
-{
- kill_all_urbs(wd, 0);
- USBEXIT(return);
-}
+++ /dev/null
-/*
- * Copyright (C) 2004 Jan Kiszka
- * Copyright (C) 2005 Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef _USB_H_
-#define _USB_H_
-
-#include "ntoskernel.h"
-
-#define IOCTL_INTERNAL_USB_SUBMIT_URB 0x00220003
-#define IOCTL_INTERNAL_USB_RESET_PORT 0x00220007
-#define IOCTL_INTERNAL_USB_GET_PORT_STATUS 0x00220013
-#define IOCTL_INTERNAL_USB_CYCLE_PORT 0x0022001F
-#define IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION 0x00220027
-
-#define URB_FUNCTION_SELECT_CONFIGURATION 0x0000
-#define URB_FUNCTION_SELECT_INTERFACE 0x0001
-#define URB_FUNCTION_ABORT_PIPE 0x0002
-#define URB_FUNCTION_TAKE_FRAME_LENGTH_CONTROL 0x0003
-#define URB_FUNCTION_RELEASE_FRAME_LENGTH_CONTROL 0x0004
-#define URB_FUNCTION_GET_FRAME_LENGTH 0x0005
-#define URB_FUNCTION_SET_FRAME_LENGTH 0x0006
-#define URB_FUNCTION_GET_CURRENT_FRAME_NUMBER 0x0007
-#define URB_FUNCTION_CONTROL_TRANSFER 0x0008
-#define URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER 0x0009
-#define URB_FUNCTION_ISOCH_TRANSFER 0x000A
-#define URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE 0x000B
-#define URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE 0x000C
-#define URB_FUNCTION_SET_FEATURE_TO_DEVICE 0x000D
-#define URB_FUNCTION_SET_FEATURE_TO_INTERFACE 0x000E
-#define URB_FUNCTION_SET_FEATURE_TO_ENDPOINT 0x000F
-#define URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE 0x0010
-#define URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE 0x0011
-#define URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT 0x0012
-#define URB_FUNCTION_GET_STATUS_FROM_DEVICE 0x0013
-#define URB_FUNCTION_GET_STATUS_FROM_INTERFACE 0x0014
-#define URB_FUNCTION_GET_STATUS_FROM_ENDPOINT 0x0015
-#define URB_FUNCTION_RESERVED_0X0016 0x0016
-#define URB_FUNCTION_VENDOR_DEVICE 0x0017
-#define URB_FUNCTION_VENDOR_INTERFACE 0x0018
-#define URB_FUNCTION_VENDOR_ENDPOINT 0x0019
-#define URB_FUNCTION_CLASS_DEVICE 0x001A
-#define URB_FUNCTION_CLASS_INTERFACE 0x001B
-#define URB_FUNCTION_CLASS_ENDPOINT 0x001C
-#define URB_FUNCTION_RESERVE_0X001D 0x001D
-#define URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL 0x001E
-#define URB_FUNCTION_CLASS_OTHER 0x001F
-#define URB_FUNCTION_VENDOR_OTHER 0x0020
-#define URB_FUNCTION_GET_STATUS_FROM_OTHER 0x0021
-#define URB_FUNCTION_CLEAR_FEATURE_TO_OTHER 0x0022
-#define URB_FUNCTION_SET_FEATURE_TO_OTHER 0x0023
-#define URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT 0x0024
-#define URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT 0x0025
-#define URB_FUNCTION_GET_CONFIGURATION 0x0026
-#define URB_FUNCTION_GET_INTERFACE 0x0027
-#define URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE 0x0028
-#define URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE 0x0029
-#define URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR 0x002A
-#define URB_FUNCTION_RESERVE_0X002B 0x002B
-#define URB_FUNCTION_RESERVE_0X002C 0x002C
-#define URB_FUNCTION_RESERVE_0X002D 0x002D
-#define URB_FUNCTION_RESERVE_0X002E 0x002E
-#define URB_FUNCTION_RESERVE_0X002F 0x002F
-// USB 2.0 calls start at 0x0030
-#define URB_FUNCTION_SYNC_RESET_PIPE 0x0030
-#define URB_FUNCTION_SYNC_CLEAR_STALL 0x0031
-#define URB_FUNCTION_CONTROL_TRANSFER_EX 0x0032
-
-#define USBD_PF_CHANGE_MAX_PACKET 0x00000001
-
-#define USBD_TRANSFER_DIRECTION_OUT 0
-#define USBD_TRANSFER_DIRECTION_IN 1
-
-#define USBD_SHORT_TRANSFER_OK 0x00000002
-#define USBD_START_ISO_TRANSFER_ASAP 0x00000004
-#define USBD_DEFAULT_PIPE_TRANSFER 0x00000008
-
-#define USBD_TRANSFER_DIRECTION(flags) \
- ((flags) & USBD_TRANSFER_DIRECTION_IN)
-
-enum pipe_type {UsbdPipeTypeControl = USB_ENDPOINT_XFER_CONTROL,
- UsbdPipeTypeIsochronous = USB_ENDPOINT_XFER_ISOC,
- UsbdPipeTypeBulk = USB_ENDPOINT_XFER_BULK,
- UsbdPipeTypeInterrupt = USB_ENDPOINT_XFER_INT};
-
-#define USBD_IS_BULK_PIPE(pipe_handle) \
- (((pipe_handle)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) \
- == USB_ENDPOINT_XFER_BULK)
-
-#define USBD_IS_INT_PIPE(pipe_handle) \
- (((pipe_handle)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) \
- == USB_ENDPOINT_XFER_INT)
-
-#define USBD_PORT_ENABLED 0x00000001
-#define USBD_PORT_CONNECTED 0x00000002
-
-typedef LONG USBD_STATUS;
-
-#define USBD_STATUS_SUCCESS 0x0
-#define USBD_STATUS_PENDING 0x40000000
-#define USBD_STATUS_CANCELED 0x00010000
-
-#define USBD_STATUS_CRC 0xC0000001
-#define USBD_STATUS_BTSTUFF 0xC0000002
-#define USBD_STATUS_DATA_TOGGLE_MISMATCH 0xC0000003
-#define USBD_STATUS_STALL_PID 0xC0000004
-#define USBD_STATUS_DEV_NOT_RESPONDING 0xC0000005
-#define USBD_STATUS_PID_CHECK_FAILURE 0xC0000006
-#define USBD_STATUS_UNEXPECTED_PID 0xC0000007
-#define USBD_STATUS_DATA_OVERRUN 0xC0000008
-#define USBD_STATUS_DATA_UNDERRUN 0xC0000009
-#define USBD_STATUS_RESERVED1 0xC000000A
-#define USBD_STATUS_RESERVED2 0xC000000B
-#define USBD_STATUS_BUFFER_OVERRUN 0xC000000C
-#define USBD_STATUS_BUFFER_UNDERRUN 0xC000000D
-#define USBD_STATUS_NOT_ACCESSED 0xC000000F
-#define USBD_STATUS_FIFO 0xC0000010
-#define USBD_STATUS_XACT_ERROR 0xC0000011
-#define USBD_STATUS_BABBLE_DETECTED 0xC0000012
-#define USBD_STATUS_DATA_BUFFER_ERROR 0xC0000013
-
-#define USBD_STATUS_NOT_SUPPORTED 0xC0000E00
-#define USBD_STATUS_BUFFER_TOO_SMALL 0xC0003000
-#define USBD_STATUS_TIMEOUT 0xC0006000
-#define USBD_STATUS_DEVICE_GONE 0xC0007000
-
-#define USBD_STATUS_NO_MEMORY 0x80000100
-#define USBD_STATUS_INVALID_URB_FUNCTION 0x80000200
-#define USBD_STATUS_INVALID_PARAMETER 0x80000300
-#define USBD_STATUS_REQUEST_FAILED 0x80000500
-#define USBD_STATUS_INVALID_PIPE_HANDLE 0x80000600
-#define USBD_STATUS_ERROR_SHORT_TRANSFER 0x80000900
-
-#define USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE PAGE_SIZE
-
-struct urb_hcd_area {
- void *reserved8[8];
-};
-
-typedef struct usb_endpoint_descriptor *usbd_pipe_handle;
-typedef struct usb_descriptor_header usb_common_descriptor_t;
-
-struct usbd_pipe_information {
- USHORT wMaxPacketSize;
- UCHAR bEndpointAddress;
- UCHAR bInterval;
- enum pipe_type type;
- usbd_pipe_handle handle;
- ULONG max_tx_size;
- ULONG flags;
-};
-
-struct usbd_interface_information {
- USHORT bLength;
- UCHAR bInterfaceNumber;
- UCHAR bAlternateSetting;
- UCHAR bInterfaceClass;
- UCHAR bInterfaceSubClass;
- UCHAR bInterfaceProtocol;
- UCHAR reserved;
- void *handle;
- ULONG bNumEndpoints;
- struct usbd_pipe_information pipes[1];
-};
-
-struct usbd_interface_list_entry {
- struct usb_interface_descriptor *intf_desc;
- struct usbd_interface_information *intf;
-};
-
-struct nt_urb_header {
- USHORT length;
- USHORT function;
- USBD_STATUS status;
- void *usbd_dev_handle;
- ULONG usbd_flags;
-};
-
-struct usbd_select_interface {
- struct nt_urb_header header;
- void *handle;
- struct usbd_interface_information intf;
-};
-
-struct usbd_select_configuration {
- struct nt_urb_header header;
- struct usb_config_descriptor *config;
- void *handle;
- struct usbd_interface_information intf;
-};
-
-struct usbd_control_descriptor_request {
- struct nt_urb_header header;
- void *reserved;
- ULONG reserved0;
- ULONG transfer_buffer_length;
- void *transfer_buffer;
- struct mdl *mdl;
- union nt_urb *urb_link;
- struct urb_hcd_area hca;
- USHORT reserved1;
- UCHAR index;
- UCHAR desc_type;
- USHORT language_id;
- USHORT reserved2;
-};
-
-struct usbd_bulk_or_intr_transfer {
- struct nt_urb_header header;
- usbd_pipe_handle pipe_handle;
- ULONG transfer_flags;
- ULONG transfer_buffer_length;
- void *transfer_buffer;
- struct mdl *mdl;
- union nt_urb *urb_link;
- struct urb_hcd_area hca;
-};
-
-struct usbd_pipe_request {
- struct nt_urb_header header;
- usbd_pipe_handle pipe_handle;
-};
-
-struct usbd_vendor_or_class_request {
- struct nt_urb_header header;
- void *reserved;
- ULONG transfer_flags;
- ULONG transfer_buffer_length;
- void *transfer_buffer;
- struct mdl *mdl;
- union nt_urb *link;
- struct urb_hcd_area hca;
- UCHAR reserved_bits;
- UCHAR request;
- USHORT value;
- USHORT index;
- USHORT reserved1;
-};
-
-struct urb_control_feature_request {
- struct nt_urb_header header;
- void *reserved;
- ULONG reserved2;
- ULONG reserved3;
- void *reserved4;
- struct mdl *reserved5;
- union nt_urb *link;
- struct urb_hcd_area hca;
- USHORT reserved0;
- USHORT feature_selector;
- USHORT index;
- USHORT reserved1;
-};
-
-struct urb_control_get_status_request {
- struct nt_urb_header header;
- void *reserved;
- ULONG reserved0;
- ULONG transfer_buffer_length;
- void *transfer_buffer;
- struct mdl *mdl;
- union nt_urb *link;
- struct urb_hcd_area hca;
- UCHAR reserved1[4];
- USHORT index;
- USHORT reserved2;
-};
-
-struct usbd_iso_packet_desc {
- ULONG offset;
- ULONG length;
- USBD_STATUS status;
-};
-
-struct usbd_isochronous_transfer {
- struct nt_urb_header header;
- usbd_pipe_handle pipe_handle;
- ULONG transfer_flags;
- ULONG transfer_buffer_length;
- void *transfer_buffer;
- struct mdl *mdl;
- union nt_urb *urb_link;
- struct urb_hcd_area hca;
- ULONG start_frame;
- ULONG number_of_packets;
- ULONG error_count;
- struct usbd_iso_packet_desc iso_packet[1];
-};
-
-union nt_urb {
- struct nt_urb_header header;
- struct usbd_select_interface select_intf;
- struct usbd_select_configuration select_conf;
- struct usbd_bulk_or_intr_transfer bulk_int_transfer;
- struct usbd_control_descriptor_request control_desc;
- struct usbd_vendor_or_class_request vendor_class_request;
- struct usbd_isochronous_transfer isochronous;
- struct usbd_pipe_request pipe_req;
- struct urb_control_feature_request feat_req;
- struct urb_control_get_status_request status_req;
-};
-
-struct usbd_bus_interface_usbdi {
- USHORT Size;
- USHORT Version;
- void *Context;
- void *InterfaceReference;
- void *InterfaceDereference;
- void *GetUSBDIVersion;
- void *QueryBusTime;
- void *SubmitIsoOutUrb;
- void *QueryBusInformation;
- /* version 1 and above have following field */
- void *IsDeviceHighSpeed;
- /* version 2 (and above) have following field */
- void *LogEntry;
-};
-
-struct usbd_bus_information_level {
- ULONG TotalBandwidth;
- ULONG ConsumedBandwidth;
- /* level 1 and above have following fields */
- ULONG ControllerNameLength;
- wchar_t ControllerName[1];
-};
-
-#define USBDI_VERSION_XP 0x00000500 // Windows XP
-#define USB_HCD_CAPS_SUPPORTS_RT_THREADS 0x00000001
-#define USB_BUSIF_USBDI_VERSION_0 0x0000
-#define USB_BUSIF_USBDI_VERSION_1 0x0001
-#define USB_BUSIF_USBDI_VERSION_2 0x0002
-
-struct usbd_version_info {
- ULONG usbdi_version;
- ULONG supported_usb_version;
-};
-
-struct usbd_idle_callback {
- void *callback;
- void *context;
-};
-
-#define NT_URB_STATUS(nt_urb) ((nt_urb)->header.status)
-
-NTSTATUS wrap_submit_irp(struct device_object *pdo, struct irp *irp);
-void wrap_suspend_urbs(struct wrap_device *wd);
-void wrap_resume_urbs(struct wrap_device *wd);
-
-void USBD_InterfaceGetUSBDIVersion(void *context,
- struct usbd_version_info *version_info,
- ULONG *hcd_capa) wstdcall;
-BOOLEAN USBD_InterfaceIsDeviceHighSpeed(void *context) wstdcall;
-void USBD_InterfaceReference(void *context) wstdcall;
-void USBD_InterfaceDereference(void *context) wstdcall;
-NTSTATUS USBD_InterfaceQueryBusTime(void *context, ULONG *frame) wstdcall;
-NTSTATUS USBD_InterfaceSubmitIsoOutUrb(void *context,
- union nt_urb *nt_urb) wstdcall;
-NTSTATUS USBD_InterfaceQueryBusInformation(void *context, ULONG level, void *buf,
- ULONG *buf_length,
- ULONG *buf_actual_length) wstdcall;
-NTSTATUS USBD_InterfaceLogEntry(void *context, ULONG driver_tag, ULONG enum_tag,
- ULONG p1, ULONG p2) wstdcall;
-
-#endif /* USB_H */
+++ /dev/null
-/*
- * Copyright (C) 2005 Karl Vogel, Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/linkage.h>
-
-#ifdef CONFIG_X86_64
-
-/*
-# Windows <---> Linux register usage conversion when calling functions
-# V = Volatile
-# NV = Non Volatile (needs to be saved)
-#
-# Win Lin
-# ---------------------------------------
-# Rax Return V Return V
-# Rbx NV NV
-# Rcx Arg1 V Arg4 V
-# Rdx Arg2 V Arg3 V
-# Rsi NV Arg2 V
-# Rdi NV Arg1 V
-# Rsp NV NV
-# Rbp NV NV
-# R8 Arg3 V Arg5 V
-# R9 Arg4 V Arg6 V
-# R10 V V
-# R11 V V
-# R12 NV NV
-# R13 NV NV
-# R14 NV NV
-# R15 NV NV
-#
-# In addition, Linux uses %rax to indicate number of SSE registers used
-# when variadic functions are called. Since there is no way to obtain this
-# from Windows, for now, we just assume this is 0 (hence %rax is cleared).
-#
-# Windows pushes arguments 5 and higher onto stack in case of integer
-# variables and 4 and higher in case of floating point variabes (passed
-# in SSE registers).
-
-In a windows function, the stackframe/registers look like this:
-
-# 0x0048 ....
-# 0x0040 arg8
-# 0x0038 arg7
-# 0x0030 arg6
-# 0x0028 arg5
-# 0x0020 shadow/spill space for arg4
-# 0x0018 shadow/spill space for arg3
-# 0x0010 shadow/spill space for arg2
-# 0x0008 shadow/spill space for arg1
-# 0x0000 ret
-
-# register spill space is same irrespective of number of arguments - even
-# if Windows function takes less than 4 arguments, 32 bytes above return
-# address is reserved for the function
-
-In Linux it should look like:
-
-# 0x0018 ....
-# 0x0010 arg8
-# 0x0008 arg7
-# 0x0000 ret
-
-*/
-
-#
-# setup for Windows to Linux function call
-#
-
- .text
-
-.macro win2lin_prolog
- push %rsi
- push %rdi
-.endm
-
-.macro win2lin_epilog
- pop %rdi
- pop %rsi
-.endm
-
-# when Windows function calls Linux function, the function address is in %r10
-
-.macro call_lin_func
- xor %rax, %rax # rax indicates number of SSE regs
- call *%r10
-.endm
-
-# before prolog, 0(%rsp) is return address, 8(%rsp) would be arg1
-# (but it is in register) and so on, so n'th arg would be at n*8(%rsp)
-# for n > 4. But in prolog, we push 2 registers that are non-volaile in
-# Windows, but volatile in Linux. So after prolog, args are at (n+2)*8(%rsp)
-
-#define win2lin_win_arg(n) (n+2)*8(%rsp)
-
-#define win2lin_arg1 mov %rcx, %rdi
-#define win2lin_arg2 mov %rdx, %rsi
-#define win2lin_arg3 mov %r8, %rdx
-#define win2lin_arg4 mov %r9, %rcx
-#define win2lin_arg5 mov win2lin_win_arg(5), %r8
-#define win2lin_arg6 mov win2lin_win_arg(6), %r9
-
- .type win2lin0, @function
-win2lin0:
- win2lin_prolog
- call_lin_func
- win2lin_epilog
- ret
- .size win2lin0, .-win2lin0
-
- .type win2lin1, @function
-win2lin1:
- win2lin_prolog
- win2lin_arg1
- call_lin_func
- win2lin_epilog
- ret
- .size win2lin1, .-win2lin1
-
- .type win2lin2, @function
-win2lin2:
- win2lin_prolog
- win2lin_arg1
- win2lin_arg2
- call_lin_func
- win2lin_epilog
- ret
- .size win2lin2, .-win2lin2
-
- .type win2lin3, @function
-win2lin3:
- win2lin_prolog
- win2lin_arg1
- win2lin_arg2
- win2lin_arg3
- call_lin_func
- win2lin_epilog
- ret
- .size win2lin3, .-win2lin3
-
- .type win2lin4, @function
-win2lin4:
- win2lin_prolog
- win2lin_arg1
- win2lin_arg2
- win2lin_arg3
- win2lin_arg4
- call_lin_func
- win2lin_epilog
- ret
- .size win2lin4, .-win2lin4
-
- .type win2lin5, @function
-win2lin5:
- win2lin_prolog
- win2lin_arg1
- win2lin_arg2
- win2lin_arg3
- win2lin_arg4
- win2lin_arg5
- call_lin_func
- win2lin_epilog
- ret
- .size win2lin5, .-win2lin5
-
- .type win2lin6, @function
-win2lin6:
- win2lin_prolog
- win2lin_arg1
- win2lin_arg2
- win2lin_arg3
- win2lin_arg4
- win2lin_arg5
- win2lin_arg6
- call_lin_func
- win2lin_epilog
- ret
- .size win2lin6, .-win2lin6
-
-# Allocate stack frame for Linux arguments before calling function.
-# First 6 args are passed through registers, so we need space for 7 and above.
-# The arguments should have been copied onto stack already.
-
-.macro call_lin_func_args n
- sub $(\n-6)*8, %rsp
- call_lin_func
- add $(\n-6)*8, %rsp
- .endm
-
-# m is index of Linux arg required, n is total number of args to function
-# After stack frame is allocated, Linux arg 7 should be at 0(%rsp),
-# arg 8 should be at 1*8(%rsp) and so on. So Linux arg m should be at (m-7)*8
-# Stack frame starts at -(n-6)*8(%rsp), so before stack frame is allocated
-# Linux arg m should be at (6-n+m-7)*8(%rsp)
-
-#define win2lin_lin_arg(m,n) (m-1-n)*8(%rsp)
-
- .type win2lin7, @function
-win2lin7:
- win2lin_prolog
-
- win2lin_arg1
- win2lin_arg2
- win2lin_arg3
- win2lin_arg4
- win2lin_arg5
- win2lin_arg6
-
- # copy windows argument 7 onto stack for Linux function
- mov win2lin_win_arg(7), %r11
- mov %r11, win2lin_lin_arg(7,7)
-
- call_lin_func_args(7)
- win2lin_epilog
- ret
- .size win2lin7, .-win2lin7
-
- .type win2lin8, @function
-win2lin8:
- win2lin_prolog
-
- win2lin_arg1
- win2lin_arg2
- win2lin_arg3
- win2lin_arg4
- win2lin_arg5
- win2lin_arg6
-
- # copy windows arguments 7 and 8 onto stack for Linux function
- mov win2lin_win_arg(7), %r11
- mov %r11, win2lin_lin_arg(7,8)
- mov win2lin_win_arg(8), %r11
- mov %r11, win2lin_lin_arg(8,8)
-
- call_lin_func_args(8)
- win2lin_epilog
- ret
- .size win2lin8, .-win2lin8
-
- .type win2lin9, @function
-win2lin9:
-win2lin10:
-win2lin11:
-win2lin12:
- win2lin_prolog
-
- # since we destroy rsi and rdi here, first copy windows
- # arguments 7 through 12 onto stack for Linux function
- mov %rcx, %r11 # save rcx
- lea win2lin_win_arg(7), %rsi # source (windows arg 7 and up)
- lea win2lin_lin_arg(7,12), %rdi # = destination
- mov $6, %rcx # 6 arguments
- rep
- movsq
- mov %r11, %rcx # restore rcx
-
- win2lin_arg1
- win2lin_arg2
- win2lin_arg3
- win2lin_arg4
- win2lin_arg5
- win2lin_arg6
-
- call_lin_func_args(12)
- win2lin_epilog
- ret
- .size win2lin9, .-win2lin9
-
-#define win2lin(name, argc) \
-ENTRY(win2lin_ ## name ## _ ## argc) \
- lea name(%rip), %r10 ; \
- jmp win2lin ## argc
-
-#include "win2lin_stubs.h"
-
-#endif // CONFIG_X86_64
+++ /dev/null
-/*
- * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef _WINNT_TYPES_H_
-#define _WINNT_TYPES_H_
-
-#define TRUE 1
-#define FALSE 0
-
-#define PASSIVE_LEVEL 0
-#define APC_LEVEL 1
-#define DISPATCH_LEVEL 2
-#define DEVICE_LEVEL_BASE 4
-
-/* soft interrupts / bottom-half's are disabled at SOFT_IRQL */
-#define SOFT_IRQL (DEVICE_LEVEL_BASE + 1)
-#define DIRQL (DEVICE_LEVEL_BASE + 2)
-
-#define STATUS_WAIT_0 0
-#define STATUS_SUCCESS 0
-#define STATUS_ALERTED 0x00000101
-#define STATUS_TIMEOUT 0x00000102
-#define STATUS_PENDING 0x00000103
-#define STATUS_FAILURE 0xC0000001
-#define STATUS_NOT_IMPLEMENTED 0xC0000002
-#define STATUS_INVALID_PARAMETER 0xC000000D
-#define STATUS_INVALID_DEVICE_REQUEST 0xC0000010
-#define STATUS_MORE_PROCESSING_REQUIRED 0xC0000016
-#define STATUS_ACCESS_DENIED 0xC0000022
-#define STATUS_BUFFER_TOO_SMALL 0xC0000023
-#define STATUS_OBJECT_NAME_INVALID 0xC0000023
-#define STATUS_MUTANT_NOT_OWNED 0xC0000046
-#define STATUS_RESOURCES 0xC000009A
-#define STATUS_DELETE_PENDING 0xC0000056
-#define STATUS_INSUFFICIENT_RESOURCES 0xC000009A
-#define STATUS_NOT_SUPPORTED 0xC00000BB
-#define STATUS_INVALID_PARAMETER_2 0xC00000F0
-#define STATUS_NO_MEMORY 0xC0000017
-#define STATUS_CANCELLED 0xC0000120
-#define STATUS_DEVICE_REMOVED 0xC00002B6
-#define STATUS_DEVICE_NOT_CONNECTED 0xC000009D
-
-#define STATUS_BUFFER_OVERFLOW 0x80000005
-
-#define SL_PENDING_RETURNED 0x01
-#define SL_INVOKE_ON_CANCEL 0x20
-#define SL_INVOKE_ON_SUCCESS 0x40
-#define SL_INVOKE_ON_ERROR 0x80
-
-#define IRP_MJ_CREATE 0x00
-#define IRP_MJ_CREATE_NAMED_PIPE 0x01
-#define IRP_MJ_CLOSE 0x02
-#define IRP_MJ_READ 0x03
-#define IRP_MJ_WRITE 0x04
-
-#define IRP_MJ_DEVICE_CONTROL 0x0E
-#define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0F
-#define IRP_MJ_POWER 0x16
-#define IRP_MJ_SYSTEM_CONTROL 0x0E
-#define IRP_MJ_PNP 0x1b
-#define IRP_MJ_MAXIMUM_FUNCTION 0x1b
-
-#define IRP_MN_WAIT_WAKE 0x00
-#define IRP_MN_POWER_SEQUENCE 0x01
-#define IRP_MN_SET_POWER 0x02
-#define IRP_MN_QUERY_POWER 0x03
-
-#define IRP_MN_REGINFO 0x08
-#define IRP_MN_REGINFO_EX 0x0b
-
-#define IRP_MN_START_DEVICE 0x00
-#define IRP_MN_QUERY_REMOVE_DEVICE 0x01
-#define IRP_MN_REMOVE_DEVICE 0x02
-#define IRP_MN_CANCEL_REMOVE_DEVICE 0x03
-#define IRP_MN_STOP_DEVICE 0x04
-#define IRP_MN_QUERY_STOP_DEVICE 0x05
-#define IRP_MN_CANCEL_STOP_DEVICE 0x06
-#define IRP_MN_QUERY_DEVICE_RELATIONS 0x07
-#define IRP_MN_QUERY_INTERFACE 0x08
-
-#define IRP_BUFFERED_IO 0x00000010
-#define IRP_DEALLOCATE_BUFFER 0x00000020
-#define IRP_INPUT_OPERATION 0x00000040
-
-#define IRP_DEFFER_IO_COMPLETION 0x00000800
-
-#define THREAD_WAIT_OBJECTS 3
-#define MAX_WAIT_OBJECTS 64
-
-#define LOW_PRIORITY 0
-#define LOW_REALTIME_PRIORITY 16
-#define HIGH_PRIORITY 31
-#define MAXIMUM_PRIORITY 32
-
-#define PROCESSOR_FEATURE_MAX 64
-
-#define IO_NO_INCREMENT 0
-
-#define WMIREG_ACTION_REGISTER 1
-#define WMIREG_ACTION_DEREGISTER 2
-#define WMIREG_ACTION_REREGISTER 3
-#define WMIREG_ACTION_UPDATE_GUIDS 4
-
-#define WMIREGISTER 0
-#define WMIUPDATE 1
-
-#ifdef CONFIG_X86_64
-#define wstdcall
-#define wfastcall
-#define noregparm
-
-#define KI_USER_SHARED_DATA 0xfffff78000000000UL
-
-#else
-
-#define noregparm __attribute__((regparm(0)))
-#define wstdcall __attribute__((__stdcall__, regparm(0)))
-#if defined(__GNUC__) && ((__GNUC__ == 3 && __GNUC_MINOR__ > 3) || __GNUC__ > 3)
-#undef fastcall
-#define wfastcall __attribute__((fastcall))
-#else
-#error "gcc 3.4 or newer should be used for compiling this module"
-#endif
-
-#define KI_USER_SHARED_DATA 0xffdf0000
-
-#endif
-
-// #define packed __attribute__((packed))
-#define no_warn_unused __attribute__((unused))
-
-typedef u8 BOOLEAN;
-typedef u8 BYTE;
-typedef u8 *LPBYTE;
-typedef s8 CHAR;
-typedef u8 UCHAR;
-typedef s16 SHORT;
-typedef u16 USHORT;
-typedef u16 WORD;
-typedef s32 INT;
-typedef u32 UINT;
-typedef u32 DWORD;
-typedef s32 LONG;
-typedef u32 ULONG;
-typedef s64 LONGLONG;
-typedef u64 ULONGLONG;
-typedef u64 ULONGULONG;
-typedef u64 ULONG64;
-
-typedef CHAR CCHAR;
-typedef USHORT wchar_t;
-typedef SHORT CSHORT;
-typedef LONGLONG LARGE_INTEGER;
-
-typedef LONG NTSTATUS;
-
-typedef LONG KPRIORITY;
-typedef LARGE_INTEGER PHYSICAL_ADDRESS;
-typedef UCHAR KIRQL;
-typedef CHAR KPROCESSOR_MODE;
-
-/* ULONG_PTR is 32 bits on 32-bit platforms and 64 bits on 64-bit
- * platform, which is same as 'unsigned long' in Linux */
-typedef unsigned long ULONG_PTR;
-
-typedef ULONG_PTR SIZE_T;
-typedef ULONG_PTR KAFFINITY;
-typedef ULONG ACCESS_MASK;
-
-typedef ULONG_PTR PFN_NUMBER;
-typedef ULONG SECURITY_INFORMATION;
-
-/* non-negative numbers indicate success */
-#define NT_SUCCESS(status) ((NTSTATUS)(status) >= 0)
-
-struct ansi_string {
- USHORT length;
- USHORT max_length;
- char *buf;
-};
-
-struct unicode_string {
- USHORT length;
- USHORT max_length;
- wchar_t *buf;
-};
-
-struct nt_slist {
- struct nt_slist *next;
-};
-
-#ifdef CONFIG_X86_64
-/* it is not clear how nt_slist_head is used to store pointer to
- * slists and depth; here we assume 'align' field is used to store
- * depth and 'region' field is used to store slist pointers */
-struct nt_slist_head {
- union {
- USHORT depth;
- ULONGLONG align;
- };
- union {
- ULONGLONG region;
- struct nt_slist *next;
- };
-} __attribute__((aligned(16)));
-typedef struct nt_slist_head nt_slist_header;
-#else
-union nt_slist_head {
- ULONGLONG align;
- struct {
- struct nt_slist *next;
- USHORT depth;
- USHORT sequence;
- };
-};
-typedef union nt_slist_head nt_slist_header;
-#endif
-
-struct nt_list {
- struct nt_list *next;
- struct nt_list *prev;
-};
-
-typedef ULONG_PTR NT_SPIN_LOCK;
-
-enum kdpc_importance {LowImportance, MediumImportance, HighImportance};
-
-struct kdpc;
-typedef void (*DPC)(struct kdpc *kdpc, void *ctx, void *arg1,
- void *arg2) wstdcall;
-struct kdpc {
- SHORT type;
- UCHAR nr_cpu;
- UCHAR importance;
- struct nt_list list;
- DPC func;
- void *ctx;
- void *arg1;
- void *arg2;
- union {
- NT_SPIN_LOCK *lock;
- /* 'lock' is not used; 'queued' represents whether
- * kdpc is queued or not */
- int queued;
- };
-};
-
-enum pool_type {
- NonPagedPool, PagedPool, NonPagedPoolMustSucceed, DontUseThisType,
- NonPagedPoolCacheAligned, PagedPoolCacheAligned,
- NonPagedPoolCacheAlignedMustS, MaxPoolType,
- NonPagedPoolSession = 32,
- PagedPoolSession = NonPagedPoolSession + 1,
- NonPagedPoolMustSucceedSession = PagedPoolSession + 1,
- DontUseThisTypeSession = NonPagedPoolMustSucceedSession + 1,
- NonPagedPoolCacheAlignedSession = DontUseThisTypeSession + 1,
- PagedPoolCacheAlignedSession = NonPagedPoolCacheAlignedSession + 1,
- NonPagedPoolCacheAlignedMustSSession = PagedPoolCacheAlignedSession + 1
-};
-
-enum memory_caching_type_orig {
- MmFrameBufferCached = 2
-};
-
-enum memory_caching_type {
- MmNonCached = FALSE, MmCached = TRUE,
- MmWriteCombined = MmFrameBufferCached, MmHardwareCoherentCached,
- MmNonCachedUnordered, MmUSWCCached, MmMaximumCacheType
-};
-
-enum lock_operation {
- IoReadAccess, IoWriteAccess, IoModifyAccess
-};
-
-enum mode {
- KernelMode, UserMode, MaximumMode
-};
-
-struct mdl {
- struct mdl *next;
- CSHORT size;
- CSHORT flags;
- /* NdisFreeBuffer doesn't pass pool, so we store pool in
- * unused field 'process' */
- union {
- void *process;
- void *pool;
- };
- void *mappedsystemva;
- void *startva;
- ULONG bytecount;
- ULONG byteoffset;
-};
-
-#define MDL_MAPPED_TO_SYSTEM_VA 0x0001
-#define MDL_PAGES_LOCKED 0x0002
-#define MDL_SOURCE_IS_NONPAGED_POOL 0x0004
-#define MDL_ALLOCATED_FIXED_SIZE 0x0008
-#define MDL_PARTIAL 0x0010
-#define MDL_PARTIAL_HAS_BEEN_MAPPED 0x0020
-#define MDL_IO_PAGE_READ 0x0040
-#define MDL_WRITE_OPERATION 0x0080
-#define MDL_PARENT_MAPPED_SYSTEM_VA 0x0100
-#define MDL_FREE_EXTRA_PTES 0x0200
-#define MDL_IO_SPACE 0x0800
-#define MDL_NETWORK_HEADER 0x1000
-#define MDL_MAPPING_CAN_FAIL 0x2000
-#define MDL_ALLOCATED_MUST_SUCCEED 0x4000
-
-#define MDL_POOL_ALLOCATED 0x0400
-#define MDL_CACHE_ALLOCATED 0x8000
-
-#define PAGE_START(ptr) ((void *)((ULONG_PTR)(ptr) & ~(PAGE_SIZE - 1)))
-#define BYTE_OFFSET(ptr) ((ULONG)((ULONG_PTR)(ptr) & (PAGE_SIZE - 1)))
-
-#define MmGetMdlByteCount(mdl) ((mdl)->bytecount)
-#define MmGetMdlVirtualAddress(mdl) ((mdl)->startva + (mdl)->byteoffset)
-#define MmGetMdlByteOffset(mdl) ((mdl)->byteoffset)
-#define MmGetSystemAddressForMdl(mdl) ((mdl)->mappedsystemva)
-#define MmGetSystemAddressForMdlSafe(mdl, priority) ((mdl)->mappedsystemva)
-#define MmGetMdlPfnArray(mdl) ((PFN_NUMBER *)(mdl + 1))
-#define MmInitializeMdl(mdl, baseva, length) \
-do { \
- (mdl)->next = NULL; \
- (mdl)->size = MmSizeOfMdl(baseva, length); \
- (mdl)->flags = 0; \
- (mdl)->startva = PAGE_START(baseva); \
- (mdl)->byteoffset = BYTE_OFFSET(baseva); \
- (mdl)->bytecount = length; \
- (mdl)->mappedsystemva = baseva; \
- TRACE4("%p %p %p %d %d", (mdl), baseva, (mdl)->startva, \
- (mdl)->byteoffset, length); \
-} while (0)
-
-struct kdevice_queue_entry {
- struct nt_list list;
- ULONG sort_key;
- BOOLEAN inserted;
-};
-
-struct kdevice_queue {
- USHORT type;
- USHORT size;
- struct nt_list list;
- NT_SPIN_LOCK lock;
- BOOLEAN busy;
-};
-
-struct wait_context_block {
- struct kdevice_queue_entry wait_queue_entry;
- void *device_routine;
- void *device_context;
- ULONG num_regs;
- void *device_object;
- void *current_irp;
- void *buffer_chaining_dpc;
-};
-
-struct wait_block {
- struct nt_list list;
- struct task_struct *thread;
- void *object;
- int *wait_done;
- USHORT wait_key;
- USHORT wait_type;
-};
-
-struct dispatcher_header {
- UCHAR type;
- UCHAR absolute;
- UCHAR size;
- UCHAR inserted;
- LONG signal_state;
- struct nt_list wait_blocks;
-};
-
-enum event_type {
- NotificationEvent,
- SynchronizationEvent,
-};
-
-enum timer_type {
- NotificationTimer = NotificationEvent,
- SynchronizationTimer = SynchronizationEvent,
-};
-
-enum dh_type {
- NotificationObject = NotificationEvent,
- SynchronizationObject = SynchronizationEvent,
- MutexObject,
- SemaphoreObject,
- ThreadObject,
-};
-
-enum wait_type {
- WaitAll, WaitAny
-};
-
-/* objects that use dispatcher_header have it as the first field, so
- * whenever we need to initialize dispatcher_header, we can convert
- * that object into a nt_event and access dispatcher_header */
-struct nt_event {
- struct dispatcher_header dh;
-};
-
-struct wrap_timer;
-
-#define WRAP_TIMER_MAGIC 47697249
-
-struct nt_timer {
- struct dispatcher_header dh;
- /* We can't fit Linux timer in this structure. Instead of
- * padding the nt_timer structure, we replace due_time field
- * with *wrap_timer and allocate memory for it when nt_timer is
- * initialized */
- union {
- ULONGLONG due_time;
- struct wrap_timer *wrap_timer;
- };
- struct nt_list nt_timer_list;
- struct kdpc *kdpc;
- union {
- LONG period;
- LONG wrap_timer_magic;
- };
-};
-
-struct nt_mutex {
- struct dispatcher_header dh;
- struct nt_list list;
- struct task_struct *owner_thread;
- BOOLEAN abandoned;
- BOOLEAN apc_disable;
-};
-
-struct nt_semaphore {
- struct dispatcher_header dh;
- LONG limit;
-};
-
-struct nt_thread {
- struct dispatcher_header dh;
- /* the rest in Windows is a long structure; since this
- * structure is opaque to drivers, we just define what we
- * need */
- int pid;
- NTSTATUS status;
- struct task_struct *task;
- struct nt_list irps;
- NT_SPIN_LOCK lock;
- KPRIORITY prio;
-};
-
-#define set_object_type(dh, type) ((dh)->type = (type))
-#define is_notify_object(dh) ((dh)->type == NotificationObject)
-#define is_synch_object(dh) ((dh)->type == SynchronizationObject)
-#define is_mutex_object(dh) ((dh)->type == MutexObject)
-#define is_semaphore_object(dh) ((dh)->type == SemaphoreObject)
-#define is_nt_thread_object(dh) ((dh)->type == ThreadObject)
-
-#define IO_TYPE_ADAPTER 1
-#define IO_TYPE_CONTROLLER 2
-#define IO_TYPE_DEVICE 3
-#define IO_TYPE_DRIVER 4
-#define IO_TYPE_FILE 5
-#define IO_TYPE_IRP 6
-#define IO_TYPE_DEVICE_OBJECT_EXTENSION 13
-
-struct irp;
-struct dev_obj_ext;
-struct driver_object;
-
-struct device_object {
- CSHORT type;
- USHORT size;
- LONG ref_count;
- struct driver_object *drv_obj;
- struct device_object *next;
- struct device_object *attached;
- struct irp *current_irp;
- void *io_timer;
- ULONG flags;
- ULONG characteristics;
- void *vpb;
- void *dev_ext;
- CCHAR stack_count;
- union {
- struct nt_list queue_list;
- struct wait_context_block wcb;
- } queue;
- ULONG align_req;
- struct kdevice_queue dev_queue;
- struct kdpc dpc;
- ULONG active_threads;
- void *security_desc;
- struct nt_event lock;
- USHORT sector_size;
- USHORT spare1;
- struct dev_obj_ext *dev_obj_ext;
- void *reserved;
-};
-
-struct dev_obj_ext {
- CSHORT type;
- CSHORT size;
- struct device_object *dev_obj;
- struct device_object *attached_to;
-};
-
-struct io_status_block {
- union {
- NTSTATUS status;
- void *pointer;
- };
- ULONG_PTR info;
-};
-
-#ifdef CONFIG_X86_64
-struct io_status_block32 {
- NTSTATUS status;
- ULONG info;
-};
-#endif
-
-#define DEVICE_TYPE ULONG
-
-struct driver_extension;
-
-typedef NTSTATUS driver_dispatch_t(struct device_object *dev_obj,
- struct irp *irp) wstdcall;
-
-struct driver_object {
- CSHORT type;
- CSHORT size;
- struct device_object *dev_obj;
- ULONG flags;
- void *start;
- ULONG driver_size;
- void *section;
- struct driver_extension *drv_ext;
- struct unicode_string name;
- struct unicode_string *hardware_database;
- void *fast_io_dispatch;
- void *init;
- void *start_io;
- void (*unload)(struct driver_object *driver) wstdcall;
- driver_dispatch_t *major_func[IRP_MJ_MAXIMUM_FUNCTION + 1];
-};
-
-struct driver_extension {
- struct driver_object *drv_obj;
- NTSTATUS (*add_device)(struct driver_object *drv_obj,
- struct device_object *dev_obj) wstdcall;
- ULONG count;
- struct unicode_string service_key_name;
- struct nt_list custom_ext;
-};
-
-struct custom_ext {
- struct nt_list list;
- void *client_id;
-};
-
-struct wrap_bin_file;
-
-struct file_object {
- CSHORT type;
- CSHORT size;
- struct device_object *dev_obj;
- void *volume_parameter_block;
- void *fs_context;
- void *fs_context2;
- void *section_object_pointer;
- void *private_cache_map;
- NTSTATUS final_status;
- union {
- struct file_object *related_file_object;
- struct wrap_bin_file *wrap_bin_file;
- };
- BOOLEAN lock_operation;
- BOOLEAN delete_pending;
- BOOLEAN read_access;
- BOOLEAN write_access;
- BOOLEAN delete_access;
- BOOLEAN shared_read;
- BOOLEAN shared_write;
- BOOLEAN shared_delete;
- ULONG flags;
- struct unicode_string _name_;
- LARGE_INTEGER current_byte_offset;
- ULONG waiters;
- ULONG busy;
- void *last_lock;
- struct nt_event lock;
- struct nt_event event;
- void *completion_context;
-};
-
-#ifdef CONFIG_X86_64
-#define POINTER_ALIGN __attribute__((aligned(8)))
-#else
-#define POINTER_ALIGN
-#endif
-
-#define CACHE_ALIGN __attribute__((aligned(128)))
-
-enum system_power_state {
- PowerSystemUnspecified = 0,
- PowerSystemWorking, PowerSystemSleeping1, PowerSystemSleeping2,
- PowerSystemSleeping3, PowerSystemHibernate, PowerSystemShutdown,
- PowerSystemMaximum,
-};
-
-enum device_power_state {
- PowerDeviceUnspecified = 0,
- PowerDeviceD0, PowerDeviceD1, PowerDeviceD2, PowerDeviceD3,
- PowerDeviceMaximum,
-};
-
-union power_state {
- enum system_power_state system_state;
- enum device_power_state device_state;
-};
-
-enum power_state_type {
- SystemPowerState = 0, DevicePowerState,
-};
-
-enum power_action {
- PowerActionNone = 0,
- PowerActionReserved, PowerActionSleep, PowerActionHibernate,
- PowerActionShutdown, PowerActionShutdownReset, PowerActionShutdownOff,
- PowerActionWarmEject,
-};
-
-struct guid {
- ULONG data1;
- USHORT data2;
- USHORT data3;
- UCHAR data4[8];
-};
-
-struct nt_interface {
- USHORT size;
- USHORT version;
- void *context;
- void (*reference)(void *context) wstdcall;
- void (*dereference)(void *context) wstdcall;
-};
-
-enum interface_type {
- InterfaceTypeUndefined = -1, Internal, Isa, Eisa, MicroChannel,
- TurboChannel, PCIBus, VMEBus, NuBus, PCMCIABus, CBus, MPIBus,
- MPSABus, ProcessorInternal, InternalPowerBus, PNPISABus,
- PNPBus, MaximumInterfaceType,
-};
-
-#define CmResourceTypeNull 0
-#define CmResourceTypePort 1
-#define CmResourceTypeInterrupt 2
-#define CmResourceTypeMemory 3
-#define CmResourceTypeDma 4
-#define CmResourceTypeDeviceSpecific 5
-#define CmResourceTypeBusNumber 6
-#define CmResourceTypeMaximum 7
-
-#define CmResourceTypeNonArbitrated 128
-#define CmResourceTypeConfigData 128
-#define CmResourceTypeDevicePrivate 129
-#define CmResourceTypePcCardConfig 130
-#define CmResourceTypeMfCardConfig 131
-
-enum cm_share_disposition {
- CmResourceShareUndetermined = 0, CmResourceShareDeviceExclusive,
- CmResourceShareDriverExclusive, CmResourceShareShared
-};
-
-#define CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE 0
-#define CM_RESOURCE_INTERRUPT_LATCHED 1
-#define CM_RESOURCE_MEMORY_READ_WRITE 0x0000
-#define CM_RESOURCE_MEMORY_READ_ONLY 0x0001
-#define CM_RESOURCE_MEMORY_WRITE_ONLY 0x0002
-#define CM_RESOURCE_MEMORY_PREFETCHABLE 0x0004
-
-#define CM_RESOURCE_MEMORY_COMBINEDWRITE 0x0008
-#define CM_RESOURCE_MEMORY_24 0x0010
-#define CM_RESOURCE_MEMORY_CACHEABLE 0x0020
-
-#define CM_RESOURCE_PORT_MEMORY 0x0000
-#define CM_RESOURCE_PORT_IO 0x0001
-#define CM_RESOURCE_PORT_10_BIT_DECODE 0x0004
-#define CM_RESOURCE_PORT_12_BIT_DECODE 0x0008
-#define CM_RESOURCE_PORT_16_BIT_DECODE 0x0010
-#define CM_RESOURCE_PORT_POSITIVE_DECODE 0x0020
-#define CM_RESOURCE_PORT_PASSIVE_DECODE 0x0040
-#define CM_RESOURCE_PORT_WINDOW_DECODE 0x0080
-
-#define CM_RESOURCE_DMA_8 0x0000
-#define CM_RESOURCE_DMA_16 0x0001
-#define CM_RESOURCE_DMA_32 0x0002
-#define CM_RESOURCE_DMA_8_AND_16 0x0004
-#define CM_RESOURCE_DMA_BUS_MASTER 0x0008
-#define CM_RESOURCE_DMA_TYPE_A 0x0010
-#define CM_RESOURCE_DMA_TYPE_B 0x0020
-#define CM_RESOURCE_DMA_TYPE_F 0x0040
-
-#define MAX_RESOURCES 20
-
-#pragma pack(push,4)
-struct cm_partial_resource_descriptor {
- UCHAR type;
- UCHAR share;
- USHORT flags;
- union {
- struct {
- PHYSICAL_ADDRESS start;
- ULONG length;
- } generic;
- struct {
- PHYSICAL_ADDRESS start;
- ULONG length;
- } port;
- struct {
- ULONG level;
- ULONG vector;
- KAFFINITY affinity;
- } interrupt;
- struct {
- PHYSICAL_ADDRESS start;
- ULONG length;
- } memory;
- struct {
- ULONG channel;
- ULONG port;
- ULONG reserved1;
- } dma;
- struct {
- ULONG data[3];
- } device_private;
- struct {
- ULONG start;
- ULONG length;
- ULONG reserved;
- } bus_number;
- struct {
- ULONG data_size;
- ULONG reserved1;
- ULONG reserved2;
- } device_specific_data;
- } u;
-};
-#pragma pack(pop)
-
-struct cm_partial_resource_list {
- USHORT version;
- USHORT revision;
- ULONG count;
- struct cm_partial_resource_descriptor partial_descriptors[1];
-};
-
-struct cm_full_resource_descriptor {
- enum interface_type interface_type;
- ULONG bus_number;
- struct cm_partial_resource_list partial_resource_list;
-};
-
-struct cm_resource_list {
- ULONG count;
- struct cm_full_resource_descriptor list[1];
-};
-
-enum file_info_class {
- FileDirectoryInformation = 1,
- FileBasicInformation = 4,
- FileStandardInformation = 5,
- FileNameInformation = 9,
- FilePositionInformation = 14,
- FileAlignmentInformation = 17,
- FileNetworkOpenInformation = 34,
- FileAttributeTagInformation = 35,
- FileMaximumInformation = 41,
-};
-
-enum fs_info_class {
- FileFsVolumeInformation = 1,
- /* ... */
- FileFsMaximumInformation = 9,
-};
-
-enum device_relation_type {
- BusRelations, EjectionRelations, PowerRelations, RemovalRelations,
- TargetDeviceRelation, SingleBusRelations,
-};
-
-enum bus_query_id_type {
- BusQueryDeviceID = 0, BusQueryHardwareIDs = 1,
- BusQueryCompatibleIDs = 2, BusQueryInstanceID = 3,
- BusQueryDeviceSerialNumber = 4,
-};
-
-enum device_text_type {
- DeviceTextDescription = 0, DeviceTextLocationInformation = 1,
-};
-
-enum device_usage_notification_type {
- DeviceUsageTypeUndefined, DeviceUsageTypePaging,
- DeviceUsageTypeHibernation, DevbiceUsageTypeDumpFile,
-};
-
-#define METHOD_BUFFERED 0
-#define METHOD_IN_DIRECT 1
-#define METHOD_OUT_DIRECT 2
-#define METHOD_NEITHER 3
-
-#define CTL_CODE(dev_type, func, method, access) \
- (((dev_type) << 16) | ((access) << 14) | ((func) << 2) | (method))
-
-#define IO_METHOD_FROM_CTL_CODE(code) (code & 0x3)
-
-#ifndef CONFIG_X86_64
-#pragma pack(push,4)
-#endif
-struct io_stack_location {
- UCHAR major_fn;
- UCHAR minor_fn;
- UCHAR flags;
- UCHAR control;
- union {
- struct {
- void *security_context;
- ULONG options;
- USHORT POINTER_ALIGN file_attributes;
- USHORT share_access;
- ULONG POINTER_ALIGN ea_length;
- } create;
- struct {
- ULONG length;
- ULONG POINTER_ALIGN key;
- LARGE_INTEGER byte_offset;
- } read;
- struct {
- ULONG length;
- ULONG POINTER_ALIGN key;
- LARGE_INTEGER byte_offset;
- } write;
- struct {
- ULONG length;
- enum file_info_class POINTER_ALIGN file_info_class;
- } query_file;
- struct {
- ULONG length;
- enum file_info_class POINTER_ALIGN file_info_class;
- struct file_object *file_object;
- union {
- struct {
- BOOLEAN replace_if_exists;
- BOOLEAN advance_only;
- };
- ULONG cluster_count;
- void *delete_handle;
- };
- } set_file;
- struct {
- ULONG length;
- enum fs_info_class POINTER_ALIGN fs_info_class;
- } query_volume;
- struct {
- ULONG output_buf_len;
- ULONG POINTER_ALIGN input_buf_len;
- ULONG POINTER_ALIGN code;
- void *type3_input_buf;
- } dev_ioctl;
- struct {
- SECURITY_INFORMATION security_info;
- ULONG POINTER_ALIGN length;
- } query_security;
- struct {
- SECURITY_INFORMATION security_info;
- void *security_descriptor;
- } set_security;
- struct {
- void *vpb;
- struct device_object *device_object;
- } mount_volume;
- struct {
- void *vpb;
- struct device_object *device_object;
- } verify_volume;
- struct {
- void *srb;
- } scsi;
- struct {
- enum device_relation_type type;
- } query_device_relations;
- struct {
- const struct guid *type;
- USHORT size;
- USHORT version;
- struct nt_interface *intf;
- void *intf_data;
- } query_intf;
- struct {
- void *capabilities;
- } device_capabilities;
- struct {
- void *io_resource_requirement_list;
- } filter_resource_requirements;
- struct {
- ULONG which_space;
- void *buffer;
- ULONG offset;
- ULONG POINTER_ALIGN length;
- } read_write_config;
- struct {
- BOOLEAN lock;
- } set_lock;
- struct {
- enum bus_query_id_type id_type;
- } query_id;
- struct {
- enum device_text_type device_text_type;
- ULONG POINTER_ALIGN locale_id;
- } query_device_text;
- struct {
- BOOLEAN in_path;
- BOOLEAN reserved[3];
- enum device_usage_notification_type POINTER_ALIGN type;
- } usage_notification;
- struct {
- enum system_power_state power_state;
- } wait_wake;
- struct {
- void *power_sequence;
- } power_sequence;
- struct {
- ULONG sys_context;
- enum power_state_type POINTER_ALIGN type;
- union power_state POINTER_ALIGN state;
- enum power_action POINTER_ALIGN shutdown_type;
- } power;
- struct {
- struct cm_resource_list *allocated_resources;
- struct cm_resource_list *allocated_resources_translated;
- } start_device;
- struct {
- ULONG_PTR provider_id;
- void *data_path;
- ULONG buf_len;
- void *buf;
- } wmi;
- struct {
- void *arg1;
- void *arg2;
- void *arg3;
- void *arg4;
- } others;
- } params;
- struct device_object *dev_obj;
- struct file_object *file_obj;
- NTSTATUS (*completion_routine)(struct device_object *,
- struct irp *, void *) wstdcall;
- void *context;
-};
-#ifndef CONFIG_X86_64
-#pragma pack(pop)
-#endif
-
-struct kapc {
- CSHORT type;
- CSHORT size;
- ULONG spare0;
- struct nt_thread *thread;
- struct nt_list list;
- void *kernele_routine;
- void *rundown_routine;
- void *normal_routine;
- void *normal_context;
- void *sys_arg1;
- void *sys_arg2;
- CCHAR apc_state_index;
- KPROCESSOR_MODE apc_mode;
- BOOLEAN inserted;
-};
-
-#define IRP_NOCACHE 0x00000001
-#define IRP_SYNCHRONOUS_API 0x00000004
-#define IRP_ASSOCIATED_IRP 0x00000008
-
-enum urb_state {
- URB_INVALID = 1, URB_ALLOCATED, URB_SUBMITTED,
- URB_COMPLETED, URB_FREE, URB_SUSPEND, URB_INT_UNLINKED };
-
-struct wrap_urb {
- struct nt_list list;
- enum urb_state state;
- struct nt_list complete_list;
- unsigned int flags;
- struct urb *urb;
- struct irp *irp;
-#ifdef USB_DEBUG
- unsigned int id;
-#endif
-};
-
-struct irp {
- SHORT type;
- USHORT size;
- struct mdl *mdl;
- ULONG flags;
- union {
- struct irp *master_irp;
- LONG irp_count;
- void *system_buffer;
- } associated_irp;
- struct nt_list thread_list;
- struct io_status_block io_status;
- KPROCESSOR_MODE requestor_mode;
- BOOLEAN pending_returned;
- CHAR stack_count;
- CHAR current_location;
- BOOLEAN cancel;
- KIRQL cancel_irql;
- CCHAR apc_env;
- UCHAR alloc_flags;
- struct io_status_block *user_status;
- struct nt_event *user_event;
- union {
- struct {
- void *user_apc_routine;
- void *user_apc_context;
- } async_params;
- LARGE_INTEGER alloc_size;
- } overlay;
- void (*cancel_routine)(struct device_object *, struct irp *) wstdcall;
- void *user_buf;
- union {
- struct {
- union {
- struct kdevice_queue_entry dev_q_entry;
- struct {
- void *driver_context[4];
- };
- };
- void *thread;
- char *aux_buf;
- struct {
- struct nt_list list;
- union {
- struct io_stack_location *csl;
- ULONG packet_type;
- };
- };
- struct file_object *file_object;
- } overlay;
- union {
- struct kapc apc;
- /* space for apc is used for ndiswrapper
- * specific fields */
- struct {
- struct wrap_urb *wrap_urb;
- struct wrap_device *wrap_device;
- };
- };
- void *completion_key;
- } tail;
-};
-
-#define IoSizeOfIrp(stack_count) \
- ((USHORT)(sizeof(struct irp) + \
- ((stack_count) * sizeof(struct io_stack_location))))
-#define IoGetCurrentIrpStackLocation(irp) \
- (irp)->tail.overlay.csl
-#define IoGetNextIrpStackLocation(irp) \
- (IoGetCurrentIrpStackLocation(irp) - 1)
-#define IoGetPreviousIrpStackLocation(irp) \
- (IoGetCurrentIrpStackLocation(irp) + 1)
-
-#define IoSetNextIrpStackLocation(irp) \
-do { \
- KIRQL _irql_; \
- IoAcquireCancelSpinLock(&_irql_); \
- (irp)->current_location--; \
- IoGetCurrentIrpStackLocation(irp)--; \
- IoReleaseCancelSpinLock(_irql_); \
-} while (0)
-
-#define IoSkipCurrentIrpStackLocation(irp) \
-do { \
- KIRQL _irql_; \
- IoAcquireCancelSpinLock(&_irql_); \
- (irp)->current_location++; \
- IoGetCurrentIrpStackLocation(irp)++; \
- IoReleaseCancelSpinLock(_irql_); \
-} while (0)
-
-static inline void
-IoCopyCurrentIrpStackLocationToNext(struct irp *irp)
-{
- struct io_stack_location *next;
- next = IoGetNextIrpStackLocation(irp);
- memcpy(next, IoGetCurrentIrpStackLocation(irp),
- offsetof(struct io_stack_location, completion_routine));
- next->control = 0;
-}
-
-static inline void
-IoSetCompletionRoutine(struct irp *irp, void *routine, void *context,
- BOOLEAN success, BOOLEAN error, BOOLEAN cancel)
-{
- struct io_stack_location *irp_sl = IoGetNextIrpStackLocation(irp);
- irp_sl->completion_routine = routine;
- irp_sl->context = context;
- irp_sl->control = 0;
- if (success)
- irp_sl->control |= SL_INVOKE_ON_SUCCESS;
- if (error)
- irp_sl->control |= SL_INVOKE_ON_ERROR;
- if (cancel)
- irp_sl->control |= SL_INVOKE_ON_CANCEL;
-}
-
-#define IoMarkIrpPending(irp) \
- (IoGetCurrentIrpStackLocation((irp))->control |= SL_PENDING_RETURNED)
-#define IoUnmarkIrpPending(irp) \
- (IoGetCurrentIrpStackLocation((irp))->control &= ~SL_PENDING_RETURNED)
-
-#define IRP_SL(irp, n) (((struct io_stack_location *)((irp) + 1)) + (n))
-#define IRP_DRIVER_CONTEXT(irp) (irp)->tail.overlay.driver_context
-#define IoIrpThread(irp) ((irp)->tail.overlay.thread)
-
-#define IRP_URB(irp) \
- (union nt_urb *)(IoGetCurrentIrpStackLocation(irp)->params.others.arg1)
-
-#define IRP_WRAP_DEVICE(irp) (irp)->tail.wrap_device
-#define IRP_WRAP_URB(irp) (irp)->tail.wrap_urb
-
-struct wmi_guid_reg_info {
- struct guid *guid;
- ULONG instance_count;
- ULONG flags;
-};
-
-struct wmilib_context {
- ULONG guid_count;
- struct wmi_guid_reg_info *guid_list;
- void *query_wmi_reg_info;
- void *query_wmi_data_block;
- void *set_wmi_data_block;
- void *set_wmi_data_item;
- void *execute_wmi_method;
- void *wmi_function_control;
-};
-
-enum key_value_information_class {
- KeyValueBasicInformation, KeyValueFullInformation,
- KeyValuePartialInformation, KeyValueFullInformationAlign64,
- KeyValuePartialInformationAlign64
-};
-
-struct file_name_info {
- ULONG length;
- wchar_t *name;
-};
-
-struct file_std_info {
- LARGE_INTEGER alloc_size;
- LARGE_INTEGER eof;
- ULONG num_links;
- BOOLEAN delete_pending;
- BOOLEAN dir;
-};
-
-enum nt_obj_type {
- NT_OBJ_EVENT = 10, NT_OBJ_MUTEX, NT_OBJ_THREAD, NT_OBJ_TIMER,
- NT_OBJ_SEMAPHORE,
-};
-
-enum common_object_type {
- OBJECT_TYPE_NONE, OBJECT_TYPE_DEVICE, OBJECT_TYPE_DRIVER,
- OBJECT_TYPE_NT_THREAD, OBJECT_TYPE_FILE, OBJECT_TYPE_CALLBACK,
-};
-
-struct common_object_header {
- struct nt_list list;
- enum common_object_type type;
- UINT size;
- UINT ref_count;
- BOOLEAN close_in_process;
- BOOLEAN permanent;
- struct unicode_string name;
-};
-
-#define OBJECT_TO_HEADER(object) \
- (struct common_object_header *)((void *)(object) - \
- sizeof(struct common_object_header))
-#define OBJECT_SIZE(size) \
- ((size) + sizeof(struct common_object_header))
-#define HEADER_TO_OBJECT(hdr) \
- ((void *)(hdr) + sizeof(struct common_object_header))
-#define HANDLE_TO_OBJECT(handle) HEADER_TO_OBJECT(handle)
-#define HANDLE_TO_HEADER(handle) (handle)
-
-enum work_queue_type {
- CriticalWorkQueue, DelayedWorkQueue, HyperCriticalWorkQueue,
- MaximumWorkQueue
-};
-
-typedef void (*NTOS_WORK_FUNC)(void *arg1, void *arg2) wstdcall;
-
-struct io_workitem {
- enum work_queue_type type;
- struct device_object *dev_obj;
- NTOS_WORK_FUNC worker_routine;
- void *context;
-};
-
-struct io_workitem_entry {
- struct nt_list list;
- struct io_workitem *io_workitem;
-};
-
-enum mm_page_priority {
- LowPagePriority, NormalPagePriority = 16, HighPagePriority = 32
-};
-
-enum kinterrupt_mode {
- LevelSensitive, Latched
-};
-
-enum ntos_wait_reason {
- Executive, FreePage, PageIn, PoolAllocation, DelayExecution,
- Suspended, UserRequest, WrExecutive, WrFreePage, WrPageIn,
- WrPoolAllocation, WrDelayExecution, WrSuspended, WrUserRequest,
- WrEventPair, WrQueue, WrLpcReceive, WrLpcReply, WrVirtualMemory,
- WrPageOut, WrRendezvous, Spare2, Spare3, Spare4, Spare5, Spare6,
- WrKernel, MaximumWaitReason
-};
-
-typedef enum ntos_wait_reason KWAIT_REASON;
-
-typedef void *LOOKASIDE_ALLOC_FUNC(enum pool_type pool_type,
- SIZE_T size, ULONG tag) wstdcall;
-typedef void LOOKASIDE_FREE_FUNC(void *) wstdcall;
-
-struct npaged_lookaside_list {
- nt_slist_header head;
- USHORT depth;
- USHORT maxdepth;
- ULONG totalallocs;
- union {
- ULONG allocmisses;
- ULONG allochits;
- } u1;
- ULONG totalfrees;
- union {
- ULONG freemisses;
- ULONG freehits;
- } u2;
- enum pool_type pool_type;
- ULONG tag;
- ULONG size;
- LOOKASIDE_ALLOC_FUNC *alloc_func;
- LOOKASIDE_FREE_FUNC *free_func;
- struct nt_list list;
- ULONG lasttotallocs;
- union {
- ULONG lastallocmisses;
- ULONG lastallochits;
- } u3;
- ULONG pad[2];
-#ifndef CONFIG_X86_64
- NT_SPIN_LOCK obsolete;
-#endif
-}
-#ifdef CONFIG_X86_64
-CACHE_ALIGN
-#endif
-;
-
-enum device_registry_property {
- DevicePropertyDeviceDescription, DevicePropertyHardwareID,
- DevicePropertyCompatibleIDs, DevicePropertyBootConfiguration,
- DevicePropertyBootConfigurationTranslated,
- DevicePropertyClassName, DevicePropertyClassGuid,
- DevicePropertyDriverKeyName, DevicePropertyManufacturer,
- DevicePropertyFriendlyName, DevicePropertyLocationInformation,
- DevicePropertyPhysicalDeviceObjectName, DevicePropertyBusTypeGuid,
- DevicePropertyLegacyBusType, DevicePropertyBusNumber,
- DevicePropertyEnumeratorName, DevicePropertyAddress,
- DevicePropertyUINumber, DevicePropertyInstallState,
- DevicePropertyRemovalPolicy
-};
-
-enum trace_information_class {
- TraceIdClass, TraceHandleClass, TraceEnableFlagsClass,
- TraceEnableLevelClass, GlobalLoggerHandleClass, EventLoggerHandleClass,
- AllLoggerHandlesClass, TraceHandleByNameClass
-};
-
-struct kinterrupt;
-typedef BOOLEAN (*PKSERVICE_ROUTINE)(struct kinterrupt *interrupt,
- void *context) wstdcall;
-typedef BOOLEAN (*PKSYNCHRONIZE_ROUTINE)(void *context) wstdcall;
-
-struct kinterrupt {
- ULONG vector;
- KAFFINITY cpu_mask;
- NT_SPIN_LOCK lock;
- NT_SPIN_LOCK *actual_lock;
- BOOLEAN shared;
- BOOLEAN save_fp;
- union {
- CHAR processor_number;
-#ifdef CONFIG_DEBUG_SHIRQ
- CHAR enabled;
-#endif
- } u;
- PKSERVICE_ROUTINE isr;
- void *isr_ctx;
- struct nt_list list;
- KIRQL irql;
- KIRQL synch_irql;
- enum kinterrupt_mode mode;
-};
-
-struct time_fields {
- CSHORT year;
- CSHORT month;
- CSHORT day;
- CSHORT hour;
- CSHORT minute;
- CSHORT second;
- CSHORT milliseconds;
- CSHORT weekday;
-};
-
-struct object_attributes {
- ULONG length;
- void *root_dir;
- struct unicode_string *name;
- ULONG attributes;
- void *security_descr;
- void *security_qos;
-};
-
-typedef void (*PCALLBACK_FUNCTION)(void *context, void *arg1,
- void *arg2) wstdcall;
-
-struct callback_object;
-struct callback_func {
- PCALLBACK_FUNCTION func;
- void *context;
- struct nt_list list;
- struct callback_object *object;
-};
-
-struct callback_object {
- NT_SPIN_LOCK lock;
- struct nt_list list;
- struct nt_list callback_funcs;
- BOOLEAN allow_multiple_callbacks;
- struct object_attributes *attributes;
-};
-
-enum section_inherit {
- ViewShare = 1, ViewUnmap = 2
-};
-
-struct ksystem_time {
- ULONG low_part;
- LONG high1_time;
- LONG high2_time;
-};
-
-enum nt_product_type {
- nt_product_win_nt = 1, nt_product_lan_man_nt, nt_product_server
-};
-
-enum alt_arch_type {
- arch_type_standard, arch_type_nex98x86, end_alternatives
-};
-
-struct kuser_shared_data {
- ULONG tick_count;
- ULONG tick_count_multiplier;
- volatile struct ksystem_time interrupt_time;
- volatile struct ksystem_time system_time;
- volatile struct ksystem_time time_zone_bias;
- USHORT image_number_low;
- USHORT image_number_high;
- wchar_t nt_system_root[260];
- ULONG max_stack_trace_depth;
- ULONG crypto_exponent;
- ULONG time_zone_id;
- ULONG large_page_min;
- ULONG reserved2[7];
- enum nt_product_type nt_product_type;
- BOOLEAN product_type_is_valid;
- ULONG nt_major_version;
- ULONG nt_minor_version;
- BOOLEAN processor_features[PROCESSOR_FEATURE_MAX];
- ULONG reserved1;
- ULONG reserved3;
- volatile LONG time_slip;
- enum alt_arch_type alt_arch_type;
- LARGE_INTEGER system_expiration_date;
- ULONG suite_mask;
- BOOLEAN kdbg_enabled;
- volatile ULONG active_console;
- volatile ULONG dismount_count;
- ULONG com_plus_package;
- ULONG last_system_rite_event_tick_count;
- ULONG num_phys_pages;
- BOOLEAN safe_boot_mode;
- ULONG trace_log;
- ULONGLONG fill0;
- ULONGLONG sys_call[4];
- union {
- volatile struct ksystem_time tick_count;
- volatile ULONG64 tick_count_quad;
- } tick;
-};
-
-#define REG_NONE (0)
-#define REG_SZ (1)
-#define REG_EXPAND_SZ (2)
-#define REG_BINARY (3)
-#define REG_DWORD (4)
-
-#define RTL_REGISTRY_ABSOLUTE 0
-#define RTL_REGISTRY_SERVICES 1
-#define RTL_REGISTRY_CONTROL 2
-#define RTL_REGISTRY_WINDOWS_NT 3
-#define RTL_REGISTRY_DEVICEMAP 4
-#define RTL_REGISTRY_USER 5
-#define RTL_REGISTRY_MAXIMUM 6
-#define RTL_REGISTRY_HANDLE 0x40000000
-#define RTL_REGISTRY_OPTIONAL 0x80000000
-
-#define RTL_QUERY_REGISTRY_SUBKEY 0x00000001
-#define RTL_QUERY_REGISTRY_TOPKEY 0x00000002
-#define RTL_QUERY_REGISTRY_REQUIRED 0x00000004
-#define RTL_QUERY_REGISTRY_NOVALUE 0x00000008
-#define RTL_QUERY_REGISTRY_NOEXPAND 0x00000010
-#define RTL_QUERY_REGISTRY_DIRECT 0x00000020
-#define RTL_QUERY_REGISTRY_DELETE 0x00000040
-
-typedef NTSTATUS (*PRTL_QUERY_REGISTRY_ROUTINE)(wchar_t *name, ULONG type,
- void *data, ULONG length,
- void *context,
- void *entry) wstdcall;
-
-struct rtl_query_registry_table {
- PRTL_QUERY_REGISTRY_ROUTINE query_func;
- ULONG flags;
- wchar_t *name;
- void *context;
- ULONG def_type;
- void *def_data;
- ULONG def_length;
-};
-
-struct io_remove_lock {
- BOOLEAN removed;
- BOOLEAN reserved[3];
- LONG io_count;
- struct nt_event remove_event;
-};
-
-struct io_error_log_packet {
- UCHAR major_fn_code;
- UCHAR retry_count;
- USHORT dump_data_size;
- USHORT nr_of_strings;
- USHORT string_offset;
- USHORT event_category;
- NTSTATUS error_code;
- ULONG unique_error_value;
- NTSTATUS final_status;
- ULONG sequence_number;
- ULONG io_control_code;
- LARGE_INTEGER device_offset;
- ULONG dump_data[1];
-};
-
-/* some of the functions below are slightly different from DDK's
- * implementation; e.g., Insert functions return appropriate
- * pointer */
-
-/* instead of using Linux's lists, we implement list manipulation
- * functions because nt_list is used by drivers and we don't want to
- * worry about Linux's list being different from nt_list (right now
- * they are same, but in future they could be different) */
-
-static inline void InitializeListHead(struct nt_list *head)
-{
- head->next = head->prev = head;
-}
-
-static inline BOOLEAN IsListEmpty(struct nt_list *head)
-{
- if (head == head->next)
- return TRUE;
- else
- return FALSE;
-}
-
-static inline void RemoveEntryList(struct nt_list *entry)
-{
- entry->prev->next = entry->next;
- entry->next->prev = entry->prev;
-}
-
-static inline struct nt_list *RemoveHeadList(struct nt_list *head)
-{
- struct nt_list *entry;
-
- entry = head->next;
- if (entry == head)
- return NULL;
- else {
- RemoveEntryList(entry);
- return entry;
- }
-}
-
-static inline struct nt_list *RemoveTailList(struct nt_list *head)
-{
- struct nt_list *entry;
-
- entry = head->prev;
- if (entry == head)
- return NULL;
- else {
- RemoveEntryList(entry);
- return entry;
- }
-}
-
-static inline void InsertListEntry(struct nt_list *entry, struct nt_list *prev,
- struct nt_list *next)
-{
- next->prev = entry;
- entry->next = next;
- entry->prev = prev;
- prev->next = entry;
-}
-
-static inline struct nt_list *InsertHeadList(struct nt_list *head,
- struct nt_list *entry)
-{
- struct nt_list *ret;
-
- if (IsListEmpty(head))
- ret = NULL;
- else
- ret = head->next;
-
- InsertListEntry(entry, head, head->next);
- return ret;
-}
-
-static inline struct nt_list *InsertTailList(struct nt_list *head,
- struct nt_list *entry)
-{
- struct nt_list *ret;
-
- if (IsListEmpty(head))
- ret = NULL;
- else
- ret = head->prev;
-
- InsertListEntry(entry, head->prev, head);
- return ret;
-}
-
-#define nt_list_for_each(pos, head) \
- for (pos = (head)->next; pos != (head); pos = pos->next)
-
-#define nt_list_for_each_entry(pos, head, member) \
- for (pos = container_of((head)->next, typeof(*pos), member); \
- &pos->member != (head); \
- pos = container_of(pos->member.next, typeof(*pos), member))
-
-#define nt_list_for_each_safe(pos, n, head) \
- for (pos = (head)->next, n = pos->next; pos != (head); \
- pos = n, n = pos->next)
-
-/* device object flags */
-#define DO_VERIFY_VOLUME 0x00000002
-#define DO_BUFFERED_IO 0x00000004
-#define DO_EXCLUSIVE 0x00000008
-#define DO_DIRECT_IO 0x00000010
-#define DO_MAP_IO_BUFFER 0x00000020
-#define DO_DEVICE_HAS_NAME 0x00000040
-#define DO_DEVICE_INITIALIZING 0x00000080
-#define DO_SYSTEM_BOOT_PARTITION 0x00000100
-#define DO_LONG_TERM_REQUESTS 0x00000200
-#define DO_NEVER_LAST_DEVICE 0x00000400
-#define DO_SHUTDOWN_REGISTERED 0x00000800
-#define DO_BUS_ENUMERATED_DEVICE 0x00001000
-#define DO_POWER_PAGABLE 0x00002000
-#define DO_POWER_INRUSH 0x00004000
-#define DO_LOW_PRIORITY_FILESYSTEM 0x00010000
-
-/* Various supported device types (used with IoCreateDevice()) */
-
-#define FILE_DEVICE_BEEP 0x00000001
-#define FILE_DEVICE_CD_ROM 0x00000002
-#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003
-#define FILE_DEVICE_CONTROLLER 0x00000004
-#define FILE_DEVICE_DATALINK 0x00000005
-#define FILE_DEVICE_DFS 0x00000006
-#define FILE_DEVICE_DISK 0x00000007
-#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008
-#define FILE_DEVICE_FILE_SYSTEM 0x00000009
-#define FILE_DEVICE_INPORT_PORT 0x0000000A
-#define FILE_DEVICE_KEYBOARD 0x0000000B
-#define FILE_DEVICE_MAILSLOT 0x0000000C
-#define FILE_DEVICE_MIDI_IN 0x0000000D
-#define FILE_DEVICE_MIDI_OUT 0x0000000E
-#define FILE_DEVICE_MOUSE 0x0000000F
-#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010
-#define FILE_DEVICE_NAMED_PIPE 0x00000011
-#define FILE_DEVICE_NETWORK 0x00000012
-#define FILE_DEVICE_NETWORK_BROWSER 0x00000013
-#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014
-#define FILE_DEVICE_NULL 0x00000015
-#define FILE_DEVICE_PARALLEL_PORT 0x00000016
-#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017
-#define FILE_DEVICE_PRINTER 0x00000018
-#define FILE_DEVICE_SCANNER 0x00000019
-#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001A
-#define FILE_DEVICE_SERIAL_PORT 0x0000001B
-#define FILE_DEVICE_SCREEN 0x0000001C
-#define FILE_DEVICE_SOUND 0x0000001D
-#define FILE_DEVICE_STREAMS 0x0000001E
-#define FILE_DEVICE_TAPE 0x0000001F
-#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020
-#define FILE_DEVICE_TRANSPORT 0x00000021
-#define FILE_DEVICE_UNKNOWN 0x00000022
-#define FILE_DEVICE_VIDEO 0x00000023
-#define FILE_DEVICE_VIRTUAL_DISK 0x00000024
-#define FILE_DEVICE_WAVE_IN 0x00000025
-#define FILE_DEVICE_WAVE_OUT 0x00000026
-#define FILE_DEVICE_8042_PORT 0x00000027
-#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028
-#define FILE_DEVICE_BATTERY 0x00000029
-#define FILE_DEVICE_BUS_EXTENDER 0x0000002A
-#define FILE_DEVICE_MODEM 0x0000002B
-#define FILE_DEVICE_VDM 0x0000002C
-#define FILE_DEVICE_MASS_STORAGE 0x0000002D
-#define FILE_DEVICE_SMB 0x0000002E
-#define FILE_DEVICE_KS 0x0000002F
-#define FILE_DEVICE_CHANGER 0x00000030
-#define FILE_DEVICE_SMARTCARD 0x00000031
-#define FILE_DEVICE_ACPI 0x00000032
-#define FILE_DEVICE_DVD 0x00000033
-#define FILE_DEVICE_FULLSCREEN_VIDEO 0x00000034
-#define FILE_DEVICE_DFS_FILE_SYSTEM 0x00000035
-#define FILE_DEVICE_DFS_VOLUME 0x00000036
-#define FILE_DEVICE_SERENUM 0x00000037
-#define FILE_DEVICE_TERMSRV 0x00000038
-#define FILE_DEVICE_KSEC 0x00000039
-#define FILE_DEVICE_FIPS 0x0000003A
-
-/* Device characteristics */
-
-#define FILE_REMOVABLE_MEDIA 0x00000001
-#define FILE_READ_ONLY_DEVICE 0x00000002
-#define FILE_FLOPPY_DISKETTE 0x00000004
-#define FILE_WRITE_ONCE_MEDIA 0x00000008
-#define FILE_REMOTE_DEVICE 0x00000010
-#define FILE_DEVICE_IS_MOUNTED 0x00000020
-#define FILE_VIRTUAL_VOLUME 0x00000040
-#define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080
-#define FILE_DEVICE_SECURE_OPEN 0x00000100
-
-#define FILE_READ_DATA 0x0001
-#define FILE_WRITE_DATA 0x0002
-
-#define FILE_SUPERSEDED 0x00000000
-#define FILE_OPENED 0x00000001
-#define FILE_CREATED 0x00000002
-#define FILE_OVERWRITTEN 0x00000003
-#define FILE_EXISTS 0x00000004
-#define FILE_DOES_NOT_EXIST 0x00000005
-
-
-#endif /* WINNT_TYPES_H */
+++ /dev/null
-/*
- * Copyright (C) 2006 Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#define _WRAPMEM_C_
-
-#include "ntoskernel.h"
-
-struct slack_alloc_info {
- struct nt_list list;
- size_t size;
-};
-
-static struct nt_list allocs;
-static struct nt_list slack_allocs;
-static spinlock_t alloc_lock;
-
-struct vmem_block {
- struct nt_list list;
- int size;
-};
-
-static struct nt_list vmem_list;
-
-#if defined(ALLOC_DEBUG)
-struct alloc_info {
- enum alloc_type type;
- size_t size;
-#if ALLOC_DEBUG > 1
- struct nt_list list;
- const char *file;
- int line;
- ULONG tag;
-#endif
-};
-
-static atomic_t alloc_sizes[ALLOC_TYPE_MAX];
-#endif
-
-void wrapmem_info(void)
-{
-#ifdef ALLOC_DEBUG
- enum alloc_type type;
- for (type = 0; type < ALLOC_TYPE_MAX; type++)
- INFO("total size of allocations in %d: %d",
- type, atomic_read(&alloc_sizes[type]));
-#endif
-}
-
-/* allocate memory and add it to list of allocated pointers; if a
- * driver doesn't free this memory for any reason (buggy driver or we
- * allocate space behind driver's back since we need more space than
- * corresponding Windows structure provides etc.), this gets freed
- * automatically when module is unloaded
- */
-void *slack_kmalloc(size_t size)
-{
- struct slack_alloc_info *info;
- gfp_t flags;
-
- ENTER4("size = %lu", (unsigned long)size);
-
- if (irql_gfp() & GFP_ATOMIC)
- flags = GFP_ATOMIC;
- else
- flags = GFP_KERNEL;
- info = kmalloc(size + sizeof(*info), flags);
- if (!info)
- return NULL;
- info->size = size;
- spin_lock_bh(&alloc_lock);
- InsertTailList(&slack_allocs, &info->list);
- spin_unlock_bh(&alloc_lock);
-#ifdef ALLOC_DEBUG
- atomic_add(size, &alloc_sizes[ALLOC_TYPE_SLACK]);
-#endif
- TRACE4("%p, %p", info, info + 1);
- EXIT4(return info + 1);
-}
-
-/* free pointer and remove from list of allocated pointers */
-void slack_kfree(void *ptr)
-{
- struct slack_alloc_info *info;
-
- ENTER4("%p", ptr);
- info = ptr - sizeof(*info);
- spin_lock_bh(&alloc_lock);
- RemoveEntryList(&info->list);
- spin_unlock_bh(&alloc_lock);
-#ifdef ALLOC_DEBUG
- atomic_sub(info->size, &alloc_sizes[ALLOC_TYPE_SLACK]);
-#endif
- kfree(info);
- EXIT4(return);
-}
-
-#if defined(ALLOC_DEBUG)
-void *wrap_kmalloc(size_t size, gfp_t flags, const char *file, int line)
-{
- struct alloc_info *info;
-
- info = kmalloc(size + sizeof(*info), flags);
- if (!info)
- return NULL;
- if (flags & GFP_ATOMIC)
- info->type = ALLOC_TYPE_KMALLOC_ATOMIC;
- else
- info->type = ALLOC_TYPE_KMALLOC_NON_ATOMIC;
- info->size = size;
- atomic_add(size, &alloc_sizes[info->type]);
-#if ALLOC_DEBUG > 1
- info->file = file;
- info->line = line;
- info->tag = 0;
- spin_lock_bh(&alloc_lock);
- InsertTailList(&allocs, &info->list);
- spin_unlock_bh(&alloc_lock);
-#endif
- TRACE4("%p", info + 1);
- return info + 1;
-}
-
-void *wrap_kzalloc(size_t size, gfp_t flags, const char *file, int line)
-{
- void *ptr = wrap_kmalloc(size, flags, file, line);
- if (ptr)
- memset(ptr, 0, size);
- return ptr;
-}
-
-void wrap_kfree(void *ptr)
-{
- struct alloc_info *info;
-
- TRACE4("%p", ptr);
- if (!ptr)
- return;
- info = ptr - sizeof(*info);
- atomic_sub(info->size, &alloc_sizes[info->type]);
-#if ALLOC_DEBUG > 1
- spin_lock_bh(&alloc_lock);
- RemoveEntryList(&info->list);
- spin_unlock_bh(&alloc_lock);
- if (!(info->type == ALLOC_TYPE_KMALLOC_ATOMIC ||
- info->type == ALLOC_TYPE_KMALLOC_NON_ATOMIC))
- WARNING("invliad type: %d", info->type);
-#endif
- kfree(info);
-}
-
-void *wrap_vmalloc(unsigned long size, const char *file, int line)
-{
- struct alloc_info *info;
-
- info = vmalloc(size + sizeof(*info));
- if (!info)
- return NULL;
- info->type = ALLOC_TYPE_VMALLOC_NON_ATOMIC;
- info->size = size;
- atomic_add(size, &alloc_sizes[info->type]);
-#if ALLOC_DEBUG > 1
- info->file = file;
- info->line = line;
- info->tag = 0;
- spin_lock_bh(&alloc_lock);
- InsertTailList(&allocs, &info->list);
- spin_unlock_bh(&alloc_lock);
-#endif
- return info + 1;
-}
-
-void *wrap__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot,
- const char *file, int line)
-{
- struct alloc_info *info;
-
- info = __vmalloc(size + sizeof(*info), gfp_mask, prot);
- if (!info)
- return NULL;
- if (gfp_mask & GFP_ATOMIC)
- info->type = ALLOC_TYPE_VMALLOC_ATOMIC;
- else
- info->type = ALLOC_TYPE_VMALLOC_NON_ATOMIC;
- info->size = size;
- atomic_add(size, &alloc_sizes[info->type]);
-#if ALLOC_DEBUG > 1
- info->file = file;
- info->line = line;
- info->tag = 0;
- spin_lock_bh(&alloc_lock);
- InsertTailList(&allocs, &info->list);
- spin_unlock_bh(&alloc_lock);
-#endif
- return info + 1;
-}
-
-void wrap_vfree(void *ptr)
-{
- struct alloc_info *info;
-
- info = ptr - sizeof(*info);
- atomic_sub(info->size, &alloc_sizes[info->type]);
-#if ALLOC_DEBUG > 1
- spin_lock_bh(&alloc_lock);
- RemoveEntryList(&info->list);
- spin_unlock_bh(&alloc_lock);
- if (!(info->type == ALLOC_TYPE_VMALLOC_ATOMIC ||
- info->type == ALLOC_TYPE_VMALLOC_NON_ATOMIC))
- WARNING("invliad type: %d", info->type);
-#endif
- vfree(info);
-}
-
-void *wrap_alloc_pages(gfp_t flags, unsigned int size,
- const char *file, int line)
-{
- struct alloc_info *info;
-
- size += sizeof(*info);
- info = (struct alloc_info *)__get_free_pages(flags, get_order(size));
- if (!info)
- return NULL;
- info->type = ALLOC_TYPE_PAGES;
- info->size = size;
- atomic_add(size, &alloc_sizes[info->type]);
-#if ALLOC_DEBUG > 1
- info->file = file;
- info->line = line;
- info->tag = 0;
- spin_lock_bh(&alloc_lock);
- InsertTailList(&allocs, &info->list);
- spin_unlock_bh(&alloc_lock);
-#endif
- return info + 1;
-}
-
-void wrap_free_pages(unsigned long ptr, int order)
-{
- struct alloc_info *info;
-
- info = (void *)ptr - sizeof(*info);
- atomic_sub(info->size, &alloc_sizes[info->type]);
-#if ALLOC_DEBUG > 1
- spin_lock_bh(&alloc_lock);
- RemoveEntryList(&info->list);
- spin_unlock_bh(&alloc_lock);
- if (info->type != ALLOC_TYPE_PAGES)
- WARNING("invliad type: %d", info->type);
-#endif
- free_pages((unsigned long)info, get_order(info->size));
-}
-
-#if ALLOC_DEBUG > 1
-#undef ExAllocatePoolWithTag
-void *wrap_ExAllocatePoolWithTag(enum pool_type pool_type, SIZE_T size,
- ULONG tag, const char *file, int line)
-{
- void *addr;
- struct alloc_info *info;
-
- ENTER4("pool_type: %d, size: %lu, tag: %u", pool_type, size, tag);
- addr = ExAllocatePoolWithTag(pool_type, size, tag);
- if (!addr)
- return NULL;
- info = addr - sizeof(*info);
- info->file = file;
- info->line = line;
- info->tag = tag;
- EXIT4(return addr);
-}
-#endif
-
-int alloc_size(enum alloc_type type)
-{
- if (type >= 0 && type < ALLOC_TYPE_MAX)
- return atomic_read(&alloc_sizes[type]);
- else
- return -EINVAL;
-}
-
-#endif // ALLOC_DEBUG
-
-int wrapmem_init(void)
-{
- InitializeListHead(&allocs);
- InitializeListHead(&slack_allocs);
- InitializeListHead(&vmem_list);
- spin_lock_init(&alloc_lock);
- return 0;
-}
-
-void wrapmem_exit(void)
-{
- enum alloc_type type;
- struct nt_list *ent;
-
- /* free all pointers on the slack list */
- while (1) {
- struct slack_alloc_info *info;
- spin_lock_bh(&alloc_lock);
- ent = RemoveHeadList(&slack_allocs);
- spin_unlock_bh(&alloc_lock);
- if (!ent)
- break;
- info = container_of(ent, struct slack_alloc_info, list);
-#ifdef ALLOC_DEBUG
- atomic_sub(info->size, &alloc_sizes[ALLOC_TYPE_SLACK]);
-#endif
- kfree(info);
- }
- type = 0;
-#ifdef ALLOC_DEBUG
- for (type = 0; type < ALLOC_TYPE_MAX; type++) {
- int n = atomic_read(&alloc_sizes[type]);
- if (n)
- WARNING("%d bytes of memory in %d leaking", n, type);
- }
-
-#if ALLOC_DEBUG > 1
- while (1) {
- struct alloc_info *info;
-
- spin_lock_bh(&alloc_lock);
- ent = RemoveHeadList(&allocs);
- spin_unlock_bh(&alloc_lock);
- if (!ent)
- break;
- info = container_of(ent, struct alloc_info, list);
- atomic_sub(info->size, &alloc_sizes[ALLOC_TYPE_SLACK]);
- WARNING("%p in %d of size %zu allocated at %s(%d) "
- "with tag 0x%08X leaking; freeing it now",
- info + 1, info->type, info->size, info->file,
- info->line, info->tag);
- if (info->type == ALLOC_TYPE_KMALLOC_ATOMIC ||
- info->type == ALLOC_TYPE_KMALLOC_NON_ATOMIC)
- kfree(info);
- else if (info->type == ALLOC_TYPE_VMALLOC_ATOMIC ||
- info->type == ALLOC_TYPE_VMALLOC_NON_ATOMIC)
- vfree(info);
- else if (info->type == ALLOC_TYPE_PAGES)
- free_pages((unsigned long)info, get_order(info->size));
- else
- WARNING("invalid type: %d; not freed", info->type);
- }
-#endif
-#endif
- return;
-}
+++ /dev/null
-/*
- * Copyright (C) 2006 Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef _WRAPMEM_H_
-
-/* set ALLOC_DEBUG to 1 to get information about memory used by both
- * ndiswrapper and Windows driver by reading
- * /proc/net/ndiswrapper/debug; this will also show memory leaks
- * (memory allocated but not freed) when ndiswrapper module is
- * unloaded.
-
- * ALLOC_DEBUG=2: details about individual allocations leaking is printed
- * ALLOC_DEBUG=3: tags in ExAllocatePoolWithTag leaking printed
-*/
-
-//#ifndef ALLOC_DEBUG
-//#define ALLOC_DEBUG 1
-//#endif
-
-enum alloc_type { ALLOC_TYPE_KMALLOC_ATOMIC, ALLOC_TYPE_KMALLOC_NON_ATOMIC,
- ALLOC_TYPE_VMALLOC_ATOMIC, ALLOC_TYPE_VMALLOC_NON_ATOMIC,
- ALLOC_TYPE_SLACK, ALLOC_TYPE_PAGES, ALLOC_TYPE_MAX };
-
-int wrapmem_init(void);
-void wrapmem_exit(void);
-void *slack_kmalloc(size_t size);
-void slack_kfree(void *ptr);
-void wrapmem_info(void);
-
-#ifdef ALLOC_DEBUG
-void *wrap_kmalloc(size_t size, gfp_t flags, const char *file, int line);
-void *wrap_kzalloc(size_t size, gfp_t flags, const char *file, int line);
-void wrap_kfree(void *ptr);
-void *wrap_vmalloc(unsigned long size, const char *file, int line);
-void *wrap__vmalloc(unsigned long size, gfp_t flags, pgprot_t prot,
- const char *file, int line);
-void wrap_vfree(void *ptr);
-void *wrap_alloc_pages(gfp_t flags, unsigned int size,
- const char *file, int line);
-void wrap_free_pages(unsigned long ptr, int order);
-int alloc_size(enum alloc_type type);
-
-#ifndef _WRAPMEM_C_
-#undef kmalloc
-#undef kzalloc
-#undef kfree
-#undef vmalloc
-#undef __vmalloc
-#undef vfree
-#define kmalloc(size, flags) \
- wrap_kmalloc(size, flags, __FILE__, __LINE__)
-#define kzalloc(size, flags) \
- wrap_kzalloc(size, flags, __FILE__, __LINE__)
-#define vmalloc(size) \
- wrap_vmalloc(size, __FILE__, __LINE__)
-#define __vmalloc(size, flags, prot) \
- wrap__vmalloc(size, flags, prot, __FILE__, __LINE__)
-#define kfree(ptr) wrap_kfree(ptr)
-#define vfree(ptr) wrap_vfree(ptr)
-
-#define wrap_get_free_pages(flags, size) \
- wrap_alloc_pages(flags, size, __FILE__, __LINE__)
-#undef free_pages
-#define free_pages(ptr, order) wrap_free_pages(ptr, order)
-
-#if ALLOC_DEBUG > 1
-void *wrap_ExAllocatePoolWithTag(enum pool_type pool_type, SIZE_T size,
- ULONG tag, const char *file, int line);
-#define ExAllocatePoolWithTag(pool_type, size, tag) \
- wrap_ExAllocatePoolWithTag(pool_type, size, tag, __FILE__, __LINE__)
-#endif
-
-#endif // _WRAPMEM_C_
-
-#else
-
-#define wrap_get_free_pages(flags, size) \
- (void *)__get_free_pages(flags, get_order(size))
-
-#endif // ALLOC_DEBUG
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include "ndis.h"
-#include "iw_ndis.h"
-#include "pnp.h"
-#include "loader.h"
-#include "wrapndis.h"
-#include <linux/inetdevice.h>
-#include <linux/ip.h>
-#include <linux/tcp.h>
-#include <linux/udp.h>
-#include <linux/in.h>
-#include "wrapper.h"
-
-/* Functions callable from the NDIS driver */
-wstdcall NTSTATUS NdisDispatchDeviceControl(struct device_object *fdo,
- struct irp *irp);
-wstdcall NTSTATUS NdisDispatchPnp(struct device_object *fdo, struct irp *irp);
-wstdcall NTSTATUS NdisDispatchPower(struct device_object *fdo, struct irp *irp);
-
-workqueue_struct_t *wrapndis_wq;
-static struct nt_thread *wrapndis_worker_thread;
-
-static int set_packet_filter(struct ndis_device *wnd,
- ULONG packet_filter);
-static void add_iw_stats_timer(struct ndis_device *wnd);
-static void del_iw_stats_timer(struct ndis_device *wnd);
-static NDIS_STATUS ndis_start_device(struct ndis_device *wnd);
-static int ndis_remove_device(struct ndis_device *wnd);
-static void set_multicast_list(struct ndis_device *wnd);
-static int ndis_net_dev_open(struct net_device *net_dev);
-static int ndis_net_dev_close(struct net_device *net_dev);
-
-/* MiniportReset */
-NDIS_STATUS mp_reset(struct ndis_device *wnd)
-{
- NDIS_STATUS res;
- struct miniport *mp;
- BOOLEAN reset_address;
- KIRQL irql;
-
- ENTER2("wnd: %p", wnd);
- if (down_interruptible(&wnd->tx_ring_mutex))
- EXIT3(return NDIS_STATUS_FAILURE);
- if (down_interruptible(&wnd->ndis_req_mutex)) {
- up(&wnd->tx_ring_mutex);
- EXIT3(return NDIS_STATUS_FAILURE);
- }
- mp = &wnd->wd->driver->ndis_driver->mp;
- prepare_wait_condition(wnd->ndis_req_task, wnd->ndis_req_done, 0);
- WARNING("%s is being reset", wnd->net_dev->name);
- irql = serialize_lock_irql(wnd);
- assert_irql(_irql_ == DISPATCH_LEVEL);
- res = LIN2WIN2(mp->reset, &reset_address, wnd->nmb->mp_ctx);
- serialize_unlock_irql(wnd, irql);
-
- TRACE2("%08X, %08X", res, reset_address);
- if (res == NDIS_STATUS_PENDING) {
- /* wait for NdisMResetComplete */
- if (wait_condition((wnd->ndis_req_done > 0), 0,
- TASK_INTERRUPTIBLE) < 0)
- res = NDIS_STATUS_FAILURE;
- else {
- res = wnd->ndis_req_status;
- reset_address = wnd->ndis_req_done - 1;
- }
- TRACE2("%08X, %08X", res, reset_address);
- }
- up(&wnd->ndis_req_mutex);
- if (res == NDIS_STATUS_SUCCESS && reset_address) {
- set_packet_filter(wnd, wnd->packet_filter);
- set_multicast_list(wnd);
- }
- up(&wnd->tx_ring_mutex);
- EXIT3(return res);
-}
-
-/* MiniportRequest(Query/Set)Information */
-NDIS_STATUS mp_request(enum ndis_request_type request,
- struct ndis_device *wnd, ndis_oid oid,
- void *buf, ULONG buflen, ULONG *written, ULONG *needed)
-{
- NDIS_STATUS res;
- ULONG w, n;
- struct miniport *mp;
- KIRQL irql;
-
- if (down_interruptible(&wnd->ndis_req_mutex))
- EXIT3(return NDIS_STATUS_FAILURE);
- if (!written)
- written = &w;
- if (!needed)
- needed = &n;
- mp = &wnd->wd->driver->ndis_driver->mp;
- prepare_wait_condition(wnd->ndis_req_task, wnd->ndis_req_done, 0);
- irql = serialize_lock_irql(wnd);
- assert_irql(_irql_ == DISPATCH_LEVEL);
- switch (request) {
- case NdisRequestQueryInformation:
- TRACE2("%p, %08X, %p", mp->queryinfo, oid, wnd->nmb->mp_ctx);
- res = LIN2WIN6(mp->queryinfo, wnd->nmb->mp_ctx, oid, buf,
- buflen, written, needed);
- break;
- case NdisRequestSetInformation:
- TRACE2("%p, %08X, %p", mp->setinfo, oid, wnd->nmb->mp_ctx);
- res = LIN2WIN6(mp->setinfo, wnd->nmb->mp_ctx, oid, buf,
- buflen, written, needed);
- break;
- default:
- WARNING("invalid request %d, %08X", request, oid);
- res = NDIS_STATUS_NOT_SUPPORTED;
- break;
- }
- serialize_unlock_irql(wnd, irql);
- TRACE2("%08X, %08X", res, oid);
- if (res == NDIS_STATUS_PENDING) {
- /* wait for NdisMQueryInformationComplete */
- if (wait_condition((wnd->ndis_req_done > 0), 0,
- TASK_INTERRUPTIBLE) < 0)
- res = NDIS_STATUS_FAILURE;
- else
- res = wnd->ndis_req_status;
- TRACE2("%08X, %08X", res, oid);
- }
- up(&wnd->ndis_req_mutex);
- DBG_BLOCK(2) {
- if (res || needed)
- TRACE2("%08X, %d, %d, %d", res, buflen, *written,
- *needed);
- }
- EXIT3(return res);
-}
-
-/* MiniportPnPEventNotify */
-static NDIS_STATUS mp_pnp_event(struct ndis_device *wnd,
- enum ndis_device_pnp_event event,
- ULONG power_profile)
-{
- struct miniport *mp;
-
- ENTER1("%p, %d", wnd, event);
- mp = &wnd->wd->driver->ndis_driver->mp;
- if (!mp->pnp_event_notify) {
- TRACE1("Windows driver %s doesn't support "
- "MiniportPnpEventNotify", wnd->wd->driver->name);
- return NDIS_STATUS_FAILURE;
- }
- /* RNDIS driver doesn't like to be notified if device is
- * already halted */
- if (!test_bit(HW_INITIALIZED, &wnd->wd->hw_status))
- EXIT1(return NDIS_STATUS_SUCCESS);
- switch (event) {
- case NdisDevicePnPEventSurpriseRemoved:
- TRACE1("%u, %p",
- (wnd->attributes & NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK),
- mp->pnp_event_notify);
- if ((wnd->attributes & NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK) &&
- !test_bit(HW_PRESENT, &wnd->wd->hw_status) &&
- mp->pnp_event_notify) {
- TRACE1("calling surprise_removed");
- LIN2WIN4(mp->pnp_event_notify, wnd->nmb->mp_ctx,
- NdisDevicePnPEventSurpriseRemoved, NULL, 0);
- } else
- TRACE1("Windows driver %s doesn't support "
- "MiniportPnpEventNotify for safe unplugging",
- wnd->wd->driver->name);
- return NDIS_STATUS_SUCCESS;
- case NdisDevicePnPEventPowerProfileChanged:
- if (power_profile)
- power_profile = NdisPowerProfileAcOnLine;
- LIN2WIN4(mp->pnp_event_notify, wnd->nmb->mp_ctx,
- NdisDevicePnPEventPowerProfileChanged,
- &power_profile, (ULONG)sizeof(power_profile));
- return NDIS_STATUS_SUCCESS;
- default:
- WARNING("event %d not yet implemented", event);
- return NDIS_STATUS_SUCCESS;
- }
-}
-
-/* MiniportInitialize */
-static NDIS_STATUS mp_init(struct ndis_device *wnd)
-{
- NDIS_STATUS error_status, status;
- UINT medium_index;
- enum ndis_medium medium_array[] = {NdisMedium802_3};
- struct miniport *mp;
-
- ENTER1("irql: %d", current_irql());
- if (test_bit(HW_INITIALIZED, &wnd->wd->hw_status)) {
- WARNING("device %p already initialized!", wnd);
- return NDIS_STATUS_FAILURE;
- }
-
- if (!wnd->wd->driver->ndis_driver ||
- !wnd->wd->driver->ndis_driver->mp.init) {
- WARNING("assuming WDM (non-NDIS) driver");
- EXIT1(return NDIS_STATUS_NOT_RECOGNIZED);
- }
- mp = &wnd->wd->driver->ndis_driver->mp;
- status = LIN2WIN6(mp->init, &error_status, &medium_index, medium_array,
- sizeof(medium_array) / sizeof(medium_array[0]),
- wnd->nmb, wnd->nmb);
- TRACE1("init returns: %08X, irql: %d", status, current_irql());
- if (status != NDIS_STATUS_SUCCESS) {
- WARNING("couldn't initialize device: %08X", status);
- EXIT1(return NDIS_STATUS_FAILURE);
- }
-
- /* Wait a little to let card power up otherwise ifup might
- * fail after boot */
- sleep_hz(HZ / 5);
- status = mp_pnp_event(wnd, NdisDevicePnPEventPowerProfileChanged,
- NdisPowerProfileAcOnLine);
- if (status != NDIS_STATUS_SUCCESS)
- TRACE1("setting power failed: %08X", status);
- set_bit(HW_INITIALIZED, &wnd->wd->hw_status);
- /* the description about NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND is
- * misleading/confusing */
- status = mp_query(wnd, OID_PNP_CAPABILITIES,
- &wnd->pnp_capa, sizeof(wnd->pnp_capa));
- if (status == NDIS_STATUS_SUCCESS) {
- TRACE1("%d, %d", wnd->pnp_capa.wakeup.min_magic_packet_wakeup,
- wnd->pnp_capa.wakeup.min_pattern_wakeup);
- wnd->attributes |= NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND;
- status = mp_query_int(wnd, OID_PNP_ENABLE_WAKE_UP,
- &wnd->ndis_wolopts);
- TRACE1("%08X, %x", status, wnd->ndis_wolopts);
- } else if (status == NDIS_STATUS_NOT_SUPPORTED)
- wnd->attributes &= ~NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND;
- TRACE1("%d", wnd->pnp_capa.wakeup.min_magic_packet_wakeup);
- /* although some NDIS drivers support suspend, Linux kernel
- * has issues with suspending USB devices */
- if (wrap_is_usb_bus(wnd->wd->dev_bus)) {
- wnd->attributes &= ~NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND;
- wnd->ndis_wolopts = 0;
- }
- mp_set_int(wnd, OID_802_11_POWER_MODE, NDIS_POWER_OFF);
- EXIT1(return NDIS_STATUS_SUCCESS);
-}
-
-/* MiniportHalt */
-static void mp_halt(struct ndis_device *wnd)
-{
- struct miniport *mp;
-
- ENTER1("%p", wnd);
- if (!test_and_clear_bit(HW_INITIALIZED, &wnd->wd->hw_status)) {
- WARNING("device %p is not initialized - not halting", wnd);
- return;
- }
- hangcheck_del(wnd);
- del_iw_stats_timer(wnd);
- if (wnd->physical_medium == NdisPhysicalMediumWirelessLan &&
- wrap_is_pci_bus(wnd->wd->dev_bus)) {
- up(&wnd->ndis_req_mutex);
- disassociate(wnd, 0);
- if (down_interruptible(&wnd->ndis_req_mutex))
- WARNING("couldn't obtain ndis_req_mutex");
- }
- mp = &wnd->wd->driver->ndis_driver->mp;
- TRACE1("halt: %p", mp->mp_halt);
- LIN2WIN1(mp->mp_halt, wnd->nmb->mp_ctx);
- /* if a driver doesn't call NdisMDeregisterInterrupt during
- * halt, deregister it now */
- if (wnd->mp_interrupt)
- NdisMDeregisterInterrupt(wnd->mp_interrupt);
- /* cancel any timers left by bugyy windows driver; also free
- * the memory for timers */
- while (1) {
- struct nt_slist *slist;
- struct wrap_timer *wrap_timer;
-
- spin_lock_bh(&ntoskernel_lock);
- if ((slist = wnd->wrap_timer_slist.next))
- wnd->wrap_timer_slist.next = slist->next;
- spin_unlock_bh(&ntoskernel_lock);
- TIMERTRACE("%p", slist);
- if (!slist)
- break;
- wrap_timer = container_of(slist, struct wrap_timer, slist);
- wrap_timer->repeat = 0;
- /* ktimer that this wrap_timer is associated to can't
- * be touched, as it may have been freed by the driver
- * already */
- if (del_timer_sync(&wrap_timer->timer))
- WARNING("Buggy Windows driver left timer %p "
- "running", wrap_timer->nt_timer);
- memset(wrap_timer, 0, sizeof(*wrap_timer));
- kfree(wrap_timer);
- }
- EXIT1(return);
-}
-
-static NDIS_STATUS mp_set_power_state(struct ndis_device *wnd,
- enum ndis_power_state state)
-{
- NDIS_STATUS status;
-
- TRACE1("%d", state);
- if (state == NdisDeviceStateD0) {
- status = NDIS_STATUS_SUCCESS;
- up(&wnd->ndis_req_mutex);
- if (test_and_clear_bit(HW_HALTED, &wnd->wd->hw_status)) {
- status = mp_init(wnd);
- if (status == NDIS_STATUS_SUCCESS) {
- set_packet_filter(wnd, wnd->packet_filter);
- set_multicast_list(wnd);
- }
- } else if (test_and_clear_bit(HW_SUSPENDED,
- &wnd->wd->hw_status)) {
- status = mp_set_int(wnd, OID_PNP_SET_POWER, state);
- if (status != NDIS_STATUS_SUCCESS)
- WARNING("%s: setting power to state %d failed? "
- "%08X", wnd->net_dev->name, state,
- status);
- } else
- return NDIS_STATUS_FAILURE;
-
- if (wrap_is_pci_bus(wnd->wd->dev_bus)) {
- pci_enable_wake(wnd->wd->pci.pdev, PCI_D3hot, 0);
- pci_enable_wake(wnd->wd->pci.pdev, PCI_D3cold, 0);
- }
- if (status == NDIS_STATUS_SUCCESS) {
- up(&wnd->tx_ring_mutex);
- netif_device_attach(wnd->net_dev);
- hangcheck_add(wnd);
- add_iw_stats_timer(wnd);
- } else
- WARNING("%s: couldn't set power to state %d; device not"
- " resumed", wnd->net_dev->name, state);
- EXIT1(return status);
- } else {
- if (down_interruptible(&wnd->tx_ring_mutex))
- EXIT1(return NDIS_STATUS_FAILURE);
- netif_device_detach(wnd->net_dev);
- hangcheck_del(wnd);
- del_iw_stats_timer(wnd);
- status = NDIS_STATUS_NOT_SUPPORTED;
- if (wnd->attributes & NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND) {
- status = mp_set_int(wnd, OID_PNP_ENABLE_WAKE_UP,
- wnd->ndis_wolopts);
- TRACE2("0x%x, 0x%x", status, wnd->ndis_wolopts);
- if (status == NDIS_STATUS_SUCCESS) {
- if (wnd->ndis_wolopts)
- wnd->wd->pci.wake_state =
- PowerDeviceD3;
- else
- wnd->wd->pci.wake_state =
- PowerDeviceUnspecified;
- } else
- WARNING("couldn't set wake-on-lan options: "
- "0x%x, %08X", wnd->ndis_wolopts, status);
- status = mp_set_int(wnd, OID_PNP_SET_POWER, state);
- if (status == NDIS_STATUS_SUCCESS)
- set_bit(HW_SUSPENDED, &wnd->wd->hw_status);
- else
- WARNING("suspend failed: %08X", status);
- }
- if (status != NDIS_STATUS_SUCCESS) {
- WARNING("%s does not support power management; "
- "halting the device", wnd->net_dev->name);
- mp_halt(wnd);
- set_bit(HW_HALTED, &wnd->wd->hw_status);
- status = STATUS_SUCCESS;
- }
- if (down_interruptible(&wnd->ndis_req_mutex))
- WARNING("couldn't lock ndis_req_mutex");
- EXIT1(return status);
- }
-}
-
-static int ndis_set_mac_address(struct net_device *dev, void *p)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- struct sockaddr *addr = p;
- struct ndis_configuration_parameter param;
- struct unicode_string key;
- struct ansi_string ansi;
- NDIS_STATUS res;
- unsigned char mac_string[2 * ETH_ALEN + 1];
- mac_address mac;
-
- memcpy(mac, addr->sa_data, sizeof(mac));
- memset(mac_string, 0, sizeof(mac_string));
- res = snprintf(mac_string, sizeof(mac_string), MACSTR, MAC2STR(mac));
- if (res != (sizeof(mac_string) - 1))
- EXIT1(return -EINVAL);
- TRACE1("new mac: %s", mac_string);
-
- RtlInitAnsiString(&ansi, mac_string);
- if (RtlAnsiStringToUnicodeString(¶m.data.string, &ansi,
- TRUE) != STATUS_SUCCESS)
- EXIT1(return -EINVAL);
-
- param.type = NdisParameterString;
- RtlInitAnsiString(&ansi, "NetworkAddress");
- if (RtlAnsiStringToUnicodeString(&key, &ansi, TRUE) != STATUS_SUCCESS) {
- RtlFreeUnicodeString(¶m.data.string);
- EXIT1(return -EINVAL);
- }
- NdisWriteConfiguration(&res, wnd->nmb, &key, ¶m);
- RtlFreeUnicodeString(&key);
- RtlFreeUnicodeString(¶m.data.string);
-
- if (res != NDIS_STATUS_SUCCESS)
- EXIT1(return -EFAULT);
- if (ndis_reinit(wnd) == NDIS_STATUS_SUCCESS) {
- res = mp_query(wnd, OID_802_3_CURRENT_ADDRESS,
- mac, sizeof(mac));
- if (res == NDIS_STATUS_SUCCESS) {
- TRACE1("mac:" MACSTRSEP, MAC2STR(mac));
- memcpy(dev->dev_addr, mac, sizeof(mac));
- } else
- ERROR("couldn't get mac address: %08X", res);
- }
- EXIT1(return 0);
-}
-
-static int setup_tx_sg_list(struct ndis_device *wnd, struct sk_buff *skb,
- struct ndis_packet_oob_data *oob_data)
-{
- struct ndis_sg_element *sg_element;
- struct ndis_sg_list *sg_list;
- int i;
-
- ENTER3("%p, %d", skb, skb_shinfo(skb)->nr_frags);
- if (skb_shinfo(skb)->nr_frags <= 1) {
- sg_element = &oob_data->wrap_tx_sg_list.elements[0];
- sg_element->address =
- PCI_DMA_MAP_SINGLE(wnd->wd->pci.pdev, skb->data,
- skb->len, PCI_DMA_TODEVICE);
- sg_element->length = skb->len;
- oob_data->wrap_tx_sg_list.nent = 1;
- oob_data->ext.info[ScatterGatherListPacketInfo] =
- &oob_data->wrap_tx_sg_list;
- TRACE3("%Lx, %u", sg_element->address, sg_element->length);
- return 0;
- }
- sg_list = kmalloc(sizeof(*sg_list) +
- (skb_shinfo(skb)->nr_frags + 1) * sizeof(*sg_element),
- GFP_ATOMIC);
- if (!sg_list)
- return -ENOMEM;
- sg_list->nent = skb_shinfo(skb)->nr_frags + 1;
- TRACE3("%p, %d", sg_list, sg_list->nent);
- sg_element = sg_list->elements;
- sg_element->length = skb_headlen(skb);
- sg_element->address =
- PCI_DMA_MAP_SINGLE(wnd->wd->pci.pdev, skb->data,
- skb_headlen(skb), PCI_DMA_TODEVICE);
- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
- skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
- sg_element++;
- sg_element->length = frag->size;
- sg_element->address =
- pci_map_page(wnd->wd->pci.pdev, frag->page,
- frag->page_offset, frag->size,
- PCI_DMA_TODEVICE);
- TRACE3("%Lx, %u", sg_element->address, sg_element->length);
- }
- oob_data->ext.info[ScatterGatherListPacketInfo] = sg_list;
- return 0;
-}
-
-static void free_tx_sg_list(struct ndis_device *wnd,
- struct ndis_packet_oob_data *oob_data)
-{
- int i;
- struct ndis_sg_element *sg_element;
- struct ndis_sg_list *sg_list =
- oob_data->ext.info[ScatterGatherListPacketInfo];
- sg_element = sg_list->elements;
- TRACE3("%p, %d", sg_list, sg_list->nent);
- PCI_DMA_UNMAP_SINGLE(wnd->wd->pci.pdev, sg_element->address,
- sg_element->length, PCI_DMA_TODEVICE);
- if (sg_list->nent == 1)
- EXIT3(return);
- for (i = 1; i < sg_list->nent; i++, sg_element++) {
- TRACE3("%Lx, %u", sg_element->address, sg_element->length);
- pci_unmap_page(wnd->wd->pci.pdev, sg_element->address,
- sg_element->length, PCI_DMA_TODEVICE);
- }
- TRACE3("%p", sg_list);
- kfree(sg_list);
-}
-
-static struct ndis_packet *alloc_tx_packet(struct ndis_device *wnd,
- struct sk_buff *skb)
-{
- struct ndis_packet *packet;
- ndis_buffer *buffer;
- struct ndis_packet_oob_data *oob_data;
- NDIS_STATUS status;
-
- NdisAllocatePacket(&status, &packet, wnd->tx_packet_pool);
- if (status != NDIS_STATUS_SUCCESS)
- return NULL;
- NdisAllocateBuffer(&status, &buffer, wnd->tx_buffer_pool,
- skb->data, skb->len);
- if (status != NDIS_STATUS_SUCCESS) {
- NdisFreePacket(packet);
- return NULL;
- }
- packet->private.buffer_head = buffer;
- packet->private.buffer_tail = buffer;
-
- oob_data = NDIS_PACKET_OOB_DATA(packet);
- oob_data->tx_skb = skb;
- if (wnd->sg_dma_size) {
- if (setup_tx_sg_list(wnd, skb, oob_data)) {
- NdisFreeBuffer(buffer);
- NdisFreePacket(packet);
- return NULL;
- }
- }
- if (skb->ip_summed == CHECKSUM_PARTIAL) {
- struct ndis_tcp_ip_checksum_packet_info csum;
- int protocol;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21)
- protocol = ntohs(skb->protocol);
-#else
- protocol = skb->nh.iph->protocol;
-#endif
- csum.value = 0;
- csum.tx.v4 = 1;
- if (protocol == IPPROTO_TCP)
- csum.tx.tcp = 1;
- else if (protocol == IPPROTO_UDP)
- csum.tx.udp = 1;
-// csum->tx.ip = 1;
- packet->private.flags |= NDIS_PROTOCOL_ID_TCP_IP;
- oob_data->ext.info[TcpIpChecksumPacketInfo] =
- (void *)(ULONG_PTR)csum.value;
- }
- DBG_BLOCK(4) {
- dump_bytes(__func__, skb->data, skb->len);
- }
- TRACE4("%p, %p, %p", packet, buffer, skb);
- return packet;
-}
-
-void free_tx_packet(struct ndis_device *wnd, struct ndis_packet *packet,
- NDIS_STATUS status)
-{
- ndis_buffer *buffer;
- struct ndis_packet_oob_data *oob_data;
- struct sk_buff *skb;
- struct ndis_packet_pool *pool;
-
- assert_irql(_irql_ <= DISPATCH_LEVEL);
- assert(packet->private.packet_flags);
- oob_data = NDIS_PACKET_OOB_DATA(packet);
- skb = oob_data->tx_skb;
- buffer = packet->private.buffer_head;
- TRACE4("%p, %p, %p, %08X", packet, buffer, skb, status);
- if (status == NDIS_STATUS_SUCCESS) {
- pre_atomic_add(wnd->net_stats.tx_bytes, packet->private.len);
- atomic_inc_var(wnd->net_stats.tx_packets);
- } else {
- TRACE1("packet dropped: %08X", status);
- atomic_inc_var(wnd->net_stats.tx_dropped);
- }
- if (wnd->sg_dma_size)
- free_tx_sg_list(wnd, oob_data);
- NdisFreeBuffer(buffer);
- dev_kfree_skb_any(skb);
- pool = packet->private.pool;
- NdisFreePacket(packet);
- if (netif_queue_stopped(wnd->net_dev) &&
- ((pool->max_descr - pool->num_used_descr) >=
- (wnd->max_tx_packets / 4))) {
- set_bit(NETIF_WAKEQ, &wnd->ndis_pending_work);
- schedule_wrapndis_work(&wnd->ndis_work);
- }
- EXIT4(return);
-}
-
-/* MiniportSend and MiniportSendPackets */
-/* this function is called holding tx_ring_mutex. start and n are such
- * that start + n < TX_RING_SIZE; i.e., packets don't wrap around
- * ring */
-static u8 mp_tx_packets(struct ndis_device *wnd, u8 start, u8 n)
-{
- NDIS_STATUS res;
- struct miniport *mp;
- struct ndis_packet *packet;
- u8 sent;
- KIRQL irql;
-
- ENTER3("%d, %d", start, n);
- mp = &wnd->wd->driver->ndis_driver->mp;
- if (mp->send_packets) {
- if (deserialized_driver(wnd)) {
- LIN2WIN3(mp->send_packets, wnd->nmb->mp_ctx,
- &wnd->tx_ring[start], n);
- sent = n;
- } else {
- irql = serialize_lock_irql(wnd);
- LIN2WIN3(mp->send_packets, wnd->nmb->mp_ctx,
- &wnd->tx_ring[start], n);
- serialize_unlock_irql(wnd, irql);
- for (sent = 0; sent < n && wnd->tx_ok; sent++) {
- struct ndis_packet_oob_data *oob_data;
- packet = wnd->tx_ring[start + sent];
- oob_data = NDIS_PACKET_OOB_DATA(packet);
- switch ((res =
- xchg(&oob_data->status,
- NDIS_STATUS_NOT_RECOGNIZED))) {
- case NDIS_STATUS_SUCCESS:
- free_tx_packet(wnd, packet,
- NDIS_STATUS_SUCCESS);
- break;
- case NDIS_STATUS_PENDING:
- break;
- case NDIS_STATUS_RESOURCES:
- wnd->tx_ok = 0;
- /* resubmit this packet and
- * the rest when resources
- * become available */
- sent--;
- break;
- case NDIS_STATUS_FAILURE:
- free_tx_packet(wnd, packet,
- NDIS_STATUS_FAILURE);
- break;
- default:
- ERROR("%p: invalid status: %08X",
- packet, res);
- free_tx_packet(wnd, packet,
- oob_data->status);
- break;
- }
- TRACE3("%p, %d", packet, res);
- }
- }
- TRACE3("sent: %d(%d)", sent, n);
- } else {
- for (sent = 0; sent < n && wnd->tx_ok; sent++) {
- struct ndis_packet_oob_data *oob_data;
- packet = wnd->tx_ring[start + sent];
- oob_data = NDIS_PACKET_OOB_DATA(packet);
- oob_data->status = NDIS_STATUS_NOT_RECOGNIZED;
- irql = serialize_lock_irql(wnd);
- res = LIN2WIN3(mp->send, wnd->nmb->mp_ctx,
- packet, packet->private.flags);
- serialize_unlock_irql(wnd, irql);
- switch (res) {
- case NDIS_STATUS_SUCCESS:
- free_tx_packet(wnd, packet, res);
- break;
- case NDIS_STATUS_PENDING:
- break;
- case NDIS_STATUS_RESOURCES:
- wnd->tx_ok = 0;
- /* resend this packet when resources
- * become available */
- sent--;
- break;
- case NDIS_STATUS_FAILURE:
- free_tx_packet(wnd, packet, res);
- break;
- default:
- ERROR("packet %p: invalid status: %08X",
- packet, res);
- break;
- }
- }
- }
- EXIT3(return sent);
-}
-
-static void tx_worker(worker_param_t param)
-{
- struct ndis_device *wnd;
- s8 n;
-
- wnd = worker_param_data(param, struct ndis_device, tx_work);
- ENTER3("tx_ok %d", wnd->tx_ok);
- while (wnd->tx_ok) {
- if (down_interruptible(&wnd->tx_ring_mutex))
- break;
- spin_lock_bh(&wnd->tx_ring_lock);
- n = wnd->tx_ring_end - wnd->tx_ring_start;
- TRACE3("%d, %d, %d", wnd->tx_ring_start, wnd->tx_ring_end, n);
- /* end == start if either ring is empty or full; in
- * the latter case is_tx_ring_full is set */
- if (n == 0) {
- if (wnd->is_tx_ring_full)
- n = TX_RING_SIZE - wnd->tx_ring_start;
- else {
- spin_unlock_bh(&wnd->tx_ring_lock);
- up(&wnd->tx_ring_mutex);
- break;
- }
- } else if (n < 0)
- n = TX_RING_SIZE - wnd->tx_ring_start;
- spin_unlock_bh(&wnd->tx_ring_lock);
- if (unlikely(n > wnd->max_tx_packets))
- n = wnd->max_tx_packets;
- n = mp_tx_packets(wnd, wnd->tx_ring_start, n);
- if (n) {
- wnd->net_dev->trans_start = jiffies;
- wnd->tx_ring_start =
- (wnd->tx_ring_start + n) % TX_RING_SIZE;
- wnd->is_tx_ring_full = 0;
- }
- up(&wnd->tx_ring_mutex);
- TRACE3("%d, %d, %d", wnd->tx_ring_start, wnd->tx_ring_end, n);
- }
- EXIT3(return);
-}
-
-static int tx_skbuff(struct sk_buff *skb, struct net_device *dev)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- struct ndis_packet *packet;
-
- packet = alloc_tx_packet(wnd, skb);
- if (!packet) {
- TRACE2("couldn't allocate packet");
- netif_tx_lock(dev);
- netif_stop_queue(dev);
- netif_tx_unlock(dev);
- return NETDEV_TX_BUSY;
- }
- spin_lock(&wnd->tx_ring_lock);
- wnd->tx_ring[wnd->tx_ring_end++] = packet;
- if (wnd->tx_ring_end == TX_RING_SIZE)
- wnd->tx_ring_end = 0;
- if (wnd->tx_ring_end == wnd->tx_ring_start) {
- netif_tx_lock(dev);
- wnd->is_tx_ring_full = 1;
- netif_stop_queue(dev);
- netif_tx_unlock(dev);
- }
- spin_unlock(&wnd->tx_ring_lock);
- TRACE4("ring: %d, %d", wnd->tx_ring_start, wnd->tx_ring_end);
- schedule_wrapndis_work(&wnd->tx_work);
- return NETDEV_TX_OK;
-}
-
-static int set_packet_filter(struct ndis_device *wnd, ULONG packet_filter)
-{
- NDIS_STATUS res;
-
- while (1) {
- res = mp_set_int(wnd, OID_GEN_CURRENT_PACKET_FILTER,
- packet_filter);
- if (res == NDIS_STATUS_SUCCESS)
- break;
- TRACE2("couldn't set filter 0x%08x", packet_filter);
- /* NDIS_PACKET_TYPE_PROMISCUOUS may not work with 802.11 */
- if (packet_filter & NDIS_PACKET_TYPE_PROMISCUOUS) {
- packet_filter &= ~NDIS_PACKET_TYPE_PROMISCUOUS;
- continue;
- }
- if (packet_filter & NDIS_PACKET_TYPE_ALL_LOCAL) {
- packet_filter &= ~NDIS_PACKET_TYPE_ALL_LOCAL;
- continue;
- }
- if (packet_filter & NDIS_PACKET_TYPE_ALL_FUNCTIONAL) {
- packet_filter &= ~NDIS_PACKET_TYPE_ALL_FUNCTIONAL;
- continue;
- }
- if (packet_filter & NDIS_PACKET_TYPE_MULTICAST) {
- packet_filter &= ~NDIS_PACKET_TYPE_MULTICAST;
- packet_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
- continue;
- }
- if (packet_filter & NDIS_PACKET_TYPE_ALL_MULTICAST) {
- packet_filter &= ~NDIS_PACKET_TYPE_ALL_MULTICAST;
- continue;
- }
- break;
- }
-
- wnd->packet_filter = packet_filter;
- res = mp_query_int(wnd, OID_GEN_CURRENT_PACKET_FILTER, &packet_filter);
- if (packet_filter != wnd->packet_filter) {
- WARNING("filter not set: 0x%08x, 0x%08x",
- packet_filter, wnd->packet_filter);
- wnd->packet_filter = packet_filter;
- }
- if (wnd->packet_filter)
- EXIT3(return 0);
- else
- EXIT3(return -1);
-}
-
-void set_media_state(struct ndis_device *wnd, enum ndis_media_state state)
-{
- ENTER2("state: 0x%x", state);
- if (state == NdisMediaStateConnected) {
- netif_carrier_on(wnd->net_dev);
- wnd->tx_ok = 1;
- if (netif_queue_stopped(wnd->net_dev))
- netif_wake_queue(wnd->net_dev);
- if (wnd->physical_medium == NdisPhysicalMediumWirelessLan) {
- set_bit(LINK_STATUS_ON, &wnd->ndis_pending_work);
- schedule_wrapndis_work(&wnd->ndis_work);
- }
- } else if (state == NdisMediaStateDisconnected) {
- netif_carrier_off(wnd->net_dev);
- netif_stop_queue(wnd->net_dev);
- wnd->tx_ok = 0;
- if (wnd->physical_medium == NdisPhysicalMediumWirelessLan) {
- memset(&wnd->essid, 0, sizeof(wnd->essid));
- set_bit(LINK_STATUS_OFF, &wnd->ndis_pending_work);
- schedule_wrapndis_work(&wnd->ndis_work);
- }
- } else {
- WARNING("invalid media state: 0x%x", state);
- }
-}
-
-static int ndis_net_dev_open(struct net_device *net_dev)
-{
- ENTER1("%p", netdev_priv(net_dev));
- netif_start_queue(net_dev);
- netif_poll_enable(net_dev);
- EXIT1(return 0);
-}
-
-static int ndis_net_dev_close(struct net_device *net_dev)
-{
- ENTER1("%p", netdev_priv(net_dev));
- netif_poll_disable(net_dev);
- netif_tx_disable(net_dev);
- EXIT1(return 0);
-}
-
-static int ndis_change_mtu(struct net_device *net_dev, int mtu)
-{
- struct ndis_device *wnd = netdev_priv(net_dev);
- int max;
-
- if (mtu < ETH_ZLEN)
- return -EINVAL;
- if (mp_query_int(wnd, OID_GEN_MAXIMUM_TOTAL_SIZE, &max) !=
- NDIS_STATUS_SUCCESS)
- return -EOPNOTSUPP;
- TRACE1("%d", max);
- max -= ETH_HLEN;
- if (max <= ETH_ZLEN)
- return -EINVAL;
- if (mtu + ETH_HLEN > max)
- return -EINVAL;
- net_dev->mtu = mtu;
- return 0;
-}
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void ndis_poll_controller(struct net_device *dev)
-{
- struct ndis_device *wnd = netdev_priv(dev);
-
- disable_irq(dev->irq);
- ndis_isr(wnd->mp_interrupt->kinterrupt, wnd->mp_interrupt);
- enable_irq(dev->irq);
-}
-#endif
-
-/* called from BH context */
-static struct net_device_stats *ndis_get_stats(struct net_device *dev)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- return &wnd->net_stats;
-}
-
-/* called from BH context */
-static void ndis_set_multicast_list(struct net_device *dev)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- set_bit(SET_MULTICAST_LIST, &wnd->ndis_pending_work);
- schedule_wrapndis_work(&wnd->ndis_work);
-}
-
-/* called from BH context */
-struct iw_statistics *get_iw_stats(struct net_device *dev)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- return &wnd->iw_stats;
-}
-
-static void update_iw_stats(struct ndis_device *wnd)
-{
- struct iw_statistics *iw_stats = &wnd->iw_stats;
- struct ndis_wireless_stats ndis_stats;
- NDIS_STATUS res;
- ndis_rssi rssi;
- int qual;
-
- ENTER2("%p", wnd);
- if (wnd->iw_stats_enabled == FALSE || !netif_carrier_ok(wnd->net_dev)) {
- memset(iw_stats, 0, sizeof(*iw_stats));
- EXIT2(return);
- }
- res = mp_query(wnd, OID_802_11_RSSI, &rssi, sizeof(rssi));
- if (res == NDIS_STATUS_SUCCESS)
- iw_stats->qual.level = rssi;
-
- qual = 100 * (rssi - WL_NOISE) / (WL_SIGMAX - WL_NOISE);
- if (qual < 0)
- qual = 0;
- else if (qual > 100)
- qual = 100;
-
- iw_stats->qual.noise = WL_NOISE;
- iw_stats->qual.qual = qual;
-
- res = mp_query(wnd, OID_802_11_STATISTICS,
- &ndis_stats, sizeof(ndis_stats));
- if (res != NDIS_STATUS_SUCCESS)
- EXIT2(return);
- iw_stats->discard.retries = (unsigned long)ndis_stats.retry +
- (unsigned long)ndis_stats.multi_retry;
- iw_stats->discard.misc = (unsigned long)ndis_stats.fcs_err +
- (unsigned long)ndis_stats.rtss_fail +
- (unsigned long)ndis_stats.ack_fail +
- (unsigned long)ndis_stats.frame_dup;
-
- EXIT2(return);
-}
-
-static void set_multicast_list(struct ndis_device *wnd)
-{
- struct net_device *net_dev;
- int mc_count;
- ULONG packet_filter;
- NDIS_STATUS res;
-
- net_dev = wnd->net_dev;
- packet_filter = wnd->packet_filter;
- mc_count = netdev_mc_count(net_dev);
-
- TRACE2("0x%08x", packet_filter);
- if (net_dev->flags & IFF_PROMISC) {
- packet_filter |= NDIS_PACKET_TYPE_PROMISCUOUS |
- NDIS_PACKET_TYPE_ALL_LOCAL;
- } else if (net_dev->flags & IFF_ALLMULTI ||
- mc_count > wnd->multicast_size) {
- packet_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
- TRACE2("0x%08x", packet_filter);
- } else if (mc_count > 0) {
- int i, size;
- char *buf;
- struct netdev_hw_addr *ha;
- size = min(wnd->multicast_size, mc_count);
- TRACE2("%d, %d", wnd->multicast_size, mc_count);
- buf = kmalloc(size * ETH_ALEN, GFP_KERNEL);
- if (!buf) {
- WARNING("couldn't allocate memory");
- EXIT2(return);
- }
- i = 0;
- netdev_for_each_mc_addr(ha, net_dev) {
- if (i >= size)
- break;
- if (net_dev->addr_len != ETH_ALEN)
- continue;
- memcpy(buf + i * ETH_ALEN, ha->addr, ETH_ALEN);
- TRACE2(MACSTRSEP, MAC2STR(ha->addr));
- i++;
- }
- res = mp_set(wnd, OID_802_3_MULTICAST_LIST, buf, i * ETH_ALEN);
- if (res == NDIS_STATUS_SUCCESS && i > 0)
- packet_filter |= NDIS_PACKET_TYPE_MULTICAST;
- else
- packet_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
- kfree(buf);
- }
- TRACE2("0x%08x", packet_filter);
- res = set_packet_filter(wnd, packet_filter);
- if (res)
- TRACE1("couldn't set packet filter (%08X)", res);
- EXIT2(return);
-}
-
-static void link_status_off(struct ndis_device *wnd)
-{
-#ifdef CONFIG_WIRELESS_EXT
- union iwreq_data wrqu;
-
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- wireless_send_event(wnd->net_dev, SIOCGIWAP, &wrqu, NULL);
-#endif
- EXIT2(return);
-}
-
-static void link_status_on(struct ndis_device *wnd)
-{
-#ifdef CONFIG_WIRELESS_EXT
- struct ndis_assoc_info *ndis_assoc_info;
- union iwreq_data wrqu;
- NDIS_STATUS res;
- const int assoc_size = sizeof(*ndis_assoc_info) + IW_CUSTOM_MAX + 32;
-#endif
-
- ENTER2("");
-#ifdef CONFIG_WIRELESS_EXT
- memset(&wrqu, 0, sizeof(wrqu));
- ndis_assoc_info = kzalloc(assoc_size, GFP_KERNEL);
- if (!ndis_assoc_info) {
- ERROR("couldn't allocate memory");
- goto send_assoc_event;
- }
- res = mp_query(wnd, OID_802_11_ASSOCIATION_INFORMATION,
- ndis_assoc_info, assoc_size);
- if (res) {
- TRACE2("query assoc_info failed (%08X)", res);
- kfree(ndis_assoc_info);
- goto send_assoc_event;
- }
- TRACE2("%u, 0x%x, %u, 0x%x, %u", ndis_assoc_info->length,
- ndis_assoc_info->req_ies, ndis_assoc_info->req_ie_length,
- ndis_assoc_info->resp_ies, ndis_assoc_info->resp_ie_length);
- if (ndis_assoc_info->req_ie_length > 0) {
- wrqu.data.length = ndis_assoc_info->req_ie_length;
- wireless_send_event(wnd->net_dev, IWEVASSOCREQIE, &wrqu,
- ((char *)ndis_assoc_info) +
- ndis_assoc_info->offset_req_ies);
- }
- if (ndis_assoc_info->resp_ie_length > 0) {
- wrqu.data.length = ndis_assoc_info->resp_ie_length;
- wireless_send_event(wnd->net_dev, IWEVASSOCRESPIE, &wrqu,
- ((char *)ndis_assoc_info) +
- ndis_assoc_info->offset_resp_ies);
- }
- kfree(ndis_assoc_info);
-
-send_assoc_event:
- get_ap_address(wnd, wrqu.ap_addr.sa_data);
- wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- TRACE2(MACSTRSEP, MAC2STR(wrqu.ap_addr.sa_data));
- wireless_send_event(wnd->net_dev, SIOCGIWAP, &wrqu, NULL);
-#endif
- EXIT2(return);
-}
-
-static void iw_stats_timer_proc(unsigned long data)
-{
- struct ndis_device *wnd = (struct ndis_device *)data;
-
- ENTER2("%d", wnd->iw_stats_interval);
- if (wnd->iw_stats_interval > 0) {
- set_bit(COLLECT_IW_STATS, &wnd->ndis_pending_work);
- schedule_wrapndis_work(&wnd->ndis_work);
- }
- mod_timer(&wnd->iw_stats_timer, jiffies + wnd->iw_stats_interval);
-}
-
-static void add_iw_stats_timer(struct ndis_device *wnd)
-{
- if (wnd->physical_medium != NdisPhysicalMediumWirelessLan)
- return;
- if (wnd->iw_stats_interval < 0)
- wnd->iw_stats_interval *= -1;
- wnd->iw_stats_timer.data = (unsigned long)wnd;
- wnd->iw_stats_timer.function = iw_stats_timer_proc;
- mod_timer(&wnd->iw_stats_timer, jiffies + wnd->iw_stats_interval);
-}
-
-static void del_iw_stats_timer(struct ndis_device *wnd)
-{
- ENTER2("%d", wnd->iw_stats_interval);
- wnd->iw_stats_interval *= -1;
- del_timer_sync(&wnd->iw_stats_timer);
- EXIT2(return);
-}
-
-static void hangcheck_proc(unsigned long data)
-{
- struct ndis_device *wnd = (struct ndis_device *)data;
-
- ENTER3("%d", wnd->hangcheck_interval);
- if (wnd->hangcheck_interval > 0) {
- set_bit(HANGCHECK, &wnd->ndis_pending_work);
- schedule_wrapndis_work(&wnd->ndis_work);
- }
- mod_timer(&wnd->hangcheck_timer, jiffies + wnd->hangcheck_interval);
- EXIT3(return);
-}
-
-void hangcheck_add(struct ndis_device *wnd)
-{
- if (!wnd->wd->driver->ndis_driver->mp.hangcheck ||
- hangcheck_interval < 0)
- EXIT2(return);
-
- if (hangcheck_interval > 0)
- wnd->hangcheck_interval = hangcheck_interval * HZ;
- if (wnd->hangcheck_interval < 0)
- wnd->hangcheck_interval *= -1;
- wnd->hangcheck_timer.data = (unsigned long)wnd;
- wnd->hangcheck_timer.function = hangcheck_proc;
- mod_timer(&wnd->hangcheck_timer, jiffies + wnd->hangcheck_interval);
- EXIT2(return);
-}
-
-void hangcheck_del(struct ndis_device *wnd)
-{
- ENTER2("%d", wnd->hangcheck_interval);
- if (wnd->hangcheck_interval > 0)
- wnd->hangcheck_interval *= -1;
- del_timer_sync(&wnd->hangcheck_timer);
- EXIT2(return);
-}
-
-/* worker procedure to take care of setting/checking various states */
-static void ndis_worker(worker_param_t param)
-{
- struct ndis_device *wnd;
-
- wnd = worker_param_data(param, struct ndis_device, ndis_work);
- WORKTRACE("0x%lx", wnd->ndis_pending_work);
-
- if (test_and_clear_bit(NETIF_WAKEQ, &wnd->ndis_pending_work)) {
- netif_tx_lock_bh(wnd->net_dev);
- netif_wake_queue(wnd->net_dev);
- netif_tx_unlock_bh(wnd->net_dev);
- }
-
- if (test_and_clear_bit(LINK_STATUS_OFF, &wnd->ndis_pending_work))
- link_status_off(wnd);
-
- if (test_and_clear_bit(LINK_STATUS_ON, &wnd->ndis_pending_work))
- link_status_on(wnd);
-
- if (test_and_clear_bit(COLLECT_IW_STATS, &wnd->ndis_pending_work))
- update_iw_stats(wnd);
-
- if (test_and_clear_bit(SET_MULTICAST_LIST,
- &wnd->ndis_pending_work))
- set_multicast_list(wnd);
-
- if (test_and_clear_bit(HANGCHECK, &wnd->ndis_pending_work)) {
- struct miniport *mp;
- BOOLEAN reset;
- KIRQL irql;
-
- mp = &wnd->wd->driver->ndis_driver->mp;
- irql = serialize_lock_irql(wnd);
- reset = LIN2WIN1(mp->hangcheck, wnd->nmb->mp_ctx);
- serialize_unlock_irql(wnd, irql);
- if (reset) {
- TRACE2("%s needs reset", wnd->net_dev->name);
- mp_reset(wnd);
- }
- }
- WORKEXIT(return);
-}
-
-NDIS_STATUS ndis_reinit(struct ndis_device *wnd)
-{
- NDIS_STATUS status;
-
- wnd->attributes &= ~NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND;
- status = mp_set_power_state(wnd, NdisDeviceStateD3);
- if (status != NDIS_STATUS_SUCCESS) {
- ERROR("halting device %s failed: %08X", wnd->net_dev->name,
- status);
- return status;
- }
- status = mp_set_power_state(wnd, NdisDeviceStateD0);
- if (status != NDIS_STATUS_SUCCESS)
- ERROR("starting device %s failed: %08X", wnd->net_dev->name,
- status);
- return status;
-}
-
-static void get_encryption_capa(struct ndis_device *wnd, char *buf,
- const int buf_len)
-{
- int i, mode;
- NDIS_STATUS res;
- struct ndis_assoc_info ndis_assoc_info;
- struct ndis_add_key ndis_key;
- struct ndis_capability *c;
-
- ENTER1("%p", wnd);
- /* set network type to g, b, or a, in that order */
- res = mp_query(wnd, OID_802_11_NETWORK_TYPES_SUPPORTED, buf, buf_len);
- if (res == NDIS_STATUS_SUCCESS) {
- struct network_type_list *net_types;
- unsigned long types = 0;
- net_types = (typeof(net_types))buf;
- for (i = 0; i < net_types->num; i++) {
- TRACE2("%d", net_types->types[i]);
- set_bit(net_types->types[i], &types);
- }
- if (types & Ndis802_11OFDM24)
- mode = Ndis802_11OFDM24;
- else if (types & Ndis802_11DS)
- mode = Ndis802_11DS;
- else if (types & Ndis802_11OFDM5)
- mode = Ndis802_11OFDM5;
- else
- mode = Ndis802_11DS;
- mp_set_int(wnd, OID_802_11_NETWORK_TYPE_IN_USE, mode);
- }
- /* check if WEP is supported */
- if (set_iw_encr_mode(wnd, IW_AUTH_CIPHER_WEP104,
- IW_AUTH_CIPHER_NONE) == 0 &&
- get_ndis_encr_mode(wnd) == Ndis802_11Encryption1KeyAbsent)
- set_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr);
-
- /* check if WPA is supported */
- if (set_ndis_auth_mode(wnd, Ndis802_11AuthModeWPA) == 0 &&
- get_ndis_auth_mode(wnd) == Ndis802_11AuthModeWPA)
- set_bit(Ndis802_11AuthModeWPA, &wnd->capa.encr);
- else
- EXIT1(return);
-
- if (set_ndis_auth_mode(wnd, Ndis802_11AuthModeWPAPSK) == 0 &&
- get_ndis_auth_mode(wnd) == Ndis802_11AuthModeWPAPSK)
- set_bit(Ndis802_11AuthModeWPAPSK, &wnd->capa.encr);
-
- /* check for highest encryption */
- mode = 0;
- if (set_iw_encr_mode(wnd, IW_AUTH_CIPHER_CCMP,
- IW_AUTH_CIPHER_NONE) == 0 &&
- (i = get_ndis_encr_mode(wnd)) > 0 &&
- (i == Ndis802_11Encryption3KeyAbsent ||
- i == Ndis802_11Encryption3Enabled))
- mode = Ndis802_11Encryption3Enabled;
- else if (set_iw_encr_mode(wnd, IW_AUTH_CIPHER_TKIP,
- IW_AUTH_CIPHER_NONE) == 0 &&
- (i = get_ndis_encr_mode(wnd)) > 0 &&
- (i == Ndis802_11Encryption2KeyAbsent ||
- i == Ndis802_11Encryption2Enabled))
- mode = Ndis802_11Encryption2Enabled;
- else if (set_iw_encr_mode(wnd, IW_AUTH_CIPHER_WEP104,
- IW_AUTH_CIPHER_NONE) == 0 &&
- (i = get_ndis_encr_mode(wnd)) > 0 &&
- (i == Ndis802_11Encryption1KeyAbsent ||
- i == Ndis802_11Encryption1Enabled))
- mode = Ndis802_11Encryption1Enabled;
-
- TRACE1("mode: %d", mode);
- if (mode == 0)
- EXIT1(return);
- set_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr);
- if (mode == Ndis802_11Encryption1Enabled)
- EXIT1(return);
-
- ndis_key.length = 32;
- ndis_key.index = 0xC0000001;
- ndis_key.struct_size = sizeof(ndis_key);
- res = mp_set(wnd, OID_802_11_ADD_KEY, &ndis_key, ndis_key.struct_size);
- TRACE2("%08X, %lu", res, (unsigned long)sizeof(ndis_key));
- if (res && res != NDIS_STATUS_INVALID_DATA)
- EXIT1(return);
- res = mp_query(wnd, OID_802_11_ASSOCIATION_INFORMATION,
- &ndis_assoc_info, sizeof(ndis_assoc_info));
- TRACE1("%08X", res);
- if (res == NDIS_STATUS_NOT_SUPPORTED)
- EXIT1(return);
-
- set_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr);
- if (mode == Ndis802_11Encryption3Enabled)
- set_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr);
- /* not all drivers support OID_802_11_CAPABILITY, so we don't
- * know for sure if driver support WPA or WPAPSK; assume
- * WPAPSK */
- set_bit(Ndis802_11AuthModeWPAPSK, &wnd->capa.auth);
- wnd->max_pmkids = 1;
-
- memset(buf, 0, buf_len);
- c = (struct ndis_capability *)buf;
- res = mp_query(wnd, OID_802_11_CAPABILITY, buf, buf_len);
- if (!(res == NDIS_STATUS_SUCCESS && c->version == 2))
- EXIT1(return);
- wnd->max_pmkids = c->num_PMKIDs;
-
- for (i = 0; i < c->num_auth_encr_pair; i++) {
- struct ndis_auth_encr_pair *ae;
-
- ae = &c->auth_encr_pair[i];
- if ((char *)(ae + 1) > buf + buf_len)
- break;
- switch (ae->auth_mode) {
- case Ndis802_11AuthModeOpen:
- case Ndis802_11AuthModeShared:
- case Ndis802_11AuthModeWPA:
- case Ndis802_11AuthModeWPAPSK:
- case Ndis802_11AuthModeWPANone:
- case Ndis802_11AuthModeWPA2:
- case Ndis802_11AuthModeWPA2PSK:
- set_bit(ae->auth_mode, &wnd->capa.auth);
- break;
- default:
- WARNING("unknown auth_mode: %d", ae->auth_mode);
- break;
- }
- switch (ae->encr_mode) {
- case Ndis802_11EncryptionDisabled:
- case Ndis802_11Encryption1Enabled:
- case Ndis802_11Encryption2Enabled:
- case Ndis802_11Encryption3Enabled:
- set_bit(ae->encr_mode, &wnd->capa.encr);
- break;
- default:
- WARNING("unknown encr_mode: %d", ae->encr_mode);
- break;
- }
- }
- EXIT1(return);
-}
-
-wstdcall NTSTATUS NdisDispatchDeviceControl(struct device_object *fdo,
- struct irp *irp)
-{
- struct ndis_device *wnd;
-
- TRACE3("fdo: %p", fdo);
- /* for now, we don't have anything intresting here, so pass it
- * down to bus driver */
- wnd = fdo->reserved;
- return IoPassIrpDown(wnd->nmb->pdo, irp);
-}
-WIN_FUNC_DECL(NdisDispatchDeviceControl,2)
-
-wstdcall NTSTATUS NdisDispatchPower(struct device_object *fdo, struct irp *irp)
-{
- struct io_stack_location *irp_sl;
- struct ndis_device *wnd;
- enum ndis_power_state state;
- NTSTATUS status;
- NDIS_STATUS ndis_status;
-
- irp_sl = IoGetCurrentIrpStackLocation(irp);
- wnd = fdo->reserved;
- IOTRACE("fdo: %p, fn: %d:%d, wnd: %p", fdo, irp_sl->major_fn,
- irp_sl->minor_fn, wnd);
- if ((irp_sl->params.power.type == SystemPowerState &&
- irp_sl->params.power.state.system_state > PowerSystemWorking) ||
- (irp_sl->params.power.type == DevicePowerState &&
- irp_sl->params.power.state.device_state > PowerDeviceD0))
- state = NdisDeviceStateD3;
- else
- state = NdisDeviceStateD0;
- switch (irp_sl->minor_fn) {
- case IRP_MN_SET_POWER:
- if (state == NdisDeviceStateD0) {
- status = IoSyncForwardIrp(wnd->nmb->pdo, irp);
- if (status != STATUS_SUCCESS)
- break;
- ndis_status = mp_set_power_state(wnd, state);
- if (ndis_status != NDIS_STATUS_SUCCESS)
- WARNING("couldn't set power to %d: %08X",
- state, ndis_status);
- TRACE2("%s: device resumed", wnd->net_dev->name);
- irp->io_status.status = status = STATUS_SUCCESS;
- IoCompleteRequest(irp, IO_NO_INCREMENT);
- break;
- } else {
- ndis_status = mp_set_power_state(wnd, state);
- /* TODO: handle error case */
- if (ndis_status != NDIS_STATUS_SUCCESS)
- WARNING("setting power to %d failed: %08X",
- state, ndis_status);
- status = IoAsyncForwardIrp(wnd->nmb->pdo, irp);
- }
- break;
- case IRP_MN_QUERY_POWER:
- if (wnd->attributes & NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND) {
- ndis_status = mp_query(wnd, OID_PNP_QUERY_POWER,
- &state, sizeof(state));
- TRACE2("%d, %08X", state, ndis_status);
- /* this OID must always succeed */
- if (ndis_status != NDIS_STATUS_SUCCESS)
- TRACE1("query power returns %08X", ndis_status);
- irp->io_status.status = STATUS_SUCCESS;
- } else
- irp->io_status.status = STATUS_SUCCESS;
- status = IoPassIrpDown(wnd->nmb->pdo, irp);
- break;
- case IRP_MN_WAIT_WAKE:
- case IRP_MN_POWER_SEQUENCE:
- /* TODO: implement WAIT_WAKE */
- status = IoPassIrpDown(wnd->nmb->pdo, irp);
- break;
- default:
- status = IoPassIrpDown(wnd->nmb->pdo, irp);
- break;
- }
- IOEXIT(return status);
-}
-WIN_FUNC_DECL(NdisDispatchPower,2)
-
-wstdcall NTSTATUS NdisDispatchPnp(struct device_object *fdo, struct irp *irp)
-{
- struct io_stack_location *irp_sl;
- struct ndis_device *wnd;
- struct device_object *pdo;
- NTSTATUS status;
-
- IOTRACE("fdo: %p, irp: %p", fdo, irp);
- irp_sl = IoGetCurrentIrpStackLocation(irp);
- wnd = fdo->reserved;
- pdo = wnd->nmb->pdo;
- switch (irp_sl->minor_fn) {
- case IRP_MN_START_DEVICE:
- status = IoSyncForwardIrp(pdo, irp);
- if (status != STATUS_SUCCESS)
- break;
- if (ndis_start_device(wnd) == NDIS_STATUS_SUCCESS)
- status = STATUS_SUCCESS;
- else
- status = STATUS_FAILURE;
- irp->io_status.status = status;
- IoCompleteRequest(irp, IO_NO_INCREMENT);
- break;
- case IRP_MN_QUERY_STOP_DEVICE:
- /* TODO: implement in NDIS */
- status = IoPassIrpDown(wnd->nmb->pdo, irp);
- break;
- case IRP_MN_STOP_DEVICE:
- mp_halt(wnd);
- irp->io_status.status = STATUS_SUCCESS;
- status = IoAsyncForwardIrp(pdo, irp);
- break;
- case IRP_MN_REMOVE_DEVICE:
- TRACE1("%s", wnd->net_dev->name);
- mp_pnp_event(wnd, NdisDevicePnPEventSurpriseRemoved, 0);
- if (ndis_remove_device(wnd)) {
- status = STATUS_FAILURE;
- break;
- }
- /* wnd is already freed */
- status = IoAsyncForwardIrp(pdo, irp);
- IoDetachDevice(fdo);
- IoDeleteDevice(fdo);
- break;
- default:
- status = IoAsyncForwardIrp(pdo, irp);
- break;
- }
- IOTRACE("status: %08X", status);
- IOEXIT(return status);
-}
-WIN_FUNC_DECL(NdisDispatchPnp,2)
-
-static void set_task_offload(struct ndis_device *wnd, void *buf,
- const int buf_size)
-{
- struct ndis_task_offload_header *task_offload_header;
- struct ndis_task_offload *task_offload;
- struct ndis_task_tcp_ip_checksum *csum = NULL;
- struct ndis_task_tcp_large_send *tso = NULL;
- NDIS_STATUS status;
-
- memset(buf, 0, buf_size);
- task_offload_header = buf;
- task_offload_header->version = NDIS_TASK_OFFLOAD_VERSION;
- task_offload_header->size = sizeof(*task_offload_header);
- task_offload_header->encap_format.flags.fixed_header_size = 1;
- task_offload_header->encap_format.header_size = sizeof(struct ethhdr);
- task_offload_header->encap_format.encap = IEEE_802_3_Encapsulation;
- status = mp_query(wnd, OID_TCP_TASK_OFFLOAD, buf, buf_size);
- TRACE1("%08X", status);
- if (status != NDIS_STATUS_SUCCESS)
- EXIT1(return);
- if (task_offload_header->offset_first_task == 0)
- EXIT1(return);
- task_offload = ((void *)task_offload_header +
- task_offload_header->offset_first_task);
- while (1) {
- TRACE1("%d, %d", task_offload->version, task_offload->task);
- switch(task_offload->task) {
- case TcpIpChecksumNdisTask:
- csum = (void *)task_offload->task_buf;
- break;
- case TcpLargeSendNdisTask:
- tso = (void *)task_offload->task_buf;
- break;
- default:
- TRACE1("%d", task_offload->task);
- break;
- }
- if (task_offload->offset_next_task == 0)
- break;
- task_offload = (void *)task_offload +
- task_offload->offset_next_task;
- }
- if (tso)
- TRACE1("%u, %u, %d, %d", tso->max_size, tso->min_seg_count,
- tso->tcp_opts, tso->ip_opts);
- if (!csum)
- EXIT1(return);
- TRACE1("%08x, %08x", csum->v4_tx.value, csum->v4_rx.value);
- task_offload_header->encap_format.flags.fixed_header_size = 1;
- task_offload_header->encap_format.header_size = sizeof(struct ethhdr);
- task_offload_header->offset_first_task = sizeof(*task_offload_header);
- task_offload = ((void *)task_offload_header +
- task_offload_header->offset_first_task);
- task_offload->offset_next_task = 0;
- task_offload->size = sizeof(*task_offload);
- task_offload->task = TcpIpChecksumNdisTask;
- memcpy(task_offload->task_buf, csum, sizeof(*csum));
- task_offload->task_buf_length = sizeof(*csum);
- status = mp_set(wnd, OID_TCP_TASK_OFFLOAD, task_offload_header,
- sizeof(*task_offload_header) +
- sizeof(*task_offload) + sizeof(*csum));
- TRACE1("%08X", status);
- if (status != NDIS_STATUS_SUCCESS)
- EXIT2(return);
- wnd->tx_csum = csum->v4_tx;
- if (csum->v4_tx.tcp_csum && csum->v4_tx.udp_csum) {
- if (csum->v4_tx.ip_csum) {
- wnd->net_dev->features |= NETIF_F_HW_CSUM;
- TRACE1("hw checksum enabled");
- } else {
- wnd->net_dev->features |= NETIF_F_IP_CSUM;
- TRACE1("IP checksum enabled");
- }
- if (wnd->sg_dma_size)
- wnd->net_dev->features |= NETIF_F_SG;
- }
- wnd->rx_csum = csum->v4_rx;
- EXIT1(return);
-}
-
-static void get_supported_oids(struct ndis_device *wnd)
-{
- NDIS_STATUS res;
- int i, n, needed;
- ndis_oid *oids;
-
- res = mp_query_info(wnd, OID_GEN_SUPPORTED_LIST, NULL, 0, NULL,
- &needed);
- if (!(res == NDIS_STATUS_BUFFER_TOO_SHORT ||
- res == NDIS_STATUS_INVALID_LENGTH))
- EXIT1(return);
- oids = kmalloc(needed, GFP_KERNEL);
- if (!oids) {
- TRACE1("couldn't allocate memory");
- EXIT1(return);
- }
- res = mp_query(wnd, OID_GEN_SUPPORTED_LIST, oids, needed);
- if (res) {
- TRACE1("failed: %08X", res);
- kfree(oids);
- EXIT1(return);
- }
- for (i = 0, n = needed / sizeof(*oids); i < n; i++) {
- TRACE1("oid: %08X", oids[i]);
- /* if a wireless device didn't say so for
- * OID_GEN_PHYSICAL_MEDIUM (they should, but in case) */
- if (wnd->physical_medium != NdisPhysicalMediumWirelessLan &&
- oids[i] == OID_802_11_SSID)
- wnd->physical_medium = NdisPhysicalMediumWirelessLan;
- }
- kfree(oids);
- EXIT1(return);
-}
-
-static void ndis_get_drvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 2);
- strcat(info->driver, "+");
- strncat(info->driver, wnd->wd->driver->name,
- sizeof(info->driver) - strlen(DRIVER_NAME) - 1);
- strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 2);
- strcat(info->version, "+");
- strncat(info->version, wnd->wd->driver->version,
- sizeof(info->version) - strlen(DRIVER_VERSION) - 1);
- if (wrap_is_pci_bus(wnd->wd->dev_bus))
- strncpy(info->bus_info, pci_name(wnd->wd->pci.pdev),
- sizeof(info->bus_info) - 1);
-#ifdef ENABLE_USB
- else
- usb_make_path(wnd->wd->usb.udev, info->bus_info,
- sizeof(info->bus_info) - 1);
-#endif
- return;
-}
-
-static u32 ndis_get_link(struct net_device *dev)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- return netif_carrier_ok(wnd->net_dev);
-}
-
-static void ndis_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
-{
- struct ndis_device *wnd = netdev_priv(dev);
-
- wol->supported = 0;
- wol->wolopts = 0;
- if (!(wnd->attributes & NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND))
- EXIT2(return);
- if (!wrap_is_pci_bus(wnd->wd->dev_bus))
- EXIT2(return);
- /* we always suspend to D3 */
- if (wnd->pnp_capa.wakeup.min_magic_packet_wakeup < NdisDeviceStateD3)
- return;
- wol->supported |= WAKE_MAGIC;
- if (wnd->ndis_wolopts & NDIS_PNP_WAKE_UP_MAGIC_PACKET)
- wol->wolopts |= WAKE_MAGIC;
- return;
-}
-
-static int ndis_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
-{
- struct ndis_device *wnd = netdev_priv(dev);
-
- if (!(wnd->attributes & NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND))
- return -EOPNOTSUPP;
- if (wnd->pnp_capa.wakeup.min_magic_packet_wakeup < NdisDeviceStateD3)
- EXIT2(return -EOPNOTSUPP);
- TRACE2("0x%x", wol->wolopts);
- if (wol->wolopts & WAKE_MAGIC) {
- wnd->ndis_wolopts |= NDIS_PNP_WAKE_UP_MAGIC_PACKET;
- if (wol->wolopts != WAKE_MAGIC)
- WARNING("ignored wake-on-lan options: 0x%x",
- wol->wolopts & ~WAKE_MAGIC);
- } else if (!wol->wolopts)
- wnd->ndis_wolopts = 0;
- else
- return -EOPNOTSUPP;
- TRACE2("0x%x", wnd->ndis_wolopts);
- return 0;
-}
-
-static u32 ndis_get_tx_csum(struct net_device *dev)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- if (wnd->tx_csum.tcp_csum && wnd->tx_csum.udp_csum)
- return 1;
- else
- return 0;
-}
-
-static u32 ndis_get_rx_csum(struct net_device *dev)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- if (wnd->rx_csum.value)
- return 1;
- else
- return 0;
-}
-
-static int ndis_set_tx_csum(struct net_device *dev, u32 data)
-{
- struct ndis_device *wnd = netdev_priv(dev);
-
- if (data && (wnd->tx_csum.value == 0))
- return -EOPNOTSUPP;
-
- if (wnd->tx_csum.ip_csum)
- ethtool_op_set_tx_hw_csum(dev, data);
- else
- ethtool_op_set_tx_csum(dev, data);
- return 0;
-}
-
-static int ndis_set_rx_csum(struct net_device *dev, u32 data)
-{
- struct ndis_device *wnd = netdev_priv(dev);
-
- if (data && (wnd->tx_csum.value == 0))
- return -EOPNOTSUPP;
-
- /* TODO: enable/disable rx csum through NDIS */
- return 0;
-}
-
-static u32 ndis_get_sg(struct net_device *dev)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- if (wnd->sg_dma_size)
- return ethtool_op_get_sg(dev);
- else
- return 0;
-}
-
-static int ndis_set_sg(struct net_device *dev, u32 data)
-{
- struct ndis_device *wnd = netdev_priv(dev);
- if (wnd->sg_dma_size)
- return ethtool_op_set_sg(dev, data);
- else
- return -EOPNOTSUPP;
-}
-
-static struct ethtool_ops ndis_ethtool_ops = {
- .get_drvinfo = ndis_get_drvinfo,
- .get_link = ndis_get_link,
- .get_wol = ndis_get_wol,
- .set_wol = ndis_set_wol,
- .get_tx_csum = ndis_get_tx_csum,
- .get_rx_csum = ndis_get_rx_csum,
- .set_tx_csum = ndis_set_tx_csum,
- .set_rx_csum = ndis_set_rx_csum,
- .get_sg = ndis_get_sg,
- .set_sg = ndis_set_sg,
-};
-
-static int notifier_event(struct notifier_block *notifier, unsigned long event,
- void *ptr)
-{
- struct net_device *net_dev = ptr;
-
- ENTER2("0x%lx", event);
- if (net_dev->ethtool_ops == &ndis_ethtool_ops
- && event == NETDEV_CHANGENAME) {
- struct ndis_device *wnd = netdev_priv(net_dev);
- /* called with rtnl lock held, so no need to lock */
- wrap_procfs_remove_ndis_device(wnd);
- printk(KERN_INFO "%s: changing interface name from '%s' to "
- "'%s'\n", DRIVER_NAME, wnd->netdev_name, net_dev->name);
- memcpy(wnd->netdev_name, net_dev->name,
- sizeof(wnd->netdev_name));
- wrap_procfs_add_ndis_device(wnd);
- }
- return NOTIFY_DONE;
-}
-
-static struct notifier_block netdev_notifier = {
- .notifier_call = notifier_event,
-};
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
-static const struct net_device_ops ndis_netdev_ops = {
- .ndo_open = ndis_net_dev_open,
- .ndo_stop = ndis_net_dev_close,
- .ndo_start_xmit = tx_skbuff,
- .ndo_change_mtu = ndis_change_mtu,
- .ndo_set_multicast_list = ndis_set_multicast_list,
- .ndo_set_mac_address = ndis_set_mac_address,
- .ndo_get_stats = ndis_get_stats,
-#ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = ndis_poll_controller,
-#endif
-};
-#endif
-
-static NDIS_STATUS ndis_start_device(struct ndis_device *wnd)
-{
- struct wrap_device *wd;
- struct net_device *net_dev;
- NDIS_STATUS status;
- char *buf;
- const int buf_len = 256;
- mac_address mac;
- struct transport_header_offset *tx_header_offset;
- int n;
-
- ENTER2("%d", in_atomic());
- status = mp_init(wnd);
- if (status == NDIS_STATUS_NOT_RECOGNIZED)
- EXIT1(return NDIS_STATUS_SUCCESS);
- if (status != NDIS_STATUS_SUCCESS)
- EXIT1(return status);
- wd = wnd->wd;
- net_dev = wnd->net_dev;
-
- get_supported_oids(wnd);
- memset(mac, 0, sizeof(mac));
- status = mp_query(wnd, OID_802_3_CURRENT_ADDRESS, mac, sizeof(mac));
- if (memcmp(mac, "\x00\x00\x00\x00\x00\x00", sizeof(mac)) == 0) {
- status = mp_query(wnd, OID_802_3_PERMANENT_ADDRESS, mac,
- sizeof(mac));
- if (status != NDIS_STATUS_SUCCESS) {
- ERROR("couldn't get mac address: %08X", status);
- goto err_start;
- }
- }
- TRACE1("mac:" MACSTRSEP, MAC2STR(mac));
- memcpy(net_dev->dev_addr, mac, ETH_ALEN);
-
- strncpy(net_dev->name, if_name, IFNAMSIZ - 1);
- net_dev->name[IFNAMSIZ - 1] = 0;
-
- wnd->packet_filter = NDIS_PACKET_TYPE_DIRECTED |
- NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_MULTICAST;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
- net_dev->netdev_ops = &ndis_netdev_ops;
-#else
- net_dev->open = ndis_net_dev_open;
- net_dev->hard_start_xmit = tx_skbuff;
- net_dev->stop = ndis_net_dev_close;
- net_dev->get_stats = ndis_get_stats;
- net_dev->change_mtu = ndis_change_mtu;
- net_dev->set_multicast_list = ndis_set_multicast_list;
- net_dev->set_mac_address = ndis_set_mac_address;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- net_dev->poll_controller = ndis_poll_controller;
-#endif
-#endif
- if (wnd->physical_medium == NdisPhysicalMediumWirelessLan) {
- net_dev->wireless_handlers = &ndis_handler_def;
- }
- net_dev->ethtool_ops = &ndis_ethtool_ops;
- if (wnd->mp_interrupt)
- net_dev->irq = wnd->mp_interrupt->irq;
- net_dev->mem_start = wnd->mem_start;
- net_dev->mem_end = wnd->mem_end;
- status = mp_query_int(wnd, OID_802_3_MAXIMUM_LIST_SIZE,
- &wnd->multicast_size);
- if (status != NDIS_STATUS_SUCCESS || wnd->multicast_size < 0)
- wnd->multicast_size = 0;
- if (wnd->multicast_size > 0)
- net_dev->flags |= IFF_MULTICAST;
- else
- net_dev->flags &= ~IFF_MULTICAST;
-
- buf = kmalloc(buf_len, GFP_KERNEL);
- if (!buf) {
- WARNING("couldn't allocate memory");
- goto err_start;
- }
-
- set_task_offload(wnd, buf, buf_len);
-#ifdef NETIF_F_LLTX
- net_dev->features |= NETIF_F_LLTX;
-#endif
-
- if (register_netdev(net_dev)) {
- ERROR("cannot register net device %s", net_dev->name);
- goto err_register;
- }
- memcpy(wnd->netdev_name, net_dev->name, sizeof(wnd->netdev_name));
- memset(buf, 0, buf_len);
- status = mp_query(wnd, OID_GEN_VENDOR_DESCRIPTION, buf, buf_len);
- if (status != NDIS_STATUS_SUCCESS) {
- WARNING("couldn't get vendor information: 0x%x", status);
- buf[0] = 0;
- }
- wnd->drv_ndis_version = n = 0;
- mp_query_int(wnd, OID_GEN_DRIVER_VERSION, &wnd->drv_ndis_version);
- mp_query_int(wnd, OID_GEN_VENDOR_DRIVER_VERSION, &n);
-
- printk(KERN_INFO "%s: ethernet device " MACSTRSEP " using %sNDIS "
- "driver: %s, version: 0x%x, NDIS version: 0x%x, vendor: '%s', "
- "%s\n", net_dev->name, MAC2STR(net_dev->dev_addr),
- deserialized_driver(wnd) ? "" : "serialized ",
- wnd->wd->driver->name, n, wnd->drv_ndis_version, buf,
- wnd->wd->conf_file_name);
-
- if (deserialized_driver(wnd)) {
- /* deserialized drivers don't have a limit, but we
- * keep max at TX_RING_SIZE */
- wnd->max_tx_packets = TX_RING_SIZE;
- } else {
- status = mp_query_int(wnd, OID_GEN_MAXIMUM_SEND_PACKETS,
- &wnd->max_tx_packets);
- if (status != NDIS_STATUS_SUCCESS)
- wnd->max_tx_packets = 1;
- if (wnd->max_tx_packets > TX_RING_SIZE)
- wnd->max_tx_packets = TX_RING_SIZE;
- }
- TRACE2("maximum send packets: %d", wnd->max_tx_packets);
- NdisAllocatePacketPoolEx(&status, &wnd->tx_packet_pool,
- wnd->max_tx_packets, 0,
- PROTOCOL_RESERVED_SIZE_IN_PACKET);
- if (status != NDIS_STATUS_SUCCESS) {
- ERROR("couldn't allocate packet pool");
- goto packet_pool_err;
- }
- NdisAllocateBufferPool(&status, &wnd->tx_buffer_pool,
- wnd->max_tx_packets + 4);
- if (status != NDIS_STATUS_SUCCESS) {
- ERROR("couldn't allocate buffer pool");
- goto buffer_pool_err;
- }
- TRACE1("pool: %p", wnd->tx_buffer_pool);
-
- if (mp_query_int(wnd, OID_GEN_MAXIMUM_TOTAL_SIZE, &n) ==
- NDIS_STATUS_SUCCESS && n > ETH_HLEN)
- ndis_change_mtu(wnd->net_dev, n - ETH_HLEN);
-
- if (mp_query_int(wnd, OID_GEN_MAC_OPTIONS, &n) == NDIS_STATUS_SUCCESS)
- TRACE2("mac options supported: 0x%x", n);
-
- tx_header_offset = (typeof(tx_header_offset))buf;
- tx_header_offset->protocol_type = NDIS_PROTOCOL_ID_TCP_IP;
- tx_header_offset->header_offset = sizeof(ETH_HLEN);
- status = mp_set(wnd, OID_GEN_TRANSPORT_HEADER_OFFSET,
- tx_header_offset, sizeof(*tx_header_offset));
- TRACE2("%08X", status);
-
- status = mp_query_int(wnd, OID_GEN_PHYSICAL_MEDIUM,
- &wnd->physical_medium);
- if (status != NDIS_STATUS_SUCCESS)
- wnd->physical_medium = NdisPhysicalMediumUnspecified;
-
- if (wnd->physical_medium == NdisPhysicalMediumWirelessLan) {
- mp_set_int(wnd, OID_802_11_POWER_MODE, NDIS_POWER_OFF);
- get_encryption_capa(wnd, buf, buf_len);
- TRACE1("capbilities = %ld", wnd->capa.encr);
- printk(KERN_INFO "%s: encryption modes supported: "
- "%s%s%s%s%s%s%s\n", net_dev->name,
- test_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr) ?
- "WEP" : "none",
-
- test_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr) ?
- "; TKIP with WPA" : "",
- test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) ?
- ", WPA2" : "",
- test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth) ?
- ", WPA2PSK" : "",
-
- test_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr) ?
- "; AES/CCMP with WPA" : "",
- test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) ?
- ", WPA2" : "",
- test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth) ?
- ", WPA2PSK" : "");
-
- set_default_iw_params(wnd);
- }
- status = mp_query_int(wnd, OID_GEN_MEDIA_CONNECT_STATUS, (int *)buf);
- if (status == NDIS_STATUS_SUCCESS)
- set_media_state(wnd, *((int *)buf));
- kfree(buf);
- wrap_procfs_add_ndis_device(wnd);
- hangcheck_add(wnd);
- add_iw_stats_timer(wnd);
- EXIT1(return NDIS_STATUS_SUCCESS);
-
-buffer_pool_err:
- wnd->tx_buffer_pool = NULL;
- if (wnd->tx_packet_pool) {
- NdisFreePacketPool(wnd->tx_packet_pool);
- wnd->tx_packet_pool = NULL;
- }
-packet_pool_err:
-err_register:
- kfree(buf);
-err_start:
- ndis_remove_device(wnd);
- EXIT1(return NDIS_STATUS_FAILURE);
-}
-
-static int ndis_remove_device(struct ndis_device *wnd)
-{
- s8 tx_pending;
-
- /* prevent setting essid during disassociation */
- memset(&wnd->essid, 0, sizeof(wnd->essid));
- wnd->tx_ok = 0;
- if (wnd->max_tx_packets)
- unregister_netdev(wnd->net_dev);
- netif_carrier_off(wnd->net_dev);
- /* if device is suspended, but resume failed, tx_ring_mutex
- * may already be locked */
- if (down_trylock(&wnd->tx_ring_mutex))
- WARNING("couldn't obtain tx_ring_mutex");
- spin_lock_bh(&wnd->tx_ring_lock);
- tx_pending = wnd->tx_ring_end - wnd->tx_ring_start;
- if (tx_pending < 0)
- tx_pending += TX_RING_SIZE;
- else if (tx_pending == 0 && wnd->is_tx_ring_full)
- tx_pending = TX_RING_SIZE - 1;
- wnd->is_tx_ring_full = 0;
- /* throw away pending packets */
- while (tx_pending-- > 0) {
- struct ndis_packet *packet;
-
- packet = wnd->tx_ring[wnd->tx_ring_start];
- free_tx_packet(wnd, packet, NDIS_STATUS_CLOSING);
- wnd->tx_ring_start = (wnd->tx_ring_start + 1) % TX_RING_SIZE;
- }
- spin_unlock_bh(&wnd->tx_ring_lock);
- up(&wnd->tx_ring_mutex);
- wrap_procfs_remove_ndis_device(wnd);
- mp_halt(wnd);
- ndis_exit_device(wnd);
-
- if (wnd->tx_packet_pool) {
- NdisFreePacketPool(wnd->tx_packet_pool);
- wnd->tx_packet_pool = NULL;
- }
- if (wnd->tx_buffer_pool) {
- NdisFreeBufferPool(wnd->tx_buffer_pool);
- wnd->tx_buffer_pool = NULL;
- }
- if (wnd->pmkids)
- kfree(wnd->pmkids);
- printk(KERN_INFO "%s: device %s removed\n", DRIVER_NAME,
- wnd->net_dev->name);
- kfree(wnd->nmb);
- free_netdev(wnd->net_dev);
- EXIT2(return 0);
-}
-
-static wstdcall NTSTATUS NdisAddDevice(struct driver_object *drv_obj,
- struct device_object *pdo)
-{
- struct device_object *fdo;
- struct ndis_mp_block *nmb;
- NTSTATUS status;
- struct ndis_device *wnd;
- struct net_device *net_dev;
- struct wrap_device *wd;
- unsigned long i;
-
- ENTER2("%p, %p", drv_obj, pdo);
- if (strlen(if_name) >= IFNAMSIZ) {
- ERROR("interface name '%s' is too long", if_name);
- return STATUS_INVALID_PARAMETER;
- }
- net_dev = alloc_etherdev(sizeof(*wnd));
- if (!net_dev) {
- ERROR("couldn't allocate device");
- return STATUS_RESOURCES;
- }
- wd = pdo->reserved;
- if (wrap_is_pci_bus(wd->dev_bus))
- SET_NETDEV_DEV(net_dev, &wd->pci.pdev->dev);
- if (wrap_is_usb_bus(wd->dev_bus))
- SET_NETDEV_DEV(net_dev, &wd->usb.intf->dev);
- status = IoCreateDevice(drv_obj, 0, NULL, FILE_DEVICE_UNKNOWN, 0,
- FALSE, &fdo);
- if (status != STATUS_SUCCESS) {
- free_netdev(net_dev);
- EXIT2(return status);
- }
- wnd = netdev_priv(net_dev);
- TRACE1("wnd: %p", wnd);
-
- nmb = kmalloc(sizeof(*nmb), GFP_KERNEL);
- if (!nmb) {
- WARNING("couldn't allocate memory");
- IoDeleteDevice(fdo);
- free_netdev(net_dev);
- return STATUS_RESOURCES;
- }
-#if defined(DEBUG) && DEBUG >= 6
- /* poison nmb so if a driver accesses uninitialized pointers, we
- * know what it is */
- for (i = 0; i < sizeof(*nmb) / sizeof(unsigned long); i++)
- ((unsigned long *)nmb)[i] = i + 0x8a3fc1;
-#endif
-
- wnd->nmb = nmb;
- nmb->wnd = wnd;
- nmb->pdo = pdo;
- wd->wnd = wnd;
- wnd->wd = wd;
- wnd->net_dev = net_dev;
- fdo->reserved = wnd;
- nmb->fdo = fdo;
- if (ndis_init_device(wnd)) {
- IoDeleteDevice(fdo);
- kfree(nmb);
- free_netdev(net_dev);
- EXIT1(return STATUS_RESOURCES);
- }
- nmb->next_device = IoAttachDeviceToDeviceStack(fdo, pdo);
- spin_lock_init(&wnd->tx_ring_lock);
- sema_init(&wnd->tx_ring_mutex, 1);
- sema_init(&wnd->ndis_req_mutex, 1);
- wnd->ndis_req_done = 0;
- initialize_work(&wnd->tx_work, tx_worker, wnd);
- wnd->tx_ring_start = 0;
- wnd->tx_ring_end = 0;
- wnd->is_tx_ring_full = 0;
- wnd->capa.encr = 0;
- wnd->capa.auth = 0;
- wnd->attributes = 0;
- wnd->dma_map_count = 0;
- wnd->dma_map_addr = NULL;
- wnd->nick[0] = 0;
- init_timer(&wnd->hangcheck_timer);
- wnd->scan_timestamp = 0;
- init_timer(&wnd->iw_stats_timer);
- wnd->iw_stats_interval = 10 * HZ;
- wnd->ndis_pending_work = 0;
- memset(&wnd->essid, 0, sizeof(wnd->essid));
- memset(&wnd->encr_info, 0, sizeof(wnd->encr_info));
- wnd->infrastructure_mode = Ndis802_11Infrastructure;
- initialize_work(&wnd->ndis_work, ndis_worker, wnd);
- wnd->iw_stats_enabled = TRUE;
-
- TRACE1("nmb: %p, pdo: %p, fdo: %p, attached: %p, next: %p",
- nmb, pdo, fdo, fdo->attached, nmb->next_device);
-
- /* dispatch routines are called as Windows functions */
- for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
- drv_obj->major_func[i] = WIN_FUNC_PTR(IoPassIrpDown,2);
-
- drv_obj->major_func[IRP_MJ_PNP] = WIN_FUNC_PTR(NdisDispatchPnp,2);
- drv_obj->major_func[IRP_MJ_POWER] = WIN_FUNC_PTR(NdisDispatchPower,2);
- drv_obj->major_func[IRP_MJ_INTERNAL_DEVICE_CONTROL] =
- WIN_FUNC_PTR(NdisDispatchDeviceControl,2);
-// drv_obj->major_func[IRP_MJ_DEVICE_CONTROL] =
-// WIN_FUNC_PTR(NdisDispatchDeviceControl,2);
- EXIT2(return STATUS_SUCCESS);
-}
-
-int init_ndis_driver(struct driver_object *drv_obj)
-{
- ENTER1("%p", drv_obj);
- drv_obj->drv_ext->add_device = NdisAddDevice;
- return 0;
-}
-
-int wrapndis_init(void)
-{
- wrapndis_wq = create_singlethread_workqueue("wrapndis_wq");
- if (!wrapndis_wq)
- EXIT1(return -ENOMEM);
- wrapndis_worker_thread = wrap_worker_init(wrapndis_wq);
- TRACE1("%p", wrapndis_worker_thread);
- register_netdevice_notifier(&netdev_notifier);
- return 0;
-}
-
-void wrapndis_exit(void)
-{
- unregister_netdevice_notifier(&netdev_notifier);
- if (wrapndis_wq)
- destroy_workqueue(wrapndis_wq);
- TRACE1("%p", wrapndis_worker_thread);
- if (wrapndis_worker_thread)
- ObDereferenceObject(wrapndis_worker_thread);
-}
+++ /dev/null
-/*
- * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef _WRAPNDIS_H_
-#define _WRAPNDIS_H_
-
-#include "ndis.h"
-#include "pnp.h"
-
-int wrapndis_init(void);
-void wrapndis_exit(void);
-
-NDIS_STATUS mp_reset(struct ndis_device *wnd);
-
-NDIS_STATUS mp_request(enum ndis_request_type request,
- struct ndis_device *wnd, ndis_oid oid,
- void *buf, ULONG buflen, ULONG *written, ULONG *needed);
-
-static inline NDIS_STATUS mp_query_info(struct ndis_device *wnd,
- ndis_oid oid, void *buf, ULONG buflen,
- ULONG *written, ULONG *needed)
-{
- return mp_request(NdisRequestQueryInformation, wnd, oid,
- buf, buflen, written, needed);
-}
-
-static inline NDIS_STATUS mp_set_info(struct ndis_device *wnd,
- ndis_oid oid, void *buf, ULONG buflen,
- ULONG *written, ULONG *needed)
-{
- return mp_request(NdisRequestSetInformation, wnd, oid,
- buf, buflen, written, needed);
-}
-
-static inline NDIS_STATUS mp_query(struct ndis_device *wnd, ndis_oid oid,
- void *buf, ULONG buflen)
-{
- return mp_request(NdisRequestQueryInformation, wnd, oid,
- buf, buflen, NULL, NULL);
-}
-
-static inline NDIS_STATUS mp_query_int(struct ndis_device *wnd,
- ndis_oid oid, ULONG *data)
-{
- return mp_request(NdisRequestQueryInformation, wnd, oid,
- data, sizeof(ULONG), NULL, NULL);
-}
-
-static inline NDIS_STATUS mp_set(struct ndis_device *wnd, ndis_oid oid,
- void *buf, ULONG buflen)
-{
- return mp_request(NdisRequestSetInformation, wnd, oid,
- buf, buflen, NULL, NULL);
-}
-
-static inline NDIS_STATUS mp_set_int(struct ndis_device *wnd,
- ndis_oid oid, ULONG data)
-{
- return mp_request(NdisRequestSetInformation, wnd, oid,
- &data, sizeof(ULONG), NULL, NULL);
-}
-
-void free_tx_packet(struct ndis_device *wnd, struct ndis_packet *packet,
- NDIS_STATUS status);
-int init_ndis_driver(struct driver_object *drv_obj);
-NDIS_STATUS ndis_reinit(struct ndis_device *wnd);
-void set_media_state(struct ndis_device *wnd, enum ndis_media_state state);
-
-void hangcheck_add(struct ndis_device *wnd);
-void hangcheck_del(struct ndis_device *wnd);
-
-driver_dispatch_t winNdisDispatchPnp;
-driver_dispatch_t winNdisDispatchPower;
-driver_dispatch_t winNdisDispatchDeviceControl;
-
-struct iw_statistics *get_iw_stats(struct net_device *dev);
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include "ndis.h"
-#include "iw_ndis.h"
-#include "loader.h"
-#include "pnp.h"
-#include "wrapper.h"
-
-char *if_name = "wlan%d";
-int proc_uid, proc_gid;
-int hangcheck_interval;
-static char *utils_version = UTILS_VERSION;
-
-#if defined(DEBUG) && (DEBUG > 0)
-int debug = DEBUG;
-#else
-int debug = 0;
-#endif
-
-WRAP_MODULE_PARM_STRING(if_name, 0400);
-MODULE_PARM_DESC(if_name, "Network interface name or template "
- "(default: wlan%d)");
-WRAP_MODULE_PARM_INT(proc_uid, 0600);
-MODULE_PARM_DESC(proc_uid, "The uid of the files created in /proc "
- "(default: 0).");
-WRAP_MODULE_PARM_INT(proc_gid, 0600);
-MODULE_PARM_DESC(proc_gid, "The gid of the files created in /proc "
- "(default: 0).");
-WRAP_MODULE_PARM_INT(debug, 0600);
-MODULE_PARM_DESC(debug, "debug level");
-
-/* 0 - default value provided by NDIS driver,
- * positive value - force hangcheck interval to that many seconds
- * negative value - disable hangcheck
- */
-WRAP_MODULE_PARM_INT(hangcheck_interval, 0600);
-MODULE_PARM_DESC(hangcheck_interval, "The interval, in seconds, for checking"
- " if driver is hung. (default: 0)");
-
-WRAP_MODULE_PARM_STRING(utils_version, 0400);
-MODULE_PARM_DESC(utils_version, "Compatible version of utils "
- "(read only: " UTILS_VERSION ")");
-
-MODULE_AUTHOR("ndiswrapper team <ndiswrapper-general@lists.sourceforge.net>");
-#ifdef MODULE_DESCRIPTION
-MODULE_DESCRIPTION("NDIS wrapper driver");
-#endif
-#ifdef MODULE_VERSION
-MODULE_VERSION(DRIVER_VERSION);
-#endif
-MODULE_LICENSE("GPL");
-
-static void module_cleanup(void)
-{
- loader_exit();
-#ifdef ENABLE_USB
- usb_exit();
-#endif
-
- wrap_procfs_remove();
- wrapndis_exit();
- ndis_exit();
- rtl_exit();
- crt_exit();
- ntoskernel_exit();
- wrapmem_exit();
-}
-
-static int __init wrapper_init(void)
-{
- printk(KERN_INFO "%s version %s loaded (smp=%s, preempt=%s)\n",
- DRIVER_NAME, DRIVER_VERSION,
-#ifdef CONFIG_SMP
- "yes"
-#else
- "no"
-#endif
- ,
-#ifdef CONFIG_PREEMPT_RT
- "rt"
-#elif defined(CONFIG_PREEMPT)
- "yes"
-#else
- "no"
-#endif
- );
-
- if (wrapmem_init() || ntoskernel_init() || crt_init() ||
- rtl_init() || ndis_init() || wrapndis_init() ||
-#ifdef ENABLE_USB
- usb_init() ||
-#endif
- wrap_procfs_init() || loader_init()) {
- module_cleanup();
- ERROR("%s: initialization failed", DRIVER_NAME);
- return -EINVAL;
- }
- EXIT1(return 0);
-}
-
-static void __exit wrapper_exit(void)
-{
- ENTER1("");
- module_cleanup();
-}
-
-module_init(wrapper_init);
-module_exit(wrapper_exit);
+++ /dev/null
-/*
- * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef WRAPPER_H
-#define WRAPPER_H
-
-extern char *if_name;
-extern int proc_uid;
-extern int proc_gid;
-extern int hangcheck_interval;
-
-#endif /* WRAPPER_H */